Request makes a http request and returns the status, the content length, the headers, the body and an error if you want the body returned set the corresponding property inside RequestOptions
(ctx context.Context, fullURL url.URL, opts RequestOptions)
| 131 | // Request makes a http request and returns the status, the content length, the headers, the body and an error |
| 132 | // if you want the body returned set the corresponding property inside RequestOptions |
| 133 | func (client *HTTPClient) Request(ctx context.Context, fullURL url.URL, opts RequestOptions) (int, int64, http.Header, []byte, error) { |
| 134 | resp, err := client.makeRequest(ctx, fullURL, opts) |
| 135 | if err != nil { |
| 136 | // ignore context canceled errors |
| 137 | if errors.Is(ctx.Err(), context.Canceled) { |
| 138 | return 0, 0, nil, nil, nil |
| 139 | } |
| 140 | return 0, 0, nil, nil, err |
| 141 | } |
| 142 | defer resp.Body.Close() |
| 143 | |
| 144 | var body []byte |
| 145 | var length int64 |
| 146 | if opts.ReturnBody { |
| 147 | body, err = io.ReadAll(resp.Body) |
| 148 | if err != nil { |
| 149 | return 0, 0, nil, nil, fmt.Errorf("could not read body %w", err) |
| 150 | } |
| 151 | length = int64(len(body)) |
| 152 | } else { |
| 153 | // DO NOT REMOVE! |
| 154 | // absolutely needed so golang will reuse connections! |
| 155 | length, err = io.Copy(io.Discard, resp.Body) |
| 156 | if err != nil { |
| 157 | return 0, 0, nil, nil, err |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | return resp.StatusCode, length, resp.Header, body, nil |
| 162 | } |
| 163 | |
| 164 | func (client *HTTPClient) makeRequest(ctx context.Context, fullURL url.URL, opts RequestOptions) (*http.Response, error) { |
| 165 | req, err := http.NewRequestWithContext(ctx, client.method, fullURL.String(), opts.Body) |