Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell from server side if client supports http/2

I am writing an analytics server that is going to be used by web users. One of the parameters that I want to test is their browser support. Please tell me if I can obtain the fallowing information and how:

  • Test if the client (user browser) supports http/2
  • Test if the client (user browser) supports http/2 pushes, some how detect when the server sends a push, does the client able to use it, this one is probably some js test, or not you tell me.
  • Test if the client (user browser) supports QUIC, the UDP version of http/2
like image 593
Ilya Gazman Avatar asked Nov 07 '22 19:11

Ilya Gazman


1 Answers

This depends on the web server used and the details it provides on the connection made to it.

Apache for instance, 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 a 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 see from the log files whether it was served over HTTP/2.0 and whether 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 to CGI scripts and the like. Note these variables will only be set if HTTP/2 is actually used.

Not all web servers expose this level of detail as easily as Apache and many don't support HTTP/2 push so probably can't detect that given that they don't support it themselves!

I'm not aware of any web browsers that give these details from the HTTPS client hello message (when HTTP/2 would be negotiated) as most only provide details of the current connection, rather than every protocol support, and only after the HTTPS session is set up. For example Apache's HTTPS variables are given here: http://httpd.apache.org/docs/current/mod/mod_ssl.html#envvars

QUIC is less supported by web servers so not as easy to detect because of that.

To actually detect all this from the client side is more difficult as these are not exposed to JavaScript as far as I am aware. Easiest option would be to call a CGI script over HTTP/2 which returns the result of those values provided by the web server.

Note that pushed resources would only be used if needed. And if needed and not pushed, then it will be fetched anyway. So your idea of a js test, presumably detecting whether a pushed resource is being used will not definitively say whether the client supports push because the resource might have been fetched.

like image 121
Barry Pollard Avatar answered Nov 14 '22 21:11

Barry Pollard