Skip to content

Commit a69904d

Browse files
committed
add response header parameter
1 parent 34acce2 commit a69904d

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

request.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package request
33
import (
44
"bytes"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"io"
89
"io/ioutil"
@@ -50,9 +51,10 @@ type Params struct {
5051
ExpectedResponseCode int
5152
}
5253

53-
// Do executes the request as specified in the request params
54-
// The response body will be parsed into the provided struct
55-
func Do(params Params, responseBody interface{}) (returnErr error) {
54+
// Do executes the request as specified in the request params.
55+
// The response body will be parsed into the provided struct.
56+
// Optionally, the headers will be copied if a header map was provided.
57+
func Do(params Params, responseBody interface{}, responseHeaderArg ...http.Header) (returnErr error) {
5658
req, err := createRequest(params)
5759
if err != nil {
5860
return fmt.Errorf("failed to create request: %w", err)
@@ -75,6 +77,11 @@ func Do(params Params, responseBody interface{}) (returnErr error) {
7577
return err
7678
}
7779

80+
err = populateResponseHeader(res, responseHeaderArg)
81+
if err != nil {
82+
return err
83+
}
84+
7885
if responseBody == nil {
7986
return nil
8087
}
@@ -117,6 +124,8 @@ func DoWithStringResponse(params Params) (result string, returnErr error) {
117124

118125
// DoWithCustomClient is the same as Do but will make the request using the
119126
// supplied http.Client instead of the cachedClient.
127+
// TODO client should become the first parameter in the next major update
128+
// so we can add the response headers at the end. They are currently not supported.
120129
func DoWithCustomClient(params Params, responseBody interface{}, client *http.Client) (returnErr error) {
121130
req, err := createRequest(params)
122131
if err != nil {
@@ -244,3 +253,20 @@ func checkResponseCode(res *http.Response, expectedResponseCode int) error {
244253
func isSuccessCode(statusCode int) bool {
245254
return 200 <= statusCode && statusCode <= 299
246255
}
256+
257+
func populateResponseHeader(res *http.Response, responseHeaderArg []http.Header) error {
258+
if len(responseHeaderArg) == 0 { // go-staticcheck says no need to check for nil separately.
259+
return nil
260+
}
261+
262+
if len(responseHeaderArg) > 1 {
263+
return errors.New("too many arguments supplied")
264+
}
265+
266+
responseHeader := responseHeaderArg[0]
267+
for key, value := range res.Header {
268+
responseHeader[key] = value
269+
}
270+
271+
return nil
272+
}

request_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,25 @@ func TestDoSuccessful(t *testing.T) {
8585
assert.Equal(t, "someValueOut", result.ResponseValue)
8686
})
8787

88+
t.Run("with response headers", func(t *testing.T) {
89+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90+
w.Header().Set("SomeHeader1", "SomeHeaderValue1")
91+
w.Header().Add("SomeHeader2", "SomeHeaderValue2")
92+
}))
93+
defer ts.Close()
94+
95+
params := Params{
96+
URL: ts.URL,
97+
}
98+
99+
responseHeaders := http.Header{}
100+
err := Do(params, nil, responseHeaders)
101+
assert.NoError(t, err)
102+
assert.Len(t, responseHeaders, 4) // 2 custom headers + ContentLength + Date
103+
assert.Equal(t, "SomeHeaderValue1", responseHeaders.Get("SomeHeader1"))
104+
assert.Equal(t, "SomeHeaderValue2", responseHeaders.Get("SomeHeader2"))
105+
})
106+
88107
t.Run("map as request and response", func(t *testing.T) {
89108
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90109
body, _ := ioutil.ReadAll(r.Body)

0 commit comments

Comments
 (0)