說明:因為翻譯中存在不少錯誤,因此貼在互動供大家一起修改。
著作權聲明:轉載時請以超連結形式標明文章原始出處和作者信息及本聲明http://haoren.blogbus.com/logs/182145.html
RFC1945HTTP1.0協定中文版
組織:中國互動出版網(http://www.china-pub.com/)
RFC文檔中文翻譯計畫(http://www.china-pub.com/compters/emook/aboutemook.htm)
E-mail:[email protected]
譯者:黃曉東(黃曉東[email protected])
譯文發布時間:2001-7-14
著作權:本中文翻譯文檔著作權歸中國互動出版網所有。可以用於非商業用途自由轉載,但必須
保留本文檔的翻譯及版權資訊。
NetworkWorkingGroupT.Berners-Lee
RequestforComments:1945MIT/LCS
Category:InformationalR.Fielding
UCIrvine
H.Frystyk
MIT/LCS
May1996
超文本傳輸協定--HTTP/1.0
(HyptertextTransferProtocol–HTTP/1.0)
備忘的狀態(Status of This Memo)
本段文字為Internet團體提供信息,並沒有以任何方式指定Internet標準。本段文字沒有分發限制。
IESG提示(IESGNote):
IESG已在關注此協定,並期待該文檔能儘快被標準跟蹤文檔所替代。
摘要(Abstract)
HTTP(HypertextTransferProtocol)是套用級協定,它適應了分散式超媒體協作系統對靈活性及速度的要求。它是一個一般的、無狀態的、基於對象的協定,通過對其請求方法
(requestmethods)進行擴展,可以被用於多種用途,比如命名伺服器(nameserver)及分
布式對象管理系統。HTTP的一個特性是其數據表現類型允許系統的構建不再依賴於要傳輸
的數據。
HTTP自從1990年就在WWW上被廣泛使用。該規範反映了“HTTP/1.0”的普通用法。
目錄(Table of Contents)
1.介紹(Introduction)61.1目的(Purpose)6
1.2術語(terminology)6
1.3概述(OverallOperation)8
1.4HTTPandMIME9
2.標誌約定及基本語法(NotationalConventionsandGenericGrammar)9
2.1補充反饋方式(augmentedBNF)9
2.2基本規則(BasicRules)10
3.協定參數(ProtocolParameters)12
3.1HTTP版本(HTTPVersion)12
3.2統一資源標識(UniformResourceIdentifiers)13
3.2.1一般語法(GeneralSyntax)13
3.2.2httpURL14
3.3Date/Time格式(Date/TimeFormats)15
3.4字元集(CharacterSets)16
3.5內容解碼(ContentCodings)16
3.6介質類型(MediaTypes)17
3.6.1標準及文本預設(CanonicalizationandTextDefaults)18
3.6.2多部分類型(MultipartTypes)18
3.7產品標識(ProductTokens)19
4.HTTP訊息(HTTPMessage)19
4.1訊息類型(MessageTypes)19
4.2訊息標題(MessageHeaders)20
4.3普通標題域(GeneralHeaderFields)20
5.請求(Request)21
5.1請求佇列(Request-Line)21
5.1.1方法(Method)22
5.1.2請求URI(Request-URI)22
5.2請求標題域(RequestHeaderFields)23
6.回應(Response)23
6.1狀態行(Status-Line)24
6.1.1狀態代碼和原因分析(StatusCodeandReasonPhrase)24
6.2回應標題域(ResponseHeaderFields)25
7.實體(Entity)26
7.1實體標題域(EntityHeaderFields)26
7.2實體主體(EntityBody)26
7.2.1類型(Type)27
7.2.2長度(Length)27
8.方法定義(MethodDefinitions)27
8.1GET28
8.2HEAD28
8.3POST28
9.狀態代碼定義(StatusCodeDefinitions)29
9.1訊息1xx(Informational1xx)29
9.2成功2xx(Successful2xx)29
9.3重定向(Redirection3xx)30
9.4客戶端錯誤(ClientError)4xx31
9.5伺服器錯誤(ServerError)5xx32
10.標題域定義(HeaderFieldDefinitions)33
10.1允許(Allow)33
10.2授權(Authorization)34
10.3內容編碼(Content-Encoding)34
10.4內容長度(Content-Length)34
10.5內容類型(Content-Type)35
10.6日期(Date)35
10.7過期(expires)36
10.8來自(From)37
10.9從何時更改(If-Modified-Since)37
10.10最近更改(Last-Modified)38
10.11位置(Location)38
10.12註解(Pragma)39
10.13提交方(Referer)39
10.14伺服器(Server)40
10.15用戶代理(User-Agent)40
10.16WWW-授權(WWW-authenticate)40
11.訪問鑑別(AccessAuthentication)41
11.1基本授權方案(BasicAuthenticationScheme)42
12.安全考慮(SecurityConsiderations)43
12.1客戶授權(AuthenticationofClients)43
12.2安全方法(SafeMethods)43
12.3伺服器日誌信息的弊端(AbuseofServerLogInformation)43
12.4敏感信息傳輸(TransferofSensitiveInformation)44
12.5基於檔案及路徑名的攻擊(AttacksBasedOnFileandPathNames)44
13.感謝(Acknowledgments)45
14.參考書目(References)45
15.作者地址(Authors'Addresses)47
附錄(Appendices)48
A.Internet介質類型訊息/http(InternetMediaTypemessage/http)48
B.容錯套用(TolerantApplications)48
C.與MIME的關係(RelationshiptoMIME)49
C.1轉換為規範形式(ConversiontoCanonicalForm)49
C.2日期格式轉換(ConversionofDateFormats)49
C.3內容編碼介紹(IntroductionofContent-Encoding)50
C.4無內容傳輸編碼(NoContent-Transfer-Encoding)50
C.5多個主體的HTTP標題域(HTTPHeaderFieldsinMultipartBody-Parts)
50
D.附加特性(AdditionalFeatures)50
D.1附加請求方法(AdditionalRequestMethods)51
D.2附加標題域定義(AdditionalHeaderFieldDefinitions)51
1. 介紹
1.1 目的
HTTP(HypertextTransferProtocol)是套用級協定,它適應了分散式超媒體協作系統對靈活性及速度的要求。它是一個一般的、無狀態的、基於對象的協定,通過對其請求方法
(requestmethods)進行擴展,可以被用於多種用途,比如命名伺服器(nameserver)及分
布式對象管理系統。HTTP的一個特性是其數據表現類型允許系統的構建不再依賴於要傳輸
的數據。
HTTP自從1990年就在WWW上被廣泛使用。該規範反映了“HTTP/1.0”的普通用法。
該規範描述了在大多數HTTP/1.0客戶機及伺服器上看起來已經實現的特性。規範將被
分成兩個部分:HTTP特性的實現是本文檔的主要內容,而其它不太通行的實現將被列在附
錄D中。
實用的信息系統需要更多的功能,而不僅僅是數據的獲取,包括搜尋、前端更新及註解。
HTTP允許使用開放的命令集來表示請求的目的,它使用基於URI[2](UniformResource
Identifier),即統一資源標識的規則來定位(URL[4])或命名(URN[16])方法所用到的資
源。HTTP使用與郵件(InternetMail[7])和MIME(MultipurposeInternetMailExtensions[5])
相似的格式來傳遞訊息。
HTTP也作為用戶代理、代理伺服器/網關與其它Internet協定進行通訊的一般協定,這
些協定是,SMTP[12],NNTP[11],FTP[14],Gopher[1],andWais[8]等。HTTP允許不同的
套用可以進行基本的超媒體資源訪問,並簡化用戶代理的實現。
1.2 術語(Terminology)
本規範用了許多與參與方、對象及HTTP通訊相關的術語,如下:連線(connection)
兩個應用程式以通訊為目的在傳輸層建立虛擬電路。
訊息(message)
HTTP通訊的基本單元,在連線中傳輸的結構化的、有順序的位元組(其含義在第四
節中定義)。
請求(request)
HTTP的請求訊息(在第五節定義)
回應(response)
HTTP的回應訊息(在第六節定義)
資源(resource)
網路上可以用URI來標識的數據對象或服務(見3.2節)
實體(entity)
可被附在請求或回應訊息中的特殊的表示法、數據資源的表示、服務資源的回應等,
由實體標題(entityheader)或實體主體(entitybody)內容形式存在的元信息組成。
客戶端(client)
指以發出請求為目的而建立連線的應用程式。
用戶代理(useragent)
指初始化請求的客戶端,如瀏覽器、編輯器、蜘蛛(web爬行機器人)或其它終端
用戶工具。
伺服器(server)
指接受連線,並通過傳送回應來回響服務請求的應用程式。
原始伺服器(originserver)
存放資源或產生資源的伺服器。
代理(proxy)
同時扮演伺服器及客戶端角色的中間程式,用來為其它客戶產生請求。請求經過變
換,被傳遞到最終的目的伺服器,在代理程式內部,請求或被處理,或被傳遞。代
理必須在訊息轉發前對訊息進行解釋,而且如有必要還得重寫訊息。代理通常被用
作經過防火牆的客戶端出口,用以輔助處理用戶代理所沒實現的請求。
網關(gateway)
伺服器之間的伺服器。與代理不同,網關接受請求就好象它就是被請求資源所在的
原始伺服器,發出請求的客戶端可能並沒有意識到它在與網關進行通訊。網關是網
絡防火牆伺服器端的門戶。對非HTTP系統資源進行訪問時,網關做為中間的協定
翻譯者。
隧道(tunnel)
隧道就好象連線兩端看不見的中繼器。處於激活狀態時,它雖然是由HTTP請求來
初始化的,但它並不參與HTTP通訊。當需要中繼連線的兩端關閉後,隧道也自然
終止。在入口有需求及中間程式無法或不該解釋要中繼的通訊時,通常要用到隧道
技術。
快取(cache)
指程式本地存儲的回應訊息和用來控制訊息存儲、重獲、刪除的子系統。
快取回應的目的是為減少請求回應時間,以及未來一段時間對網路頻寬的消耗。任
何客戶端及服務端都可以包含快取。伺服器在以隧道方式工作時不能使用快取。
任何指定的程式都有能力同時做為客戶端和伺服器。我們在使用這個概念時,不是看程
序功能上是否能實現客戶及伺服器,而是看程式在特定連線時段上扮演何種角色(客戶或服
務器)。同樣,任何伺服器可以扮演原始伺服器、代理、網關、隧道等角色,行為的切換取
決於每次請求的內容。
1.3 概述(Overall Operation)
HTTP協定是基於請求/回應機制的。客戶端與伺服器端建立連線後,以請求方法、URI、協定版本等方式向伺服器端發出請求,該請求可跟隨包含請求修飾符、客戶信息、及可能的
請求體(body)內容的MIME類型訊息。
伺服器端通過狀態佇列(statusline)來回應,內容包括訊息的協定版本、成功或錯誤代
碼,也跟隨著包含伺服器信息、實體元信息及實體內容的MIME類型訊息。
絕大多數HTTP通訊由用戶代理進行初始化,並通過它來組裝請求以獲取存儲在一些原
始伺服器上的資源。在最簡單的情況下,通過用戶代理(UA)與原始伺服器(O)之間一
個簡單的連線(v)就可以完成。
requestchain------------------------>
UA-------------------v-------------------O
<-----------------------responsechain
更複雜的情況是當請求/回應鏈之間存在一個或更多中間環節。總體看來,有三種中間
環節:代理(proxy)、網關(gateway)、隧道(tunnel)。
代理(proxy)是向前推送的代理人(agent),它以絕對形式接收URI請求,重寫全部
或部分訊息,並將經過改寫的請求繼續向URI中指定的伺服器處推送。
網關是接收代理,它處於伺服器層之上,在必要時候,它用伺服器可識別的協定來傳遞
請求。
隧道不改變訊息,它只是連線兩端的中繼點。在有中間層(如防火牆)或中間層無法解
析訊息內容的情況下,需要靠隧道技術來幫助通訊穿越中間層。
requestchain-------------------------------------->
UA-----v-----A-----v-----B-----v-----C-----v-----O
<-------------------------------------responsechain
上面的圖形表示在用戶代理和原始伺服器之間有三個中間層(A,B和C)。由圖可見,
請求或回應訊息在整個信息鏈上運行需要通過四個單獨的連線,它與在此之前介紹的簡單情
況是有區別的,而且此區別是十分重要的。因為HTTP通訊選項可以設定成幾種情況,如只
與最近的非隧道鄰居連線、只與信息鏈末端連線、或者可與鏈中全部環節連線等等。雖然上
面的圖是線性的,而實際上每個參與環節都在同時與多方進行通訊活動。例如,B在接受除
A之外其它客戶端請求的同時,向除C之外的其它伺服器推送請求,在這個時刻,它可能
接受到A的請求,並給予處理。
參與通訊的任何一方如果沒有以隧道方式進行工作,必須要藉助內部快取機制來處理請
求,如果鏈上某個參與方碰巧快取了某個請求的回應,那就相應於縮短了請求/回應鏈。下
面的圖例演示了當B快取了從O經由C過來的回應信息,而UA和A沒快取的情況:
requestchain---------->
UA-----v-----A-----v-----B------C------O
<---------responsechain
並非所有的回應都可以被快取,某些請求所包含的修飾符中可能對快取行為進行了特別
指明。一些基於HTTP/1.0的套用使用了啟發式的方法來描述哪些回應可被快取,而哪些則
不可以,但遺憾的是,這些規則並沒有形成標準。
在Internet上,HTTP通訊往往基於TCP/IP的連線方式。預設的連線埠是TCP80[15]口,
但也可以使用其它連線埠。並不排除基於Ineternet上的其它協定或網路協定的HTTP實現方
式,HTTP只是假定傳輸是可靠的,因而任何能提供這種保證的協定都可以被使用。至於
HTTP/1.0請求和回應在數據傳輸過程中的數據結構問題,不在本文討論範圍之內。
實驗室套用除外,當前的做法是客戶端在每次請求之前建立連線,而伺服器端在傳送回
應後關閉此連線。不管客戶端還是伺服器端都應注意處理突發的連線中斷,因為雙方都有可
能因為用戶操作、自動逾時、程式失敗等原因關閉與對方的連線。在這種情況下,不管請求
處於什麼樣的狀態,如單方或雙方同時關閉連線,都會導致當前的請求被終止。
1.4 HTTP and MIME
HTTP/1.0使用了多種結構來定義MIME,詳見RFC1521[5]。附錄C描述了Internet承認的Internet介質類型與mail介質類型的不同工作方式,並給出二者區別的基本解釋。
2. 標誌約定及通用語法
2.1 補充反饋方式(Augmented BNF)
與RFC822[7]很類似,本文對所有機制的說明都是以散文和補充反饋的方式來描述的。對於實現者來說,要想理解這些約定,必須對這些符號很熟悉。補充反饋方式(augmented
BNF)包括下面的結構:
要解釋的名詞=名詞解釋(name=definition)
規則的名字(name)就是它本身(不帶任何尖括弧,“<”,“>”),後面跟個等號=,
然後就是該規則的定義。如果規則需要用多個行來描述,利用空格進行縮進格式排
版。某些基本的規則使用大寫,如SP,LWS,HT,CRLF,DIGIT,ALPHA,等等。定義
中還可以使用尖括弧來幫助理解規則名的使用。
字面意思("literal")
文字的字面意思放在引號中間,除非特別指定,該段文字是大小寫不敏感的。
規則1|規則2(rule1|rule2)
“|”表示其分隔的元素是可選的,比如,“是|否”要選擇‘是’或‘否’。
(規則1 規則2)((rule1rule2))
在圓括弧中的元素表明必選其一。如(元素1(元素2|元素3)元素4)可表明兩
種意思,即“元素1 元素2 元素4”和“元素1 元素3 元素4”
*規則(*rule)
在元素前加星號“*”表示循環,其完整形式是“<n>*<m>元素”,表明元素最少產
生<n>次,最多<m>次。預設值是0到無限,例如,“1*元素”意思是至少有一個,
而“1*2元素”表明允許有1個或2個。
[規則]([rule])
方括弧內是可選元素。如“[元素1 元素2]”與“*1(元素1 元素2)”是一回
事。
N 規則(Nrule)
表明循環的次數:“<n>(元素)”就是“<n>*<n>(元素)”,也就是精確指出<n>
取值。因而,2DIGIT就是2位數字,3ALPHA就是由三個字母組成字元串。
#規則(#rule)
“#”與“*”類似,用於定義元素列表。
完整形式是“<n>#<m>元素”表示至少有<n>個至多有<m>個元素,中間用“,”或
任意數量的空格(LWS-linearWhiteSpace)來分隔,這將使列表非常方便,如“(*LWS
元素*(*LWS","*LWS元素))”就等同於“1#元素”。
空元素在結構中可被任意使用,但不參與元素個數的計數。也就是說,“(元素1),,
(元素2)”僅表示2個元素。但在結構中,應至少有一個非空的元素存在。預設
值是0到無限,即“#(元素)”表示可取任何數值,包括0;而“1#元素”表示至
少有1個;而“1#2元素”表示有1個或2個。
;注釋(;comment)
分號後面是注釋,僅在單行使用。
隱含*LWS(implied*LWS)
本文的語法描述是基於單詞的。除非另有指定,線性空格(LWS)可以兩個鄰近符
號或分隔設定(tspecials)之間任意使用,而不會對整句的意思造成影響。在兩個符號之
間必須有至少一個分隔設定,因為它們也要做為單獨的符號來解釋。實際上,應用程式在
產生HTTP結構時,應當試圖遵照“通常方式”,因為現在的確有些實現方式在通常方
式下無法正常工作。
2.2 基本規則(Basic Rules)
下面的規則將用於本文後面對結構基本解析。US-ASCII編碼字元集定義[17]。
octet=<8-bit的順序數據,即bytes>
CHAR=<US-ASCII字元(取值為0–127的OCTET)>
UPALPHA=<US-ASCII大寫字元"A"到"Z">
LOALPHA=<US-ASCII小寫字元"a"到"z">
ALPHA=UPALPHA|LOALPHA
DIGIT=<US-ASCII數字"0"到"9">
CTL=<US-ASCII控制字元(取值0到31的octet)和DEL(127)>
CR=<US-ASCIICR,回車符carriagereturn(13)>
LF=<US-ASCIILF,換行符linefeed(10)>
SP=<US-ASCIISP,空格space(32)>
HT=<US-ASCIIHT,水平制表符horizontal-tab(9)>
<">=<US-ASCII雙引號標記double-quotemark(34)>
HTTP/1.0規定,除實體主體(Entity-Body,見附錄B容錯套用)外,所有協定元
素的行結束標誌都是CRLF(按位元組順序)。在實體主體內部的行結束標誌定義及
其對應的介質類型定義,見3.6節的描述。
CRLF=CRLF
HTTP/1.0的頭可以折成許多行,只要每個後續行以空格或水平制表符開頭。所有
的線性空格(LWS),同空格(SP)有相同的語義。
LWS=[CRLF]1*(SP|HT)
實際上,有些套用並沒有考慮處理這樣多行的頭,所以從兼容性上考慮,HTTP/1.0
套用最好不要產生折成多行的頭。
TEXT規則只是用於描述訊息解釋器不關心的域的內容及其取值。文本內容可包含
不同於US-ASCII的字元。
TEXT=<除了控制字元(CTLs)之外的任何OCTET,包括LWS>
在標題域中的收件人域如包含US-ASCII字元集以外的字元,這些字元將按照
ISO-8859-1標準來解釋。
十六進制數字型字元在幾個協定元素中到。
HEX="A"|"B"|"C"|"D"|"E"|"F"
|"a"|"b"|"c"|"d"|"e"|"f"|DIGIT
許多HTTP/1.0頭域的內容由被LWS分隔的單詞或特殊字元組成,這些特殊字元
必須置於引號中間的字元串內,作為參數值使用。
Word=符號(token)|被引號引起來的字元串
token=1*<除控制字元(CTLs)或tspecials之外的任意字元>
tspecials="("|")"|"<"|">"|"@"
|","|";"|":"|"\"|<">
|"/"|"["|"]"|"?"|"="
|"{"|"}"|SP|HT
在HTTP頭域中可用括弧表示注釋文字。注釋只允許寫在包含注釋的域,做為域值
定義的一部分。在除此之外其它域中,括弧將被視為域值。
comment="("*(ctext|comment)")"
ctext=<除圓括弧外的任何TEXT>
被雙引號圈中的文本字元串將被視為一個單詞。
quoted-string=(<">*(qdtext)<">)
qdtext=<除了雙引號及控制字元之外的任何字元,包括LWS>
在HTTP/1.0中不允許使用後斜線“\”來引用單字元。
3. 協定參數(Protocol Parameters)
3.1 HTTP版本(HTTP Version)
HTTP採用主從(<major>.<minor>)數字形式來表示版本。協定的版本政策傾向於讓發送方表明其訊息的格式及功能,而不僅僅為了獲得通訊的特性,這樣做的目的是為了與更高
版本的HTTP實現通訊。只增加擴展域的值或增加了不影響通訊行為的訊息組件都不會導致
版本數據的變化。當協定訊息的主要解析算法沒變,而訊息語法及傳送方的隱含功能增加了,
將會導致從版本號(<minor>)增加;當協定中訊息的格式變化了,主版本號(<major>)也
將發生改變。
HTTP訊息的版本由訊息第一行中的HTTP版本域來表示。如果訊息中的協定版本沒有
指定,接收方必須假定它是符合HTTP/0.9的簡單標準。
HTTP-Version="HTTP""/"1*DIGIT"."1*DIGIT
注意,主從版本應當被看作單獨的整數,因為它們都有可能增加,從而超過一位整
數。因而,HTTP/2.4比HTTP/2.13版本低,而HTTP/2.13又比HTTP/12.3版本低。
版本號前面的0將被接收方忽略,而在傳送方處也不應產生。
本文檔定義了HTTP協定的0.9及1.0版本。傳送完整請求(Full-Request)及完整
回應(Full-Response)訊息的套用必須指明HTTP的版本為“HTTP/1.0”。
HTTP/1.0伺服器必須:
o識別HTTP/0.9及HTTP/1.0請求命令中的請求佇列(Request-Line)的格式。
o理解任何HTTP/0.9及HTTP/1.0中的合法請求格式。
o使用與客戶端相同版本的協定進行訊息回應。
HTTP/1.0客戶端必須:
o識別HTTP/1.0回應中狀態佇列(Status-Line)的格式。
o理解HTTP/0.9及HTTP/1.0中合法回應的格式。
當代理及網關收到與其自身版本不同的HTTP請求時,必須小心處理請求的推送,因為
協定版本表明傳送方的能力,代理或網關不應發出高於自身版本的訊息。如果收到高版本的
請求,代理或網關必須降低該請求的版本,並回應一個錯誤。而低版本的請求也應在被推送
前升級。
代理或網關回應請求時必須遵照前面列出的規定。
3.2 統一資源標識(URI)
URI有許多名字,如WWW地址、通用檔案標識(UniversalDocumentIdentifiers)、通用資源標識(UniversalResourceIdentifiers[2]),以及最終的統一資源定位符(Uniform
ResourceLocators(URL)[4])和統一資源名(URN)。在涉及HTTP以前,URI用簡單格式
的字元串描述-名字、位置、或其它特性,如網路資源。
3.2.1 一般語法(General Syntax)
在HTTP中URI可以用絕對形式表示,也可用相對於某一基本URI[9]的形式表示,具體取決於它們的使用方式。這兩種形式的不同在於絕對URI總是以方法名稱後跟“:”開頭。
URI=(absoluteURI|relativeURI)["#"fragment]
absoluteURI=scheme":"*(uchar|reserved)
relativeURI=net_path|abs_path|rel_path
net_path="//"net_loc[abs_path]
abs_path="/"rel_path
rel_path=[path][";"params]["?"query]
path=fsegment*("/"segment)
fsegment=1*PCHAR
segment=*pchar
params=param*(";"param)
param=*(pchar|"/")
scheme=1*(ALPHA|DIGIT|" "|"-"|".")
net_loc=*(pchar|";"|"?")
query=*(uchar|reserved)
fragment=*(uchar|reserved)
pchar=uchar|":"|"@"|"&"|"="|" "
uchar=unreserved|escape
unreserved=ALPHA|DIGIT|safe|extra|national
escape="%"HEXHEX
reserved=";"|"/"|"?"|":"|"@"|"&"|"="|" "
extra="!"|"*"|"'"|"("|")"|","
safe="$"|"-"|"_"|"."
unsafe=CTL|SP|<">|"#"|"%"|"<"|">"
national=<anyOCTETexcludingALPHA,DIGIT,
reserved,extra,safe,andunsafe>
權威的URL語法及語義信息請參見RFC1738[4]和RFC1808[9]。上面所提到的BNF中
包括了合法URL中不允許出現的符號(RFC1738),因為HTTP伺服器並沒有限制為只能用
非保留字元集中的字元來表示地址路徑,而且HTTP代理也可能接收到RFC1738沒有定義
的URI請求。
3.2.2 http URL
“http”表示要通過HTTP協定來定位網路資源。本節定義了HTTPURL的語法和語義。http_URL="http:""//"host[":"port][abs_path]
host=<合法的Internet主機域名或IP位址(用十進制數及點組成)
,見RFC1123,2.1節定義>
port=*DIGIT
如是連線埠為空或沒指定,則預設為80連線埠。對於絕對路徑的URI來說,擁有被請求的
資源的伺服器主機通過偵聽該連線埠的TCP連線來接收該URI請求。如果URL中沒有給出
絕對路徑,要作為請求URI(參見5.1.2節)使用,必須以“/”形式給出。
注意:雖然HTTP協定獨立於傳輸層協定,httpURL只是標識資源的TCP位置,而對
於非TCP資源來說,必須用其它的URI形式來標識。
規範的HTTPURL形式可通過將主機中的大寫字元轉換成小寫(主機名是大小寫敏感
的)來獲得。如果連線埠是80,去掉冒號及連線埠號,並將空路徑替換成“/”。
3.3 Date/Time 格式(Date/Time Formats)
出於歷史原因,HTTP/1.0套用允許三種格式來表示時間戳:Sun,06Nov199408:49:37GMT;RFC822,updatedbyRFC1123
Sunday,06-Nov-9408:49:37GMT;RFC850,obsoletedbyRFC1036
SunNov608:49:371994;ANSIC'sasctime()format
第一種格式是首選的Internet標準格式,表示方法長度固定(RFC1123[6])。第二種格
式在普通情況下使用,但是它是基於已經廢棄的RFC850[10]中的日期格式,而且年不是用
四位數字表示的。HTTP/1.0客戶端及伺服器端在解析日期時可識別全部三種格式,但是它
們不可以產生第三種時間格式(asctime)。
注意:對於接收到由非HTTP套用產生的日期數據時,提倡對接收到的日期值進行填充。
這樣做是因為,在某些時候,代理或網關可能通過SMTP或NNTP來獲取或傳送訊息。
所有的HTTP/1.0date/timp時間戳必須用世界時間(UniversalTime,UT),即格林威治
時間來表示(GreenwichMeanTime,GMT),沒有任何修改的餘地。前面的兩種格式用了
“GMT”表示時區,在讀ASC表示的時間時,也應假定是這個時區。
HTTP-date=rfc1123-date|rfc850-date|asctime-date
rfc1123-date=wkday","SPdate1SPtimeSP"GMT"
rfc850-date=weekday","SPdate2SPtimeSP"GMT"
asctime-date=wkdaySPdate3SPtimeSP4DIGIT
date1=2DIGITSPmonthSP4DIGIT
;daymonthyear(e.g.,02Jun1982)
date2=2DIGIT"-"month"-"2DIGIT
;day-month-year(e.g.,02-Jun-82)
date3=monthSP(2DIGIT|(SP1DIGIT))
;monthday(e.g.,Jun2)
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要求只能在協定流中使用data/time時間戳格式,不要求客戶端及服務
器端在用戶描述、請求登錄等情況下使用這類格式。
3.4 字元集(Character Sets)
HTTP所使用的字元集定義和描述MIME時用的相同:本文檔用字元集(characterset)來指明利用一個或多個表將順序位元組轉換成順序字
符的方法。注意,不需要其它方向的無條件轉換,因為不是所有的字元都可以用給
定字元集來表示,同時,一個字元集也可能提供一種以上的位元組順序來表示一種特
殊的字元。這種定義傾向於允許不同類型的字元編碼通過簡單的單表映射來實現,
如,從表US-ASCII切換到複雜表如ISO2202。實際上,與MIME字元集名相關的
定義必須完整指定從位元組到字元的映射,特別是不允許通過利用外部配置信息來確
定精確的映射。
注意:術語字元集(characterset)歸於字元編碼(characterencoding)。事實上,
由於HTTP與MIME共同使用同樣的註冊,所以其術語也應一致。
HTTP字元集由大小寫敏感的符號組成。全部的符號定義參見IANA字元集註冊
[15]。因為註冊處不會為每個字元集單獨定義一套符號,所以我們在這看到的字元
集名大多是與HTTP實體使用相關的。這些在RFC1521[5]中註冊的字元集,即
US-ASCII[17]及ISO-8859[18]字元集,還有一些其它字元集被強烈建議在MIME
字元集參數內部使用。
charset="US-ASCII"
|"ISO-8859-1"|"ISO-8859-2"|"ISO-8859-3"
|"ISO-8859-4"|"ISO-8859-5"|"ISO-8859-6"
|"ISO-8859-7"|"ISO-8859-8"|"ISO-8859-9"
|"ISO-2022-JP"|"ISO-2022-JP-2"|"ISO-2022-KR"
|"UNICODE-1-1"|"UNICODE-1-1-UTF-7"|"UNICODE-1-1-UTF-8"
|token
雖然HTTP允許使用專用符號做為字元集值,但是任何在IANA字元集註冊表[15]
中有預定義值的符號都必須表明其所屬的字元集。套用應當將其對字元集的使用限
制在IANA註冊表規定的範圍之內。
實體主體的字元集如果屬於US-ASCII或ISO-8859-1字元集,則勿需標記,否則,
應當用主體字元編碼方式中的最基本命名來標記。
3.5 內容解碼(Content Codings)
內容解碼值用於指示對資源進行的編碼轉換。內容解碼主要用於將經過壓縮、加密等操作的檔案進行還原,使其保持其原來的介質類型。典型情況下,經過編碼保存的資源只能經
過解碼或類似的操作才能還原。
content-coding="x-gzip"|"x-compress"|token
注意:出於對未來兼容性的考慮,HTTP/1.0套用應將"gzip"和"compress"分別與
"x-gzip"和"x-compress"對應起來。
所有的內容解碼值都是大小寫敏感的。HTTP/1.0在內容編碼(10.3節)頭域中使用內
容解碼值。雖然該值描述的是內容解碼,但更為重要的是,它指明了應當用什麼機制來進行
解碼。注意,單獨的程式可能有能力實現對多種格式編碼的解碼。
在這段文字中,提到了兩個值:
x-gzip
檔案壓縮程式"gzip"(GNUzip,由Jean-loupGailly開發)的編碼格式。該格式屬於
典型的帶有32位CRC校驗的Lempel-Ziv解碼(LZ77)。
x-compress
檔案壓縮程式"compress"的編碼格式,該格式適用於LZW(Lempel-Ziv-Welch)譯
碼。
注意:用程式名來標識編碼格式的做法不是很理想,在將來可能不會繼續這樣做。現在
之所以這樣做是出於歷史的原因,並非良好的設計。
3.6 介質類型(Media Types)
HTTP在Content-Typeheader域(10.5節)中使用Internet介質類型[13],用以提供開放的可擴展的數據類型。
media-type=type"/"subtype*(";"parameter)
type=token
subtype=token
參數可參照屬性/值對的方式,用類型/子類型的格式來寫。
Parameter=attribute"="value
Attribute=token
Value=token|quoted-string
其中,類型、子類型、參數屬性名是大小寫敏感的。而參數值不一定是大小寫敏感的,
這得看參數名的語法而定。在類型和子類型、屬性名和屬性值之間不能有LWS(空格)。當
接收到不能識別的介質類型的參數時,用戶代理應當忽略它們。
一些老的HTTP套用不能識別介質類型參數,所以HTTP/1.0的應用程式只能在定義消
息內容時使用介質參數。
介質參數(Media-type)值用Internet授權分配數字(InternetAssignedNumber
Authority,IANA[15])註冊。介質類型註冊過程請參見RFC1590[13]。不鼓勵使用未註冊
的介質類型。
3.6.1標準及文本預設(CanonicalizationandTextDefaults)
Internet介質類型是用規範形式註冊的。一般來說,在通過HTTP協定傳輸實體主體
(Entity-Body)之前,必須先將其表示成適當的規範格式。如果主體用使用了一種
Content-Encoding進行編碼,下面的數據在編碼前必須轉換成規範形式:
"text"類型的介質子類型在規範形式中使用CRLF做為文本行中斷。實際上,為和實體
主體(Entitybody)內的使用方式保持一致,HTTP允許傳輸純以CR或LF單獨表示行中斷
的文本介質。HTTP應用程式必須將其通過HTTP方式接收到的文本介質中的CRLF、CR、
LF看做是行中斷符。
另外,如果文本介質的字元集沒有使用位元組13和10做為CR和LF,象一些多位元組字
符集,HTTP允許使用該字元集指定的任何順序的位元組替代CR和LF做為行中斷,這種行
中斷的靈活運用方式僅可於實體主體(Entity-Body)中。一個純CR或LF不應在任何HTTP
控制結構(如標題域-headerfield和多塊分界線-multipartboundaries)中替代CRLF。
參數"charset"在定義數據的字元集(3.4節)時,與一些介質類型一起使用。當傳送方
沒有顯式給出字元參數時,HTTP在接收時將"text"的介質子類型定義為預設
值"ISO-8859-1"。"ISO-8859-1"字元集或其子集以外的數據必須要標記其相應的字元集值,
這樣可以保證接收方能正確地對其進行解析。
注意:許多當前HTTP伺服器提供的數據使用"ISO-8859-1"以外的其它字元集,而且也
沒有正確的進行標記,這種工作方式限制了互操作性,建議不要採用。做為一種補救方法,
一些HTTP用戶代理提供了配置選項,使用戶可以在字元集參數沒指定的情況下,自行更改
預設的介質類型解釋方式。
3.6.2多部分類型(MultipartTypes)
MIME提供了多部分("multipart")類型的數字――在一個單獨的訊息實體主體
(Entity-Body)內可以封裝幾個實體(entities)。雖然用戶代理可能需要了解每種類型,從
而可以正確解釋每部分主體的意圖,但是在IANA[15]的多部分類型(multiparttypes)註冊
中卻找不到專為HTTP/1.0所指定的內容。HTTP用戶代理只得自己來做接收多部分類型的
工作,其過程和行為與MIME用戶代理是相同或相似的。HTTP伺服器不應假定HTTP客戶
端都有能力處理多部分類型。
所有的多部分類型都使用通用的語法,而且必須在介質類型值部分包括邊界參數
(boundaryparameter)。訊息的主體是其自身,做為協定元素,它必須只使用CRLF做為段
間(body-parts)的行中斷符。多段主體(Multipartbody-parts)中可能包括對各段有重要意
義的HTTP標題域。
3.7 產品標識(Product Tokens)
是通訊應用程式用來標識其自身的一個簡單符號,常和任意字母及版本描述一起使用。大多數產品標識也將其產品的重要組成部分的版本號一起列出,中間用空格分隔。
按慣例,在標識應用程式時,組件以其重要性順序排列。
Product=token["/"product-version]
product-version=token
例如:
User-Agent:CERN-LineMode/2.15libwww/2.17b3
Server:Apache/0.8.4
產品標識應當短小,因而禁止利用該域填寫廣告或其它無關信息。雖然任何符號字元都
可能出現在產品版本中,該符號應當只用於做版本定義,也就是說,同一個產品的連續版本
之間只能通過產品版本值進行區分。
4. HTTP 訊息(HTTP Message)
4.1 訊息類型(Message Types)
HTTP訊息由客戶端到伺服器的請求和由伺服器到客戶端的回應組成。HTTP-message=Simple-Request;HTTP/0.9messages
|Simple-Response
|Full-Request;HTTP/1.0messages
|Full-Response
完整的請求(Full-Request)和完整的回應(Full-Response)都使用RFC822[7]中實體傳
輸部分規定的訊息格式。兩者的訊息都可能包括標題域(headers,可選)、實體主體(entity
body)。實體主體與標題間通過空行來分隔(即CRLF前沒有內容的行)。
Full-Request=Request-Line;Section5.1
*(General-Header;Section4.3
|Request-Header;Section5.2
|Entity-Header);Section7.1
CRLF
[Entity-Body];Section7.2
Full-Response=Status-Line;Section6.1
*(General-Header;Section4.3
|Response-Header;Section6.2
|Entity-Header);Section7.1
CRLF
[Entity-Body];Section7.2
簡單請求(Simple_Request)與簡單回應(Simple-Response)不允許使用任何標題信息,
並限制只能使用唯一的請求方法(GET)
Simple-Request="GET"SPRequest-URICRLF
Simple-Response=[Entity-Body]
不提倡使用簡單方式請求格式,因為它防止了伺服器在接到簡單請求時對返回實體的介
質類型進行驗證。
4.2 訊息標題(Message Headers)
HTTP標題域,包括主標題(General-Header,4.3節)、請求標題(Request-Header,5.2節)、回應標題(Response-Header,6.2節)及實體標題(Entity-Header,7.1節),都遵照RFC822-3.1
節[7]給出的通用格式定義。每個標題域由後緊跟冒號的名字,單空格(SP),字元及域值組
成。域名是大小寫敏感的。雖然不提倡,標題域還是可以擴展成多行使用,只要這些行以一
個以上的SP或HT開頭就行。
HTTP-header=field-name":"[field-value]CRLF
field-name=token
field-value=*(field-content|LWS)
field-content=<theOCTETsmakingupthefield-value
andconsistingofeither*TEXTorcombinations
oftoken,tspecials,andquoted-string>
標題域接收的順序並不重要,但良好的習慣是,先傳送主標題,然後是請求標題或回應
標題,最後是實體標題。
若且唯若標題域的全部域值都用逗號分隔的列表示時(即,#(值)),多個有相同域名
的HTTP標題域才可以表示在一個訊息里。而且必須能在不改變訊息語法的前提下,將並發
的域值加到第一個值後面,之間用逗號分隔,最終能將多個標題域結合成“域名:域值”對。
4.3 普通標題域(General Header Fields)
有幾種標題域是請求與回應都要使用的,但並不用於被傳輸的實體。這些標題只用於被傳輸的訊息。
General-Header=Date;Section10.6
|Pragma;Section10.12
普通標題域名稱只有在與協定版本的變化結合起來後,才能進行可靠的擴展。實際上,
新的或實驗中的標題域只要能被通訊各方識別,其語法就可使用,而無法識別的標題域都將
被視為實體域。
5. 請求(Request)
從客戶端到伺服器端的請求訊息包括,訊息首行中,對資源的請求方法、資源的標識符及使用的協定。考慮到局限性更大的HTTP/0.9的向後兼容問題,有兩種合法的HTTP請求
格式:
Request=Simple-Request|Full-Request
Simple-Request="GET"SPRequest-URICRLF
Full-Request=Request-Line;Section5.1
*(General-Header;Section4.3
|Request-Header;Section5.2
|Entity-Header);Section7.1
CRLF
[Entity-Body];Section7.2
如果HTTP/1.0伺服器收到簡單請求,它必須回應一個HTTP/0.9格式的簡單回應。
HTTP/1.0的客戶端有能力接收完整回應,但不能產生簡單請求。
5.1 請求行(Request-Line)
請求行以一個方法符號開頭,跟在請求URI及協定版本的後面,以CRLF為結尾。該元素用空格SP分隔。除了最後的CRLF,不允許出現單獨的CR或LF符。
Request-Line=MethodSPRequest-URISPHTTP-VersionCRLF
注意,簡單請求與完整請求的請求佇列之間的區別在於是否有HTTP版本域和是否可以
使用除GET以外的其它方法。
5.1.1方法(Method)
方法代號指明了將要以何種方式來訪問由請求URI指定的資源。方法是大小寫敏感的。
Method="GET" ;Section8.1
|"HEAD";Section8.2
|"POST";Section8.3
|extension-method
extension-method=token
可以訪問指定資源的方法列表是可以動態變化的;如果用某種方法訪問資源被拒絕,客
戶端可從回應中的返回碼得到通知。伺服器端在方法無法識別或沒有實現時,返回狀態代碼
501(尚未沒實現)。
這些方法被HTTP/1.0的應用程式普遍使用,完整定義請參見第8節。
5.1.2請求URI(Request-URI)
請求URI就是統一資源標識符(3.2節),用來標識要請求的資源。
Request-URI=absoluteURI|abs_path
上面兩種請求URI方式可根據實際的請求方式選擇使用。
絕對URI(absoluteURI)格式只在代理(proxy)在產生請求時使用。代理的責任是將
請求向前推送,並將回應返回。如果請求是GET或HEAD方式,而且之前的回應被快取,
如果代理忽略標題域的過期信息限制,它可能使用快取中的訊息。注意,代理可能將請求推
送至另外一個代理,也可將請求直接送至絕對URI中所指定的目的伺服器。為了避免請求
循環,代理必須能夠識別它的所有伺服器名,包括別名、本地變數及數字形式的IP位址。
下面是一個請求佇列的例子:
GEThttp://www.w3.org/pub/WWW/TheProject.htmlHTTP/1.0
最普通的請求URI形式就是原始伺服器或網關用來標識資源的方式。在這種方式下,
只有給出絕對路徑的URI才能被傳輸(見3.2.1節)。例如,如客戶端希望直接從原始服務
器上接收資源,它們將產生一個與主機"www.w3.org"80連線埠的TCP連線,並在完整請求之
後傳送下面的命令:
GET/pub/WWW/TheProject.htmlHTTP/1.0
注意絕對路徑不可以為空,如果URI中沒有內容,也必須加上一個"/"(serverroot)。
請求URI以編碼字元串方式傳輸,有些字元可能在傳輸過程中被轉義(escape),如變
成“%HEXHEX”形式。具體這方面內容請參見RFC1738[4]。原始伺服器在正確解釋請求
之前必須對請求URI進行解碼。
5.2 請求標題域(Request Header Fields)
請求標題域允許客戶端向伺服器端傳遞該請求的附加信息及客戶端信息。該域做為請求的修飾部分,遵照程式語言程式調用參數的語法形式。
Request-Header=Authorization;Section10.2
|From;Section10.8
|If-Modified-Since;Section10.9
|Referer;Section10.13
|User-Agent;Section10.15
請求標題域名只有在與協定版本的變化結合起來後,才能進行可靠的擴展。實際上,新
的或實驗中的標題域只要能被通訊各方識別,其語法就可使用,而無法識別的標題域都將被
視為實體域。
6. 回應(Response)
在接收、解釋請求訊息後,伺服器端返回HTTP回應訊息。Response=Simple-Response|Full-Response
Simple-Response=[Entity-Body]
Full-Response=Status-Line;Section6.1
*(General-Header;Section4.3
|Response-Header;Section6.2
|Entity-Header);Section7.1
CRLF
[Entity-Body];Section7.2
當請求是HTTP/0.9的或者伺服器端只支持HTTP/0.9時,只能以Simple-Response方式
回應。如果客戶端傳送HTTP/1.0完整請求後,接收到的回應不是以狀態行(Status-Line)
開頭的,客戶端將其視為簡單回應,並相應對其進行分析。注意,簡單請求只包括實體主體,
它在伺服器端關閉連線時終止。
6.1 狀態行(Status-Line)
完整回應訊息的第一行就是狀態行,它依次由協定版本、數字形式的狀態代碼、及相應的詞語文本組成,各元素間以空格(SP)分隔,除了結尾的CRLF外,不允許出現單獨的
CR或LF符。
Status-Line=HTTP-VersionSPStatus-CodeSPReason-PhraseCRLF
狀態行總是以協定版本及狀態代碼開頭,如:
"HTTP/"1*DIGIT"."1*DIGITSP3DIGITSP
(如,"HTTP/1.0200")。
這種表示方式並不足以區分完整請求和簡單請求。簡單回應可能允許這種表達式出現在
實體主體的開始部分,但會引起訊息的誤解。因為大多數HTTP/0.9的伺服器都只能回
應"text/html"類型,在這種情況下,不可能產生完整的回應。
6.1.1狀態代碼和原因分析(StatusCodeandReason
Phrase)
狀態代碼(Status-Code)由3位數字組成,表示請求是否被理解或被滿足。原因分析是
用簡短的文字來描述狀態代碼產生的原因。狀態代碼用來支持自動操作,原因分析是為人類
用戶準備的。客戶端不需要檢查或顯示原因分析。
狀態代碼的第一位數字定義了回應的類別,後面兩位數字沒有具體分類。首位數字有5
種取值可能:
o1xx::保留,將來使用。
o2xx:成功-操作被接收、理解、接受(received,understood,accepted)。
o3xx:重定向(Redirection)-要完成請求必須進行進一步操作。
o4xx:客戶端出錯-請求有語法錯誤或無法實現。
o5xx:伺服器端出錯-伺服器無法實現合法的請求。
HTTP/1.0的狀態代碼、原因解釋在下面給出。下面的原因解釋只是建議採用,可任意
更改,而不會對協定造成影響。完整的代碼定義在第9節。
Status-Code="200";OK
|"201";Created
|"202";Accepted
|"204";NoContent
|"301";Movedpermanently
|"302";MovedTemporarily
|"304";NotModified
|"400";BadRequest
|"401";Unauthorized
|"403";Forbidden
|"404";NotFound
|"500";InternalServerError
|"501";NotImplemented
|"502";BadGateway
|"503";Serviceunavailable
|extension-code
extension-code=3DIGIT
&n