smtplib.SMTP.send_message 将文本内容中的 "From" 替换为“>From”
smtplib.SMTP.send_message replaces "From" with ">From" in text content
考虑以下示例,通过 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
请注意在电子邮件的 body 中 From
是如何变成 >From
的,如果它在一行的开头。如果电子邮件文本中使用了 From,我不想将 >
放在那里。我怀疑这是为了防止 from
被注入到 body 中,如果它没有在 headers 中定义但在我的例子中它被定义了。
有趣的是,这不在 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
似乎 body 中的 \nFrom
在方法 SMTP(...).send_message
中变成了 \n>From
,这不是由邮件本身的电子邮件策略引起的。
所以问题是如何在发送邮件时停止将文本body中的\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='\r\n')
注意如何通过将 bytesmsg
作为参数传递来创建生成器。
然后 initiation of the generator:
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
。
经过几次方法调用后,调用了一个执行 this:
的方法
...
if self._mangle_from_:
payload = fcre.sub('>From ', payload)
self._write_lines(payload)
...
这会在电子邮件的文本内容中的 n\From
前面添加 >
。
因此,似乎无法摆脱将正文中的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
请注意在电子邮件的 body 中 From
是如何变成 >From
的,如果它在一行的开头。如果电子邮件文本中使用了 From,我不想将 >
放在那里。我怀疑这是为了防止 from
被注入到 body 中,如果它没有在 headers 中定义但在我的例子中它被定义了。
有趣的是,这不在 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
似乎 body 中的 \nFrom
在方法 SMTP(...).send_message
中变成了 \n>From
,这不是由邮件本身的电子邮件策略引起的。
所以问题是如何在发送邮件时停止将文本body中的\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='\r\n')
注意如何通过将 bytesmsg
作为参数传递来创建生成器。
然后 initiation of the generator:
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
。
经过几次方法调用后,调用了一个执行 this:
的方法...
if self._mangle_from_:
payload = fcre.sub('>From ', payload)
self._write_lines(payload)
...
这会在电子邮件的文本内容中的 n\From
前面添加 >
。
因此,似乎无法摆脱将正文中的From
替换为>From
。您可以将方法子类化,复制代码并自己修复策略,但这并不干净。