OLD | NEW |
1 // An HTTP Client which sends json and binary requests, handling data marshallin
g and response processing. | 1 // An HTTP Client which sends json and binary requests, handling data marshallin
g and response processing. |
2 | 2 |
3 package http | 3 package http |
4 | 4 |
5 import ( | 5 import ( |
6 "bytes" | 6 "bytes" |
7 "encoding/json" | 7 "encoding/json" |
8 "fmt" | 8 "fmt" |
9 "io" | 9 "io" |
10 "io/ioutil" | 10 "io/ioutil" |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 194 |
195 func (c *Client) sendRateLimitedRequest(method, URL string, headers http.Header,
reqData []byte, | 195 func (c *Client) sendRateLimitedRequest(method, URL string, headers http.Header,
reqData []byte, |
196 logger *log.Logger) (resp *http.Response, err error) { | 196 logger *log.Logger) (resp *http.Response, err error) { |
197 for i := 0; i < c.maxSendAttempts; i++ { | 197 for i := 0; i < c.maxSendAttempts; i++ { |
198 var reqReader io.Reader | 198 var reqReader io.Reader |
199 if reqData != nil { | 199 if reqData != nil { |
200 reqReader = bytes.NewReader(reqData) | 200 reqReader = bytes.NewReader(reqData) |
201 } | 201 } |
202 req, err := http.NewRequest(method, URL, reqReader) | 202 req, err := http.NewRequest(method, URL, reqReader) |
203 if err != nil { | 203 if err != nil { |
204 » » » err = errors.Newf(err, URL, "failed creating the request
") | 204 » » » err = errors.Newf(err, "failed creating the request %s",
URL) |
205 return nil, err | 205 return nil, err |
206 } | 206 } |
207 for header, values := range headers { | 207 for header, values := range headers { |
208 for _, value := range values { | 208 for _, value := range values { |
209 req.Header.Add(header, value) | 209 req.Header.Add(header, value) |
210 } | 210 } |
211 } | 211 } |
212 resp, err = c.Do(req) | 212 resp, err = c.Do(req) |
213 if err != nil { | 213 if err != nil { |
214 » » » return nil, errors.Newf(err, URL, "failed executing the
request") | 214 » » » return nil, errors.Newf(err, "failed executing the reque
st %s", URL) |
215 } | 215 } |
216 if resp.StatusCode != http.StatusRequestEntityTooLarge || resp.H
eader.Get("Retry-After") == "" { | 216 if resp.StatusCode != http.StatusRequestEntityTooLarge || resp.H
eader.Get("Retry-After") == "" { |
217 return resp, nil | 217 return resp, nil |
218 } | 218 } |
219 retryAfter, err := strconv.ParseFloat(resp.Header.Get("Retry-Aft
er"), 32) | 219 retryAfter, err := strconv.ParseFloat(resp.Header.Get("Retry-Aft
er"), 32) |
220 if err != nil { | 220 if err != nil { |
221 » » » return nil, errors.Newf(err, URL, "Invalid Retry-After h
eader") | 221 » » » return nil, errors.Newf(err, "Invalid Retry-After header
%s", URL) |
222 } | 222 } |
223 if retryAfter == 0 { | 223 if retryAfter == 0 { |
224 » » » return nil, errors.Newf(err, URL, "Resource limit exeede
d at URL %s.", URL) | 224 » » » return nil, errors.Newf(err, "Resource limit exeeded at
URL %s", URL) |
225 } | 225 } |
226 if logger != nil { | 226 if logger != nil { |
227 logger.Printf("Too many requests, retrying in %dms.", in
t(retryAfter*1000)) | 227 logger.Printf("Too many requests, retrying in %dms.", in
t(retryAfter*1000)) |
228 } | 228 } |
229 time.Sleep(time.Duration(retryAfter) * time.Second) | 229 time.Sleep(time.Duration(retryAfter) * time.Second) |
230 } | 230 } |
231 » return nil, errors.Newf(err, URL, | 231 » return nil, errors.Newf(err, "Maximum number of attempts (%d) reached se
nding request to %s", c.maxSendAttempts, URL) |
232 » » "Maximum number of attempts (%d) reached sending request to %s."
, c.maxSendAttempts, URL) | |
233 } | 232 } |
234 | 233 |
235 type HttpError struct { | 234 type HttpError struct { |
236 StatusCode int | 235 StatusCode int |
237 Data map[string][]string | 236 Data map[string][]string |
238 url string | 237 url string |
239 responseMessage string | 238 responseMessage string |
240 } | 239 } |
241 | 240 |
242 func (e *HttpError) Error() string { | 241 func (e *HttpError) Error() string { |
(...skipping 26 matching lines...) Expand all Loading... |
269 case http.StatusForbidden, http.StatusUnauthorized: | 268 case http.StatusForbidden, http.StatusUnauthorized: |
270 return errors.NewUnauthorisedf(httpError, "", "Unauthorised URL
%s", URL) | 269 return errors.NewUnauthorisedf(httpError, "", "Unauthorised URL
%s", URL) |
271 case http.StatusBadRequest: | 270 case http.StatusBadRequest: |
272 dupExp, _ := regexp.Compile(".*already exists.*") | 271 dupExp, _ := regexp.Compile(".*already exists.*") |
273 if dupExp.Match(errBytes) { | 272 if dupExp.Match(errBytes) { |
274 return errors.NewDuplicateValuef(httpError, "", string(e
rrBytes)) | 273 return errors.NewDuplicateValuef(httpError, "", string(e
rrBytes)) |
275 } | 274 } |
276 } | 275 } |
277 return httpError | 276 return httpError |
278 } | 277 } |
OLD | NEW |