Ошибка настраиваемого SSLContext Hyper HTTP2

Я пытаюсь сделать 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


person naren    schedule 25.07.2017    source источник


Ответы (1)


При использовании HTTP / 2 поверх TLS клиент должен согласовать использование HTTP / 2 с сервером:

реализации, поддерживающие HTTP / 2 через TLS, ДОЛЖНЫ использовать согласование протокола в TLS [TLS-ALPN]

Это делается через ALPN (и исторически это делалось с помощью NPN - отсюда и появляется сообщение об ошибке). Это означает, что при настройке контекста вы должны объявить, что клиент поддерживает HTTP / 2 в сообщении TLS ClientHelo.

context.set_alpn_protocols(['h2'])
person Frederik Deweerdt    schedule 25.07.2017
comment
Пытался, не повезло, узнал от гипер-разработчиков, правильный способ создания контекста - ssl_context = init_context(), и я ищу способ делать запросы к серверу с поддержкой SNI. - person naren; 31.07.2017