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. %% @todo We probably want to allow Data to be the {sendfile, ...} tuple also.
commands(State=#state{socket=Socket, transport=Transport, streams=Streams}, StreamID, commands(State=#state{socket=Socket, transport=Transport, streams=Streams}, StreamID,
[{data, IsFin, Data}|Tail]) -> [{data, IsFin, Data}|Tail]) ->
%% Do not send anything when the user asks to send an empty
%% @todo We need to kill the stream if it tries to send data before headers. %% data frame, as that would break the protocol.
Size = iolist_size(Data),
%% @todo Same as above. case Size of
case lists:keyfind(StreamID, #stream.id, Streams) of 0 -> ok;
#stream{version='HTTP/1.1'} -> _ ->
Size = iolist_size(Data), %% @todo We need to kill the stream if it tries to send data before headers.
Transport:send(Socket, [integer_to_binary(Size, 16), <<"\r\n">>, Data, <<"\r\n">>]); %% @todo Same as above.
#stream{version='HTTP/1.0'} -> case lists:keyfind(StreamID, #stream.id, Streams) of
Transport:send(Socket, Data) #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, end,
maybe_terminate(State, StreamID, Tail, IsFin); maybe_terminate(State, StreamID, Tail, IsFin);
%% Send a file. %% Send a file.