From 40ffcf86dc7eb4b3daaec10f3c7ac28f9840e783 Mon Sep 17 00:00:00 2001 From: benoitc Date: Sat, 7 Oct 2023 18:36:35 +0200 Subject: [PATCH] recev stream: fix case when body_state=done ensure we can still receive the trailers when not on stream and body_state is done and the parser state is on_trailers --- src/hackney_response.erl | 45 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/hackney_response.erl b/src/hackney_response.erl index e5df2470..7a42c1a1 100644 --- a/src/hackney_response.erl +++ b/src/hackney_response.erl @@ -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