#python #apple-push-notifications #http2 #httpx
Вопрос:
Я работаю над push-уведомлениями в Apple Push-уведомлениях , которые используют только HTTP/2 (следовательно, использование requests
невозможно), и продолжаю получать httpx.RemoteProtocolError: illegal request line
. Я понятия не имею, что это значит:
>>> import httpx
>>> httpx.__version__
'0.18.2'
>>> httpx.post('https://api.development.push.apple.com:443/3/device/<device-token>')
Traceback (most recent call last):
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_transports/default.py", line 61, in map_httpcore_exceptions
yield
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_transports/default.py", line 181, in handle_request
status_code, headers, byte_stream, extensions = self._pool.handle_request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpcore/_sync/connection_pool.py", line 237, in handle_request
response = connection.handle_request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpcore/_sync/connection.py", line 148, in handle_request
return self.connection.handle_request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 128, in handle_request
) = self._receive_response(timeout)
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 189, in _receive_response
event = self._receive_event(timeout)
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 222, in _receive_event
event = self._h11_state.next_event()
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.RemoteProtocolError: illegal request line
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_api.py", line 304, in post
return request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_api.py", line 100, in request
return client.request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_client.py", line 785, in request
return self.send(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_client.py", line 871, in send
response = self._send_handling_auth(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_client.py", line 907, in _send_handling_auth
response = self._send_handling_redirects(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_client.py", line 943, in _send_handling_redirects
response = self._send_single_request(request, timeout)
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_client.py", line 977, in _send_single_request
(status_code, headers, stream, extensions) = transport.handle_request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_transports/default.py", line 181, in handle_request
status_code, headers, byte_stream, extensions = self._pool.handle_request(
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "/home/martin/.pyenv/versions/3.8.9/lib/python3.8/site-packages/httpx/_transports/default.py", line 78, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.RemoteProtocolError: illegal request line
Как я могу расследовать это дальше? В чем же проблема? (Я удалил заголовки / полезную нагрузку / маркер устройства для этого вопроса; Я продолжаю получать эту проблему)
локон
С curl
помощью я получаю ожидаемый результат:
curl -X POST https://api.development.push.apple.com:443/3/device/adsf -v
* Trying 17.188.138.70:443...
* TCP_NODELAY set
* Connected to api.development.push.apple.com (17.188.138.70) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=api.development.push.apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US
* start date: Feb 8 21:41:22 2021 GMT
* expire date: Mar 10 21:41:22 2022 GMT
* subjectAltName: host "api.development.push.apple.com" matched cert's "api.development.push.apple.com"
* issuer: CN=Apple Public Server RSA CA 12 - G1; O=Apple Inc.; ST=California; C=US
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5606c3af1e10)
> POST /3/device/adsf HTTP/2
> Host: api.development.push.apple.com
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 1)!
< HTTP/2 403
< apns-id: DFA9D8D5-D99D-26B0-9EA3-95076FF3B575
<
* Connection #0 to host api.development.push.apple.com left intact
{"reason":"MissingProviderToken"}
С помощью HTTPX_LOG_LEVEL=трассировка
См. Документы httpx о переменных среды
HTTPX_LOG_LEVEL=trace python example.py
trace
TRACE [2021-09-07 15:46:26] httpx._config - load_ssl_context verify=True cert=None trust_env=True http2=False
TRACE [2021-09-07 15:46:26] httpx._config - load_verify_locations cafile=/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/certifi/cacert.pem
TRACE [2021-09-07 15:46:26] httpcore._sync.connection_pool - get_connection_from_pool=(b'https', b'api.development.push.apple.com', 443)
TRACE [2021-09-07 15:46:26] httpcore._sync.connection_pool - created connection=<SyncHTTPConnection [Connecting]>
TRACE [2021-09-07 15:46:26] httpcore._sync.connection_pool - adding connection to pool=<SyncHTTPConnection [Connecting]>
TRACE [2021-09-07 15:46:26] httpcore._sync.connection - open_socket origin=(b'https', b'api.development.push.apple.com', 443) timeout={'connect': 5.0, 'read': 5.0, 'write': 5.0, 'pool': 5.0}
TRACE [2021-09-07 15:46:27] httpcore._sync.connection - create_connection socket=<httpcore._backends.sync.SyncSocketStream object at 0x7fdbdc632cd0> http_version='HTTP/1.1'
TRACE [2021-09-07 15:46:27] httpcore._sync.connection - connection.handle_request method=b'POST' url=(b'https', b'api.development.push.apple.com', None, b'/3/device/') headers=[(b'Host', b'api.development.push.apple.com'), (b'Content-Length', b'0'), (b'Accept', b'*/*'), (b'Accept-Encoding', b'gzip, deflate'), (b'Connection', b'keep-alive'), (b'User-Agent', b'python-httpx/0.19.0')]
TRACE [2021-09-07 15:46:27] httpcore._sync.http11 - send_request method=b'POST' url=(b'https', b'api.development.push.apple.com', None, b'/3/device/') headers=[(b'Host', b'api.development.push.apple.com'), (b'Content-Length', b'0'), (b'Accept', b'*/*'), (b'Accept-Encoding', b'gzip, deflate'), (b'Connection', b'keep-alive'), (b'User-Agent', b'python-httpx/0.19.0')]
TRACE [2021-09-07 15:46:27] httpcore._sync.http11 - send_data=Data(<0 bytes>)
TRACE [2021-09-07 15:46:27] httpcore._sync.connection_pool - remove from pool connection=<SyncHTTPConnection [HTTP/1.1, ACTIVE]>
TRACE [2021-09-07 15:46:27] httpcore._sync.connection_pool - removing connection from pool=<SyncHTTPConnection [HTTP/1.1, ACTIVE]>
Traceback (most recent call last):
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_transports/default.py", line 61, in map_httpcore_exceptions
yield
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_transports/default.py", line 180, in handle_request
status_code, headers, byte_stream, extensions = self._pool.handle_request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 237, in handle_request
response = connection.handle_request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 148, in handle_request
return self.connection.handle_request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpcore/_sync/http11.py", line 128, in handle_request
) = self._receive_response(timeout)
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpcore/_sync/http11.py", line 189, in _receive_response
event = self._receive_event(timeout)
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpcore/_sync/http11.py", line 222, in _receive_event
event = self._h11_state.next_event()
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/contextlib.py", line 135, in __exit__
self.gen.throw(type, value, traceback)
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.RemoteProtocolError: illegal request line
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/moose/example.py", line 5, in <module>
print(httpx.post('https://api.development.push.apple.com:443/3/device/<device-token>'))
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_api.py", line 304, in post
return request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_api.py", line 100, in request
return client.request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_client.py", line 787, in request
return self.send(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_client.py", line 878, in send
response = self._send_handling_auth(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_client.py", line 908, in _send_handling_auth
response = self._send_handling_redirects(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_client.py", line 947, in _send_handling_redirects
response = self._send_single_request(request, timeout)
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_client.py", line 983, in _send_single_request
(status_code, headers, stream, extensions) = transport.handle_request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_transports/default.py", line 180, in handle_request
status_code, headers, byte_stream, extensions = self._pool.handle_request(
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/contextlib.py", line 135, in __exit__
self.gen.throw(type, value, traceback)
File "/home/moose/.pyenv/versions/3.9.1/lib/python3.9/site-packages/httpx/_transports/default.py", line 78, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.RemoteProtocolError: illegal request line
Комментарии:
1. См. также: github.com/encode/httpx/discussions/1841
Ответ №1:
Проблема заключалась в том, что вам необходимо установить дополнительные зависимости и явно включить http2:
$ pip install httpx[http2]
И
import httpx
client = httpx.Client(http2=True)
client.post('https://api.development.push.apple.com:443/3/device/<device-token>')