aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http2.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-11-01 15:33:10 +0000
committerLoïc Hoguin <[email protected]>2017-11-01 15:33:10 +0000
commit83bd8bc935cbbba39c8c706a1f7d5a6e9ac932ef (patch)
tree168cd9ffcffe5a8caaaa9dd8b2459d3bd4fa52f1 /src/cowboy_http2.erl
parent774824cd0f37e5956e1dd8f903be990c3ce4666a (diff)
downloadcowboy-83bd8bc935cbbba39c8c706a1f7d5a6e9ac932ef.tar.gz
cowboy-83bd8bc935cbbba39c8c706a1f7d5a6e9ac932ef.tar.bz2
cowboy-83bd8bc935cbbba39c8c706a1f7d5a6e9ac932ef.zip
Fix two edge cases for cowboy_req:stream_body
Sending data of size 0 with the fin flag set resulted in nothing being sent to the client and still considering the response to be finished for HTTP/1.1. For both HTTP/1.1 and HTTP/2, the final chunk of body that is sent automatically by Cowboy at the end of a response that the user did not properly terminate was not passing through stream handlers. This resulted in issues like compression being incorrect. Some tests still fail under 20.1.3. They are due to recent zlib changes and should be fixed in a future patch release. Unfortunately it does not seem to be any 20.1 version that is safe to use for Cowboy, although some will work better than others.
Diffstat (limited to 'src/cowboy_http2.erl')
-rw-r--r--src/cowboy_http2.erl10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/cowboy_http2.erl b/src/cowboy_http2.erl
index 21f0aeb..9e81957 100644
--- a/src/cowboy_http2.erl
+++ b/src/cowboy_http2.erl
@@ -830,8 +830,7 @@ stream_linger(State=#state{lingering_streams=Lingering0}, StreamID) ->
Lingering = [StreamID|lists:sublist(Lingering0, 100 - 1)],
State#state{lingering_streams=Lingering}.
-stream_terminate(State0=#state{socket=Socket, transport=Transport,
- streams=Streams0, children=Children0}, StreamID, Reason) ->
+stream_terminate(State0=#state{streams=Streams0, children=Children0}, StreamID, Reason) ->
case lists:keytake(StreamID, #stream.id, Streams0) of
%% When the stream terminates normally (without sending RST_STREAM)
%% and no response was sent, we need to send a proper response back to the client.
@@ -843,10 +842,11 @@ stream_terminate(State0=#state{socket=Socket, transport=Transport,
Children = cowboy_children:shutdown(Children0, StreamID),
State#state{streams=Streams, children=Children};
%% When a response was sent but not terminated, we need to close the stream.
- {value, Stream=#stream{state=StreamState, local=nofin, local_buffer_size=0}, Streams}
+ {value, Stream=#stream{local=nofin, local_buffer_size=0}, Streams}
when Reason =:= normal ->
- Transport:send(Socket, cow_http2:data(StreamID, fin, <<>>)),
- State = maybe_skip_body(State0, Stream, Reason),
+ State1 = #state{streams=Streams1} = info(State0, StreamID, {data, fin, <<>>}),
+ State = maybe_skip_body(State1, Stream, Reason),
+ #stream{state=StreamState} = lists:keyfind(StreamID, #stream.id, Streams1),
stream_call_terminate(StreamID, Reason, StreamState),
Children = cowboy_children:shutdown(Children0, StreamID),
State#state{streams=Streams, children=Children};