github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/api/cloudcontroller/wrapper/retry_request.go (about) 1 package wrapper 2 3 import ( 4 "net/http" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller" 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 8 ) 9 10 // RetryRequest is a wrapper that retries failed requests if they contain a 5XX 11 // status code. 12 type RetryRequest struct { 13 maxRetries int 14 connection cloudcontroller.Connection 15 } 16 17 // NewRetryRequest returns a pointer to a RetryRequest wrapper. 18 func NewRetryRequest(maxRetries int) *RetryRequest { 19 return &RetryRequest{ 20 maxRetries: maxRetries, 21 } 22 } 23 24 // Make retries the request if it comes back with a 5XX status code. 25 func (retry *RetryRequest) Make(request *cloudcontroller.Request, passedResponse *cloudcontroller.Response) error { 26 var err error 27 28 for i := 0; i < retry.maxRetries+1; i++ { 29 err = retry.connection.Make(request, passedResponse) 30 if err == nil { 31 return nil 32 } 33 34 if retry.skipRetry(request.Method, passedResponse.HTTPResponse) { 35 break 36 } 37 38 // Reset the request body prior to the next retry 39 resetErr := request.ResetBody() 40 if resetErr != nil { 41 if _, ok := resetErr.(ccerror.PipeSeekError); ok { 42 return ccerror.PipeSeekError{Err: err} 43 } 44 return resetErr 45 } 46 } 47 return err 48 } 49 50 // Wrap sets the connection in the RetryRequest and returns itself. 51 func (retry *RetryRequest) Wrap(innerconnection cloudcontroller.Connection) cloudcontroller.Connection { 52 retry.connection = innerconnection 53 return retry 54 } 55 56 // skipRetry will skip retry if the request method is POST or contains a status 57 // code that is not one of following http status codes: 500, 502, 503, 504. 58 func (*RetryRequest) skipRetry(httpMethod string, response *http.Response) bool { 59 return httpMethod == http.MethodPost || 60 response != nil && 61 response.StatusCode != http.StatusInternalServerError && 62 response.StatusCode != http.StatusBadGateway && 63 response.StatusCode != http.StatusServiceUnavailable && 64 response.StatusCode != http.StatusGatewayTimeout 65 }