@@ -8,11 +8,11 @@ import (
88 "io"
99 "net/http"
1010 "net/url"
11- "os"
1211 "strings"
1312 "time"
1413
1514 "github.com/rclone/rclone/fs"
15+ "github.com/rclone/rclone/fs/fserrors"
1616 "github.com/rclone/rclone/lib/rest"
1717)
1818
@@ -130,20 +130,26 @@ func apiErrorHandler(resp *http.Response) (err error) {
130130 return e
131131}
132132
133- func apiRetry (resp * http.Response , err error ) (bool , error ) {
134- if resp != nil {
135- if resp .StatusCode == 429 {
136- return true , err
137- } else if resp .StatusCode == 500 {
138- return true , err
139- }
140- }
141- if os .IsTimeout (err ) {
142- return true , err
133+ var retryErrorCodes = []int {
134+ 429 , // Too Many Requests.
135+ 500 , // Internal Server Error
136+ 502 , // Bad Gateway
137+ 503 , // Service Unavailable
138+ 504 , // Gateway Timeout
139+ }
140+
141+ // shouldRetry returns a boolean as to whether this resp and err deserve to be
142+ // retried. It returns the err as a convenience so it can be used as the return
143+ // value in the pacer function
144+ func shouldRetry (ctx context.Context , resp * http.Response , err error ) (bool , error ) {
145+ if fserrors .ContextError (ctx , & err ) {
146+ return false , err
143147 }
144- return false , err
148+ return fserrors . ShouldRetry ( err ) || fserrors . ShouldRetryHTTP ( resp , retryErrorCodes ) , err
145149}
146150
151+ // paramsFromMetadata turns the fs.Metadata into instructions the pixeldrain API
152+ // can understand.
147153func paramsFromMetadata (meta fs.Metadata ) (params url.Values ) {
148154 params = make (url.Values )
149155
@@ -203,7 +209,7 @@ func (f *Fs) put(
203209 params .Set ("make_parents" , "true" )
204210
205211 return node , f .pacer .Call (func () (bool , error ) {
206- return apiRetry ( f .srv .CallJSON (
212+ resp , err := f .srv .CallJSON (
207213 ctx ,
208214 & rest.Opts {
209215 Method : "PUT" ,
@@ -214,7 +220,8 @@ func (f *Fs) put(
214220 },
215221 nil ,
216222 & node ,
217- ))
223+ )
224+ return shouldRetry (ctx , resp , err )
218225 })
219226}
220227
@@ -226,7 +233,7 @@ func (f *Fs) read(ctx context.Context, path string, options []fs.OpenOption) (in
226233 Path : f .escapePath (path ),
227234 Options : options ,
228235 })
229- return apiRetry ( resp , err )
236+ return shouldRetry ( ctx , resp , err )
230237 })
231238 if err != nil {
232239 return nil , err
@@ -236,7 +243,7 @@ func (f *Fs) read(ctx context.Context, path string, options []fs.OpenOption) (in
236243
237244func (f * Fs ) stat (ctx context.Context , path string ) (fsp FilesystemPath , err error ) {
238245 return fsp , f .pacer .Call (func () (bool , error ) {
239- return apiRetry ( f .srv .CallJSON (
246+ resp , err := f .srv .CallJSON (
240247 ctx ,
241248 & rest.Opts {
242249 Method : "GET" ,
@@ -248,13 +255,14 @@ func (f *Fs) stat(ctx context.Context, path string) (fsp FilesystemPath, err err
248255 },
249256 nil ,
250257 & fsp ,
251- ))
258+ )
259+ return shouldRetry (ctx , resp , err )
252260 })
253261}
254262
255263func (f * Fs ) changeLog (ctx context.Context , start , end time.Time ) (changeLog ChangeLog , err error ) {
256264 return changeLog , f .pacer .Call (func () (bool , error ) {
257- return apiRetry ( f .srv .CallJSON (
265+ resp , err := f .srv .CallJSON (
258266 ctx ,
259267 & rest.Opts {
260268 Method : "GET" ,
@@ -267,7 +275,8 @@ func (f *Fs) changeLog(ctx context.Context, start, end time.Time) (changeLog Cha
267275 },
268276 nil ,
269277 & changeLog ,
270- ))
278+ )
279+ return shouldRetry (ctx , resp , err )
271280 })
272281}
273282
@@ -276,7 +285,7 @@ func (f *Fs) update(ctx context.Context, path string, fields fs.Metadata) (node
276285 params .Set ("action" , "update" )
277286
278287 return node , f .pacer .Call (func () (bool , error ) {
279- return apiRetry ( f .srv .CallJSON (
288+ resp , err := f .srv .CallJSON (
280289 ctx ,
281290 & rest.Opts {
282291 Method : "POST" ,
@@ -285,13 +294,14 @@ func (f *Fs) update(ctx context.Context, path string, fields fs.Metadata) (node
285294 },
286295 nil ,
287296 & node ,
288- ))
297+ )
298+ return shouldRetry (ctx , resp , err )
289299 })
290300}
291301
292302func (f * Fs ) mkdir (ctx context.Context , dir string ) (err error ) {
293303 return f .pacer .Call (func () (bool , error ) {
294- return apiRetry ( f .srv .CallJSON (
304+ resp , err := f .srv .CallJSON (
295305 ctx ,
296306 & rest.Opts {
297307 Method : "POST" ,
@@ -301,7 +311,8 @@ func (f *Fs) mkdir(ctx context.Context, dir string) (err error) {
301311 },
302312 nil ,
303313 nil ,
304- ))
314+ )
315+ return shouldRetry (ctx , resp , err )
305316 })
306317}
307318
@@ -330,7 +341,7 @@ func (f *Fs) rename(ctx context.Context, src fs.Fs, from, to string, meta fs.Met
330341 params .Set ("make_parents" , "true" )
331342
332343 return node , f .pacer .Call (func () (bool , error ) {
333- return apiRetry ( f .srv .CallJSON (
344+ resp , err := f .srv .CallJSON (
334345 ctx ,
335346 & rest.Opts {
336347 Method : "POST" ,
@@ -340,7 +351,8 @@ func (f *Fs) rename(ctx context.Context, src fs.Fs, from, to string, meta fs.Met
340351 },
341352 nil ,
342353 & node ,
343- ))
354+ )
355+ return shouldRetry (ctx , resp , err )
344356 })
345357}
346358
@@ -352,7 +364,7 @@ func (f *Fs) delete(ctx context.Context, path string, recursive bool) (err error
352364 }
353365
354366 return f .pacer .Call (func () (bool , error ) {
355- return apiRetry ( f .srv .CallJSON (
367+ resp , err := f .srv .CallJSON (
356368 ctx ,
357369 & rest.Opts {
358370 Method : "DELETE" ,
@@ -361,13 +373,14 @@ func (f *Fs) delete(ctx context.Context, path string, recursive bool) (err error
361373 NoResponse : true ,
362374 },
363375 nil , nil ,
364- ))
376+ )
377+ return shouldRetry (ctx , resp , err )
365378 })
366379}
367380
368381func (f * Fs ) userInfo (ctx context.Context ) (user UserInfo , err error ) {
369382 return user , f .pacer .Call (func () (bool , error ) {
370- return apiRetry ( f .srv .CallJSON (
383+ resp , err := f .srv .CallJSON (
371384 ctx ,
372385 & rest.Opts {
373386 Method : "GET" ,
@@ -378,6 +391,7 @@ func (f *Fs) userInfo(ctx context.Context) (user UserInfo, err error) {
378391 },
379392 nil ,
380393 & user ,
381- ))
394+ )
395+ return shouldRetry (ctx , resp , err )
382396 })
383397}
0 commit comments