1. 程式人生 > >RFC2616------超文字傳輸協議HTTP/1.1

RFC2616------超文字傳輸協議HTTP/1.1

說明
本文件規定了網際網路社群的標準組協議,並需要討論和建議以便更加完善。請參考
“網際網路官方協議標準”(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應用程式的激增,這就迫切需要一個新的版本,
以便能使兩個通訊程式能夠確定彼此的真實能力。
此規範定義的協議叫做“HTTP/1.1”,.這個協議與HTTP/1.0相比,此規範更為嚴格,以確保
各個協議的特徵得到可靠實現。
實際的資訊系統除了簡單的獲取資訊之外,還要求更多的功能,包括查詢(search),終端更
新(front-end update)和註解(annotation)。HTTP為請求提供可擴充方法集和訊息頭集
[47]。HTTP是建立在統一資源識別符號(URI)[3]的約束上的,作為一個地址(URL)[4]或名稱
(URN)[20],以指定被一個方法使用的資源。訊息以一種類似於網際網路郵件[9]訊息格式來傳
輸的,網際網路訊息格式定義於多目的網際網路郵件擴充套件(MIME)[7]裡。
HTTP也是用於使用者代理(user agents)和其它網際網路系統的代理/閘道器之間通訊的通訊協議,
這些網際網路系統可能由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)
實體是請求或響應的有效承載資訊。一個實體包含元資訊和內容,元資訊以實體頭域(entityheader
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)需要代理認證和代理識別,而不修改請求或響應。非透明代理(nontransparent
proxy)需修改請求或響應,以便為使用者代理(user agent)提供附加服務,附加
服務包括組註釋服務,媒體型別轉換,協議簡化,或者匿名過濾等。除非透明行為或非透明行
為經被顯式地宣告,否則,HTTP代理既是透明代理也是非透明代理。
閘道器(gateway)
閘道器其實是一個伺服器,扮演著代表其它伺服器為客戶端提供服務的中間者。與代理(proxy)
不同,閘道器接收請求,彷彿它就是請求資源的源伺服器。請求的客戶端可能覺察不到它正在同
閘道器通訊。
隧道(tunnel)
隧道也是一箇中間程式,它一個在兩個連線之間充當盲目中繼(blind relay)的中間程式。一旦
隧道處於活動狀態,它不能被認為是這次HTTP通訊的參與者,雖然HTTP請求可能已經把它
初始化了。當兩端的中繼連線都關閉的時候,隧道不再存在。
快取(cache)
快取是程式響應訊息的本地儲存。快取是一個子系統,控制訊息的儲存、獲取和刪除。快取裡存
放可快取的響應(cacheable response)為的是減少對將來同樣請求的響應時間和網路頻寬消
耗。任一客戶端或伺服器都可能含有快取,但快取不能存在於一個充當隧道(tunnel)的伺服器
裡。
可快取的(cacheable)
我們說響應(response)是可快取的,如果這個響應可以被快取(cache)儲存其副本,為的
是能響應後續請求。確定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 協議是一種請求/響應型的協議。 客戶端給伺服器傳送請求的格式是一個請求方法
(request method),URI,協議版本號,然後緊接著一個包含請求修飾符(modifiers),客
戶端資訊,和可能的訊息主體的類MIME(MIME-like)訊息。伺服器對請求端傳送響應的格式
是以一個狀態行(status line),其後跟隨一個包含伺服器資訊、實體元資訊和可能的實體主體
內容的類MIME(MIME-like)的訊息。其中狀態行(status line)包含訊息的協議版本號和一
個成功或錯誤碼。HTTP和MIME之間的關係如附錄19.4節所闡述。
大部分的HTTP通訊是由使用者代理(user agent)發起的,由應用於一個源伺服器資源的請求
構成。最簡單的情形,這可以通過使用者代理(UA)和源伺服器(O)之間的單一連線(v)來實
現。
請求鏈(Request chain)-------------------------------------- ----------
使用者代理(UA)----------------單一連線(v)--------------源伺服器(O)
<----------------------------------------------------------響應鏈(response chain)
有可能在請求/響應鏈中出現一個或多箇中間者(intermediares),這是比較複雜的情形。常見
的中間者(intermediares)有三種:代理(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的伺服器,與此同
時C正在處理A的請求。
通訊中任何非隧道成員都可能會採用一個內部快取(internal cache)來處理請求。如果沿著鏈
的成員有請求已快取的響應,請求/響應鏈就會大大縮短。下圖闡明瞭一個最終請求響應鏈,假
定B擁有一個來自於O(通過C)的以前請求響應的快取副本,並且此請求的響應並未被UA
或A快取。
請求鏈(request chain)---------->
UA-----v----------A-----v-----B-----C----O
<---------響應鏈 (response chain)
並不是所有的響應都能有效地快取,一些請求可能含有修飾符(modifiers),這些修飾符對緩
存動作有特殊的要求。HTTP對快取行為(behavior)和可快取響應(cacheable responses)
的定義在第13章定義。
實際上,目前全球資訊網上有多種被實踐和部署的快取和代理的體系結構和配置。這些系統包括節
省頻寬的快取代理(proxy cache)層次(hierarchies)系統,可以廣播(broadcast)或多播
(multicast)快取資料的系統,通過CD-ROM釋出快取資料子集的機構,等等。HTTP系統
(http system)會被應用於寬頻連線的企業區域網中的協作,並且可以被用於PDAs進行低耗
無線斷續連線訪問。HTTP1.1的宗旨是為了支援各種各樣的已經部署的配置,同時引進一種協
議結構,讓它滿足可以建立高可靠性的web應用程式,即使不能達到這種要求,也至少可以可
靠的定位故障。
HTTP通訊通常發生在TCP/IP連線上。預設埠是TCP 80,不過其它埠也可以使用。但並不
排除HTTP協議會在其它協議之上被實現。HTTP僅僅期望的是一個可靠的傳輸(譯註:HTTP
一般建立在傳輸層協議之上);所以任何提供這種保證的協議都可以被使用;協議傳輸資料單
元(transport data unit)與HTTP/1.1請求和響應的訊息結構之間的映象已經超出了本規範的
範圍。
大部分HTTP/1.0 的實現都是對每個請求/響應交換(exchange)產生一個新的連線。而
HTTP/1.1中,一個連線可以用於一個或更多請求/響應交換,雖然連線可能會因為各種原因中
斷(見第8.1節)。
2 符號習慣和一般語法
2.1 擴充的BNF(擴充的 巴科斯-諾爾正規化)
本文件規定的所有機制都用兩種方法描述:散文體(prose)和類似於RFC 822 的擴充
Backus-Naur Form(BNF)。要理解本規範,使用者需熟悉符號表示法。擴充BNF結構如下:
名字(name)=定義(definition)
名字(name)就是代表規則的名字,規則名裡不能包含“<”和“>”,通過等號把規則名和規
則定義(definiation)分離開。空格只有在採用延續行縮排來指定跨度多於一行的規則定義的時
候才有意義。某些基本規則(basic rules)使用大寫字母包含在規則定義裡, 如
SP,LWS,HT,CRLF,DIGIT,ALPHA,等等。尖括號可以包含在規則定義裡,只要它們的
存在有利於區分規則名的使用。
“字面文字”(“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)
用分號引導註釋。
隱含的*LWS
本規範所描述的語法是基於字(word-based)的。除非特別註明,線性空白(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”的域裡。在其他域裡,圓括號被視作域值的一部分。
comment (註釋)= "(" *(ctext | quoted-pair | comment )” )"
ctext = <除"(" 和 ")"以外的任意TEXT >
如果一個TEXT若被包含在雙引號裡,則當作一個字。
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext = <any TEXT except <">>
斜劃線("\")可以被作為單字元的引用機制,但是必須要在quoted-string和comment構造之
內。
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-Version裡,並且對任何不相容HTTP/1.0的訊息也必須這麼做。關於何
時傳送特定的HTTP-Version值的細節,參見RFC2145[36]。
應用程式的HTTP版本是應用程式最少條件遵循的最高HTTP版本。
當代理或閘道器應用程式轉發(forwarding)訊息的協議版本不同於代理或閘道器應用程式本身協
議版本的時候,代理(proxy)和閘道器(gateway)應用程式就要小心。因為訊息裡協議版本說
明瞭傳送者處理協議的能力,所以一個代理/閘道器千萬不要傳送一個高於該代理/閘道器應用程式
協議版本的訊息。如果代理或閘道器接收了一個更高版本的訊息,它必須要麼使協議的版本降低,
要麼以一個錯誤響應,或者要麼切換到隧道行為(tunnel behavior)。
自從RFC 2068[33]釋出後,由於存在與HTTP/1.0代理(proxy)的互操作問題,所以快取代
理(caching proxies)必須能提升請求的版本到他們能支援的程度,但閘道器(gateway)可以
這麼做也可以不這麼做,而隧道(tunnels)卻不能這麼做。代理(Proxy)/閘道器(gateway)
的響應(Response)必須和請求(request)的主版本(major version)號保持一致。
注意:HTTP版本間的轉換可能會對訊息頭域(header fields)在版本里有或沒有而進行改變。
3.2 通用資源識別符號(URI)
URIs有許多名字已為人所知:WWW地址,通用文件識別符號,通用資源識別符號[3],以及後來
的統一資源定位器(URL)[4]和統一資源名稱(URN)[20]。就HTTP而言,通用資源識別符號
(URI)只是簡單的格式化字串---通過名稱,位置,或其它特徵---識別一個資源。
3.2.1 一般語法
根據使用的背景,HTTP裡的URIs可以表示成絕對(absoulute)形式或相對形式(相對URI
基於根URI[11])。兩種形式的區別是根據這樣的事實:絕對URI總是以一個模式(scheme)
名作為開頭,其後是一個冒號。關於URL 更詳盡的語法和含義請參看“統一資源識別符號
(URI):一般語法和語義”,RFC 2396 [42](代替了RFCs 1738 [4]和RFC 1808 [11])。本
規範採用了RFC 2396 裡的” URIreference”
, "absoluteURI" , "relativeURI" , "port" , "host" , "abs_path" , "rel_path",
和"authority"的定義格式。
HTTP協議不對URI的長度作事先的限制,伺服器必須能夠處理任何他們提供資源的URI,並
且應該能夠處理無限長度的URIs,這種無效長度的URL可能會在客戶端以基於GET方式的
請求時產生。如果伺服器不能處理太長的URI的時候,伺服器應該返回414狀態碼(此狀態碼
代表Request-URI太長)。
注:伺服器在依賴大於255位元組的URI時應謹慎,因為一些舊的客戶或代理實現可能不支援這
些長度。
3.2.2 HTTP URL
在HTTP協議裡,http模式(http scheme)被用於定位網路資源(resourse)的位置。本節定
義了http URLs這種特定模式(scheme)的語法和語義。
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
如果埠為空或未給出,就假定為80。它的語義即:已識別的資源存放於正在監聽tcp連線的
那個埠的伺服器上,並且請求資源的的Request-UR為絕對路徑(5.1.2節)。無論什麼可能
的時候,URL 裡使用IP 地址都是應該避免的(參看RFC 1900 [24])。如果絕對地址
(abs_path)沒有出現在URL 裡,那麼應該給出"/"。如果代理(proxy)收到一個主機
(host)名,但是這個主機名不是全稱域名(fully quanlified domain name),則代理應該把
它的域名加到主機名上。如果代理(proxy)接收了一個全稱域名,代理不能改變主機(host)
名稱。
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-date的地方。
注:日期值的接收者被鼓勵能可靠地接收來自於非HTTP應用程式傳送的的日期值,例如有時
可以通過代理(proxy)/閘道器(gateway)向SMTP或NNTP獲取或提交訊息。
所有的HTTP日期/時間都必須以格林威治時間(GMT)表示。對HTTP而言,GMT完全等同
於UTC(世界協調時間)。前兩種日期/時間格式裡包含“GMT”,它是時區的三個字面的簡寫,
並且當讀到一個asctime格式時必須先被假定是GMT時間。HTTP日期(HTTP-date)區分大
小寫,不能在此語法中除SP之外包含一個多餘的LWS。
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對日期/時間格式的要求僅僅應用在協議流的使用。客戶和伺服器不必把這種格式
應用於使用者呈現(user presentation),請求記錄日誌,等等。.
3.3.2 Delta Seconds (秒間隔)
一些HTTP頭域(header field)允許時間值以秒為單位,以十進位制整數表示,此值代表訊息
接收後的時間。
delta-seconds = 1*DIGIT
3.4 字符集 (Character Sets)
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頭域裡包含一個字符集引數,即使字符集
是ISO-8859-1的也應該指明,這樣就不會讓接收者產生混淆。
不幸的是,一些舊的HTTP/1.0客戶端不能處理在Content-Type頭域裡明確指定的字符集引數。
HTTP/1.1接收端必須要認真對待發送者提供的字符集;並且當用戶代理(user agent,譯註:
如瀏覽器)開始呈現一個文件時,雖然使用者代理可以猜測文件的字符集,但如果content-type
頭域裡提供了字符集,並且使用者代理也支援這種字符集的顯示,不管使用者代理是否願意,它必
須要利用這種字符集。參見3.7.1節。
3.5 內容編碼(Content Codings)
內容編碼(content coding)的值表示一種曾經或能被應用於一個實體的編碼轉換(encoding
transformation)。內容編碼主要用於文件的壓縮或其它有效的變換,但這種變換必須不能丟失
文件的媒體型別的特性,並且不能丟失文件的資訊(譯註:就像有失真壓縮和無失真壓縮,前者不
會丟失資訊,後者會丟失資訊)。實體經常被編碼後儲存,然後傳送出去,並且在接收端被解
碼。
content-coding = token
所有內容編碼(content-coding)的值是不區分大小寫的。HTTP/1.1在接受譯碼 (Accept-
Encoding,14.3 節)和內容譯碼(Content-Encoding)(14.11 節)頭域裡使用內容編碼
(content-coding)的值。儘管該值描述了內容編碼,更重要的是它指出了一種解碼機制,利用
這種機制對實體的編碼進行解碼。
網路分配數字權威( (IANA)充當內容編碼的值標記(token)註冊機構。最初,登錄檔裡包
含下列標記:
gzip(壓縮程式)
一種由檔案壓縮程式"gzip"(GNU zip)產生的編碼格式(在RFC 1952中描述)。這種編碼格
式是一種具有32位CRC的Lempel-Ziv編碼(LZ77)。
compress(壓縮)
一種由UNIX檔案壓縮程式"compress"產生的編碼格式。這種編碼格式是一種具有可適應性的
Lempel-Ziv-Welch編碼(LZW)。
對於將來的編碼,用程式名識表徵編碼格式是不可取。在這裡用到他們是因為他們在歷史的作
用,雖然這樣做並不好。為了同以前的HTTP 實現相相容,應用程式應該將"x-gzip"和"xcompress"
分別等同於"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 ,譯註: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
所有傳輸編碼的值是大小寫不敏感。傳輸編碼的值在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,MIME [7])的值相似,它
被定義能夠實現在7位傳輸服務上保證二進位制資料的安全傳輸。不過,傳輸編碼與內容傳輸譯
碼(Content-Transfer-Encoding)對純8位傳輸協議有不同的側重點。在HTTP中,訊息主體
存在不安全的特性是因為有時候很難確定訊息主體的長度(7.2.2節)和在共享的傳輸上加密
資料。
網路分配數字權威(IANA)擔任註冊傳輸編碼的值標記(token)的角色。起初,註冊包含如下
標記:"塊"(3.6.1 節),"身份"(3.6.2 節),"gzip"(3.5 節),"壓縮"(3.5 節),和"縮小"(3.5
節).
新的傳輸編碼的值標記應該註冊,這同新的內容編碼的值標記也需要註冊一樣。.
如果接收端接收到一個經過傳輸編碼編碼過的實體主體(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,在14.40 節闡述)來指明哪些頭域被包含在塊傳輸編碼的尾部
(trailer) (見14.40節)
如果伺服器要使用塊傳輸編碼進行響應,除非以下至少一條為真時它才能包含尾部
(trailer):
a)如果此響應的對應請求包括一個TE頭域,並且利用 “trailers”指明瞭塊傳輸編碼響應的尾
部是可以接受的(TE頭域在14.39節中描述;或者
b)如果是源伺服器進行響應,響應裡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)以一種 屬性/值(attribute/value)形式(如3.6節定義)跟隨 型別/子型別
(type/subtype)。
型別(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訊息控制結構(如頭域和多邊界體(multipart boundaries))裡,一個純
粹的CR或LF都不能代替CRLF的作用。
如果一個實體主體(entity-body)用內容編碼(content-coding)進行編碼,原始資料在被編
碼前必須是一種以上定義的媒體型別格式。.
"charset"引數(parameter)被應用於一些媒體型別,來定義資料的字符集(見3.4節)。當發
送端沒有指明charset引數(parameter)時,“text”型別的子媒體型別(subtype)被接收端
接收後會被認為是預設的ISO-8859-1字符集。非“ISO-8859-1”字符集和它的子類(subsets)
的資料必須被指示恰當的字符集。3.4.1節描述了相容性問題。
3.7.2 多部分型別(Multipart type)
MIME提供了一系列“多部分”(multipart)型別---在單個訊息主體內包裝一個或多個實體。所
有的多部分型別共享一個公共的語法(這在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使用者代
理一樣或者相似的行為,這依賴於接收何種多部分型別。一個多部分型別訊息的每一個體部分
(body-part)裡的MIME頭域對於HTTP除了MIME語意並沒有太大意義。
通常, 一個HTTP使用者代理應該遵循與一個MIME使用者代理相同或相似的行為。如果一個應用
程式收到一個不能識別的多部分子型別,這個應用程式必須將它視為"multipart/mixed"。
注:"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
標籤中不允許出現空格,標籤大小寫不敏感(case-insensitive)。由IANA來管理語言標籤中
的名字。典型的標籤包括:
en, en-US, en-cockney, i-cherokee, x-pig-latin
上面的任意兩個字母的主標籤是一個ISO-639語言的縮寫,並且兩個大寫字母的子標籤是一個
ISO-3166的國家程式碼。(上面的最後三個標籤是未經註冊的標籤;但是除最後一個之外所有的
標籤都會將來註冊)。
3.11 實體標籤 (Entity Tags)
實體標籤被用於比較相同請求資源中兩個或更多實體。HTTP/1.1 在ETag(14.19節),Ifmatch(
14.24節),If-None-match(14.26節)和If-Rang(14.27節)頭域中運用實體標籤。
關於它們怎樣被當作一個快取驗證器(cache validator)被使用和比較在13.3.3節被定義。一
個實體標籤由一個給定的晦澀引用字串(opaque quoted string),還可能前面帶一個弱指
示器組成。
entity-tag = [ weak ] opaque-tag
weak = "W/"
opaque-tag = quoted-string
一個“強實體標籤”如果被一個資源的兩個實體裡共享,那麼這兩個實體必須在位元組上等價。
一個“弱實體標籤”是以"W/"字首的,它可能會被一個資源的兩個實體共享,如果這兩個實體
是等價的,並且能彼此替換,並且替換後也不會在語義上發生太大改變。一個弱實體標籤只能
用於弱比較(weak comparison)。
在一個特定資源的所有實體版本里,一個實體標籤必須能唯一。一個給定的實體標籤值可以被
用於不同的URI請求的實體。相同實體標籤的值應用於不同URI請求的實體,並不意味著這些
實體是等價的。
3.12 範圍單位(Range Units)
HTTP/1.1 允許客戶請求響應實體的一部分。HTTP/1.1 在Range(14.35 節)和Content-
Range(14.16節)頭域裡應用範圍單位(range units)。任何實體根據不同結構化單元都能被
分解成子範圍
range-unit = bytes-unit | other-range-unit
bytes-unit = "bytes"
other-range-unit = token
HTTP/1.1中定義的唯一的範圍單位是"bytes"。HTTP/1.1實現可能忽略其他單位指定的範圍。
HTTP/1.1被設計允許應用程式實現不依賴於對範圍的瞭解。
4 HTTP訊息
4.1 訊息型別(Message Types)
HTTP訊息由從客戶到伺服器的請求訊息和從伺服器到客戶的響應訊息兩部分組成.
HTTP-message = Request|Response ;HTTP/1.1
請求(第5節)和響應(第6節)訊息利用RFC 822[9]定義的常用訊息的格式,這種訊息格式
是用於傳輸實體(訊息的負載)。兩種型別的訊息都由一個開始行(start-line),零個或更多
個頭域(經常被稱作“頭”),一個指示頭域結束的空行(也就是以一個CRLF為字首的什麼
也沒有的行),最後一個可有可無的訊息主體(message-body)組成。
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
為了健壯性,伺服器應該忽略任意請求行(Request-Line)前面的空行。換句話說,如果服務
器開始讀訊息流的時候發現了一個CRLF,它應該忽略這個CRLF。
一般一個存在問題的HTTP/1.0客戶端會在POST請求訊息之後新增額外的CRLF。為了重新聲
明被BNF明確禁止的行為,一個HTTP/1.1客戶端不能在請求前和請求後附加一些不必要的
CRLF。
4.2 訊息頭 (Message Headers)
HTTP頭域包括常用頭域(4.5 節),請求頭域(5.3 節),響應頭域(6.2 節)和實體頭域
(7.1節)。它們遵循的是RFC822[0]3.1節中給出的同一個常用格式。每一個頭域由一個名字
(域名)跟隨一個":"和域值構成。域名是大小寫不敏感的。域值前面可能有任意數量的LWS的。
但SP(空格)是首選的。頭域能被延伸多行,這通過在這些行前面加一些SP或HT。應用程式
當產生HTTP訊息時,應該遵循“常用格式”,因為可能存在一些應用程式,他們不能接收任
何常用形式之外的形式。.
message-header = field-name ":" [ field-value ]
field-name = token
field-value = *( field-content | LWS )
field-content = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, separators, and quoted-string>
filed-content 不包括任何前導或後續的LWS(線性空白):線性空白出現在域值(filedvalue)
的第一個非空白字元之前或最後一個非空白字元之後。前導或後續LWS可能會在不會
改變域值語意情況下被刪除。任何出現在filed-content之間的LWS可能在解析域值之前或把這
個訊息往下流傳遞時會被一個SP代替。.
不同域名的頭域被接收的順序是不重要的。然而,首先發送常用頭域,然後緊接著是請求頭域
或者是響應頭域,然後是以實體頭域結束,這樣做是一個好的的方法。
如果一個頭域的域值被定義成一個以逗號隔開的列表,那麼使用同一個域名(filed-name)的
多個訊息頭域可能會出現在一些訊息中。不改變訊息的語義,可以把相同名的多個頭域結合成
一個“域名:域值”對的形式,這可以通過把每一個後續的域值加到第一個裡,每一個域值用
逗號隔開的演算法實現。同名頭域的接收順序對合並的域值的解釋是有重要意義的,所以代理
(proxy)當把訊息轉發時不能改變域值的順序。
4.3 訊息主體 (Message Body)
HTTP 訊息的訊息主體用來承載請求和響應的實體主體(entity-body)的。這些訊息主體
(message-body)僅僅當被傳輸譯碼頭域(Transfer-Encoding)指明的傳輸編碼(transfercoding)
應用於實體主體(entity-body)時才和實體主體相區別,其它情況訊息主體和實體主
體相同。傳輸譯碼頭域在14.41節闡述。
message-body=entity-body|<entity-body encoded as per Transfer-Encoding>
傳輸譯碼頭域被用來指明應用程式的傳輸編碼,它是為了保證訊息的安全和合適的傳輸。傳輸
譯碼(Transfer-Encoding)頭域是訊息的屬性,而不是實體的屬性,因此可能會沿著請求/響
應鏈被新增或刪除。(然而,3.6節描述了一些限制當使用某個傳輸編碼時)
什麼時候訊息主體(message-body)允許出現在訊息中,這根據不同請求和響應來決定的。
請求中訊息主體(message-body)的存在是被請求中訊息頭域中是否存在內容長度
(Content-Length)或傳輸譯碼(Transfer-Encoding)頭域來通知的。一個訊息主體
(message-body)不能被包含在請求裡如果某種請求方法(見5.1.1節)不支援請求裡包含實
體主體(entity-body)。一個伺服器應該能閱讀或再次轉發請求裡的訊息主體;如果請求方法
不允許包含一個實體主體(entity-body),那麼當伺服器處理這個請求時訊息主體應該被忽略。
對於響應訊息,訊息裡是否包含訊息主體依賴相應的請求方法和響應狀態碼。所有HEAD請求
方法的請求的響應訊息不能包含訊息主體,即使實體頭域出現在請求裡。所有1XX(資訊的),
204(無內容的)和304(沒有修改的)的響應都不能包括一個訊息主體(message-body)。
所有其他的響應必須包括訊息主體,即使它長度可能為零。
4.4 訊息的長度(Message Length)
當訊息主體出現在訊息中時,一條訊息的傳輸長度(transfer-length)是訊息主體(messagebody)
的長度;也就是說在實體主體被應用了傳輸編碼(transfer-coding)後。當訊息中出現
訊息主體時,訊息主體的傳輸長度(transfer-length)由下面(以優先權的順序)決定::
1。任何不能包含訊息主體(message-body)的訊息(這種訊息如1xx,204和304響應和任
何HEAD方法請求的響應)總是被頭域後的第一個空行(CRLF)終止,不管訊息裡是否存在
實體頭域(entity-header fields)。
2。如果Transfer-Encoding頭域(見14.41節)出現,並且它的域值是非”“dentity”傳輸編碼
值,那麼傳輸長度(transfer-length)被“塊”(chunked)傳輸編碼定義,除非訊息因為通過
關閉連線而結束。
3。如果出現Content-Length頭域(屬於實體頭域)(見14.13節),那麼它的十進位制值(以
位元組表示)即代表實體主體長度(entity-length,譯註:實體長度其實就是實體主體的長度,
以後把entity-length翻譯成實體主體的長度)又代表傳輸長度(transfer-length)。Content-
Length 頭域不能包含在訊息中,如果實體主體長度(entity-length)和傳輸長度(transferlength)
兩者不相等(也就是說,出現Transfer-Encodind頭域)。如果一個訊息即存在傳輸譯
碼(Transfer-Encoding)頭域並且也Content-Length頭域,後者會被忽略。
4。如果訊息用到媒體型別“multipart/byteranges”,並且傳輸長度(transfer-length)另外也沒
有指定,那麼這種自我定界的媒體型別定義了傳輸長度(transfer-length)。這種媒體型別不能
被利用除非傳送者知道接收者能怎樣去解析它; HTTP1.1客戶端請求裡如果出現Range頭域
並且帶有多個位元組範圍(byte-range)指示符,這就意味著客戶端能解析multipart/byteranges
響應。
一個Range請求頭域可能會被一個不能理解multipart/byteranges的HTTP1.0代理(proxy)
再次轉發;在這種情況下,伺服器必須能利用這節的1,3或5項裡定義的方法去定界此訊息。
5。通過伺服器關閉連線能確定訊息的傳輸長度。(請求端不能通過關閉連線來指明請求訊息體
的結束,因為這樣可以讓伺服器沒有機會繼續給予響應)。
為了與HTTP/1.0應用程式相容,包含HTTP/1.1訊息主體的請求必須包括一個有效的內容長
度(Content-Length)頭域,除非伺服器是HTTP/1.1遵循的。如果一個請求包含一個訊息主體
並且沒有給出內容長度(Content-Length),那麼伺服器如果不能判斷訊息長度的話應該以
400響應(錯誤的請求),或者以411響應(要求長度)如果它堅持想要收到一個有效內容長
度(Content-length)。
所有的能接收實體的HTTP/1.1應用程式必須能接受"chunked"的傳輸編碼(3.6節),因此當
訊息的長度不能被提前確定時,可以利用這種機制來處理訊息。
訊息不能同時都包括內容長度(Content-Length)頭域和非identity傳輸編碼。如果訊息包括了
一個非identity的傳輸編碼,內容長度(Content-Length)頭域必須被忽略.
當內容長度(Content-Length)頭域出現在一個具有訊息主體(message-body)的訊息裡,
它的域值必須精確匹配訊息主體裡位元組數量。HTTP/1.1使用者代理(user agents)當接收了一個
無效的長度時必須能通知使用者。
4.5 常用頭域(General Header Fields)
有一些頭域即適用於請求訊息也適用於響應訊息,但是這些頭域並不適合傳輸實體。這些頭域
只能應用於傳輸訊息。
general-header = Cache-Control ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.18
| Pragma ; Section 14.32
| Trailer ; Section 14.40
| Transfer-Encoding ; Section 14.41
| Upgrade ; Section 14.42
| Via ; Section 14.45
| Warning ; Section 14.46
常用頭域名能被擴充套件,但這要和協議版本的變化相結合。然而,如果通訊裡的所有參與者都認
同新的或實踐性的頭域是常用頭域,那麼它們可能就被賦於常用頭域的語意。不被識別的頭域
會被作為實體頭(entity-header)頭域來看待。
5 請求(Request)
一個請求訊息是從客戶端到伺服器端的,在訊息首行裡包含方法,資源指示符,協議版本。
Request = Request-Line ; Section 5.1
*(( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 4.3
5.1 請求行 (Request-Line)
請求行(Request-Line)是以一個方法標記開始,後面跟隨Request-URI和協議版本(HTTPVersion),
最後以CRLF結束。元素是以SP字元分隔。除了最後的CRLF,CR或LF是不被允
許的。
Request-Line =Method SP Request-URL SP HTTP-Version CRLF
5.1.1方法 (Method)
方法標記(token)指明瞭在被Request-URI指定的資源上執行的方法。這種方法是大小寫敏
感的。
Method = "OPTIONS" ;9.2節
| "GET" ;9.3節
| "HEAD" ;9.4節
|"POST" ;9.5節
|"PUT" ;9.6節
|"DELETE" ;9.7節
|"TRACE" ;9.8節
|"CONNECT" ;9.9節
| extension-method
Extension-method = token
資源所允許的方