Closed
Description
Since Go 1 (1.0), there has been this line in transfer.go:
https://github.com/golang/go/blob/release-branch.go1/src/pkg/net/http/transfer.go
if rr.ContentLength != 0 && rr.Body == nil {
return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
}
Which causes a Request.Write of a Request with a nil Body and non-zero length to fail.
But the Transport accepts that, and makes a nil Body imply a ContentLength of 0.
This program should probably have the same output:
package main
import (
"bytes"
"log"
"net/http"
"net/http/httputil"
)
func main() {
req, _ := http.NewRequest("GET", "http://foo.com/", nil)
req.Body = nil
req.ContentLength = -1
// Using Request.Write
var writeBuf bytes.Buffer
if err := req.Write(&writeBuf); err != nil {
log.Printf("Request.Write = %v", err)
} else {
log.Printf("Request.Write = %s", writeBuf.Bytes())
}
// Using Transport (DumpRequestOut uses Transport)
dump, err := httputil.DumpRequestOut(req, true)
if err != nil {
log.Printf("Dump = %v", err)
} else {
log.Printf("Dump = %s", dump)
}
}
But it says:
2016/11/30 18:36:14 Request.Write = http: Request.ContentLength=-1 with nil Body
2016/11/30 18:36:14 Dump = GET / HTTP/1.1
Host: foo.com
User-Agent: Go-http-client/1.1
Transfer-Encoding: chunked
Accept-Encoding: gzip
For Go tip, Go 1.7, Go 1.6, etc.
Decide whether this is okay or we should fix.