Skip to content

Commit

Permalink
recev stream: fix case when body_state=done
Browse files Browse the repository at this point in the history
ensure we can still receive the trailers when not on stream and
body_state is done and the parser state is on_trailers
  • Loading branch information
benoitc committed Oct 9, 2023
1 parent 1fd8721 commit 40ffcf8
Showing 1 changed file with 28 additions and 17 deletions.
45 changes: 28 additions & 17 deletions src/hackney_response.erl
Original file line number Diff line number Diff line change
Expand Up @@ -166,29 +166,40 @@ stream_body1(Error, _Client) ->

-spec stream_body_recv(binary(), #client{})
-> {ok, binary(), #client{}} | {error, term()}.
stream_body_recv(Buffer, Client=#client{version=Version, clen=CLen, parser=#hparser{body_state={stream, _, TransferState, _}}}) ->
stream_body_recv(Buffer, Client=#client{parser=#hparser{body_state={stream, _, TransferState, _}}}) ->
case recv(Client, TransferState) of
{ok, Data} ->
stream_body(Data, Client);
{error, Reason} ->
Client2 = close(Client),
case Reason of
closed when (Version =:= {1, 0} orelse Version =:= {1, 1}) andalso (CLen =:= nil orelse CLen =:= undefined) ->
{ok, Buffer, Client2#client{response_state=done,
body_state=done,
buffer = <<>>,
parser=nil}};
closed when Client#client.te =:= <<"identity">> ->
{ok, Buffer, Client2#client{response_state=done,
body_state=done,
buffer = <<>>}};
closed ->
{error, {closed, Buffer}};
_Else ->
{error, Reason}
end
stream_body_recv_error(Reason, Buffer, Client)
end;
stream_body_recv(Buffer, Client=#client{parser=#hparser{body_state=done}}) ->
case recv(Client) of
{ok, Data} ->
stream_body(Data, Client);
{error, Reason} ->
stream_body_recv_error(Reason, Buffer, Client)
end.

stream_body_recv_error(Reason, Buffer, Client=#client{version=Version, clen=CLen}) ->
Client2 = close(Client),
case Reason of
closed when (Version =:= {1, 0} orelse Version =:= {1, 1}) andalso (CLen =:= nil orelse CLen =:= undefined) ->
{ok, Buffer, Client2#client{response_state=done,
body_state=done,
buffer = <<>>,
parser=nil}};
closed when Client#client.te =:= <<"identity">> ->
{ok, Buffer, Client2#client{response_state=done,
body_state=done,
buffer = <<>>}};
closed ->
{error, {closed, Buffer}};
_Else ->
{error, Reason}
end.


%% @doc stream a multipart response
%%
%% Use this function for multipart streaming. For each part in the
Expand Down

0 comments on commit 40ffcf8

Please sign in to comment.