尝试在HTTP / 2上进行POST,但libcurl在HTTP / 1.1上进行连接

时间:2019-05-28 08:50:54

标签: ubuntu-16.04 libcurl http2

我已经开发了一个客户端应用程序,以使用libcurl在HTTP / 2上连接自定义服务器。它可以在Ubuntu 18.04上完美运行。顺便说一句,在Ubuntu 16.04中,它选择的是HTTP / 1.1,而不是HTTP / 2。

我发现需要在16.04上安装nghttp2库,因此我安装了它,然后我发现ALPN也提供h2。但最终它仍然使用HTTP / 1.1。

    CURL *curl;
    CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT);
    if(res != CURLE_OK) {
        fprintf(stderr, "curl_global_init() failed: %s\n",
                curl_easy_strerror(res));
        return 1;
    }

    curl = curl_easy_init();
    if(curl) {
        struct curl_slist *headerList = agent->getHeaderList();

        /* what call to write: */
        curl_easy_setopt(curl, CURLOPT_URL, agent->getUrl().c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, ASR_CLIENT_DEBUG ? 1L : 0L);

        CURLcode rv;
        do { /* dummy loop, just to break out from */
            rv = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
            rv = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
            rv = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, ConnectAgent::headerCallback);
            rv = curl_easy_setopt(curl, CURLOPT_HEADERDATA, agent);
            rv = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ConnectAgent::bodyCallback);
            rv = curl_easy_setopt(curl, CURLOPT_WRITEDATA, agent);

            rv = curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
            rv = curl_easy_setopt(curl, CURLOPT_POST, 1L);
            rv = curl_easy_setopt(curl, CURLOPT_READFUNCTION, ConnectAgent::readToVoiceServerCallback);
            rv = curl_easy_setopt(curl, CURLOPT_READDATA, agent);

            /* Perform the request, res will get the return code */
            res = curl_easy_perform(curl);

            /* Check for errors */
            if(res != CURLE_OK)
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(res));

            /* we are done... */
        } while(0);
        /* always cleanup */
        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();

在Ubuntu 16.04中,似乎HTTP2已准备就绪,但实际连接在HTTP / 1.1上

*   Trying xx.xxx.xxx.xxx...
* Connected to xxx.xxx.xxx.xxx (xx.xxx.xxx.xxx) port xxxxx (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: -----------------------
  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*    subject: C=Unknown; ST=Unknown; L=Unknown; O=Mort Bay Consulting Pty. Ltd.; OU=Jetty; CN=jetty.eclipse.org
*    start date: May 20 11:38:03 2015 GMT
*    expire date: Aug 18 11:38:03 2015 GMT
*    issuer: C=Unknown; ST=Unknown; L=Unknown; O=Mort Bay Consulting Pty. Ltd.; OU=Jetty; CN=jetty.eclipse.org
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* TCP_NODELAY set
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f40f00008c0)
> POST /voice HTTP/1.1

使用相同的源代码在Ubuntu 18.04上构建可以在HTTP / 2上正常运行

1 个答案:

答案 0 :(得分:0)

我发现它发生在curl 7.46和curl 7.47中。当我使用curl-7.58构建库并使用它构建应用程序时,问题得以解决并且有效。