Reputation: 816
I am trying to make a http2 request through pycurl. I have installed the nghttp2 c library that libcurl needs and I am able to do an http2 request with curl.
I tried something like this with 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()
And the output that I get is:
* 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
What am I doing wrong in this request?
Edit:
As per the comment I made sure that pycurl uses OpenSSL/1.0.2k. Now the User-Agent
header looks like this:
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
but I get the same result as above.
Upvotes: 4
Views: 3297
Reputation: 816
It seems that the pycurl script was using the wrong http version constant. The correct one is c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_0)
.
Upvotes: 4
Reputation: 58034
That libcurl version you're using here identifies that it was built with OpenSSL/1.0.1f. OpenSSL before 1.0.2 doesn't have ALPN support and that's the TLS extension required to negotiate HTTP/2 on most current HTTPS sites. (Some still support the older NPN extension but its getting rarer, especially since no browser uses NPN anymore.)
Presumably, the libcurl your curl command line tool uses that you say is successful, uses another install?
Finally, providing those custom headers you do will probably only risk breaking your operation rather than help it. When libcurl negotiates HTTP/2 with a site, it uses the necessary headers automatically.
Upvotes: 1