Re: Can servers generate responses to malformed requests in h2?

On Mon, Sep 25, 2023, at 13:33, Glenn Strauss wrote:
> My understanding is that I could treat all HTTP request header errors
> received as HTTP/2 requests as h2 stream error PROTOCOL_ERROR.  If that
> is what is desired by the RFC authors, please issue an update or errata
> and I'll change that code in lighttpd.

That was never really the intent.  The goal of HTTP/2 was to limit stream errors to those cases where errors are found in HTTP/2-specific stuff (frame format and ordering mainly).

This encroaches into "headers" in only two ways: pseudo-fields and Content-Length.  Control data and length delimiting are functions in HTTP/1.1 that are not so cleanly separate from the rest of the protocol.  Those are considered part of HTTP/2 proper and not HTTP in general.

For Content-Length in particular, we originally decided that this was necessary because of the way in which the length of requests and responses was a function that HTTP/2 provided and we wanted to ensure that there was no way for a Content-Length field to create an alternative narrative.  The believe was that that could be used for request-smuggling in some cases.

So our response was to make these stream errors.  Perhaps we should have allowed either type of error in the case of Content-Length, but that was the decision at the time.

> However, I currently am unable to understand why h2 PROTOCOL_ERROR
> (or H3_GENERAL_PROTOCOL_ERROR) is somehow better than 400 Bad Request.

I think that your "another reason" below might point to why this is preferable.  A client that makes a request via a proxy that upgrades it to HTTP/2 or HTTP/3 is not responsible for errors that arise in translation to the target request format, so it is in no position to correct that error.  The error is something that the proxy caused and so the proxy needs to handle it.

Maybe that's no real help to a client who is dealing with a busted proxy and who is presented with a request that times out or whatever the proxy does in that case.  But it's about ensuring that the error is appropriately targeted.  If the proxy isn't implementing the protocol properly, then the developers of that proxy really do need to pay attention.  Protocol errors like this should not occur during normal operation.

Yes, PROTOCOL_ERROR isn't exactly the nicest error (which is partly why closing the connection might be preferable, because you get to include a reason phrase), but that only suggests that we might want to explore ways of making errors clearer or more actionable.

> I can see where h2 specification around pseudo-headers is specific to
> the h2 protocol.  However, an implementation "could" HPACK-decode the
> entire HEADERS frame into a single string that looks almost identical
> to HTTP/1.1 request headers with the exception of the addition of
> pseudo-headers.  It could then be loosely parsed as HTTP/1.x request
> headers.  

If you are rewriting HTTP/2 into HTTP/1.x, you need all the pseudo-fields in order to make sense of the message.  If one is missing, then your converter can generate an error (which you can send as a stream error).  Same if a pseudo-field arrives late.

> An implementation might need to fully parse the HEADERS frame
> before being able to determine that a required pseudo-header is missing.
> If it has already gotten this far parsing the HTTP request, why should
> the RFC disallow the implementation from returning an HTTP error code?

The specification requires that pseudo-fields precede real fields, so this is not really an option.

Received on Monday, 25 September 2023 05:58:31 UTC