多用途網際郵件擴展協定

MIME(Multipurpose Internet Mail Extensions)多功能Internet 郵件擴充服務。它是一個Internet標準,MIME給web瀏覽器提供了查閱多格式檔案的方法。多用途網際郵件擴充協定,多用途Internet郵件擴展(多用途網際郵件擴充協定(MIME))。

簡介

MIME(Multipurpose Internet Mail Extensions)多功能Internet 郵件擴充服務。它是一個Internet標準,MIME給web瀏覽器提供了查閱多格式檔案的方法。多用途網際郵件擴充協定

多用途Internet郵件擴展(多用途網際郵件擴充協定(MIME))

第一部分:Internet信息體格式

(RFC2045--Multipurpose Internet Mail Extensions(MIME)
Part One:Format of Internet Message Bodies)

本備忘錄的狀態

本文檔講述了一種Internet團體的Internet標準跟蹤協定,它需要進一步的討論和建議以得到改進。請參考最新版的“Internet正式協定標準” (STD1)來獲得本協定的標準化程度和狀態。本備忘錄的發布不受任何限制。

摘要

STD11,RFC 882定義了一種信息表示協定,該協定規定了US-ASCII訊息報頭(message header)的詳細細節,並規定訊息內容(message content)和訊息體(message body)為US-ASCII 文本格式。本系列文檔共同被稱為MIME(Multipurpose Internet Mail Extensions),重新定義了一系列允許下列內容的信息格式:

(1) 非US-ASCII的字元集的文本訊息體(message body)

(2) 不同格式的非文本訊息體(message body)的擴展集

(3) 多部分訊息體(message body)

(4) 非US-ASCII字元集的文本報頭息

這套文檔基於更早的文檔RFC934、STD 11及RFC1049,但對它們進行了擴展和修正。由於RFC822對訊息體(message body)涉及太少,所以這套文檔與RFC822的相關性不大(不是修正RFC822 )。

本文檔說明了用於描述MIME訊息(message)的多種報頭;第二個文檔RFC2046定義了MIME媒體類型系統的總體結構並且定義了媒體類型的初始集;第三個文檔是RFC 2047,它擴展了RFC822,允許在Internet郵件報頭中出現非US-ASCII文本;第四個文檔RFC2048說明了MIME相關程式的不同IANA註冊過程;第五個也是最後一個文檔RFC2049描述了MIME一致性標準,同時提供了一些關於MIME訊息格式的說明性示例,還有“致謝”和“參考書目”。

這些文檔都是RFC1521、RFC1522和RFC1590的修正版,而後面三個RFC又是RFC1341和1342的修訂版。在RFC2049中的附錄描述了與以前版本的不同及變化。

目錄

1. 介紹... 3

2. 定義、約定和一般的BNF語法... 4

2.1 CRLF. 5

2.2 字元集 (Character Set)... 5

2.3 訊息 (Message). 5

2.4 實體 (Entity)... 6

2.5 部分主體 (Body Part)... 6

2.6 主體 (Body)... 6

2.7 7位的數據 (7bit Data)... 6

2.8 8位的數據 (8bit Data)... 6

2.9 二進制數據 (Binary Data)... 7

2.10 行 (Lines) 7

3. MIME頭欄位(MIME Header Fields)... 7

4. MIME-Version頭欄位... 8

5. Content-Type 頭欄位... 9

5.1 Content-Type頭欄位的語法... 10

5.2 Content-Type的預設值... 12

6. Content-Transfer-Encoding頭欄位... 12

6.1 Content-Transfer-Encoding 句法... 12

6.2 Content-Transfer-Encoding 語義... 13

6.3 新的Content-Transfer-Encoding. 14

6.4 解釋及使用... 14

6.5編碼轉換... 16

6.6 規範的編碼模式(Canonical Encoding Model)... 16

6.7 Quoted-printable編碼... 16

6.8 Base64 Content-Transfer-Encoding. 20

7. Content-ID 頭欄位... 21

8. Content-Description 頭欄位... 22

9. 另外的MIME頭欄位... 22

10. 摘要... 22

11. 安全考慮... 23

12. 作者地址... 23

附錄A :收集的語法... 24

1. 介紹

自從1982年發布以來,RFC822已經定義了一個在Internet上傳輸文本郵件的標準格式。RFC822格式是如此的成功,它已經完全或部分的為大家所接受,其程度甚至超越了Internet或在RFC821中定義的Internet SMTP。也正是由於這種格式被廣泛的使用,所以許多限制因素日益約束著使用者群體。

RFC822被制定為用來指定文本信息格式。這樣,非文本信息――如包含音頻或圖像的多媒體信息――就完全沒有被提及。甚至對一些文本的情況也是這樣。RFC822不適用於那些需要多於US-ASCII字元集內容的使用者。因為RFC822沒有定義一種機制,以允許郵件包含音頻視頻、亞洲語言的文本甚至一些歐洲的語言文本,所以需要一個額外的規範來進行說明。

RFC821/822中的一個基於郵件系統的明顯限制,就是將電子郵件訊息(message)內容限制在一些由7位的US-ASCII字元組成的短行中(每行1000位元組或更少[RFC821])。這就迫使使用者在用本地用戶代理(UA—User Agent,用來收發郵件的程式)傳送他們的郵件之前,先要將將要傳送的非文本數據轉換為可列印的7位的US-ASCII字元。當前在Internet上使用的編碼方式有:純十六進制、uuencode、RFC1421中說明的base 64、ATK(the Andrew Toolkit Representation)及一些其它方式。

當為在RFC822主機與X.400主機之間交換郵件信息而設計網關時,RFC822的局限性就更加明顯了。X.400[X400]指定了一種在電子郵件訊息中包含非文本內容的機制。當前,從X.400訊息到RFC822訊息的映射標準規定,X.400訊息中的非文本部分必須要轉換為IA5Text格式,否則,這些內容就會被丟棄,並在丟棄即將發生時,通報RFC822的使用者。當一個用戶丟掉了他想接收的內容時,這顯然是十分另人不快的。即使在用戶代理不能處理非文本內容的時候,用戶也可以對其採取一些額外的機制,來提取有用的信息。另外,這種處理也沒有考慮到:訊息最後可能會被網關轉發到支持非文本信息的X.400訊息處理系統中。

這篇文檔描述了幾種機制,將它們聯合起來,可以解決大部分的這類問題,而不會引入與RFC822不兼容的問題。詳細的說,它描述了:

(1) “MIME-Version”頭欄位。它使用一個版本號來說明訊息適用於MIME,而且允許郵件處理代理將這類訊息與其它由舊版本或不適用的軟體所產生的訊息相區別。

(2) 在RFC1049中歸納的“Content-Type”頭欄位。用來指定訊息數據的媒體類型(media type)及子類型,以及指定這些數據的本地表示方法(規範形式)。

(3) “Content-Transfer-Encoding”頭欄位。用來指定套用於主體(body)的編碼轉換方式及結果所處的範圍。編碼轉換不同於恆等轉換,它通常用於使數據通過那些有數據或字元集限制的郵件傳輸機制。

(4) 兩個附加的頭欄位:“Content-ID”、“Content-Description”。它們被用來更深層的描述主體(body)中的數據。

這篇文檔中的所有的頭欄位定義都服從於RFC822中規定的句法規則。特別的,除了“Content-Disposition”以外,所有的這些頭欄位都可以包含RFC822注釋。這些注釋沒有實際意義,應該在MIME處理過程中忽略。

最後,為了說明及促進互用性,RFC2049為以上機制的子集提供了一個基本的適用性聲明。它定義了與本文檔相適應的最低限度。

歷史注釋:在第一次閱讀時,這組文檔中所描述的幾個機制看起來會有些奇怪或具有巴洛克風格。但要注意,對於開發這組文檔的團體而言,與現有標準兼容以及遇到現有習慣時的穩健性,這兩者具有相同的優先權。特別是“兼容性”永遠優先於“簡潔”。

請查閱當前版本的《網際網路官方標準》(“Internet Official Protocol Standards”)以得到本協定的標準化狀態及情況。RFC 822和STD3,RFC1123也提供了MIME的基本背景,符合MIME的實現都不會違背它們。另外,MIME的實現者也許會關心幾個另外的RFC文檔,特別是RFC1344、RFC1345和RFC1524。

2. 定義、約定和一般的BNF語法
雖然這組文檔所定義的機制都以文字的形式給出,但仍有一部分是由RFC 822定義的BNF符號所描述。為了了解這組文檔,實現者需要熟悉這些符號,並參考RFC 822,以得到這些擴充的BNF符號的完整解釋。

本文檔中的一些擴展BNF所構成的名字參考了RFC 822中的句法規則。或要獲得完整的語法則要組合如下內容:本系列每個文檔中收集了語法的附錄、RFC 822中定義的BNF以及在RFC 1123中對RFC 822 所進行的修正。(其中給出了“return”、“data”、“mailbox”的語法變化)

在這組文檔中,所有的數值字及位元組的值都由十進制的形式給出。所有的媒體類型(media type)、子類型以及參數名稱都是大小寫無關的。然而,除非特別說明,否則參數內容是大小寫相關的。

格式注釋:這部分的“注釋”提供了一些不重要的信息,在閱讀時可以跳過它們而不會錯過任何本質的東西。添加這些注釋的基本目的是為了說明關於這系列文檔的基礎原理,或是為了將其恰當地放置於歷史或發展過程中。這些信息,可以被那些只關心建立實現的人所忽略,但對那些希望懂得為什麼某種設計會被套用的人來說,這些信息還是會有一定用處的。

2.1 CRLF
在這系列文檔中,術語CRLF指一個US-ASCII字元序列。它由兩個字元組成:CR(十進制值為13)和LF(十進制值為10),它們按順序放在一起,構成RFC 822郵件的換行。

2.2 字元集 (Character Set)
在MIME中,術語“字元集”(character set)被用來表示一種將位元組序列轉換成字元序列的方法。注意,反方向不需要絕對的、明確的轉換,因為並不是所有的字元都可以被一個已知的字元集描述,而且一個字元集可能提供多於一個的位元組序列,來表示某字元序列。

本定義允許將各種類型的字元編碼做為字元集使用,如從簡單的單表映射(如US-ASCII)到多錶轉換方法(如使用ISO 2022技術)等。然而與MIME字元集名稱相關的定義則必須完全說明所要執行的映射。特別的,不允許使用外部描述信息來決定精確的映射。

注釋:術語字元集(“character set”)最初是用來描述一些簡單的方案如US-ASCII和ISO-8859-1的,它們都是從單一位元組到單一字元的一對一映射。多位元組編碼字元集和轉換方法使得情況更加複雜。例如,一些團體使用術語“character encoding”,而不是MIME中所使用的術語“character set”來表示字元集,而且使用“coded character set”來抽象的表示從整數(而不是位元組)到字元的映射。

2.3 訊息 (Message)
術語“訊息”(Message)在沒有進一步限定的時候,表示的是在Internet上傳輸的(完整或“頂層”的)RFC822訊息,或者表示壓縮在“message/rfc822”或“message/partial”中的內容。

2.4 實體 (Entity)
術語“實體”(Entity)特指MIME定義的頭欄位(header field)及內容(content),它們存在於訊息(message)及多部分實體的一部分之中。對這些實體的規範是MIME的基本內容。因為一個實體的內容經常被稱為“主體”(“body”),所以關於實體主體說法是有意義的。任何欄位都可以出現在實體頭信息中,但是只有那些以“content-”開頭的欄位有真實的、與MIME相關的意義。注意,這並不意味著它們沒有意義,一個沒有MIME頭欄位的實體(或訊息)的意義由RFC822所定義。

2.5 部分主體 (Body Part)
“body part”指的是多部分實體(mulitpart entity)中的一個實體(entity)。

2.6 主體 (Body)
在沒做進一步說明的時候,術語“主體”(body)指的是一個實體(entity)的主體部分。也就是指“訊息”(message)或“部分主體”(body part)的主體部分。

注釋:很明顯,以上四個概念被循環定義。因為MIME訊息的整個結構就是遞歸的,所以這種情況不可避免。

2.7 7位的數據 (7bit Data)
“7位的數據”(7bit Data)所描述的是相對較短的數據行:每行有998個或更少的8位位元組內容,行分隔設定為CRLF序列[RFC-821]。其中,每一個8位位元組的值都不可以大於十進制的127,也不能為NUL(十進制的0),而且CR(十進制值為13)和LF(十進制值為10)位元組只可以出現在CRLF序列中。

2.8 8位的數據 (8bit Data)
“8位的數據”(8bit Data)所描述的是相對較短的數據行:每行有998個或更少的8位位元組內容,行分隔設定為CRLF序列[RFC-821]。其但是位元組的值可以大於十進制的127。與“7bit data”一樣, CR(十進制值為13)和LF(十進制值為10)位元組只可以出現在CRLF序列中,位元組的值不能為NUL(十進制的0)。

2.9 二進制數據 (Binary Data)
“二進制數據”(Binary Data)是指可以包含任何位元組序列的數據。

2.10 行 (Lines)
“行”(Lines)被定義為由CRLF分隔的位元組序列。這與RFC 821及RFC 822一致。“行”(Lines)是指訊息(Message)中的數據單位,它可以符合或不符合用戶代理(user agent)所顯示的真實情形。
3. MIME頭欄位(MIME Header Fields)
MIME定義了許多新的RFC822頭欄位,用以描述MIME實體內容(entity content)。這些頭欄位至少會在以下兩個地方出現:

(1) 做為規則的RFC822訊息(message)頭信息的一部分。

(2) 在多部分結構(multipart construct)里,存在於“部分主體”(body part)頭信息中。

這些頭欄位的形式定義如下:

entity-headers := [ content CRLF ]

[ encoding CRLF ]

[ id CRLF ]

[ description CRLF ]

*( MIME-extension-field CRLF )

MIME-message-headers := entity-headers

fields

version CRLF

; 當前BNF所暗含的實體頭信息

; 順序可以被忽略。

MIME-part-headers := entity-headers

[ fields ]

; 任何不以“content-”開始的欄位

; 都沒有被定義,可以被忽略。

; 當前BNF所暗含的實體頭信息

; 順序也可以被忽略。

不同的MIME頭欄位的語法細節會在下面的章節中說明。

4. MIME-Version頭欄位
自從1982年發布了RFC 822以來,實際上只存在這一種Internet訊息格式標準,而且幾乎沒人意識到需要聲明那些正在使用中的格式。這篇文檔是一個補充RFC822的獨立說明。雖然在這篇文檔中所做的擴展已經被定義為與RFC 822兼容,但是,郵件處理代理仍然需要知道一個訊息是否是按照新的標準構成。

為此,本文檔定義了一個新的頭欄位:“MIME-Version”。它被用來聲明Internet訊息主體(message body)所使用格式的版本號。

按照本文檔格式所構成的訊息(message),必須按如下格式包含這個頭欄位:

MIME-Version: 1.0

這個欄位就是一個聲明,它表示訊息的結構符合本文檔所規定的格式。

因為今後的文檔中有可能再次擴展訊息格式的標準,所以這裡給出MIME-Version頭欄位的BNF:

version := "MIME-Version" ":" 1*DIGIT "." 1*DIGIT

這樣,將來的格式說明符都被約束為以小數點分隔的兩個整數,它們可能會替代或擴展字元:“1.0”。如果接收到一個訊息,它的MIME-version值不是“1.0”,那么就可以假定它不符合本文檔的規範。

還有一件值得注意的事情是,不可以使用MIME-Version機制來實行對媒體類型的版本控制。特別的,一些格式(如application/postscript)擁有包含在媒體格式內部的約定版本號。當這種約定存在時,MIME不會將其取代。當這種約定不存在時,MIME會在必要的時候使用“content-type”欄位中的一個“version”參數進行聲明。

實現者要注意的問題:在檢查MIME-Version的時候,一定要忽略任何在RFC822中所定義的注釋部分。詳細的說,以下的MIME-Version欄位是等價的:

MIME-Version: 1.0

MIME-Version: 1.0 (produced by MetaSend Vx.x)

MIME-Version: (produced by MetaSend Vx.x) 1.0

MIME-Version: 1.(produced by MetaSend Vx.x)0

當缺少MIME-Version欄位時,接收郵件的代理(無論此代理是否符合MIME要求)都可以按照本地的約定,任意的解釋訊息體。在當前的使用中存在的許多這樣的約定。應該注意到,在實際中非MIME訊息可以包含任何內容。

無法確定一個非mime郵件訊息中只包含US-ASCII字元集的純文本內容,因為這個訊息很可能使用了一些非標準的比MIME更早出現的本地約定,或是包含其它字元集的內容或非文本的內容,這樣,訊息就無法被自動的識別。(如用UUENCODE方式編碼的UNIX tar壓縮檔案)

5. Content-Type 頭欄位

設定“Content-Type”頭欄位的目的是為了完整的描述主體(body)中數據的內容。這樣,接收代理就可以挑選出適當的代理或機制,來向用戶呈現數據內容,或以適當的方式處理數據。這個欄位值被稱為“媒體類型”(media type)。

歷史注釋:“Content-Type”頭欄位最初是在RFC1049中定義的。RFC1049中使用的是相對簡單的,不強大的語法,但是在很大程度上與本文檔所定義的機制相兼容。

“Content-Type”頭欄位通過指定媒體類型及子類型的標識符來說明實體主體(body of an entity)中數據的原始類型,而且它還會為一些特別的媒體類型提供輔助信息。在媒體類型及子類型名稱之後,本欄位中的其餘部分均為參數,它們以“屬性 = 值”的形式給出,至於這些參數是按什麼順序給出的,則並不重要。

總的來說,頂層的媒體類型被用來聲明數據的一般類型,而子類型則指明了數據的細節格式。因此,媒體類型“image/xyz”足以使用戶代理知道,接收的數據是一個圖像,哪怕這個用戶代理並不知道這種特殊的圖像類型:“xyz”。因此,這類信息可以被用來決定是否向用戶顯示一種擁有不能識別的子類型的原始數據――此操作對於擁有不可識別子類型的文本內容來說是合理的,但不適用於圖像(image)和音頻(audio)類型的數據。由於這個原因,文本、圖像、音頻和視頻的子類型都不能包含有不同類型的嵌入信息。這種複合的格式應該由類型“multipart”和“application”所描述。

參數是媒體子類型的修飾成份,而不會影響內容的性質。一組有意義的參數依賴於媒體類型及子類型。大部分的參數只與某單一的子類型相關聯。然而,一個頂級的媒體類型可以定義一些與其中的任何子類型都關聯的參數。對於所涉及到的內容類型(content type)或子類型(subtype)來說,參數可能是必須的,也可能是可選的。MIME的實現過程中必須忽略所有不能識別的參數。

例如,“charset”參數可適用於“text”類型中的任何子類型,而“boundary”參數則是“multipart”類型中所有子類型所必須的。

不存在適用於所有媒體類型的全局參數。真正的全局機制是通過在MIME原型中定義“Content-*”頭欄位而提出的。

在RFC2046中定義了最初的七個頂級媒體類型。其中的五個是不連續的類型,它們的內容是MIME處理過程所不關心的。另外的兩個類型是合成的,它們的內容需要MIME處理器進行額外的處理。

這組頂級的媒體類型(media type)已被完全定義。希望在對這組媒體類型進行擴充的時候,只是擴充初始類型中的子類型。將來,只可以在擴展本標準的情況下,才能定義更多的頂級媒體類型。無論任何原因,如果需要使用另一個頂級類型,那么這個類型的名稱必須以“X-”開頭,以表示它是一個非標準的狀態,以避免今後與官方定義的名稱衝突。

5.1 Content-Type頭欄位的語法

用一種擴充的BNF符號定義“Content-Type”頭欄位,如下:

content := "Content-Type" ":" type "/" subtype

*(";" parameter)

; 匹配媒體類型或子類型時,是大小寫無關的

type := discrete-type / composite-type

discrete-type := "text" / "image" / "audio" / "video" /

"application" / extension-token

composite-type := "message" / "multipart" / extension-token

extension-token := ietf-token / x-token

ietf-token := <An extension token defined by a

standards-track RFC and registered

with IANA.>

x-token := <The two characters "X-" or "x-" followed, with

no intervening white space, by any token>

subtype := extension-token / iana-token

iana-token := <A publicly-defined extension token. Tokens

of this form must be registered with IANA

as specified in RFC 2048.>

parameter := attribute "=" value

attribute := token

; 匹配屬性( attributes)時,

; 總是大小寫無關的

value := token / quoted-string

token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,

or tspecials>

tspecials := "(" / ")" / "<" / ">" / "@" /

"," / ";" / ":" / "\" / <">

"/" / "[" / "]" / "?" / "="

; Must be in quoted-string,

; to use within parameter values

注意,對“tspecials”的定義與RFC822中對“specials”的定義是幾乎一樣的,只是新增了三個字元:“/”、“?”、“=”,又去掉了一個字元:“.”。

還要注意到,對子類型(subtype)的定義是強制性的――子類型不可以被Content-Type欄位所忽略,因此,也就不存在預設的子類型(subtype)。

類型、子類型、參數名稱都是大小寫無關的。例如:“TEXT”、“Text”和“TeXt”表示相同的頂級媒體類型。參數值通常都是大小寫相關的,但是一些時候也被定義為大小寫無關的形式,這依賴於具體的套用。(例如,multipart boundary就是大小寫相關的、而“access-type”則是大小寫無關的)

注意一個用引號括起來的參數值中不包括引號,這就是說,一個被引號括起來的字元串中,引號是不包括在參數值中的,但這僅限於使用引號確定參數值界線的情況下。另外,格式與RFC822規則一致的注釋也允許出現在這個欄位中,因些,以下兩種形式是完全等價的:

Content-type: text/plain; charset=us-ascii (Plain text)

Content-type: text/plain; charset="us-ascii"

除了這些句法之外,對構成子類型名稱的唯一句法約束是它們在使用中不可以相互衝突。這就是說,不可以有兩個不同的團體使用“Content-Type: application/foobar”來表示兩種不同東西。定義一個媒體子類型的過程,並不受限制:只需要公布這些類型的定義,並使用它們即可。因此,兩種廣泛接受的定義媒體子類型的機制如下:

(1) 私有值(以“X-”開頭的名稱)可以在兩個協同工作的代理之間雙向的定義,而不需要外部的註冊或標準化。這種值不可以被註冊或制定為標準。

(2) 可以向IANA註冊新的標準,如RFC2048中描述的情況。

這組文檔中的第二篇:RFC2046定義了媒體類型的初始集合。

5.2 Content-Type的預設值

沒有“Content-Type”頭欄位的RFC822訊息被默認為是US-ASCII字元集、純文本類型的內容。它可以被精確的描述為:

Content-type: text/plain; charset=us-ascii

這個預設值是在沒有指定“Content-Type”頭欄位時而使用的。而且,在遇到句法錯誤的“Content-Type”頭欄位時,也會使用這個預設值。當訊息中存在“MIME-Version”頭欄位,而缺少“Content-Type”頭欄位時,接收方的用戶代理也可以假定傳送者所傳送的是US-ASCII字元集的純文本內容。在沒有“MIME-Version”頭欄位或有錯誤語法的“Content-Type”頭欄位時,仍然可以假定其內容是US-ASCII字元集的純文本,但是這可能不是傳送者的本意。
6. Content-Transfer-Encoding頭欄位

通過郵件傳輸的一些數據可能會被聲明成它們的“原始”格式,如8位字元(8bit character)或二進制數據(binary data)。這些數據不通過一些傳輸協定進行傳輸。如:RFC821(SMTP)中限制郵件訊息中只可以由一些包括行結束符CRLF序列在內,長度不超過1000位元組的行組成,而且所有的字元都是7位的US-ASCII字元。

因此需要定義一種機制來將這些數據編碼為7位數據(7bit data)的短行。並且,當在限制很少的系統中直接傳輸無限制的格式時,需要對其中未編碼內容進行適當的標記。本文檔通過一個新的“Content-Transfer-Encoding”頭欄位來指定這類編碼。這個頭欄位並沒有在以前的標準中進行過定義。

6.1 Content-Transfer-Encoding 句法

“Content-Transfer-Encoding”頭欄位中只有一個值,它指定了編碼類型,格式如下:

encoding := "Content-Transfer-Encoding" ":" mechanism

mechanism := "7bit" / "8bit" / "binary" /

"quoted-printable" / "base64" /

ietf-token / x-token

這些值都是大小寫無關的,“Base64”、“BASE64”、“bAsE64”的意義相同。

編碼方式“7bit”要求實體體中的內容都是7位位元組。而且它也是預設值,這就是說,如果沒有“Content-Transfer-Encoding”頭欄位,則假定其為:“"Content-Transfer-Encoding: 7BIT”。

6.2 Content-Transfer-Encoding 語義
字元串“Content-Transfer-Encoding”實際上提供了兩條信息。它指明了在傳輸主體(body)的時候,採用了哪種編碼方式及必須用哪種解碼方式將數據解碼成它的原始狀態。同時,它還指明了解碼結果所處的範圍。任何“Content-Transfer-Encoding”的轉換部分――無論是確定的還是預設的――都指定了一個單一的、詳細定義的解碼算法。這個算法可以將編碼後的任意位元組序列轉換為編碼前的原始序列,或說明某部分內容是非法的編碼序列。“Content-Transfer-Encoding”轉換永遠不會依賴於附加的外部信息。注意,解碼器必須為每一個合法的編碼內容提供一個單一的、詳細定義的輸出。而對於編碼器卻不存在這樣的限制。對同一個輸入序列,編碼器可以給出不同的,等價的編碼序列――這是完全合法的。

目前定義了三種轉換方式:恆等的、“quoted-printable”編碼、“base64”編碼。範圍是“binary”、“8bit”、“7bit”。

“Content-Transfer-Encoding”的值為“7bit”、“8bit”、“binary”時,說明編碼轉換已經完成(也就是沒有編碼),同時,作為簡單的標識符,它們給出了實體體數據的範圍,並提供了在某個特定的傳輸系統中傳輸數據時可能會採用某種編碼方式的相關信息。術語“7bit data”、“8bit data”、“binary data”的定義見第二節。

“quoted-printable”及“base64”會將任意的輸入內容轉換到“7bit”範圍中,以使數據可以在受限制的系統中傳輸。轉換的定義將在下文中給出。

必須始終使用正確的“Content-Transfer-Encoding”標誌。不允許將未編碼的8位字元(8bit characters)標誌為“7bit”。而且,未編碼的與行無關的內容只能被標識為“binary”。

與媒體子類型不同,“Content-Transfer-Encoding”值不需要有子類型值。然而,不可能只建立一個單一的到“7bit”的轉化方式。因為要在以下兩個方面進行權衡:對較長的二進制內容進行簡潔、高效的編碼,或是需要一個更易讀的編碼內容,而編碼可以不完全是7bit的。由於這個原因,至少要提供兩種編碼機制:或多或少可讀的編碼(quoted-printable)和“緊湊”、“均勻”的編碼(base64)。

在RFC1652中定義了傳輸未編碼的8位數據的方式。到最初公布本文檔時為止,還沒有為在網際網路上傳輸包含未編碼二進制數據郵件而制定的標準。因此就不存在“二進制”(binary) Content-Transfer-Encoding類型值合法的出現在網際網路郵件中的情況。然而,當傳輸“二進制”郵件成為可能時,或MIME被用來連線其它任何的可傳輸“二進制”郵件的郵件傳輸機構時,就必須用這種機制對“二進制”內容進行標識。

注意:為“Content-Transfer-Encoding”頭欄位所定義的五個值只是為媒體類型提供了編碼或解碼的算法。

6.3 新的Content-Transfer-Encoding

如果需要,實現者可以定義私有的“Content-Transfer-Encoding”值。但是必須使用X標記,就是指要在名字前面加上“X-”,以說明它是一個非標準的狀態。如,“Content-Transfer-Encoding: x-my-new-encoding”。 其它的“Content-Transfer-Encoding”標準值,則必須通過標準途徑RFC來定義。在RFC2048中給出了這些說明須符合的要求。同樣的,除了以“X-”開頭的“Content-Transfer-Encoding”名字之外,所有的名字都是為IETF將來的使用而保留的。

與媒體類型及子類型不同,不提倡創建新的“Content-Transfer-Encoding”值。因為它會阻礙互用性,並且幾乎沒有一點潛在的好處。

6.4 解釋及使用
如果“Content-Transfer-Encoding”頭欄位是訊息頭信息的一部分,那么它對這個訊息中的全部主體(body)都適用。如果“Content-Transfer-Encoding”頭欄位是實體(entity)頭信息的一部分,那么它只適用於這個實體(entity)的主體(body)。如果實體類型是“multipart”,則“Content-Transfer-Encoding”只能是“7bit”、“8bit”、“binary”中的一個。一些更為嚴格的約束將套用於“message”媒體類型的子類型。

應該注意到,大部分的媒體類型都是按照位元組而不是位而定義的,因此,這裡描述的機制是解碼任意位元組流而非位流。如果需要通過這些機制對位流進行編碼,則必須要先使用網路位順序標準(大端位元組序[big-endian])將位流轉換成8位位元組流――位流中靠前的位出現在位元組的高位中。如果位流中剩下的部分不足8位,則必須補0。RFC2046中提供了用參數為“padding”的“application/octet-stream”媒體類型來說明上述這種填充機制。

這裡定義的編碼機制可以將任何數據編碼為US-ASCII字元集的內容。因此,如果假設一個實體有如下頭欄位:

Content-Type: text/plain; charset=ISO-8859-1

Content-transfer-encoding: base64

則必須被解釋為:實體內容是BASE64 US-ASCII編碼的數據,而原始數據為ISO-8859-1字元集內容,而且解碼後內容也處於同一字元集ISO-8859-1中。

特定的“Content-Transfer-Encoding”值可以被用於特定的媒體類型。特別的,明確禁止將除“7bit”、“8bit”、“binary”之外的編碼方式套用於任何複合的媒體類型,如遞歸包含其它“Content-Type”頭欄位的媒體類型。當前僅有的複合媒體類型是“multipart”和“message”。想要對“multipart”或“message”類型的實體編碼時,必須在最裡面的一層中,對需要編碼的真實實體進行編碼。

同樣要注意,如果一個實體的編碼類型被定義為“7bit”,而其中還包含有一個編碼類型為“8bit”的實體。這時,或者外部的“7bit”標籤是錯誤的,因為它包含了8位的數據;或者內部的“8bit”標籤對傳輸系統提出了不必要的要求,因為實際上它包含的數據類型只是7位的。

關於編碼約束的注釋:雖然禁止在複合結構中使用“Content-Transfer-Encoding”可能有些過度嚴格,但是必須要防止嵌套編碼――這樣會導致對數據進行多次編碼,以及為正確顯示出數據內容必須進行多次解碼。嵌套編碼會給用戶代理的工作增加很大的複雜度:多次編碼除了會帶來效率問題,還會使訊息的原始結構變得含糊。特別的,它們暗示了只有在進行所有的解碼操作之後,才可以知道訊息內容的類型是什麼。禁止嵌套編碼會使郵件網關的工作變得複雜,但是,與重複編碼可能給用戶代理所帶來的影響相比,這個問題要小得多。

對於任何帶有不可識別的“Content-Transfer-Encoding”值的實體,不論其“Content-Type”真實值是什麼,都要將其看作為“application/octet-stream”類型。

“Content-Type”與“Content-Transfer-Encoding”的關係:看起來似乎可以通過被編碼媒體的特徵來推斷出“Content-Transfer-Encoding”的值,或者至少可以通過對一些特定媒體類型的使用來確定“Content-Transfer-Encoding”。但實際上,這些假設是不正確的,這裡給出幾個原因:首先,對於郵件,存在不同的傳輸方式,一些編碼可能只適用於某些而不是全部的媒體類型或傳輸方式。(如,在8位傳輸系統中,不需要對特定字元集中的文本進行編碼,而在7位傳輸系統中,卻一定需要編碼。)

其次,同一媒體類型在不同的環境中,可能會需要不同的傳輸編碼方式。例如,許多郵件的附言(PostScript)部分完全是由7位數據的短行組成,因此不需要編碼。而其它的(特別是那些使用Level 2 PostScript二進制編碼機制的)附言可能需要使用二進制傳輸編碼進行描述。

最後,因為“Content-Type”已經被制定為可擴充式的規範機制,所以,如果嚴格定義媒體類型與編碼的關係,就會將套用協定的定義與更低層的傳輸細節相結合。而這是不合乎 要求的,因為媒體類型的設計者不一定需要知道所有會被使用的傳輸方式及其局限性。

6.5編碼轉換
可以在“quoted-printable”和“base64”編碼方式之間進行轉換操作。只有當需要在“quoted-printable”編碼中強制輸出換行符的時候才需要這種操作。從“quoted-printable”轉換到“base64”格式的時候,“quoted-printable”編碼中的換行符被表示為CRLF序列。因此,它必須被轉換為用“base64”方式編碼後的相應內容。同樣,解碼後數據中的CRLF序列也必須被轉換成“quoted-printable”的強制換行符,但這隻適用於文本情況。
6.6 規範的編碼模式(Canonical Encoding Model)

何時將郵件數據轉換為標準形式並編碼、這個過程如何處理CRLF(新行符,並且在不同的系統中具有不同的形式)、傳輸編碼與字元集之間有什麼關係――在以前版本的RFC中,關於這些方面的問題都很混亂。由於這個原因,RFC2049給出了編碼的規範模型。

6.7 Quoted-Printable編碼
Quoted-Printable編碼適用於內容多為US-ASCII字元集中可列印字元的情況。經過它編碼的數據不再需要郵件傳輸系統進行轉換。如果被編碼的數據多為US-ASCII字元,則編碼後的內容會保留那些可人為識別的部分。完全由US-ASCII字元構成的內容也可以進行Quoted-Printable編碼,以確保可以通過字元轉換及(或)行封裝的網關來傳遞所有的訊息 數據。

在這種編碼方式中,位元組按如下規則描述:

(1) (普通的8位位元組描述)除了被編碼內容中標準換行符CRLF序列里的CR和LF位元組之外的任何位元組,都應該被表示成“=”後面緊跟著兩個表示位元組值的十六進制數字的形式。此處使用的十六進制字元表是“0123456789ABCDEF”。必須使用大寫字母,而不允許使用小寫字母。因此,十進制的值12可以被表示為:“=0C”,十進制值61(表示US-ASCII字元集中的等號)可以被表示為“=3D”。除了選擇後面規則中所規定的編碼方式之外,必須遵循本規則。

(2) (文字表示法) 十進制值從33到60、從62到126的位元組,可以直接表示為US-ASCII字元集中的相應字元(即從感嘆號‘!’到小於號‘<’、從大於號‘>’到符號‘~’)。

(3) (空格) 十進制值為9和 32的位元組可以被分別表示為US-ASCII字元集中的TAB(HT)和空格(SPACE)。但是這種表示方法不可以套用在編碼行的末尾。在編碼後的內容中,任何TAB(HT)及空格(SPACE)字元後面都必須跟隨有可列印的字元。特別的,行末的“=”表示“軟換行”(見規則5),它可以跟隨在一個或多個TAB(HT)或空格(SPACE)字元後面。它遵循了這樣一條規則:當行末的最後一個位元組的值在9到32之間時,必須按照規則(1)進行編碼。這是必要的,因為一些傳送訊息的MTA(Message Transport Agent--訊息傳送代理:將訊息從一個用戶傳送至另一個用戶處或進行其中一部分工作的程式)會用空白字元來填充行,而其它的則會從行末移除空白字元。因此,當進行“Quoted-Printable”解碼時,要刪除行末的任何空白字元, 因為它們很可能是被中間的傳送代理加上的。

(4) (換行符) Quoted-Printable編碼將文本內容中的換行符(CRLF序列)表示成RFC 822的換行符(也是CRLF序列)。因為,除了文本類型(text)之外的其它規範媒體類型通常都不會包含有換行符CRLF序列。這些媒體類型的Quoted-Printable編碼中不會出現硬換行符(就是有意義的、要顯示給用戶的換行符)。所以,在Quoted-Printable編碼的非文本類型的數據中就可能會出現“=0D”、“=0A”、“=0A0D”、“=0D0A”等序列。

注意,許多實現機制都是直接將不同的媒體類型編碼為本地形式,而不是先將它們轉換成規範的格式然後編碼,最後再轉換成本地形式。特別的,在不使用CRLF序列做為行終止符的系統中,當對純文本內容進行操作時,會出現這種情況。而只有在某種組合的規範編碼等價於分別執那三步操作的時候,才允許執行這種最佳化的操作。

(5) (軟換行符) Quoted-Printable編碼規則要求每個編碼行的長度不超過76位元組。如果需要編碼更長的行,就必須要使用“軟”換行符。在編碼內容中,出現在一行最後位置的等號(“=”)表示無意義的換行符(軟換行符)。

因此,如果編碼前的格式是一個單獨的未編碼行:

Now's the time for all folk to come to the aid of their country.

那么在Quoted-Printable編碼後,它可以被表示為:

Now's the time =

for all folk to come=

to the aid of their country.

通過這種機制,過長的行可以被編碼成一種能被用戶代理存貯的形式。76個字元的限制不包含行末的CRLF序列,但是計算了其它的全部內容,包括所有的等號。

因為在Quoted-Printable中,連字元(“-”)可以不編碼,所以當Quoted-Printable編碼的內容被包含在一個或多個multipart實體中時,一定要注意不能讓邊界分隔設定(boundary delimiter)出現在編碼內容的任何位置上。(選擇邊界分隔設定時,最好使其包含一個“=_”序列,因為這個序列永遠不會出現在Quoted-Printable編碼內容中。參考RFC2046中關於multipart的定義)

注意:Quoted-Printable編碼為傳輸中數據的可讀性及可靠性提供了一種折中的方法。通過Quoted-Printable編碼的主體(body)能可靠的在多數的郵件網關上傳輸,但是在少數網關上--特別是在涉及EBCDIC轉換的網關上--它也許不能很好的工作。base64編碼方式提供了更高的可信度。另外一個能經過EBCDIC網關進行可靠傳輸的方法,就是將如下US-ASCII字元按照規則(1)進行編碼:

!"#$@[\]^`{|}~

quoted-printable數據內容都被假定為面向行的,因此可以預料,在傳輸過程中可能會轉換各行之間的換行符。也就是說,在不同換行習慣的系統間傳輸的純文本郵件通常被轉換成網際網路郵件。如果這種轉換會構成錯誤的數據,那么就需要採用base64而不是quoted-printable來進行編碼。

注釋:quoted-printable編碼規則決定了不能生成幾種類型的子串,因此,如果quoted-printable編碼器輸出這些字元串,則說明它們是非法的。本注釋列舉了這些情況以及在解碼過程中處理這些非法子串的方法。

(1) 等號“=”後而跟著兩個十六進制的數字,但兩個數字或其中的一個是小寫字母“abcdef”的非法格式。一個健壯的執行程式可以選擇將它們當做相應的大寫字母來識別。

(2) 如果等號“=”後面的字元即不是十六進制數字(包括“abcdef”),也不是CRLF對中的CR字元,那么就是非法的。產生這種情況可能是因為將未編碼的US-ASCII文本包含進了訊息中的quoted-printable編碼部分。對於健壯的執行程式來說,一個合理的解決方式是將等號及其後面的字元包含進解碼內容中,而不進行任何轉換。而且如若可能,要向用戶指出:在這個位置處的解碼也許會出現錯誤。

(3) 等號“=”不可以是編碼內容中的最後一個或倒數第二個字元。相應的處理方式可以參考上面的情況(2)。

(4) 除TAB字元、CRLF對中的CRLF字元之外,不可以出現其它的控制字元。同樣也不可以存在十進制值大於126的位元組。如果解碼時在輸入數據中出現這些字元,則健壯的執行程式要將這些非法字元從解碼數據中刪除,並要警告用戶發現非法字元。

(5) 編碼後的行長度不可以超過76字元(不包括CRLF換行符)。對於一個健壯的解碼程式而言,如果在解碼時從輸入的編碼內容中發現了更長的行,則仍然要對其進行解碼,同時還可以向用戶報告編碼錯誤。

對實現者的警告:如果用quoted-printable編碼二進制數據,則必須要分別將CR和LF字元編碼為“=0D”和“=0A”。特別的,應該將二進制數據中的CRLF序列編碼為“=0D=0A”。否則,如果CRLF序列被描述成一個硬換行符,那么在使用其它換行符的系統中解碼數據時就會出錯。

按照如下語法描述quoted-printable數據:

quoted-printable := qp-line *(CRLF qp-line)

qp-line := *(qp-segment transport-padding CRLF)

qp-part transport-padding

qp-part := qp-section

; 最大長度為76字元

qp-segment := qp-section *(SPACE / TAB) "="

; 最大長度為76字元

qp-section := [*(ptext / SPACE / TAB) ptext]

ptext := hex-octet / safe-char

safe-char := <any octet with decimal value of 33 through

60 inclusive, and 62 through 126>

; 也不推薦使用

; 沒有在RFC2049中列為“mail-safe”的字元

hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")

; 這些位元組被用來表示值大於127的位元組,

; 以及出現在行尾的空格或TAB。而且,

; 對於沒有在RFC2049中列為“mail-safe”

; 的字元,也推薦使用這種表示方式。

transport-padding := *LWSP-char

; 設計者不可以產生非零長度的填充,

; 但是接收者必須能夠處理由傳輸機構

; 增加的填充內容。

注意:本BNF中所提到的附加LWSP是不被承認的,因為這個BNF並沒有詳細說明一個結構頭欄位。
6.8 Base64 Content-Transfer-Encoding

設計Base64內容傳輸編碼是為了描述任意的不需要人為識別的位元組序列。編碼及解碼算法很簡單,不過,編碼後的數據總是比編碼前的數據長33%。Base64與RFC1421中定義的Privacy Enhanced Mail (PEM)是同一個編碼方法。

由US-ASCII中65個字元組成一個子集,使用6位來表示每一個可列印的字元(第65個字元“=”表示要進行特殊的操作)

注意:這個子集有個很重要的性質,那就是,在任何版本的ISO 646(包括US-ASCII)中,它都被描述成相同的內容。而且,在任何版本的EBCDIC中,子集中的所有字元也都具有相同的描述。其它常用的的編碼,如UUENCODE、Macintosh binhex 4.0 [RFC-1741]、base85就沒有這些性質,因此就無法滿足郵件二進制傳輸編碼的可移植性要求。

編碼時,每次輸入24位數據,輸出為4個編碼字元。將輸入的3個8位位元組從左到右連續排列,就可以形成24位數據。將這24位看做是4個連續的6位組,每組都可以單獨譯成一個base64表中的字元。當通過base64編碼方式編碼一個位流時,必須假定位流為“重要位優先”的順序。就是說,位流中的第1位應該是第一個位元組中的最高位;位流中的第8位應該是第一個位元組中的最低位,依此累推

用每組(6位)的值來索引64個可列印字元。索引後將得到的字元依次放入輸出字元串中。選擇表1中的這些字元,是為了能夠完備的描述,並且排除在SMTP中有特殊意義的字元(如‘.’、CF、LF)以及在RFC2046中定義的multipart的邊界分隔設定中有特殊意義的字元(如‘-’)。

表1:base64字母表

Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y

編碼輸出的流必須被描述成一些不大於76位元組的行。解碼時,必須要忽略換行符及其它所有不存在於表1中的字元。在base64數據中,除表1中字元、換行符、空格之外的字元都可能表示存在傳輸錯誤,在某些情況下,可以適當的給出一些警告信息甚至是拒絕信息。

如果需要被編碼數據的剩餘部分不足24位,則要執行特殊的操作。編碼量通常在主體(body)結尾部分結束。當輸入少於24位時,會在末尾(右側)添加一些值為0的位,以形成完整的6位組。用“=”來表示數據結尾的填充。因為所有base64的輸入都是完整的位元組,所以只可能出現如下情況:(1)最後的編碼輸入是完整的24位;這時,編碼輸出的最後一個單元會是完整的4個不為“=”的個字元。(2)最後的輸入是8位;這時,編碼輸出的最後一個單元是兩個編碼字元後接兩個填充字元“=”。(3)最後的輸入剛好是16位;這時,編碼輸出的最後一個單元是三個編碼字元後接一個填充字元“=”。

因為“=”是用來填充數據的結尾部分,所以,它的出現意味著可能已經到達數據末尾(但不切斷傳輸)。然而,也可能無法以這種方式進行判斷:當傳輸的位元組個數是三的整數倍時,編碼中就不會出現“=”。

在base64編碼數據中,要忽略任何不屬於base64字母表的字元。

一定要注意,當base64編碼直接套用於未經過規範化的文本內容時,要使用恰當的位元組做為換行符。特別是在進行base64編碼前,必須要將文本換行符轉換為CRLF序列。要注意,一件很重要的事情就是:這些操作可以直接由編碼器來完成,而不是在一些實現中先進行一個標準化的步驟。

注釋:不用擔心multipart實體中的base64編碼部分引用到潛在的邊界分隔設定(boundary delimiter),因為base64編碼中沒有使用連字元“-”。

7. Content-ID 頭欄位

在構建一個高級別的用戶代理時,可能會需要在一個主體(body)中涉及到另一個主體。因此需要用“Content-ID”頭欄位給主體(body)設定標籤。這個欄位在語法構成上與“Message-ID”相同:

id := "Content-ID" ":" msg-id

與Message-ID的值一樣,Content-ID的值也必須是世界上唯一的。

Content-ID的值可以被用來在多處上下文中唯一的確定MIME實體,尤其用於被message/external-body機制所引用的快取數據。雖然Content-ID頭欄位通常是可選的,但是對於生成可選的媒體類型“message/external-body”的實現程式來說,它則是必須存在的。這就是說,每一個message/external-body實體(entity)必須有一個Content-ID欄位來允許對這些數據的快取。值得注意的是,Content-ID值在multipart/alternative媒體類型中有特殊的意義。這一點會在RFC2046中關於multipart/alternative的那一節中進行解釋。

8. Content-Description 頭欄位

經常需要將一些描述信息與給定的實體結合起來。例如,將某個“image”類型的實體標記為“a picture of the Space Shuttle Endeavor.”會有一定的用處。這些文字可以被放入ContentDescription頭欄位中。這個頭欄位通常是可選的。

description := "Content-Description" ":" *text

描述被假定為以US-ASCII字元集的形式給出,不過在RFC2047中定義了一種使用非US-ASCII字元集的Content-Description值的機制。

9. 另外的MIME頭欄位

將來的文檔可能會為不同目的而另外定義一些MIME頭欄位。任何進一步描述訊息內容的頭欄位都就應該以字元串“Content-”開始,以便在訊息頭域中從普通的RFC822頭欄位中區分出這類頭欄位。

MIME-extension-field := <Any RFC 822 header field which
begins with the string
"Content-">

10. 摘要

使用MIME-Version,Content-Type,以及Content-Transfer-Encoding頭欄位,就可以按照標準方法,在與RFC822標準相一致的郵件中包含任意的媒體類型。即沒有違背RFC821與RFC822中所規定的任何約束,也小心的避免了由網際網路郵件傳輸機制的約束所引起的問題。(見RFC 2049)

這個文檔集中的下一篇文檔是RFC2046, 它詳細說明了可以使用這些頭域進行標記及傳輸的媒體類型初始集合。

11. 安全考慮

安全問題在RFC2046中進行討論。

12. 作者地址

若需要更多信息,請通過網際網路郵件聯繫本文檔作者。

Ned Freed
Innosoft International, Inc.
1050 East Garvey Avenue South
West Covina, CA 91790
USA
Phone: +1 818 919 3600
Fax: +1 818 919 3614
EMail: [email protected]
Nathaniel S. Borenstein
First Virtual Holdings
25 Washington Avenue
Morristown, NJ 07960
USA
Phone: +1 201 540 8967
Fax: +1 201 993 3032
EMail: [email protected]
MIME is a result of the work of the Internet Engineering Task Force
Working Group on RFC 822 Extensions. The chairman of that group,
Greg Vaudreuil, may be reached at:
Gregory M. Vaudreuil
Octel Network Services
17080 Dallas Parkway
Dallas, TX 75248-1905
USA
EMail: [email protected]
附錄A :收集的語法

這個附錄中包含了本文檔中定義的全部BNF語法。

對於自身來說,這些語法是完整的。其中提及了幾個在RFC 822中定義的語法名稱,而沒有重複進行定義,這樣可以降低由於無意識操作而在兩種定義中產生差別的風險。一旦發現了未定義的術語,請參考RFC 822中的相關定義。

attribute := token
; Matching of attributes
; is ALWAYS case-insensitive.
composite-type := "message" / "multipart" / extension-token
content := "Content-Type" ":" type "/" subtype
*(";" parameter)
; Matching of media type and subtype
; is ALWAYS case-insensitive.
description := "Content-Description" ":" *text
discrete-type := "text" / "image" / "audio" / "video" /
"application" / extension-token
encoding := "Content-Transfer-Encoding" ":" mechanism
entity-headers := [ content CRLF ]
[ encoding CRLF ]
[ id CRLF ]
[ description CRLF ]
*( MIME-extension-field CRLF )
extension-token := ietf-token / x-token
hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
; Octet must be used for characters > 127, =,
; SPACEs or TABs at the ends of lines, and is
; recommended for any character not listed in
; RFC 2049 as "mail-safe".
iana-token := <A publicly-defined extension token. Tokens
of this form must be registered with IANA
as specified in RFC 2048.>
ietf-token := <An extension token defined by a
standards-track RFC and registered
with IANA.>
id := "Content-ID" ":" msg-id
mechanism := "7bit" / "8bit" / "binary" /
"quoted-printable" / "base64" /
ietf-token / x-token
MIME-extension-field := <Any RFC 822 header field which
begins with the string
"Content-">
MIME-message-headers := entity-headers
fields
version CRLF
; The ordering of the header
; fields implied by this BNF
; definition should be ignored.
MIME-part-headers := entity-headers
[fields]
; Any field not beginning with
; "content-" can have no defined
; meaning and may be ignored.
; The ordering of the header
; fields implied by this BNF
; definition should be ignored.
parameter := attribute "=" value
ptext := hex-octet / safe-char
qp-line := *(qp-segment transport-padding CRLF)
qp-part transport-padding
qp-part := qp-section
; Maximum length of 76 characters
qp-section := [*(ptext / SPACE / TAB) ptext]
qp-segment := qp-section *(SPACE / TAB) "="
; Maximum length of 76 characters
quoted-printable := qp-line *(CRLF qp-line)
safe-char := <any octet with decimal value of 33 through
60 inclusive, and 62 through 126>
; Characters not listed as "mail-safe" in
; RFC 2049 are also not recommended.
subtype := extension-token / iana-token
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
or tspecials>
transport-padding := *LWSP-char
; Composers MUST NOT generate
; non-zero length transport
; padding, but receivers MUST
; be able to handle padding
; added by message transports.
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
type := discrete-type / composite-type
value := token / quoted-string
version := "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
x-token := <The two characters "X-" or "x-" followed, with
no intervening white space, by any token>

相關詞條

相關搜尋

熱門詞條

聯絡我們