smtpd --- SMTP 服務(wù)器?

源代碼: Lib/smtpd.py


該模塊提供了幾個(gè)類來實(shí)現(xiàn) SMTP (電子郵件)服務(wù)器。

Deprecated since version 3.6, removed in version 3.12: The smtpd module is deprecated (see PEP 594 for details). The aiosmtpd package is a recommended replacement for this module. It is based on asyncio and provides a more straightforward API.

有幾個(gè)服務(wù)器的實(shí)現(xiàn);一個(gè)是通用的無為實(shí)現(xiàn),可以被重寫,而另外兩個(gè)則提供特定的郵件發(fā)送策略。

此外, SMTPChannel 可以被擴(kuò)展以實(shí)現(xiàn)與 SMTP 客戶端非常具體的交互行為。

該代碼支持 RFC 5321 ,加上 RFC 1870 SIZE和 RFC 6531 SMTPUTF8 擴(kuò)展。

SMTPServer 對象?

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

新建一個(gè) SMTPServer 對象,它會(huì)綁定到本機(jī)地址 localaddr。 它將把 remoteaddr 當(dāng)作上游 SMTP 中繼器。 localaddrremoteaddr 都應(yīng)當(dāng)是 (host, port) 元組。 該對象繼承自 asyncore.dispatcher,因而會(huì)在實(shí)例化時(shí)將自己插入到 asyncore 的事件循環(huán)。

data_size_limit 指定將在 DATA 命令中被接受的最大字節(jié)數(shù)。 值為 None0 表示無限制。

map 是用于連接的套接字映射(初始為空的字典是適當(dāng)?shù)闹担?如果未指定則會(huì)使用 asyncore 全局套接字映射。

enable_SMTPUTF8 決定是否應(yīng)當(dāng)啟用 SMTPUTF8 擴(kuò)展(如 RFC 6531 所定義的。 默認(rèn)值為 False。 當(dāng)設(shè)為 True 時(shí),會(huì)接受 SMTPUTF8 作為 MAIL 命令的形參并在被提供時(shí)將其傳給 kwargs['mail_options'] 列表中的 process_message()。 decode_dataenable_SMTPUTF8 不可同時(shí)被設(shè)為 True

decode_data 指明 SMTP 事務(wù)的數(shù)據(jù)部分是否應(yīng)當(dāng)使用 UTF-8 來解碼。 當(dāng) decode_dataFalse 時(shí)(默認(rèn)值),服務(wù)器會(huì)聲明 8BITMIME 擴(kuò)展 (RFC 6152),接受來自 MAIL 命令的 BODY=8BITMIME 形參,并在該形參存在時(shí)將其傳給 kwargs['mail_options'] 列表中的 process_message() 方法。 decode_dataenable_SMTPUTF8 不可同時(shí)被設(shè)為 True

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

引發(fā) NotImplementedError 異常。 請?jiān)谧宇愔兄剌d此方法以實(shí)際運(yùn)用此消息。 在構(gòu)造器中作為 remoteaddr 傳入的任何東西都可以 _remoteaddr 屬性的形式來訪問。 peer 是遠(yuǎn)程主機(jī)的地址,mailfrom 是封包的發(fā)送方,rcpttos 是封包的接收方而 data 是包含電子郵件內(nèi)容的字符串(應(yīng)該為 RFC 5321 格式)。

如果構(gòu)造器關(guān)鍵字參數(shù) decode_data 被設(shè)為 True,則 data 參數(shù)將為 Unicode 字符串。 如果被設(shè)為 False,則將為字節(jié)串對象。

kwargs 是包含附加信息的字典。 如果給出 decode_data=True 作為初始參數(shù)則該字典為空,否則它會(huì)包含以下的鍵:

mail_options:

MAIL 命令所接收的所有參數(shù)組成的列表 (其元素為大寫形式的字符串;例如: ['BODY=8BITMIME', 'SMTPUTF8'])。

rcpt_options:

mail_options 類似但是針對 RCPT 命令。 目前不支持任何 RCPT TO 選項(xiàng),因此其值將總是為空列表。

process_message 的實(shí)現(xiàn)應(yīng)當(dāng)使用 **kwargs 簽名來接收任意關(guān)鍵字參數(shù),因?yàn)槲磥淼脑鰪?qiáng)特性可能會(huì)向 kwargs 字典添加新鍵。

返回 None 以請求一個(gè)正常的 250 Ok 響應(yīng);在其他情況下則以 RFC 5321 格式返回所需的響應(yīng)字符串。

channel_class?

重載這個(gè)子類以使用自定義的 SMTPChannel 來管理 SMTP 客戶端。

3.4 新版功能: map 構(gòu)造器參數(shù)。

在 3.5 版更改: localaddrremoteaddr 現(xiàn)在可以包含 IPv6 地址。

3.5 新版功能: decode_dataenable_SMTPUTF8 構(gòu)造器形參,以及當(dāng) decode_dataFalse 時(shí)傳給 process_message()kwargs 形參。

在 3.6 版更改: decode_data 現(xiàn)在默認(rèn)為 False。

DebuggingServer 對象?

class smtpd.DebuggingServer(localaddr, remoteaddr)?

創(chuàng)建一個(gè)新的調(diào)試服務(wù)器。 參數(shù)是針對每個(gè) SMTPServer。 消息將被丟棄,并在 stdout 上打印出來。

PureProxy 對象?

class smtpd.PureProxy(localaddr, remoteaddr)?

創(chuàng)建一個(gè)新的純代理服務(wù)器。 參數(shù)是針對每個(gè) SMTPServer。 一切都將被轉(zhuǎn)發(fā)到 remoteaddr。 請注意運(yùn)行此對象有很大的機(jī)會(huì)令你成為一個(gè)開放的中繼站,所以需要小心。

SMTPChannel 對象?

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

創(chuàng)建一個(gè)新的 SMTPChannel 對象,該對象會(huì)管理服務(wù)器和單個(gè) SMTP 客戶端之間的通信。

connaddr 是針對下述的每個(gè)實(shí)例變量。

data_size_limit 指定將在 DATA 命令中被接受的最大字節(jié)數(shù)。 值為 None0 表示無限制。

enable_SMTPUTF8 確定 SMTPUTF8 擴(kuò)展 (如 RFC 6531 所定義的) 是否應(yīng)當(dāng)被啟用。 默認(rèn)值為 False。 decode_dataenable_SMTPUTF8 不能被同時(shí)設(shè)為 True。

可以在 map 中指定一個(gè)字典以避免使用全局套接字映射。

decode_data 指明 SMTP 事務(wù)的數(shù)據(jù)部分是否應(yīng)當(dāng)使用 UTF-8 來解碼。 默認(rèn)值為 False。 decode_dataenable_SMTPUTF8 不能被同時(shí)設(shè)為 True。

要使用自定義的 SMTPChannel 實(shí)現(xiàn)你必須重載你的 SMTPServerSMTPServer.channel_class

在 3.5 版更改: 添加了 decode_dataenable_SMTPUTF8 形參。

在 3.6 版更改: decode_data 現(xiàn)在默認(rèn)為 False。

SMTPChannel 具有下列實(shí)例變量:

smtp_server?

存放生成此通道的 SMTPServer

conn?

存放連接到客戶端的套接字對象。

addr?

存放客戶端的地址,socket.accept 所返回的第二個(gè)值。

received_lines?

存放從客戶端接收的行字符串列表 (使用 UTF-8 解碼)。 所有行的 "\r\n" 行結(jié)束符都會(huì)被轉(zhuǎn)寫為 "\n"。

smtp_state?

存放通道的當(dāng)前狀態(tài)。 其初始值將為 COMMAND 而在客戶端發(fā)送 "DATA" 行后將為 DATA

seen_greeting?

存放包含客戶端在其 "HELO" 中發(fā)送的問候信息的字符串。

mailfrom?

存放包含客戶端在 "MAIL FROM:" 行中標(biāo)識(shí)的地址的字符串。

rcpttos?

存放包含客戶端在 "RCPT TO:" 行中標(biāo)識(shí)的地址的字符串。

received_data?

存放客戶端在 DATA 狀態(tài)期間發(fā)送的所有數(shù)據(jù)的字符串,直至但不包括末尾的 "\r\n.\r\n"。

fqdn?

存放由 socket.getfqdn() 所返回的服務(wù)器完整限定域名。

peer?

存放由 conn.getpeername() 所返回的客戶端對等方名稱,其中 connconn。

SMTPChannel 在接收到來自客戶端的命令行時(shí)會(huì)通過發(fā)起調(diào)用名為 smtp_<command> 的方法來進(jìn)行操作。 在基類 SMTPChannel 中具有用于處理下列命令(并對他們作出適當(dāng)反應(yīng))的方法:

命令

所采取的行動(dòng)

HELO

接受來自客戶端的問候語,并將其存儲(chǔ)在 seen_greeting 中。將服務(wù)器設(shè)置為基本命令模式。

EHLO

接受來自客戶的問候并將其存儲(chǔ)在 seen_greeting 中。將服務(wù)器設(shè)置為擴(kuò)展命令模式。

NOOP

不采取任何行動(dòng)。

QUIT

干凈地關(guān)閉連接。

MAIL

接受 "MAIL FROM:" 句法并將所提供的地址保存為 mailfrom。 在擴(kuò)展命令模式下,還接受 RFC 1870 SIZE 屬性并根據(jù) data_size_limit 的值作出適當(dāng)返應(yīng)。

RCPT

接受 "RCPT TO:" 句法并將所提供的地址保存在 rcpttos 列表中。

RSET

重置 mailfrom, rcpttos, 和 received_data ,但不重置問候語。

DATA

將內(nèi)部狀態(tài)設(shè)為 DATA 并將來自客戶端的剩余行保存在 received_data 中直至接收到終止符 "\r\n.\r\n"。

HELP

返回有關(guān)命令語法的最少信息

VRFY

返回代碼252(服務(wù)器不知道該地址是否有效)

EXPN

報(bào)告該命令未實(shí)現(xiàn)。