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
net/http: NewRequest panics if body is typed nil #32897
Comments
This is not a bug. You're passing a non-nil io.Reader to NewRequest. The latter thus expects to be able to call its methods. It is perfectly possible to implement io.Reader using a nil pointer. NewRequest cannot return an error for this case. See the following as an example (adjusted from your code): Also see the relevant FAQ entry: |
It is definitely possible to implement an io.Reader using a nil pointer. To clarify my intention with this bug: if I pass in a nil
The block is explicitly checking that I think that the following modifications should correct the behaviour which is incorrect (at least, in my opinion) without preventing the use of custom io.Reader implementations that use nil pointers:
TL;DR for my modifications above: in each of the non-default cases wrap the existing code in a I quickly tested this behaviour (playground: https://play.golang.org/p/lKp_LtwlTWC) and it seems to behave as I expected. |
The primary point of the existing nil check is to discover whether the (optional) request body was provided. If the body argument wasn't optional, there would be no use for that check. What's the use case for passing a non-nil io.Reader containing a nil *bytes.Buffer to NewRequest? This most likely signals a bug in the calling code. The proposed changes to NewRequest would just cover it up. The code in question should panic. edit: don't get too hung up on those special cases. For the sake of this discussion, they can be ignored entirely, I think. A nil *bytes.Buffer is going to panic at the first invocation of its Read method. It is thus not a useful thing to pass around as an io.Reader. NewRequest shouldn't be in the business of trying to predict whether the provided interface value really implements the io.Reader contract. It should just call the Read method. |
The use case is if you have a function that uses NewRequest and also accepts an optional "body" parameter. Currently, the wrapper function needs to explicitly check that it was passed a nil and then explicitly pass an untyped nil instead of just always passing along the argument that was passed in. Snippet illustrating what I mean: https://play.golang.org/p/LA9YJ6nTatq The proposal @bcmills linked has some changes to the language which would improve this, but it looks like there won't be much action on it until Go 2. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yep. Go Playground link: https://play.golang.org/p/UuBFg4Z31NY
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Passing a nil as a function argument and then passing that argument into
http.NewRequest
as thebody
parameter (3rd parameter), causeshttp.NewRequest
to panic.https://play.golang.org/p/UuBFg4Z31NY
What did you expect to see?
A new
*http.Request
with an empty body and no error are returned OR a nil pointer and a non-nil error are returned. There should not be a panic.What did you see instead?
http.NewRequest
panics due to a nil pointer dereference.The text was updated successfully, but these errors were encountered: