smtpd — SMTP 服务器 — Python 文档
smtpd — SMTP 服务器
该模块提供了几个类来实现 SMTP(电子邮件)服务器。
存在几种服务器实现; 一个是通用的什么都不做的实现,它可以被覆盖,而另外两个提供特定的邮件发送策略。
此外,可以扩展 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 中继器。 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 指定是否应使用 UTF-8 对 SMTP 事务的数据部分进行解码。 当 decode_data 为
False
(默认)时,服务器通告8BITMIME
扩展(RFC 6152),接受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
作为 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 版更改:localaddr 和 remoteaddr 现在可能包含 IPv6 地址。
3.5 版新功能:decode_data 和 enable_SMTPUTF8 构造函数参数,以及 process_message() 的 kwargs 参数当 decode_data 为
False
时。在 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 客户端之间的通信。
conn 和 addr 是根据下面描述的实例变量。
data_size_limit 指定将在
DATA
命令中接受的最大字节数。None
或0
的值表示没有限制。enable_SMTPUTF8 确定是否应启用
SMTPUTF8
扩展(如 RFC 6531 中定义)。 默认值为False
。 decode_data 和 enable_SMTPUTF8 不能同时设置为True
。可以在 map 中指定字典以避免使用全局套接字映射。
decode_data 指定是否应使用 UTF-8 对 SMTP 事务的数据部分进行解码。 默认值为
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() 返回的服务器的完全限定域名。
- peer
保存由
conn.getpeername()
返回的客户端对等的名称,其中conn
是 conn。
SMTPChannel 通过调用名为
smtp_<command>
的方法在接收到来自客户端的命令行时进行操作。 内置在基本 SMTPChannel 类中的是用于处理以下命令(并适当地响应它们)的方法:命令
采取的行动
海洛
接受来自客户端的问候并将其存储在 seen_greeting 中。 将服务器设置为基本命令模式。
欧洲劳工组织
接受来自客户端的问候并将其存储在 seen_greeting 中。 将服务器设置为扩展命令模式。
NOOP
不采取任何行动。
辞职
干净地关闭连接。
邮件
接受“MAIL FROM:”语法并将提供的地址存储为 mailfrom。 在扩展命令模式下,接受 RFC 1870 SIZE 属性并根据 data_size_limit 的值做出适当的响应。
RCPT
接受“RCPT TO:”语法并将提供的地址存储在 rcpttos 列表中。
RSET
重置 mailfrom、rcpttos 和 received_data,但不重置问候语。
数据
将内部状态设置为
DATA
并将来自客户端的剩余行存储在 received_data 中,直到接收到终结符"\r\n.\r\n"
。帮助
返回有关命令语法的最少信息
VRFY
返回代码 252(服务器不知道地址是否有效)
经验值
报告命令未执行。