@@ -34,7 +34,6 @@ import (
34
34
"context"
35
35
"errors"
36
36
"fmt"
37
- "github.com/hashicorp/errwrap"
38
37
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
39
38
"google.golang.org/api/googleapi"
40
39
"io/ioutil"
@@ -99,19 +98,29 @@ func (t *retryTransport) RoundTrip(req *http.Request) (resp *http.Response, resp
99
98
backoff := time .Millisecond * 500
100
99
nextBackoff := time .Millisecond * 500
101
100
101
+ // VCR depends on the original request body being consumed, so
102
+ // consume here. Since this won't affect the request itself,
103
+ // we do this before the actual Retry loop so we can consume the request Body as needed
104
+ // e.g. if the request couldn't be retried, we use the original request
105
+ if _ , err := httputil .DumpRequestOut (req , true ); err != nil {
106
+ log .Printf ("[WARN] Retry Transport: Consuming original request body failed: %v" , err )
107
+ }
108
+
102
109
log .Printf ("[DEBUG] Retry Transport: starting RoundTrip retry loop" )
103
110
Retry:
104
111
for {
105
- log .Printf ("[DEBUG] Retry Transport: request attempt %d" , attempts )
106
-
107
- // Copy the request - we dont want to use the original request as
108
- // RoundTrip contract says request body can/will be consumed
112
+ // RoundTrip contract says request body can/will be consumed, so we need to
113
+ // copy the request body for each attempt.
114
+ // If we can't copy the request, we run as a single request.
109
115
newRequest , copyErr := copyHttpRequest (req )
110
116
if copyErr != nil {
111
- respErr = errwrap .Wrapf ("unable to copy invalid http.Request for retry: {{err}}" , copyErr )
117
+ log .Printf ("[WARN] Retry Transport: Unable to copy request body: %v." , copyErr )
118
+ log .Printf ("[WARN] Retry Transport: Running request as non-retryable" )
119
+ resp , respErr = t .internal .RoundTrip (req )
112
120
break Retry
113
121
}
114
122
123
+ log .Printf ("[DEBUG] Retry Transport: request attempt %d" , attempts )
115
124
// Do the wrapped Roundtrip. This is one request in the retry loop.
116
125
resp , respErr = t .internal .RoundTrip (newRequest )
117
126
attempts ++
@@ -141,13 +150,6 @@ Retry:
141
150
continue
142
151
}
143
152
}
144
-
145
- // VCR depends on the original request body being consumed, so consume it here
146
- _ , err := httputil .DumpRequestOut (req , true )
147
- if err != nil {
148
- log .Printf ("[DEBUG] Retry Transport: Reading request failed: %v" , err )
149
- }
150
-
151
153
log .Printf ("[DEBUG] Retry Transport: Returning after %d attempts" , attempts )
152
154
return resp , respErr
153
155
}
@@ -157,15 +159,13 @@ Retry:
157
159
// so it can be consumed.
158
160
func copyHttpRequest (req * http.Request ) (* http.Request , error ) {
159
161
newRequest := * req
160
-
161
162
if req .Body == nil || req .Body == http .NoBody {
162
163
return & newRequest , nil
163
164
}
164
-
165
165
// Helpers like http.NewRequest add a GetBody for copying.
166
166
// If not given, we should reject the request.
167
167
if req .GetBody == nil {
168
- return nil , errors .New ("invalid HTTP request for transport, expected request.GetBody for non-empty Body" )
168
+ return nil , errors .New ("request.GetBody is not defined for non-empty Body" )
169
169
}
170
170
171
171
bd , err := req .GetBody ()
0 commit comments