Re: Ambiguity on HTTP/3 HEADERS and QUIC STREAM FIN requirement

Martin Thomson <> Fri, 17 June 2022 00:04 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id BF773C157B59 for <>; Thu, 16 Jun 2022 17:04:42 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.761
X-Spam-Status: No, score=-2.761 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, MAILING_LIST_MULTI=-1, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key) header.b=Lnyeu/mZ; dkim=pass (2048-bit key) header.b=mHIb2yBc
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id ZVAgnGuRuNqi for <>; Thu, 16 Jun 2022 17:04:38 -0700 (PDT)
Received: from ( []) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by (Postfix) with ESMTPS id 194CFC14CF18 for <>; Thu, 16 Jun 2022 17:04:37 -0700 (PDT)
Received: from lists by with local (Exim 4.92) (envelope-from <>) id 1o1zQS-0001ns-RF for; Fri, 17 Jun 2022 00:01:24 +0000
Resent-Date: Fri, 17 Jun 2022 00:01:24 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from <>) id 1o1zQQ-0001lN-Ua for; Fri, 17 Jun 2022 00:01:22 +0000
Received: from ([]) by with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from <>) id 1o1zQP-0008Mv-3e for; Fri, 17 Jun 2022 00:01:22 +0000
Received: from compute3.internal (compute3.nyi.internal []) by mailout.west.internal (Postfix) with ESMTP id 1048C32007E8 for <>; Thu, 16 Jun 2022 20:01:07 -0400 (EDT)
Received: from imap41 ([]) by compute3.internal (MEProxy); Thu, 16 Jun 2022 20:01:08 -0400
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; h=cc:content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm3; t=1655424067; x=1655510467; bh=a26qdHscDG U0ONRAKiquH28ygHDrh+8qxg7PCSnN20A=; b=Lnyeu/mZzc6GgeNfx04zzcPSUQ rsLrWEmhOZqwCdzRF/0AlqaUnxMYGfO4cUh72+qN/IfMOJbMYbjZ+HHtfsmqlKk/ QeQxWN07fmIuBB7+G9er58e1trSplIHvblx4aD3e9DxzYD0AA5tDjLfIfQsWclHu 09KOv0wStVgDydHlyVobY6d+Z2fFpojzvUpfFcQh4N4a6DsIDBJF3B93palK7CVw sOCOFuV6yhw2rIpxuUElOQp7rRUYJuataWJsP/pp+Ks9EgneQuVwIv6FtrMnaRME fuNGwFYNuErJMBJt61mGgpypY3M+n+TRp2Sm20il9zd8jDQD1YVmV8yWz8Cw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=; h=cc:content-type:date:date:feedback-id :feedback-id:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:sender:subject:subject:to:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; t=1655424067; x=1655510467; bh=a26qdHscDGU0ONRAKiquH28ygHDr h+8qxg7PCSnN20A=; b=mHIb2yBcbY4vpiKjy8AME5dUGuId3ZVK8uhCcVHrf61P lbfokz2u4x83AvAq5jPp2dKhZikbbfKEfBJ2rhCdVoTRtGwzFx9ep2HFCkE5HrQD vC6IU74PKR0BDi/fmh2AP+BavfKAECIz171ZehhsBLvor48A6nUDLUwnB+TxTdTB rDZ/KfhZK+aSdyG3BtPUxP90DciJwsBIUNuO9Nh0d8aEm5v6+TCQV/HSBQakvSxl 9Re1SZd5sGwHlpvx2tVoBXNmLdqp7DD7Ojj4QNad5Fugo48gmXsOY1yrPlHbme2l 1op3ihaROVSf/9/oIbqHWGRR5e4zPIWpnPs5tD7Txg==
X-ME-Sender: <xms:Q8SrYq3BZBlxGMC_Nzlut7OYNUcDKKkLMxSLDTkpJ1OWMTpFCVyv1Q> <xme:Q8SrYtEAWi_iE-tuR5UAmuRHLsh12jrFMrSi1fn0VqS5_VNviNEIwy6fkYeYzgfNz j7Q-F2m0qXgYbZXR0w>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddvgedgvdejucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefofgggkfgjfhffhffvufgtsehttd ertderredtnecuhfhrohhmpedfofgrrhhtihhnucfvhhhomhhsohhnfdcuoehmtheslhho figvnhhtrhhophihrdhnvghtqeenucggtffrrghtthgvrhhnpeelteetteehtdejudduff duueffhfdukeefiefhtdeffefgffejueefjeekjeekveenucffohhmrghinhephhhtthhp rhgvqhhuvghsthdrihhnnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrg hilhhfrhhomhepmhhtsehlohifvghnthhrohhphidrnhgvth
X-ME-Proxy: <xmx:Q8SrYi53Gvy3KIkyLuukkPZ707rxmDEOFKgxjAZZE_C3Rf94XYSCsw> <xmx:Q8SrYr1-oyWYymhq69C-pgnDPiWMoR8BCb3xKfLwbP1jP7REBKHTww> <xmx:Q8SrYtGI-uJ2Q6hjg8ektRzvc1MqiDEvEqLwtZtJOvBaHHpq6qFH2A> <xmx:Q8SrYhTVmNfst1fU_yjY1caYvVqAjXEJjlRyTP1x_pDtbyebO3bwYA>
Feedback-ID: ic129442d:Fastmail
Received: by mailuser.nyi.internal (Postfix, from userid 501) id 565EB2340081; Thu, 16 Jun 2022 20:01:07 -0400 (EDT)
X-Mailer: Webmail Interface
User-Agent: Cyrus-JMAP/3.7.0-alpha0-712-gb9e94258b0-fm-20220610.001-gb9e94258
Mime-Version: 1.0
Message-Id: <>
In-Reply-To: <>
References: <YqsBZ0M4lDXGRQTo@miskatonic> <> <> <>
Date: Fri, 17 Jun 2022 10:00:50 +1000
From: Martin Thomson <>
Content-Type: text/plain
Received-SPF: pass client-ip=;;
X-W3C-Hub-DKIM-Status: validation passed: (, signature is good
X-W3C-Hub-DKIM-Status: validation passed: (, signature is good
X-W3C-Hub-Spam-Status: No, score=-6.8
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, W3C_AA=-1, W3C_DB=-1, W3C_IRA=-1, W3C_WL=-1
X-W3C-Scan-Sig: 1o1zQP-0008Mv-3e ed3f510038186a8826ef56cd79eca725
Subject: Re: Ambiguity on HTTP/3 HEADERS and QUIC STREAM FIN requirement
Archived-At: <>
X-Mailing-List: <> archive/latest/40137
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

David's approach is the ideal one, but there are others that trade some downsides for performance.

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.

All of the above is also true if you only have GET and a URI (which might need Host).  If you don't condition the response on the value of any header field, then you can answer before seeing them, the only risk being that you miss something that might have changed your answer.

On Fri, Jun 17, 2022, at 09:23, David Schinazi wrote:
> Such an intermediary would already need to buffer an incomplete request 
> (for example when it's received part of the HEADERS frame but not all 
> of it). Instead of deciding you've received the full GET request at the 
> end of the HEADERS frame, just decide you've received it when you've 
> received the QUIC FIN bit. That's what our implementation does. Note 
> however that this doesn't work with CONNECT so you'll want to make it 
> method-specific.
> David
> On Thu, Jun 16, 2022 at 3:26 PM Lucas Pardue <> wrote:
>> Hi Amaury,
>> + the HTTP WG list, since they now own HTTP/3 and in case there are folks over there not watching QUIC closely.
>> On Thu, Jun 16, 2022 at 11:23 PM Ryan Hamilton <> wrote:
>>> Instead of assuming chunked encoding in this case, an intermediary could delay sending the request until it either receives the QUIC FIN, or receives an HTTP/3 DATA frame, right? (Though admittedly, that is a potentially performance hit). Now that HTTP/3 is RFC 9114, I suspect it's too late to add new normative language.
>>> Cheers,
>>> Ryan
>>> On Thu, Jun 16, 2022 at 3:08 PM Amaury Denoyelle <> wrote:
>>>> Hello,
>>>> I have read HTTP/3 specification and I do not find any requirement on
>>>> setting the FIN bit of a QUIC STREAM frame which contains a H3 HEADERS
>>>> if the request does not have a body.
>>>> For me, it represents an ambiguity on the internal HTTP message
>>>> representation. If no content-length header is present, it could be
>>>> interpreted as equivalent to HTTP/1.1 chunked transfer encoding. This
>>>> ambiguity could be removed by requiring the STREAM FIN bit set for the
>>>> frame containing H3 HEADERS if no body is present. If instead it's
>>>> preferable to maintain a separation between HTTP/3 and QUIC, maybe a new
>>>> H3 internal mechanism could be implemented to signal the end of a stream
>>>> without a body.
>>>> I think this issue is particularly important for intermediaries, such as
>>>> haproxy. Currently, when receiving a H3 HEADERS frame from a client
>>>> without the underlying STREAM FIN bit set, we generate for the server a
>>>> HTTP/1.1 message with a chunked transfer encoding body. This is to
>>>> ensure that we do not discard any possible arriving H3 DATA frames
>>>> after. However, a lot of HTTP servers are stricter with the presence of
>>>> a body and will for example reject GET requests with a chunked transfer
>>>> encoding.
>>>> Please let me know your thoughts on the subject,
>>>> Regards,
>>>> -- 
>>>> Amaury Denoyelle