@@ -166,45 +166,70 @@ maybe_continue(Parent, Owner, Ref, #client{transport=Transport,
166
166
% % - {redirect, To, Headers}
167
167
% % - {see_other, To, Headers} for status 303 and POST requests.
168
168
maybe_redirect (Parent , Owner , Ref , StatusInt , Reason ,
169
- # client {transport = Transport ,
170
- socket = Socket ,
171
- method = Method ,
172
- follow_redirect = true }= Client ) ->
169
+ # client {method = Method , follow_redirect = true }= Client ) ->
173
170
case lists :member (StatusInt , [301 , 302 , 307 , 308 ]) of
174
171
true ->
175
- Transport :setopts (Socket , [{active , false }]),
176
- case parse (Client ) of
177
- {loop , Client2 } ->
178
- maybe_redirect (Parent , Owner , Ref , StatusInt ,
179
- Reason , Client2 );
180
- {ok , {headers , Headers }, Client2 } ->
181
- Location = hackney :redirect_location (Headers ),
182
- case {Location , lists :member (Method , [get , head ])} of
183
- {undefined , _ } ->
172
+ maybe_redirect_1 (Parent , Owner , Ref , Reason , Client );
173
+ false when StatusInt =:= 303 , Method =:= <<" POST" >> ->
174
+ maybe_redirect_2 (Parent , Owner , Ref , Reason , Client );
175
+ _ ->
176
+ Owner ! {hackney_response , Ref , {status , StatusInt , Reason }},
177
+ maybe_continue (Parent , Owner , Ref , Client )
178
+ end ;
179
+ maybe_redirect (Parent , Owner , Ref , StatusInt , Reason , Client ) ->
180
+ Owner ! {hackney_response , Ref , {status , StatusInt , Reason }},
181
+ maybe_continue (Parent , Owner , Ref , Client ).
182
+
183
+ % % The first case for redirections are status codes 301, 302, 307 and 308.
184
+ % % In this case {redirect, Location, Headers} is sent to the owner if
185
+ % % the request is valid.
186
+ maybe_redirect_1 (Parent , Owner , Ref , Reason ,
187
+ # client {transport = Transport , socket = Socket }= Client ) ->
188
+ Transport :setopts (Socket , [{active , false }]),
189
+ case parse (Client ) of
190
+ {loop , Client2 } ->
191
+ maybe_redirect_1 (Parent , Owner , Ref , Reason , Client2 );
192
+ {more , Client2 , Rest } ->
193
+ Continuation = fun (Client3 ) ->
194
+ maybe_redirect_1 (Parent , Owner , Ref , Reason , Client3 )
195
+ end ,
196
+ async_recv (Parent , Owner , Ref , Client2 , Rest , Continuation );
197
+ {ok , {headers , Headers }, Client2 } ->
198
+ Location = hackney :redirect_location (Headers ),
199
+ case Location of
200
+ undefined ->
201
+ Owner ! {hackney_response , Ref , {error ,invalid_redirection }},
202
+ hackney_manager :handle_error (Client2 );
203
+ _ ->
204
+ case hackney_response :skip_body (Client2 ) of
205
+ {skip , Client3 } ->
206
+ hackney_manager :store_state (Client3 ),
184
207
Owner ! {hackney_response , Ref ,
185
- {error ,invalid_redirection }},
186
- hackney_manager :handle_error (Client2 );
187
- {_ , _ } ->
188
- case hackney_response :skip_body (Client2 ) of
189
- {skip , Client3 } ->
190
- hackney_manager :store_state (Client3 ),
191
- Owner ! {hackney_response , Ref ,
192
- {redirect , Location , Headers }};
193
- Error ->
194
- Owner ! {hackney_response , Ref , Error },
195
- hackney_manager :handle_error (Client2 )
208
+ {redirect , Location , Headers }};
209
+ Error ->
210
+ Owner ! {hackney_response , Ref , Error },
211
+ hackney_manager :handle_error (Client2 )
196
212
end
197
213
end ;
198
- {error , Error } ->
199
- Owner ! {hackney_response , Ref , {error , Error }},
200
- hackney_manager :handle_error (Client )
201
- end ;
202
- false when StatusInt =:= 303 , Method =:= post ->
214
+ {error , Error } ->
215
+ Owner ! {hackney_response , Ref , {error , Error }},
216
+ hackney_manager :handle_error (Client )
217
+ end .
218
+
219
+ % % The second case is for status code 303 and POST requests.
220
+ % % This results in sending {see_other, Location, Headers} to the owner.
221
+ maybe_redirect_2 (Parent , Owner , Ref , Reason ,
222
+ # client {transport = Transport ,
223
+ socket = Socket }= Client ) ->
203
224
Transport :setopts (Socket , [{active , false }]),
204
225
case parse (Client ) of
205
226
{loop , Client2 } ->
206
- maybe_redirect (Parent , Owner , Ref , StatusInt ,
207
- Reason , Client2 );
227
+ maybe_redirect_2 (Parent , Owner , Ref , Reason , Client2 );
228
+ {more , Client2 , Rest } ->
229
+ Continuation = fun (Client3 ) ->
230
+ maybe_redirect_2 (Parent , Owner , Ref , Reason , Client3 )
231
+ end ,
232
+ async_recv (Parent , Owner , Ref , Client2 , Rest , Continuation );
208
233
{ok , {headers , Headers }, Client2 } ->
209
234
case hackney :redirect_location (Headers ) of
210
235
undefined ->
@@ -225,21 +250,19 @@ maybe_redirect(Parent, Owner, Ref, StatusInt, Reason,
225
250
{error , Error } ->
226
251
Owner ! {hackney_response , Ref , {error , Error }},
227
252
hackney_manager :handle_error (Client )
228
- end ;
229
- _ ->
230
- Owner ! {hackney_response , Ref , {status , StatusInt , Reason }},
231
- maybe_continue (Parent , Owner , Ref , Client )
232
- end ;
233
- maybe_redirect (Parent , Owner , Ref , StatusInt , Reason , Client ) ->
234
- Owner ! {hackney_response , Ref , {status , StatusInt , Reason }},
235
- maybe_continue (Parent , Owner , Ref , Client ).
253
+ end .
236
254
237
255
256
+ async_recv (Parent , Owner , Ref , Client , Buffer ) ->
257
+ Continuation = fun (Client2 ) ->
258
+ stream_loop (Parent , Owner , Ref , Client2 )
259
+ end ,
260
+ async_recv (Parent , Owner , Ref , Client , Buffer , Continuation ).
261
+
238
262
async_recv (Parent , Owner , Ref ,
239
263
# client {transport = Transport ,
240
264
socket = TSock ,
241
- recv_timeout = Timeout }= Client , Buffer ) ->
242
-
265
+ recv_timeout = Timeout }= Client , Buffer , Continuation ) ->
243
266
{OK , Closed , Error } = Transport :messages (TSock ),
244
267
Sock = raw_sock (TSock ),
245
268
Transport :setopts (TSock , [{active , once }]),
@@ -263,7 +286,7 @@ async_recv(Parent, Owner, Ref,
263
286
Transport :controlling_process (TSock , From ),
264
287
From ! {Ref , ok };
265
288
{OK , Sock , Data } ->
266
- stream_loop ( Parent , Owner , Ref , Client # client {buffer = Data });
289
+ Continuation ( Client # client {buffer = Data });
267
290
{Closed , Sock } ->
268
291
case Client # client .response_state of
269
292
on_body when (Version =:= {1 , 0 } orelse Version =:= {1 , 1 })
0 commit comments