- From: Willy Tarreau <w@1wt.eu>
- Date: Fri, 17 Jun 2022 06:53:30 +0200
- To: Martin Thomson <mt@lowentropy.net>
- Cc: ietf-http-wg@w3.org, Amaury Denoyelle <adenoyelle@haproxy.com>
Hi Martin! On Fri, Jun 17, 2022 at 10:00:50AM +1000, Martin Thomson wrote: > David's approach is the ideal one, but there are others that trade some > downsides for performance. Probably, but I'm still seeing it as a workaround. I mean, since HTTP/1.0 we've been used to know when receiving a full headers block the entire list of the header fields. And it looks like with H3 the headers block is uncertain at the end of a HEADERS frame. I'm a bit concerned about long-term impacts, especially when the ambiguity affects the presence or absence of a body. The risk that we start to see intermediaries pass the header block as-is to HTTP/1, followed by the contents of subsequent DATA frames is non-negligible, and that would create new request smuggling attacks. Conversely, requiring to wait (even a bit) risks to encourage bad behaviors such as clients sending the FIN very late, which brings slowloris back. I think that this situation is not good at all for interoperability and that we should at least pass the word about it to encourage implementations to signal that they know there is no data following the HEADERS frame. I suspect we should really file an errata proposing to add something like the following, at least to make sure implementations are aware of this problem: A sender which knows that no data follows the headers block SHOULD signal the end of the message by setting the FIN bit along with the HEADERS frame. A receiver that processes a HEADERS frame without seeing a FIN bit MAY expect more data to follow regardless of the HTTP method used. From what Amaury told me, in the interop tests, all client implementations but two already proceed like this, which is not surprising since content producers normally know whether or not they're willing to pass a body, and gateways from other HTTP versions already have the information available. Thus I think it would still be better to limit the risk of proliferation of an ambiguous behavior. > It is also possible to generate a response to an incomplete request if you > are confident that anything that might follow won't change the response. > (That's generally true for any HTTP request.) In this case, you have a > complete header block and it is a GET request. Though you might get content, > you probably won't. Deciding to serve the answer isn't likely to cause > problems. It's a tiny gamble, but one with modest costs: if you do get > content, then you committed to ignoring it rather than generating an error. > You might be able to use RESET_STREAM if you care about signaling an error > and the response hasn't already been delivered. The real loss there is that > you can't signal at the HTTP layer. Sure but while you can often do this when you're a server, you practically can't when you're a gateway, because that would require to adjust the behavior per-URI. Not only it's a real problem in terms of deployments (think about an edge load-balancer deployed in front of a massive hosting infrastructure with tens of thousands of hosted clients who would find it surprising that the hosting company requires them to declare all of their content-aware URIs), but sometimes it will not even be applicable due a chicken-and-egg problem by which you need a complete headers block to start to process HTTP and apply processing rules, and you'll need to do that to decide that the headers block is complete. Thanks! Willy
Received on Friday, 17 June 2022 04:54:07 UTC