[PATCH] HTTP/2: copy additional headers in the pushed requests
ru at nginx.com
Fri Feb 9 07:23:46 UTC 2018
On Thu, Feb 08, 2018 at 08:04:57PM +0000, Alessandro Ghedini wrote:
> On Thu, Feb 08, 2018 at 10:18:54PM +0300, Maxim Dounin wrote:
> > Hello!
> > On Thu, Feb 08, 2018 at 05:07:49PM +0000, Alessandro Ghedini wrote:
> > > On Thu, Feb 08, 2018 at 05:04:58PM +0000, Alessandro Ghedini wrote:
> > > > # HG changeset patch
> > > > # User Alessandro Ghedini <alessandro at cloudflare.com>
> > > > # Date 1518109032 0
> > > > # Thu Feb 08 16:57:12 2018 +0000
> > > > # Branch push-copy-headers
> > > > # Node ID 4f7f42e6d13add2ab0c7a9654472bb74085181d1
> > > > # Parent a49af443656f2b65ca5de9d8cad5594f44e18ff7
> > > > HTTP/2: copy additional headers in the pushed requests.
> > > >
> > > > To ensure pushed requests are processed consistently with the original
> > > > client request, some headers need to be copied from the original request
> > > > into the pushed one.
> > > >
> > > > The headers currently copied are User-Agent, Accept, Accept-Language and
> > > > Accept-Encoding.
> > >
> > > So, I'm not quite sure if this is the correct way to go about doing this, but
> > > I think the issue is real and worth fixing, so I'd be happy to implement this
> > > differently if you have alternative ideas.
> > Could you please elaborate more on "the issue is real"?
> Right, sorry. Essentially the problem is that origins may generate a different
> responses dependning on these headers, and a pushed request may be processed
> inconsistently from the original request if these headers are different (say,
> stupid example, if the client requests a specific language, the main request
> may get a response in one language, and the pushed one in another).
> Additionally things like compression wouldn't work for pushed requests, which
> is not optimal.
> There are of course other headers that could influence the origin's response,
> but this somewhat minimal list of standard headers seemed like a good start.
> FWIW, other server push implementations like Apache's mod_http2, h2o (used
> in production by Fastly) and Cloudflare's closed-source implementation, all
> behave like this, and have done so for years, without any apparent issue.
Akamai copies User-Agent and Accept-Encoding, but sets "Accept: */*",
and doesn't copy/set Accept-Language, on pushes requests:
Pushing "Accept: */* looks redundant, as
says that "A request without any Accept header field implies that the
user agent will accept any media type in response.".
h2o seems to blindly copy the headers you mentioned, including Accept
from the original request, which is obviously wrong:
: [ 1.239] recv (stream_id=13) :method: GET
: [ 1.239] recv (stream_id=13) :scheme: https
: [ 1.239] recv (stream_id=13) :authority: h2o.examp1e.net
: [ 1.239] recv (stream_id=13) :path: /search/jquery-1.9.1.min.js
: [ 1.239] recv (stream_id=13) accept: text/html
: [ 1.239] recv (stream_id=13) accept-encoding: [...]
: [ 1.239] recv (stream_id=13) user-agent: [...]
: [ 1.239] recv (stream_id=13) accept-language: [...]
: [ 1.239] recv PUSH_PROMISE frame <length=207, flags=0x04, stream_id=13>
: ; END_HEADERS
: (padlen=0, promised_stream_id=2)
https://http2.golang.org/serverpush only sets the minimally required
fields, as we currently do.
Can't test IIS, but its API allows setting additional headers to push:
Can't tell for Cloudflare as I can't find a working site on it that
uses HTTP/2 with push enabled, maybe due to this:
And last but not least:
: To maximize the likelihood that a pushed resource will be accepted,
: content negotiation is best avoided.
More information about the nginx-devel