How to tell from server side if client supports HTTP / 2
I am writing an analytics server to be used by web users. One of the parameters I want to check is their browser support. Please tell me if I can get the following information and how:
- Check if client (user's browser) supports http / 2
- Check if the client (user's browser) supports http / 2 push, some how is detected when the server sends a push, if the client makes it capable of using it, this is probably some kind of js test, or you won't tell me.
- Check if client (user browser) supports QUIC , UDP version http / 2
source to share
This depends on the web server used and the details it provides when connected to it.
Apache, for example, provides the following variables: https://httpd.apache.org/docs/2.4/mod/mod_http2.html#envvars
Including these variables:
Variable Name: Value Type: Description:
HTTP2 flag HTTP/2 is being used.
H2PUSH flag HTTP/2 Server Push is enabled for this connection and also supported by the client.
H2_PUSHED string empty or PUSHED for a request being pushed by the server.
So you can easily add this to your log files using LogFormat like this:
LogFormat "%h %l %u %t %{ms}T \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{SSL_PROTOCOL}x %{SSL_CIPHER}x %{Content-Encoding}o %{H2_PUSHED}e" combined
And then look from the log files if it was transferred over HTTP / 2.0 and if it was PUSHED or not. For example:
86.1.2.3 - - [11/Jul/2017:22:14:56 +0100] 2 "GET / HTTP/2.0" 200 1700 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 br
86.1.2.3 - - [11/Jul/2017:22:14:56 +0100] 3 "GET /assets/css/common.css HTTP/2.0" 200 5381 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 br PUSHED
These variables are also available for CGI scripts and the like. Note that these variables will only be set if the actual HTTP / 2 protocol is used.
Not all web servers expose this verbosity as easily as Apache, and a lot of them don't support HTTP / 2 push, so they probably can't detect that, given that they don't support it themselves!
I am not aware of any web browsers that provide this data from the HTTPS client hello (when the HTTP / 2 protocol is negotiated) as most of them only contain information about the current connection , not every protocol support and only after installation HTTPS session. For example, Apache HTTPS variables are given here: http://httpd.apache.org/docs/current/mod/mod_ssl.html#envvars
QUIC is less supported by web servers, so it is not easy to detect because of this.
In fact, these are more difficult to detect from the client side, since they are not affected by JavaScript as far as I know. The easiest option is to call a CGI script over HTTP / 2 that returns the result of the values ββprovided by the web server.
Please note that the pushed assets will only be used when needed. And if it is necessary, and not pushed, it will still be retrieved. So your js test idea supposedly detecting if a pushed resource is in use will not definitively tell if the client supports push, because the resource could have been fetched.
source to share