Я пытаюсь сделать HTTP2-запрос к серверу (виртуальному хосту), который выдает SSL-сертификаты на основе значения заголовка хоста (SNI).
# conn = hyper.HTTP20Connection('http2.akamai.com', port=443, ssl_context=context)
# conn.request('GET', '/path', headers={'Host': 'www.mywebsite.com'})
Пакет Hyper-h2 для Python не поддерживает SNI или отключение проверки сертификата! https://hyper.readthedocs.io/en/latest/advanced.html#ssl-tls-certificate-verification.
Один из способов отключить проверку сертификатов - настроить SSLContext и застрять в ошибке утверждения протокола.
Базовый код для вызова HTTP2 с настраиваемым SSLContext:
import ssl
import hyper
# Custom SSLCONTEXT for not verifying SSLCertificate and Hostname
# or need SSLCONTEXT for SNI support
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.verify_mode = ssl.CERT_NONE
context.check_hostname = False
hyper.tls._context = context
conn = hyper.HTTP20Connection('http2.akamai.com', port=443, ssl_context=context)
conn.request('GET', '/')
print conn.get_response()
Ошибка :
Traceback (most recent call last):
File "ssl_custom.py", line 32, in <module>
conn.request('GET', '/')
File "/usr/local/lib/python2.7/site-packages/hyper/http20/connection.py", line 281, in request
self.endheaders(message_body=body, final=True, stream_id=stream_id)
File "/usr/local/lib/python2.7/site-packages/hyper/http20/connection.py", line 544, in endheaders
self.connect()
File "/usr/local/lib/python2.7/site-packages/hyper/http20/connection.py", line 373, in connect
assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL
AssertionError
РЕДАКТИРОВАТЬ / ОБНОВЛЕНИЕ: теперь, когда я узнал, как правильно строить контекст init_context()
, проблема все еще сохраняется при запросе к серверу с поддержкой SNI.
ssl_context = init_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_OPTIONAL
headers={'Host': 'www.opentable.com'}
conn = hyper.HTTP20Connection('ev-www.opentable.com.edgekey.net', port=443, ssl_context=ssl_context)
conn.request('GET', '/washington-dc-restaurants', headers=headers)
print conn.get_response()
Выход:
assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL
Нужен способ указать SNI или эквивалент Curl --resolve в Hyper