【问题标题】:How to detect if a site supports HTTP/2 in PHP如何在 PHP 中检测站点是否支持 HTTP/2
【发布时间】:2018-05-01 15:12:51
【问题描述】:

PHP 中是否有一种简单的方法来测试 URL 是否支持 HTTP/2?我尝试按照HTTP/2 identification in the specs 检查curl_setopt($curl, CURLOPT_HEADER, true) 中的连接升级或h2。有许多站点可以添加 URL,它会告诉站点是否支持 HTTP/2。只是想知道他们是如何测试它的,以及是否可以在 PHP 中完成类似的事情。在命令行我可以做类似$ curl -vso --http2 https://www.example.com/

【问题讨论】:

    标签: php https http-headers http2


    【解决方案1】:

    2021 年 2 月 25 日更新
    正如mentioneddjdance 一样,HTTP/2.0 已经成为HTTP/2 有一段时间了。因此,您真的应该检查 HTTP/2(以及即将到来的 HTTP 3 的 HTTP/3)。

    如果您不想使用strpos,现在也可以在使用 PHP 8 时使用 str_starts_with($response, "HTTP/2")。否则,您可以在 PHP 7 中使用 substr($response, 0, 6) === "HTTP/2"

    对于 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,它是基于 TLS 的 HTTP/2):

    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);
    

    【讨论】:

    • 注意,这个 URL (google.com) 是通过“HTTP/2”(没有零点)回答的,所以从 strpos 中裁剪它
    • @djdance 感谢您告诉我!我已经更新了答案以反映这一点以及最新 PHP 版本中的更改,因为您现在可以使用 curl_getinfo() 检查请求使用的 HTTP 版本。
    • 你是明星。突然之间,没有一个 API 请求对标头中的 API 密钥进行识别,所以在阅读了您的帖子后,我意识到我们正在检查大写的 API 密钥,因此修改了我的代码以检查两者并再次工作。 A+++
    猜你喜欢
    • 2019-06-03
    • 2017-01-01
    • 2016-09-07
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多