Как узнать со стороны сервера, поддерживает ли клиент http/2

Я пишу аналитический сервер, который будет использоваться веб-пользователями. Один из параметров, который я хочу протестировать, — это их поддержка браузером. Скажите, пожалуйста, могу ли я получить следующую информацию и как:

  • Проверьте, поддерживает ли клиент (пользовательский браузер) https://http2.github.io/faq/.
  • Проверьте, поддерживает ли клиент (браузер пользователя) пуши HTTP/2., как-то определить, когда сервер отправляет push, может ли клиент его использовать, это, вероятно, какой-то тест js, или вы мне не говорите.
  • Проверьте, поддерживает ли клиент (браузер пользователя) QUIC, UDP-версию http/2.

person Ilya Gazman    schedule 11.07.2017    source источник


Ответы (2)


Это зависит от используемого веб-сервера и сведений, которые он предоставляет о подключении к нему.

Apache, например, предоставляет следующие переменные: https://httpd.apache.org/docs/2.4/mod/mod_http2.html#envvars

Включая эти переменные:

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.

Таким образом, вы можете легко добавить это в свои файлы журналов, используя LogFormat следующим образом:

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

А затем посмотрите из файлов журнала, было ли оно обслуживаться через HTTP/2.0 и было ли оно PUSHED или нет. Например:

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

Эти переменные также доступны для сценариев CGI и т.п. Обратите внимание, что эти переменные будут установлены только в том случае, если HTTP/2 действительно используется.

Не все веб-серверы раскрывают этот уровень детализации так же легко, как Apache, и многие из них не поддерживают HTTP/2 push, поэтому, вероятно, не могут обнаружить это, учитывая, что они сами его не поддерживают!

Я не знаю ни одного веб-браузера, который предоставляет эти данные из приветственного сообщения HTTPS-клиента (когда будет согласовываться HTTP/2), поскольку большинство из них предоставляют сведения только о текущем соединении, а не о поддержке каждого протокола. и только после настройки HTTPS-сессии. Например, HTTPS-переменные Apache приведены здесь: http://httpd.apache.org/docs/current/mod/mod_ssl.html#envvars

QUIC в меньшей степени поддерживается веб-серверами, поэтому его не так легко обнаружить.

На самом деле обнаружить все это со стороны клиента сложнее, поскольку, насколько мне известно, они не подвергаются воздействию JavaScript. Самый простой вариант — вызвать сценарий CGI через HTTP/2, который возвращает результат этих значений, предоставленных веб-сервером.

Обратите внимание, что выталкиваемые ресурсы будут использоваться только в случае необходимости. А если нужен и не протолкнут, то он все равно будет получен. Таким образом, ваша идея теста js, предположительно определяющего, используется ли отправленный ресурс, не будет окончательно говорить, поддерживает ли клиент push, потому что ресурс мог быть извлечен.

person Barry Pollard    schedule 11.07.2017
comment
Я еще не уверен, какой сервер будет использовать серверная часть, поэтому я просто хочу знать, что клиент отправляет на серверную часть, что позволит серверной части понять, какой протокол поддерживает клиент. - person Ilya Gazman; 12.07.2017
comment
Независимо от толчка, в случае, если ресурс был отправлен, как вы можете проверить с помощью js, что вы использовали отправленный ресурс и не обновили его. - person Ilya Gazman; 12.07.2017
comment
Как я уже сказал, это полностью зависит от того, какие детали раскрывает выбранный вами сервер. И вы не можете различить использованный ресурс, который был использован, и тот же ресурс, который был получен без нажатия, опять же, как я упоминал в ответе. Если вы не измените содержимое этого ресурса на основе того, знаете ли вы из серверной части, поддерживается ли push. - person Barry Pollard; 12.07.2017
comment
Ок, понял про толчки - person Ilya Gazman; 12.07.2017
comment
Я проверил и обнаружил, что информация о протоколе согласовывается вместе с рукопожатием ssl, и его запускает клиент. Таким образом, теоретически, когда согласование ssl начинается с приветствия клиента, он уже должен отправлять информацию о том, поддерживает ли он http/2 или собирается ли он использовать QUIC или нет, независимо от того, какой сервер вы используете, и независимо от его поддержки. http/2 - person Ilya Gazman; 12.07.2017
comment
Верный. И если вы найдете сервер, который предоставляет эту информацию от приветствия клиента, тогда ваша проблема решена. Но, насколько я знаю, никто этого не делает, поэтому вы получаете подробную информацию об этом соединении только ПОСЛЕ того, как соединение установлено. Вы, конечно, можете написать свой собственный сервер TLS, но это непростая задача. Проще настроить сервер HTTP/2 и посмотреть, работает ли соединение, а затем определить на стороне сервера, какой протокол он использует для этого установленного соединения. Как я заявил. - person Barry Pollard; 12.07.2017
comment
Добавил дополнительное предложение к ответу, чтобы подчеркнуть это. Хотя видите, вы все равно уже приняли мой ответ, так что спасибо за это. - person Barry Pollard; 12.07.2017

Лучшее, что вы сможете сделать, это определить их браузер через их пользовательский агент, а затем сопоставить его с некоторой базой данных браузеров и функций.

Конечно, юзер-агент может врать, но большинство из них заявит о себе соответствующим образом.

person samanime    schedule 11.07.2017
comment
Пользовательский агент не сообщает вам протокол - person Ilya Gazman; 11.07.2017
comment
Это было бы правильно. Если вы читали, что я на самом деле сказал, именно поэтому я сказал, что вам нужно сопоставить пользовательский агент с базой данных, которая говорит, что для этого пользовательского агента он поддерживает эти функции. В браузере нет ничего, что говорило бы о его протоколе. - person samanime; 11.07.2017
comment
Сервер должен быть в состоянии сказать, поддерживает ли клиент http/2 или нет, иначе как он узнает, какой протокол использовать для связи с этим клиентом. - person Ilya Gazman; 11.07.2017
comment
Вы правы, но строка пользовательского агента может быть подделана, или может быть другая причина, по которой HTTP/2 не поддерживается в текущем соединении, например, HTTPS не используется. - person PHP Guru; 17.06.2020