|
5 | 5 | "fmt" |
6 | 6 | "io" |
7 | 7 | "net/http" |
| 8 | + "strconv" |
8 | 9 | "strings" |
| 10 | + "time" |
9 | 11 |
|
10 | 12 | "github.com/checkmarx/ast-cli/internal/logger" |
11 | 13 | "github.com/checkmarx/ast-cli/internal/params" |
@@ -248,6 +250,10 @@ func get(client *http.Client, url string, target interface{}, queryParams map[st |
248 | 250 | if err != nil { |
249 | 251 | return nil, err |
250 | 252 | } |
| 253 | + resp, err = handleRateLimit(resp, client, req, url, token, tokenFormat, queryParams) |
| 254 | + if err != nil { |
| 255 | + return nil, err |
| 256 | + } |
251 | 257 | defer func() { |
252 | 258 | if err == nil { |
253 | 259 | _ = resp.Body.Close() |
@@ -276,3 +282,23 @@ func get(client *http.Client, url string, target interface{}, queryParams map[st |
276 | 282 | } |
277 | 283 | return resp, nil |
278 | 284 | } |
| 285 | + |
| 286 | +func handleRateLimit(resp *http.Response, client *http.Client, req *http.Request, url, token, authFormat string, queryParams map[string]string) (*http.Response, error) { |
| 287 | + if resp.StatusCode == http.StatusForbidden { |
| 288 | + remaining := resp.Header.Get("X-RateLimit-Remaining") |
| 289 | + reset := resp.Header.Get("X-RateLimit-Reset") |
| 290 | + if remaining == "0" && reset != "" { |
| 291 | + resetUnix, err := strconv.ParseInt(reset, 10, 64) |
| 292 | + if err == nil { |
| 293 | + waitDuration := time.Until(time.Unix(resetUnix, 0)) |
| 294 | + if waitDuration > 0 { |
| 295 | + time.Sleep(waitDuration) |
| 296 | + return GetWithQueryParamsAndCustomRequest(client, req, url, token, tokenFormat, queryParams) // Indicate to retry |
| 297 | + } |
| 298 | + } else { |
| 299 | + return resp, err |
| 300 | + } |
| 301 | + } |
| 302 | + } |
| 303 | + return resp, nil //Not rate limited |
| 304 | +} |
0 commit comments