1. 程式人生 > >HTTP1.1協議中文版-RFC2616

HTTP1.1協議中文版-RFC2616

less bnf 在那 消息發送 example 允許 cd-rom arch 防範

轉自:http://www.cnblogs.com/k1988/archive/2010/01/12/2165683.html

說明

本文檔規定了互聯網社區的標準組協議,並需要討論和建議以便更加完善。請參考

“互聯網官方協議標準”(STD 1)來了解本協議的標準化狀態。本協議不限流傳發布。

版權聲明

Copyright (C) The Internet Society (1999). All Rights Reserved.

摘要

超文本傳輸協議(HTTP)是一種為分布式,合作式,超媒體信息系統。它是一種通用的,無狀態(stateless)的協議,除了應用於超文本傳輸外,它也可以應用於諸如名稱服務器和分布對象管理系統之類的系統,這可以通過擴展它的請求方法,錯誤代碼和報頭[47]來實現。HTTP的一個特點是數據表現形式是可輸入的和可協商性的,這就允許系統能被建立而獨立於數據傳輸。

HTTP在1990年WWW全球信息剛剛起步的時候就得到了應用。本說明書詳細闡述了HTTP/1.1 協議,是RFC 2068的修訂版[33]。

目錄(略)

1 引論
1.1 目的
超文本傳輸協議(HTTP)是一種為分布式,合作式,多媒體信息系統服務,面向應用層的 協議。在1990年WWW全球信息剛剛起步的時候HTTP就得到了應用。HTTP的第一個版本叫做HTTP/0.9,是一種為互聯網原始數據傳輸服務的簡單協議。由RFC 1945[6]定義的HTTP/1.0進一步完善了這個協議。它允許消息以類似MIME的格式傳送,包括有關數據傳輸的維護信息和關於請求/響應的句法修正。但是,HTTP/1.0沒有充分考慮到分層代理,緩存的作用以及對穩定連接和虛擬主機的需求。並且隨著不完善的應用程序的激增,HTTP/1.0迫切需要一個新的版本,以便使兩個通信應用程序能夠確定彼此的真實性能。

這裏規定的協議叫做擧TTP/1.1".這個協議與HTTP/1.0相比,要求更為嚴格,以確保各項功能得到可靠實現。

實際的信息系統除了簡單的檢索外,要求更多的功能性(functionality),包括查找(search),前端更新(front-end update)和註解(annotation)。HTTP允許可擴充的方法集和報頭集以指示請求的目的[47]。它是建立在統一資源標識符(URI)[3]提供的地址(URL)[4]和名字(URN)上[20],以指出方法應用於哪個資源的。消息以類似於一種叫做多用途網絡郵件擴展(MIME)[7] 的互聯網郵件的格式傳送。

HTTP也是用於用戶代理之間及代理/網關到其他網絡系統的通用通信協議,這樣的網絡系統可能由SMTP[16],NNTP[13],FTP[18],Gopher[2]和WAIS[10]協議支持。這樣,HTTP允許不同的應用程序對資源進行基本的超媒體訪問。

1.2 要求
本文的關鍵詞"MUST", "MUST NOT", "REQUIRED", "SHALL","SHALL NOT","SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和 "OPTIONAL"將由RFC 2119[34]解釋。

一個應用程序如果不能滿足協議提供的一個或多個MUST或REQUIRED等級的要求,是不符合要求的。一個應用程序如果滿足所有MUST或REQUIRED等級以及所有SHOULD等級的要求,則被稱為非條件遵循(unconditionally compliant)的;若滿足所有MUST等級的要求但不能滿足所有SHOULD等級的要求則被稱為條件遵循的(conditionally compliant)。

1.3 術語
本說明用到了若幹術語,以表示HTTP通信中各參與者和對象扮演的不同角色。

連接(connection)

為通信而在兩個程序間建立的傳輸層虛擬電路。

消息(message)

HTTP通信中的基本單元。它由一個結構化的八比特字節序列組成,與第4章定義的句法相匹配,並通過連接得到傳送。

請求(request)

一種HTTP請求消息,參看第5章的定義。

響應(response)

一種HTTP響應消息,參看第6章的定義。

資源(resource)

一種網絡數據對象或服務,可以用第3.2節定義的URI指定。資源可以以多種表現方式(例如多種語言,數據格式,大小和分辨率)或者根據其它方面而而不同的表現形式。

實體(entity)

實體是請求或響應的有效承載信息。一個實體包含元信息和內容,元信息以實體頭域(entity-header field)形式表示,內容以消息主體(entity-body)形式表示。在第7節詳述。

表現形式 (representation)

一個響應包含的實體是由內容協商(content negotiation)決定的。如第12章所述。有可能存在一個特定的響應狀態碼對應多個表現形式。

內容協商(content negotiation)

當服務一個請求時選擇資源的一種適當的表示形式的機制(mechanism),如第12節所述。任何響應裏實體的表現形式都是可協商的(包括出錯響應).

變量(variant)

在任何給定時刻,一個資源對應的表現形式(representation)可以有一個或多個(譯註:一個URI請一個資源,但返回的是此資源對應的表現形式,這根據內容協商決定)。每個表現形式(representation)被稱作一個變量。使用變量這個術語並不是意味著資源(resource)是必須由內容協商決定的.

客戶端(client)

為發送請求建立連接的程序.

用戶代理(user agent)

初始化請求的客戶端程序。常見的如瀏覽器,編輯器,蜘蛛(網絡穿越機器人),或其他的終端用戶工具.

服務器(Server)

服務器是這樣一個應用程序,它同意請求端的連接,並發送響應(response)。任何給定的程序都有可能既做客戶端又做服務器;我們使用這些術語是為了說明特定連接中應用程序所擔當的角色,而不是指通常意義上應用程序的能力。同樣,任何服務器都可以基於每個請求的性質扮演源服務器,代理,網關,或者隧道等角色之一。

源服務器(Origin server)

存在資源或者資源在其上被創建的服務器(server)被成為源服務器(origin server)。

代理( Proxy)

代理是一個中間程序,它既擔當客戶端的角色也擔當服務器的角色。代理代表客戶端向服務器發送請求。客戶端的請求經過代理,會在代理內部得到服務或者經過一定的轉換轉至其他服務器。一個代理必須能同時實現本規範中對客戶端和服務器所作的要求。透明代理(transparent proxy)需要代理授權和代理識別,但不修改請求或響應。非透明代理(non-transparent proxy)需修改請求或響應,以便為用戶代理(user agent)提供附加服務,附加服務包括組註釋服務,媒體類型轉換,協議簡化,或者匿名過濾等。除非透明行為或非透明行為經明確指出,否則,HTTP代理既是透明代理也是非透明代理。

網關(gateway)

網關其實是一個服務器,扮演著代表其它服務器為客戶端提供服務的中間者。與代理(proxy)不同,網關接收請求,仿佛它就是請求資源的源服務器。請求的客戶端可能覺察不到它正在同網關通信。

隧道(tunnel)

隧道也是一個中間程序,它一個在兩個連接之間充當盲目中繼(blind relay)的中間程序。一旦隧道處於活動狀態,它不能被認為是這次HTTP通信的參與者,雖然HTTP請求可能已經把它初始化了。當兩端的中繼連接都關閉的時候,隧道不再存在。

緩存(cache)

緩存是程序響應消息的本地存儲。緩存是一個子系統,控制消息的存儲、取回和刪除。緩存裏存放可緩存響應(cacheable response)為的是減少對將來同樣請求的響應時間和網絡帶寬消耗。任一客戶端或服務器都可能含有緩存,但高速緩存不能被一個充當隧道(tunnel)的服務器使用。

可緩存(cacheable)

我們可以說響應(response)是可緩存的,如果一個緩存(cache)為了響應後繼請求而被允許存儲響應消息(response message)的副本。確定HTTP響應的緩存能力(cacheability)在13節中有介紹。即使一個資源(resourse)是可緩存的,也可能存在緩存是否能利用緩存副本的約束。

第一手的(first-hand)

如果一個響應直接從源服務器或經過若幹代理(proxy),並且沒有不必要的延時,最後到達客戶端,那麽這個響應就是第一手的(first-hand)。

如果響應被源服務器(origin server)驗證是有效性(validity)的,那麽這個響應也同樣是第一手的。

明確過期時間(explicit expiration time)

是源服務器希望實體(entity)如果沒有被進一步驗證(validation)就不要再被緩存(cache)返回的時間。

啟發式過期時間(heuristic expiration time)

當沒有明確終止時間(explicit expiration time)可利用時,由緩存所指定的終止時間.

年齡(age)

一個響應的年齡是從被源服務器發送或被源服務器成功確認的時間點到現在的時間。

保鮮壽命(freshness lifetime)

一個響應產生的時間點到過期時間點之間的長度。

保鮮(Fresh)

如果一個響應的年齡還沒有超過保鮮壽命(freshness lifetime),它就是保鮮的.

陳舊(Stale)

一個響應的年齡已經超過了它的保鮮壽命(freshness lifetime),就是陳舊的.

語義透明(semantically transparent)

緩存(cache)可能會以一種語意透明(semantically transparent)的方式工作。這時,對於一個特定的響應,使用緩存既不會對請求客戶端產生影響也不會對源服務器產生影響,緩存的使用只是為了提高性能。當緩存(cache)具有語意透明性時,客戶端從緩存接收的響應跟直接從源服務器接收的響應完全一致(除了使用hop-by-hop頭域)。

驗證器(Validator)

驗證器其實是協議元素(例如:實體頭(entity tag)或最後更改時間(last-modified time)等),這些協議元素被用於識別緩存裏保存的數據(即緩存項)是否是源服務器的實體的副本。

上遊/下遊(upstream/downstream)

上遊和下遊描述了消息的流動:所有消息都從上遊流到下遊.

向內/向外(inbound/outbound)

向內和向外指的是消息的請求和響應路徑:"向內"即"移向源服務器","向外"即"移向用戶代理(user agent)".

1.4 總體操作
HTTP協議是一種請求/響應協議。 與服務器建立連接後,客戶端以請求方法,URI和協議版本號,然後緊接著跟隨一個類MIME(MIME-like)消息,這個類MIME消息包括請求修飾符,客戶信息和可能的消息主體。服務器以一個狀態行並跟隨一個類MIME(MIME-like)消息響應,狀態行包含消息的協議版本和成功出錯的狀態碼,類MIME消息包含服務器信息,實體元信息,和可能的實體。HTTP和MIME之間的關系如附錄19.4節所闡述。

大部分的HTTP通信是由用戶代理(user agent)開始的,由應用到一個需要源服務器資源的請求構成。最簡單的情形,可以經用戶代理(UA)和源服務器(O)之間的單一連接(v)完成。

請求鏈(Request chain)--------------------- ----------à

用戶代理(UA)----------------單一連接(v)--------------源服務器(O)

<---------------------------------------響應鏈(response chain)

當一個或多個中間者在請求/響應鏈中出現的時候,會出現更復雜的情形。常見的中間者有三種:代理(proxy),網關(gateway)和隧道(tunnel)。代理(proxy)是一種轉發代理(a forwarding agent),它接收絕對URI(absoulute url,相對於相對url)請求,重寫全部或部分消息,然後把格式化後的請求發送到URI指定的服務器上。網關是一種接收代理(receiving agent),它充當一個層(layer),這個層在服務器之上,必要時它會把請求翻譯成為下層服務器的協議。隧道不改變消息而充當兩個連接之間的中繼點;它用於通信需要穿過中間者(如防火墻)甚至當中間者不能理解消息內容的時候。

請求鏈(request chain)----------------------------------------à

UA-----v-----A-----v-----B-----v-----C------------v-----------------O

<----------------------------------------響應鏈(response chain)

上圖顯示了用戶代理(user agent)和源服務器之間的三個中間者(A,B和C)。整條鏈的請求或響應將會通過四個單獨的連接。這個特性很重要,因為某些HTTP通信選項可能只能應用於與最近的非隧道鄰接點的連接,只能應用於鏈的端點(end-point)的連接,或者能應用於此鏈的所有連接。圖表盡管是線性的,每個參與者可能忙於多路同時通信。例如,B可以接收來自不同於A的許多客戶的請求,並且/或者可以把請求轉到不同於C的服務器,與此同時,它還在處理A的請求。

任何非隧道的通信成員都可能會采用一個內部緩存(cache)來處理請求。如果沿著鏈的通信成員對請求采用了緩存響應,請求/響應鏈就會大大縮短。下圖闡明了一個最終請求響應鏈,這是在假定B擁有一個來自O(通過C)的以前請求的響應副本,但此響應尚未被UA或A緩存。

請求鏈(request chain)---------->

UA-----v----------A-----v-----B-----C----O

<---------響應鏈 (response chain)

並不是所有的響應都能有效地緩存,一些請求可能含有修飾符,這些修飾符對緩存動作有特殊的要求。緩存動作和緩存響應的HTTP行為要求將在第13節定義。

實際上,目前萬維網上有多種結構和配置的緩存(cache)和代理(proxy)正在被使用。這些系統包括節省帶寬的緩存代理(proxy cache),可以廣播或多點傳送緩存數據的系統,通過CD-ROM分配緩存數據子集的機構,等等。HTTP系統(http system)會被應用於寬帶連接的企業局域網中的協作,並且可以通過PDA進行低耗無線的,斷續連接的訪問。HTTP1.1的宗旨是為了支持各種各樣的已經部署的配置,同時引進一種協議結構,讓它滿足那些需要較高可靠性,即使不能達到較高可靠性的要求,也要也讓它至少可以指示故障的網絡應用的要求。

HTTP通信通常發生在TCP/IP連接上。默認端口是TCP 80,不過其它端口也可以使用。這並不妨礙HTTP的實現被應用於互聯網(internt)或其它網的協議之上。Http僅僅期望的是一個可靠的傳輸(譯註:HTTP一般建立在傳輸層協議之上);任何提供這種保證的協議都可以被使用;協議傳輸數據單元(transport data unit)與HTTP/1.1請求和響應的消息結構之間的映象已經超出了本說明書的範圍。

大部分HTTP/1.0的實現都是針對每個請求/響應交換產生一個新的連接。而http/1.1中,一個連接可以被用於一個或更多請求/響應交換,雖然連接可能會因為各種原因中斷(見第8.1節)。

2 符號習慣和一般語法
2.1 擴充的BNF(擴充的 巴科斯-諾爾範式)
本文檔規定的所有機制都用兩種方法描述:散文體(prose)和類似於RFC 822的擴充Backus-Naur Form(BNF)。要理解本規範,使用者需熟悉符號表示法。擴充BNF結構如下:

名字(name)=定義(definition)

名字(name)就是代表規則的名字(譯註:如:CRLF,DIGIT等等都是規則名),規則名裏不能包含“<”和“>”,通過等於號把規則名和規則定義(definiation)分離開。空白(white space)是有意義的,因為可以用縮進(indentation,譯註:縮進就是空白,後面會講到LWS) 把規則定義顯示成多行。某些基本規則(basic rule,譯註:2.2節說明基本規則的語法)使用大寫字母包含在規則定義裏, 你如SP,LWS,HT,CRLF,DIGIT,ALPHA,等等。尖括號可以包含在規則定義裏,只要它們的存在有利於識別規則名(譯註:LWS,HT等都是規則名)。

“字面文本”(“literal”)

字面文本(literal text)兩邊用引號。除非聲明,字面文本大小寫不敏感(譯註:如,HEX = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT 裏的A,B,C,D等等都是字面文本(literal text))。

規則1 | 規則2

由豎線(“|”)分開的元素是可選的,例如,“yes | no”表示yes或no都是可接受的。

(規則1 規則2)

圍在括號裏的多個元素視作一個元素。所以,“(elem (foo | bar) elem)”的符合的字符串是“elem foo elem”和“elem bar elem”。

*規則

前面的字符“*”表示重復。完整的形式是“<n>*<m>元素”,表示元素至少出現<n>次,至多出現<m>次。默認值是0和無窮大,所以"*(元素)"允許任何數值,包括零;"1*元素"至少需要一次;"1*2element"允許一次或兩次。

[規則]

方括號裏是任選元素;“[foo bar]”相當於“*1(foo bar)”。

N 規則

特殊的重復:“<n>(元素)”與“<n>*<n>(元素)”等價;就是說,(元素)正好出現了<n>次。這樣2DIGIT是一個兩位數字,3ALPHA是一個由三個字符組成的字符串。

#規則

類似於“*”,結構“#”是用來定義一系列元素的。完整的形式是<n>#<m>元素,表示至少<n>個元素,至多<m>個元素,元素之間被一個或多個逗號(“,”)以及可選的線性空白(LWS)隔開了。這就使得表示列表這樣的形式變得非常容易;像

( *LWS element) *( *LWS ","*LWS element ))

就可以表示為

1#element

無論在哪裏使用這個結構,空元素都是允許的,但是不計入元素出現的次數。換句話說 ,

“(element ), , (element) ”是允許的,但是僅僅視為兩個元素。因此,在至少需要一個元素的地方,必須存在至少一個非空元素。默認值是0和無窮大,這樣,“#element”允許任意零個或多個元素;“1# element”需要至少一個;“1#2element”允許一個或兩個元素。

;註釋(comment)

用分號引導註釋。

隱含的(implied) *LWS

本說明書所描述的語法是基於字的。除非特別註明,線性空白可出現在任何兩個相鄰字之間(標記(token)或引用字符串(quoted-string)),以及相鄰字和間隔符之間,這並沒有改變一個域的解釋。任何兩個標記(token)之間必須有至少一個分割符,否則將會被理解為單一標記。

2.2基本規則 (basic rule)
下面的規則貫穿於本規範的全文,此規則描述了基本的解析結構。US-ASCII(美國信息交換標準碼)編碼字符集是由ANSI X3.4-1986[21]定義的。

OCTET(字節) = <任意八比特的數據序列>

CHAR = <任意ASCII字符(ascii碼值從 0到127的字節)>

UPALPHA = <任意大寫字母"A"..."Z">

LOALPHA = <任意小寫字母"a"..."z">

ALPHA = UPALPHA | LOALPHA

DIGIT = <任意數字0,1,...9>

CTL = <任意控制字符(ascii碼值從0 到 31的字節)及刪除鍵DEL(127>

CR = <US-ASCII CR, 回車(13)>

LF = <US-ASCII LF, 換行符(10)>

SP = <US-ASCII SP, 空格(32)>

HT = <US-ASCII HT, 水平制表 (9)>

<"> = <US-ASCII 雙引號(34)>

HTTP/1.1將 CR LF 的序列定義為任何協議元素的行尾標誌,但這除了實體主體(endtity-body)外(要求比較松的應用見附錄19.3)。實體主體(entity-body)的行尾標誌是由它的關聯媒體類型定義的,如3.7節所述。

CRLF = CR LF

HTTP/1.1 的消息頭域值可以折疊成多行,但緊接著的折疊行由空格(SP)或水平制表(HT)折疊標記開始。所有的線性空白(LWS)包括折疊行的折疊標記(空格SP或水平制表鍵HT),具有同SP一樣的語義。接收者在解析域值或將消息轉送到下遊(downstream)之前可能會將任何線性空白(LWS)替換成單個SP(空格)。

LWS = [CRLF] 1*( SP | HT )

下面的TEXT規則僅僅適用於域內容和域值的描述,不會被消息解釋器解析。TEXT裏的字可以包含不僅僅是ISO-8859-1[22]裏的字符集,也可以包含RFC 2047裏規定的字符集。

TEXT = <除CTLs以外的任意OCTET,但包括LWS>

一個CRLF只有作為HTTP消息頭域延續的一部分時才在TEXT定義裏使用。

十六進制數字字符用在多個協議元素(protocol element)裏。

HEX = "A" | "B" | "C" | "D" | "E" | "F"

| "a" | "b" | "c" | "d" | "e" | "f" | DIGIT

許多HTTP/1.1的消息頭域值是由LWS或特殊字符分隔的字構成的。這些特殊字符必須先被包含在引用字符串(quoted string)裏之後才能用於參數值(如3.6節定義)裏。

token (標記) = 1*<除CTLs與分割符以外的任意 CHAR >

separators(分割符) = "(" | ")" | "<" | ">" | "@"

| "," | ";" | ":" | """ | <">

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

| "{" | "}" | SP | HT

通過用圓括號括起來,註釋(comment)可以包含在一些HTTP頭域裏。註釋只可以作為域定義的一部分。在其他域裏,圓括號被視作域值的一部分。

comment (註釋)= "(" *( ctext | quoted-pair | comment ) ")"

ctext = <除"(" 和 ")"以外的任意TEXT >

如果一個TEXT若被包含在雙引號裏,則當作一個字。

quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )

qdtext = <any TEXT except <">>

斜劃線(""")可以被作為單個字符的引用機制,但是必須要在引號和註釋區之內。

quoted-pair = """ CHAR

3 協議參數
3.1 HTTP版本
HTTP使用一個“<major>.<minor>”數字模式來指明協議的版本號。協議的版本號是為了讓發送端指明消息的格式和它的能力,這是為了進一步的HTTP通信,而不僅僅是獲得通信的特征。協議版本是不需要修改的,當消息組件的增加不會影響通信行為或著只增加了擴展的域值。<minor>數字是遞增的,當協議會因為添加一些特征而做了修改的時候。但這些變化不會影響通常的消息解析算法,但是它會給消息添加語意(semantic)並且會暗示發送者具有額外的能力。<major>數字也是不斷遞增的,當協議的消息格式每次發生變化時。

HTTP消息的版本在HTTP-Version域被指明,HTTP-Version域在消息的第一行中。

HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT

註意major和minor數字必須被看成兩個獨立整數,每個整數都可以遞增,並且可以增大到大於一位數的整數,如HTTP/2.4比HTTP/2.13低,而HTTP/2.4又比HTTP/12.3低。前導0必須被接收者忽略並且不能被發送者發送。

一個應用程序發送請求或響應消息,如果請求或響應消息裏的HTTP-Version是”HTTP/1.1”,那麽此應用程序必須條件遵循此協議規範。最少條件遵循此規範的應用程序應該把”HTTP/1.1”包含在他們的消息裏,並且對任何不兼容HTTP/1.1的消息必須這麽做。關於何時發送特定的HTTP-Version值的細節,參見RFC2145。

應用程序的HTTP版本是應用程序最少條件遵循的最高HTTP版本。

代理(proxy)和網關(gateway)應用程序需要被仔細對待,當轉發(forwarding)消息的協議版本不同於代理或網關應用程序的協議版本。因為消息裏協議版本說明了發送者處理協議的能力,所以一個代理/網關千萬不要發送一個高於該代理/網關應用程序協議版本的消息。如果代理或網關接收了一個更高版本的消息,它也必須要降低請求的版本,要麽以一個錯誤響應,要麽切換到隧道行為(tunnel behavior)。

由於自從RFC 2068[33]發布後,產生了與HTTP/1.0代理(proxy)的互操作問題,所以緩存代理(caching proxy)必須能改變請求(request),使請求能到達他們能支持的最高版本,但網關(gateway)可以這麽做也可以不這麽做,而tunnel不能這麽做。代理(Proxy)/網關(gateway)的響應(Response)必須和請求(request)的HTTP版本的major數字相同。

註意:在HTTP版本間的轉換可能包含頭域(header field)的改變,而這些改變會可能會根據HTTP版本而被要求或被拒絕。

3.2 統一資源標識符(URI)
URIs的許多名字已為人所知:WWW地址,通用文檔標識符,通用資源標識符[3],以及後來的統一資源定位器(URL)[4]和統一資源名稱(URN)[20]。就HTTP而言,統一資源定位器只是格式化的字符串,它通過名稱,地址,或任何別的特征識別資源。

3.2.1一般語法
根據使用的背景,HTTP裏的URI可以表示成絕對(absoulute)形式或相對形式(相對於已知的URL)。兩種形式的區別是根據這樣的事實:絕對URI總是以一個方案(scheme)名作為開頭,其後是一個冒號。關於URL更詳盡的信息請參看"統一資源標識符(URI):一般語法和語義",RFC 2396 [42](代替了RFCs 1738 [4]和RFC 1808 [11])。本規範采用了RFC 2396裏的"URI-reference","absoluteURI","relativeURI","port","host","abs_path","rel_path",和"authority"的定義格式。

HTTP協議不對URI的長度作事先的限制,服務器必須能夠處理它們資源的URI,並且應該能夠處理無限長度的URI,這種無效長度的URL可能會在客戶端以GET形式的請求產生。服務器應該返回414狀態碼(此狀態碼代表Request-URI太長),如果服務器不能處理太長的URI的時候。

註:服務器在依賴大於255字節的URI時應謹慎,因為一些舊的客戶或代理實現可能不支持這些長度。

3.2.2 http URL
通過HTTP協議,http方案(http scheme)被用於定位網絡資源(resourse)的位置。本節定義了這種方案的語法和語義。

http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]

如果端口為空或未給出,就假定為80。語義即:已識別的資源放在服務器上,在那臺主機的那個端口上監聽TCP連接。這時資源的請求的URI為絕對路徑(5.1.2節)。無論什麽可能的時候,URL裏使用IP地址都是應該避免的(參看RFC 1900 [24])。如果絕對地址(abs_path)沒有出現在URL裏,那麽應該給出"/"。如果代理(proxy)收到一個主機(host)名,但是這個主機名不是全稱的域名(fully quanlified domain name),則代理應該把它的域名加到主機名上。如果代理(proxy)接收了一個全稱的域名,代理不必改變主機。

3.2.3 URI 比較
當比較兩個URI是否匹配時,客戶應該對整個URI比較時應該區分大小寫,並且一個字節一個字節的比較。 但下面有些特殊情況:

- 一個為空或未給定的端口等同於URI-refernece(見RFC 2396)裏的默認端口;

- 主機(host)名的比較必須不必分大小寫;

- 方案(scheme)名的比較必須是不區分大小寫的;

- 一個空絕對路徑(abs_path)等同於"/"。

除了"保留(reserved)"和"不安全(unsafe)"字符集裏的字符(參見RFC 2396 [42]) ,其它字符都等效於它們的"%HEXHEX"編碼.

例如,以下三個URI是等同的:

http://abc.com:80/~smith/home.html

http://ABC.com/%7Esmith/home.html

http://ABC.com:/%7esmith/home.html

3.3 日期/時間格式(Date/Time Formats)
3.3.1完整日期 (Full Date)
HTTP應用曾經一直允許三種不同日期/時間格式:

Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123

Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036

Sun Nov 6 08:49:37 1994 ; ANSI C‘s asctime() format

第一種格式是作為Internet標準提出來的,它是一個國定長度的,由RFC 1123 [8](RFC 822[9]的升級版本)定義的一個子集。第二種格式使用比較普遍,但是基於廢棄的RFC 850 [12],並且沒有年份。如果HTTP/1.1客戶端和服務器解析日期,他們必須能接收所有三種格式(為了兼容HTTP/1.0),但是它們只能產生RFC 1123裏定義的日期格式來填充頭域(header field)用到日期的地方。

註:日期值的接收者被鼓勵能健壯的接收可能由非HTTP應用發來的日期值,例如有時可以通過代理(proxy)/網關(gateway)向SMTP或NNTP獲得或轉發消息。

所有的HTTP日期/時間都必須以格林威治時間(GMT)表示。對HTTP而言,GMT完全等同於UTC(世界協調時間)。前兩種日期/時間格式裏包含“GMT”,它是時區的三個字面的簡寫,並且當讀到一個asctime格式時必須先被假定是GMT時間。HTTP日期(HTTP-date)區分大小寫,不能包含一個額外的LWS,除非此LWS作為在下面的Http-date語法中指定的SP。

HTTP-date = rfc1123-date | rfc850-date | asctime-date

rfc1123-date = wkday "," SP date1 SP time SP "GMT"

rfc850-date = weekday "," SP date2 SP time SP "GMT"

asctime-date = wkday SP date3 SP time SP 4DIGIT

date1 = 2DIGIT SP month SP 4DIGIT

; day month year (e.g., 02 Jun 1982)

date2 = 2DIGIT "-" month "-" 2DIGIT

; day-month-year (e.g., 02-Jun-82)

date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))

; month day (e.g., Jun 2)

time = 2DIGIT ":" 2DIGIT ":" 2DIGIT

; 00:00:00 - 23:59:59

wkday = "Mon" | "Tue" | "Wed"

| "Thu" | "Fri" | "Sat" | "Sun"

weekday = "Monday" | "Tuesday" | "Wednesday"

| "Thursday" | "Friday" | "Saturday" | "Sunday"

month = "Jan" | "Feb" | "Mar" | "Apr"

| "May" | "Jun" | "Jul" | "Aug"

| "Sep" | "Oct" | "Nov" | "Dec"

註意:HTTP對日期/時間格式的要求僅僅應用在協議的消息(譯註:原文是protocol stream,便於理解這裏譯作消息)裏。客戶和服務器不必把這種格式應用於用戶呈現(user presentation),請求記錄日誌,等等。.

3.3.2 Delta Seconds
一些HTTP頭域(header field)允許用整數秒表示時間值,整數秒用十進制表示,此整數秒表示消息被接收後時間。

delta-seconds = 1*DIGIT

3.4 字符集
HTTP使用術語"字符集"的定義,這和MIME中所描述的是一樣.

本文檔中的術語"字符集"涉及到一種方法,此方法是用一個或多個表將一個節序列轉換成一個字符序列(譯註:從這裏來看,這應該是一種映射關系,表保存了映射關系)。註意反方向的無條件轉換(譯註:從一個字符序列到一個字節序列的轉換)是不需要的,因為並不是所有的字符都能在一個給定的字符集裏得到,一個字符集可能提供多個字節序列表征一個特定的字符。這個定義是為了允許不同種類的字符編碼從單一簡單表映射(如US-ASCII)到復雜表的轉換方法如ISO-2022技術用到的。然而,與MIME字符集名字相關的定義必須要充分說明從字節到字符的映射。特別的,使用外部輪廓信息來精確確定映射是不允許的.

註:這裏使用的術語"字符集"一般的被稱作一種"字符編碼"。不過既然HTTP和MIME在同一機構註冊,術語統一是很重要的。

HTTP字符集是用不區分大小寫的標記(token)表示。所有的標記集由IANA字符集註冊機構[19]定義。

charset = token

盡管HTTP允許用任意標記(token)作為字符集(charset)值,但任何標記值如果它已經在IANA字符集註冊機構註冊了則必須表示在該註冊機構定義的字符集。對那些非IANA定義的字符集,應用程序應該限制使用。

HTTP協議的實現者應該註意IETF字符集的要求[38][41].

3.4.1丟失的字符集(Missing Charset)
一些HTTP/1.0應用程序當他們解析Content-Type頭時,當發現沒有字符集參數(charset parameter,譯註:Content-Type: text/plain; charset=UTF-8,此時charset=UTF-8就是字符集參數)可用時,這意味著接收者必須猜測實體主體(entity body,譯註:這裏翻譯成“實體主體”因為Content-Type頭是實體頭,消息頭可以分為實體頭,常用頭,請求頭,響應頭,在譯文中多次用到“頭”和“頭域”,如消息頭,消息頭域,其實是同一個意思,HTTP1.1協議有時候概念並不是完全統一的)的字符集是什麽。如果發送者希望避免這種情況,他應該在Content-Type頭域裏包含一個字符集參數,即使字符集是ISO-8859-1也應該這樣做,這樣就不會讓接收者產生混淆。

不幸的是,一些舊的HTTP/1.0客戶端不能處理在Content-Type頭域裏明確指定的字符集參數。HTTP/1.1接收端必須要認真對待發送者提供的字符集;並且當用戶代理(user agent,譯註:如瀏覽器,可認為是接收端)開始顯示一個文檔時,雖然用戶代理可以猜測文檔的字符集,但如果content-type頭域裏提供了字符集,並且用戶代理也支持這種字符集的顯示,不管用戶代理是否願意,它必須要利用這種字符集。參見3.7.1節。

3.5 內容編碼(Content Codings)
內容編碼值(content coding value)表示一種已經或可以應用於實體的編碼轉換(encoding transformation)。內容編碼主要用於文檔的壓縮或其它有效的變換,但這種變換需要不能丟失文檔的媒體類型(media type,譯註:文檔一般會有媒體類型,這通過在content-type裏指定)的特性,也不能丟失文檔的信息(譯註:就像有損壓縮和無損壓縮,前者不會丟失信息,後者會丟失信息)。實體經常被編碼的儲存,然後直接傳送,接收端只能解碼。

content-coding = token

所有內容編碼值(content-coding value)是不區分大小寫的。HTTP/1.1在接收譯碼 (14.3節)和內容譯碼(Content-Encoding)(14.11節)頭域裏使用內容編碼值(content-coding value)。盡管該值描述了內容編碼,更重要的是它指出了一種解碼機制,利用這種機制對實體的編碼進行解碼。

網絡分配數字權威( (IANA)充當內容編碼值標記(token)的註冊機構。最初,註冊表裏包含下列標記:

gzip(壓縮程序)

一種由文件壓縮程序"gzip"(GNU zip)產生的編碼格式(在RFC 1952中描述)。這種編碼格式是一種具有32位CRC的Lempel-Ziv編碼(LZ77)。

compress(壓縮)

一種由UNIX文件壓縮程序"compress"產生的編碼格式。這種編碼格式是一種具有可適應性的Lempel-Ziv-Welch編碼(LZW)。

對於將來的編碼,用程序名識表征編碼格式是不可取。在這裏用到他們是因為他們在歷史的作用,雖然這樣做並不好。為了同以前的HTTP實現相兼容,應用程序應該將"x-gzip"和"x-compress"分別等同於"gzip"和"compress"。

deflate(縮小) 

deflate編碼是由RFC 1950 [31]定義的"zlib"編碼格式與RFC 1951 [29]裏描述的"deflate"壓縮機制的組合的產物。

identity(一致性)

Identity是缺省編碼;指明這種編碼表明不進行任何編碼轉換。這種內容編碼僅被用於接收譯碼(Accept-Encoding)頭域,但不能被用在內容譯碼(Content-Encoding)頭域。.

新的內容編碼值標記(token)應該被註冊;為了實現客戶和服務器間的互操作性,實現新值的內容編碼算法規範應該能公開利用並且能獨立實現,並且與本節中被定義的內容編碼目的相一致。

3.6 傳輸編碼 (Transfer Codings)
傳輸編碼值(transfer-coding value,譯註:transfer coding和和transfer-coding這兩個術語在本協議規範裏所表達的意思其實沒什麽太大區別,“transfer-coding”可能更能表達語意,因為它是規則中的規則名,見下面紅字的規則)被用來表示一個已經,能夠,或可能應用於一個實體的編碼轉換,傳輸編碼是為了能夠確保網絡安全傳輸。這不同於內容編碼(content coding),因為傳輸編碼(transfer coding)是消息的屬性而不是實體的屬性。

transfer-coding = "chunked" | transfer-extension

transfer-extension = token *( ";" parameter )

參數(parameter)采用屬性/值對的形式.

parameter = attribute "=" value

attribute = token

value = token | quoted-string

所有傳輸編碼值(transfer-coding value,譯註:上面紅體字等號右邊規則表達式所表達的值)是大小寫不敏感。傳輸編碼值在TE頭域(14.39節)和在傳輸譯碼(Transfer-encoding) 頭域中(14.41節)被運用。

無論何時,傳輸編碼(transfer-coding)應用於一個消息主體(message body)時,如果存在多個傳輸編碼,則這些傳輸編碼中必須包括“塊”("chunked")傳輸編碼,除非通過關閉連接而中斷消息。當“塊”(“chunked”)傳輸編碼被用於傳輸編碼時,它必須是應用於消息主體的最後傳輸編碼。"塊"("chunked")傳輸編碼最多只能用於消息主體(message-body)一次。規定了上述規則後,接收者就可以確定消息的傳輸長度(transfer-length)(4.4節)

傳輸編碼與MIME[7]的內容傳輸譯碼(Content-Transfer-Encoding,譯註:transfer應該是轉移,遷移的意思,又例如HTTP協議,應該翻譯成“超文本轉移協議”,但是歷史上都翻譯成“超文本傳輸協議”,所以這裏翻譯成“超文本傳輸協議”)值有相類似型,它被定義能夠實現在7位傳輸服務上保證二進制數據的傳輸安全。不過,傳輸編碼與內容傳輸譯碼(Content-Transfer-Encoding)對純8位傳輸協議有不同的關註點。在HTTP中,消息主體存在不安全的隱患,因為有時候很難確定消息主體的長度,在共享的傳輸上加密數據也會帶來安全性問題(7.2.2節)。

網絡分配數字權威(IANA)擔任註冊傳輸編碼值標(token)記的角色。起初,註冊包含如下標記:"塊"(3.6.1節),"身份"(3.6.2節),"gzip"(3.5節),"壓縮"(3.5節),和"縮小"(3.5節).

新的傳輸編碼值標記應該註冊,這同新的內容編碼值標記也需要註冊一樣。.

接收端接收到一個帶有傳輸編碼(transfer-coding)(譯註:通過消息頭域transfer-encoding指明此實體主體的傳輸編碼)的實體主體(entity body),如果它不能對這個編碼後的實體主體進行解碼,那麽它應返回501(不能實現),並且要切斷聯系。服務器不能向HTTP/1.0客戶發送傳輸編碼.

3.6.1塊傳輸編碼(Chunked Transfer Coding)
塊編碼(chunked encoding)改變消息主體使消息主體(message body,譯註:消息主體與實體主體是有區別的,後面章節將會介紹)成塊發送。每一個塊有它自己的大小(size)指示器,在所有的塊之後會緊接著一個可選的包含實體頭域的尾部(trailer)。這允許發送端能動態生成內容,並能攜帶有用的信息,這些信息能讓接收者判斷消息是否接收完整。

Chunked-Body(塊正文) = *chunk(塊)

last-chunk(最後塊)

trailer(尾部)

CRLF

chunk(塊) = chunk-size [ chunk-extension ] CRLF

chunk-data CRLF

chunk-size = 1*HEX

last-chunk = 1*("0") [ chunk-extension ] CRLF

chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )

chunk-ext-name = token

chunk-ext-val = token | quoted-string

chunk-data = chunk-size(OCTET)

trailer = *(entity-header CRLF)

chunk-size是用16 進制數字字符串。塊編碼(chunked encoding)以任一大小為0的塊結束,緊接著是尾部(trailer),尾部以一個空行終止。

尾部(trailer)允許發送端在消息的末尾包含附加的HTTP頭域(header field)。Trailer頭域(Trailer header field,譯註:Trailer頭是常用消息頭,在14.40節說明)被應用來指明哪些頭域被包含在塊編碼的尾部(trailer) (見14.40節)

如果服務器要用塊傳輸編碼進行響應,它不能包含尾部(trailer),除非以下至少一條為真:

a)如果此響應的請求包括一個TE頭域,並且它指明了傳輸編碼中的“trailers”是可接受的,當響應的傳輸編碼(transfer-coding)是塊編碼時。這在14.39節中描述;或者

b)如果服務器是響應的源服務器,並且接收端接收塊傳輸編碼響應但不會去理會響應的尾部(trailer,譯註:尾部包含頭域,頭域就是消息的元數據(metadata))並且這種方式源服務器是可以接受的,這時服務器是不需要把尾部(trailer)包含進消息的塊傳輸編碼中去的。換句話說,源服務器原意接受尾部(trailer)可能會在到達客戶端時被丟棄的可能性。

此要求防止了一種互操作性的失敗,當消息被一個HTTP/1.1(或更遲的)代理(proxy)接收並且轉到一個HTTP/1.0的接收端的時候。

在附錄19.4.6節介紹了一個例子,這個例子介紹怎樣對一個塊正文(chunked-body)進行解碼。

所有HTTP/1.1應用程序必須能接收和解碼塊(chunked)傳輸譯碼,並且必須忽略它們不能理解的塊擴展(chunk-extentsion,譯註:見上面的規則表達式).

3.7 媒體類型(Media Type)
HTTP在Content-Type(14.17節)實體頭域和Accept請求頭域裏利用網絡媒體[17]類型,這是為了提供公開的,可擴展的數據打印和類型協商。

media-type = type "/" subtype *( ";" parameter )

type = token

subtype = token

參數(parameter)以一種屬性/值對的形式跟隨type/subtype(如3.6節定義) 。

類型(type),子類型(subtype),和參數(parameter)裏屬性名稱是大小寫不敏感的。參數值有可能是大小寫敏感的,也可能不是,這根據參數裏屬性名的語意。線性空白(LWS)不能被用於類型(type)和子類型(subtype)之間,也不能用於參數的屬性和值之間。參數的出現或不出現對處理媒體類型(media-type)可能會有幫助,這取決於它在媒體類型註冊表裏的定義。

註意一些舊的HTTP應用程序不能識別媒體類型的參數(parameter)。當向一個舊的HTTP應用程序發送數據時,發送端只有在被type/subtype定義需要時才使用類型參數(parameter)。

媒體類型(media-type)值需要被註冊到網絡數字分配權威(IANA[19])裏。媒體類型的註冊程序在RFC 1590[17]中大概描述。使用未經註冊的媒體類型是不被鼓勵的。

3.7.1規範化和文本缺省 (Canonicalization and Text Defaults)
網絡媒體類型以規範化的格式被註冊。一個實體主體(entity-body)通過HTTP消息傳輸,它必須在傳輸前以一種合適的規範化的格式表征除了文本類型(text type),文本類型將會在下一段闡述。

當消息以一種規範化的格式表現時,文本類型的子類型(subtype)運用GRLF作為文本裏的換行符。HTTP放松了這個要求,並且允許文本媒體以一個CR或LF代表一個換行符傳輸,並且這樣做要貫穿整個實體主體(entity-body)。HTTP應用程序必須能接收CRLF,CR和LF作為在文本媒體一個換行符。另外,如果文本字符集(character set)不能用字節13和10來分別地表征CR和LF因為存在一些多字節字符,HTTP允許應用字符集裏等價於CR和LF的字節序列來表示換行符。對換行符的靈活處理只能應用於實體主體裏的文本媒體;在HTTP消息結構裏,一個單獨的CR或LF都不能代替CRLF(如頭域和多邊界體(multipart boundaries)結構裏)。

如果一個實體主體(entity-body)用內容編碼(content-coding)進行編碼,原始數據(譯註:被編碼前的數據)在被編碼前必須是一種定義的媒體類型格式。.

"charset"參數(parameter)被應用於一些媒體類型,來定義數據的字符集(見3.4節)。當發送者沒有在媒體類型(media-type)裏指明charset參數(parameter)時,文本類型的子媒體類型(subtype)被認為是缺省的ISO-8859-1字符集當被接收者接收後。數據必須被合適的字符集標識。3.4.1節描述了兼容性問題。

3.7.2多部分類型(Multipart type)
MIME提供了一系列"多部分"類型---在單個消息主體內包裝一個或多個實體。所有的多部分類型共享一個公共的語法(這在RFC 2046[40]的5.1.1節中描述),並且包含一個邊界(boundary)參數作為多部分媒體類型值的一部分。多部分類型的消息主體是一個協議元素,並且必須用CRLF來標識體部分(body-part,譯註:見RFC 2046 的5節)之間的換行。

不同於RFC 2046裏的多部分消息類型的描述,HTTP1.1規定任何多部分類型的消息尾聲(epilogue,譯:見RFC 2046對多部分消息類型的規則描述)必須不能存在;HTTP應用程序不能傳輸尾聲(epilogue)(即使原始的多部分消息尾部包含一個尾聲)。存在這些限制是為了保護多部分消息主體的自我定界的特性,因為多部分邊界的結束(譯註:根據RFC2046中定義,多部分邊界結束後可能還會有尾聲)標誌著消息主體的結束。

通常,HTTP把一個多部分類型的消息主體(message-body)和任何其他媒體類型的消息主體相同對待:嚴格看作有用的負載體。有一個例外就是"multipart/byterange"類型(附錄19.2),當它出現在206(部分內容)響應時,此響應會被一些HTTP緩存機制解析,緩存機制將會在13.5.4節和14.16節介紹。在其它情況下,一個HTTP用戶代理會遵循MIME用戶代理一樣的或者相似的行為,這依賴於接收何種多部分類型。一個多部分類型消息的每一個體部分(bady-part)裏的MIME頭域對於HTTP並沒有太大意義除了MIME語意。

通常, 一個HTTP用戶代理應該遵循與一個MINE用戶代理相同或相似。如果一個應用程序收到一個不能識別的多部分子類型,這個應用程序必須將它視為"multipart/mixed"。

註:"multipart/form-data"類型已經被規範的定義為傳送窗體數據(譯註:一般用窗體上傳數據時,上傳的數據類型就是為multipart/form-data類型),當用POST請求方法處理數據時。這在RFC 1867[15]裏定義。

3.8 產品標記 (product Tokens)
產品標記用產品名和版本號識別通訊應用軟件。很多頭域都會利用產品標記,它允許構成應用程序重要部分的子產品被以空白分隔列舉。通常,產品以應用程序的重要性的順序來列舉的。

product = token ["/" product-version]

product-version = token

例:

User-Agent:CERN-LineMode/2.15 libwww/2.17b3

Server: Apache/0.8.4

產品標示應言簡意賅。它們不能用來做廣告或其他不重要的信息。雖然任一標記可能出現product-version裏,但這個標記僅能用來做一個版本 (i.e., 同產品中的後續版本應該在product-version上有區別)

3.9 質量值(Quality Values)
HTTP內容協商(content negotiation,12節介紹)運用短“浮點”數字(short floating point number)來表針不同協商參數的相對重要性。重要性的權值被規範化成一個從0到1的實數。0是最小值,1是最大值。如果一個參數的質量值(quanlity value)為0,那麽這個參數的內容不被客戶端接受。HTTP/1.1應用程序不能產生多於三位小數的實數。下面規則限定了這些值。

qvalue = ( "0" [ "." 0*3DIGIT ] )

| ( "1" [ "." 0*3("0") ] )

"質量值" 是一個不當的用詞,因為這些值僅僅表現一中相對的降級。

3.10 語言標簽 (Language Tags)
一個語言標簽表征一種自然語言,這種自然語言能說,能寫,或者被用來人與人之間的溝通。計算機語言明顯不包括在內的。HTTP在Accept-Language和Content-Language頭域裏應用到語言標簽(language tag)。

HTTP語言標簽的語法和註冊和RFC 1766[1]中定義的一樣。總之,一個語言標簽是由一部分或多部分構成:一個主語言標簽和可能為空的子標簽系列。

Language-tag = primary-tag*("-" subtag)

primary = 1*8ALPHA

subtag = 1*8ALPHA