I'm trying to check if a http service supports HTTP/2 using a python 3 script. Unfortunately, after many research and a lot of time spent on my script, I don't perform it.
Here what I have:
import sys
import http.client as HttpClient
h2c = {
"User-agent": 'python/' + str(sys.version.split()[0]),
"Connection": "Upgrade, HTTP2-Settings",
"Upgrade": "h2c",
"HTTP2-Settings": "AAMAAABkAAQAAP__",
"Accept": "*/*"
}
c = HttpClient.HTTPSConnection(ip, port) # IP and port given in arguments
c.request('HEAD', '/', None, h2c)
r = c.getresponse()
# Print result (see below)
I know it exists hyper but I don't always want SSL and currently certificate verification cannot be disabled with hyper
Here an example of my script running on localhost :
➜ http2 git:(master) ✗ python3 main.py -i localhost -p 443
HEAD / HTTP/1.1
Host: localhost
Upgrade: h2c
User-agent: python/3.4.2
Accept: */*
Connection: Upgrade, HTTP2-Settings
HTTP2-Settings: AAMAAABkAAQAAP__
HTTP/1.1 200 OK
Server: nginx/1.9.12
Date: Tue, 22 Mar 2016 15:05:15 GMT
Content-Type: text/html
Content-Length: 867
Last-Modified: Mon, 21 Mar 2016 10:03:18 GMT
Connection: keep-alive
ETag: "56efc6e6-363"
Accept-Ranges: bytes
I checked and HTTP/2 is enable on my nginx server (with curl --http2
)
If someone has an idea to force the server to reply HTTP 101 ...
HTTP/2 can be negotiated in 2 ways: via TLS by means of ALPN or via clear-text HTTP/1.1 upgrade.
What you are doing here is a mix of the two methods: you are using a TLS connection and sending a HTTP/1.1 upgrade.
What you should do instead is to use the TLS connection, specify the ALPN extension with the list of protocols supported by the client (in your case, at least h2
), then - if the server accepts to speak HTTP/2 - start sending directly HTTP/2 frames (not the HTTP/1.1 upgrade).
I am no Python expert, but it is possible to specify the ALPN protocols, see here and here.
You also want to look at other Python projects that implemented HTTP/2.