1
0
mirror of https://github.com/golang/go synced 2024-11-12 05:30:21 -07:00

net/http: Request Body error should not be ignored.

Fixes #7521.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/76320043
This commit is contained in:
Luka Zakrajšek 2014-03-17 15:52:52 -07:00 committed by Brad Fitzpatrick
parent fba1dfc6f0
commit 2701dadbac
2 changed files with 53 additions and 2 deletions

View File

@ -310,6 +310,46 @@ var reqWriteTests = []reqWriteTest{
WantError: errors.New("http: Request.ContentLength=5 with nil Body"), WantError: errors.New("http: Request.ContentLength=5 with nil Body"),
}, },
// Request with a 0 ContentLength and a body with 1 byte content and an error.
{
Req: Request{
Method: "POST",
URL: mustParseURL("/"),
Host: "example.com",
ProtoMajor: 1,
ProtoMinor: 1,
ContentLength: 0, // as if unset by user
},
Body: func() io.ReadCloser {
err := errors.New("Custom reader error")
errReader := &errorReader{err}
return ioutil.NopCloser(io.MultiReader(strings.NewReader("x"), errReader))
},
WantError: errors.New("Custom reader error"),
},
// Request with a 0 ContentLength and a body without content and an error.
{
Req: Request{
Method: "POST",
URL: mustParseURL("/"),
Host: "example.com",
ProtoMajor: 1,
ProtoMinor: 1,
ContentLength: 0, // as if unset by user
},
Body: func() io.ReadCloser {
err := errors.New("Custom reader error")
errReader := &errorReader{err}
return ioutil.NopCloser(errReader)
},
WantError: errors.New("Custom reader error"),
},
// Verify that DumpRequest preserves the HTTP version number, doesn't add a Host, // Verify that DumpRequest preserves the HTTP version number, doesn't add a Host,
// and doesn't add a User-Agent. // and doesn't add a User-Agent.
{ {

View File

@ -17,6 +17,14 @@ import (
"sync" "sync"
) )
type errorReader struct {
err error
}
func (r *errorReader) Read(p []byte) (n int, err error) {
return 0, r.err
}
// transferWriter inspects the fields of a user-supplied Request or Response, // transferWriter inspects the fields of a user-supplied Request or Response,
// sanitizes them without changing the user object and provides methods for // sanitizes them without changing the user object and provides methods for
// writing the respective header, body and trailer in wire format. // writing the respective header, body and trailer in wire format.
@ -53,8 +61,11 @@ func newTransferWriter(r interface{}) (t *transferWriter, err error) {
if t.ContentLength == 0 { if t.ContentLength == 0 {
// Test to see if it's actually zero or just unset. // Test to see if it's actually zero or just unset.
var buf [1]byte var buf [1]byte
n, _ := io.ReadFull(t.Body, buf[:]) n, rerr := io.ReadFull(t.Body, buf[:])
if n == 1 { if rerr != nil && rerr != io.EOF {
t.ContentLength = -1
t.Body = &errorReader{rerr}
} else if n == 1 {
// Oh, guess there is data in this Body Reader after all. // Oh, guess there is data in this Body Reader after all.
// The ContentLength field just wasn't set. // The ContentLength field just wasn't set.
// Stich the Body back together again, re-attaching our // Stich the Body back together again, re-attaching our