简体   繁体   中英

HTTP/2 Server Push not working, what am I doing wrong?

This is my first question here, hope I'm doing it right.

I'm using a LiteSpeed webserver with HTTP/2 (shared hosting provider), but I can't get the push feature to work. I'm not quite sure how to check if it works, but at least as far as I can tell it isn't working properly.

So I have looked up a ton of guides ( HTTP/2 Server Push Tutorial or A Comprehensive Guide To HTTP/2 Server Push as examples), and they all mention changing the headers by adding the following:

link: </my/theme/css/style.css>; rel=preload; as=style

I understand that this code tells the server to preload said resource, in this case style.css. However, if the server supports HTTP/2 push, then it should automatically push the resource instead (as long as you don't add nopush at the end of it). The second link does mention that this is true for most, but not all servers.

So with this in mind, I created a simple test PHP page to see if I could get it working. The result was this:

Chrome DevTools showing Headers tab with link preload

Network tab in DevTools showing the result

So most of the guides I saw mentioned that the Initiator in the Network tab for the pushed resource would say Push / Other (or similar) instead of just Other , but as you can see from my result it just says Other. Not to mention that the resource doesn't get loaded in the same request, it just looks like a simple preload to me. I also tested my site with https://http2.pro/check , and it says no resource is pushed.

This was tested with Chrome 71.0.3578.98.

  • Am I missing something important here? Could it be a problem with my server?
  • Another question. When defining multiple resources in the headers for preload and push, some guides mention creating multiple link-elements, while others mention comma separating them in a single link-element. Are both of these correct, is one better than the other?

Any help or enlightenment is appreciated, thanks!

So there can be a few things after some testing with various configurations, browser versions and flags enabled/disabled within Chrome as well as investigating with the network event viewer.

If the LiteSpeed Web Server has QUIC enabled, Chrome v71 seems to be showing the request as a normal GET request, and won't indicate it being pushed, however looking in the network event viewer in Chrome, it reveals that it indeed is pushed (Look for QUIC_SESSION_PUSH_PROMISE_RECEIVED).

Now, this will only be the case if QUIC in the browser is enabled as well, which it isn't by default currently in Chrome v71 as far as I can tell (they disable and enable things from time to time) - so you either have to have a flag set in Chrome to enable QUIC and you'll see the above behavior (You should also see http/2+quic/43 in "Protocol" under web developer tools).

If QUIC isn't enabled in the Browser or on the web server, you should see the file being pushed, and Chrome v71 would indicate this with the Initiator "Push / Other".

Now, in Chrome v73 (Canary release), it will have the "Initiator" set to Other and the "Size" should be (from memory cache) , this indicates the file being pushed.

In Google Chrome you can go to chrome://net-export/ and click "Start Logging to Disk", then refresh your browser window where you have the file that expects to be pushed - stop the measurement, and go to https://netlog-viewer.appspot.com/ - import the json file here, and go to "QUIC", find your domain name in the list, and click on the "Connection ID".

Then click the "QUIC_SESSION" in the list, and search for QUIC_SESSION_PUSH_PROMISE_RECEIVED - if there's matches, you know for a fact that the files are pushed.

It's a bit of digging to figure out whether it's pushed currently, and the confusion is mainly related to Chrome Dev Tools not really being consistent between protocols and versions.

First of all you need to find out if your infrastructure uses Link headers to activate push. Litespeed documentation doesn't seem great here but let's assume that is how you activate push.

Next is to check if your server is sending the pushed request. I find nghttp the best tool to do this so if you have access to this too, then run a command like this to see the HTTP/2 frames and if the PUSH_PROMISE frame is sent, indicating the style sheet is being pushed:

nghttp -anv https://www.example.com

You can also see the frames using Chrome, though they've just made this a lot harder but insisting on logging to disk first and then opening in a viewer. Follow the instructions similar to @LucasRolff's answer, but for HTTP/2 or here .

Assuming the server is pushing the resource you're next left with why Chrome is not using that pushed resource. The most common reason is if you are using a self-signed TLS certificate to provide HTTPS that the browser does not recognise. Even if you click through the error and get a connection with a red padlock, Chrome will not use the cache for that connection, and so cannot use HTTP/2 push (which requires using the HTTP/2 push cache). The nghttp or Chrome event log output should show if this is the case. Alternatively try using Firefox which DOES allow HTTP/2 push to be used if unrecognised certificates are clicked through.

Finally to your last question:

When defining multiple resources in the headers for preload and push, some guides mention creating multiple link-elements, while others mention comma separating them in a single link-element. Are both of these correct, is one better than the other?

Both are correct. HTTP (whether HTTP/1.1 or HTTP/2) defines this:

header1: value1
header1: value2

and this:

header1: value1, value2

as syntactically identical :

A recipient MAY combine multiple header fields with the same field name into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM