aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-04-23 15:49:34 +0200
committerLoïc Hoguin <[email protected]>2018-04-23 15:49:34 +0200
commit8b9a09c9fe670e95fe888009e3eb28439eab9ce0 (patch)
treea74be0d668124dd023b371a15b3abfa5f2bec3dd
parent9af8b0d23a2887f9bae5e8f54bc2b055a0375efe (diff)
downloadcowboy-8b9a09c9fe670e95fe888009e3eb28439eab9ce0.tar.gz
cowboy-8b9a09c9fe670e95fe888009e3eb28439eab9ce0.tar.bz2
cowboy-8b9a09c9fe670e95fe888009e3eb28439eab9ce0.zip
HTTP/2 informational responses don't end the stream
-rw-r--r--src/cowboy_http2.erl2
-rw-r--r--test/rfc7540_SUITE.erl21
2 files changed, 22 insertions, 1 deletions
diff --git a/src/cowboy_http2.erl b/src/cowboy_http2.erl
index 82f4d2e..74ebe5e 100644
--- a/src/cowboy_http2.erl
+++ b/src/cowboy_http2.erl
@@ -534,7 +534,7 @@ commands(State, Stream, [{error_response, _, _, _}|Tail]) ->
commands(State, Stream, Tail);
%% Send an informational response.
commands(State0, Stream=#stream{local=idle}, [{inform, StatusCode, Headers}|Tail]) ->
- State = send_headers(State0, Stream, StatusCode, Headers, fin),
+ State = send_headers(State0, Stream, StatusCode, Headers, nofin),
commands(State, Stream, Tail);
%% Send response headers.
%%
diff --git a/test/rfc7540_SUITE.erl b/test/rfc7540_SUITE.erl
index a97da71..6c3d989 100644
--- a/test/rfc7540_SUITE.erl
+++ b/test/rfc7540_SUITE.erl
@@ -2767,6 +2767,27 @@ settings_initial_window_size_reject_overflow(Config) ->
% behavior. These MAY be treated by an implementation as being
% equivalent to INTERNAL_ERROR.
+headers_informational_nofin(Config) ->
+ doc("Informational HEADERS frames must not have the END_STREAM flag set. (RFC7540 8.1)"),
+ {ok, Socket} = do_handshake(Config),
+ %% Send a HEADERS frame on an idle stream.
+ {HeadersBlock, _} = cow_hpack:encode([
+ {<<":method">>, <<"POST">>},
+ {<<":scheme">>, <<"http">>},
+ {<<":authority">>, <<"localhost">>}, %% @todo Correct port number.
+ {<<":path">>, <<"/echo/read_body">>},
+ {<<"expect">>, <<"100-continue">>},
+ {<<"content-length">>, <<"1000000">>}
+ ]),
+ ok = gen_tcp:send(Socket, cow_http2:headers(1, nofin, HeadersBlock)),
+ %% Receive an informational HEADERS frame without the END_STREAM flag.
+ {ok, << Len:24, 1:8, 0:5, 1:1, 0:2, _:32 >>} = gen_tcp:recv(Socket, 9, 6000),
+ {ok, RespHeadersBlock} = gen_tcp:recv(Socket, Len, 6000),
+ %% Confirm it has a 100 status code.
+ {RespHeaders, _} = cow_hpack:decode(RespHeadersBlock),
+ {_, <<"100">>} = lists:keyfind(<<":status">>, 1, RespHeaders),
+ ok.
+
%% (RFC7540 8.1)
% A HEADERS frame (and associated CONTINUATION frames) can only appear
% at the start or end of a stream. An endpoint that receives a HEADERS