github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/api/plugin/wrapper/retry_request.go (about) 1 package wrapper 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 8 "code.cloudfoundry.org/cli/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 // Make retries the request if it comes back with a 5XX status code. 26 func (retry *RetryRequest) Make(request *http.Request, passedResponse *plugin.Response, proxyReader plugin.ProxyReader) error { 27 var err error 28 var rawRequestBody []byte 29 30 if request.Body != nil { 31 rawRequestBody, err = ioutil.ReadAll(request.Body) 32 defer request.Body.Close() 33 if err != nil { 34 return err 35 } 36 } 37 38 for i := 0; i < retry.maxRetries+1; i++ { 39 if rawRequestBody != nil { 40 request.Body = ioutil.NopCloser(bytes.NewBuffer(rawRequestBody)) 41 } 42 err = retry.connection.Make(request, passedResponse, proxyReader) 43 if err == nil { 44 return nil 45 } 46 47 if retry.skipRetry(request.Method, passedResponse.HTTPResponse) { 48 break 49 } 50 } 51 return err 52 } 53 54 // Wrap sets the connection in the RetryRequest and returns itself. 55 func (retry *RetryRequest) Wrap(innerconnection plugin.Connection) plugin.Connection { 56 retry.connection = innerconnection 57 return retry 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 }