|
1 | 1 | # Experimental httpc adapter to test the adapter contract. |
2 | 2 |
|
3 | | -defmodule Req.HttpcTest do |
4 | | - use ExUnit.Case, async: true |
5 | | - |
6 | | - require Logger |
7 | | - |
8 | | - # TODO |
9 | | - @moduletag :skip |
10 | | - |
11 | | - setup do |
12 | | - bypass = Bypass.open() |
13 | | - |
14 | | - req = |
15 | | - Req.new( |
16 | | - adapter: &run_httpc/1, |
17 | | - url: "http://localhost:#{bypass.port}" |
18 | | - ) |
19 | | - |
20 | | - [bypass: bypass, req: req] |
21 | | - end |
22 | | - |
23 | | - if function_exported?(Mix, :ensure_application!, 1) do |
24 | | - Mix.ensure_application!(:inets) |
25 | | - end |
26 | | - |
27 | | - describe "run_httpc/1" do |
28 | | - test "request", %{bypass: bypass, req: req} do |
29 | | - Bypass.expect(bypass, "GET", "/", fn conn -> |
30 | | - Plug.Conn.send_resp(conn, 200, "ok") |
31 | | - end) |
32 | | - |
33 | | - resp = Req.get!(req) |
34 | | - assert resp.status == 200 |
35 | | - assert Req.Response.get_header(resp, "server") == ["Cowboy"] |
36 | | - assert resp.body == "ok" |
37 | | - end |
38 | | - |
39 | | - test "post request body", %{bypass: bypass, req: req} do |
40 | | - Bypass.expect(bypass, "POST", "/", fn conn -> |
41 | | - assert {:ok, body, conn} = Plug.Conn.read_body(conn) |
42 | | - Plug.Conn.send_resp(conn, 200, body) |
43 | | - end) |
44 | | - |
45 | | - resp = Req.post!(req, body: "foofoofoo") |
46 | | - assert resp.status == 200 |
47 | | - assert resp.body == "foofoofoo" |
48 | | - end |
49 | | - |
50 | | - test "stream request body", %{bypass: bypass, req: req} do |
51 | | - Bypass.expect(bypass, "POST", "/", fn conn -> |
52 | | - assert {:ok, body, conn} = Plug.Conn.read_body(conn) |
53 | | - Plug.Conn.send_resp(conn, 200, body) |
54 | | - end) |
55 | | - |
56 | | - resp = Req.post!(req, body: {:stream, Stream.take(["foo", "foo", "foo"], 2)}) |
57 | | - assert resp.status == 200 |
58 | | - assert resp.body == "foofoo" |
59 | | - end |
60 | | - |
61 | | - test "into: fun", %{req: req, bypass: bypass} do |
62 | | - Bypass.expect(bypass, "GET", "/", fn conn -> |
63 | | - conn = Plug.Conn.send_chunked(conn, 200) |
64 | | - {:ok, conn} = Plug.Conn.chunk(conn, "foo") |
65 | | - {:ok, conn} = Plug.Conn.chunk(conn, "bar") |
66 | | - conn |
67 | | - end) |
68 | | - |
69 | | - pid = self() |
70 | | - |
71 | | - resp = |
72 | | - Req.get!( |
73 | | - req, |
74 | | - into: fn {:data, data}, acc -> |
75 | | - send(pid, {:data, data}) |
76 | | - {:cont, acc} |
77 | | - end |
78 | | - ) |
79 | | - |
80 | | - assert resp.status == 200 |
81 | | - assert resp.headers["transfer-encoding"] == ["chunked"] |
82 | | - assert_receive {:data, "foobar"} |
83 | | - |
84 | | - # httpc seems to randomly chunk things |
85 | | - receive do |
86 | | - {:data, ""} -> :ok |
87 | | - after |
88 | | - 0 -> :ok |
89 | | - end |
90 | | - |
91 | | - refute_receive _ |
92 | | - end |
93 | | - |
94 | | - test "into: :self", %{req: req, bypass: bypass} do |
95 | | - Bypass.expect(bypass, "GET", "/", fn conn -> |
96 | | - conn = Plug.Conn.send_chunked(conn, 200) |
97 | | - {:ok, conn} = Plug.Conn.chunk(conn, "foo") |
98 | | - {:ok, conn} = Plug.Conn.chunk(conn, "bar") |
99 | | - conn |
100 | | - end) |
101 | | - |
102 | | - resp = Req.get!(req, into: :self) |
103 | | - assert resp.status == 200 |
104 | | - |
105 | | - # httpc seems to randomly chunk things |
106 | | - assert Req.parse_message(resp, assert_receive(_)) in [ |
107 | | - {:ok, [data: "foo"]}, |
108 | | - {:ok, [data: "foobar"]} |
109 | | - ] |
110 | | - |
111 | | - assert Req.parse_message(resp, assert_receive(_)) in [ |
112 | | - {:ok, [data: "bar"]}, |
113 | | - {:ok, [data: ""]}, |
114 | | - {:ok, [:done]} |
115 | | - ] |
116 | | - end |
117 | | - |
118 | | - test "into: pid cancel", %{req: req, bypass: bypass} do |
119 | | - Bypass.expect(bypass, "GET", "/", fn conn -> |
120 | | - conn = Plug.Conn.send_chunked(conn, 200) |
121 | | - {:ok, conn} = Plug.Conn.chunk(conn, "foo") |
122 | | - {:ok, conn} = Plug.Conn.chunk(conn, "bar") |
123 | | - conn |
124 | | - end) |
125 | | - |
126 | | - resp = Req.get!(req, into: :self) |
127 | | - assert resp.status == 200 |
128 | | - assert :ok = Req.cancel_async_response(resp) |
129 | | - end |
130 | | - end |
131 | | - |
132 | | - def run_httpc(request) do |
| 3 | +defmodule Req.Httpc do |
| 4 | + def run(request) do |
133 | 5 | httpc_url = request.url |> URI.to_string() |> String.to_charlist() |
134 | 6 |
|
135 | 7 | httpc_headers = |
@@ -331,3 +203,133 @@ defmodule Req.HttpcTest do |
331 | 203 | end |
332 | 204 | end |
333 | 205 | end |
| 206 | + |
| 207 | +defmodule Req.HttpcTest do |
| 208 | + use ExUnit.Case, async: true |
| 209 | + |
| 210 | + require Logger |
| 211 | + |
| 212 | + # TODO |
| 213 | + @moduletag :skip |
| 214 | + |
| 215 | + setup do |
| 216 | + bypass = Bypass.open() |
| 217 | + |
| 218 | + req = |
| 219 | + Req.new( |
| 220 | + adapter: &Req.Httpc.run/1, |
| 221 | + url: "http://localhost:#{bypass.port}" |
| 222 | + ) |
| 223 | + |
| 224 | + [bypass: bypass, req: req] |
| 225 | + end |
| 226 | + |
| 227 | + if function_exported?(Mix, :ensure_application!, 1) do |
| 228 | + Mix.ensure_application!(:inets) |
| 229 | + end |
| 230 | + |
| 231 | + describe "httpc" do |
| 232 | + test "request", %{bypass: bypass, req: req} do |
| 233 | + Bypass.expect(bypass, "GET", "/", fn conn -> |
| 234 | + Plug.Conn.send_resp(conn, 200, "ok") |
| 235 | + end) |
| 236 | + |
| 237 | + resp = Req.get!(req) |
| 238 | + assert resp.status == 200 |
| 239 | + assert Req.Response.get_header(resp, "server") == ["Cowboy"] |
| 240 | + assert resp.body == "ok" |
| 241 | + end |
| 242 | + |
| 243 | + test "post request body", %{bypass: bypass, req: req} do |
| 244 | + Bypass.expect(bypass, "POST", "/", fn conn -> |
| 245 | + assert {:ok, body, conn} = Plug.Conn.read_body(conn) |
| 246 | + Plug.Conn.send_resp(conn, 200, body) |
| 247 | + end) |
| 248 | + |
| 249 | + resp = Req.post!(req, body: "foofoofoo") |
| 250 | + assert resp.status == 200 |
| 251 | + assert resp.body == "foofoofoo" |
| 252 | + end |
| 253 | + |
| 254 | + test "stream request body", %{bypass: bypass, req: req} do |
| 255 | + Bypass.expect(bypass, "POST", "/", fn conn -> |
| 256 | + assert {:ok, body, conn} = Plug.Conn.read_body(conn) |
| 257 | + Plug.Conn.send_resp(conn, 200, body) |
| 258 | + end) |
| 259 | + |
| 260 | + resp = Req.post!(req, body: {:stream, Stream.take(["foo", "foo", "foo"], 2)}) |
| 261 | + assert resp.status == 200 |
| 262 | + assert resp.body == "foofoo" |
| 263 | + end |
| 264 | + |
| 265 | + test "into: fun", %{req: req, bypass: bypass} do |
| 266 | + Bypass.expect(bypass, "GET", "/", fn conn -> |
| 267 | + conn = Plug.Conn.send_chunked(conn, 200) |
| 268 | + {:ok, conn} = Plug.Conn.chunk(conn, "foo") |
| 269 | + {:ok, conn} = Plug.Conn.chunk(conn, "bar") |
| 270 | + conn |
| 271 | + end) |
| 272 | + |
| 273 | + pid = self() |
| 274 | + |
| 275 | + resp = |
| 276 | + Req.get!( |
| 277 | + req, |
| 278 | + into: fn {:data, data}, acc -> |
| 279 | + send(pid, {:data, data}) |
| 280 | + {:cont, acc} |
| 281 | + end |
| 282 | + ) |
| 283 | + |
| 284 | + assert resp.status == 200 |
| 285 | + assert resp.headers["transfer-encoding"] == ["chunked"] |
| 286 | + assert_receive {:data, "foobar"} |
| 287 | + |
| 288 | + # httpc seems to randomly chunk things |
| 289 | + receive do |
| 290 | + {:data, ""} -> :ok |
| 291 | + after |
| 292 | + 0 -> :ok |
| 293 | + end |
| 294 | + |
| 295 | + refute_receive _ |
| 296 | + end |
| 297 | + |
| 298 | + test "into: :self", %{req: req, bypass: bypass} do |
| 299 | + Bypass.expect(bypass, "GET", "/", fn conn -> |
| 300 | + conn = Plug.Conn.send_chunked(conn, 200) |
| 301 | + {:ok, conn} = Plug.Conn.chunk(conn, "foo") |
| 302 | + {:ok, conn} = Plug.Conn.chunk(conn, "bar") |
| 303 | + conn |
| 304 | + end) |
| 305 | + |
| 306 | + resp = Req.get!(req, into: :self) |
| 307 | + assert resp.status == 200 |
| 308 | + |
| 309 | + # httpc seems to randomly chunk things |
| 310 | + assert Req.parse_message(resp, assert_receive(_)) in [ |
| 311 | + {:ok, [data: "foo"]}, |
| 312 | + {:ok, [data: "foobar"]} |
| 313 | + ] |
| 314 | + |
| 315 | + assert Req.parse_message(resp, assert_receive(_)) in [ |
| 316 | + {:ok, [data: "bar"]}, |
| 317 | + {:ok, [data: ""]}, |
| 318 | + {:ok, [:done]} |
| 319 | + ] |
| 320 | + end |
| 321 | + |
| 322 | + test "into: pid cancel", %{req: req, bypass: bypass} do |
| 323 | + Bypass.expect(bypass, "GET", "/", fn conn -> |
| 324 | + conn = Plug.Conn.send_chunked(conn, 200) |
| 325 | + {:ok, conn} = Plug.Conn.chunk(conn, "foo") |
| 326 | + {:ok, conn} = Plug.Conn.chunk(conn, "bar") |
| 327 | + conn |
| 328 | + end) |
| 329 | + |
| 330 | + resp = Req.get!(req, into: :self) |
| 331 | + assert resp.status == 200 |
| 332 | + assert :ok = Req.cancel_async_response(resp) |
| 333 | + end |
| 334 | + end |
| 335 | +end |
0 commit comments