斯姆普利布。SMTP.send_message将文本内容中的"From"替换为">From"



考虑以下示例,通过Python 3中的smtplib和电子邮件库发送电子邮件:

import smtplib
from email.message import EmailMessage
# Make the email:
msg = EmailMessage()
msg.set_content("""
Hi,
From foo
from bar
From baz
""")
msg['Subject'] = 'Example'
msg['From'] = "me@example.com"
msg['To'] = "you@example.com"
# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()

这将生成一封看起来像这样的电子邮件:

Message-ID: <...>
Date: Thu, 17 Mar 2022 12:01:47 -0700 (PDT)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Subject: Example
From: me@example.com
To: you@examole.com

Hi,
>From foo
from bar
From baz

请注意,如果From位于一行的开头,那么它是如何在电子邮件正文中变为>From的。如果电子邮件文本中使用了From,我不想把>放在那里。我怀疑这是为了防止from被注入到主体中,如果它没有在头部中定义,但在我的情况下它是定义的。

有趣的是,这并不在EmailMessage本身中:

>>> print(msg)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Subject: Example
From: me@example.com
To: you@example.com

Hi,
From foo
from bar
From baz

正文中的nFrom似乎在方法SMTP(...).send_message中变成了n>From,这不是由消息本身中的电子邮件策略引起的。

因此,问题是如何在发送电子邮件时停止将文本主体中的nFrom替换为n>From

我找到了答案,并决定在其他人遇到相同问题时将其记录下来。简而言之,答案是你无能为力

基本上这就是smtplib中发生的情况。SMTP.send_message:

def send_message(self, msg, from_addr=None, to_addrs=None,
mail_options=(), rcpt_options=()):
...
else:
g = email.generator.BytesGenerator(bytesmsg)
g.flatten(msg_copy, linesep='rn')

注意生成器是如何通过将bytesmsg作为参数来创建的。

然后启动生成器:

def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, *,
policy=None):
...
if mangle_from_ is None:
mangle_from_ = True if policy is None else policy.mangle_from_
self._fp = outfp
self._mangle_from_ = mangle_from_
self.maxheaderlen = maxheaderlen
self.policy = policy

仅传递outfp(bytesmsg(。策略为None,因此在smtplib的send_message方法中,mangle_from_始终为True

在几个方法调用之后,将调用一个执行以下操作的方法:

...
if self._mangle_from_:
payload = fcre.sub('>From ', payload)
self._write_lines(payload)
...

这将在电子邮件的文本内容中的nFrom前面添加>

因此,似乎无法摆脱将正文中的From替换为>From。您可以自己对方法进行子类化,复制代码并修复策略,但这并不干净。

最新更新