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

源代碼: Lib/smtpd.py


該模塊提供了幾個類來實現(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.

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

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

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

SMTPServer 對象?

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

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

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

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

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

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

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

引發(fā) NotImplementedError 異常。 請在子類中重載此方法以實際運用此消息。 在構(gòu)造器中作為 remoteaddr 傳入的任何東西都可以 _remoteaddr 屬性的形式來訪問。 peer 是遠程主機的地址,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ù)則該字典為空,否則它會包含以下的鍵:

mail_options:

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

rcpt_options:

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

process_message 的實現(xiàn)應(yīng)當(dāng)使用 **kwargs 簽名來接收任意關(guān)鍵字參數(shù),因為未來的增強特性可能會向 kwargs 字典添加新鍵。

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

channel_class?

重載這個子類以使用自定義的 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 時傳給 process_message()kwargs 形參。

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

DebuggingServer 對象?

class smtpd.DebuggingServer(localaddr, remoteaddr)?

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

PureProxy 對象?

class smtpd.PureProxy(localaddr, remoteaddr)?

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

SMTPChannel 對象?

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

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

connaddr 是針對下述的每個實例變量。

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

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

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

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

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

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

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

SMTPChannel 具有下列實例變量:

smtp_server?

存放生成此通道的 SMTPServer。

conn?

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

addr?

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

received_lines?

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

smtp_state?

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

seen_greeting?

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

mailfrom?

存放包含客戶端在 "MAIL FROM:" 行中標識的地址的字符串。

rcpttos?

存放包含客戶端在 "RCPT TO:" 行中標識的地址的字符串。

received_data?

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

fqdn?

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

peer?

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

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

命令

所采取的行動

HELO

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

EHLO

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

NOOP

不采取任何行動。

QUIT

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

MAIL

接受 "MAIL FROM:" 句法并將所提供的地址保存為 mailfrom。 在擴展命令模式下,還接受 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

報告該命令未實現(xiàn)。