@@ -341,11 +341,21 @@ where
341341
342342 fn call ( & mut self , mut req : Request < ReqBody > ) -> Self :: Future {
343343 let service = self . inner . clone ( ) ;
344- let mut request = RedirectingRequest :: new (
345- mem:: replace ( & mut self . inner , service) ,
346- self . policy . clone ( ) ,
347- & mut req,
348- ) ;
344+ let service = mem:: replace ( & mut self . inner , service) ;
345+ let mut policy = self . policy . clone ( ) ;
346+ let mut body = BodyRepr :: None ;
347+ body. try_clone_from ( req. body ( ) , & policy) ;
348+ policy. on_request ( & mut req) ;
349+
350+ let mut request = RedirectingRequest {
351+ method : req. method ( ) . clone ( ) ,
352+ uri : req. uri ( ) . clone ( ) ,
353+ version : req. version ( ) ,
354+ headers : req. headers ( ) . clone ( ) ,
355+ service,
356+ body,
357+ policy,
358+ } ;
349359 ResponseFuture {
350360 future : Either :: Left ( request. service . call ( req) ) ,
351361 request,
@@ -380,65 +390,8 @@ where
380390 fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
381391 let mut this = self . project ( ) ;
382392 let mut res = ready ! ( this. future. as_mut( ) . poll( cx) ?) ;
383- CB :: on_response ( & mut res, & this. request ) ;
384-
385- match this. request . handle_response ( & mut res) {
386- Ok ( Some ( pending) ) => {
387- this. future . set ( Either :: Right ( pending) ) ;
388- cx. waker ( ) . wake_by_ref ( ) ;
389- Poll :: Pending
390- }
391- Ok ( None ) => Poll :: Ready ( Ok ( res) ) ,
392- Err ( e) => Poll :: Ready ( Err ( e) ) ,
393- }
394- }
395- }
396-
397- /// Wraps a [`http::Request`] with a [`policy::Policy`] to apply,
398- /// and an underlying service in case further requests are required.
399- #[ derive( Debug ) ]
400- struct RedirectingRequest < S , B , P > {
401- service : S ,
402- policy : P ,
403- method : Method ,
404- uri : Uri ,
405- version : Version ,
406- headers : HeaderMap < HeaderValue > ,
407- body : BodyRepr < B > ,
408- }
409-
410- impl < S , ReqBody , ResBody , P > RedirectingRequest < S , ReqBody , P >
411- where
412- S : Service < Request < ReqBody > , Response = Response < ResBody > > + Clone ,
413- ReqBody : Body + Default ,
414- P : Policy < ReqBody , S :: Error > ,
415- {
416- #[ inline]
417- /// Build a [`RedirectingRequest`] from a service, attached policy and original [`http::Request`]
418- fn new ( service : S , mut policy : P , req : & mut Request < ReqBody > ) -> Self {
419- let mut body = BodyRepr :: None ;
420- body. try_clone_from ( req. body ( ) , & policy) ;
421- policy. on_request ( req) ;
422- Self {
423- method : req. method ( ) . clone ( ) ,
424- uri : req. uri ( ) . clone ( ) ,
425- version : req. version ( ) ,
426- headers : req. headers ( ) . clone ( ) ,
427- service,
428- body,
429- policy,
430- }
431- }
393+ CB :: on_response ( & mut res, this. request ) ;
432394
433- /// Handle an incoming [`http::Response`] from the underlying service.
434- /// Returns an error if the policy failed.
435- /// Returns a future if there is more work to do.
436- /// Otherwise, returns an empty result.
437- #[ inline]
438- fn handle_response (
439- & mut self ,
440- res : & mut Response < ResBody > ,
441- ) -> Result < Option < Oneshot < S , Request < ReqBody > > > , S :: Error > {
442395 let drop_payload_headers = |headers : & mut HeaderMap | {
443396 for header in & [
444397 CONTENT_TYPE ,
@@ -453,63 +406,84 @@ where
453406 StatusCode :: MOVED_PERMANENTLY | StatusCode :: FOUND => {
454407 // User agents MAY change the request method from POST to GET
455408 // (RFC 7231 section 6.4.2. and 6.4.3.).
456- if self . method == Method :: POST {
457- self . method = Method :: GET ;
458- self . body = BodyRepr :: Empty ;
459- drop_payload_headers ( & mut self . headers ) ;
409+ if this . request . method == Method :: POST {
410+ this . request . method = Method :: GET ;
411+ this . request . body = BodyRepr :: Empty ;
412+ drop_payload_headers ( & mut this . request . headers ) ;
460413 }
461414 }
462415 StatusCode :: SEE_OTHER => {
463416 // A user agent can perform a GET or HEAD request (RFC 7231 section 6.4.4.).
464- if self . method != Method :: HEAD {
465- self . method = Method :: GET ;
417+ if this . request . method != Method :: HEAD {
418+ this . request . method = Method :: GET ;
466419 }
467- self . body = BodyRepr :: Empty ;
468- drop_payload_headers ( & mut self . headers ) ;
420+ this . request . body = BodyRepr :: Empty ;
421+ drop_payload_headers ( & mut this . request . headers ) ;
469422 }
470423 StatusCode :: TEMPORARY_REDIRECT | StatusCode :: PERMANENT_REDIRECT => { }
471- _ => return Ok ( None ) ,
424+ _ => return Poll :: Ready ( Ok ( res ) ) ,
472425 } ;
473426
474- let body = if let Some ( body) = self . body . take ( ) {
427+ let body = if let Some ( body) = this . request . body . take ( ) {
475428 body
476429 } else {
477- return Ok ( None ) ;
430+ return Poll :: Ready ( Ok ( res ) ) ;
478431 } ;
479432
480433 let location = res
481434 . headers ( )
482435 . get ( & LOCATION )
483- . and_then ( |loc| resolve_uri ( str:: from_utf8 ( loc. as_bytes ( ) ) . ok ( ) ?, & self . uri ) ) ;
436+ . and_then ( |loc| resolve_uri ( str:: from_utf8 ( loc. as_bytes ( ) ) . ok ( ) ?, & this . request . uri ) ) ;
484437 let location = if let Some ( loc) = location {
485438 loc
486439 } else {
487- return Ok ( None ) ;
440+ return Poll :: Ready ( Ok ( res ) ) ;
488441 } ;
489442
490443 let attempt = Attempt {
491444 status : res. status ( ) ,
492445 location : & location,
493- previous : & self . uri ,
446+ previous : & this . request . uri ,
494447 } ;
495- match self . policy . redirect ( & attempt) ? {
448+ match this . request . policy . redirect ( & attempt) ? {
496449 Action :: Follow => {
497- self . uri = location;
498- self . body . try_clone_from ( & body, & self . policy ) ;
450+ this. request . uri = location;
451+ this. request
452+ . body
453+ . try_clone_from ( & body, & this. request . policy ) ;
499454
500455 let mut req = Request :: new ( body) ;
501- * req. uri_mut ( ) = self . uri . clone ( ) ;
502- * req. method_mut ( ) = self . method . clone ( ) ;
503- * req. version_mut ( ) = self . version ;
504- * req. headers_mut ( ) = self . headers . clone ( ) ;
505- self . policy . on_request ( & mut req) ;
506- Ok ( Some ( Oneshot :: new ( self . service . clone ( ) , req) ) )
456+ * req. uri_mut ( ) = this. request . uri . clone ( ) ;
457+ * req. method_mut ( ) = this. request . method . clone ( ) ;
458+ * req. version_mut ( ) = this. request . version ;
459+ * req. headers_mut ( ) = this. request . headers . clone ( ) ;
460+ this. request . policy . on_request ( & mut req) ;
461+ this. future . set ( Either :: Right ( Oneshot :: new (
462+ this. request . service . clone ( ) ,
463+ req,
464+ ) ) ) ;
465+
466+ cx. waker ( ) . wake_by_ref ( ) ;
467+ Poll :: Pending
507468 }
508- Action :: Stop => Ok ( None ) ,
469+ Action :: Stop => Poll :: Ready ( Ok ( res ) ) ,
509470 }
510471 }
511472}
512473
474+ /// Wraps a [`http::Request`] with a [`policy::Policy`] to apply,
475+ /// and an underlying service in case further requests are required.
476+ #[ derive( Debug ) ]
477+ struct RedirectingRequest < S , B , P > {
478+ service : S ,
479+ policy : P ,
480+ method : Method ,
481+ uri : Uri ,
482+ version : Version ,
483+ headers : HeaderMap < HeaderValue > ,
484+ body : BodyRepr < B > ,
485+ }
486+
513487/// Response [`Extensions`][http::Extensions] value that represents the effective request URI of
514488/// a response returned by a [`FollowRedirect`] middleware.
515489///
0 commit comments