Current section

5 Versions

Jump to

Compare versions

9 files changed
+482 additions
-116 deletions
  @@ -36,7 +36,7 @@ dialyzer:
36 36 -rebar3 dialyzer
37 37
38 38 ct:
39 - -rebar3 ct --cover --verbose --readable false
39 + -rebar3 ct --cover --verbose --readable true
40 40
41 41 logs: test
42 42 lynx _build/test/logs/index.html
  @@ -92,7 +92,7 @@ Given an already open connection, send a request.
92 92
93 93 By design there is no help with the `content_length` header; its under the caller's control. Its possible to specify a non-zero `content_length` and provide an initially empty body. The caller should follow a successful request with `httpb:send(Connection, Body)`.
94 94
95 - The `Body` argument is ignored for `head` and `trace` methods. To support `OPTIONS * HTTP/1.1`, specify a `Url` like `http://localhost/*`, which only applies to the `options` method.
95 + The `Body` argument is ignored for `head` and `trace` methods. To support `OPTIONS * HTTP/1.1`, specify a `Url` without a path `http://localhost`, which only applies to the `options` method.
96 96
97 97 - - -
98 98 ### httpb:response(Connection) -> {ok, Result} | {error, Reason}
  @@ -4,10 +4,10 @@
4 4 {<<"files">>,
5 5 [<<"LICENSE">>,<<"Makefile">>,<<"README.md">>,<<"priv/localhost.crt">>,
6 6 <<"priv/localhost.key">>,<<"rebar.config">>,<<"src/httpb.app.src">>,
7 - <<"src/httpb.erl">>,<<"src/recv_loop.erl.OFF">>,<<"test/common_test.hrl">>,
7 + <<"src/httpb.erl">>,<<"src/httpb.erl.x">>,<<"test/common_test.hrl">>,
8 8 <<"test/httpb_SUITE.erl">>,<<"test/httpd_dummy.erl">>]}.
9 9 {<<"licenses">>,[<<"MIT">>]}.
10 10 {<<"links">>,[{<<"Github">>,<<"https://github.com/SirWumpus/erlang-httpb">>}]}.
11 11 {<<"name">>,<<"httpb">>}.
12 12 {<<"requirements">>,[]}.
13 - {<<"version">>,<<"0.4.1">>}.
13 + {<<"version">>,<<"0.4.2">>}.
  @@ -1,6 +1,6 @@
1 1 {application,httpb,
2 2 [{description,"An HTTP basic client"},
3 - {vsn,"0.4.1"},
3 + {vsn,"0.4.2"},
4 4 {registered,[]},
5 5 {applications,[kernel,stdlib,ssl]},
6 6 {env,[]},
  @@ -73,7 +73,14 @@ request(Method, Url, Hdrs, Body, Options) when is_atom(Method) ->
73 73 case connect(Scheme, Host, Port, SocketOpts, Timeout) of
74 74 {ok, Socket} ->
75 75 Conn = #{scheme => Scheme, host => Host, port => Port, socket => Socket},
76 - request(Conn, Method, Url, Hdrs, Body);
76 + case request(Conn, Method, Url, Hdrs, Body) of
77 + {error, Reason} ->
78 + % Initial request failed, cleanup connection.
79 + close(Conn),
80 + {error, Reason};
81 + Result ->
82 + Result
83 + end;
77 84 Other ->
78 85 Other
79 86 end;
  @@ -82,11 +89,13 @@ request(Conn, Method, Url, Hdrs, Body) when is_map(Conn) andalso is_list(Url) ->
82 89 request(Conn, Method, list_to_binary(Url), Hdrs, Body);
83 90 request(#{host := Host, port := Port} = Conn, Method, Url, Hdrs, Body) when is_map(Conn) ->
84 91 UrlMap = uri_string:parse(Url),
85 - Path1 = case {Method, maps:get(path, UrlMap, <<"/">>)} of
86 - {_, <<>>} ->
87 - <<"/">>;
92 + Path1 = case {Method, maps:get(path, UrlMap)} of
88 93 {options, <<"/*">>} ->
89 94 <<"*">>;
95 + {options, <<>>} ->
96 + <<"*">>;
97 + {_, <<>>} ->
98 + <<"/">>;
90 99 {_, Path0} ->
91 100 Path0
92 101 end,
  @@ -311,7 +320,13 @@ response(#{socket := Socket} = Conn, Timeout, Res) ->
311 320 Other
312 321 end;
313 322 false ->
314 - % Stop reading before first chunk.
323 + % Either response has no body or there are chunks to follow,
324 + % in which case caller invokes recv_chunk/2 as needed.
325 + %
326 + % Poor man's websockets: If the request body was chunked and
327 + % the response body is chunked then its possible to send a
328 + % custom server chunked messages and receive chunked messages
329 + % or replies. Seen this done is a real application.
315 330 {ok, Res}
316 331 end;
317 332 Other ->
Loading more files…