python 3 smtplib : binary attachment encodes incorrectly in flask when gnupg is active

标签 python python-3.x mime gnupg smtplib

我正在尝试使用 python 3.5.2 smtplib 通过 TLS 发送二进制附件。我的平台是 OSX,我使用的是从自制软件安装的 python。

当我收到附件时,编码似乎已被修改。而不是以此十六进制开头的原始文件:

ffd8 ffe0 0010 4a46 4946 0001 0100 0001

i.e., <FF><D8><FF><E0>^@^PJFIF^@^A^A

我收到的附件的起始十六进制有一些奇怪的 base64 剩余部分:

5c75 6463 6666 5c75 6463 6438 5c75 6463 6666 5c75 6463 6530 0010 4a46 4946 0001

i.e., \udcff\udcd8\udcff\udce0^@^PJFIF

这是一个失败的最小案例,除了添加了 TLS 逻辑和 gnupg 之外,这与官方文档中的内容几乎完全相同:

import gnupg
gpg = gnupg.GPG('/path/to/gpg')

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

def send_my_email():
    msg = MIMEMultipart()
    msg['Subject'] = 'subject'
    msg['From'] = 'XXXX@gmail.com'
    msg['To'] = 'YYYY@gmail.com'
    with open('/tmp/image.jpg', mode='rb') as image_file:
        image = MIMEImage(image_file.read())
    msg.attach(image)
    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.starttls()
    s.login('XXXX@gmail.com', 'password')
    s.send_message(msg)
    s.quit()

根据这里的另一个问题,我尝试了这个而不是 send_message()它也失败了:

    s.sendmail('XXXX@gmail.com', ['YYYY@gmail.com'], msg.as_string())

我还尝试显式添加 _subtype='jpg'当我初始化MIMEImage时,添加Content-Transfer-Encoding header ,并添加 Content-Disposition标题,这些似乎都没有什么区别。

我已经验证,当我的电子邮件客户端从其他客户端接收到 Base64 编码的附件时,我的电子邮件客户端没有出现问题。

我查看了 smtplib 源代码,注意到 smtplib 处理行分隔符的方式看起来有点奇怪,想知道这是否可能相关。 (另请参阅引用:https://bugs.python.org/issue14645)

我是否需要对某些内容进行不同的编码,为我的平台设置一些特殊的内容,或者这是一个故障?谢谢!

<小时/>

更新:此问题仅在我运行 Flask 时存在,在 Flask 之外不会发生。我正在尝试隔离 Flask 环境中的问题。我认为这可能是flask_mail,但删除它并没有解决问题。下面的代码在我的系统上从 Flask 运行时会失败,但如果我从同一虚拟环境和同一 python 二进制文件中的 shell 脚本运行它,则不会失败。由于复杂性,我目前不期望得到任何答案,但会将其留给后代。

更新 2:我已将这个问题缩小到与 https://github.com/isislovecruft/python-gnupg/ 中的 gnupg 库的交互。 。我已经更新了我的最小示例来反射(reflect)这一点。 python-gnupug 中的 python 编解码器猴子补丁负责解决此问题:codecs.register_error('strict', codecs.replace_errors)

最佳答案

这是由于 gnupg 和 smtplib + MIME 之间的不良交互造成的。 gnupg 调用 codecs.register_error('strict', codecs.replace_errors) ,这会干扰其他包执行的编码。

引用:https://github.com/isislovecruft/python-gnupg/issues/49

关于python 3 smtplib : binary attachment encodes incorrectly in flask when gnupg is active,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40118544/

相关文章:

python - 与丘比的自相关

python - 字典解包过程中内部发生了什么?

java - 通过电子邮件标题检测电子邮件正文语言的可能性

C# 创建 MIME 消息?

python - SIGINT 对脚本没有影响

python - Tkinter 框架不填充剩余空间

Python - 如何删除以数字开头并包含句点的单词

python-3.x - 在python包中查找某些方法和函数的所有用法

python - 如何在不使用 with open 的情况下检查文件是否为空?

reactjs - React 应用程序突然出现空白页 - mime 问题?