Re: [quicwg/base-drafts] Forwarding upstream error mid-body to downstream (#3300)

Kazuho Oku <> Tue, 17 December 2019 00:02 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 3EC84120043 for <>; Mon, 16 Dec 2019 16:02:28 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8
X-Spam-Status: No, score=-8 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id mH7CzvpVkltt for <>; Mon, 16 Dec 2019 16:02:26 -0800 (PST)
Received: from ( []) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 23A6712002E for <>; Mon, 16 Dec 2019 16:02:26 -0800 (PST)
Date: Mon, 16 Dec 2019 16:02:25 -0800
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=pf2014; t=1576540945; bh=kUtsf/TmAOigZHAfJuX4H8cNXZEqqIwh4a9hAfLIb5E=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=j8kPkA4cx5z8MKFcmQ7QhTFqoBYFRqurKAaHMzXwq6EVFDa7nfG+gmXRGdlHmtsSc dN6MpAr3u69BzZfa95Wo78SJQE4laVfuWCc8csmwW5gSlRsvRROHf0eBwT9wmd0BjR W1cqRbQXesmFbJTCtuMDAyEyfvdo2Lg2XeuytLTw=
From: Kazuho Oku <>
Reply-To: quicwg/base-drafts <>
To: quicwg/base-drafts <>
Cc: Subscribed <>
Message-ID: <quicwg/base-drafts/issues/3300/>
In-Reply-To: <quicwg/base-drafts/issues/>
References: <quicwg/base-drafts/issues/>
Subject: Re: [quicwg/base-drafts] Forwarding upstream error mid-body to downstream (#3300)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5df81b11341f2_47f93fc7e70cd96c86513"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: kazuho
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
Archived-At: <>
X-Mailman-Version: 2.1.29
List-Id: Notification list for GitHub issues related to the QUIC WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Tue, 17 Dec 2019 00:02:28 -0000

@ianswett @janaiyengar Thank you for your responses.

The issue is NOT related with TCP resets.

HTTP/1.1 does not distinguish between TCP FIN and RST, but it has it's own framing; see [RFC 7230 section 3.3.3]( HTTP/2 does not (need to) distinguish between the two, it relies on HTTP/2 frames to see if an HTTP message has been transferred completely.

My point is that a HTTP/1.1 or HTTP/2 intermediary acting as a "tunnel" (as defined in  [RFC 7230 section 2.3]( is able to forward unexpected termination of an HTTP message that it received from upstream to downstream. In HTTP/1.1, what a tunnel can do is abruptly terminate a chunked encoding (by closing the connection normally). In HTTP/2, a tunnel sends a RST_STREAM.

In either case, the close signal never overtakes the partial payload.

I am not sure what others do, but at least H2O have been strict about forwarding partial payload and error close as they were received from upstream; see The intention is to provide the same response to the user even when a server running behind returns a corrupt response.

But in HTTP/3, because a stream reset can overtake the transmission of application data, it becomes very hard to act as a tunnel in such a way.

The worst case is as follows: consider the case where an origin always returns an HTTP response (containing an image) that terminates abruptly (at the HTTP/1.1 or HTTP/2 layer). Note that the delivery of partial, progressive JPEG image might not have any negative effects on user experience. Or the origin might in fact be returning an entire image, but failing to terminate the chunked encoding correctly.

When the connection between the tunnel and the client is HTTP/1.1 or HTTP/2, the tunnel can (and likely will) forward that partial response. But when the connection between the tunnel and the client is HTTP/3, it is very hard for the tunnel to deliver the partial response before the stream reset. Assuming that the partial response is of low priority, it is likely that the client would see nothing (rather than an image), as the stream reset signal would precede delivery of any stream data.

You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub: