@@ -380,65 +380,8 @@ where
380
380
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
381
381
let mut this = self . project ( ) ;
382
382
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 ) ;
384
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
- }
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 > {
442
385
let drop_payload_headers = |headers : & mut HeaderMap | {
443
386
for header in & [
444
387
CONTENT_TYPE ,
@@ -453,59 +396,104 @@ where
453
396
StatusCode :: MOVED_PERMANENTLY | StatusCode :: FOUND => {
454
397
// User agents MAY change the request method from POST to GET
455
398
// (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 ) ;
460
403
}
461
404
}
462
405
StatusCode :: SEE_OTHER => {
463
406
// 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 ;
466
409
}
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 ) ;
469
412
}
470
413
StatusCode :: TEMPORARY_REDIRECT | StatusCode :: PERMANENT_REDIRECT => { }
471
- _ => return Ok ( None ) ,
414
+ _ => return Poll :: Ready ( Ok ( res ) ) ,
472
415
} ;
473
416
474
- let body = if let Some ( body) = self . body . take ( ) {
417
+ let body = if let Some ( body) = this . request . body . take ( ) {
475
418
body
476
419
} else {
477
- return Ok ( None ) ;
420
+ return Poll :: Ready ( Ok ( res ) ) ;
478
421
} ;
479
422
480
423
let location = res
481
424
. headers ( )
482
425
. 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 ) ) ;
484
427
let location = if let Some ( loc) = location {
485
428
loc
486
429
} else {
487
- return Ok ( None ) ;
430
+ return Poll :: Ready ( Ok ( res ) ) ;
488
431
} ;
489
432
490
433
let attempt = Attempt {
491
434
status : res. status ( ) ,
492
435
location : & location,
493
- previous : & self . uri ,
436
+ previous : & this . request . uri ,
494
437
} ;
495
- match self . policy . redirect ( & attempt) ? {
438
+ match this . request . policy . redirect ( & attempt) ? {
496
439
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 ) ;
499
444
500
445
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
507
458
}
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,
509
497
}
510
498
}
511
499
}
0 commit comments