@@ -54,6 +54,10 @@ pub enum SyncError {
5454 InvalidPushFrameNoHigh ( u32 , u32 ) ,
5555 #[ error( "failed to pull frame: status={0}, error={1}" ) ]
5656 PullFrame ( StatusCode , String ) ,
57+ #[ error( "failed to get location header for redirect: {0}" ) ]
58+ RedirectHeader ( http:: header:: ToStrError ) ,
59+ #[ error( "redirect response with no location header" ) ]
60+ NoRedirectLocationHeader ,
5761}
5862
5963impl SyncError {
@@ -194,7 +198,7 @@ impl SyncContext {
194198 Ok ( durable_frame_num)
195199 }
196200
197- async fn push_with_retry ( & self , uri : String , body : Bytes , max_retries : usize ) -> Result < ( u32 , u32 ) > {
201+ async fn push_with_retry ( & self , mut uri : String , body : Bytes , max_retries : usize ) -> Result < ( u32 , u32 ) > {
198202 let mut nr_retries = 0 ;
199203 loop {
200204 let mut req = http:: Request :: post ( uri. clone ( ) ) ;
@@ -243,6 +247,17 @@ impl SyncContext {
243247 return Ok ( ( generation as u32 , max_frame_no as u32 ) ) ;
244248 }
245249
250+ if res. status ( ) . is_redirection ( ) {
251+ uri = match res. headers ( ) . get ( hyper:: header:: LOCATION ) {
252+ Some ( loc) => loc. to_str ( ) . map_err ( SyncError :: RedirectHeader ) ?. to_string ( ) ,
253+ None => return Err ( SyncError :: NoRedirectLocationHeader . into ( ) ) ,
254+ } ;
255+ if nr_retries == 0 {
256+ nr_retries += 1 ;
257+ continue ;
258+ }
259+ }
260+
246261 // If we've retried too many times or the error is not a server error,
247262 // return the error.
248263 if nr_retries > max_retries || !res. status ( ) . is_server_error ( ) {
@@ -263,7 +278,7 @@ impl SyncContext {
263278 }
264279 }
265280
266- async fn pull_with_retry ( & self , uri : String , max_retries : usize ) -> Result < PullResult > {
281+ async fn pull_with_retry ( & self , mut uri : String , max_retries : usize ) -> Result < PullResult > {
267282 let mut nr_retries = 0 ;
268283 loop {
269284 let mut req = http:: Request :: builder ( ) . method ( "GET" ) . uri ( uri. clone ( ) ) ;
@@ -308,6 +323,16 @@ impl SyncContext {
308323 . ok_or_else ( || SyncError :: JsonValue ( generation. clone ( ) ) ) ?;
309324 return Ok ( PullResult :: EndOfGeneration { max_generation : generation as u32 } ) ;
310325 }
326+ if res. status ( ) . is_redirection ( ) {
327+ uri = match res. headers ( ) . get ( hyper:: header:: LOCATION ) {
328+ Some ( loc) => loc. to_str ( ) . map_err ( SyncError :: RedirectHeader ) ?. to_string ( ) ,
329+ None => return Err ( SyncError :: NoRedirectLocationHeader . into ( ) ) ,
330+ } ;
331+ if nr_retries == 0 {
332+ nr_retries += 1 ;
333+ continue ;
334+ }
335+ }
311336 // If we've retried too many times or the error is not a server error,
312337 // return the error.
313338 if nr_retries > max_retries || !res. status ( ) . is_server_error ( ) {
0 commit comments