From 550df2a38aa62a980a73f8bda447dd52833cd5d3 Mon Sep 17 00:00:00 2001 From: Geoff Greer Date: Wed, 28 Feb 2024 15:14:24 -0800 Subject: [PATCH] Send the headers and body to option functions. This lets us avoid dealing with creating a reader every time we call an option function. --- pkg/uhttp/wrapper.go | 21 +++++++++++++++------ pkg/uhttp/wrapper_test.go | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/pkg/uhttp/wrapper.go b/pkg/uhttp/wrapper.go index a1fcd715..cae3ff18 100644 --- a/pkg/uhttp/wrapper.go +++ b/pkg/uhttp/wrapper.go @@ -20,7 +20,7 @@ type ( HttpClient *http.Client } - DoOption func(*http.Response) error + DoOption func(*http.Header, []byte) error RequestOption func() (io.ReadWriter, map[string]string, error) ) @@ -31,9 +31,8 @@ func NewBaseHttpClient(httpClient *http.Client) *BaseHttpClient { } func WithJSONResponse(response interface{}) DoOption { - return func(resp *http.Response) error { - defer resp.Body.Close() - return json.NewDecoder(resp.Body).Decode(response) + return func(resp *http.Header, body []byte) error { + return json.Unmarshal(body, response) } } @@ -43,10 +42,20 @@ func (c *BaseHttpClient) Do(req *http.Request, options ...DoOption) (*http.Respo return nil, err } - defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + err = resp.Body.Close() + if err != nil { + return nil, err + } + + // Replace resp.Body with a no-op closer so nobody has to worry about closing the reader. + resp.Body = io.NopCloser(bytes.NewBuffer(body)) for _, option := range options { - err = option(resp) + err = option(&resp.Header, body) if err != nil { return nil, err } diff --git a/pkg/uhttp/wrapper_test.go b/pkg/uhttp/wrapper_test.go index cd722bb9..b5af7569 100644 --- a/pkg/uhttp/wrapper_test.go +++ b/pkg/uhttp/wrapper_test.go @@ -79,7 +79,7 @@ func TestWrapper_WithJSONResponse(t *testing.T) { responseBody := example{} option := WithJSONResponse(&responseBody) - err = option(&resp) + err = option(&resp.Header, exampleResponseBuffer.Bytes()) require.Nil(t, err) require.Equal(t, exampleResponse, responseBody)