0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

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.
This commit is contained in:
Loïc Hoguin 2017-01-20 15:16:50 +01:00
parent 0f8452cafa
commit 353dc29d8f
No known key found for this signature in database
GPG key ID: 71366FF21851DF03

View file

@ -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.