github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/api/plugin/wrapper/retry_request.go (about) 1 package wrapper 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 8 "github.com/liamawhite/cli-with-i18n/api/plugin" 9 ) 10 11 // RetryRequest is a wrapper that retries failed requests if they contain a 5XX 12 // status code. 13 type RetryRequest struct { 14 maxRetries int 15 connection plugin.Connection 16 } 17 18 // NewRetryRequest returns a pointer to a RetryRequest wrapper. 19 func NewRetryRequest(maxRetries int) *RetryRequest { 20 return &RetryRequest{ 21 maxRetries: maxRetries, 22 } 23 } 24 25 // Wrap sets the connection in the RetryRequest and returns itself. 26 func (retry *RetryRequest) Wrap(innerconnection plugin.Connection) plugin.Connection { 27 retry.connection = innerconnection 28 return retry 29 } 30 31 // Make retries the request if it comes back with a 5XX status code. 32 func (retry *RetryRequest) Make(request *http.Request, passedResponse *plugin.Response, proxyReader plugin.ProxyReader) error { 33 var err error 34 var rawRequestBody []byte 35 36 if request.Body != nil { 37 rawRequestBody, err = ioutil.ReadAll(request.Body) 38 defer request.Body.Close() 39 if err != nil { 40 return err 41 } 42 } 43 44 for i := 0; i < retry.maxRetries+1; i++ { 45 if rawRequestBody != nil { 46 request.Body = ioutil.NopCloser(bytes.NewBuffer(rawRequestBody)) 47 } 48 err = retry.connection.Make(request, passedResponse, proxyReader) 49 if err == nil { 50 return nil 51 } 52 53 if retry.skipRetry(request.Method, passedResponse.HTTPResponse) { 54 break 55 } 56 } 57 return err 58 } 59 60 // skipRetry if the request method is POST, or not one of the following http 61 // status codes: 500, 502, 503, 504. 62 func (*RetryRequest) skipRetry(httpMethod string, response *http.Response) bool { 63 return httpMethod == http.MethodPost || 64 response != nil && 65 response.StatusCode != http.StatusInternalServerError && 66 response.StatusCode != http.StatusBadGateway && 67 response.StatusCode != http.StatusServiceUnavailable && 68 response.StatusCode != http.StatusGatewayTimeout 69 }