smtpd — SMTP 服务器 — Python 文档

来自菜鸟教程
Python/docs/3.9/library/smtpd
跳转至:导航、​搜索

smtpd — SMTP 服务器

源代码: :source:`Lib/smtpd.py`



该模块提供了几个类来实现 SMTP(电子邮件)服务器。

也可以看看

aiosmtpd 包是该模块的推荐替代品。 它基于 asyncio 并提供更直接的 API。 smtpd 应视为已弃用。


存在几种服务器实现; 一个是通用的什么都不做的实现,它可以被覆盖,而另外两个提供特定的邮件发送策略。

此外,可以扩展 SMTPChannel 以实现与 SMTP 客户端的非常具体的交互行为。

代码支持 RFC 5321,加上 RFC 1870 SIZE 和 RFC 6531[X12X] SMTPUTF8 扩展。

SMTPServer 对象

class smtpd.SMTPServer(localaddr, remoteaddr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=False)

创建一个新的 SMTPServer 对象,该对象绑定到本地地址 localaddr。 它将 remoteaddr 视为上游 SMTP 中继器。 localaddrremoteaddr 都应该是一个 (host, port) 元组。 该对象继承自 asyncore.dispatcher,因此将在实例化时将自身插入到 asyncore 的事件循环中。

data_size_limit 指定将在 DATA 命令中接受的最大字节数。 None0 的值表示没有限制。

map 是用于连接的套接字映射(初始为空的字典是合适的值)。 如果未指定,则使用 asyncore 全局套接字映射。

enable_SMTPUTF8 确定是否应启用 SMTPUTF8 扩展(如 RFC 6531 中定义)。 默认值为 False。 当 True, SMTPUTF8 被接受为 MAIL 命令的参数,并且存在时,将其传递给 kwargs['mail_options'] 中的 process_message() ] 列表。 decode_dataenable_SMTPUTF8 不能同时设置为 True

decode_data 指定是否应使用 UTF-8 对 SMTP 事务的数据部分进行解码。 当 decode_dataFalse(默认)时,服务器通告 8BITMIME 扩展(RFC 6152),接受BODY=8BITMIME 参数,当存在时将其传递给 kwargs['mail_options'] 列表中的 process_message()decode_dataenable_SMTPUTF8 不能同时设置为 True

process_message(peer, mailfrom, rcpttos, data, **kwargs)

引发 NotImplementedError 异常。 在子类中覆盖它以对该消息做一些有用的事情。 在构造函数中作为 remoteaddr 传递的任何内容都可以作为 _remoteaddr 属性使用。 peer 是远程主机的地址,mailfrom 是信封发起者,rcpttos 是信封收件人,data 是包含内容的字符串电子邮件(应采用 RFC 5321 格式)。

如果 decode_data 构造函数关键字设置为 True,则 data 参数将是一个 unicode 字符串。 如果设置为 False,它将是一个字节对象。

kwargs 是一个包含附加信息的字典。 如果 decode_data=True 作为 init 参数给出,则为空,否则包含以下键:

mail_options:

MAIL 命令的所有接收参数的列表(元素是大写字符串;例如:['BODY=8BITMIME', 'SMTPUTF8'])。

rcpt_options:

mail_options 相同,但用于 RCPT 命令。 目前不支持 RCPT TO 选项,所以现在这将始终是一个空列表。


process_message 的实现应该使用 **kwargs 签名来接受任意关键字参数,因为未来的功能增强可能会向 kwargs 字典添加键。

返回 None 请求正常的 250 Ok 响应; 否则以 RFC 5321 格式返回所需的响应字符串。

channel_class

在子类中覆盖它以使用自定义 SMTPChannel 来管理 SMTP 客户端。

3.4 版新功能: map 构造函数参数。

3.5 版更改:localaddrremoteaddr 现在可能包含 IPv6 地址。

3.5 版新功能:decode_dataenable_SMTPUTF8 构造函数参数,以及 process_message()kwargs 参数当 decode_dataFalse 时。

在 3.6 版更改:decode_data 现在默认为 False


调试服务器对象

class smtpd.DebuggingServer(localaddr, remoteaddr)
创建一个新的调试服务器。 参数按照 SMTPServer。 消息将被丢弃,并打印在标准输出上。


纯代理对象

class smtpd.PureProxy(localaddr, remoteaddr)
创建一个新的纯代理服务器。 参数按照 SMTPServer。 一切都将中继到 remoteaddr。 请注意,运行此操作很有可能使您成为开放中继,因此请小心。


MailmanProxy 对象

class smtpd.MailmanProxy(localaddr, remoteaddr)
创建一个新的纯代理服务器。 参数按照 SMTPServer。 一切都将中继到 remoteaddr,除非本地邮递员配置知道地址,在这种情况下,它将通过邮递员处理。 请注意,运行此操作很有可能使您成为开放中继,因此请小心。


SMTPChannel 对象

class smtpd.SMTPChannel(server, conn, addr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=False)

创建一个新的 SMTPChannel 对象,用于管理服务器和单个 SMTP 客户端之间的通信。

connaddr 是根据下面描述的实例变量。

data_size_limit 指定将在 DATA 命令中接受的最大字节数。 None0 的值表示没有限制。

enable_SMTPUTF8 确定是否应启用 SMTPUTF8 扩展(如 RFC 6531 中定义)。 默认值为 Falsedecode_dataenable_SMTPUTF8 不能同时设置为 True

可以在 map 中指定字典以避免使用全局套接字映射。

decode_data 指定是否应使用 UTF-8 对 SMTP 事务的数据部分进行解码。 默认值为 Falsedecode_dataenable_SMTPUTF8 不能同时设置为 True

要使用自定义 SMTPChannel 实现,您需要覆盖 SMTPServerSMTPServer.channel_class

3.5 版更改: 添加了 decode_dataenable_SMTPUTF8 参数。

在 3.6 版更改:decode_data 现在默认为 False

SMTPChannel 具有以下实例变量:

smtp_server

持有产生此频道的 SMTPServer

conn

保存连接到客户端的套接字对象。

addr

持有客户端的地址,socket.accept返回的第二个值

received_lines

保存从客户端接收到的行字符串列表(使用 UTF-8 解码)。 这些行的 "\r\n" 行结束转换为 "\n"

smtp_state

保持通道的当前状态。 这将是最初的 COMMAND,然后是客户端发送“DATA”行后的 DATA

seen_greeting

保存一个字符串,其中包含客户端在其“HELO”中发送的问候语。

mailfrom

保存一个字符串,其中包含来自客户端的“MAIL FROM:”行中标识的地址。

rcpttos

保存一个字符串列表,其中包含来自客户端的“RCPT TO:”行中标识的地址。

received_data

保存一个字符串,其中包含客户端在 DATA 状态期间发送的所有数据,直到但不包括终止 "\r\n.\r\n"

fqdn

保存 socket.getfqdn() 返回的服务器的完全限定域名。

peer

保存由 conn.getpeername() 返回的客户端对等的名称,其中 connconn

SMTPChannel 通过调用名为 smtp_<command> 的方法在接收到来自客户端的命令行时进行操作。 内置在基本 SMTPChannel 类中的是用于处理以下命令(并适当地响应它们)的方法:

命令

采取的行动

海洛

接受来自客户端的问候并将其存储在 seen_greeting 中。 将服务器设置为基本命令模式。

欧洲劳工组织

接受来自客户端的问候并将其存储在 seen_greeting 中。 将服务器设置为扩展命令模式。

NOOP

不采取任何行动。

辞职

干净地关闭连接。

邮件

接受“MAIL FROM:”语法并将提供的地址存储为 mailfrom。 在扩展命令模式下,接受 RFC 1870 SIZE 属性并根据 data_size_limit 的值做出适当的响应。

RCPT

接受“RCPT TO:”语法并将提供的地址存储在 rcpttos 列表中。

RSET

重置 mailfromrcpttosreceived_data,但不重置问候语。

数据

将内部状态设置为 DATA 并将来自客户端的剩余行存储在 received_data 中,直到接收到终结符 "\r\n.\r\n"

帮助

返回有关命令语法的最少信息

VRFY

返回代码 252(服务器不知道地址是否有效)

经验值

报告命令未执行。