【问题标题】:How can I make a pycurl http2 request?如何发出 pycurl http2 请求?
【发布时间】:2017-08-04 21:09:44
【问题描述】:

我正在尝试通过 pycurl 发出 http2 请求。我已经安装了 libcurl 需要的 nghttp2 c 库,并且可以使用 curl 执行 http2 请求。

我用 pycurl 尝试过这样的事情:

import pycurl
import cStringIO


if __name__ == '__main__':
    c = pycurl.Curl()

    buf = cStringIO.StringIO()

    c = pycurl.Curl()
    c.setopt(c.URL, 'https://nghttp2.org')
    c.setopt(pycurl.HTTP_VERSION, pycurl.VERSION_HTTP2)
    c.setopt(c.WRITEFUNCTION, buf.write)
    c.setopt(pycurl.VERBOSE, 1)
    c.perform()

    buf.close()

我得到的输出是:

* Rebuilt URL to: https://nghttp2.org/
*   Trying 106.186.112.116...
* Connected to nghttp2.org (106.186.112.116) port 443 (#0)
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
 CApath: none
* NPN, negotiated HTTP1.1
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*    subject: CN=nghttp2.org
*    start date: Jan 21 22:58:00 2017 GMT
*    expire date: Apr 21 22:58:00 2017 GMT
*    subjectAltName: nghttp2.org matched
*    issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*    SSL certificate verify ok.
> GET / HTTP/1.1
Host: nghttp2.org
User-Agent: PycURL/7.43.0 libcurl/7.46.0 OpenSSL/1.0.1f zlib/1.2.8          libidn/1.28 nghttp2/1.21.0-DEV librtmp/2.3
Accept: */*
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings:

< HTTP/1.1 200 OK
< Date: Tue, 14 Mar 2017 13:33:48 GMT
< Content-Type: text/html
< Last-Modified: Sun, 26 Feb 2017 12:19:00 GMT
< Etag: "58b2c7b4-19e1"
< Accept-Ranges: bytes
< Content-Length: 6625
< X-Backend-Header-Rtt: 0.001418
< Strict-Transport-Security: max-age=31536000
< Server: nghttpx
< Via: 2 nghttpx
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
<
* Connection #0 to host nghttp2.org left intact

我在这个请求中做错了什么?

编辑: 根据评论,我确保 pycurl 使用 OpenSSL/1.0.2k。现在User-Agent 标头看起来像这样: User-Agent: PycURL/7.43.0 libcurl/7.46.0 OpenSSL/1.0.2k zlib/1.2.11 libidn/1.28 nghttp2/1.21.0-DEV librtmp/2.3 但我得到与上面相同的结果。

【问题讨论】:

    标签: python curl httprequest http2 pycurl


    【解决方案1】:

    似乎 pycurl 脚本使用了错误的 http 版本常量。正确的是c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_0)

    【讨论】:

      【解决方案2】:

      您在此处使用的那个 libcurl 版本表明它是使用 OpenSSL/1.0.1f 构建的。 1.0.2 之前的 OpenSSL 不支持 ALPN,这是在大多数当前 HTTPS 站点上协商 HTTP/2 所需的 TLS 扩展。 (有些仍然支持旧的 NPN 扩展,但它越来越少了,特别是因为没有浏览器不再使用 NPN。)

      想必,你说的curl命令行工具用的libcurl成功了,用别的安装?

      最后,提供您所做的那些自定义标头可能只会冒破坏您的操作的风险,而不是帮助它。当 libcurl 与站点协商 HTTP/2 时,它会自动使用必要的标头。

      【讨论】:

      • 根据您的评论,我已于 2015 年 3 月 19 日安装了 OpenSSL 1.0.2a。我再次尝试了我的脚本,发现它使用的是旧版本。如何强制pycurl使用新版本的OpenSSL?
      • (您应该使用 1.0.2k 来避免很多错误。)您可能编辑 /etc/ld.so。 conf,重新加载ldconfig或设置LD_LIBRARY_PATH...
      • 我设法让 pycurl 使用 OpenSSL/1.0.2k 但我仍然得到相同的结果。我还删除了额外的标题。
      猜你喜欢
      • 2019-02-12
      • 2013-06-09
      • 2023-01-14
      • 2019-06-26
      • 2016-03-31
      • 2018-09-03
      • 1970-01-01
      • 2020-02-09
      • 2021-10-25
      相关资源
      最近更新 更多