diff options
author | Loïc Hoguin <[email protected]> | 2017-11-27 13:42:04 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2017-11-27 13:42:04 +0100 |
commit | bc82679330ea027e311474ddb3d28c8da50e5544 (patch) | |
tree | a1130d695f926892de47977b9d54021af65b502a /src | |
parent | 843b104fcb75bcd217359a8b02d0b1f263d42602 (diff) | |
download | cowboy-bc82679330ea027e311474ddb3d28c8da50e5544.tar.gz cowboy-bc82679330ea027e311474ddb3d28c8da50e5544.tar.bz2 cowboy-bc82679330ea027e311474ddb3d28c8da50e5544.zip |
Fix a few rfc7540 tests
Cowboy takes a few shortcuts to avoid wasting resources when
there is a protocol error. The RFC wants us to send a different
error depending on the state of the stream at the time of the
error, and for us to maintain the connection in cases where we
would have to spend valuable resources to decode headers. In
all these cases Cowboy will simply close the connection with
an appropriate error.
Diffstat (limited to 'src')
-rw-r--r-- | src/cowboy_http2.erl | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/cowboy_http2.erl b/src/cowboy_http2.erl index 39a36f7..cbcaf79 100644 --- a/src/cowboy_http2.erl +++ b/src/cowboy_http2.erl @@ -360,9 +360,12 @@ frame(State, {headers, StreamID, _, _, _}) when StreamID rem 2 =:= 0 -> terminate(State, {connection_error, protocol_error, 'HEADERS frame received with even-numbered streamid. (RFC7540 5.1.1)'}); %% HEADERS frame received on (half-)closed stream. +%% +%% We always close the connection here to avoid having to decode +%% the headers to not waste resources on non-compliant clients. frame(State=#state{client_streamid=LastStreamID}, {headers, StreamID, _, _, _}) when StreamID =< LastStreamID -> - stream_reset(State, StreamID, {stream_error, stream_closed, + terminate(State, {connection_error, stream_closed, 'HEADERS frame received on a stream in closed or half-closed state. (RFC7540 5.1)'}); %% Single HEADERS frame headers block. frame(State, {headers, StreamID, IsFin, head_fin, HeaderBlock}) -> @@ -895,7 +898,7 @@ stream_terminate(State0=#state{streams=Streams0, children=Children0}, StreamID, Children = cowboy_children:shutdown(Children0, StreamID), State0#state{streams=[Stream#stream{state=flush, local=flush}|Streams], children=Children}; - %% Otherwise we sent an RST_STREAM and/or the stream is already closed. + %% Otherwise we sent or received an RST_STREAM and/or the stream is already closed. {value, Stream=#stream{state=StreamState}, Streams} -> State = maybe_skip_body(State0, Stream, Reason), stream_call_terminate(StreamID, Reason, StreamState), |