Skip to content

Commit

Permalink
fix: get body size 0 when the http status code is 307 or 308 (go-rest…
Browse files Browse the repository at this point in the history
  • Loading branch information
shiguangyin committed Nov 1, 2020
1 parent 9e4ce7a commit 0de0d7e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 20 deletions.
1 change: 1 addition & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ var (
hdrContentLengthKey = http.CanonicalHeaderKey("Content-Length")
hdrContentEncodingKey = http.CanonicalHeaderKey("Content-Encoding")
hdrAuthorizationKey = http.CanonicalHeaderKey("Authorization")
hdrLocationKey = http.CanonicalHeaderKey("Location")

plainTextType = "text/plain; charset=utf-8"
jsonContentType = "application/json"
Expand Down
51 changes: 31 additions & 20 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,29 +206,16 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
r.RawRequest = r.RawRequest.WithContext(r.ctx)
}

bodyCopy, err := getBodyCopy(r)
if err != nil {
return err
}

// assign get body func for the underlying raw request instance
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
// If r.bodyBuf present, return the copy
if r.bodyBuf != nil {
return ioutil.NopCloser(bytes.NewReader(r.bodyBuf.Bytes())), nil
}

// Maybe body is `io.Reader`.
// Note: Resty user have to watchout for large body size of `io.Reader`
if r.RawRequest.Body != nil {
b, err := ioutil.ReadAll(r.RawRequest.Body)
if err != nil {
return nil, err
}

// Restore the Body
closeq(r.RawRequest.Body)
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))

// Return the Body bytes
return ioutil.NopCloser(bytes.NewBuffer(b)), nil
if bodyCopy != nil {
return ioutil.NopCloser(bytes.NewReader(bodyCopy.Bytes())), nil
}

return nil, nil
}

Expand Down Expand Up @@ -530,3 +517,27 @@ func saveResponseIntoFile(c *Client, res *Response) error {

return nil
}

func getBodyCopy(r *Request) (*bytes.Buffer, error) {
// If r.bodyBuf present, return the copy
if r.bodyBuf != nil {
return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
}

// Maybe body is `io.Reader`.
// Note: Resty user have to watchout for large body size of `io.Reader`
if r.RawRequest.Body != nil {
b, err := ioutil.ReadAll(r.RawRequest.Body)
if err != nil {
return nil, err
}

// Restore the Body
closeq(r.RawRequest.Body)
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))

// Return the Body bytes
return bytes.NewBuffer(b), nil
}
return nil, nil
}
34 changes: 34 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1807,3 +1807,37 @@ func TestDebugLoggerRequestBodyTooLarge(t *testing.T) {
assertNotNil(t, resp)
assertEqual(t, true, strings.Contains(output.String(), "REQUEST TOO LARGE"))
}

func TestPostMapTemporaryRedirect(t *testing.T) {
ts := createPostServer(t)
defer ts.Close()

c := dc()
resp, err := c.R().SetBody(map[string]string{"username":"testuser", "password": "testpass"}).
Post(ts.URL + "/redirect")

assertNil(t, err)
assertNotNil(t, resp)
assertEqual(t, http.StatusOK, resp.StatusCode())
}

type brokenReadCloser struct{}

func (b brokenReadCloser) Read(p []byte) (n int, err error) {
return 0, errors.New("read error")
}

func (b brokenReadCloser) Close() error {
return nil
}

func TestPostBodyError(t *testing.T) {
ts := createPostServer(t)
defer ts.Close()

c := dc()
resp, err := c.R().SetBody(brokenReadCloser{}).Post(ts.URL + "/redirect")
assertNotNil(t, err)
assertEqual(t, "read error", err.Error())
assertNil(t, resp)
}
3 changes: 3 additions & 0 deletions resty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ func createPostServer(t *testing.T) *httptest.Server {

return
}
} else if r.URL.Path == "/redirect" {
w.Header().Set(hdrLocationKey, "/login")
w.WriteHeader(http.StatusTemporaryRedirect)
}
}
})
Expand Down

0 comments on commit 0de0d7e

Please sign in to comment.