aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-01-20 15:16:50 +0100
committerLoïc Hoguin <[email protected]>2017-01-20 15:16:50 +0100
commit353dc29d8f7e9aed7a35426f680f39a975a4cbcb (patch)
tree0afab7e097390bbb0333ce2f61c4b707f2c9dbdd /src
parent0f8452cafaa27aeffb103019564c086eacfd34f9 (diff)
downloadcowboy-353dc29d8f7e9aed7a35426f680f39a975a4cbcb.tar.gz
cowboy-353dc29d8f7e9aed7a35426f680f39a975a4cbcb.tar.bz2
cowboy-353dc29d8f7e9aed7a35426f680f39a975a4cbcb.zip
Fix protocol breaking when user tries to send empty chunk
The {data, IsFin, Data} uses IsFin to indicate whether this is the last chunk, while chunked transfer-encoding uses the length of Data, and ends when it is 0. We must therefore not send chunks with empty data.
Diffstat (limited to 'src')
-rw-r--r--src/cowboy_http.erl24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index dcda3fb..1f32b6a 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -842,16 +842,20 @@ commands(State0=#state{socket=Socket, transport=Transport, streams=Streams}, Str
%% @todo We probably want to allow Data to be the {sendfile, ...} tuple also.
commands(State=#state{socket=Socket, transport=Transport, streams=Streams}, StreamID,
[{data, IsFin, Data}|Tail]) ->
-
- %% @todo We need to kill the stream if it tries to send data before headers.
-
- %% @todo Same as above.
- case lists:keyfind(StreamID, #stream.id, Streams) of
- #stream{version='HTTP/1.1'} ->
- Size = iolist_size(Data),
- Transport:send(Socket, [integer_to_binary(Size, 16), <<"\r\n">>, Data, <<"\r\n">>]);
- #stream{version='HTTP/1.0'} ->
- Transport:send(Socket, Data)
+ %% Do not send anything when the user asks to send an empty
+ %% data frame, as that would break the protocol.
+ Size = iolist_size(Data),
+ case Size of
+ 0 -> ok;
+ _ ->
+ %% @todo We need to kill the stream if it tries to send data before headers.
+ %% @todo Same as above.
+ case lists:keyfind(StreamID, #stream.id, Streams) of
+ #stream{version='HTTP/1.1'} ->
+ Transport:send(Socket, [integer_to_binary(Size, 16), <<"\r\n">>, Data, <<"\r\n">>]);
+ #stream{version='HTTP/1.0'} ->
+ Transport:send(Socket, Data)
+ end
end,
maybe_terminate(State, StreamID, Tail, IsFin);
%% Send a file.