aboutsummaryrefslogtreecommitdiffstats
path: root/test/http_SUITE.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-11-18 13:21:36 +0100
committerLoïc Hoguin <[email protected]>2018-11-18 13:25:12 +0100
commit8d6d78575f64055be2d0992d8ccf802d9efa1faa (patch)
treeee95f8c365487a23afb8c10c225c1a2128a945fc /test/http_SUITE.erl
parent417032a445926ea79c42e82be25b384f2d17d8ac (diff)
downloadcowboy-8d6d78575f64055be2d0992d8ccf802d9efa1faa.tar.gz
cowboy-8d6d78575f64055be2d0992d8ccf802d9efa1faa.tar.bz2
cowboy-8d6d78575f64055be2d0992d8ccf802d9efa1faa.zip
Add the chunked option for HTTP/1.1
It allows disabling the chunked transfer-encoding. It can also be disabled on a per-request basis, although it will be ignored for responses that are not streamed.
Diffstat (limited to 'test/http_SUITE.erl')
-rw-r--r--test/http_SUITE.erl78
1 files changed, 77 insertions, 1 deletions
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl
index f330d58..1d6c3fc 100644
--- a/test/http_SUITE.erl
+++ b/test/http_SUITE.erl
@@ -24,6 +24,8 @@
-import(cowboy_test, [raw_open/1]).
-import(cowboy_test, [raw_send/2]).
-import(cowboy_test, [raw_recv_head/1]).
+-import(cowboy_test, [raw_recv/3]).
+-import(cowboy_test, [raw_expect_recv/2]).
all() -> [{group, clear}].
@@ -33,12 +35,39 @@ init_routes(_) -> [
{"localhost", [
{"/", hello_h, []},
{"/echo/:key", echo_h, []},
+ {"/resp/:key[/:arg]", resp_h, []},
{"/set_options/:key", set_options_h, []}
]}
].
+chunked_false(Config) ->
+ doc("Confirm the option chunked => false disables chunked "
+ "transfer-encoding for HTTP/1.1 connections."),
+ {ok, _} = cowboy:start_clear(name(), [{port, 0}], #{
+ env => #{dispatch => cowboy_router:compile(init_routes(Config))},
+ chunked => false
+ }),
+ Port = ranch:get_port(name()),
+ Request = "GET /resp/stream_reply2/200 HTTP/1.1\r\nhost: localhost\r\n\r\n",
+ Client = raw_open([{type, tcp}, {port, Port}, {opts, []}|Config]),
+ ok = raw_send(Client, Request),
+ Rest = case catch raw_recv_head(Client) of
+ {'EXIT', _} -> error(closed);
+ Data ->
+ %% Cowboy always advertises itself as HTTP/1.1.
+ {'HTTP/1.1', 200, _, Rest0} = cow_http:parse_status_line(Data),
+ {Headers, Rest1} = cow_http:parse_headers(Rest0),
+ false = lists:keyfind(<<"content-length">>, 1, Headers),
+ false = lists:keyfind(<<"transfer-encoding">>, 1, Headers),
+ Rest1
+ end,
+ Bits = 8000000 - bit_size(Rest),
+ raw_expect_recv(Client, <<0:Bits>>),
+ {error, closed} = raw_recv(Client, 1, 1000),
+ ok.
+
http10_keepalive_false(Config) ->
- doc("Confirm the option {http10_keepalive, false} disables keep-alive "
+ doc("Confirm the option http10_keepalive => false disables keep-alive "
"completely for HTTP/1.0 connections."),
{ok, _} = cowboy:start_clear(name(), [{port, 0}], #{
env => #{dispatch => cowboy_router:compile(init_routes(Config))},
@@ -101,6 +130,53 @@ request_timeout_infinity(Config) ->
ok
end.
+set_options_chunked_false(Config) ->
+ doc("Confirm the option chunked can be dynamically set to disable "
+ "chunked transfer-encoding. This results in the closing of the "
+ "connection after the current request."),
+ {ok, _} = cowboy:start_clear(name(), [{port, 0}], #{
+ env => #{dispatch => cowboy_router:compile(init_routes(Config))},
+ chunked => true
+ }),
+ Port = ranch:get_port(name()),
+ Request = "GET /set_options/chunked_false HTTP/1.1\r\nhost: localhost\r\n\r\n",
+ Client = raw_open([{type, tcp}, {port, Port}, {opts, []}|Config]),
+ ok = raw_send(Client, Request),
+ _ = case catch raw_recv_head(Client) of
+ {'EXIT', _} -> error(closed);
+ Data ->
+ %% Cowboy always advertises itself as HTTP/1.1.
+ {'HTTP/1.1', 200, _, Rest} = cow_http:parse_status_line(Data),
+ {Headers, <<>>} = cow_http:parse_headers(Rest),
+ false = lists:keyfind(<<"content-length">>, 1, Headers),
+ false = lists:keyfind(<<"transfer-encoding">>, 1, Headers)
+ end,
+ raw_expect_recv(Client, <<0:8000000>>),
+ {error, closed} = raw_recv(Client, 1, 1000),
+ ok.
+
+set_options_chunked_false_ignored(Config) ->
+ doc("Confirm the option chunked can be dynamically set to disable "
+ "chunked transfer-encoding, and that it is ignored if the "
+ "response is not streamed."),
+ {ok, _} = cowboy:start_clear(name(), [{port, 0}], #{
+ env => #{dispatch => cowboy_router:compile(init_routes(Config))},
+ chunked => true
+ }),
+ Port = ranch:get_port(name()),
+ ConnPid = gun_open([{type, tcp}, {protocol, http}, {port, Port}|Config]),
+ %% We do a first request setting the option but not
+ %% using chunked transfer-encoding in the response.
+ StreamRef1 = gun:get(ConnPid, "/set_options/chunked_false_ignored"),
+ {response, nofin, 200, _} = gun:await(ConnPid, StreamRef1),
+ {ok, <<"Hello world!">>} = gun:await_body(ConnPid, StreamRef1),
+ %% We then do a second request to confirm that chunked
+ %% is not disabled for that second request.
+ StreamRef2 = gun:get(ConnPid, "/resp/stream_reply2/200"),
+ {response, nofin, 200, Headers} = gun:await(ConnPid, StreamRef2),
+ {_, <<"chunked">>} = lists:keyfind(<<"transfer-encoding">>, 1, Headers),
+ ok.
+
set_options_idle_timeout(Config) ->
doc("Confirm that the idle_timeout option can be dynamically "
"set to change how long Cowboy will wait before it closes the connection."),