@@ -42,7 +42,10 @@ if Code.ensure_loaded?(:hackney) do
4242 end
4343
4444 defp format_body ( data ) when is_list ( data ) , do: IO . iodata_to_binary ( data )
45- defp format_body ( data ) when is_binary ( data ) or is_reference ( data ) , do: data
45+
46+ defp format_body ( data )
47+ when is_binary ( data ) or is_reference ( data ) or is_function ( data ) ,
48+ do: data
4649
4750 defp request ( env , opts ) do
4851 request (
@@ -68,14 +71,22 @@ if Code.ensure_loaded?(:hackney) do
6871 end
6972
7073 defp request ( method , url , headers , body , opts ) do
71- handle ( :hackney . request ( method , url , headers , body || '' , opts ) )
74+ response = :hackney . request ( method , url , headers , body || '' , opts )
75+
76+ case Keyword . get ( opts , :stream_response , false ) do
77+ true -> handle ( response , :stream )
78+ false -> handle ( response )
79+ end
7280 end
7381
7482 defp request_stream ( method , url , headers , body , opts ) do
7583 with { :ok , ref } <- :hackney . request ( method , url , headers , :stream , opts ) do
7684 case send_stream ( ref , body ) do
77- :ok -> handle ( :hackney . start_response ( ref ) )
78- error -> handle ( error )
85+ :ok ->
86+ handle ( :hackney . start_response ( ref ) )
87+
88+ error ->
89+ handle ( error )
7990 end
8091 else
8192 e -> handle ( e )
@@ -106,6 +117,31 @@ if Code.ensure_loaded?(:hackney) do
106117
107118 defp handle ( { :ok , status , headers , body } ) , do: { :ok , status , headers , body }
108119
120+ defp handle ( { :ok , status , headers , ref } , :stream ) when is_reference ( ref ) do
121+ state = :hackney_manager . get_state ( ref )
122+
123+ body =
124+ Stream . resource (
125+ fn -> state end ,
126+ fn
127+ { :done , state } ->
128+ { :halt , state }
129+
130+ { :ok , data , state } ->
131+ { [ data ] , state }
132+
133+ { :error , reason } ->
134+ raise inspect ( reason )
135+
136+ state ->
137+ { [ ] , :hackney_response . stream_body ( state ) }
138+ end ,
139+ & :hackney_response . close / 1
140+ )
141+
142+ { :ok , status , headers , body }
143+ end
144+
109145 defp handle_async_response ( { ref , % { headers: headers , status: status } } )
110146 when not ( is_nil ( headers ) or is_nil ( status ) ) do
111147 { :ok , status , headers , ref }
0 commit comments