@@ -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,7 +71,12 @@ 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_stream ( response )
78+ false -> handle ( response )
79+ end
7280 end
7381
7482 defp request_stream ( method , url , headers , body , opts ) do
@@ -106,6 +114,41 @@ if Code.ensure_loaded?(:hackney) do
106114
107115 defp handle ( { :ok , status , headers , body } ) , do: { :ok , status , headers , body }
108116
117+ defp handle_stream ( { :ok , status , headers , ref } ) when is_reference ( ref ) do
118+ state = :hackney_manager . get_state ( ref )
119+
120+ body =
121+ Stream . resource (
122+ fn -> state end ,
123+ fn
124+ { :done , state } ->
125+ { :halt , state }
126+
127+ { :ok , data , state } ->
128+ { [ data ] , state }
129+
130+ { :error , reason } ->
131+ raise inspect ( reason )
132+
133+ state ->
134+ { [ ] , :hackney_response . stream_body ( state ) }
135+ end ,
136+ & :hackney_response . close / 1
137+ )
138+
139+ { :ok , status , headers , body }
140+ end
141+
142+ defp handle_stream ( response ) do
143+ case handle ( response ) do
144+ { :ok , _status , _headers , ref } = response when is_reference ( ref ) ->
145+ handle_stream ( response )
146+
147+ response ->
148+ response
149+ end
150+ end
151+
109152 defp handle_async_response ( { ref , % { headers: headers , status: status } } )
110153 when not ( is_nil ( headers ) or is_nil ( status ) ) do
111154 { :ok , status , headers , ref }
0 commit comments