Re: Server Push and Content Negotiation

Mark Nottingham <> Wed, 07 September 2016 03:57 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 18E2912B110 for <>; Tue, 6 Sep 2016 20:57:24 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8.429
X-Spam-Status: No, score=-8.429 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.508, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id wnKduNTzdnVl for <>; Tue, 6 Sep 2016 20:57:22 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 61F1312B016 for <>; Tue, 6 Sep 2016 20:57:22 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1bhTv9-0003ds-Kb for; Wed, 07 Sep 2016 03:53:07 +0000
Resent-Date: Wed, 07 Sep 2016 03:53:07 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bhTv2-0003co-Ag for; Wed, 07 Sep 2016 03:53:00 +0000
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from <>) id 1bhTux-0003Hk-CM for; Wed, 07 Sep 2016 03:52:59 +0000
Received: from [] (unknown []) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPSA id 62CBC22E1F3; Tue, 6 Sep 2016 23:52:31 -0400 (EDT)
Content-Type: text/plain; charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 9.3 \(3124\))
From: Mark Nottingham <>
In-Reply-To: <>
Date: Wed, 7 Sep 2016 13:52:28 +1000
Cc: Patrick McManus <>, HTTP Working Group <>
Content-Transfer-Encoding: quoted-printable
Message-Id: <>
References: <> <> <>
To: Tom Bergan <>
X-Mailer: Apple Mail (2.3124)
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-8.4
X-W3C-Hub-Spam-Report: AWL=1.216, BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, W3C_AA=-1, W3C_DB=-1, W3C_IRA=-1, W3C_IRR=-3, W3C_WL=-1
X-W3C-Scan-Sig: 1bhTux-0003Hk-CM fc371d809f4bf0dabecaa5379470940b
Subject: Re: Server Push and Content Negotiation
Archived-At: <>
X-Mailing-List: <> archive/latest/32380
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

> On 25 Aug 2016, at 3:12 AM, Tom Bergan <> wrote:
> On Tue, Aug 23, 2016 at 9:26 PM, Mark Nottingham <> wrote:
>> The interaction of Content Negotiation and Server Push isn't really specified. Depending on how it's implemented, it could be quite tricky, because it seemingly requires the server to guess what the client would have sent, in order to negotiate upon it.
> This sounds right to me. Though, if the server and client are well-behaved, the worst-case is wasted bandwidth, not an incorrect response:
> - If the server pushes response with a non-empty Vary (or Key) field, it should make a guess for all headers mentioned in Vary (or Key) and include those guesses in the PUSH_PROMISE
> - The client should is match pushed (request, response) pairs to client requests using the Vary (or Key) field in the usual way

Right. One complicating factor is how closely current clients follow <>, versus using their own heuristics.

>> Additionally, the server needs to know what the base capabilities and preferences of the client are, to allow it to select the appropriate responses to push. To aid this, servers SHOULD create a PUSH_PROMISE's request by copying the values of the request header fields mentioned in the `Vary` response header field from the request that is identified by the `PUSH_PROMISE` frame's Stream ID.
> For fields like Accept-Encoding and User-Agent, that's probably sufficient. But in general, it's not quite that simple -- e.g., what if the response has "Vary: Cookie", which can in theory change between requests? You make a similar observation when talking about how Client Hints might change between requests. Also see the discussion for "Rule #4" in this doc:

Don't push something with Vary: Cookie? :)

Otherwise, the client is going to have to get into the business of checking a request to figure out "would I have sent that request?" Making that more complicated is the secondary question, "when?", because things like cookies can change quite quickly.

Client Hints is a bit easier, because AIUI the response is still presumed to be usable by the client, even if the hints don't line up.

>> I'd be tempted to go even further and say that PUSH_PROMISE headers SHOULD NOT contain `DNT`, `User-Agent`, `Cookie` or similar headers UNLESS they were specified in Vary.
> I'd agree with that. I would say that PUSH_PROMISE only needs to contain header fields that describe the cache key of the response (which includes :method, :scheme, :path, :authority, and any header field referenced by Vary or Key).
>> What do people think -- is this worth specifying? How are implementations currently doing this?
> Chrome is not doing anything (yet):
> I think most readers come to roughly the same conclusion when reading the RFC, but there is enough uncertainty that I think this is worth specifying in more detail.

Mark Nottingham