Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: fix mishandling of POST/PUT requests with empty body, causing net/http to send request without a Content-Length header #194

Merged
merged 1 commit into from
Jun 6, 2023

Conversation

manicminer
Copy link
Contributor

@manicminer manicminer commented May 5, 2023

This PR addresses a mishandling of POST and PUT requests having an empty body.

In a few places within net/http, in order to determine whether the request has a body or not, Request.Body which is an io.ReadCloser, does not have its Read() method called but is instead simply nil checked or compared to the http.NoBody value - so even if its Read() method returns 0, io.EOF, it's still considered to represent a nonempty request body.

// NoBody is an io.ReadCloser with no bytes. Read always returns EOF
// and Close always returns nil. It can be used in an outgoing client
// request to explicitly signal that a request has zero bytes.
// An alternative, however, is to simply set Request.Body to nil.
var NoBody = noBody{}

type noBody struct{}

func (noBody) Read([]byte) (int, error)         { return 0, io.EOF }
func (noBody) Close() error                     { return nil }
func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }

(Note this docstring also suggests that you should set Request.Body to nil or http.NoBody)

For HTTP/1.1, even when the request body is an io.ReadCloser with a zero length buffer, the resulting request on the wire then contains neither a Content-Length nor a Transfer-Encoding header and is therefore invalid (incurring a 411 response from a compliant server).

For HTTP/2.0, the http.http2actualContentLength() function, if it isn't specifically http.NoBody, the Content-Length is incorrectly discarded instead of being set to zero, which has the same effect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants