@@ -380,65 +380,8 @@ where
380380 fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
381381 let mut this = self . project ( ) ;
382382 let mut res = ready ! ( this. future. as_mut( ) . poll( cx) ?) ;
383- CB :: on_response ( & mut res, & this. request ) ;
383+ CB :: on_response ( & mut res, this. request ) ;
384384
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- }
432-
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 > {
442385 let drop_payload_headers = |headers : & mut HeaderMap | {
443386 for header in & [
444387 CONTENT_TYPE ,
@@ -453,59 +396,104 @@ where
453396 StatusCode :: MOVED_PERMANENTLY | StatusCode :: FOUND => {
454397 // User agents MAY change the request method from POST to GET
455398 // (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 ) ;
399+ if this . request . method == Method :: POST {
400+ this . request . method = Method :: GET ;
401+ this . request . body = BodyRepr :: Empty ;
402+ drop_payload_headers ( & mut this . request . headers ) ;
460403 }
461404 }
462405 StatusCode :: SEE_OTHER => {
463406 // 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 ;
407+ if this . request . method != Method :: HEAD {
408+ this . request . method = Method :: GET ;
466409 }
467- self . body = BodyRepr :: Empty ;
468- drop_payload_headers ( & mut self . headers ) ;
410+ this . request . body = BodyRepr :: Empty ;
411+ drop_payload_headers ( & mut this . request . headers ) ;
469412 }
470413 StatusCode :: TEMPORARY_REDIRECT | StatusCode :: PERMANENT_REDIRECT => { }
471- _ => return Ok ( None ) ,
414+ _ => return Poll :: Ready ( Ok ( res ) ) ,
472415 } ;
473416
474- let body = if let Some ( body) = self . body . take ( ) {
417+ let body = if let Some ( body) = this . request . body . take ( ) {
475418 body
476419 } else {
477- return Ok ( None ) ;
420+ return Poll :: Ready ( Ok ( res ) ) ;
478421 } ;
479422
480423 let location = res
481424 . headers ( )
482425 . get ( & LOCATION )
483- . and_then ( |loc| resolve_uri ( str:: from_utf8 ( loc. as_bytes ( ) ) . ok ( ) ?, & self . uri ) ) ;
426+ . and_then ( |loc| resolve_uri ( str:: from_utf8 ( loc. as_bytes ( ) ) . ok ( ) ?, & this . request . uri ) ) ;
484427 let location = if let Some ( loc) = location {
485428 loc
486429 } else {
487- return Ok ( None ) ;
430+ return Poll :: Ready ( Ok ( res ) ) ;
488431 } ;
489432
490433 let attempt = Attempt {
491434 status : res. status ( ) ,
492435 location : & location,
493- previous : & self . uri ,
436+ previous : & this . request . uri ,
494437 } ;
495- match self . policy . redirect ( & attempt) ? {
438+ match this . request . policy . redirect ( & attempt) ? {
496439 Action :: Follow => {
497- self . uri = location;
498- self . body . try_clone_from ( & body, & self . policy ) ;
440+ this. request . uri = location;
441+ this. request
442+ . body
443+ . try_clone_from ( & body, & this. request . policy ) ;
499444
500445 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) ) )
446+ * req. uri_mut ( ) = this. request . uri . clone ( ) ;
447+ * req. method_mut ( ) = this. request . method . clone ( ) ;
448+ * req. version_mut ( ) = this. request . version ;
449+ * req. headers_mut ( ) = this. request . headers . clone ( ) ;
450+ this. request . policy . on_request ( & mut req) ;
451+ this. future . set ( Either :: Right ( Oneshot :: new (
452+ this. request . service . clone ( ) ,
453+ req,
454+ ) ) ) ;
455+
456+ cx. waker ( ) . wake_by_ref ( ) ;
457+ Poll :: Pending
507458 }
508- Action :: Stop => Ok ( None ) ,
459+ Action :: Stop => Poll :: Ready ( Ok ( res) ) ,
460+ }
461+ }
462+ }
463+
464+ /// Wraps a [`http::Request`] with a [`policy::Policy`] to apply,
465+ /// and an underlying service in case further requests are required.
466+ #[ derive( Debug ) ]
467+ struct RedirectingRequest < S , B , P > {
468+ service : S ,
469+ policy : P ,
470+ method : Method ,
471+ uri : Uri ,
472+ version : Version ,
473+ headers : HeaderMap < HeaderValue > ,
474+ body : BodyRepr < B > ,
475+ }
476+
477+ impl < S , ReqBody , ResBody , P > RedirectingRequest < S , ReqBody , P >
478+ where
479+ S : Service < Request < ReqBody > , Response = Response < ResBody > > + Clone ,
480+ ReqBody : Body + Default ,
481+ P : Policy < ReqBody , S :: Error > ,
482+ {
483+ #[ inline]
484+ /// Build a [`RedirectingRequest`] from a service, attached policy and original [`http::Request`]
485+ fn new ( service : S , mut policy : P , req : & mut Request < ReqBody > ) -> Self {
486+ let mut body = BodyRepr :: None ;
487+ body. try_clone_from ( req. body ( ) , & policy) ;
488+ policy. on_request ( req) ;
489+ Self {
490+ method : req. method ( ) . clone ( ) ,
491+ uri : req. uri ( ) . clone ( ) ,
492+ version : req. version ( ) ,
493+ headers : req. headers ( ) . clone ( ) ,
494+ service,
495+ body,
496+ policy,
509497 }
510498 }
511499}
0 commit comments