github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/api/uaa/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/uaa" 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 uaa.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 uaa.Connection) uaa.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 *uaa.Response) 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 += 1 { 45 if rawRequestBody != nil { 46 request.Body = ioutil.NopCloser(bytes.NewBuffer(rawRequestBody)) 47 } 48 err = retry.connection.Make(request, passedResponse) 49 if err == nil { 50 return nil 51 } 52 53 if request.Method == http.MethodPost || 54 passedResponse.HTTPResponse != nil && 55 passedResponse.HTTPResponse.StatusCode != http.StatusInternalServerError && 56 passedResponse.HTTPResponse.StatusCode != http.StatusBadGateway && 57 passedResponse.HTTPResponse.StatusCode != http.StatusServiceUnavailable && 58 passedResponse.HTTPResponse.StatusCode != http.StatusGatewayTimeout { 59 break 60 } 61 } 62 return err 63 }