RFC822:電子郵件的基本框架

RFC822:電子郵件的基本框架

11 電子郵件的結構

如同傳統信件,電子郵件也是由信封和信件內容兩部分所構成。但是電子郵件不是寫在紙上的東西,而是由計算機編輯、傳送和顯示的一串文字字符。一封電子郵件如同我們在Windows“記事本”中看到的純文本內容,但是其中的字符是機器“寫”上去的,而不是用戶輸入、編輯的。

 

釋疑:你可能不同意這種說法,因爲郵件內容,包括收件人地址、轉發地址,肯定必須由用戶輸入。但是我們這裏討論的是在機器中傳送、存儲的電子郵件,用戶一般通過某種電子郵件應用程序(如Outlook ExpressFoxMail等)收發、編寫電子郵件,這些程序按照用戶輸入的信息自動產生符合RFC822MIME標準的郵件,然後才發送出去。

 

一封電子郵件的內容是純文本的,其中開頭若干行是信件“信封”,然後是一個空行(即只有回車換行字符的一行),其後是信件正文。“信封”、信件正文都是一行行的文字,郵件中的第一個空行是“信封”部分的終結標誌,其後是郵件正文,郵件正文可以包含空行,也可以沒有空行,這無關緊要。RFC822規定,所有的字符都必須是ASCII字符,或者更準確地說,必須是ASCII編碼的字符。注意RFC822是指定字符編碼的,符合RFC822標準的電子郵件,其中所有的字符只能使用ASCII編碼,不能是其它編碼。

RFC822對於信件正文沒有什麼規定,只是要求必須由ASCII字符組成,而“信封”上的信息則是要由機器處理的,因而有着嚴格的語法規定。“信封”的正式名稱是郵件頭(header),郵件頭由若干“頭段”(header field)組成,每一頭段的格式爲:

    field-name : [field-body] CRLF

(注:在本章中,當描述語法格式時,我們用斜體字表示一個語法成分的名稱,用方括號表示可選項,即,包含在方括號中的語法成分可用也可不用,用粗體表示必須照樣書寫的字符。)

其中field-name是段名,RFC822定義了常用的段名及其語義,應用程序也可以定義自己的段名及其語義,但不得與已定義的段名同名。field-body是段體,即段的具體內容。段名和段體用一個冒號分隔,最後用CRLF(回車換行)結束整個段。

    以下是一些郵件頭段的例子:

    From: George Jones <Group@Host>
    Sender: Secy@Host

    Reply-To: Secy@Host

其中每一行爲一個頭段,其中“From”、“Sender”和“Reply-To”是段名,段名不區分大小寫,每行冒號右邊的文字是段體,段體的語法、含義是有規定的。

    一個頭段邏輯上就是一行,但是當文字較長時,也允許換行。換行可在任何一個空格位置進行,但是要求換行之後在新行開頭至少必須有一個空格或Tab,表示本行是接續上一行的。這種換行稱爲“摺疊”。一個頭段可以摺疊爲若干行,應用程序進行語法分析時,應去掉摺疊,將每一段都整理爲一行,以便分析。

    例如:Received: from m15-40.126.com (220.181.15.40)CRLF by localhost with SMTP;

    文本編輯窗口顯示出來的效果:

    Received: from m15-40.126.com (220.181.15.40)

 by localhost with SMTP;

    RFC822定義的頭段按其功能可分爲源地址、目的地址、日期和可選段四大部分,以下分別介紹各個部分。

12 源地址

描述信件來源的段名有FromSenderReturn-pathReceivedReply-To,它們的語法如下:

    From: mailbox

    Sender: mailbox

    Return-path: < [route] local-part@domain >

    Reply-To: mailbox

    Received[from domain][by domain][via atom][with atom]

[id msg-id][for local-part@domain]

; date-time

From用來指出發信人是誰,段體mailbox發信人的郵箱地址,mailbox可以採用兩種形式之一,一種是local-part@domain,其中local-part是用戶帳號名稱,domain是郵件服務器的域名。另一種形式是發信人名稱後面再加上尖括號括起來的郵件地址,例如

  From:  George Jones <Group@Host>

    郵箱地址中的local-part一般不能使用圓括號、尖括號、方括號、逗號、分號、冒號、@、斜槓和空格這些字符,如果要使用這些字符,則整個local-part部分必須用雙引號括起來。

    如果某些程序使得信件不是從寫信人的郵箱寄出,而是從另一個郵箱寄出,則必須用Sender再加上From,這時Sender的段體是寄出的郵箱地址,而From的段體是寫信人的郵箱地址

    一封電子郵件可能要經過若干次轉發才能到達目的地。最後的轉發站(轉發郵件的計算機)可以用Return-path指出回送郵件給發信人的路由Return-path段體中的可選項route指出路由,其形式爲

    @domain_1, @domain_2, ... ..., @domian_n

其中各個domain_i是郵件服務器的域名。段體中最後的local-part@domain則是發信人的郵箱地址。

    Reply-To則是由最初發出郵件的機器填寫的頭段,它直接指出信件的回覆地址

    當郵件經過多次中轉轉發時,每一個轉發站都必須在郵件開頭加上Received頭段,說明郵件何時從何地來,往何處去。Received段體中的可選項用來記錄這些信息:

from domain說明郵件從何處來,domain發來郵件的主機IP地址、域名或主機名

by domain指出郵件接收者,domain接收郵件的主機IP地址、域名或主機名

via atom指出郵件的物理傳輸路徑,例如通過互聯網或電話網,atom是這種物理路徑的名稱。

with atom指出郵件的傳輸協議,例如SMTPESMTPatom是協議名稱。

id msg-id一些轉發站可能會將郵件排隊,msg-id指出郵件的內部ID

for local-part@domain指出郵件的目的地local-part@domain是郵箱地址

Received段最後要加上分號和時間戳date-time記錄郵件的接收時間。時間戳的格式將在1.4節詳述。

    一些郵件系統允許郵件接收者將接收到的郵件轉發給他人,並保留原有的郵件頭。這種情況下爲了與原來郵件頭中的頭段相區別,新加上的頭段的段名前要加上Resent-,即Resent-From Resent-Sender Resent-Reply-To,它們的作用與FromSenderReply-To相同。

    在郵件頭中各段的段體中,可以插入註釋。註釋用一對圓括號括起來,內容可以是任何字符串。註釋是給人看的,在語法上沒有其它意義。

    1:以下是一封電子郵件郵件頭中的片斷:

Received: from unknown (HELO mail.scnu.edu.cn) ([email protected])

 by 202.116.32.4 with SMTP; Fri, 09 Feb 2007 14:22:51 +0800

Received: from m15-40.126.com (220.181.15.40)

  by localhost with SMTP; 9 Feb 2007 06:32:51 -0000

Received: from 192.168.208.33 by webmail-app40 (Coremail) ;

Fri, 9 Feb 2007 14:30:58 +0800 (CST)

From: [email protected]

從這些頭段可以知道郵件來自[email protected],首先被主機webmail-app40收到,時間是200729,星期五,當地時間143058秒,當時郵件來自主機192.168.208.33

然後郵件被主機localhost接收到,郵件來自主機m15-40.126.com,郵件通過SMTP協議接收,接收到郵件的時間是200729,格林威治標準時間63251秒。

最後郵件被主機202.116.32.4收到,郵件來自未知主機unknown,郵件通過SMTP協議接收,接收到郵件的時間是200729,當地時間142251秒。

13目的地址

描述郵件目的地址的頭段有Toccbcc,它們的語法如下:

    To: address

    cc: address

    bcc: address

其中address是一個或多個郵箱地址,在多個郵箱地址的情況下,郵箱地址彼此用逗號分隔。

To用來指出郵件的第一接收者,cc用來指出郵件的第二接收者。當郵件同時抄送給多人時,需要用到cc,其段體指出抄送的收件人。bcc是英文Blind Carbon Copy的縮寫,意思是隱藏地將郵件同時抄送給其他人,而不讓收件人知道。當郵件頭包含bcc段時,該段的內容將不會傳送給第一和第二收件人。至於bcc段中的收件人,他們可能看到bcc段的內容,也可能看不到,這取決於傳送郵件的系統。

當郵件被轉發時,可用Resent-ToResent-ccResent-bcc指出郵件的接收者和抄送接收者,它們的語法語義與Toccbcc分別對應。

 

釋疑:注意抄送和轉發的區別。抄送是在發送郵件時同時發送給多人,轉發是收信人收到郵件後,再傳送給其他人。

14 日期

Date頭段用來指出郵件的創建日期,其語法是

     Date: date-time

其中date-time指出日期時間,其語法爲

         [day , ] date time

其中可選項day表示星期幾,這一項後面要加逗號。date表示日期(年、月、日),time表示時間(時、分、秒)。

    星期幾用英文縮寫表示,即MonTueWedThuFriSatSun

    日期的格式爲dd month yyyy,其中dd是表示“日”的兩位數字,month是月份,用3個字母的英文縮寫,即JanFebMarApr等等,yyyy是年份,用4位數字表示。

    時間的格式是時分秒加時差。時分秒的格式是hh:mm:ss,分別用兩位數字表示時、分和秒,採用24小時記時制。日期時間必須用當地時間,但郵件接收者和沿途的轉發站未必在同一時區,因此最後加上“+hhmm或“-hhmm的時差部分,說明當地時間與格林威治標準時間相差(增加或減少)幾小時幾分鐘。

例如,Fri, 02 Mar 2007 22:13:00 +0800表示200732星期五22130秒,當地時間比格林威治標準時間多8小時0分。

    以上介紹的日期事件格式其實是RFC1123制定的格式。RFC822所制定的日期格式中,年份只用兩位數字,這顯然將導致“千年蟲”問題。RFC1123修正了RFC822的規定,年份改用4位數字。另外,RFC822的時間格式可以不用數字時差,而改用北美地區的時區符號說明當地時間,例如“EST”、“EDT”等,RFC1123建議採用數字時差。

    除了Date段,Received段最後的時間戳也使用這種日期時間格式。

當郵件被轉發時,可添加Resent-Date以說明日期時間,其用法與Date相同。

15 可選頭段

     可選頭段包括Message-IDResent-Message-IDIn-Reply-ToReferences Keywords SubjectCommentsEncrypted

Message-ID用來爲郵件指定一個唯一標識,其語法爲

         Message-ID: msg-id

其中msg-id形式爲<local-part@domian>,此處local-part是一串作爲郵件ID的字符串domian是指定這個ID的主機域名ID的唯一性由指定ID的主機負責。當一封郵件經過若干郵件服務器傳送時,這些郵件服務器可以各自爲這封郵件指定不同的ID,以便服務器內部管理郵件。

    當郵件被轉發時,可用Resent-Message-ID指定ID,其用法和Message-ID相同。

    In-Reply-To用來指出當前郵件是對哪一封郵件的答覆,其語法爲

         In-Reply-To:  *( phrase / msg-id )

    (注: 語法中的斜槓“/”表示“或者”,“*”表示可重複任意次)

其中phrase是一串字符串,msg-id是郵件ID,兩者可以單獨使用,也可以混合使用,目的是標識所答覆的郵件。例如:

    In-Reply-to: <000601c87ead$elcd28a0$0200a8c0@c220>

    References頭段用來指出與當前郵件相關的有哪些郵件。例如,當我們利用電子郵件討論某個問題時,可能來來往往會有很多封郵件,這時References可用來指出當前郵件涉及到哪些郵件。References的語法是:

         References:  *( phrase / msg-id )

例如:

    References: <000601c87ead$elcd28a0$0200a8c0@c220>

      <15662676.1412391204620030868.JavaMail.coremail@bj163app125.163.com>

    Keywords頭段用來指出當前郵件中的關鍵詞,其語法是:

         Keywords: #phrase

    (注: “#”表示其後的語法項可多次出現,彼此之間用逗號分隔)

其中phrase是關鍵詞,可以列出多個關鍵詞,彼此之間用逗號分隔。

     Subject頭段用來指出郵件的標題,其語法是

         Subject: text

其中text是任意的文字。

     Comments頭段是註釋,其語法爲

         Comments: text

注意Comments是整個段作爲註釋,在其它段中也可以插入註釋,插入的註釋內容只要用圓括號括起來即可。

    Encrypted頭段用來通知郵件接收者如何解密。郵件正文可以加密,接收方爲了解密,可能需要知道發送方使用何種加密手段。Encrypted的語法是

         Encryptedwd1, wd2

其中wd1指出加密程序的名稱,wd2用來幫助接收者選擇密鑰,例如,指出內部密鑰表的索引。

    郵件正文可以加密,但是郵件頭不能加密,因爲郵件頭中的信息是傳送郵件的主機必須知道的,如果加密,郵件將無法傳送。

    Encrypted已經被PEMPrivacy Enhanced Messaging)淘汰,有興趣的讀者可查閱RFC1421RFC1422RFC1423RFC1424

16 用戶自定義段

    以上介紹了RFC822所定義的頭段,以後還可能有新的RFC文件來定義一些新頭段,新頭段的段名必須在NIC(Network Information Center, SRI International, Menlo Park, California)登記。登記的新頭段段名不允許以“X-”或“x-”開頭。

    用戶可以自由使用自己定義的頭段,但這種段的段名不能與RFC822所定義的段名相同,也不能與將來登記的新頭段段名相同,否則可能被排斥。爲此,用戶自定義的段名可用“X-”或“x-”開頭,因爲RFC822已承諾新增加的段名不會以這兩個字母開頭。

17 例子和解釋

2:以下是一封垃圾郵件的全文,略去信件正文。雖然內容是垃圾,但語法格式是正確的(否則無法傳播),廢物利用,權當示例:

Received: (eyou send program); Mon, 26 Feb 2007 03:35:50 +0800

Message-ID: <[email protected]>

Received: from unknown (HELO downboy.com) ([email protected])

 by 202.116.32.4 with SMTP; Mon, 26 Feb 2007 03:35:50 +0800

Received: from domy5ly6i69dod ([89.131.200.82])

        by 83.7.213.189 (7.81.9/7.81.9) with SMTP id 8K7gQ4BTGPRFCJ;

        Sun, 25 Feb 2007 20:44:10 +0100

Message-ID: <001801c7591d$b39b46d0$00deed84@domy5ly6i69dod>

From: "Belinda May" <[email protected]>

To: "somebody" <[email protected]>

Subject: expenditure

Date: Sun, 25 Feb 2007 20:42:34 +0100

 

Some garbage text here ... ..., omitted.

從郵件頭可以看到,郵件創建於2007-2-2520:42:34,當地時間比格林威治時間多1小時。郵件標題是“expenditure”,收件人地址是[email protected],發信人地址是[email protected]。主機domy5ly6i69dod爲郵件指定了一個ID001801c7591d$b39b46d0$00deed84

郵件最先被IP地址爲83.7.213.189的主機收到,時間是2007-2-2520:44:10當地時間比格林威治時間多1小時。信件來自名稱爲domy5ly6i69dod的主機,通過SMTP協議接收。信件在該主機上的id8K7gQ4BTGPRFCJ

隨後郵件被IP地址爲202.116.32.4的主機接收到,時間是2007-2-2603:35:50,當地時間比格林威治時間多8小時。信件來自未知的主機,通過SMTP協議接收。主機scnu.edu.cn爲郵件指定了ID372432150.27375

最後信件被最終轉發程序接收,時間是2007-2-2603:35:50,當地時間比格林威治時間多8小時。

    信件中有一個空行,空行之前爲郵件頭,之後是信件正文。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章