-
Notifications
You must be signed in to change notification settings - Fork 129
/
request.go
84 lines (78 loc) · 2.1 KB
/
request.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package requestutils
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"time"
"github.com/LambdaTest/test-at-scale/pkg/core"
"github.com/LambdaTest/test-at-scale/pkg/lumber"
"github.com/cenkalti/backoff/v4"
)
type requests struct {
logger lumber.Logger
client http.Client
retryBackoff backoff.BackOff
}
func New(logger lumber.Logger, requestTimeout time.Duration, retryBackoff backoff.BackOff) core.Requests {
return &requests{
logger: logger,
client: http.Client{Timeout: requestTimeout},
retryBackoff: retryBackoff,
}
}
func (r *requests) MakeAPIRequest(
ctx context.Context,
httpMethod, endpoint string,
body []byte,
params, headers map[string]string,
) (respBody []byte, statusCode int, err error) {
u, err := url.Parse(endpoint)
if err != nil {
r.logger.Errorf("error while parsing endpoint %s, %v", endpoint, err)
return nil, 0, err
}
q := u.Query()
for id, val := range params {
q.Set(id, val)
}
u.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, httpMethod, u.String(), bytes.NewBuffer(body))
if err != nil {
r.logger.Errorf("error while creating http request %v", err)
return nil, 0, err
}
for id, val := range headers {
req.Header.Add(id, val)
}
operation := func() error {
resp, errD := r.client.Do(req)
if errD != nil {
r.logger.Errorf("error while sending http request %v", errD)
return errD
}
defer resp.Body.Close()
statusCode = resp.StatusCode
if 500 <= statusCode && statusCode < 600 {
return fmt.Errorf("status code %d received", statusCode)
}
respBody, err = io.ReadAll(resp.Body)
if err != nil {
r.logger.Errorf("error while reading http response body %v", err)
return nil
}
return nil
}
if errR := backoff.Retry(operation, r.retryBackoff); errR != nil {
r.logger.Errorf("Retry limit exceeded. Error %+v", errR)
return respBody, statusCode, errors.New("retry limit exceeded")
}
if statusCode != http.StatusOK {
r.logger.Errorf("non 200 status code %s", statusCode)
return respBody, statusCode, errors.New("non 200 status code")
}
return respBody, statusCode, err
}