PHP 7.1: нет cURL с HTTP/2

Мой вопрос не о том, чтобы узнать, поддерживает ли сервер HTTP/2 (они оба поддерживают), а о том, как убедиться, что PHP использует HTTP/2 с правильными настройками cURL для самой последней версии PHP в CentOS (созданной на основе репозиторий). Мой собственный ответ касается некоторых странностей, касающихся этого.

Я настроил свой сервер CentOS 7 для поддержки HTTP/2 с помощью этого прекрасного руководства: Настройка HTTP/2 на вашем веб-сервере

Итак, я получил последние выпуски, скомпилировал и установил их, и все работает нормально. Страницы обслуживаются с заголовками HTTP/2, как и должны.

Теперь я хотел бы использовать функциональность HTTP/2 в своих PHP-скриптах. В основном, выполняя вызовы cURL в стиле HTTP/2. Я обнаружил, что мне нужно обновить libcurl, собрать и скомпилировать его с определенной поддержкой HTTP/2. С некоторыми неудачами я заставил его работать.

Итак, curl -V говорит мне:

curl 7.55.0-DEV (x86_64-unknown-linux-gnu) libcurl/7.55.0-DEV OpenSSL/1.1.0f zlib/1.2.7 nghttp2/1.23.1
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy 

Большой!

И phpinfo() дает мне ту же версию (7.55.0-DEV) в связке с только что установленным OpenSSL, а именно:

OpenSSL 1.1.0f 25 May 2017

И Apache, кстати:

Server version: Apache/2.4.26 (Unix)
Server built:   Jul  7 2017 09:47:22

Однако, когда я пишу простой PHP-скрипт с вызовом cURL и для параметра CURLOPT_HTTP_VERSION установлено значение CURL_HTTP_VERSION_2_0, как показано в этом примере: https://stackoverflow.com/a/37146586/1005334, он говорит мне, что сервер не поддерживает HTTP/2...

Как такое может быть?

Я заметил одну вещь: в разделе phpinfo() о модуле OpenSSL по-прежнему упоминается моя старая версия OpenSSL (OpenSSL 1.0.1e-fips), хотя версия OpenSSL, упомянутая в модуле cURL, указывает OpenSSL 1.1.0f.

Я установил PHP 7.1 (в настоящее время он имеет версию 7.1.7) из репозитория Remi, может быть, он создан для более старой версии OpenSSL, поэтому он не будет работать с моей новой версией? Я также читал, что поддержка HTTP/2 в PHP 7 не совсем очевидна, но я думаю, что это не должно быть проблемой, верно?

Или проблема не в OpenSSL, и мне следует искать в другом месте, возможно, компилируя PHP из исходного кода с некоторыми предполагаемыми флагами?


person kasimir    schedule 07.07.2017    source источник
comment
Возможный дубликат Выполнить запрос HTTP/2 с помощью PHP   -  person miken32    schedule 27.07.2017


Ответы (2)


После некоторой возни я могу получить ответ HTTP/2 через вызов PHP cURL с PHP-пакетами Remi и свежесобранным cURL/OpenSSL.

Я использовал этот фрагмент кода для тестирования (взято из здесь):

if (curl_version()["features"] & CURL_VERSION_HTTP2 !== 0) {
    $url = "https://www.google.com/";
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            =>$url,
        CURLOPT_HEADER         =>true,
        CURLOPT_NOBODY         =>true,
        CURLOPT_RETURNTRANSFER =>true,
        CURLOPT_HTTP_VERSION   =>CURL_HTTP_VERSION
CURLOPT_HTTP_VERSION => 3
0, ]); $response = curl_exec($ch); if ($response !== false && strpos($response, "HTTP/2.0") === 0) { echo "HTTP/2 support!"; } elseif ($response !== false) { echo "No HTTP/2 support on server."; } else { echo curl_error($ch); } curl_close($ch); } else { echo "No HTTP/2 support on client."; }

Требовались доработки:

CURLOPT_HTTP_VERSION => 3

...а также:

if ($response !== false && strpos($response, "HTTP/2") === 0)

Поэтому вместо CURL_HTTP_VERSION_2_0 в качестве версии HTTP в параметрах cURL я использовал 3, что должно означать то же самое, но, видимо, PHP не подбирает правильное значение при использовании CURL_HTTP_VERSION_2_0.

Глядя на необработанный ответ, я заметил, что Google отправляет обратно HTTP/2 вместо HTTP/2.0.

Я надеюсь, что это может помочь кому-то!

person kasimir    schedule 14.07.2017

Пакеты в моем репозитории созданы на основе стандартного базового репозитория, поэтому OpenSSL 1.0.1e и Curl 7.29.0 (с использованием NSS).

Таким образом, вам нужно перестроить ВСЕ, что использует библиотеку тезисов, чтобы воспользоваться новыми функциями (включая PHP).

person Remi Collet    schedule 09.07.2017
comment
Я рассматривал это, но надеялся, что это не понадобится, так как у меня уже были Apache, cURL и OpenSSL. Однако, похоже, это можно сделать (см. мой ответ на мой собственный вопрос). - person kasimir; 14.07.2017