Re: Server Push and Caching

Amos Jeffries <> Sat, 27 May 2017 03:05 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 9731812EA42 for <>; Fri, 26 May 2017 20:05:46 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -5.502
X-Spam-Status: No, score=-5.502 tagged_above=-999 required=5 tests=[BAYES_05=-0.5, HEADER_FROM_DIFFERENT_DOMAINS=0.001, RCVD_IN_DNSWL_HI=-5, RP_MATCHES_RCVD=-0.001, 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 Q-z29hNjHHZu for <>; Fri, 26 May 2017 20:05:43 -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 5AAFC12EA52 for <>; Fri, 26 May 2017 20:05:43 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1dERyw-0000V1-Un for; Sat, 27 May 2017 03:01:34 +0000
Resent-Date: Sat, 27 May 2017 03:01:34 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1dERyr-0000TO-Or for; Sat, 27 May 2017 03:01:29 +0000
Received: from [] ( by with esmtp (Exim 4.84_2) (envelope-from <>) id 1dERyH-0004GB-Ko for; Sat, 27 May 2017 03:01:24 +0000
Received: from [] (unknown []) by (Postfix) with ESMTP id 54B5D6606A2 for <>; Sat, 27 May 2017 15:00:20 +1200 (NZST)
References: <> <> <>
From: Amos Jeffries <>
Message-ID: <>
Date: Sat, 27 May 2017 15:00:15 +1200
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0
MIME-Version: 1.0
In-Reply-To: <>
Content-Type: text/plain; charset="utf-8"; format="flowed"
Content-Transfer-Encoding: 7bit
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=0.0
X-W3C-Scan-Sig: 1dERyH-0004GB-Ko ab381b902544d1cb21c69b20ec14a6d8
Subject: Re: Server Push and Caching
Archived-At: <>
X-Mailing-List: <> archive/latest/33958
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

On 27/05/17 09:50, David Witherspoon wrote:
> Yes, thanks for the clarification.  I agree invalidation is too strong 
> of wording.  Rather a request with cache-control: no-cache directive 
> allows for updating or adding entries to the cache.
> > it certainly doesn't MUST or even SHOULD it.
> I believe I might still disagree but let me clarify the scenario:
> 1. client issues request 1, and gets a cache-able response 1.
> 2. The client then issues the same request (request 2) but with the 
> no-cache cache request directive and gets a cache-able response 2 from 
> the origin server.
> 3.  The client issues request 3 that matches both previous requests 
> and assume both responses are valid.  rfc7234#section-4.4 states that 
> "When more than one suitable response is stored, a cache MUST use the 
> most recent response".  So response 2 would presumably be served from 
> cache to answer request 3  (OR It can also forward the request with 
> "Cache-Control: max-age=0" or "Cache-Control: no-cache" to 
> disambiguate which response to use.)
> If we now assume that request 2 is server-initiated via a push 
> promise, and that the push promise is not cancelled, and the client 
> "is just replaying" it onto the cache then I would assume Step 3 MUST 
> operate in the same way.

After that step-2 has occured there are only one of two situations possible:
* the cache ignored the response-2 and contains the response-1, or
* it replaced/updated the cache contents with response-2.

The Cache-Control header is exceptionally unlikely to be part of the 
Vary header list, so it is almost not possible to emit a single 
request-3 that causes the response-1 and response-2 to be treated as 
different representations of the same resource. It is possible they are 
different in some other way, but that no-cache itself is irrelevant to 
the variation identity.

> > I do agree that a cached-response that you wouldn't use to satisfy 
> the pushed request is not a good rationale for canceling the pushed stream
> Agreed, this arose because Chrome has a PR that implements an 
> optimization on their implementation of just replaying it onto the 
> cache.  That optimization "Cancel[s] unnecessary push streams when 
> it's discovered they're in cache".  I believe the semantics of a 
> no-cache request header is well defined such that it can't already be 
> discovered in cache.  Sure it can cancel the Push Promise for any 
> reason, but in this case, it is ignoring the semantics that the 
> no-cache request directive syntax defines.

The semantics of request CC:no-cache is that a cache *MAY* be updated. 
There is no requirement that the updates be stored for future clients.

PUSH simply proactively delivers a response that can be sent on as-is to 
the client, skipping delivery of whatever the cache contained.

If the cache decides to cancel a PUSH stream with no-cache or any 
similar revalidation requirement, the only thing it affects is to 
prevent itself from being able to PUSH that resource onwards. Middleware 
caches must wait to see if the client really does send that requirement 
and handle it in the normal way for such requests. Browser / UA caches I 
would expect to have better info on hand than a remote server - so that 
information should be informing the decision to cancel the push.

> Note, if response 2 has a longer validation lifetime then response 1, 
> then I believe it is behaviorally equivalent to invalidating response 1.

Only if the PUSH'd response is cached instead of cancelled. If it got 
cancelled there is no complete response object to do cache replacement with.