@@ -54,6 +54,10 @@ pub enum SyncError {
54
54
InvalidPushFrameNoHigh ( u32 , u32 ) ,
55
55
#[ error( "failed to pull frame: status={0}, error={1}" ) ]
56
56
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 ,
57
61
}
58
62
59
63
impl SyncError {
@@ -194,7 +198,7 @@ impl SyncContext {
194
198
Ok ( durable_frame_num)
195
199
}
196
200
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 ) > {
198
202
let mut nr_retries = 0 ;
199
203
loop {
200
204
let mut req = http:: Request :: post ( uri. clone ( ) ) ;
@@ -243,6 +247,17 @@ impl SyncContext {
243
247
return Ok ( ( generation as u32 , max_frame_no as u32 ) ) ;
244
248
}
245
249
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
+
246
261
// If we've retried too many times or the error is not a server error,
247
262
// return the error.
248
263
if nr_retries > max_retries || !res. status ( ) . is_server_error ( ) {
@@ -263,7 +278,7 @@ impl SyncContext {
263
278
}
264
279
}
265
280
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 > {
267
282
let mut nr_retries = 0 ;
268
283
loop {
269
284
let mut req = http:: Request :: builder ( ) . method ( "GET" ) . uri ( uri. clone ( ) ) ;
@@ -308,6 +323,16 @@ impl SyncContext {
308
323
. ok_or_else ( || SyncError :: JsonValue ( generation. clone ( ) ) ) ?;
309
324
return Ok ( PullResult :: EndOfGeneration { max_generation : generation as u32 } ) ;
310
325
}
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
+ }
311
336
// If we've retried too many times or the error is not a server error,
312
337
// return the error.
313
338
if nr_retries > max_retries || !res. status ( ) . is_server_error ( ) {
0 commit comments