3. 協(xié)議參數(shù)(Protocol Parameters)
3.1 HTTP版本(HTTP Version)
HTTP采用主從(<major>.<minor>)數(shù)字形式來(lái)表示版本,。協(xié)議的版本政策傾向于讓發(fā)
送方表明其消息的格式及功能,,而不僅僅為了獲得通訊的特性,這樣做的目的是為了與更高
版本的HTTP實(shí)現(xiàn)通訊,。只增加擴(kuò)展域的值或增加了不影響通訊行為的消息組件都不會(huì)導(dǎo)致
版本數(shù)據(jù)的變化,。當(dāng)協(xié)議消息的主要解析算法沒(méi)變,,而消息語(yǔ)法及發(fā)送方的隱含功能增加了,
將會(huì)導(dǎo)致從版本號(hào)(<minor>)增加,;當(dāng)協(xié)議中消息的格式變化了,,主版本號(hào)(<major>)也
將發(fā)生改變。
HTTP消息的版本由消息第一行中的HTTP版本域來(lái)表示,。如果消息中的協(xié)議版本沒(méi)有
指定,,接收方必須假定它是符合HTTP/0.9的簡(jiǎn)單標(biāo)準(zhǔn)。
HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
注意,,主從版本應(yīng)當(dāng)被看作單獨(dú)的整數(shù),,因?yàn)樗鼈兌加锌赡茉黾樱瑥亩^(guò)一位整
數(shù),。因而,,HTTP/2.4比HTTP/2.13版本低,而HTTP/2.13又比HTTP/12.3版本低,。
版本號(hào)前面的0將被接收方忽略,,而在發(fā)送方處也不應(yīng)產(chǎn)生。
本文檔定義了HTTP協(xié)議的0.9及1.0版本,。發(fā)送完整請(qǐng)求(Full-Request)及完整
回應(yīng)(Full-Response)消息的應(yīng)用必須指明HTTP的版本為“HTTP/1.0”,。
HTTP/1.0服務(wù)器必須:
o識(shí)別HTTP/0.9及HTTP/1.0請(qǐng)求命令中的請(qǐng)求隊(duì)列(Request-Line)的格式。
o理解任何HTTP/0.9及HTTP/1.0中的合法請(qǐng)求格式,。
o 使用與客戶端相同版本的協(xié)議進(jìn)行消息回應(yīng),。
HTTP/1.0 客戶端必須:
o 識(shí)別HTTP/1.0回應(yīng)中狀態(tài)隊(duì)列(Status-Line)的格式。
o 理解HTTP/0.9及HTTP/1.0中合法回應(yīng)的格式,。
當(dāng)代理及網(wǎng)關(guān)收到與其自身版本不同的HTTP請(qǐng)求時(shí),,必須小心處理請(qǐng)求的推送,因?yàn)?/font>
協(xié)議版本表明發(fā)送方的能力,,代理或網(wǎng)關(guān)不應(yīng)發(fā)出高于自身版本的消息,。如果收到高版本的
請(qǐng)求,代理或網(wǎng)關(guān)必須降低該請(qǐng)求的版本,,并回應(yīng)一個(gè)錯(cuò)誤,。而低版本的請(qǐng)求也應(yīng)在被推送
前升級(jí)。
代理或網(wǎng)關(guān)回應(yīng)請(qǐng)求時(shí)必須遵照前面列出的規(guī)定,。
3.2 統(tǒng)一資源標(biāo)識(shí)(Uniform Resource Identifiers)
URI有許多名字,如WWW地址,、通用文件標(biāo)識(shí)(Universal Document Identifiers),、通
用資源標(biāo)識(shí)(Universal Resource Identifiers [2]),以及最終的統(tǒng)一資源定位符(Uniform
Resource Locators (URL) [4])和統(tǒng)一資源名(URN),。在涉及HTTP以前,,URI用簡(jiǎn)單格式
的字符串描述-名字,、位置、或其它特性,,如網(wǎng)絡(luò)資源,。
3.2.1 一般語(yǔ)法(General Syntax)
在HTTP中URI可以用絕對(duì)形式表示,也可用相對(duì)于某一基本URI[9]的形式表示,,具
體取決于它們的使用方式,。這兩種形式的不同在于絕對(duì)URI總是以方法名稱(chēng)后跟“:”開(kāi)頭。
URI = ( absoluteURI | relativeURI ) [ "#" fragment ]
absoluteURI = scheme ":" *( uchar | reserved )
relativeURI = net_path | abs_path | rel_path
net_path = "http://" 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 = "%" HEX HEX
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
extra = "!" | "*" | "'" | "(" | ")" | ","
safe = "$" | "-" | "_" | "."
unsafe = CTL | SP | <"> | "#" | "%" | "<" | ">"
national = <any OCTET excluding ALPHA, DIGIT,
reserved, extra, safe, and unsafe>
權(quán)威的URL語(yǔ)法及語(yǔ)義信息請(qǐng)參見(jiàn)RFC1738[4]和RFC1808[9],。上面所提到的BNF中
包括了合法URL中不允許出現(xiàn)的符號(hào)(RFC1738),,因?yàn)?/font>HTTP服務(wù)器并沒(méi)有限制為只能用
非保留字符集中的字符來(lái)表示地址路徑,而且HTTP代理也可能接收到RFC1738沒(méi)有定義
的URI請(qǐng)求,。
3.2.2 http URL
“http”表示要通過(guò)HTTP協(xié)議來(lái)定位網(wǎng)絡(luò)資源,。本節(jié)定義了HTTP URL的語(yǔ)法和語(yǔ)義。
http_URL = "http:" "http://" host [ ":" port ] [ abs_path ]
host = <合法的Internet主機(jī)域名或IP地址(用十進(jìn)制數(shù)及點(diǎn)組成)
,,見(jiàn)RFC1123,,2.1節(jié)定義>
port = *DIGIT
如是端口為空或沒(méi)指定,則缺省為80端口,。對(duì)于絕對(duì)路徑的URI來(lái)說(shuō),,擁有被請(qǐng)求的
資源的服務(wù)器主機(jī)通過(guò)偵聽(tīng)該端口的TCP連接來(lái)接收該URI請(qǐng)求。如果URL中沒(méi)有給出
絕對(duì)路徑,,要作為請(qǐng)求URI(參見(jiàn)5.1.2節(jié))使用,,必須以“/”形式給出。
注意:雖然HTTP協(xié)議獨(dú)立于傳輸層協(xié)議,,http URL只是標(biāo)識(shí)資源的TCP位置,,而對(duì)
于非TCP資源來(lái)說(shuō),必須用其它的URI形式來(lái)標(biāo)識(shí),。
規(guī)范的HTTP URL形式可通過(guò)將主機(jī)中的大寫(xiě)字符轉(zhuǎn)換成小寫(xiě)(主機(jī)名是大小寫(xiě)敏感
的)來(lái)獲得,。如果端口是80,去掉冒號(hào)及端口號(hào),,并將空路徑替換成“/”,。
3.3 Date/Time 格式(Date/Time Formats)
出于歷史原因,HTTP/1.0應(yīng)用允許三種格式來(lái)表示時(shí)間戳:
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標(biāo)準(zhǔn)格式,,表示方法長(zhǎng)度固定(RFC1123[6]),。第二種格
式在普通情況下使用,但是它是基于已經(jīng)廢棄的RFC850[10]中的日期格式,,而且年不是用
四位數(shù)字表示的,。HTTP/1.0 客戶端及服務(wù)器端在解析日期時(shí)可識(shí)別全部三種格式,但是它
們不可以產(chǎn)生第三種時(shí)間格式(asctime) 。
注意:對(duì)于接收到由非HTTP應(yīng)用產(chǎn)生的日期數(shù)據(jù)時(shí),,提倡對(duì)接收到的日期值進(jìn)行填充,。
這樣做是因?yàn)椋谀承r(shí)候,,代理或網(wǎng)關(guān)可能通過(guò)SMTP或NNTP來(lái)獲取或發(fā)送消息,。
所有的HTTP/1.0 date/timp時(shí)間戳必須用世界時(shí)間(Universal Time,UT),,即格林威治
時(shí)間來(lái)表示(Greenwich Mean Time,,GMT),沒(méi)有任何修改的余地,。前面的兩種格式用了
“GMT”表示時(shí)區(qū),,在讀ASC表示的時(shí)間時(shí),也應(yīng)假定是這個(gè)時(shí)區(qū),。
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要求只能在協(xié)議流中使用data/time時(shí)間戳格式,,不要求客戶端及服務(wù)
器端在用戶描述、請(qǐng)求登錄等情況下使用這類(lèi)格式,。
3.4 字符集(Character Sets)
HTTP所使用的字符集定義和描述MIME時(shí)用的相同:
本文檔用字符集(character set)來(lái)指明利用一個(gè)或多個(gè)表將順序字節(jié)轉(zhuǎn)換成順序字
符的方法,。注意,不需要其它方向的無(wú)條件轉(zhuǎn)換,,因?yàn)椴皇撬械淖址伎梢杂媒o
定字符集來(lái)表示,,同時(shí),一個(gè)字符集也可能提供一種以上的字節(jié)順序來(lái)表示一種特
殊的字符,。這種定義傾向于允許不同類(lèi)型的字符編碼通過(guò)簡(jiǎn)單的單表映射來(lái)實(shí)現(xiàn),,
如,從表US-ASCII切換到復(fù)雜表如ISO2202,。實(shí)際上,,與MIME字符集名相關(guān)的
定義必須完整指定從字節(jié)到字符的映射,,特別是不允許通過(guò)利用外部配置信息來(lái)確
定精確的映射,。
注意:術(shù)語(yǔ)字符集(character set)歸于字符編碼(character encoding)。事實(shí)上,,
由于HTTP與MIME共同使用同樣的注冊(cè),,所以其術(shù)語(yǔ)也應(yīng)一致,。
HTTP字符集由大小寫(xiě)敏感的符號(hào)組成。全部的符號(hào)定義參見(jiàn)IANA字符集注冊(cè)
[15],。因?yàn)樽?cè)處不會(huì)為每個(gè)字符集單獨(dú)定義一套符號(hào),,所以我們?cè)谶@看到的字符
集名大多是與HTTP實(shí)體使用相關(guān)的。這些在RFC 1521 [5] 中注冊(cè)的字符集,,即
US-ASCII [17] 及ISO-8859 [18]字符集,,還有一些其它字符集被強(qiáng)烈建議在MIME
字符集參數(shù)內(nèi)部使用。
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允許使用專(zhuān)用符號(hào)做為字符集值,但是任何在IANA字符集注冊(cè)表[15]
中有預(yù)定義值的符號(hào)都必須表明其所屬的字符集,。應(yīng)用應(yīng)當(dāng)將其對(duì)字符集的使用限
制在IANA注冊(cè)表規(guī)定的范圍之內(nèi)。
實(shí)體主體的字符集如果屬于US-ASCII 或ISO-8859-1字符集,,則勿需標(biāo)記,,否則,
應(yīng)當(dāng)用主體字符編碼方式中的最基本命名來(lái)標(biāo)記,。
3.5 內(nèi)容譯碼(Content Codings)
內(nèi)容譯碼值用于指示對(duì)資源進(jìn)行的編碼轉(zhuǎn)換,。內(nèi)容譯碼主要用于將經(jīng)過(guò)壓縮、加密等操
作的文件進(jìn)行還原,,使其保持其原來(lái)的介質(zhì)類(lèi)型,。典型情況下,經(jīng)過(guò)編碼保存的資源只能經(jīng)
過(guò)解碼或類(lèi)似的操作才能還原,。
content-coding = "x-gzip" | "x-compress" | token
注意:出于對(duì)未來(lái)兼容性的考慮,,HTTP/1.0應(yīng)用應(yīng)將"gzip" 和"compress" 分別與
"x-gzip"和"x-compress"對(duì)應(yīng)起來(lái)。
所有的內(nèi)容譯碼值都是大小寫(xiě)敏感的,。HTTP/1.0在內(nèi)容編碼(10.3節(jié))頭域中使用內(nèi)
容譯碼值,。雖然該值描述的是內(nèi)容譯碼,但更為重要的是,,它指明了應(yīng)當(dāng)用什么機(jī)制來(lái)進(jìn)行
解碼,。注意,單獨(dú)的程序可能有能力實(shí)現(xiàn)對(duì)多種格式編碼的解碼,。
在這段文字中,,提到了兩個(gè)值:
x-gzip
文件壓縮程序"gzip" (GNU zip,由Jean-loup Gailly開(kāi)發(fā))的編碼格式,。該格式屬于
典型的帶有32位CRC 校驗(yàn)的Lempel-Ziv譯碼 (LZ77),。
x-compress
文件壓縮程序"compress"的編碼格式,該格式適用于LZW(Lempel-Ziv-Welch)譯
碼,。
注意:用程序名來(lái)標(biāo)識(shí)編碼格式的做法不是很理想,,在將來(lái)可能不會(huì)繼續(xù)這樣做。現(xiàn)在
之所以這樣做是出于歷史的原因,,并非良好的設(shè)計(jì),。
3.6 介質(zhì)類(lèi)型(Media Types)
HTTP在Content-Type header域(10.5節(jié))中使用Internet介質(zhì)類(lèi)型[13],用以提供開(kāi)放
的可擴(kuò)展的數(shù)據(jù)類(lèi)型,。
media-type = type "/" subtype *( ";" parameter )
type = token
subtype = token
參數(shù)可參照屬性/值對(duì)的方式,,用類(lèi)型/子類(lèi)型的格式來(lái)寫(xiě)。
Parameter = attribute "=" value
Attribute = token
Value = token | quoted-string
其中,,類(lèi)型,、子類(lèi)型、參數(shù)屬性名是大小寫(xiě)敏感的。而參數(shù)值不一定是大小寫(xiě)敏感的,,
這得看參數(shù)名的語(yǔ)法而定,。在類(lèi)型和子類(lèi)型、屬性名和屬性值之間不能有LWS(空格),。當(dāng)
接收到不能識(shí)別的介質(zhì)類(lèi)型的參數(shù)時(shí),,用戶代理應(yīng)當(dāng)忽略它們。
一些老的HTTP應(yīng)用不能識(shí)別介質(zhì)類(lèi)型參數(shù),,所以HTTP/1.0的應(yīng)用程序只能在定義消
息內(nèi)容時(shí)使用介質(zhì)參數(shù),。
介質(zhì)參數(shù)(Media-type)值用Internet授權(quán)分配數(shù)字(Internet Assigned Number
Authority ,IANA [15])注冊(cè),。介質(zhì)類(lèi)型注冊(cè)過(guò)程請(qǐng)參見(jiàn)RFC1590[13],。不鼓勵(lì)使用未注冊(cè)
的介質(zhì)類(lèi)型。
3.6.1標(biāo)準(zhǔn)及文本缺?。?/font>Canonicalization and Text Defaults)
Internet介質(zhì)類(lèi)型是用規(guī)范形式注冊(cè)的,。一般來(lái)說(shuō),在通過(guò)HTTP協(xié)議傳輸實(shí)體主體
(Entity-Body)之前,,必須先將其表示成適當(dāng)?shù)囊?guī)范格式,。如果主體用使用了一種
Content-Encoding進(jìn)行編碼,下面的數(shù)據(jù)在編碼前必須轉(zhuǎn)換成規(guī)范形式:
"text"類(lèi)型的介質(zhì)子類(lèi)型在規(guī)范形式中使用CRLF做為文本行中斷,。實(shí)際上,,為和實(shí)體
主體(Entity body)內(nèi)的使用方式保持一致,HTTP允許傳輸純以CR或LF單獨(dú)表示行中斷
的文本介質(zhì),。HTTP應(yīng)用程序必須將其通過(guò)HTTP方式接收到的文本介質(zhì)中的CRLF,、CR、
LF看做是行中斷符,。
另外,,如果文本介質(zhì)的字符集沒(méi)有使用字節(jié)13和10做為CR和LF,象一些多字節(jié)字
符集,,HTTP允許使用該字符集指定的任何順序的字節(jié)替代CR和LF做為行中斷,,這種行
中斷的靈活運(yùn)用方式僅可于實(shí)體主體(Entity-Body)中。一個(gè)純CR或LF不應(yīng)在任何HTTP
控制結(jié)構(gòu)(如標(biāo)題域-header field和多塊分界線-multipart boundaries)中替代CRLF,。
參數(shù)"charset"在定義數(shù)據(jù)的字符集(3.4節(jié))時(shí),,與一些介質(zhì)類(lèi)型一起使用。當(dāng)發(fā)送方
沒(méi)有顯式給出字符參數(shù)時(shí),,HTTP在接收時(shí)將"text"的介質(zhì)子類(lèi)型定義為缺省
值"ISO-8859-1",。"ISO-8859-1"字符集或其子集以外的數(shù)據(jù)必須要標(biāo)記其相應(yīng)的字符集值,
這樣可以保證接收方能正確地對(duì)其進(jìn)行解析,。
注意:許多當(dāng)前HTTP服務(wù)器提供的數(shù)據(jù)使用"ISO-8859-1"以外的其它字符集,,而且也
沒(méi)有正確的進(jìn)行標(biāo)記,,這種工作方式限制了互操作性,建議不要采用,。做為一種補(bǔ)救方法,,
一些HTTP用戶代理提供了配置選項(xiàng),使用戶可以在字符集參數(shù)沒(méi)指定的情況下,,自行更改
缺省的介質(zhì)類(lèi)型解釋方式,。
3.6.2 多部分類(lèi)型(Multipart Types)
MIME提供了多部分("multipart")類(lèi)型的數(shù)字――在一個(gè)單獨(dú)的消息實(shí)體主體
(Entity-Body)內(nèi)可以封裝幾個(gè)實(shí)體(entities)。雖然用戶代理可能需要了解每種類(lèi)型,,從
而可以正確解釋每部分主體的意圖,但是在IANA[15]的多部分類(lèi)型(multipart types)注冊(cè)
中卻找不到專(zhuān)為HTTP/1.0所指定的內(nèi)容,。HTTP用戶代理只得自己來(lái)做接收多部分類(lèi)型的
工作,,其過(guò)程和行為與MIME用戶代理是相同或相似的。HTTP服務(wù)器不應(yīng)假定HTTP客戶
端都有能力處理多部分類(lèi)型,。
所有的多部分類(lèi)型都使用通用的語(yǔ)法,,而且必須在介質(zhì)類(lèi)型值部分包括邊界參數(shù)
(boundary parameter)。消息的主體是其自身,,做為協(xié)議元素,,它必須只使用CRLF做為段
間(body-parts)的行中斷符。多段主體(Multipart body-parts)中可能包括對(duì)各段有重要意
義的HTTP標(biāo)題域,。
3.7 產(chǎn)品標(biāo)識(shí)(Product Tokens)
是通訊應(yīng)用程序用來(lái)標(biāo)識(shí)其自身的一個(gè)簡(jiǎn)單符號(hào),,常和任意字母及版本描述一起使用。
大多數(shù)產(chǎn)品標(biāo)識(shí)也將其產(chǎn)品的重要組成部分的版本號(hào)一起列出,,中間用空格分隔,。
按慣例,在標(biāo)識(shí)應(yīng)用程序時(shí),,組件以其重要性順序排列,。
Product = token ["/" product-version]
product-version = token
例如:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Server: Apache/0.8.4
產(chǎn)品標(biāo)識(shí)應(yīng)當(dāng)短小,因而禁止利用該域填寫(xiě)廣告或其它無(wú)關(guān)信息,。雖然任何符號(hào)字符都
可能出現(xiàn)在產(chǎn)品版本中,,該符號(hào)應(yīng)當(dāng)只用于做版本定義,也就是說(shuō),,同一個(gè)產(chǎn)品的連續(xù)版本
之間只能通過(guò)產(chǎn)品版本值進(jìn)行區(qū)分