Re: [quicwg/base-drafts] Remove DUPLICATE_PUSH and allow duplicate PUSH_PROMISE (#3309)

Ryan Hamilton <> Fri, 10 January 2020 21:03 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 36D2E1200E9 for <>; Fri, 10 Jan 2020 13:03:26 -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, SPF_HELO_NONE=0.001, SPF_PASS=-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 zK0NzdL15nDq for <>; Fri, 10 Jan 2020 13:03:22 -0800 (PST)
Received: from ( []) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id A4AD91200CC for <>; Fri, 10 Jan 2020 13:03:22 -0800 (PST)
Date: Fri, 10 Jan 2020 13:03:21 -0800
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=pf2014; t=1578690201; bh=Y96ewK2qWJweF2wEmoX9SO/pSS0JwQox7cCV8xqVsoo=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=IesTzKq9+DJ+airsA05ItEklipwszyqD2fC1BhKVo2oM8Z6mnQQVxhzl0Fd7xuOTD dd4q9dSUi1NoPXk0pNUwi5E/O2IS4ivMeuD3Y3a5lPHFRueaW48tmCOKmTlPqiGIpU rAB55eLcnGemx085wy7UodTr1zan4lbuMryb2SC4=
From: Ryan Hamilton <>
Reply-To: quicwg/base-drafts <>
To: quicwg/base-drafts <>
Cc: Subscribed <>
Message-ID: <quicwg/base-drafts/pull/3309/review/>
In-Reply-To: <quicwg/base-drafts/pull/>
References: <quicwg/base-drafts/pull/>
Subject: Re: [quicwg/base-drafts] Remove DUPLICATE_PUSH and allow duplicate PUSH_PROMISE (#3309)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5e18e69984d7b_3c453fbd110cd95c17004f"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: RyanAtGoogle
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: Fri, 10 Jan 2020 21:03:26 -0000

RyanAtGoogle commented on this pull request.

> @@ -1238,9 +1232,20 @@ MAX_PUSH_ID frame ({{frame-max-push-id}}). A client MUST treat receipt of a
 PUSH_PROMISE frame that contains a larger Push ID than the client has advertised
 as a connection error of H3_ID_ERROR.
-A server MUST NOT use the same Push ID in multiple PUSH_PROMISE frames. A client
-MUST treat receipt of a Push ID which has already been promised as a connection
-error of type H3_ID_ERROR.
+A server MAY use the same Push ID in multiple PUSH_PROMISE frames. If so, the
+decompressed request header sets MUST contain the same fields in the same
+order, and both the name and and value in each field MUST be exact
+matches. If a client receives a Push ID that has already been promised
+and detects a mismatch, it MUST respond with a connection error of type
+H3_GENERAL_PROTOCOL_ERROR. If the decompressed header sets match exactly, the
+client MUST ignore the duplicate PUSH_PROMISE frame.

Hm. I think there is a difference in philosophy here. 

> HTTP/2 associates each push with the (single) request where the server promised it. HTTP/3 allows a push to be associated with multiple requests.

Totally agree with this! If a client makes requests A and B, the server can promise to push resource C on both A and B. This is clearly true.

But at the HTTP/3 layer (not at the web browsing layer) there is no notion of navigation or of subsequent requests being "associated" with earlier HTTP/3 streams (on which a resource may have been promised). Or at least I don't think there is.

My understanding of the motivation for allowing multiple pushes in HTTP/3 is not because we want to allow multiple subsequent requests for the same resources to be associated with the same pushed stream. Instead it was because HTTP/2 is in-order and HTTP/3 is not. In HTTP/2 if a client requested A and B and the server knew that both referenced resource C, it could push C a single time and be confident that requests initiated by the reference to C in the bodies of A and B would both come *after* the promise of C. However in HTTP/3 this is not the case. Since the promise for C is delivered on the request stream there is no ordering guarantee that the push (on A) will arrive at the client before the body of B (which contains the reference to C) arrives. As such, if the server only wants to push C once, it needs to make sure both promises are know.

But this, to me, is orthogonal to the issue of associating multiple subsequent requests with the same push data down at the HTTP/3 layer because each of these requests are somehow associated with the original requests A and B.

Am I thinking about this the wrong way?

> Since Chrome can split navigations across connections, doesn't having the push cache at the connection level means you might miss that something was already pushed because it was promised on a different connection than Chrome was going to use for the request?

While Chrome does store pushes in a per-connection cache (which is really just the pushed streams themselves) it also has a "global" index of "promises by URL" which allows a request which would, by default, go on one connection to be satisfied by a promise from another connection (which might otherwise be going away, for example).

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