Python 我应该如何配置我的头以向APNs发送HTTP/2 POST以避免;收到重复的伪报头字段“;错误?
我对HTTP非常陌生,主要是iOS,所以请耐心听我说。 我正在使用httpxpython库尝试向iPhone发送通知,因为我必须发送HTTP/2 POST才能这样做。苹果的文档说它需要“:method”和“:path”标题,但当我试图在文章中包含这些标题时Python 我应该如何配置我的头以向APNs发送HTTP/2 POST以避免;收到重复的伪报头字段“;错误?,python,ios,http2,Python,Ios,Http2,我对HTTP非常陌生,主要是iOS,所以请耐心听我说。 我正在使用httpxpython库尝试向iPhone发送通知,因为我必须发送HTTP/2 POST才能这样做。苹果的文档说它需要“:method”和“:path”标题,但当我试图在文章中包含这些标题时 headers = { ':method' : 'POST', ':path' : '/3/device/{}'.format(deviceToken), ... } 我得到了错误 h2.except
headers = {
':method' : 'POST',
':path' : '/3/device/{}'.format(deviceToken),
...
}
我得到了错误
h2.exceptions.ProtocolError:收到重复的伪标头字段b':路径
很明显,包含“:path”标题有问题,但我也需要发送它,所以我不确定我做错了什么。苹果公司的文件也说
将:path和authorization值编码为文本头字段,无需索引
使用增量索引将所有其他字段编码为文字标题字段
我真的不知道这意味着什么,也不知道如何实现,也不知道这是否相关。我认为httpx会将我的“:path”头与默认头合并以消除重复项,但我只是在这里胡说
完全回溯
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpx/_client.py", line 992, in post
return self.request(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpx/_client.py", line 733, in request
return self.send(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpx/_client.py", line 767, in send
response = self._send_handling_auth(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpx/_client.py", line 805, in _send_handling_auth
response = self._send_handling_redirects(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpx/_client.py", line 837, in _send_handling_redirects
response = self._send_single_request(request, timeout)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpx/_client.py", line 861, in _send_single_request
(status_code, headers, stream, ext) = transport.request(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 218, in request
response = connection.request(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 106, in request
return self.connection.request(method, url, headers, stream, ext)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpcore/_sync/http2.py", line 119, in request
return h2_stream.request(method, url, headers, stream, ext)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpcore/_sync/http2.py", line 292, in request
self.send_headers(method, url, headers, has_body, timeout)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpcore/_sync/http2.py", line 330, in send_headers
self.connection.send_headers(self.stream_id, headers, end_stream, timeout)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/httpcore/_sync/http2.py", line 227, in send_headers
self.h2_state.send_headers(stream_id, headers, end_stream=end_stream)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/h2/connection.py", line 770, in send_headers
frames = stream.send_headers(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/h2/stream.py", line 865, in send_headers
frames = self._build_headers_frames(
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/h2/stream.py", line 1252, in _build_headers_frames
encoded_headers = encoder.encode(headers)
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/hpack/hpack.py", line 249, in encode
for header in headers:
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/h2/utilities.py", line 496, in inner
for header in headers:
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/h2/utilities.py", line 441, in _validate_host_authority_header
for header in headers:
File "/Users/User/.pyenv/versions/3.9.0/lib/python3.9/site-packages/h2/utilities.py", line 338, in _reject_pseudo_header_fields
raise ProtocolError(
h2.exceptions.ProtocolError: Received duplicate pseudo-header field b':method'
请求:
devServer = "https://api.sandbox.push.apple.com:443"
title = "some title"
notification = { "aps": { "alert": title, "sound": "someSound.caf" } }
client = httpx.Client(http2=True)
try:
r = client.post(devServer, json=notification, headers=headers)
finally:
client.close()
只需将
'/3/device/{}.format(deviceToken)
作为路径附加到devServer url,并且“:path”伪头将自动设置为它
就是
devServer = 'https://api.sandbox.push.apple.com:443/3/device/{}'.format(deviceToken)
说明:
通常不需要在http2中手动添加“:path”、“:method”和“:scheme”伪头
参考资料:您的http请求调用是什么样子?@C.Nivs将其添加到我的问题中。从您的标题中取出“:path”&“:method”-通过http2,httpx会自动将其放入。(我使用了差不多相同的代码,减去那些头!)@Sebastian那么我如何在没有“:path”头的情况下传递设备令牌呢?我想我可以不使用“:method”,因为POST是可以推断出来的,但我只是不确定如何传递设备令牌信息,否则…@Jake将路径放入传递给POST函数的URL中。现在,您只需将其放入
devServer
,改为如下:'{}/3/device/{}.format(devServer,deviceToken)