在 Python 3 中为 HTTP 请求创建带有二进制组件的多部分 MIME 消息
Posted
技术标签:
【中文标题】在 Python 3 中为 HTTP 请求创建带有二进制组件的多部分 MIME 消息【英文标题】:Creating a multi-part MIME message with a binary component for an HTTP request in Python 3 【发布时间】:2013-10-01 08:42:48 【问题描述】:我正在尝试使用 Python 3.3 中的 MIMEApplication 对二进制文件进行编码,作为多部分 MIME HTTP POST 的一部分。我有一个问题,字符 0x0d 被重新解释为换行符 0xa,尽管所有内容都设置为二进制字节。
这是一个最小的测试场景,其中包含一个带有 0x0d 的二进制字符串,但会被误解:
from email.encoders import encode_noop
from email.generator import BytesGenerator
from email.mime.application import MIMEApplication
import io
app = MIMEApplication(b'Q\x0dQ', _encoder=encode_noop)
b = io.BytesIO()
g = BytesGenerator(b)
g.flatten(app)
for i in b.getvalue()[-3:]:
print("%02x " % i, end="")
print()
当它应该是51 0d 51
时,输出是:51 0a 51
请注意,这是为多部分 http POST 消息生成二进制部分。
【问题讨论】:
【参考方案1】:尝试以下(不指定编码器,使用默认 base64 编码器):
import email
from email.encoders import encode_noop
from email.generator import BytesGenerator
from email.mime.application import MIMEApplication
import io
app = MIMEApplication(b'Q\x0dQ')
b = io.BytesIO()
g = BytesGenerator(b)
g.flatten(app)
msg = email.message_from_bytes(b.getvalue())
assert msg.get_payload(decode=True) == b'Q\x0dQ'
【讨论】:
谢谢!你是对的,这回答了所问的问题。但是您知道我如何将其用作 MIME 多部分消息的一部分吗?这就是我实际需要使用它的方式。【参考方案2】:我能够通过在 MIMEApplication 内容中放置一个虚拟“标记”来解决我的问题,然后在生成 MIME 消息后替换为真正的二进制文本:
from email.encoders import encode_noop
from email.generator import BytesGenerator
from email.mime.application import MIMEApplication
import io
# Actual binary "file" I want to encode (in real life, this is a file read from disk)
bytesToEncode = b'Q\x0dQ'
# unique marker that we can find and replace after message generation
binarymarker = b'GuadsfjfDaadtjhqadsfqerasdfiojBDSFGgg'
app = MIMEApplication(binarymarker, _encoder=encode_noop)
b = io.BytesIO()
g = BytesGenerator(b)
g.flatten(app, linesep='\r\n') # linesep for HTTP-compliant header line endings
# replace the marker with the actual binary data, then you have the output you want!
body = b.getvalue().replace(binarymarker, bytesToEncode)
在此之后,body
具有我想要的值,而不会弄乱二进制字节:
b'Content-Type: application/octet-stream\r\nMIME-Version: 1.0\r\n\r\nQ\rQ'
对于多部分消息,您只需先组装多部分消息,然后在最后执行替换()。
【讨论】:
以上是关于在 Python 3 中为 HTTP 请求创建带有二进制组件的多部分 MIME 消息的主要内容,如果未能解决你的问题,请参考以下文章
Ajax 请求复杂类型在 ApiController 参数中为空
通过 iis 上的 python 脚本处理带有 json 的 http post 请求