http2etags

HTTP2 does not yet support etags?


I am currently making a server for dynamic and static files with Node. I'm trying to implement HTTP2. What surprises me is that it seems that the HTTP2 push does not support ETags!

When the client sends the headers to retrieve a file that starts with a push, and that it has accepted, it ignores the "IF-NONE-MATCH" header.

It's a waste, I do not understand the reason for this behavior. Is this the case or am I missing something?


Solution

  • As discussed in the comments the server pushes the resource, so there is no client request, so there is no Etag to send.

    So HTTP/2 does support Etags - they just have no relevance for pushed requests.

    And yes this does mean cached resources are ignored for Pushed resources - which is one of the big drawbacks of Push and why many people do not recommend using it. When a client sees the PUSH_PROMISE that a server sends before pushing a resource, it can reject it with a RST_STREAM request but by the time that makes it to the server often a good part (if not all) of the resource will have already been pushed.

    There are a few ways around this:

    1. You could track what has already been pushed using cookies for example. I've a simple example with Apache config here: https://www.tunetheweb.com/performance/http2/http2-push/. Of course that assumes that cookies and cache are in sync but they may not be (they can be cleared independently).
    2. Some servers track what has already been pushed. Apache for example allows an HTTP/2 push diary to be configured (set to 256 items by default) which tracks items pushed on that connection. If you visit page1.html and it pushes styles.css, and then you visit page2.html and it also attempts to push styles.css Apache will not push it as it knows you already have it. However that only works if you are using the same connection. It you come back later on a new connection, but it's still in the cache then it will be re-pushed.
    3. There was a proposal for Cache digests, which allow the browser to send an encoded list of what is in the cache at the start of any connection, and the server could use that to know whether to push an item or not. However work on that has been stopped recently as there were some privacy concerns about this.

    Ultimately HTTP/2 Push has proven to be tricky to make useful and usage of it is incredibly low because of this. In large part due to this, but also because it is complex and there are other implication issues. Even if all those were solved, it's still easy to over push resources when perhaps it's best to let the browser request the resources in the order it knows it needs them. The Chrome team have even talked about turning it off and not supporting it.

    Many are recommending using Early Hints with status code 103 instead, as it tells the browser what to request, rather than just pushing it. The browser can then use all it's usual knowledge (what's in the cache, what priority it should be requested with...etc.) rather than overriding all this like Push does.

    Cheap plug, but if interested in this then Chapter 5 of my recently published book discusses this all in a lot more detail then can be squeezed into an answer on Stack Overflow.