- From: Willy Tarreau <w@1wt.eu>
- Date: Sat, 24 Oct 2020 08:16:22 +0200
- To: Mark Nottingham <mnot@mnot.net>
- Cc: HTTP Working Group <ietf-http-wg@w3.org>
Hi Mark, On Sat, Oct 24, 2020 at 01:07:19PM +1100, Mark Nottingham wrote: > My .02 - > > 204/304/1xx and head responses are defined by HTTP's core semantics to not have a body. > > HTTP/1 enforced those in the framing mechanism (if you didn't, you lost framing reliability and Bad Things happened). > > HTTP/2 doesn't explicitly enforce them, which means that we're now in similar territory to "Can GET have a request body?" ... and we've all seen how much angst that causes. > > Whether or not you should strip them, generate an error, or just pass them > through depends on what you're doing. In general, HTTP wants implementations > that don't have to "know" the whole protocol, to allow extensions to be > deployed successfully, and to allow simpler implementations to succeed. So > while HTTP/1 requires that implementations understand these situations to > maintain framing, I think it's reasonable to not have that requirement (and > we don't) in HTTP/2, because framing doesn't depend upon it. > > That doesn't mean that putting a response body on a 304 or HEAD response is > interoperable or a good thing to do; it just means that you're not obligated > to refuse that message -- and we should be super crisp in http-core about > what this means. That's exactly the difficulty. We know that responses to HEAD containing body were quite frequent due to error pages. Typically a hard-coded 403 or 500 returned directly based on the URI or due to a server malfunction would not even check the method. But I think that it's getting tricky for intermediaries, as they want to have the smallest possible impact on the existing infrastructure, thus if possible not add errors on top of existing errors. Also they have a greater responsibility here, for example when translating H1 requests to H2: if an H2 response contains a body where it's not supposed to, it must in no way be serialized to H1. So this is what makes me think that the "cleanup" if any should be enforced at the semantic layer, and that the messaging layers should only produce errors if the unexpected situation would break the protocol. In haproxy's case, this would mean always passing headers of 204/304/HEAD responses to a client, and silently dropping any body for H2 or breaking the server-side connection for H1 if a body appears there. For H2 remains the case of trailers. My view on this (possibly skewed by H1) is that trailers extend the body and must not be delivered when no body is expected. In H1 there's no doubt about it since it was explicitly stated that bodyless responses end after the "first empty line" and "regardless of headers" which means that T-E is ignored and that there's no way to append trailers. But in H2 they can be used to trivially deliver an operational status and I can understand how some implementations would prefer to always send their status in a trailer rather than in a header. This could result in HEAD/204/304 to contain trailers. And I'm even wondering if gRPC doesn't do that with their "grpc-status" trailer. Thus I suspect that for now we'll stick to strict semantics by trimming any received body but possibly appending trailers for H2. We may revisit this later if that causes trouble :-/ Thanks! Willy
Received on Saturday, 24 October 2020 06:16:41 UTC