1
0
mirror of https://github.com/golang/go synced 2024-11-26 07:47:57 -07:00

net/http: document and test Client.Post treating Reader body as ReadCloser

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/11542044
This commit is contained in:
Brad Fitzpatrick 2013-07-19 12:02:54 +10:00
parent bc31bcccd3
commit b2b15d1230
2 changed files with 42 additions and 2 deletions

View File

@ -74,8 +74,8 @@ type RoundTripper interface {
// authentication, or cookies.
//
// RoundTrip should not modify the request, except for
// consuming the Body. The request's URL and Header fields
// are guaranteed to be initialized.
// consuming and closing the Body. The request's URL and
// Header fields are guaranteed to be initialized.
RoundTrip(*Request) (*Response, error)
}
@ -346,6 +346,9 @@ func Post(url string, bodyType string, body io.Reader) (resp *Response, err erro
// Post issues a POST to the specified URL.
//
// Caller should close resp.Body when done reading from it.
//
// If the provided body is also an io.Closer, it is closed after the
// body is successfully written to the server.
func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
req, err := NewRequest("POST", url, body)
if err != nil {

View File

@ -15,6 +15,7 @@ import (
"io"
"io/ioutil"
"net"
"net/http"
. "net/http"
"net/http/httptest"
"net/url"
@ -1610,6 +1611,42 @@ func TestIdleConnChannelLeak(t *testing.T) {
}
}
// Verify the status quo: that the Client.Post function coerces its
// body into a ReadCloser if it's a Closer, and that the Transport
// then closes it.
func TestTransportClosesRequestBody(t *testing.T) {
defer afterTest(t)
ts := httptest.NewServer(http.HandlerFunc(func(w ResponseWriter, r *Request) {
io.Copy(ioutil.Discard, r.Body)
}))
defer ts.Close()
tr := &Transport{}
defer tr.CloseIdleConnections()
cl := &Client{Transport: tr}
closes := 0
res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
if err != nil {
t.Fatal(err)
}
res.Body.Close()
if closes != 1 {
t.Errorf("closes = %d; want 1", closes)
}
}
type countCloseReader struct {
n *int
io.Reader
}
func (cr countCloseReader) Close() error {
(*cr.n)++
return nil
}
// rgz is a gzip quine that uncompresses to itself.
var rgz = []byte{
0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,