How does HTTP2 server push know what do push? - http2

Server push works by sending js, css, images etc. just after responding to a request, instead of waiting for the client to receive the html, parse it and request the resources, saving a round trip. But pushing js, css, images, fonts etc. for example.com/about when those same files already got downloaded by the client when it fetched example.com a minute ago is a complete waste of bandwidth, because the client already has those files.
Keeping state server-side for each request seems expensive, and that's cannot be how it's done, since HTTP is stateless. Presumably, the client would re-request the html on subsequent visits, to see if anything's changed.
How does the HTTP2-server know what files to push?

There are several techniques for that. The browser can for example reset the streams. Or cache digests can be used.
Here is more information on that:
https://www.shimmercat.com/blog/cache-digests/
Just today some people are having an interesting conversation on cache digests:
https://lists.w3.org/Archives/Public/ietf-http-wg/2016AprJun/0371.html

Related

With HTTP/2 Push, can I push assets before the initial response?

I have a webpage that has JS, CSS, and font assets. The page has to do some heavy processing before determining the HTTP Status code and headers for its response.
I'd like to use HTTP/2 Push to send the assets to the browser without waiting on this heavy processing. The timeline would look something like this:
Client requests index.html
Server sends PUSH_PROMISES for script.js, styles.css, and font.woff2
Server sends HTTP headers and data for the assets above
Server does some heavy processing to determine index.html response...
Server sends HTTP headers and data for index.html
Is this possible? Based on my understanding of Server Push in the HTTP/2 spec, it appears possible. However, it's my first time diving into the HTTP/2 spec, so I could definitely be missing something.
Yes that’s totally allowed and it’s possible in Apache for instance as detailed here: https://icing.github.io/mod_h2/earlier.html
Or an example with Node is given here: https://github.com/bazzadp/http2-in-action/blob/master/Listing%205.3/app.js
Other servers may allow this too, but many servers use preload HTTP headers as signals to push so that needs the response to be sent sent back to show the header.
An extra 103 Early Hint response has been defined which can be sent back early with these headers while your main response is being processed, however support of this is poor not least because some implementations will be confused to get back two responses (a 103 followed by a 200).
What you want to do is possible, but the details of how to do it depend on the technology that you have chosen.
Your application needs to have explicit HTTP/2 APIs to push assets to the client.
For example, if you use Java and Servlet, you need to use Servlet 4.0 which has introduced the PushBuilder APIs to explicitly push assets, and this can be done independently from the main resource response, like you would like to do.
I'm sure other technologies such as NodeJS have similar APIs that you can leverage, but you have to check with the technology you are using.

Cloudfront queues parallel requests - high and sequential time-to-first-byte (TTFB)

I have a web application that requests a lot of media assets in parallel using AJAX. All assets are coming from the same Cloudfront Origin, which is itself directly plugged into an S3 bucket.
I'm seeing requests from Cloudfront with TTFB of the order of seconds. Even more odd, it seems that those requests are basically queued until a previous request has been served:
Those two requests are initiated in parallel, and you can see that it's not Chrome queueing them, but Cloudfront not answering anything to the second (2KB) request until the first request has completed download. This is slowing down my application by a huge margin, and I cannot figure out what is going wrong... I see the same behavior when I check with Safari too.
Here are the two requests details
As you can see, they are also both Hit from cloudfront.
Finally, as it might be relevant, I'm using a lambda function in my Origin's behavior to add the proper Vary headers, to prevent Chrome from using cached requests without the CORS headers that will make subseqeuent CORS request fail (see details here).
Here is my complete Origin's behavior settings:
Any help is appreciated, and please feel free to ask more details if needed! Thanks a lot in advance.

Is there any official way to use the "server push" with HTTP/2 as a long live push channel? [duplicate]

The most use cases for http/2 server push is to pre-emptively push assets files (such as javascript and css files) to browser. I am wondering can http/2 server push be used to send dynamic payload such as JSON documents to client application? From the http2-spec, it doesn't mention anything about this. Can anyone elaborate more on this? Why or why not?
HTTP/2 is not intended as a replacement of websockets in that you make a request (e.g. a web page) and may get several resources back (e.g. The web page, the CSS needed to display the webpage, JavaScript needed to run that webpage... etc.).
HTTP/2 is therefore not truly bidirectional in that it still responds to an initial request.
So if you're intending to send the JSON request in response to the initial request then that's fine - it's just another resource in much the same as CSS and javascript.
However if you're intending to keep the channel open to continually send further JSON payloads to keep your page up to date then that's not what HTTP/2 is intended for. That's what websockets are for.
This question has some further details on HTTP/2 versus websockets: Does HTTP/2 make websockets obsolete?
Yes, you can use HTTP/2 Push to send any type of assets. But keep in mind the following:
As BazzaDP said, HTTP/2 Push is not a push notification mechanism. But HTTP/2 is excellent for doing long polling, and then you have content-encoding compression, encryption, HTTP headers and flow control, so for 90% of the cases you can and probably should skip websockets anyway. Notice that when doing long polling, HTTP/2 Push is not required.Also notice that there is something called Server Sent Events which sort of is the browser-endorsed version of long polling.
HTTP/2 Push is so far transparent to the application. Meaning that you have to do the Push and do a request for the resource from your application.
For now, only cacheable things are made available to the application. That means that you need to set cache headers in the dynamically generated JSON response. Probably you can set a short expiration time, or a long one but under a dynamic URL.

HTTP/2 Push JSON Payload

The most use cases for http/2 server push is to pre-emptively push assets files (such as javascript and css files) to browser. I am wondering can http/2 server push be used to send dynamic payload such as JSON documents to client application? From the http2-spec, it doesn't mention anything about this. Can anyone elaborate more on this? Why or why not?
HTTP/2 is not intended as a replacement of websockets in that you make a request (e.g. a web page) and may get several resources back (e.g. The web page, the CSS needed to display the webpage, JavaScript needed to run that webpage... etc.).
HTTP/2 is therefore not truly bidirectional in that it still responds to an initial request.
So if you're intending to send the JSON request in response to the initial request then that's fine - it's just another resource in much the same as CSS and javascript.
However if you're intending to keep the channel open to continually send further JSON payloads to keep your page up to date then that's not what HTTP/2 is intended for. That's what websockets are for.
This question has some further details on HTTP/2 versus websockets: Does HTTP/2 make websockets obsolete?
Yes, you can use HTTP/2 Push to send any type of assets. But keep in mind the following:
As BazzaDP said, HTTP/2 Push is not a push notification mechanism. But HTTP/2 is excellent for doing long polling, and then you have content-encoding compression, encryption, HTTP headers and flow control, so for 90% of the cases you can and probably should skip websockets anyway. Notice that when doing long polling, HTTP/2 Push is not required.Also notice that there is something called Server Sent Events which sort of is the browser-endorsed version of long polling.
HTTP/2 Push is so far transparent to the application. Meaning that you have to do the Push and do a request for the resource from your application.
For now, only cacheable things are made available to the application. That means that you need to set cache headers in the dynamically generated JSON response. Probably you can set a short expiration time, or a long one but under a dynamic URL.

Can I disable GZIP on Google App Engine?

I'm serving up tiny little chunks of minimized javascript through Google App Engine, and I think the GZIP-unGZIP process is slowing me down unnecessarily. (To clarify, I'm sending them quickly to many different websites who request them and I've optimized most of the other parts of the process).
For reference the files are so small that the GZIP savings can be less then the "Content-Encoding: gzip" header.
However, from the documentation
If the client sends HTTP headers with the request indicating that the client can accept compressed (gzipped) content, App Engine compresses the response data automatically and attaches the appropriate response headers.
Is there a setting in app.yaml or somewhere that I can disable GZIP-ing? It must be possible since some files are served unzipped.
It's not currently possible to change this behavior from the server side (although, if you control the client, you can remove gzip from its Accept-Encoding header to accomplish the same thing)
There's an open bug about this with Google, and a team member has marked it "Acknowledged", but it doesn't look like there's been any action on it in the last year or so. You should probably add your voice to that ticket and star it for future notifications.

Resources