Skip to content

ResetBody HTTP request body and GetBody same object,is not the http specification #5343

Closed as not planned
@NameHaibinZhang

Description

@NameHaibinZhang

Describe the bug

func (r *Request) ResetBody() {
body, err := r.getNextRequestBody()
if err != nil {
r.Error = awserr.New(ErrCodeSerialization,
"failed to reset request body", err)
return
}

r.HTTPRequest.Body = body
r.HTTPRequest.GetBody = r.getNextRequestBody

}

why set http requet body and GetBody same object,is not the http request GetBody specification

// GetBody defines an optional func to return a new copy of
// Body. It is used for client requests when a redirect requires
// reading the body more than once. Use of GetBody still
// requires setting Body.
//
// For server requests, it is unused.
GetBody func() (io.ReadCloser, error)

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

GetBody Can Read repeatedly

Current Behavior

requestBody, err := req.HTTPRequest.GetBody()
if err != nil {

}
defer requestBody.Close()
requestData, err := io.ReadAll(requestBody)
if err != nil {

}

read the GetBody,the http body buf will to be nil

Reproduction Steps

func TestRequest_FollowPUTRedirects(t *testing.T) {
const bodySize = 9

redirectHit := 0
endpointHit := 0

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/redirect-me":
		u := *r.URL
		u.Path = "/endpoint"
		w.Header().Set("Location", u.String())
		fmt.Println(r.ContentLength)
		w.WriteHeader(307)
		redirectHit++
	case "/endpoint":
		fmt.Println("xxxxx")
		b := bytes.Buffer{}
		io.Copy(&b, r.Body)
		r.Body.Close()
		fmt.Println("body size", b.Len())
		if e, a := bodySize, b.Len(); e != a {
			t.Fatalf("expect %d body size, got %d", e, a)
		}
		endpointHit++
	default:
		t.Fatalf("unexpected endpoint used, %q", r.URL.String())
	}
}))
defer server.Close()

svc := awstesting.NewClient(&aws.Config{
	Region:     unit.Session.Config.Region,
	DisableSSL: aws.Bool(true),
	Endpoint:   aws.String(server.URL),
})

req := svc.NewRequest(&request.Operation{
	Name:       "Operation",
	HTTPMethod: "PUT",
	HTTPPath:   "/endpoint",
}, &struct{}{}, &struct{}{})
var xx = "111111111"
req.HTTPRequest.ContentLength = int64(len(xx))
req.SetReaderBody(bytes.NewReader([]byte(xx)))

requestBody, err := req.HTTPRequest.GetBody()
if err != nil {

}
defer requestBody.Close()
requestData, err := io.ReadAll(requestBody)
if err != nil {

}

fmt.Println("request data", string(requestData))

/*requestBody1, err := req.HTTPRequest.GetBody()
if err != nil {

}
defer requestBody1.Close()
requestData1, err := io.ReadAll(requestBody1)
if err != nil {

}

fmt.Println("request data1", string(requestData1))*/
fmt.Println(req.HTTPRequest.ContentLength)
err = req.Send()
if err != nil {
	t.Errorf("expect no error, got %v", err)
}
/*if e, a := 1, redirectHit; e != a {
	t.Errorf("expect %d redirect hits, got %d", e, a)
}*/
if e, a := 1, endpointHit; e != a {
	t.Errorf("expect %d endpoint hits, got %d", e, a)
}

}

can test this function

Possible Solution

No response

Additional Information/Context

No response

SDK version used

main

Environment details (Version of Go (go version)? OS name and version, etc.)

1.18

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions