0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Add streaming without chunking for HTTP/1.1

If content-length is set in the response headers
we can skip chunked transfer-encoding.
This commit is contained in:
Eric Meadows-Jönsson 2018-05-16 13:28:49 +02:00 committed by Loïc Hoguin
parent 69451dd98d
commit f08f4610a0
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764
4 changed files with 140 additions and 38 deletions

View file

@ -146,6 +146,23 @@ do_decode(Headers, Body) ->
_ -> Body
end.
do_get_error(Path, Config) ->
do_get_error(Path, [], Config).
do_get_error(Path, Headers, Config) ->
ConnPid = gun_open(Config),
Ref = gun:get(ConnPid, Path, [{<<"accept-encoding">>, <<"gzip">>}|Headers]),
{response, IsFin, Status, RespHeaders} = gun:await(ConnPid, Ref),
Result = case IsFin of
nofin -> gun:await_body(ConnPid, Ref);
fin -> {ok, <<>>}
end,
gun:close(ConnPid),
case Result of
{ok, RespBody} -> {Status, RespHeaders, do_decode(RespHeaders, RespBody)};
_ -> Result
end.
%% Tests: Request.
binding(Config) ->
@ -856,6 +873,38 @@ stream_body_nofin(Config) ->
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body/nofin", Config),
ok.
stream_body_content_length_multiple(Config) ->
doc("Streamed body via multiple calls."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body_content_length/multiple", Config),
ok.
stream_body_content_length_fin0(Config) ->
doc("Streamed body with last chunk of size 0."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body_content_length/fin0", Config),
ok.
stream_body_content_length_nofin(Config) ->
doc("Unfinished streamed body."),
{200, _, <<"Hello world!">>} = do_get("/resp/stream_body_content_length/nofin", Config),
ok.
stream_body_content_length_nofin_error(Config) ->
doc("Not all of body sent."),
case config(protocol, Config) of
http ->
case do_get_error("/resp/stream_body_content_length/nofin-error", Config) of
{200, Headers, <<"Hello">>} ->
{_, <<"gzip">>} = lists:keyfind(<<"content-encoding">>, 1, Headers);
{error, {closed, "The connection was lost."}} ->
ok;
{error, timeout} ->
ok
end;
http2 ->
%% @todo HTTP2 should have the same content-length checks
ok
end.
%% @todo Crash when calling stream_body after the fin flag has been set.
%% @todo Crash when calling stream_body after calling reply.
%% @todo Crash when calling stream_body before calling stream_reply.