如何在PHP中检测网站是否支持HTTP/2

12

在PHP中,有没有一种简单的方法来测试URL是否支持HTTP/2?我尝试检查连接升级或curl_setopt($curl, CURLOPT_HEADER, true)中的h2,就像规范中的HTTP/2标识。有许多网站可以添加URL并告诉您该网站是否支持HTTP/2。只是想知道他们如何进行测试,是否可以在PHP中进行类似的操作。在命令行上,我可以做类似以下的操作:$ curl -vso --http2 https://www.example.com/

1个回答

20
更新于2021年2月25日:
正如提到的那样,djdance指出,HTTP/2.0已经改为HTTP/2有一段时间了。因此,您应该真正针对HTTP/2进行检查(对于即将推出的HTTP 3,也可以使用HTTP/3)。
如果您不想使用strpos,您现在还可以使用str_starts_with($response, "HTTP/2")来使用PHP 8。否则,您可以使用substr($response, 0, 6) === "HTTP/2"用于PHP 7。
对于PHP 7.3和cURL 7.50.0,curl_getinfo现在也支持CURLINFO_HTTP_VERSION
echo curl_getinfo($ch, CURLINFO_HTTP_VERSION);
// 3 for HTTP/2

可能由 CURLINFO_HTTP_VERSION 返回的值(截至 PHP 7.3):
CURL_HTTP_VERSION_NONE              === 0
CURL_HTTP_VERSION_1_0               === 1
CURL_HTTP_VERSION_1_1               === 2
CURL_HTTP_VERSION_2                 === 3
CURL_HTTP_VERSION_2_0               === 3
CURL_HTTP_VERSION_2TLS              === 4
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE === 5

这意味着您可以检查特定的协议版本(例如,CURL_HTTP_VERSION_2TLS,即HTTP/2 over TLS):
if (
    $response !== false
    && curl_getinfo($ch, CURLINFO_HTTP_VERSION) === CURL_HTTP_VERSION_2TLS
) {
    // The connection was established using HTTP/2 over TLS
    // if the server does not support TLS HTTP/1.1 will be used.
}

翻译:
您的服务器和cURL安装都需要支持HTTP/2.0。之后,您只需进行普通的cURL请求并添加CURLOPT_HTTP_VERSION参数,这将使cURL尝试进行HTTP/2.0请求。之后,您需要检查请求的头信息以确定服务器是否确实支持HTTP/2.0。

示例:

$url = "https://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_2_0, // cURL will attempt to make an HTTP/2.0 request (can downgrade to HTTP/1.1)
]);
$response = curl_exec($ch);

现在您需要检查 cURL 是否确实发出了一个 HTTP/2.0 请求:
if ($response !== false && strpos($response, "HTTP/2.0") === 0) {
    echo "Server of the URL has HTTP/2.0 support."; // yay!
} elseif ($response !== false) {
    echo "Server of the URL has no HTTP/2.0 support."; // nope!
} else {
    echo curl_error($ch); // something else happened causing the request to fail
}
curl_close($ch);

1
请注意,此URL(google.com)由“HTTP / 2”(无小数点)响应,请在strpos中截断它。 - djdance
@djdance 感谢您告诉我!我已经更新了答案,以反映最新的PHP版本中的更改,现在您可以使用 curl_getinfo() 来检查请求使用的HTTP版本。 - Tom Udding
你真是个明星。突然间,所有的 API 请求都无法识别头部中的 API 密钥,所以在阅读了你的帖子后,我意识到我们检查 API 密钥时使用了大写字母,于是修改了我的代码以检查大小写,现在又可以正常工作了。A+++ - Craig Edmonds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接