Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
net/http: allow user-defined behaviour on malformed HTTP requests #25116
The net/http HTTP server handles certain malformed HTTP requests completely autonomously, without ever passing control to non-library code. This means that the application is never made aware of them, so it cannot take any action, e.g. logging that a malformed request was received. It also prevents the application from customising the response.
For example, running a minimal Go HTTP server at localhost:8000 and doing this:
(The error is caused by the whitespace in the first line of the request - the parser naively splits it on space and expects [method, URI, protocol]).
This is a problem because:
I propose adding an exported variable of type
to http.Server. It can be set by the application before ListenAndServe or ListenAndServeTLS is called. If this is nil (the default), the current behaviour stays. If it is not nil, then it is called (with the error, responseWriter and, optionally, a byte slice containing the offending part of the request - or even all of it?) when the server encounters a malformed request which it cannot pass on to the handler.
Related bug: #14952 (net/http: add switches to accept/send bogus HTTP?)
I think I'd be fine adding in some HTTP1-specific hook for malformed requests, but I don't think I'd want to involve ResponseWriter at all. I'd prefer to just provide the
Regarding the signature, the idea is that control is passed to the application to do whatever it wants. It might just discard the byte (if, as you say, it just doesn't know what to do with a malformed request), but why not let the application decide whether the request is so broken it can't be dealt with? For example, in the "literal space in the URL" example I gave originally, it's conceivable that application code could in fact rescue the request.
I can't comment on how this would interact with HTTP/2 because I don't know enough (i.e. anything, really) about HTTP/2.
Maybe, but you won't be able to pass it back to
Yes, that's what I had in mind - when a malformed request comes in, the hook gets called and from then on it's up to the application to handle it entirely - if it wants to rescue the request it has to do all the header parsing and so on by itself.
I expect the real-life use cases would simply be to respond with a 400 Bad Request, but in a more customisable way than literally putting "400 Bad Request" on the wire. Also logging.