Say I have a server that serves an HTML file at the url https://example.com/
and this refers to a css file at the url https://test.com/mystyles.css
. Is it possible to push the mystyles.css
file alongside the html content as part of an HTTP2 connection, so that a browser will use this css content?
I have tried to create such a request using a self-signed certificate on my localhost (and I have pre-created a security exception for both hosts in my browser) by sending the html file when a request arrives at http://localhost/
, and pushing the css with a differing hostname/port in the :authority
or Host
header. However, on a full-page refresh, the CSS file is fetched in a separate request from the server, rather than using the pushed css file.
See this gist for a file that I have been using to test this. If I visit http://localhost:8080/
then the text is red, but if I visit http://test:8080/
it is green, implying that the pushed content is used if the origin is the same.
Is there a combination of headers that needs to be used for this to work? Possibly invoking CORS?
Unfortunately HTTP/2 push always felt like feature that wasn't quite there yet. It's usefulness was stunted due to Cache-Digest for HTTP/2 being killed off, and no browser APIs to hook into push events. The Chrome team has considered removing Push support since at least 2018.
HTTP/2 Server Push allows an HTTP/2-compliant server to send resources to an HTTP/2-compliant client before the client requests them. Server Push is a performance technique aimed at reducing latency by loading resources preemptively, even before the client knows they will be needed.
The CORS mechanism supports secure cross-origin requests and data transfers between browsers and servers. Modern browsers use CORS in APIs such as XMLHttpRequest or Fetch to mitigate the risks of cross-origin HTTP requests.
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos.
Yes it is theoretically possible according to this blog post from a Chrome developer advocate from 2017.
As the owners of developers.google.com/web, we could get our server to push a response containing whatever we wanted for android.com, and set it to cache for a year.
...
You can't push assets for any origin, but you can push assets for origins which your connection is "authoritative" for.
If you look at the certificate for developers.google.com, you can see it's authoritative for all sorts of Google origins, including android.com.
Viewing certificate information in Chrome Now, I lied a little, because when we fetch android.com it'll perform a DNS lookup and see that it terminates at a different IP to developers.google.com, so it'll set up a new connection and miss our item in the push cache.
We could work around this using an ORIGIN frame. This lets the connection say "Hey, if you need anything from android.com, just ask me. No need to do any of that DNS stuff", as long as it's authoritative. This is useful for general connection coalescing, but it's pretty new and only supported in Firefox Nightly.
If you're using a CDN or some kind of shared host, take a look at the certificate, see which origins could start pushing content for your site. It's kinda terrifying. Thankfully, no host (that I'm aware of) offers full control over HTTP/2 push, and is unlikely to thanks to this little note in the spec: ...
In practice, it sounds like it's possible if your certificate has authority over the other domains and they're hosted at the same IP address, but it also depends on browser support. I was personally trying to do this with Cloudflare and found that they don't support cross-origin push (similar to the blog post author's observations about CDNs in 2017).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With