From 8b9a09c9fe670e95fe888009e3eb28439eab9ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 23 Apr 2018 15:49:34 +0200 Subject: HTTP/2 informational responses don't end the stream --- src/cowboy_http2.erl | 2 +- test/rfc7540_SUITE.erl | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) 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 -- cgit v1.2.3