@@ -341,11 +341,21 @@ where
341
341
342
342
fn call ( & mut self , mut req : Request < ReqBody > ) -> Self :: Future {
343
343
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
+ } ;
349
359
ResponseFuture {
350
360
future : Either :: Left ( request. service . call ( req) ) ,
351
361
request,
@@ -380,65 +390,8 @@ where
380
390
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
381
391
let mut this = self . project ( ) ;
382
392
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 ) ;
432
394
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
395
let drop_payload_headers = |headers : & mut HeaderMap | {
443
396
for header in & [
444
397
CONTENT_TYPE ,
@@ -453,63 +406,84 @@ where
453
406
StatusCode :: MOVED_PERMANENTLY | StatusCode :: FOUND => {
454
407
// User agents MAY change the request method from POST to GET
455
408
// (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 ) ;
460
413
}
461
414
}
462
415
StatusCode :: SEE_OTHER => {
463
416
// 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 ;
466
419
}
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 ) ;
469
422
}
470
423
StatusCode :: TEMPORARY_REDIRECT | StatusCode :: PERMANENT_REDIRECT => { }
471
- _ => return Ok ( None ) ,
424
+ _ => return Poll :: Ready ( Ok ( res ) ) ,
472
425
} ;
473
426
474
- let body = if let Some ( body) = self . body . take ( ) {
427
+ let body = if let Some ( body) = this . request . body . take ( ) {
475
428
body
476
429
} else {
477
- return Ok ( None ) ;
430
+ return Poll :: Ready ( Ok ( res ) ) ;
478
431
} ;
479
432
480
433
let location = res
481
434
. headers ( )
482
435
. 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 ) ) ;
484
437
let location = if let Some ( loc) = location {
485
438
loc
486
439
} else {
487
- return Ok ( None ) ;
440
+ return Poll :: Ready ( Ok ( res ) ) ;
488
441
} ;
489
442
490
443
let attempt = Attempt {
491
444
status : res. status ( ) ,
492
445
location : & location,
493
- previous : & self . uri ,
446
+ previous : & this . request . uri ,
494
447
} ;
495
- match self . policy . redirect ( & attempt) ? {
448
+ match this . request . policy . redirect ( & attempt) ? {
496
449
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 ) ;
499
454
500
455
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
507
468
}
508
- Action :: Stop => Ok ( None ) ,
469
+ Action :: Stop => Poll :: Ready ( Ok ( res ) ) ,
509
470
}
510
471
}
511
472
}
512
473
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
+
513
487
/// Response [`Extensions`][http::Extensions] value that represents the effective request URI of
514
488
/// a response returned by a [`FollowRedirect`] middleware.
515
489
///
0 commit comments