From 353dc29d8f7e9aed7a35426f680f39a975a4cbcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 20 Jan 2017 15:16:50 +0100 Subject: 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. --- src/cowboy_http.erl | 24 ++++++++++++++---------- 1 file 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. -- cgit v1.2.3