Skip to content

Commit

Permalink
aws/request: Fix for Go 1.8 request incorrectly sent with body
Browse files Browse the repository at this point in the history
Go 1.8 tightened and clarified the rules code needs to use when building
requests with the http package. Go 1.8 removed the automatic detection
of if the Request.Body was empty, or actually had bytes in it. The SDK
always sets the Request.Body even if it is empty and should not actually
be sent. This is incorrect.

Go 1.8 did add a http.NoBody value that the SDK can use to tell the http
client that the request really should be sent without a body. The
Request.Body cannot be set to nil, which is preferable, because the
field is exported and could introduce nil pointer dereferences for users
of the SDK if they used that field.

Related golang/go#18257

Fix aws#984
  • Loading branch information
jasdel committed Dec 9, 2016
1 parent 6545347 commit e66ba2a
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 2 deletions.
7 changes: 5 additions & 2 deletions aws/request/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,11 @@ func (r *Request) ResetBody() {
r.safeBody.Close()
}

r.safeBody = newOffsetReader(r.Body, r.BodyStart)
r.HTTPRequest.Body = r.safeBody
// Resets the body with the offset reader. For Go +1.8 the
// body is only wrapped if it is no empty. Otherwise the
// http.NoBody value will be written to the http.Request.Body
// field.
resetBody(r)
}

// GetBody will return an io.ReadSeeker of the Request's underlying
Expand Down
22 changes: 22 additions & 0 deletions aws/request/request_resetbody.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// +build go1.8

package request

import (
"io"
"net/http"
)

func resetBody(r *Request) {
curOffset, _ := r.Body.Seek(0, io.SeekCurrent)
endOffset, _ := r.Body.Seek(0, io.SeekEnd)
r.Body.Seek(r.BodyStart, io.SeekStart)

r.safeBody = newOffsetReader(r.Body, r.BodyStart)

if endOffset-curOffset == 0 {
r.HTTPRequest.Body = http.NoBody
} else {
r.HTTPRequest.Body = r.safeBody
}
}
8 changes: 8 additions & 0 deletions aws/request/request_resetbody_1.7.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// +build !go1.8

package request

func resetBody(r *Request) {
r.safeBody = newOffsetReader(r.Body, r.BodyStart)
r.HTTPRequest.Body = r.safeBody
}
41 changes: 41 additions & 0 deletions aws/request/request_resetbody_1.7_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// +build !go1.8

package request

import (
"net/http"
"strings"
"testing"
)

func TestResetBody_WithBodyContents(t *testing.T) {
r := Request{
HTTPRequest: &http.Request{},
}

reader := strings.NewReader("abc")
r.Body = reader

r.ResetBody()

if v, ok := r.HTTPRequest.Body.(*offsetReader); !ok || v == nil {
t.Errorf("expected request body to be set to reader, got %#v",
r.HTTPRequest.Body)
}
}

func TestResetBody_WithEmptyBody(t *testing.T) {
r := Request{
HTTPRequest: &http.Request{},
}

reader := strings.NewReader("")
r.Body = reader

r.ResetBody()

if v, ok := r.HTTPRequest.Body.(*offsetReader); !ok || v == nil {
t.Errorf("expected request body to be set to reader, got %#v",
r.HTTPRequest.Body)
}
}
41 changes: 41 additions & 0 deletions aws/request/request_resetbody_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// +build go1.8

package request

import (
"net/http"
"strings"
"testing"
)

func TestResetBody_WithBodyContents(t *testing.T) {
r := Request{
HTTPRequest: &http.Request{},
}

reader := strings.NewReader("abc")
r.Body = reader

r.ResetBody()

if v, ok := r.HTTPRequest.Body.(*offsetReader); !ok || v == nil {
t.Errorf("expected request body to be set to reader, got %#v",
r.HTTPRequest.Body)
}
}

func TestResetBody_WithEmptyBody(t *testing.T) {
r := Request{
HTTPRequest: &http.Request{},
}

reader := strings.NewReader("")
r.Body = reader

r.ResetBody()

if a, e := r.HTTPRequest.Body, http.NoBody; a != e {
t.Errorf("expected request body to be set to reader, got %#v",
r.HTTPRequest.Body)
}
}

0 comments on commit e66ba2a

Please sign in to comment.