我正试图将hyper.contrib
HTTP20Adapter
与此处所述的requests
模块一起使用,但即使按照使用HTTP/2的示例进行操作,它仍然使用HTTP/1.1。这导致ConnectionResetError
和HTTP/2从未尝试过。如果我使用hyper HTTPConnection
,它也会使用HTTP/1.1并失败。但如果我使用HTTP20Connection
,它使用HTTP/2并成功。有没有办法强制requests
和HTTP20Adapter
只使用HTTP/2?
第一次测试,使用HTTPConnection
。wireshark跟踪确认这导致了HTTP/1.1 GET和连接重置。
>>> from hyper import HTTPConnection
>>> c = HTTPConnection('10.11.22.33:8080')
>>> c.request('GET', '/my/path/')
>>> resp = c.get_response()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/common/connection.py", line 129, in get_response
return self._conn.get_response(*args, **kwargs)
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/http11/connection.py", line 203, in get_response
self._sock.fill()
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/common/bufsocket.py", line 169, in fill
raise ConnectionResetError()
ConnectionResetError
第二次测试,使用HTTP20Connection
。这导致了HTTP/2 GET请求和成功的响应。
>>> from hyper import HTTP20Connection
>>> c = HTTP20Connection('10.11.22.33:8080')
>>> c.request('GET', '/my/path/')
1
>>> resp = c.get_response()
>>> print(resp.headers)
HTTPHeaderMap([(b'server', b'nginx/1.14.1'), (b'date', b'Wed, 12 Aug 2020 13:29:34 GMT'), (b'content-type', b'application/problem+json'), (b'3gpp-sbi-message-priority', b'10'), (b'x-envoy-upstream-service-time', b'109')])
第三个测试,使用带适配器的requests
。这也导致了HTTP/1.1请求和ConnectionResetError
。在网络上看不到HTTP/2。
>>> import requests
>>> from hyper.contrib import HTTP20Adapter
>>>
>>> s = requests.Session()
>>> s.mount('http://10.11.22.33:8080', HTTP20Adapter())
>>> s
<requests.sessions.Session object at 0x7f68f3487f28>
>>>
>>>
>>> r = s.get('http://10.11.22.33:8080/my/path/')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/Python/myApp/lib64/python3.6/site-packages/requests/sessions.py", line 543, in get
return self.request('GET', url, **kwargs)
File "/root/Python/myApp/lib64/python3.6/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/root/Python/myApp/lib64/python3.6/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/contrib.py", line 80, in send
resp = conn.get_response()
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/common/connection.py", line 129, in get_response
return self._conn.get_response(*args, **kwargs)
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/http11/connection.py", line 203, in get_response
self._sock.fill()
File "/root/Python/myApp/lib64/python3.6/site-packages/hyper/common/bufsocket.py", line 169, in fill
raise ConnectionResetError()
ConnectionResetError
我真的需要完成最后一个测试,因为我的框架的其余部分都在使用requests
模块。
我建议您在这里使用猴痘。
写一个自定义请求,如下所示,使用HTTP20Connection而不是HTTP11Connection
from hyper.http20.connection import HTTP20Connection
def custom_request(self, method, url, body=None, headers=None):
headers = headers or {}
if self._conn.__class__.__name__ == 'HTTP11Connection':
self._conn = HTTP20Connection(
self._host, self._port, **self._h2_kwargs
)
try:
return self._conn.request(
method=method, url=url, body=body, headers=headers
)
except TLSUpgrade as e:
assert e.negotiated in H2_NPN_PROTOCOLS
self._conn = HTTP20Connection(
self._host, self._port, **self._h2_kwargs
)
self._conn._sock = e.sock
self._conn._send_preamble()
return self._conn.request(
method=method, url=url, body=body, headers=headers
)
之后,您可以按以下进行猴痘接种
from hyper.common.connection import HTTPConnection
HTTPConnection.request = custom_request