21.18. smtpd
— SMTP 服务器¶
源代码: Lib/smtpd.py
该模块提供了几个类来实现 SMTP (电子邮件)服务器。
也參考
The aiosmtpd package is a recommended
replacement for this module. It is based on asyncio
and provides a
more straightforward API. smtpd
should be considered deprecated.
有几个服务器的实现;一个是通用的无为实现,可以被重写,而另外两个则提供特定的邮件发送策略。
此外, SMTPChannel 可以被扩展以实现与 SMTP 客户端非常具体的交互行为。
该代码支持 RFC 5321 ,加上 RFC 1870 SIZE和 RFC 6531 SMTPUTF8 扩展。
21.18.1. SMTPServer 对象¶
-
class
smtpd.
SMTPServer
(localaddr, remoteaddr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=False)¶ 新建一个
SMTPServer
对象,它会绑定到本机地址 localaddr。 它将把 remoteaddr 当作上游 SMTP 中继器。 localaddr 和 remoteaddr 都应当是 (host, port) 元组。 该对象继承自asyncore.dispatcher
,因而会在实例化时将自己插入到asyncore
的事件循环。data_size_limit 指定将在
DATA
命令中被接受的最大字节数。 值为None
或0
表示无限制。map 是用于连接的套接字映射(初始为空的字典是适当的值)。 如果未指定则会使用
asyncore
全局套接字映射。enable_SMTPUTF8 决定是否应当启用
SMTPUTF8
扩展(如 RFC 6531 所定义的。 默认值为False
。 当设为True
时,会接受SMTPUTF8
作为MAIL
命令的形参并在被提供时将其传给kwargs['mail_options']
列表中的process_message()
。 decode_data 和 enable_SMTPUTF8 不可同时被设为True
。decode_data 指明 SMTP 事务的数据部分是否应当使用 UTF-8 来解码。 当 decode_data 为
False
时(默认值),服务器会声明8BITMIME
扩展 (RFC 6152),接受来自MAIL
命令的BODY=8BITMIME
形参,并在该形参存在时将其传给kwargs['mail_options']
列表中的process_message()
方法。 decode_data 和 enable_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
作为初始参数则该字典为空,否则它会包含以下的键:- 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 版更變: localaddr 和 remoteaddr 现在可以包含 IPv6 地址。
3.5 版新加入: decode_data 和 enable_SMTPUTF8 构造器形参,以及当 decode_data 为
False
时传给process_message()
的 kwargs 形参。3.6 版更變: decode_data 现在默认为
False
。-
21.18.2. DebuggingServer 对象¶
-
class
smtpd.
DebuggingServer
(localaddr, remoteaddr)¶ 创建一个新的调试服务器。 参数是针对每个
SMTPServer
。 消息将被丢弃,并在 stdout 上打印出来。
21.18.3. PureProxy对象¶
-
class
smtpd.
PureProxy
(localaddr, remoteaddr)¶ 创建一个新的纯代理服务器。 参数是针对每个
SMTPServer
。 一切都将被转发到 remoteaddr。 请注意运行此对象有很大的机会令你成为一个开放的中继站,所以需要小心。
21.18.4. MailmanProxy 对象¶
-
class
smtpd.
MailmanProxy
(localaddr, remoteaddr)¶ 创建一个新的纯代理服务器。 参数是针对每个
SMTPServer
。 一切都将被转发到 remoteaddr,除非本地 mailman 配置知道另一个地址,在那种情况下它将由 mailman 来处理。 请注意运行此对象有很大的机会令你成为一个开放的中继站,所以需要小心。
21.18.5. SMTPChannel 对象¶
-
class
smtpd.
SMTPChannel
(server, conn, addr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=False)¶ 创建一个新的
SMTPChannel
对象,该对象会管理服务器和单个 SMTP 客户端之间的通信。conn 和 addr 是针对下述的每个实例变量。
data_size_limit 指定将在
DATA
命令中被接受的最大字节数。 值为None
或0
表示无限制。enable_SMTPUTF8 确定
SMTPUTF8
扩展 (如 RFC 6531 所定义的) 是否应当被启用。 默认值为False
。 decode_data 和 enable_SMTPUTF8 不能被同时设为True
。可以在 map 中指定一个字典以避免使用全局套接字映射。
decode_data 指明 SMTP 事务的数据部分是否应当使用 UTF-8 来解码。 默认值为
False
。 decode_data 和 enable_SMTPUTF8 不能被同时设为True
。要使用自定义的 SMTPChannel 实现你必须重载你的
SMTPServer
的SMTPServer.channel_class
。3.5 版更變: 添加了 decode_data 和 enable_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()
所返回的服务器完整限定域名。
SMTPChannel
在接收到来自客户端的命令行时会通过发起调用名为smtp_<command>
的方法来进行操作。 在基类SMTPChannel
中具有用于处理下列命令(并对他们作出适当反应)的方法:命令
所采取的行动
HELO
接受来自客户端的问候语,并将其存储在
seen_greeting
中。将服务器设置为基本命令模式。EHLO
接受来自客户的问候并将其存储在
seen_greeting
中。将服务器设置为扩展命令模式。NOOP
不采取任何措施。
QUIT
干净地关闭连接。
MAIL
接受 「MAIL FROM:」 句法并将所提供的地址保存为
mailfrom
。 在扩展命令模式下,还接受 RFC 1870 SIZE 属性并根据 data_size_limit 的值作出适当返回。RCPT
接受 「RCPT TO:」 句法并将所提供的地址保存在
rcpttos
列表中。RSET
重置
mailfrom
,rcpttos
, 和received_data
,但不重置问候语。DATA
将内部状态设为
DATA
并将来自客户端的剩余行保存在received_data
中直至接收到终止符"\r\n.\r\n"
。HELP
返回有关命令语法的最少信息
VRFY
返回代码252(服务器不知道该地址是否有效)
EXPN
报告该命令未实现。
-