Aiohttp:如何在标头中发送字节?

Posted

技术标签:

【中文标题】Aiohttp:如何在标头中发送字节?【英文标题】:Aiohttp: How to send bytes in headers? 【发布时间】:2018-06-07 01:48:42 【问题描述】:

我正在尝试通过 aiohttp 将字节作为标头值发送:

payload = 
#ommited for brevity


encoded_payload = str.encode(json.dumps(payload))
b64 = base64.b64encode(encoded_payload)

# sign the requests
signature = hmac.new(str.encode(keys['private']), b64, hashlib.sha384).hexdigest()

headers = 
        'Content-Type': 'text/plain',
        'APIKEY': keys['public'],
        'PAYLOAD': b64, // base64 value
        'SIGNATURE': signature
    

async with aiohttp.request(method="POST", url="example.com", headers=headers) as response:
    print(await response.text())

但是,我收到一个错误:

Traceback(最近一次调用最后一次): 文件“get_gem.py”,第 34 行,在 loop.run_until_complete(get_gemini()) 文件“/home/thorad/anaconda3/lib/python3.6/asyncio/base_events.py”,第 466 行,在 run_until_complete 返回future.result() 文件“get_gem.py”,第 29 行,在 get_gemini 中 与 aiohttp.request(method="POST", url=base_url + payload["request"], headers=headers) 异步作为响应: aenter 中的文件“/home/thorad/anaconda3/lib/python3.6/site-packages/aiohttp/client.py”,第 692 行 self._resp = self._coro 的产量 _request 中的文件“/home/thorad/anaconda3/lib/python3.6/site-packages/aiohttp/client.py”,第 277 行 resp = req.send(conn) 发送中的文件“/home/thorad/anaconda3/lib/python3.6/site-packages/aiohttp/client_reqrep.py”,第 463 行 writer.write_headers(status_line,self.headers) 文件“/home/thorad/anaconda3/lib/python3.6/site-packages/aiohttp/http_writer.py”,第 247 行,在 write_headers [k + SEP + v + END for k, v in headers.items()]) 文件“/home/thorad/anaconda3/lib/python3.6/site-packages/aiohttp/http_writer.py”,第 247 行,在 [k + SEP + v + END for k, v in headers.items()]) TypeError: 必须是 str,而不是 bytes

这表明我不能将字节作为标头发送。

很遗憾,我正在使用的服务要求我这样做,否则它会返回错误。

我已尝试删除 'Content-Type': 'text/plain'

如何通过 aiohttp 将字节作为标头发送? 感谢您的帮助。

【问题讨论】:

【参考方案1】:

这里的问题是 b64encode 返回字节,但这些可以很容易地转换为正确的 unicode 字符串。它不会对您的服务器产生影响。

>>> b64 = base64.b64encode(b'...')
>>> type(b64)
<class 'bytes'>
>>> b64 = base64.b64encode(b'...').decode('utf8')
>>> type(b64)
<class 'str'>

【讨论】:

【参考方案2】:

将payload转换成ascii:

payload = 
#ommited for brevity


encoded_payload = str.encode(json.dumps(payload))
b64 = base64.b64encode(encoded_payload)
b64 = b4.decode('ascii')  # conversion back to unicode

# sign the requests
signature = hmac.new(str.encode(keys['private']), b64, hashlib.sha384).hexdigest()

headers = 
        'Content-Type': 'text/plain',
        'APIKEY': keys['public'],
        'PAYLOAD': b64, // base64 value
        'SIGNATURE': signature
    

async with aiohttp.request(method="POST", url="example.com", headers=headers) as response:
    print(await response.text())

【讨论】:

以上是关于Aiohttp:如何在标头中发送字节?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 aiohttp 制作 reddit discord bot

aiohttp 异步http请求-9.ClientSession自定义请求头部

如何检测 WAV 文件的标头是 44 字节还是 46 字节?

如何在 ASP.NET Core Web API 控制器中接收字节数组和标头内容

如何在 JmsTemplate 中发送标头消息?

如何在scrapy中发送带有标头和有效负载的Post请求