SMTP提供一種可靠的有效的傳送機制,它用于傳送電子郵件。雖然十幾年來,它的作用已經有目共睹,可是對它功能的擴充也是必不可少的。對SMTP服務的擴展我們介紹一下:在SMTP轉發的郵件中包括信封和內容這兩種東西。我們寫信也寫信封和信皮,我們可以借生活中的信件來幫助理解。
(1)SMTP信封比較容易理解,它被作為一系列的SMTP協議單元傳送,它包括發送者地址,傳送模式,還有一個或多個接收者地址。如果有不清楚的地方,請參閱《SMTP協議標準》。
(2)至于內容,它是由兩部分組成的,一部分是信頭,一部分是信體,信頭是由一個個的域/值對(一個域,一個值)組成的,如果信體有結構的話,它的結構是以MIME構造的。內容從根本上來說是文本的,一般也是由ASCII碼構成的,但是由于使用了MIME,所以這個限制應該也是沒有了,但信頭卻不行,一般都應該使用ASCII碼表示。雖然SMTP協議是一個不錯的協議,可是對它的擴展還是不可避免,本文主要說明了一種擴展方法,使用這種擴展方法,服務器和用戶之間可以相互知道對方使用了擴展,使用了多少,如果進行通信。
這里我們希望讓大家知道網絡協議中的一個經驗:參數越多,死得越快;參數越少,越能持久。參數太多了,根本不利于使用,無法推廣,早晚會被別的協議取代。這也符合科學的基礎原理,簡單。這說明在實現時一定要小心,如果不小心會便得到的遠遠小于付出的,有時根本不能提供任何益處。
下面我們看一下EHLO命令,支持SMTP服務擴展的客戶應該以EHLO命令開始SMTP會話,而不是通常的HELO命令。如果服務器也支持,那就返回確認響應,如果不支持就返回失敗響應。因為引入了EHLO命令,因此會話開始的第一條命令可以是HELO或EHLO。
因此引入了新的參數,所以SMTP的MAILFROM和RCPTTO命令行長度也能再是512字節了,但是引入新參數的長度必須加以說明,以便實現者準備緩沖區。
命令格式如下:
ehlo-cmd::="EHLO"SPdomainCRLF
在命令成功是,服務器返回代碼250,如果失敗返回代碼550,如果出錯,返500,501,502,504或421。對比《SMTP協議標準》,EHLO命令可以出現在任何HELO命令出現的地方,在成功發送一個HELO或EHLO命令后再次發送它會使服務器返回503??蛻暨@時不能緩存服務器返回的任何信息。這里一定要注意的是,每次開始SMTP擴展服務會話的時候必須發送EHLO命令。如果服務器能夠處理EHLO命令,它會返回代碼250。這樣,服務器和客戶就處于初始狀態了,也就是說,所有的狀態表和緩沖區已經準備完畢。通常這種響應是多行的,每行響應包括一個關鍵字,如果有的話,還有一個或多個參數,響應的語法如下:
ehlo-ok-rsp::="250"domain[SPgreeting]CRLF
/("250-"domain[SPgreeting]CRLF
*("250-"ehlo-lineCRLF)
"250"SPehlo-lineCRLF)
greeting::=1*<除了CR或LF的所有字符>
ehlo-line::=ehlo-keyword*(SPehlo-param)
ehlo-keyword::=(字母/數字)*(字母/數字/"-")
ehlo-param::=1*<隨了空格和控制字符外的字符>
ALPHA::=<大寫A到Z,小寫A到Z>
DIGIT::=<0到9>
CR::=<回車,ASCII碼13>
LF::=<換行,ASCII碼10>
SP::=<空格,ASCII碼32>
雖然EHLO關鍵字可以是大寫,小寫,大小寫混合的,但是對它的處理是大小寫敏感的,這是與原來規定不同的。IANA支持SMTP服務擴展注冊,相對于每個擴展都有一個相應的EHLO關鍵字值,每個在IANA注冊的服務擴展必須在一個RFC中定義。如果一個關鍵字以X開頭,它指的是這個服務擴展是雙方約定的,不是標準的。
如果出于某種原因,服務器不能列出它所支持的服務擴展,就返回代碼554。在接收到這個代碼后,客戶要么發送HELO,要么發送QUIT命令。有時候服務器接收到EHLO命令,可是命令參數不可接受,它就返回代碼501。如果服務器識別了EHLO,但對服務器擴展未實現,則返回代碼502。
如果服務器不再提供服務擴展,則返回代碼421。在接收到這個代碼后,客戶要么發送HELO,要么發送QUIT命令。如果服務器不支持服務擴展,則返回500,服務器保持現有狀態,在接收到這個代碼后,客戶要么發送HELO,要么發送QUIT命令。
有時候,SMTP服務器會在接收到EHLO命令后因為某種原因關閉連接,這種情況在原來的SMTP協議標準中未涉及。為了處理這種情況,客戶必須能夠確認服務器是否能夠工作,它可以重新連接并發送HELO或EHLO命令。有些服務器在接收到一個EHLO命令后會拒絕接收新的HELO命令,這時可以利用RSET命令重新啟動,然后再發送HELO。如果客戶不注意這樣的小細節,會收到失敗代碼。
下面我們來看一下MAILFROM和RCPTTO參數。許多服務擴展是在MAILFROM和RCPTTO命令后加入一些參數來實現的。下面我們看一下這兩個命令的格式:
esmtp-cmd::=inner-esmtp-cmd[SPesmtp-parameters]CRLF
esmtp-parameters::=esmtp-parameter*(SPesmtp-parameter)
esmtp-parameter::=esmtp-keyword["="esmtp-value]
esmtp-keyword::=(字母/數字)*(字母/數字/"-")
esmtp-value::=1*<除了空格,"="和控制字符的所有字符>
inner-esmtp-cmd::=("MAILFROM:"返回路徑)/("RCPTTO:"轉發路徑)
如果服務器不能識別或實現一個或多個MAILFROM或RCPTTO參數,它應該返回代碼555。如果這種情況只是暫時的,服務器返回代碼455。其它返回代碼請查閱相關資料,這里不再詳述了。服務器以服務擴展處理時,它處理的任何信息都應該在包頭上加上“服務擴展標記”以示區別。
下面是一個例子:
(1)雙方交互:S是服務器,C是客戶。
S:<等待連接在TCP端口25>
C:<連接到服務器>
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:250dbc.mtview.ca.ussayshello
...
(2)下面也是一個例子:
S:<等待連接在TCP端口25>
C:<連接到服務器>
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:250-dbc.mtview.ca.ussayshello
S:250-EXPN
S:250-HELP
S:250-8BITMIME
S:250-XONE
S:250XVRB
...
這說明服務器實現了服務擴展EXPN和HELP,這兩個是標準的服務擴展,另外兩個以X開頭的是非標準的?!?BR>
(3)最后,我們來看看服務器不支持服務擴展時的情況:
S:<等待連接在TCP端口25>
C:<連接到服務器>
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:500Commandnotrecognized:EHLO
...
代碼500表示服務器不支持服務擴展。