aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-11-27 13:42:04 +0100
committerLoïc Hoguin <[email protected]>2017-11-27 13:42:04 +0100
commitbc82679330ea027e311474ddb3d28c8da50e5544 (patch)
treea1130d695f926892de47977b9d54021af65b502a /src
parent843b104fcb75bcd217359a8b02d0b1f263d42602 (diff)
downloadcowboy-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.erl7
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),