超文本傳輸協議-HTTP/1.1(修訂版)html
---譯者:孫超進本協議不限流傳發布。版權聲明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")將由RFC2119[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)實體是請求或響應的有效承載信息。一個實體包含元信息和內容,元信息以實體頭域(entityheaderfield)形式表示,內容以消息主體(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)須要代理認證和代理識別,而不修改請求或響應。非透明代理(nontransparentproxy)需修改請求或響應,以便爲用戶代理(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)」符合的字符串是「elemfoo elem」和「elem bar elem」。*規則前面的字符「*」表示重複。完整的形式是「*元素」,表示元素至少出現次,至多出現次。默認值是0和無窮大,因此"*(元素)"容許任何數值,包括零;"1*元素"至少出現一次;"1*2element"容許出現一次或兩次。[規則]方括號裏是任選元素;「[foo bar]」至關於「*1(foo bar)」。N 規則特殊的重複:「(元素)」與「*(元素)」等價;就是說,(元素)正好出現次。這樣2DIGIT是一個兩位數字,3ALPHA是一個由三個字符組成的字符串。#規則相似於「*」,結構「#」是用來定義一系列元素的。完整的形式是#元素,表示至少個元素,至多個元素,元素之間被一個或多個逗號(「,」)以及可選的線性空白(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 | LOALPHADIGIT = <任意數字0,1,...9>CTL = <任意控制字符(ascii碼值從0 到 31的字節)及刪除鍵DEL(127>CR = LF = SP = HT = <"> = HTTP/1.1 將 CR LF 的序列定義爲任何協議元素的行尾標誌,但這個規定對實體主體(endtity-body)除外(要求比較鬆的應用見附錄19.3)。實體主體(entity-body)的行尾標誌是由其相應的媒體類型定義的,如3.7節所述。CRLF = CR LFHTTP/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 = "\" CHAR3 協議參數3.1 HTTP版本HTTP使用一個「.」數字模式來指明協議的版本號。爲了進一步的理解HTTP通訊,協議的版本號指示了發送端指明消息的格式和能力,而不只僅是經過雙方通訊而得到的通訊特性。當消息元素的增長不會影響通訊行爲或擴展了域值時,協議版本是不須要修改的。當協議會由於添加一些特徵而作了修改時,數字就會遞增。這些修改不會影響一般的消息解析算法,但它會給消息添加額外的語意(semantic)而且會暗示發送者具備額外的能力。協議的消息格式發生變化時,數字就會增長。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.htmlhttp://ABC.com/%7Esmith/home.htmlhttp://ABC.com:/%7esmith/home.html3.3 日期/時間格式(Date/Time Formats)3.3.1 完整日期 (Full Date)HTTP應用曾經一直容許三種不一樣日期/時間格式:Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format第一種格式是做爲Internet 標準提出來的,它是一個國定長度的,由RFC 1123 [8](RFC822[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-daterfc1123-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 4DIGITdate1 = 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:59wkday = "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*DIGIT3.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 頭時,當發現沒有字符集參數(charsetparameter,譯註: 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)的值表示一種曾經或能被應用於一個實體的編碼轉換(encodingtransformation)。內容編碼主要用於文檔的壓縮或其它有效的變換,但這種變換必須不能丟失文檔的媒體類型的特性,而且不能丟失文檔的信息(譯註:就像有損壓縮和無損壓縮,前者不會丟失信息,後者會丟失信息)。實體常常被編碼後保存,而後傳送出去,而且在接收端被解碼。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-extensiontransfer-extension = token *( ";" parameter )參數(parameter)採用屬性/值對的形式.parameter = attribute "=" valueattribute = tokenvalue = 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(尾部)CRLFchunk(塊) = chunk-size [ chunk-extension ] CRLFchunk-data CRLFchunk-size = 1*HEXlast-chunk = 1*("0") [ chunk-extension ] CRLFchunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )chunk-ext-name = tokenchunk-ext-val = token | quoted-stringchunk-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 = tokensubtype = 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.17b3Server: Apache/0.8.4產品標記應言簡意賅。它們不能用來作廣告或其餘不重要的信息。雖然任一標記可能出現product-version 裏,但這個標記僅能用來作一個版本 (i.e., 同產品中的後續版本應該在product-version上有區別)3.9 質量值(Quality Values)HTTP內容協商(content negotiation,12節介紹)運用短「浮點」數字(short floating pointnumber)來表示不一樣協商參數的相對重要性。重要性的權值被規範化成一個從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*8ALPHAsubtag = 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-tagweak = "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-unitbytes-unit = "bytes"other-range-unit = tokenHTTP/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 = tokenfield-value = *( field-content | LWS )field-content = 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|傳輸譯碼頭域被用來指明應用程序的傳輸編碼,它是爲了保證消息的安全和合適的傳輸。傳輸譯碼(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.1CRLF[ message-body ] ; Section 4.35.1 請求行 (Request-Line)請求行(Request-Line)是以一個方法標記開始,後面跟隨Request-URI和協議版本(HTTPVersion),最後以CRLF結束。元素是以SP字符分隔。除了最後的CRLF,CR或LF是不被容許的。Request-Line =Method SP Request-URL SP HTTP-Version CRLF5.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-methodExtension-method = token資源所容許的方法由Allow頭域指定(14.7節)。響應的返回碼老是通知客戶某個方法對當前資源是不是被容許的,由於被容許的方法能被動態的改變。若是服務器能理解某方法但此方法對請求資源不被容許的,那麼源服務器應該返回405狀態碼(方法不容許);若是源服務器不能識別或沒有實現某個方法,那麼服務器應返回501狀態碼(沒有實現)。方法GET和HEAD必須被全部通常的服務器支持。全部其它的方法是可選的;然而,若是上面的方法都被實現,這些方法遵循的語意必須和第9章指定的相同。5.1.2 請求URL(Request-URI)Request-URI是一種通用資源標識符(3.2 節),而且它用於指定請求的請求資源。Request-URI ="*" | absoluteURI | abs_path | authotityRequest-URI的四個選項依賴於請求的性質。星號「*」意味着請求不能應用於一個特定的資源,只能應用於服務器自己,而且只能在方法不該用於一個資源的時候才被容許。舉例以下OPTIONS * HTTP/1.1當向代理(proxy)提交請求時,絕對URI(absoluteRUI)格式是不可缺乏的。代理(proxy)可能會被要求再次轉發請求或者從一個有效的緩存(cache)裏構造響應去響應請求。注意:代理可能轉發請求給另外一個代理或直接給被absoluteURI指定的源服務器。爲了不循環請求,代理(proxy)必須能識別全部的服務器名字,包括任何別名,本地的變化值,數字IP地址。一個請求行(Request-Line)的例子以下:GET http://www.w3.org/pub/www/TheProject.html HTTP/1.1爲了將來HTTP版本的全部請求能遷移到absoluteURI地址,全部基於HTTP/1.1的服務器必須接受絕對absoluteURI形式的請求,即便HTTP/1.1客戶端只爲代理產生絕對absoluteURI請求。authority格式只被用於CONNECT方法(9.9節).Request-URI大多數狀況是被用於指定一個源服務器或網關(gateway)上的資源。這種狀況下,URI 的絕對路徑(abs_path,見3.2.1 節)做爲Request-URI 被傳輸,而且URI 網絡位置(authority)必須在Host頭域裏指出。例如:客戶但願直接從源服務器獲取資源,這種狀況下,它可能會創建一個TCP鏈接,此鏈接是特定於主機「www.w3.org」的80端口的,這時會發送下面行:GET /pub/WWW/TheProject.html HTTP/1.1Host:www.w3.org接下來是請求的其餘部分。注意絕對路徑(absolute path)不能是空的;若是在原始URI裏沒有出現絕對路徑,必須給出"/"(服務器的根)。Request-URI是以3.2.1節裏指定的格式傳輸。若是Request-URI用"%HEX HEX"[42]編碼,源服務器爲了解析請求必須能對它進行解碼。服務器接收到一個無效的Request-URI時必須以一個合適的狀態碼響應。透明代理(proxy)不能重寫接收到的Request-URI裏的「abs_path」部分,當它轉發此請求到下一個內向服務器(inbound server,見1.3術語)時,但除了上面說的把一個空的abs_path用一個」/」代替以外。注:不重寫的規則是爲了防止代理(proxy)改變請求的原意,由於存在源服務器利用非保留(non-reserved)的URI字符爲相反的目的 。實現者應該知道某些低於HTTP/1.1版本的代理(proxy)會重寫Request-URI。5.2請求資源的識別 (The Resource Identified by a Request)請求資源的精肯定位是由請求裏的Request-URI和Host頭域決定的。若是源服務器不容許資源根據請求的不一樣主機來區分時,那麼它能夠會忽略Host頭域的值,當它決定經過HTTP/1.1 請求來識別資源的時候。(在HTTP/1.1 裏關於對Host 的支持在19.6.1.1節描述了其餘的要求)。一個源服務器若是必須基於請求主機來區分資源(這是由於存在虛擬主機(virtual hosts)和虛擬主機名(vanity host names)),那麼,對HTTP/1.1請求,它必須遵循下面的規則去決定請求的資源:1. 若是Request-URI是絕對地址(absoluteURI),那麼主機(host)是Request-URI的一部分。任何出如今請求裏Host頭域的值應當被忽略。2. 假如Request-URI不是絕對地址(absoluteURI),而且請求包括一個Host頭域,則主機(host)由該Host頭域的值決定.3. 假如由規則1或規則2定義的主機(host)對服務器來講是一個無效的主機(host),則應當以一個400(壞請求)錯誤消息返回。缺乏Host頭域的HTTP/1.0請求的接收者可能會嘗試去利用啓發式的規則(例如:檢查URI路徑是不是特定某個主機)去決定被請求的真正資源。5.3請求頭域 (Request Header Fields)請求頭域容許客戶端傳遞請求的附加信息和客戶端本身的附加信息給服務器。這些頭域做爲請求的修飾,這和程序語言方法調用的參數語義是等價的。請求頭(request-header) = Accept ;14.1節| Accept-Charset ;14.2節|Accept-Encoding ;14.3節|Accept-Language ;14.4節|Authorization ;14.8節|Expect ;14.20節|From ;14.22節|Host ;14.23節|If-Match ;14.24節|If-Modified-Since ;14.25節| If-None-Match ;14.26節| If-Range ;14.27節| If-Unmodified-Since ;14.28節| Max-Forwards ;14.31節| Proxy-Authorization ;14.34節| Range ;14.35節| Referer ;14.36節|TE ;14.39節| User-Agent ;14.43節請求頭域的名字是能被擴展,但只能隨協議版本改變而被擴展。然而新的或實踐性的頭域能夠給定請求頭域語義,若是全部通訊方都把它看做請求頭域。不能識別的頭域會被看做實體頭域(entity-header)。6 響應 (Response)接收和解析一個請求消息後,服務器發出一個HTTP響應消息。response =Status-Line ;6.1節*(( general-header) ; 4.5節| response-header ;6.2節| entity-header)CRLF) ;7.1節CRLF[ message-body ] ;7.2節6.1 狀態行 (Status-Line)響應消息的第一行是狀態行(stauts-Line),由協議版本以及數字狀態碼和相關的文本短語組成,各部分間用空格符隔開,除了最後的CRLF序列,中間不容許有CR或LF。Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF6.1.1狀態碼與緣由短語 (Status Code and Reason Phrase)Status-Code元素是一個試圖理解和知足請求的三位數字整數碼,這些碼的完整定義在第十章。緣由短語(Reason-Phrase)是爲了給出關於狀態碼的簡單的文本描述。狀態碼用於控制,而緣由短語(Reason-Phrase)是讓用戶便於閱讀。客戶端不須要檢查和顯示緣由短語。狀態碼的第一位數字定義響應類別。後兩位數字沒有任何分類角色。第一位數字有五種值:-1xx :報告的 -請求被接收到,繼續處理-2xx :成功 - 被成功地接收(received),理解(understood),接受(accepted)的動做 。-3xx :重發 - 爲了完成請求必須採起進一步的動做。-4xx :客戶端出錯 - 請求包括錯的語法或不能被知足。-5xx :服務器出錯 - 服務器沒法完成顯然有效的請求。下面列舉了爲HTTP/1.1定義的態碼值,和對應的緣由短語(Reason-Phrase)的例子。緣由短語在這裏例舉只是建議性的----它們也許被一個局部的等價體代替而不會影響此協議的語義。Status-Code ="100" ; 10.1.1節: 繼續|"101" ; 10.1.2節: 轉換協議|"200" ; 10.2.1節: OK|"201" ; 10.2.2節: 已建立|"202" ; 10.2.3節: 接受|"203" ; 10.2.4節: 非權威信息|"204" ; 10.2.5節: 無內容|"205" ; 10.2.6節: 重置內容|"206" ; 10.2.7節: 部份內容|"300" ; 10.3.1節: 多個選擇|"301" ; 10.3.2節: 永久移動|"302" ; 10.3.3節: 發現|"303" ; 10.3.4節: 見其它|"304" ; 10.3.5節: 沒有被改變|"305" ; 10.3.6節: 使用代理|"307" ; 10.3.8節 臨時重發|"400" ; 10.4.1節: 壞請求|"401" ; 10.4.2節: 未受權的|"402" ; 10.4.3節: 必要的支付|"403" ; 10.4.4節: 禁用|"404" ; 10.4.5節: 沒有找到|"405" ; 10.4.6節: 方式不被容許|"406" ; 10.4.7節: 不接受的|"407" ; 10.4.8節: 須要代理驗證|"408" ; 10.4.9節: 請求超時|"409" ; 10.4.10節; 衝突|"410" ; 10.4.11節: 不存在|"411" ; 10.4.12節: 長度必需|"412" ; 10.4.13節;先決條件失敗|"413" ; 10.4.14節: 請求實體太大|"414" ; 10.4.15節; 請求URI太大|"415" ; 10.4.16節: 不被支持的媒體類型|"416" ; 10.4.17節: 請求的範圍不知足|"417" ; 10.4.18節: 指望失敗|"500" ; 10.5.1節: 服務器內部錯誤|"501" ; 10.5.2節: 不能實現|"502" ; 10.5.3節: 壞網關|"503" ; 10.5.4節: 服務不能得到|"504" ; 10.5.5節: 網關超時|"505" ; 10.5.6節: HTTP版本不支持|擴展碼extension-code =3DIGITReason-Phrase = *HTTP狀態碼是可擴展的。HTTP應用程序不須要理解全部已註冊狀態碼的含義,儘管那樣的理解是很但願的。可是,應用程序必須瞭解由第一位數字指定的狀態碼的類別,任何未被識別的響應應被看做是那個類別的x00狀態碼,未被識別的響應不能被緩存除外。例如,若是客戶端收到一個未被識別的狀態碼431,則能夠安全的認爲請求有錯,而且它會對待此響應就像它接收了一個狀態碼是400的響應。在這種狀況下,用戶代理(user agent)應當把響應的實體展示給用戶,由於實體有可能包括人類可讀的信息,這些信息也許能解釋非正常狀態的緣由。6.2響應頭域 (Response Header Fields)響應頭域容許服務器傳送響應的附加信息,這些信息不能放在狀態行(Status-Line)裏.。這些頭域給出有關服務器的信息以及請求URI(Request-URI)指定資源的更進一步訪問信息。response-header = Accept-Ranges ; 14.5節|Age ; 14.6節|Etag ; 14.19節|Location ; 14.30節|Proxy-Autenticate ; 14.33節|Retry-After ; 14.37節|Server ; 14.38節|Vary ; 14.44節|WWW-Authenticate ; 14.47節響應頭域的名字能依賴於協議版本的變化而擴展。然而,新的或者實踐性的頭域可能會給予響應頭域的語義若是通訊全部成員都能識別他們並把他們看做響應頭域。不被識別的頭域被看做實體頭域。7 實體(Entity)若是不被請求方法或響應狀態碼所限制,請求和響應消息均可以傳輸實體。 實體包括實體頭域(entity-header)與實體主體(entity-body),而有些響應只包括實體頭域(entity-header)。在本節中的發送者和接收者是不是客戶端或服務器,這依賴於誰發送或誰接收此實體。7.1 實體頭域(Entity Header Fields)實體(entity-header)頭域定義了關於實體主體的的元信息,或在無主體的狀況下定義了請求的資源的元信息。有些元信息是可選的;一些是必須的。entity-header = Allow ; Section 14.7| Content-Encoding ; Section 14.11| Content-Language ; Section 14.12| Content-Length ; Section 14.13| Content-Location ; Section 14.14| Content-MD5 ; Section 14.15| Content-Range ; Section 14.16| Content-Type ; Section 14.17| Expires ; Section 14.21| Last-Modified ; Section 14.29| extension-headerextension-header = message-header擴展頭機制容許在不改變協議的前提下定義額外的實體頭域,但不保證這些域在接收端可以被識別。未被識別的頭域應當被接收者忽略,且必須被透明代理(transparent proxy)轉發。7.2 實體主體(Entity Body)由HTTP請求或響應發送的實體主體(若是存在的話)的格式與編碼方式應由實體的頭域決定。Entity-body= *OCTET如4。3節所述,實體主體(entity-body)只有當消息主體存在時時才存在。實體主體(entitybody)從消息主體根據傳輸譯碼頭域(Transfer-Encoding)解碼獲得,傳輸譯碼用於確保消息的安全和合適傳輸。7.2.1 類型(Type)當消息包含實體主體(entity-body)時,主體的數據類型由實體頭域的Content-Type 和Content-Encoding頭域肯定。這些頭域定義了兩層順序的編碼模型:Entity-body:=Content-Encoding( Content-Type( data) )Content-Type指定了下層數據的媒體類型。Content-Encoding可能被用來指定附加的應用於數據的內容編碼,常常用於數據壓縮的目的,內容編碼是請求資源的屬性。沒有缺省的編碼。任一包含了實體主體的HTTP/1.1消息都應包括Content-Type頭域以定義實體主體的媒體類型。若是隻有媒體類型沒有被Content-Type頭域指定時,接收者可能會嘗試猜想媒體類型,這經過觀察實體主體的內容而且/或者經過觀察URI指定資源的擴展名。若是媒體類型仍然不知道,接收者應該把類型看做」application/octec-stream」。7.2.2 實體主體長度(Entity Length)消息的實體主體長度指的是消息主體在被應用於傳輸編碼(transfer-coding)以前的長度。4.4節定義了怎樣去肯定消息主體的傳輸長度。8 鏈接8.1 持久鏈接(Persistent Connection)。8.1.1 目的在沒有持久鏈接以前,爲獲取每個URL指定的資源都必須創建了一個獨立的TCP 鏈接,這就加劇了HTTP服務器的負擔,易引發互聯網的阻塞。嵌入圖片與其它相關數據一般使用戶在短期內對同一服務器進行屢次請求。目前針對這些性能問題的分析以及一個原型實現的結果是能夠得到的[26][30]。 HTTP/1.1(RFC2068)實現的實踐過程和度量展示了一個滿意的結果。對其餘方法也有了初步探究,如T/TCP [27]。HTTP持久鏈接有着諸多的優勢:--- 經過創建與關閉較少的TCP鏈接,不只節省了路由器與主機(客戶端,服務器,代理,網關,隧道或緩存)的CPU時間,還節省了主機用於TCP協議控制塊(TCP protocol controlblocks)的內存。--- HTTP請求和響應能在鏈接上進行管線請求方式。 管線請求方式能容許客戶端執行屢次請求而不用等待每個請求的響應(譯註:即客戶端能夠發送請求而不用等待之前的請求的響應到來後再發請求),而且此時只有一個TCP鏈接被使用,從而提升了效率,減小了時間。--- 網絡阻塞會被減小,這是因爲減小了因TCP鏈接產生的包的數量而且也因爲容許TCP有充分的時間去決定網絡阻塞的狀態。--- 由於無須在建立TCP鏈接時的握手上耗費時間,而使後續請求的等待時間減小。---HTTP改進的愈來愈優雅,由於報告錯誤不須要關閉tcp鏈接的代價。未來的HTTP版本客戶端能夠樂觀的嘗試利用一個新特性,可是若是和老服務器通訊時錯誤被報告,那麼就要用舊的語義進行從新嘗試。HTTP實現應該實現持久鏈接。8.1.2 整體操做HTTP/1.1 與早期HTTP 版本的一個顯著區別在於持久鏈接是HTTP/1.1的缺省方式。也就是說,除非另有指定,客戶端總應當假定服務器會保持持久鏈接,即使在收到服務器的出錯響應時也應如此。持久鏈接提供了一種能夠由客戶端或服務器通知終止TCP鏈接的機制。利用Connection頭域(14。10節)能夠產生終止鏈接信號。一旦出現了終止鏈接的信號,客戶端便不可再向此鏈接提出任何新請求。8.1.2.1 協商(Negotiation)除非請求裏Connection頭域中包含「close」鏈接標記(connection-token),HTTP/1.1服務器總能夠認爲HTTP/1.1 客戶端想要維持持久鏈接(persistent connection)。若是服務器想在發出響應後當即關閉鏈接,它應當發送一個含「close」的Connection頭域。一個HTTP/1.1客戶端可能指望鏈接一直保持開着,但這必須是基於服務器響應裏是否包含一個Connection頭域而且此頭域裏是否包含「close」。若是客戶端不想再繼續維持鏈接來發送更多請求,那麼它應發送一個值爲「close」的Connection頭域。若是客戶端或服務器中的任一方在Connection頭域裏包含「close」,那麼那個請求就成爲這個鏈接的最後一個請求。客戶端和服務器不該認爲持久鏈接是低於1.1的HTTP版本所擁有的,除非它被顯式地指明。19.6.2節指出了跟HTTP/1.1客戶端兼容的更多信息。8.1.2.2 管線(pilelining)支持持久鏈接(persistent conncetion)的客戶端能夠以管線的方式發送請求(即無須等待響應而發送多個請求)。服務器必須按接收請求的順序發送響應。假定以持久鏈接方式進行鏈接,而且假定在鏈接創建後進行管線方式請求的客戶端應該準備去從新嘗試鏈接若是首次管線請求方式嘗試失敗。若是客戶端從新去嘗試鏈接,那麼,只有在客戶端知道鏈接是持久鏈接以後,客戶端才能進行管線發送請求。若是服務器在響應全部對應的請求以前關閉了鏈接,客戶端必須準備去從新發送請求。客戶端不該該利用非等冪的方法或者非等冪的方法序列(見9.1.2節)進行管線方式的請求。不然一個過早的傳輸層鏈接的終止可能會致使不肯定的結果。但願發送非等冪方法請求的客戶端只有接收了上次它發出請求的響應後才能再次發送請求給服務器。8.1.3 代理 (Proxy Servers)代理是很是重要的,由於代理正確地實現了Connection頭域的屬性,這在14.10節指出了。代理必須分別向它相連的客戶端或源服務器(或其餘的代理)指明持久鏈接。每個持久鏈接只能應用於一個傳輸層鏈接。代理不能和一個HTTP/1.0客戶端創建一個HTTP/1.1持久鏈接(可是參見RFC2068[33]裏的關於許多HTTP/1.1客戶端利用Keep-Alive頭域的問題的討論)。8.1.4 實際考慮 (Practical Considerations)服務器一般有一個時限值,超過必定時間即再也不維持處於非活動的鏈接。代理會選一個較高的值,由於客戶端極可能會與同一服務器創建多個鏈接。持久鏈接方式的採用對於客戶端與服務器來講均未提出任何須須存在超時或給定多長時間的要求。當客戶端或服務器但願超時時, 它應該優雅的去關閉傳輸鏈接。客戶端與服務器端應始終注意對方是否終止了傳輸層鏈接,並適當的予以響應。若客戶端或服務器未能及時檢測到對方已終止了鏈接,將會形成沒必要要的網絡資源浪費。客戶端,服務器,或代理可能在任意時刻會終止傳輸鏈接。好比,客戶端可能正想發出新的請求,而此時服務器卻決定關閉「閒置」的鏈接。在服務器看來,鏈接已經由於閒置被關閉了,但客戶端認爲我正在請求。這代表客戶端,服務器與代理必須有能力從鏈接的異步終止事件中恢復。只要請求是等冪的(見9.1.2節),客戶端軟件應該能從新打開傳輸層鏈接並重試傳輸遺棄的請求序列而不須要用戶進行去交互。對非等冪方法的請求就不能自動重試請求,儘管用戶代理(user agent)可能提供一我的工操做去重試這些請求。用戶代理(user-agent)對應用程序語義理解的確認應該替代用戶的確認。若是再次重試請求序列失敗,那麼就不能再進行自動重試請求了。服務器儘量應該至少在每次鏈接中響應一個請求。除非出於網絡或客戶端的故障,服務器不該在傳送響應的中途斷開鏈接。使用持久鏈接的客戶端應限制與某一服務器同時鏈接的個數。單用戶客戶端不該與任一服務器或代理保持兩個以上的鏈接。代理應該與其它服務器或代理之間維護2*N個鏈接,其中N是同時在線的用戶數。這些準則是爲了改善響應時間和和避免阻塞。8.2 消息傳送的要求(Message Transmission Requirements)8.2.1 持久鏈接與流量控制 (Persistent Connections and Flow Control)HTTP/1.1服務器應保持持久鏈接並使用TCP流量控制機制來解決臨時過載,而不是在終止鏈接後期望客戶端的重試。後一方法會惡化網絡阻塞。8.2.2 監視鏈接中出錯狀態的消息HTTP/1.1(或更新)客戶端應該當在發送請求的消息主體時同時監視網絡鏈接是否處於出錯狀態。若客戶端發現了錯誤,它應當當即中止消息主體的的傳送。若消息主體是以塊傳輸編碼方式發送的(3.6節),能夠用長度爲零的塊和空尾部(trailer)來提早標記報文結束。若消息主體以前有Content-Length頭域,那麼客戶端必須關閉鏈接。8.2.3 100狀態碼的用途100狀態碼(繼續,見10.1.1節)的目的在於容許客戶端,在發送此請求消息主體前,斷定服務器是否願意接受發送消息的主體(基於請求的頭域)。 在有些狀況下,若是服務器拒絕查看消息主體,這時客戶端發送消息主體是不恰當的或會大大下降效率。HTTP/1.1客戶端的要求:--- 若客戶端想要在發送請求消息主體以前等候100(繼續)響應,則它必須發送一個Expect請求頭域(見14.20節),而且值是「100-continue」。--- 客戶端不能發送一個值是「100-continue」的Expect請求頭域,若是此客戶端不打算髮送帶消息主體的請求。因爲存在舊實現,協議容許二義性的情形存在,這在客戶端在發送「Expect:100-continue」後而不必定要接收一個417(指望失敗)狀態碼或着100(繼續)狀態碼時。所以,當一個客戶端發送Expect請求頭域給一個源服務器(可能經過代理),此服務器也沒有以100(繼續)狀態碼響應,那麼客戶端不該該在發送請求消息的主體前無限等待。HTTP/1.1源服務器的要求:--- 當接收一個包含值爲「100-contitue」的Expect請求頭域的請求時,源服務器必須或者以100(繼續)狀態碼響應從而繼續從輸入流裏接收數據,或者以一個最終的狀態碼響應。源服務器不能在發送100(繼續)狀態碼響應以前接收請求主體。若是服務器以一個終結狀態碼響應後,它可能會關閉傳輸層鏈接或者它也可能會繼續接收或遺棄剩餘的請求。可是既然它返回了一個終結狀態碼的響應,它就不能再去執行那個請求的方法(如:POST方法,PUT方法)。--- 若是請求消息不含值爲「100-continue」的Expect請求頭域, 源服務器不該發送100(繼續)響應,而且,當請求來自HTTP/1.0(或更早)的客戶端時,服務器也不得發送100(繼續)響應。對此規定有一例外:爲了與RFC 2068兼容,源服務器可能會發送一個100(繼續)狀態響應以響應HTTP/1.1的PUT或POSt 請求,雖然這些請求中沒有包含值爲」100-continue」的Expect請求頭域。這個例外的目的是爲了減小任何客戶端由於等待100(繼續)狀態響應的延時,但此例外只能應用於HTTP/1.1請求,並不適合於其餘HTTP版本的請求。--- 若源服務器已經接收到部分或所有請求的消息的主體,源服務器能夠不須要發100(繼續)響應。---一旦請求消息主體被接收和被處理,發送100(繼續)響應的源服務器必須最終能發送一個終結狀態響應,,除非源服務器過早切斷了傳輸層鏈接。--- 若源服務器接收到不含值爲「100-contitue」的Expect請求頭域的請求,但該請求含有請求消息主體,而服務器在從傳輸層鏈接上接收整個請求消息主體前返回一個終結狀態響應,那麼此源服務器不能關閉傳輸層鏈接直到它接收了整個請求或者直到客戶端關閉了此鏈接。不然客戶端可能不會信任接收此響應消息。然而,這一要求不該該被解釋爲防止服務器免受拒絕服務攻擊,或者防止服務器被客戶端攻擊。對HTTP/1.1代理的要求:--- 若代理接到一個請求,此請求包含值爲「100-continue」的Expect請求頭域,而且代理可能不能肯定下一站服務器是否遵循HTTP/1.1或更高版協議,那麼它必須轉發此請求時包含此Expect頭域。--- 若代理知道下一站服務器版本是HTTP/1.0或更低,則它不能轉發此請求,而且它必須以417(指望失敗)狀態響應。--- 代理應當維護一個緩存,以記錄最近訪問下一站點服務器的HTTP版本號。--- 若接收到的請求來自於版本是HTTP/1.0(或更低)的客戶端,而且此請求不含值爲「100-continue」的Expect請求頭域,那麼代理不能轉發100(繼續)響應。 這一要求可覆蓋1xx響應轉發的通常規則(參見10.1節)。8.2.4 服務器過早關閉鏈接時客戶端的行爲若是HTTP/1.1 客戶端發送一條含有消息主體的請求消息,但不含值爲「100-continue」的Expect請求頭域,而且若是客戶端沒有直接與HTTP/1.1源服務器相連,而且客戶端在接收到服務器的狀態響應以前看到了鏈接的關閉,那麼客戶端應該重試此請求。在重試時,客戶端能夠利用下面的算法來得到可靠的響應。1. 向服務器發起一新鏈接。2. 發送請求頭域。3. 初始化變量R,使R的值爲通往服務器的往返時間的估計值(好比基於創建鏈接的時間),或在沒法估計往返時間時設爲一常數值5秒。4. 計算T=R*(2**N),N爲此前重試請求的次數。5. 等待服務器出錯響應,或是等待T秒(二者中時間較短的)。6. 若沒等到出錯響應,T秒後發送請求的消息主體。7. 若客戶端發現鏈接被提早關閉,轉到第1步,直到請求被接受,接收到出錯響應,或是用戶因不耐煩而終止了重試過程。在任意點上,客戶端若是接收到服務器的出錯響應,客戶端--- 不該再繼續發送請求, 而且--- 應該關閉鏈接若是客戶端沒有完成發送請求消息。9 方法定義(Method Definitions)HTTP/1.1經常使用方法的定義以下。雖然方法能夠被展開,但新加的方法不能被認爲與擴展客戶端和服務器共享一樣的語義。Host請求頭域(見14.23節)必須能在全部的HTTP/1.1請求裏出現。9.1 安全和等冪(Idempotent)方法9.1.1 安全方法(Safe Methods)實現者應當知道軟件是表明用戶在互聯網上進行交互,而且應該當心地容許用戶知道任何它們可能採起的動做(action),這些動做可能給他們本身或他人帶來沒法預料的結果。GET和HEAD方法只是執行沒有影響的動做那就是獲取資源。這些方法應該被考慮是「安全」的。可讓用戶代理調用的其它方法,如:POST,PUT,DELETE,這些方法是特殊的,用戶代理應該知道這些方法可能會執行不安全的動做。天然的,保證當服務器因爲執行GET請求而不能產生反作用是不可能的;實際上,一些動態的資源會考慮這個特性。用戶並無請求這些反作用,所以這些反作用對用戶應該是不受影響的。9.1.2 等冪方法(Idempotent Mehtods)方法能夠有等冪的性質由於(除了出錯或終止問題)N>0個相同請求的反作用同單個請求的反作用的效果是同樣(譯註:等冪就是值不變性,相同的請求獲得相同的響應結果,不會出現相同的請求出現不一樣的響應結果)。方法GET,HEAD,PUT,DELETE都有這種性質。一樣,方法OPTIONS和TRACE不該該有反作用,所以具備內在的等冪性。然而,有可能有多個請求的請求序列是不等冪的,即便在那樣的序列中全部方法都是等冪的。(若是整個序列總體的執行的結果老是相同的,而且此結果不會由於序列的總體,部分的再次執行而改變,那麼此序列是等冪的。)例如,一個序列是非等冪的若是它的結果依賴於一個值,此值在之後相同的序列裏會改變。根據定義,一個序列若是沒有反作用,那麼此序列是等冪的(假設在資源集上沒有並行的操做)。9.2 OPTIONS(選項)OPTIONS方法代表請求想獲得請求/響應鏈上關於此請求裏的URI(Request-URI)指定資源的通訊選項信息。此方法容許客戶端去斷定請求資源的選項和/或需求,或者服務器的能力,而不須要利用一個資源動做(譯註:使用POST,PUT,DELETE方法)或一個資源獲取(譯註:用GET方法)方法。此方法的響應是不能緩存的.。若是OPTIONS 請求消息裏包括一個實體主體(當請求消息裏出現Content-Length 或者Transfer-Encoding頭域時),那麼媒體類型必須經過Content-Type頭域指明。雖然此規範沒有定義如何使用此實體主體,未來的HTTP擴展可能會利用OPTIONS請求的消息主體去獲得服務器得更多信息。一個服務器若是不支持OPTION請求的消息主體,它會遺棄此請求消息主體。若是請求URI是一個星號("*"),,OPTIONS請求將會應用於服務器的全部資源而不是特定資源。由於服務器的通訊選項一般依賴於資源,因此」*」請求只能在「ping」或者「no-op」方法時纔有用;它幹不了任何事情除了容許客戶端測試服務器的能力。例如:它能被用來測試代理是否遵循HTTP/1.1。若是請求URI不是一個星號("*"),,OPTIONS請求只能應用於請求URI指定資源的選項。200響應應該包含任何指明選項性質的頭域,這些選項性質由服務器實現而且只適合那個請求的資源(例如,Allow頭域),但也可能包一些擴展的在此規範裏沒有定義的頭域。若是有響應主體的話也應該包含一些通訊選項的信息。這個響應主體的格式並無在此規範裏定義,可是可能會在之後的HTTP裏定義。內容協商可能被用於選擇合適的響應格式。若是沒有響應主體包含,響應就應該包含一個值爲「0」的Content-Length頭域。Max-Forwards請求頭域可能會被用於針對請求鏈中特定的代理。當代理接收到一個OPTIONS請求,且此請求的URI 爲absoluteURI,而且此請求是能夠被轉發的,那麼代理必需要檢測Max-Forwards頭域。若是Max-Forwards頭域的值爲「0」,那麼此代理不能轉發此消息;而是代理應該以它本身的通訊選項響應。若是Max-Forwards頭域是比0大的整數值,那麼代理必須遞減此值當它轉發此請求時。若是沒有Max-Forwards頭域出如今請求裏,那麼代理轉發此請求時不能包含Max-Forwards頭域。9.3 GETGET方法意思是獲取被請求URI(Request-URI)指定的信息(以實體的格式)。若是請求URI涉及到一個數據生成過程,那麼這個過程生成的數據應該被做爲實體在響應中返回而不是過程的源文本,除非源文本剛好是過程的輸出。若是請求消息包含 If-Modified-Since,,If-Unmodified-Since,If-Match,If-None-Match 或者If-Range頭域,GET的語義將變成「條件(conditionall) GET」。一個條件GET方法會請求知足條件頭域的實體。條件GET方法的目的是爲了減小沒必要要的網絡使用,這經過容許利用緩存裏仍然保鮮的實體而不用屢次請求或傳輸客戶端已經擁有的實體來實現的。.若是請求方法包含一個Range頭域,那麼GET方法就變成「部分Get」(partial GET)方法。一個部分GET會請求實體的一部分,這在14.35節裏描述了。 部分GET方法的目的是爲了減小沒必要要的網絡使用,能夠容許客戶端從服務器獲取實體的部分數據,而不須要獲取客戶端本地已經擁有的部分實體數據。GET請求的響應是可緩存的(cacheable)若是此響應知足第13節HTTP緩存的要求。看15.1.3節關於GET請求用於表單時安全考慮。9.4 HEADHEAD 方法和GET 方法一致,除了服務器不能在響應裏返回消息主體。HEAD請求響應裏HTTP頭域裏的元信息(譯註:元信息就是頭域信息)應該和GET請求響應裏的元信息一致。此方法被用來獲取請求實體的元信息而不須要傳輸實體主體(entity-body)。此方法常常被用來測試超文本連接的有效性,可訪問性,和最近的改變。.HEAD請求的響應是可緩存的,由於響應裏的信息可能被緩存用於更新之前那個資源對應緩存的實體.。若是出現一個新的域值指明緩存的實體和當前源服務器上的實體有所不一樣(可能由於Content-Length,Content-MD5,ETag或Last-Modified值的改變),那麼緩存(cache)必須認爲緩存項是過期的(stale)。9.5 POSTPOST 方法被用於請求源服務器接受請求中的實體做爲請求資源的一個新的從屬物。POST被設計涵蓋下面的功能。--已存在的資源的註釋;--發佈消息給一個佈告板,新聞組,郵件列表,或者類似的文章組。--提供一個數據塊,如提交一個表單給一個數據處理過程。--經過追加操做來擴展數據庫。POST方法的實際功能是由服務器決定的,而且常常依賴於請求URI(Request-URI)。POST提交的實體是請求URI的從屬物,就好像一個文件從屬於一個目錄,一篇新聞文章從屬於一個新聞組,或者一條記錄從屬於一個數據庫。POST方法執行的動做可能不會對請求URI所指的資源起做用。在這種狀況下,200(成功)或者204(沒有內容)將是適合的響應狀態,這依賴於響應是否包含一個描述結果的實體。若是資源被源服務器建立,響應應該是201(Created)而且包含一個實體,此實體描述了請求的狀態。而且引用了這個新資源和一個Location頭域(見14.30節)。POST方法的響應是不可緩存的。除非響應裏有合適的Cache-Control或者Expires頭域。然而,303(見其餘)響應能被用戶代理利用去得到可緩存的響應。POST 請求必須遵循8.2節裏指明的消息傳送的要求。參見15.1.3節關於安全性的考慮.9.6 PUTPUT方法請求服務器去把請求裏的實體存儲在請求URI(Request-URI)標識下。若是請求URI(Request-URI)指定的的資源已經在源服務器上存在,那麼此請求裏的實體應該被看成是源服務器關於此URI所指定資源實體的最新修改版本。若是請求URI(Request-URI)指定的資源不存在,而且此URI被用戶代理定義爲一個新資源,那麼源服務器就應該根據請求裏的實體建立一個此URI所標識下的資源。若是一個新的資源被建立了,源服務器必須能向用戶代理(user agent) 發送201(已建立)響應。若是已存在的資源被改變了,那麼源服務器應該發送200(Ok)或者204(無內容)響應。若是資源不能根據請求URI建立或者改變,一個合適的錯誤響應應該給出以反應問題的性質。實體的接收者不能忽略任何它不理解和不能實現的Content-*(如:Content-Range)頭域,而且必須返回501(沒有被實現)響應。若是請求穿過一個緩存(cache),而且此請求URI(Request-URI)指示了一個或多個當前緩存的實體,那麼這些實體應該被看做是舊的。PUT方法的響應是不可緩存的。POST方法和PUT方法請求最根本的區別是請求URI(Request-URI)的含義不一樣。POST請求裏的URI 指示一個能處理請求實體的資源(譯註:此資源多是一段程序,如jsp 裏的servlet) 。此資源多是一個數據接收過程,一個網關(gateway,譯註:網關和代理的區別是:網關能夠進行協議轉換,而代理不能,只是起代理的做用,好比緩存服務器其實就是一個代理),或者一個單獨接收註釋的實體。對比而言,PUT方法請求裏的URI標識請求裏封裝的實體一一用戶代理知道URI 意指什麼,而且服務器不能把此請求應用於其它資源(resource)。若是服務器指望請求被應用於一個不一樣的URI,那麼它必須發送301(永久移動)響應;用戶代理能夠本身決定是否重定向請求。一個單獨的資源可能會被許多不一樣的URI指定。如:一篇文章可能會有一個URI指定當前版本,而這個URI區別於這篇文章其它特殊版本的URI。這種狀況下,對一個通用URI的PUT請求可能會致使其資源的其它URI請求被源服務器重定義。HTTP/1.1沒有定義PUT方法對源服務器的狀態影響。PUT請求必須遵循8.2節中的消息傳送的要求。除非特別指出,PUT方法請求裏的實體頭域應該被用於資源的建立或修改。9.7 DELETE(刪除)DELETE方法請求源服務器刪除請求URI指定的資源。此方法可能會在源服務器上被人爲的干涉(或經過其餘方法)。客戶端不能保證此操做能被執行,即便源服務器返回成功狀態碼。然而,服務器不該該指明成功除非它打算刪除資源或把此資源移到一個不可訪問的位置。若是響應裏包含描述成功的實體,響應應該是200(OK);若是DELETE動做尚未執行,應該以202(已接受)響應;若是DELETE請求方法已經執行但響應不包含實體,那麼應該以204(無內容)響應。若是請求穿過緩存,而且請求URI(Request-URI)指定了一個或多個緩存當前實體,那麼這些緩存項應該被認爲是舊的。DELETE方法的響應是不能被緩存的。9.8 TRACETRACE方法被用於激發一個遠程的,應用層的請求消息迴路(譯註:TRACE方法讓客戶端測試到服務器的網絡通路,迴路的意思如發送一個請返回一個響應,這就是一個請求響應迴路,)。最後的接收者也許是源服務器,也許是接收到包含Max-Forwards頭域值爲0請求的代理或網關。TRACE請求不能包含一個實體。TRACE方法容許客戶端去了解數據被請求鏈的另外一端接收的狀況,而且利用那些數據信息去測試或診斷。Via頭域值(見14.45)有特殊的用途,由於它能夠做爲請求鏈的跟蹤信息。利用Max-Forwards頭域容許客戶端限制請求鏈的長度,這是很是有用的,由於能夠利用此去測試代理鏈在無限循環裏轉發消息。若是請求是有效的,響應應該在實體主體裏包含整個請求消息,而且響應應該包含一個Content-Type頭域值爲」message/http」的頭域。此方法的響應不能被緩存。9.9 CONNECT(鏈接)HTTP1.1 協議規範保留了CONNECT方法,此方法是爲了能用於能動態切換到隧道的代理((如 SSL tunneling [44]).)。10.狀態碼定義每個狀態碼在下面定義,包括此狀態碼依賴於方法的描述和響應裏須要的任何元信息的描述。10.1 通知的 1xx這類狀態代碼指明瞭一個臨時性的響應,包含一個Status-Line和可選的頭域,而且被一個空行結束(譯註:空行就是CRLF)。這類狀態碼響應沒有必須的頭域。由於HTTP/1.0沒有定義任何1xx狀態碼,因此服務器不能發送一個1xx響應給一個HTTP/1.1客戶端,除了實驗性的目的。客戶端必須能在一個常規響應以前接受一個或多個1xx狀態,即便客戶端不指望100(繼續)狀態響應。不被客戶端指望的1xx狀態響應可能會被用戶代理忽略。代理必須能轉發1xx響應,除非代理和它的客戶端的鏈接關閉了,或者除非代理本身響應請求併產生1xx響應。(例如:若是代理添加了「Expect:100-continue」頭域當轉發請求時,那麼它沒必要轉發相應的100(繼續)狀態響應。)10.1.1 100 繼續 (Continue)100狀態響應告訴客戶端應該繼續請求。100響應是個中間響應,它被用於通知客戶端請求的初始部分已經被接收了而且此請求尚未被服務器丟棄。客戶端應該繼續發送請求的剩餘部分,或者,若是此請求已經完成了客戶端會忽略此100響應。服務器在接收請求後必須發送一個終結響應。見8.2.3節關於此狀態碼的討論和使用。10.1.2 101切換協議 (Switching Protocols)服務器理解和願意遵循客戶端這樣的請求,此請求經過Upgrade消息頭域(見14.42節)指明在鏈接上應用層協議的改變。 服務器將會切換到響應裏Upgrade頭域裏指明的協議,它會以一個空行結束此101響應。只有協議切換時能受益協議才應該切換。例如,當傳輸資源時,切換到一個新的HTTP版本比舊的版本要好,或者切換到一個實時的,同步的協議會帶來好處時,這時咱們都應該考慮切換。10.2 成功 2xx這類狀態碼指明客戶端的請球已經被服務器成功的接收,理解,而且接受了。10.2.1 200 OK此狀態碼指明客戶端請求已經成功了。響應返回的信息依賴於請求裏的方法,例如:GET 請求資源的相應的實體已經包含在響應裏並返回給客戶端。HEAD 相應於請求資源實體的實體頭域已經被包含在無消息主體的響應裏。POST 響應裏已經包含一個實體,此實體描述或者包含此POST動做執行的結果TRACE 響應裏包含一個實體,此實體包含終端對服務器接收的請求消息。10.2.2 201 已建立(Created)請求已經被服務器知足了而且已經產生了一個新的資源。新建立的資源的URI在響應的實體裏返回,可是此資源最精確的URI是在Location頭域裏給出的。響應應該含有一實體,此實體包含此資源的特性和位置,用戶或用戶代理能從這些特性和位置裏選擇最合適的。實體格式被Content-Type頭域裏媒體類型指定。源服務器必須能在返回201狀態碼以前創建資源。若是動做(譯註:這裏指能建立資源的方法,如POST方法)不能被當即執行,那麼服務器應該以202(接受)響應代替。一個201響應能夠包含一個ETag響應頭域,此頭域的值指明瞭當前請求變量(譯註:變量的含義見第1.3節「變量」的解釋)也即剛剛建立的資源的實體標籤(entity tag)值,見14.19節。10.2.3 202 接受(Accepted)請求已經被接受去處理,可是尚未處理完成。請求可能會或者不會處理完成,由於存在當處理的過程當中拒絕處理的狀況。202響應是有意非擔保性的。它是爲了容許服務器能夠爲其它處理(如:天天執行一次的批處理)接收請求而不須要用戶代理在處理沒有完成以前長期鏈接到服務器。響應裏的實體應該包含請求當前狀態的聲明而且應該包含一個狀態監視指針或一些用戶指望什麼時候請求被知足的評估值。10.2.4 203 非權威信息(Non-Authoritative information)此狀態碼響應指明響應裏實體頭域元信息不能從源服務器獲而是從本地的或第三方響應副本里收集的。這些元信息多是源服務器版本的子集或超集。如,包含一個存在本地的資源註釋信息就能夠產生一個源服務器能理解的元信息的超集。利用此響應狀態碼不是必須可是比200(Ok)響應卻更加合適。10.2.5 204 無內容 (No Content)服務器已經知足了請求但並無返回一個實體而是返回更新的元信息。此響應可能包含新的或更新的元信息以實體頭域的形式,這些元信息應該相關於請求變量。利用此204響應,客戶端若是是一個用戶代理,它就能夠不用改變引發請求發送的文檔視圖(譯註:如一篇html文檔在瀏覽器裏呈現的樣子)。204狀態響應主要的目的是容許輸入,而沒必要引發用戶代理當前文檔視圖的改變,儘管一些新的或更新了的元信息可能會應用於用戶代理視圖裏的當前文檔。204響應不能包含一個消息主體,而且在頭域後包含一個空行結束。10.2.6 205 重置內容(Reset Content)205狀態響應是服務器告訴用戶代理應該重置引發請求被髮送的文檔視圖。此響應主要的目的是清空文檔視圖表單裏的輸入框以便用戶能輸入其它信息。此響應不能包含一個實體。10.2.7 206 部份內容(Partial Content)服務器已經完成了客戶端對資源的部分GET請求。請求必須包含一個Range頭域(14.35節)用來指出想要的範圍,而且也有可能包含一個If-Range頭域(見14.27節)來使請求成爲一個條件請求。206狀態的響應必須包含如下的頭域:- 或者含有一個Content-Range 頭域,此頭域指明瞭響應裏的範圍;或者含有一個值爲「multipart/byteranges」的Content-Type頭域而且每部分包含Content-Range頭域。若是一個Content-Length頭域出如今響應裏,它的值必須是實際傳輸的消息主體的字節數。- Date頭域- ETag 和/或 Content-Location頭域,若是這些頭域假設在相同請求的200響應裏也會出現的話。- Expire,Cache-Control,和/或者Vary頭域,若是這些頭域的域值與之前同一變量響應中的不同。若是206響應是使用了強緩存驗證(見13.3.3)的If-Range請求的結果,那麼此響應不該該包含其餘的實體頭域。若是響應是使用了弱緩存驗證的If-Range請求的結果,那麼響應必須不能包含其餘的實體頭域;這能防止緩存裏緩存的實體主體與更新頭域之間的不一致性。另外,響應必須包含假設在相同請求的200響應裏的全部實體頭域。緩存不能把206響應和之前的緩存內容相合並若是ETag或Last-Modified頭域並不能精確匹配,見13.5.4。一個不能支持Range和Content-Range頭域的緩存不能緩存206(部分的)響應。10.3 從新定向 3xx.這類狀態碼指明用戶代理須要更進一步的動做去完成請求。進一步的動做可能被用戶代理自動執行而不須要用戶的交互,而且進一步動做請求的方法必須爲GET或HEAD。一個客戶端應該發現無限的重定向循環,由於此循環能產生網絡擁擠。注意:之前此規範版本建議一個最多能有五個重定向。內容開發者應該知道客戶端可能存在這個限制。10.3.1 300 多個選擇.(Multiple Choices)請求資源對應於衆多表現形式中的一個,每一個表現形式都有一個特定的位置(location),而且代理驅動協商(agent-driven negotiation)信息(見13章)被提供以便用戶(或用戶代理)能選擇一個更適的表現形式並重定向它的請求到那個表現形式的位置。除非是HEAD請求,不然300狀態響應應該包含一個實體,此實體包含一個資源特性和位置列表,從這個列表裏用戶或用戶代理能選擇最合適的資源的表現形式。實體格式被Content-Type頭域裏的媒體類型指定。用戶代理選擇最合適的表現形式的行爲可能會被自動執行,這依賴於實體格式和本身的能力。然而,此規範並無定義自動執行行爲的標準。若是服務器能肯定更好的表現形式,它應該爲此表現形式在Location頭域裏包含一個特定的URI來指明此表現形式的位置;用戶代理可能會利用此Location頭域自動重定向。300狀態響應是可緩存的除非被特別指明。10.3.2 301 永久移動 (Moved Permanently)請求資源被賦於一個新的永久的URI,而且任何未來對此資源的引用都會利用此301狀態響應返回的URI。具備連接編輯能力的客戶端應該能自動把請求URI的引用轉到到服務器返回的新的引用下。此響應是能緩存的除非另外聲明。新的永久URI應該在響應中被Location頭域給定。除非請求方法是HEAD,不然此響應應該包含一個超文本提示和一個指向新URI的超文本連接。若是客戶端接收了一個來自非GET或HEAD請求方法的301響應,那麼用戶代理不能自動重定向請求除非它能被用戶確認,由於這可能會改變請求提交的條件。注意:當客戶端在接收了301 狀態碼響應後,會重定向POST 請求,一些已經存在的HTTP/1.0用戶代理會錯誤的把此請求變成一個GET請求。10.3.3 302 發現(Found)請求的資源暫時地存放在一個不一樣的URI下。由於重定向的地址可能有時會被改變,客戶端應該繼續爲未來的請求利用請求URI(Request-URI)。302響應是隻有在Cache-Control或Expires頭域指明的狀況下才能被緩存。臨時的URI應該在Location頭域裏指定。除非請求方法是HEAD,不然此響應應該包含一個超文本提示和一個指向新URI的超文本連接。若是客戶端接收了一個來自非GET或HEAD請求方法的302響應,那麼用戶代理不能自動重定向請求除非它能被用戶確認,由於這可能會改變請求提交的條件。注意:RFC1945和RFC2068指定客戶端不能在重定向請求的時候改變請求方法。然而,大多數用戶代理實現會把302響應當作是303響應,從而根據Location頭域值的URI執行GET請求,無論原始的請求方法是什麼。303和307狀態響應的目的是爲使服務器明白客戶端指望哪一種類型的重定向。10.3.4 303 見其餘(See Other)請求的響應被放在一個不一樣的URI下,而且應該用GET方法得到那個資源。此方法的存在主要是讓POST調用腳本的輸出能使用戶代理重定向到一個選擇的資源。新的URI並非原始請求資源的代替引用。303響應不能被緩存,可是再次重定向請求的響應應該被緩存。不一樣的URI應該在Location頭域裏指定。除非請求方法是HEAD,除非請求方法是HEAD,不然此響應應該包含一個超文本提示和一個指向新URI的超文本連接。注意:許多HTTP/1.1之前版本的用戶代理不能理解303狀態響應。當這些客戶端比較關注於互操做性的時候,302狀態碼應該被代替利用,由於大多用戶代理對302響應的理解就是303響應。10.3.5 304 沒有改變(Not Modified)若是客戶端已經執行了條件GET請求,而且訪問服務器的資源是容許的,可是服務器上的文檔並無被改變,那麼服務器應該以此狀態碼響應。304響應不能包含一個消息主體(messagebody),而且在頭域後面老是以一個空行結束。此響應必須包含下面的頭域:- Date,除非14.18.1指明的那些規則下Date是能夠遺漏的。若是時鐘不許確的源服務器遵循這些規則,而且代理和客戶端在接收了一個沒有Date頭域的響應後加上了本身的Date(這在RFC 2086裏聲明瞭,見14.19節),緩存將會正確操做。- ETag 和/或 Content-Location頭域,若是這些頭域應在相同請求的200響應裏出現的話。- Expire,Cache-Control,和/或者Vary頭域,若是這些頭域值與之前同一變量響應中的不一致。若是條件GET請求使用強緩存驗證(見13.3.3節)時,那麼響應不該包含其它實體頭域。當條件GET使用弱緩存驗證時,那麼響應必須不能包含其它實體頭域;這能防止緩存的實體主體與更新的頭域之間的不一致性。若是一個304響應指示一個沒有被緩存的實體,那麼此緩存必須不用理會此響應,而且以無條件請求重試請求。若是緩存利用一個接收到的304響應去更新一個緩存項,那麼緩存必須用此響應響應裏任何最新的域值更新緩存項。10.3.6 305 使用代理 (Use Proxy)請求資源必須能經過代理訪問,代理的地址在響應的Location頭域裏指定。Location頭域指定了代理的URI。接收者被指望經過代理重試此請求,305響應必須被源服務器產生。注意:RFC 2068並無說明305響應必須重定向一個單獨請求而且只能被源服務器產生。不注意這些限制會有重要的安全後果。10.3.7 306沒有使用的(unused)306狀態碼被用於此規範之前的版本,是再也不使用的意思,而且此狀態碼被保留。10.3.8 307臨時重發(Temporary Redirect)請求的資源臨時存在於一個不一樣的URI下。因爲從新向可能有時會改變,因此客戶端應該繼續利用此請求URI(Request-URI)爲未來的請求。307響應只有被Cache-Control或Expire頭域指明時才能被緩存。臨時URI應該在響應的Location頭域裏給定。不然此響應應該包含一個超文本提示和一個指向新URI的超文本連接,由於許多HTTP/1.1之前的用戶代理不能理解307狀態響應。所以,此提示應該包含用戶在新的URI上重試原始請求的必需信息。若是307狀態響應.對應的請求的方法不是GET或HEAD,那麼用戶代理不能自動重定向此請求除非它能被用戶確認,由於由於這可能會改變請求提交的條件。10.4 客戶端錯誤 4xx狀態碼4xx類的目的是爲了指明客戶端出現錯誤的狀況。除了當響應一個HEAD請求,服務器應該包含一個實體,此實體包含一個此錯誤請求的解釋。此狀態碼對全部請求方法都是適合的。用戶代理應該展現任何響應裏包含的實體給用戶。若是客戶端發送數據,利用TCP的服務器實現應該當心地確保客戶端確認包含了響應的包(packets)的接收,在服務器關閉此輸入鏈接前。若是在關閉鏈接後,客戶端繼續發送數據給服務器,那麼服務器的TCP棧將發送一個重置包給客戶端,這能擦除客戶端非確認的輸入緩衝(input buffers)在這些緩衝被HTTP應用程序讀和解析以前。10.4.1 400 壞請求(Bad Request)請求不能被服務器理解,因爲錯誤的語法。客戶端不該該在沒有改變請求的狀況下重試請求。10.4.2 401 未受權的 (Unauthorized)服務器須要對請求進行用戶認證。響應必須包含一個WWW-Authenticate頭域(見14.47),此頭域包含一個適用於請求資源的受權的激勵(challenge)。客戶端會以一個Authorization頭域重試請求。若是請求包含了受權證書,那麼401響應指明對這些證書的受權失敗。若是401響應包含一個和之前響應的一樣激勵,而且用戶代理已經嘗試至少一次的受權,那麼用戶應該被呈現包含在響應裏的實體,由於這些實體可能包含相關的診斷信息。HTTP受權訪問在「HTTPAuthentication:Basic and Digest Access Authentication」[43]裏解釋。10.4.3 402 必需的支付 (Payment Required)此狀態碼爲未來的應用保留。10.4.4 403 禁用 (Forbidden)服務器理解此請求,但拒絕知足此請求。認證是沒有做用的,而且請求不該該被重試。若是請求方法是HEAD而且服務器想讓客戶端知道請求爲何不能被知足,那麼服務器起應該在響應實體裏描述此拒絕的緣由。若是服務器不但願告訴客戶端拒絕的緣由,那麼404 狀態碼(NotFound)響應將被使用。10.4.5 404 沒有找到(Not Found)服務器並無找到任何能夠匹配請求URI 的資源。沒有跡象代表條件是暫時或永久的。410(Gone)狀態響應應該被使用,若是服務器經過內部配置機制知道一箇舊資源永遠不能得到而且也沒有轉發地址。此狀態碼一般被使用,當服務器不但願精確指出請求爲什麼被拒絕,或者當沒有任何其它響應可用時。10.4.6 405 方法不被容許(Method Not Allowed)此狀態碼錶示請求行(Request-Line)裏的方法對此資源來講不被容許。響應必須包含一個Allow頭域,此頭域包含以一系列對此請求資源有效的方法。10.4.7 406 不可接受的 (Not Acceptable)根據客戶端請求的接受頭域(譯註:如:Accept, Accept-Charset, Accept-Encoding, 或者 Accept-Language),服務器不能產生讓客戶端能夠接受的響應。除非是HEAD請求,不然響應應該包含一個實體,此實體應該包含一個可得的實體特性和位置列表,經過它用戶或用戶代理能選擇最合適本身的。實體格式被媒體類型指定。依賴於此格式和用戶代理的自己能力,選擇最合適的可能會被自動執行。然而,此規範並無定義自動執行選擇的標準。注意:HTTP/1.1服務器被准許根據請求裏的接受頭域會返回不可接受的響應。在一些狀況下,這可能更傾向於發送一個406響應。用戶代理被鼓勵觀察到來的響應的頭域來肯定此響應是不是可接受的。若是響應是不可接受的,用戶代理應該暫時中止剩餘數據的接收而且詢問用戶而後去決定進一步的動做。10.4.8 407 須要代理驗證(Proxy Authentication Required)此狀態碼和401(Unauthorized)類似,可是指示客戶端首先必須利用代理對本身驗證。代理必須返回一個Proxy-Authenticate頭域(見14.33節),此頭域包含一個適用於代理的受權激勵。客戶端可能利用一個合適的Proxy-Autorization頭域去重試此請求(見14.34節)。HTTP訪問受權在「HTTP Authentication;Basic and Digest Access Authentication」[43]。10.4.9 408 請求超時(Request Timeout)客戶端在服務器等待的時間裏不能產生請求。客戶端可能在之後會重試此請求。10.4.10 409 衝突 (Confilict)請求不能完成因爲和當前資源的狀態衝突。此狀態碼只被容許出如今指望用戶也許能解決此衝而且能從新提交此請求的狀況下。響應主體應該包含足夠的爲用戶認識此資源衝突的信息。理想的狀況下,響應實體應該包含足夠爲用戶或用戶代理解決此問題的信息;然而,這是也許沒有可能而且也沒有必要。衝突最可能發生在響應PUT請求的時候。例如,若是版本被使用而且被PUT的實體包含資源的改變,而這些改變會和之前的(第三方的)請求的相沖突,那麼服務器應該使用409響應去指明它不能完成此請求。在這種狀況下,此響應的實體可能包含這兩個版本的差別點,響應的實體格式以Content-Type頭域指定。10.4.11 410 不存在(gone)請求資源在源服務器上再也不可得而且也沒有轉發地址可用。此條件被認爲是永久的。具備連接編輯能力的客戶端應該在用戶確認後刪除請求URI的引用。若是服務器不知道或不容易去肯定條件是不是永久的,那麼此404(沒有發現)狀態響應將被代替利用。響應是可緩存的,除非另外申明。410響應主要的目的是爲了web維護任務,這經過告訴接收者資源已經不可得了而且告訴接收者服務器擁有者已經把那個資源的遠程鏈接給移除了。對有時間限制的,推銷性的服務,和對再也不繼續工做在服務器站點人員的資源,這個事件(410響應)是很是廣泛的。它不須要把全部長久不可得的資源標記爲「gone」或者保持任意長時間—這須要服務器擁有者本身的判斷10.4.12 411 長度必需 (Length Required)服務器拒絕接受請求裏沒有包含Content-Length頭域的請求。客戶端能夠重試此請求若是它添加了一個有效的Content-Length頭域,此頭域值指定了請求消息裏消息主體的長度。10.4.13 412 先決條件失敗 (Precondition Failed)在一個或多個請求頭域裏指定的先決條件當在服務器上測試爲false時返回的響應。此響應容許客戶端把先決條件放放到當前資源的元信息(頭域數據)之上,這樣能防止請求方法被應用於一個非目的性的資源。10.4.14 413 請求實體太大服務器拒絕處理請求由於請求實體太大以至達到服務器不肯意去處理。服務器可能關閉此鏈接去防止客戶端繼續請求。若是條件是暫時的,服務器應該包含一個Retry-After頭域用來指明此條件是暫時的而且指明客戶端應該何時重試。10.4.15 414 請求URI太長(Request-URI Too Long)服務器拒絕爲請求服務由於此請求URI太長了以致於服務器不能解析。這種狀況是不多的,只發生在當客戶端把POST請求不合適地轉換爲帶有大量查詢信息的GET請求時。10.4.16 415 不被支持的媒體類型(Unsupported Media Type)服務器拒絕爲請求服務,由於請求的實體的格式不能被此方法的請求資源所支持。10.4.17 416 請求範圍不知足 (Requested Range Not Satisfiable)服務器返回一個此狀態碼的響應,若是請求包含一個Range請求頭域(見14.35節),而且此頭域裏range-specifier值沒有和已選資源的當前extent值重疊,而且請求沒有包含一個If-Range請求頭域。(對byte-ranges來講,這意味着byte-range-spec的全部first-byte-pos值大於選擇的資源的當前長度)。當此狀態碼響應是在byte-range請求返回時,響應應該包含一個Content-Range實體頭域用來指定已選資源的當前長度(見14.16節)。響應不能使用multipart/byteranges媒體類型。10.4.18 417 指望失敗(Expectation Failed)Expect請求頭域裏指定的但願不能被服務器知足,或者,若是服務器是代理,那麼能肯定請求不能被下一站(next-hop)服務器知足。10.5 服務器錯誤 5xx (Server Error)這類狀態碼指明服務器處理請求時產生錯誤或不能處理請求。除了HEAD請求,服務器應該包含一個實體,此實體用來解釋錯誤,和是不是暫時或長期條件。用戶代理應該展現實體給用戶。此響應狀態碼能應用於任何請求方法。10.5.1 500 服務器內部錯誤 (Internal Server Error)服務器遇到了一個意外條件,此條件防止服務器知足此請求。10.5.2 501 不能實現 (Not Implemented)服務器沒有能力去知足請求。當服務器不能識別請求方法而且不支持它請求資源的時候,這個響應是很合適的。10.5.3 502 壞網關 (Bad Gateway)此響應說明:做爲網關或代理的服務器從上游(upstream)服務器接收了一個無效的響應。10.5.4 503 服務不能得到(Service Unavailable)因爲服務器暫時地過載或維護,服務器不能處理請求。這就是說這是暫時條件,此條件將會在一些延時後被減輕。延遲的長度能夠在Retry-After頭域裏指定。若是沒有Retry-After被給,那麼客戶端應該處理此響應就像它處理500響應同樣。注意:503狀態碼的存在並非意指服務器當產生過載時必須利用它。一些服務器可能但願拒絕此鏈接。10.5.5 504 網關超時(Gateway Timeout)做爲網關或代理的服務器在不能及時地接收一個從URI指定的上游(upstream)服務器(例如:HTTP,FTP,LDAP服務器)或者其餘的輔助性服務器(例如:DNS服務器)的響應。注意:當DNS查找超時時,一些部署的代理將會返回400或500響應。10.5.6 505 HTTP版本不支持 (HTTP version Not Supported)服務器不能支持,或拒絕支持此HTTP協議版本消息。505響應指明服務器不能或不肯意完成這樣的請求,這在3.1中描述了。此響應應該包含一個實體,此實體描述了爲何此協議版本不被支持和其餘能被服務器支持的協議版本。11.訪問認證(Access Authentication)HTTP提供一些可選的激勵響應(challenge-response)認證(authentication)機制,這些機制能被用於服務器去激勵客戶端請求,使客戶端提供認證信息。經常使用訪問認證框架,還有「basic」和「digest」認證規範,都在「HTTP Authentication:basic and Digest AccessAuthentication」[43]規範裏指定。HTTP/1.1 規範採用了「激勵(chanllenge)」和「證書(credentials)」的定義。12.內容協商 (Content Negotiation)大多數響應包含一個實體,此實體包含人類用戶能理解的信息。一般,但願響應能提供給用戶相應請求的「最可得」(best available)的實體。對服務器和緩存來講,不幸的是,並非全部的用戶都對這個「最可得」的實體有相同的喜愛,而且並非全部的用戶代理(如web瀏覽器)都能一致的呈現這些實體。因此,HTTP提供了幾個「內容協商」的機制 — 當有多個可得的表現形式的時候,對給定響應去選擇最好的表現形式的過程。注意:沒有稱作「格式協商」(譯註:「格式」指的是「媒體類型」)的,這是由於選擇的表現形式可能會有相同的媒體類型,但卻根據其它能力(capabilities),例如一種不一樣的語言。任何包含一個實體主體的響應應該由受協商來決定,包括錯誤響應。在HTTP中,有兩種類型的內容協商:服務器驅動協商和代理驅動協商。這兩種類型的協商具備正交性,所以能被單獨使用或聯合使用。一個聯合使用的協商會被叫作透明協商,這發生在當緩存利用源服務器提供的代理驅動協商信息爲後續請求提供服務器驅動協商的時候。12.1 服務器驅動協商(Server-driven Negotiation)若是響應的最好的表現形式的選擇是經過服務器上的算法來實現,那麼這種方式的協商稱作服務器驅動協商。選擇是基於響應可得的表現形式(根據不一樣的維度,響應會不一樣;例如,語言,內容編碼,等等)和請求消息裏特定的頭域或附屬於請求的其餘信息(如:網絡客戶端的地址)。服務器驅動協商是有優勢的,當從可行的表現形式裏進行選擇的算法對用戶代理來講描述是比較難的(譯註:代理驅動協商),或者當服務器指望經過第一個響應發送「最好的猜想」(「best guess」)給客戶端時(若是「最好的猜想」對用戶是合適的,能避免後續請求的迴路延遲)的時候。爲了改善服務器的猜想,用戶代理應該包含請求頭域(Accept,Accept-Language,Accept-Encoding,等等),這些頭域能描述它對響應的喜愛。服務驅動協商有以下缺點:1. 對服務器來講不可能確切地決定什麼對用戶來講是最好的,由於那須要對用戶代理和響應目的的全面理解(如:用戶到底想把響應展現到屏幕仍是打印到紙上?)。2. 使用戶代理在而每個請求裏描述它的能力即不高效(假定只有少許的響應卻擁有多個表現形式)也潛在地侵犯用戶的隱私。3. 使源服務器的實現變得複雜,而且使爲請求產生響應的算法實現變得複雜。4. 可能會限制公有緩存(public cache)爲多個客戶請求利用相同響應的能力HTTP/1.1包含下面的請求頭域來使服務器驅動協商啓動,這些請求頭域描述了用戶代理的能力和用戶喜愛:Accept(14.1 節),Accept-Charset(14.2 節),Accept-Encoding(14.3節),Accept-Language(14.4節),和User-Agent(14.43節)。然而,一些源服務器並不僅侷限於這些維度,這些服務器能基於請求的任何方面來讓響應不一樣,這些方面包括請求頭域以外的信息或在此規範裏沒有定義的擴展頭域信息。Vary頭域能被用來表達服務器選擇表現形式(representation)利用的參數,表現形式受服務器驅動協商決定的。見14.44節描述了Vary頭域如何被服務器的使用,13.6節描述了Vary頭域如何被緩存的使用。12.2 代理驅動協商 (Agent-driven Negotiation)對代理驅動協商來講,在源服務器一個初始響應後,響應的最好表現形式的選擇是被用戶代理執行的。選擇是基於響應的一系列可得的表現形式,這些表現形式被包含在初始響應的頭域或初始響應的實體主體(entity-body)裏,每一個表現形式被一個屬於本身的URI指定。從這些表現形式中選擇可能被自動執行(若是用戶代理有能力這樣作)或者被用戶從超文本鏈接菜單中手工選擇。代理驅動協商是有優勢的,當響應可能只能根據通常用途的維度(如:類型,語義,編碼)而不一樣的時候,當源服務器不能經過查看請求而斷定用戶代理能力的時候,當共有緩存(publiccache)被用來分派服務器的承載和減小網絡使用的時候。代理驅動協商也須要第二次請求去得到最好表現形式的缺點。第二次請求只有當緩存被使用時纔是有效率的。另外,此規範沒有定義用戶代理自動選擇表現形式的機制,雖然它也沒有避免這樣的機制被做爲一個擴展使用於HTTP/1.1。HTTP/1.1定義了300(多個選擇)和406(不接受的)狀態響應來進行代理驅動協商,當服務器不能或不肯意利用服務器驅動協商來提供一個不一樣響應(a varying response)的是時候。12.3 透明協商(Transparent Negotiation)透明協商是服務器驅動協商和代理驅動協商的結合體。當一個緩存接收到服務器的響應,而且響應裏提供了一系列可得的表現形式(就像在代理驅動協商裏的響應同樣)而且緩存能理解維度的差別,那麼此緩存變得有能力表明源服務器爲那個資源的後續請求去執行服務器驅動協商。透明協商的優勢在於它能分發源服務器的協商工做而且能移除代理驅動協商的第二次請求的延遲,由於緩存能正確的猜想到合適的響應並返回給請求端。此規範沒有定義透明協商的機制,雖然它也沒有避免任何這樣的機制做爲擴展被用於HTTP/1.1。13 HTTP中的緩存HTTP一般應用於能經過採用緩存技術提升性能的分佈式信息系統。HTTP/1.1協議包括的許多使緩存儘量的工做的元素。由於這些元素與協議的其餘方面有着千絲萬縷的聯繫,並且他們相互做用、影響,所以有必要分別從方法(methods),頭(headers),響應狀態碼來介紹緩存的基本設計。若是緩存不能改善性能,他將一無用處。HTTP/1.1中緩存能夠在許多狀況下排除發送請求和發送完整響應。前者減小了網絡迴路的數量;咱們利用一個「過時(expiration)」機制來爲此目的(見13.2節)。後者減小了網絡應用的帶寬;咱們用「驗證(validation)」機制來爲此目的(見13.3)。對行爲,可行性,和關閉的操做的要求須要咱們能放鬆了語義透明性。HTTP/1.1協議容許服務器,緩存,和客戶端在必要的時候能顯式地下降透明性。然而,由於不透明的操做能混淆非專業的用戶,同時可能和某個服務器應用程序不兼容(例如訂購商品),所以協議透明性在下面狀況下才能被放鬆:-- 當被客戶端或源服務器放鬆時,只能被一個顯式的協議層(protocol-level)請求放鬆-- 當被緩存或被客戶端放鬆時,只能在出現一個對終端用戶的顯式的警告時才能被放鬆所以,HTTP/1.1協議提供這些重要的元素:1.提供了徹底語義透明性(full semantic transparency)的特性當被通訊全部方須要時2. 容許源服務器或用戶代理顯式地請求和控制非透明性操做的協議特性3. 容許緩存給響應綁定警告信息(經過Warning頭域來實現)的協議特性,當這些響應沒有保持語義透明的請求近似性(requested approximation)時一個基本的原則是客戶端必須可以發現任何語義透明性的潛在放鬆規則。注意:服務器,緩存,或者客戶端的實現者可能會面對設計上的決策,它並無明確地在此規範裏討論。若是一個決策影響了語義透明性,那麼實現者將會在維持語義透明性上犯錯,除非一個仔細且完整的分析能向咱們展現打破透明性帶來的好處。13.1.1 緩存正確性(Cache Correctness)一個正確的緩存必須能用緩存裏最新的(up-to-date)響應來響應請求(見13.2.5,13.2.6,和13.12),已緩存的響應必須知足下面的條件:1.已緩存的響應已被檢測應與經過源服務器重驗證後返回的響應等價。2.已緩存的響應是足夠保鮮(fresh)的(見13.2節)。缺省的狀況下,這意味着此響應必須知足客戶端,源服務器,和緩存(見14.9節)的最少嚴格(least restrictive freshness)保鮮要求;若是源服務器指定了保鮮要求,那麼它是源服務器本身的保鮮要求。若是一個已緩存的響應,因爲客戶端和源服務器的最多嚴格(most restrictive freshness)保鮮要求,而不是足夠保鮮的,那麼在仔細考慮的狀況下,緩存也許仍然會根據一個合適的警告頭域(見13.15和14.46)返回此已緩存的響應,除非這個響應不被容許(例如:經過」no-store」 cache-directive ,或者經過一個」no-cache」 cache-request-directive;見14.9節)。3.已緩存的響應是一個合適的304(沒有被改變),305(代理重定向),或 錯誤(4xx或者5xx)響應消息。若是緩存不能同源服務器通訊,若是已緩存的響應能正確的服務於請求,那麼一個正確的緩存應該用它緩存的響應去響應請求;若是不能服務器於此請求,那麼緩存必須能返回一個錯誤或一個警告指示通訊失敗。若是緩存從服務器端接收到一個響應(或者是一個完整的響應,或者一個304(沒有改變)的響應),此響應應該是服務器正常狀況下發送到請求的客戶端的響應,而且此響應並再也不新鮮,那麼此緩存應該把此響應轉發給請求客戶端而不須要添加一個新的Warning頭域(而不須要移去已經存在的Warning頭域)。緩存並非簡單的由於傳輸中響應變得陳舊而去嘗試重驗證響應;這可能會致使一個無限的循環。用戶代理接收一個陳舊的但沒有Warning頭域的響應,它應該提示用戶一個警告信息。13.1.2 警告信息(Warnings)不管什麼時候,緩存返回一個響應,此響應既不是第一手的(first-hand)也不是足夠保鮮(在13.1.1節的條件2),那麼緩存必須利用一個Warning經常使用頭域來警告產生的影響。Warning頭域和當前定義的警告在14.46節裏描述。這些警告容許客戶端去採起合適的動做。Warning頭域可能被用於緩存相關的和其餘的目的。使用Warning頭域而不是錯誤狀態碼,區別因而否是真正的錯誤。警告被賦予三位數字警告碼(warn-codes)。第一個數字指明:在一個成功的重驗證以後,警告是否必須或沒必要從緩存項裏刪除。1xx 警告描述了響應的保鮮或重驗證狀態,而且這些狀態必須在一個成功重驗證以後刪除。1xx警告碼(warn-codes)多是由緩存產生的,當驗證一個緩存項時。此警告碼不能被客戶端產生。2xx 警告描述了實體主體或實體頭域的某些方面的信息,這些信息不能被重驗證修改(例如,一個實體主體的有損壓縮),而且這些信息不能在成功重驗證以後被刪除。見14.46節關於警告碼的定義。HTTP/1.0緩存將緩存全部響應中的警告,而且不會刪除第一類警告。被要通往到HTTP/1.0緩存的響應,存在其響應中的警告攜帶一個額外的warning-date域可防止未來的HTTP/1.1接收端信任一錯誤的已緩存的警告。警告一樣攜帶一個警告文本。此文本多是任何合適的天然語義(可能基於客戶端請求的Accept頭域),同時包含一個可選擇的關於何種字符集被使用的聲明。多個警告可能會綁定一個響應(或者被源服務器發送或者被一個緩存發送),而且包括多個警告能夠共用一個警告碼。例如,服務器可能會以英語和法語提供相同的警告。當多個警告綁定一個響應時,有時候不可能把全部的警告都展現給客戶。HTTP版本沒有指定嚴格優先規則去決定哪一個警告優先展現和以何種順序去展現,可是能夠探索一些方法。13.1.3 緩存控制機制 (Cache-control Mechanism)HTTP/1.1基本緩存機制(服務器指定過時時間和驗證器)對緩存是隱式指令。某些狀況下,服務器或客戶端可能須要給HTTP緩存提供顯式指令。咱們利用Cache-Control頭域爲此目的。Cache-Control頭域容許客戶端或服務器在請求或響應裏傳輸多個指令。這些指令經常覆蓋缺省的緩存算法。做爲一個經常使用規則,若是頭域值中存在一個明顯的衝突,那麼最多嚴格解釋(most restrictive interpretation)的頭域值會被應用(也就是說,能保留語義透明性的值)。然而,一些狀況下,cache-control 指令被顯式地用來削弱語義透明性的近似性(例如,」max-stale」 或者 「public」)。Cache-control指令在14.9節被描述。13.1.4 顯式用戶代理警告(Explicit User Agent Warnings)不少用戶代理容許用戶覆蓋基本緩存機制。例如,用戶代理可能容許用戶指定緩存實體(即便實體明顯是陳舊的)永遠不要被驗證。或者,用戶代理可能習慣於給任何請求加上「Cache-Control:max-stale=3600」。用戶代理不該該缺省的執行非透明行爲或致使非正常且無效率的緩存行爲,可是能夠經過一個顯式的用戶動做,代理可能會被顯式地設置去這樣作。若是用戶已覆蓋基本緩存機制,那麼用戶代理不管什麼時候遇到不能知足服務器透明性要求(server’s transparency requirements)的信息被展示時,用戶代理應該顯式地給用戶以指示(特別是,若是被展示實體被認爲是陳舊的)。由於協議一般容許用戶代理去斷定響應是不是陳舊,因此此指示只須要實際發生時才被展示。此指示沒必要是對話框;它應該是一個圖標(例如,一個正在腐爛的魚)或者一些其餘的指示器。若是用戶以某種方式已覆蓋緩存機制,同時這種方式可能非正常地下降了緩存效率,那麼用戶代理應該繼續指示此狀態給用戶(例如,經過一個圖片顯示)以便用戶能謹慎地消費額外資源或忍受額外延遲。13.1.5 規則和警告的例外狀況(Exceptions to the Rules and Warnings)在某些狀況下,緩存的操做者能夠選擇去設置返回陳舊的響應,即便此響應沒有被客戶端請求。這個決定不該該被輕易決定,可是爲了實用性或性能方面的要求可能會這樣作,特別是當緩存和源服務器鏈接很差時。無能什麼時候當緩存會返回一個陳舊的響應時,緩存必須給此響應作個標記(利用Warning頭域),這樣能使客戶端軟件能提醒用戶可能會存在潛在的問題。一樣能夠容許用戶代理去採起步驟得到第一手的或保鮮的響應。因爲這個緣由,若是客戶端顯式地請求第一手的或保鮮的響應,緩存就不該該返回一個陳舊的響應,除非因爲技術或策略方面的緣由而不能遵照。13.1.6 由客戶控制的行爲(Client-controlled Behavior)當源服務器(退一步講,能夠是經過在響應裏添加年齡的中間緩存)是過時信息的主要來源時,在某些狀況下,客戶端可能須要控制緩存決定是否返回一個已緩存的響應而不須要經過服務器驗證它。客戶端經過利用一些Cache-Control頭域的指示命令(directives)來達到此目的。客戶端的請求可能會指定本身願意接受一沒有通過驗證響應的最大年齡(age);指定0值會強迫緩存重驗證全部的響應。客戶端一樣也會指定在響應過時以前的最小保持時間。這兩個選項會加強對緩存行爲的限制,所以不能進一步地放鬆緩存語義透明的近似性(approximation ofsemantic transparency)。客戶端一樣可能會指定它願意接受(accept)到達的陳舊響應。這放鬆了對緩存的限制,同時這可能違反了源服務器對語義透明性的限制,可是這能夠支持脫機操做(disconnectedoperation),或者高可用性(high availability)當鏈接很差時。13.2 過時模型 (Expiration Model)13.2.1 服務器指定過時(Server-Specified Expiratiion)HTTP緩存會工做的很好,這是由於緩存能徹底地避免客戶端對源服務器的請求。避免請求的主要機制是使服務器經過提供一個未來的顯式過時時間(explicit expiration time)以指示響應能夠知足後續的請求。也就是說,緩存能返回一個保鮮(fresh)的響應而不須要和源服務器接觸。服務器能夠給響應賦一個未來的顯式過時時間(explicit expiration time),並確信在過時時間以前實體不會改變。這一般能保持語義透明性,只要服務器對過時時間仔細斟酌。過時機制只能應用於從緩存構建響應,而不能應用於當即轉發給客戶端的第一手(first-hand,見1.3節術語)響應。若是源服務器但願強制語義透明的緩存去驗證每一個請求,它給顯式過時時間( explicitexpiration time)設爲過去。這就是說響應老是陳舊的,因此當緩存利用此響應去服務於後續請求時,緩存應該驗證此響應。見14.9.4節,有更嚴格的方式來進行重驗證。若是源服務器但願強迫任何HTTP/1.1緩存(無論此緩存是怎樣設置的)去驗證每個請求,源服務器應該利用 「must-revalidate」緩存控制指令(見14.9節)。服務器指定顯式過時時間是經過利用Expires頭域或Cache-Control頭域裏的max-age緩存控制指令。過時時間不能被用於強制客戶代理去刷新顯示或重載資源;過時的語義只能應用於緩存機制,而且當對資源的發起新請求時,此機制只需檢測此資源的過時狀態。見13.13節,關於緩存和歷史機制的差別。13.2.2 啓發式過時由於源服務器不能老是提供一個顯式過時時間(explicit expiration time),HTTP緩存一般會賦予一個啓發式過時時間(heuristic expiration time),它採用一種算法,此算法利用其它頭域的值(例如Last-Modified時間)去估計一個合理的過時時間。HTTP/1.1規範沒有提供特定的算法,可是卻增強了算法結果最壞狀況的限制。由於啓發式過時時間可能會損壞語義透明性,他們應該被謹慎地使用,而且咱們鼓勵源服務器儘量提供顯式過時時間(explicit expirationtimes)。13.2.3 年齡(Age)計算爲了瞭解緩存項(譯註:緩存項是用來響應請求的,它包含已緩存的響應實體)是不是保鮮的(fresh),緩存須要知道其年齡是否已超過保鮮壽命(freshness lifetime)。咱們在13.2.4節中討論如何計算保鮮壽命,本節討論如何計算響應或緩存項的年齡。在討論中,咱們利用術語「now」來表示「執行計算主機上時鐘的當前值」。使用HTTP協議的主機,特別是運行於源服務器和緩存的主機,應該使用NTP[28] 或其餘相似協議來同步其時鐘到全球(globally)精確時間標準上。HTTP1.1協議要求源服務器儘量在每一個響應裏附加一個Date頭域,而且賦予響應產生的時間(見14.18節)。咱們利用術語「date_value」去表示Date頭域的值,這是一種適合於運算操做的表示方法。當從緩存裏獲取響應消息時,HTTP/1.1利用Age響應頭域來表達響應消息的估計年齡。Age響應頭域值是緩存對響應自從被源服務器產生或重驗證到如今的時間估計值。實際上,年齡的值是響應從源服務器途徑每個緩存的逗留時間的總和,再加上響應在網絡路徑上傳輸的時間。咱們用「age_value」來表示Age頭域的值,這是一種適於算術操做的表示方法。一個響應的年齡(age)能夠經過兩種徹底獨立的途徑來計算::1.now - date_value,若是本地時鐘與源服務器時鐘同步的至關好。若結果爲負,則取零。2.age_value,若是途徑響應路徑(response path)的全部緩存均遵循HTTP1.1協議。若是咱們有兩種不一樣的方法計算響應的年齡,咱們能夠合併兩者以下:corrected_received_age = max(now – date_value,age_value)而且只要咱們有近似同步時鐘或全HTTP/1.1(all-HTTP/1.1)路徑,就能獲得一個可信賴的(保守的)結果。因爲網絡附加延時,會在服務器產生響應與下一個緩存或客戶端接收響應之間產生時間延遲。若是不經修訂,這一延遲會帶來不正常的低年齡。因爲致使產生年齡值的請求是早於年齡值的產生,咱們能校訂網絡附加延遲經過記錄請求產生的時間。而後,當一個年齡值被接收後,它必須被解釋成相對於請求產生的時間,而不是相對響應接收的時間。無論有多少延遲,此算法會致使保守的結果。因此,咱們計算:corrected_initial_age = corrected_received_age + (now - request_time)這裏「request_time」是請求的發送時間。當緩存收到響應時,年齡計算的算法總結以下:/** age_value* is the value of Age: header received by the cache with this response.* date_value* is the value of the origin server's Date: header* request_time* is the (local) time when the cache made the request* that resulted in this cached response* response_time* is the (local) time when the cache received the response* now* is the current (local) time*/apparent_age = max(0, response_time - date_value); //緩存收到響應時響應的年齡corrected_received_age = max(apparent_age, age_value);response_delay = response_time - request_time;corrected_initial_age = corrected_received_age + response_delay;resident_time = now - response_time; //即收到響應到如今的時間間隔current_age = corrected_initial_age + resident_time;緩存項(cache entry)的current_age是緩存項從被源服務器最後驗證到如今的時間間隔(以秒記)再加上corrected_initial_age。當從緩存項裏產生一條響應時,緩存必須在響應裏包含一個Age頭域,它的值應該等於此緩存項的current_age值。Age頭域出如今響應裏說明響應不是第一手的(first-hand)(譯註:第一手的說明,響應是直接來自於源服務器到達接收端的,而不是來自於緩存裏保存的副本)。然而相反的狀況並不成立,由於響應裏缺乏Age頭域並不能說明響應是第一手的(fisrt-hand),除非全部請求路徑上的緩存都遵循HTTP/1.1協議(也就是說,之前HTTP版本緩存沒有定義Age頭域)。13.2.4 過時計算(Expiration Calculations)爲了肯定一條響應是保鮮的(fresh)仍是陳舊的(stale),咱們須要將其保鮮壽命(freshness lifetime)和年齡(age)進行比較。年齡的計算見13.2.3節,本節講解怎樣計算保鮮壽命,以及斷定一個響應是否已通過期。在下面的討論中,數值能夠用任何適於算術操做的形式表示。咱們用術語「expires_value」來代表Expires頭域的值。咱們用術語「max_age_value」來表示Cache-Control頭域裏「max-age」控制指令的值(見14.9.3節)。max-age指令優於Expires頭域執行,因此若是max-age出如今響應裏,那麼定義以下:freshness_lifetime = max_age_value不然,若Expires頭域出如今響應裏,定義以下:freshness_lifetime = expires_value - date_value注意上述運算不受時鐘偏差影響,由於全部信息均來自源服務器。若是Expires, Cache-Control:max-age, 或 Cache-Control:s-maxage (見 14.9.3) 均未在響應中出現,且響應沒有包含對緩存的其餘控制,那麼緩存能夠用啓發式算法計算保鮮壽命(freshness lifetime)。緩存必須對年齡大於24小時的響應附加113警告,若是此響應不帶這種警告。一樣,若是響應有最後修改時間(Last-Modified time),啓發式過時值應不大於從那個時間開始到如今這段時間間隔的某個分數。典型設置爲間隔的10% 。計算響應是否過時很是簡單:response_is_fresh = (freshness_lifetime > current_age)13.2.5 澄清過時值(Disambiguation Expiration Values)因爲過時值容易被任意設置,有可能兩個緩存包含同一資源的不一樣保鮮值(fresh values)。若是客戶端執行獲取請求接收到一個非第一手的響應,此請求響應在客戶端緩存裏仍然是保鮮的,而且緩存項裏的Date頭域的值比新響應的Date頭域值要新,那麼客戶端應該忽略此新響應。若是這樣的話,它能夠以「Cache-Control:max-age=0」指令(見14.9節)重試請求,從而去強制和源服務器重驗證。若是一個緩存對同一個表現形式(representation)擁有兩個保鮮響應卻有不一樣的驗證器,那麼緩存必須利用Date頭域值最近的響應。這種狀況可能發生因爲緩存會緩存來自其它緩存的響應,或者因爲客戶端已要求重載或重驗證一個顯然保鮮的緩存項的。13.2.6 澄清多個響應(Disambiguating Multiple Response)由於客戶端可能收到經多個路徑而來的響應,因此某些響應會通過一些緩存集,某些響應會通過其它緩存集,客戶端收到響應的順序可能與源服務器發送響應的順序不一樣。咱們但願客戶端利用最新的響應,即便舊響應仍然是保鮮的。實體標籤(entity tag)和過時值(expiration value)都不能決定響應的順序,由於可能會出現晚一點的響應故意攜帶過早的過時時間(expiration time)。日期值的精度被規定只有一秒。當客戶端嘗試重驗證一個緩存項的時,而且接收到的響應裏Date頭域晚於已存在的緩存項,那麼客戶端應該無條件的重試請求,而且包含Cache-Control: max-age=0去強制任何中間緩存經過源服務器來驗證(validate)它們的緩存副本,或者Cache-Control: no-cache去強制任何中間緩存去從源服務器得到一個新的副本。13.3 驗證模型(Validation Model)當緩存擁有一箇舊緩存項而且想利用它來做爲客戶端請求的響應時,緩存必須首先經過源服務器(或者可能經過一個有保鮮響應的中間緩存)對其進行驗證看是否此緩存項可用。咱們稱作「驗證(validating)」此緩存項。咱們能夠沒必要花代價來重傳完整響應(full response),而且在緩存項無效時能夠沒必要產生額外的迴路,所以HTTP1.1 協議支持使用條件方法(conditional methods)。.協議支持條件方法(conditional methods)的關鍵特徵是圍繞「緩存驗證器(cachevalidator)」展開的。當源服務器產生一個完整響應(full response)時,它同時會附加一些驗證器給響應,這些驗證器和緩存項一塊兒保存。當客戶端(用戶代理或緩存)對有緩存項的資源執行條件請求時,客戶端在請求裏包含一個相關的驗證器(validator)。服務器(有多是源服務器或緩存服務器)覈對請求裏的驗證器和當前此實體本地驗證器是否匹配,若是匹配(見13.3.3),則返回一個特定狀態碼(一般爲304(沒有改變))的響應並不包含實體主體(entity body)。若是不匹配,服務器就返回完整響應(包含實體主體)。這樣,若是驗證器匹配,咱們就避免了傳輸完整響應(full response);同時,若是驗證器不匹配,也避免了額外的迴路。在HTTP1.1協議中,一個條件請求和普通的請求類似,除條件請求攜帶一些特殊的頭域(這些頭域包含驗證器),包含這些特殊的頭域就隱含地代表請求方法(一般是GET方法)爲條件請求方法。協議中緩存驗證條件有正向條件和負向條件。也就是說有存在驗證器匹配,請求方法會執行;驗證器不匹配,請求方法也可能會執行。注意:缺乏驗證器的響應可能會被緩存,並且會被緩存用來爲請求提供服務直到緩存副本過時,除非用緩存控制指令顯式地禁止緩存這樣去作。然而,若是緩存沒有實體的驗證器,那麼緩存不能執行條件方法來獲取資源,這就意味着在緩存副本過時以後不會獲得刷新。13.3.1 最後修改日期 (Last-Modified Dates)Last-Modifed實體頭域值常常被用做一個緩存驗證器。簡而言之,若是實體自從Last-Modifed值以後沒有改變,那麼緩存項被認爲是有效的。13.3.2 實體標籤緩存驗證器(Entity Tag Cache Validators)ETag響應頭域值是實體標籤,它提供了一個「晦澀(opaque)」緩存驗證器。當在不方便保存修改日期時,當在HTTP日期值的一秒精度不能知足須要時,或當源服務器但願避免使用修改日期產生的衝突時,經過實體標籤能獲得更可靠的驗證,。實體標籤在3.11節描述了。使用了實體標籤的頭域在14.19,14.24,14.26和14.44節裏描述了。13.3.3 強,弱驗證器 (Weak and Strong Validators)因爲源服務器和緩存會比較兩個驗證器來肯定他們是否表明相同的實體,因此一般但願實體發生任何變化時驗證器也相應變化,這樣的驗證器爲強驗證器。.然而,可能存在這樣的請求,服務器傾向於僅在實體發生重要的語義變化時才改變驗證器,而在實體的某些方面不發生重大改變時就不改變驗證器。在資源變化時驗證器未必變化的驗證器稱爲弱驗證器.。實體標籤一般是強驗證器,但協議提供一種機制來使實體標籤變成弱驗證器。能夠認爲強驗證器在實體的每一字節變化時而變化,而弱驗證器僅在實體的語義變化時才變化。換言之,咱們能認爲強驗證器是特定實體的標識,而弱驗證器是同一類語義等價實體的標識。注: 強驗證器的例子:一個整數他會隨着每次實體發生變化而遞增。一個實體的修改時間,若是以秒爲精度,能被看做爲弱驗證器,由於在一秒內資源可能改變兩次。對弱驗證器的支持是可選擇的。然而,弱驗證器容許更有效地緩存等價對象。.客戶端產生請求並把驗證器包含在一個驗證頭域(validating header fiield)裏時或服務器比較兩個驗證器的時候均用到驗證器。強驗證器可在任何狀況下使用,而弱驗證器僅在不依賴於嚴格相等時纔可用。當客戶端產生條件GET請求來請求一個完整實體時,任何類型的驗證器均可以使用。然而,子範圍(sub-range)請求時只能使用強驗證器,不然客戶端可能會獲得一個不一致的實體。客戶端能夠在發出簡單(非子範圍)GET請求裏既能夠利用弱驗證器也能夠利用強驗證器。客戶端不能利用弱驗證器在其它的請求形式裏。HTTP1.1協議定義驗證的惟一功能就是比較。有兩種驗證器比較方法,這依賴於比較的背景是否容許利用弱驗證器。.- 強比較方法:若是相等,兩驗證器必須徹底一致,而且兩個驗證器都是強驗證器。.- 弱比較方法:若是相等,兩驗證器必須徹底一致,但它們中的任何一個或所有被標明「弱」(「weak」)的不會影響結果。實體標籤是強驗證器除非它被顯式地標記爲弱(weak)的。3.11節給出了實體標籤的語法。最後修改時間(Last-Modifed頭域的值)被用做請求的驗證器時默認爲弱驗證器,除非知足下列規則才斷定它是強驗證器:.- 此驗證器正在被源服務器用來和當前實體驗證器進行比較,而且- 源服務器知道相關的實體不會在當前驗證器涵蓋的秒內改變兩次,或者- 此驗證器即將被客戶端用於If-Modified-Since 或者 If-Unmodified-Since頭域裏,由於客戶端有一個關於實體的緩存項,而且- 緩存項包含一個日期值(Date value),日期值給出了源服務器發送源響應的時間,而且- Last-Modifed頭域值至少提早於日期值(Date value)60秒。或者- 此驗證器正在被中間緩存經過與其緩存項裏保存的驗證器相比較 ,而且- 緩存項包含日期值(Date value),它指明瞭源服務器發送源響應(original response)的時間,而且- Last-Modifed頭域值至少提早於日期值(Date value)60秒。此種方法依賴於如下事實,若是兩個不一樣響應被源服務器在同一秒內被髮出,但這兩個響應都有相同的最後修改時間(Last-Modified time),那麼其中至少有一個響應的日期值和最後修改時間的值(Last-Modifed的值)相等。60秒的限制能保證Date和Last-Modifed的值在不一樣時鐘或在響應準備期間的不一樣時刻產生。一個實現可能會利用大於60秒的值,若是它認爲60秒過短。若是客戶端但願執行子範圍(sub-range)請求來請求一個只有最後修改(Last-Modifed)時間但沒有晦澀(opaque)驗證器時,它可能會認爲只有最後修改(Last-Modified)時間是強的。若緩存或源服務器接收到一條件請求,而不是完整響應GET請求時,他必須使用強比較方法去計算條件。此規定容許HTTP1.1,緩存和客戶端能安全地執行子範圍(sub-range)請求得到來自HTTP/1.0得來的值。13.3.4 關於什麼時候使用實體標籤和最後修改時間的規則咱們對源服務器,客戶端和緩存採用一套規則和建議來規定不一樣的驗證器什麼時候被使用,出於何種目的被使用。HTTP/1.1 源服務器:- 應發送一個實體標籤驗證器,除非產生此實體標籤不可行。- 能夠發送弱實體標籤來替代強實體標籤,若是使用弱實體標籤能提升性能或者不能發送強實體標籤。- 應發送一Last-Modifed值若是能夠的話,除非打破語義透明性(這可能因爲利用此日期於if-Modified-Since頭域裏)會致使嚴重的後果。換句話說,對http1.1 源服務器來講,比較好的作法是同時發送強實體標籤和Last-Modified值。.爲了合法,強實體標籤必須隨相關聯的實體值改變而改變。弱實體標籤應該隨相關聯的實體在語義上發生改變而改變。注意:爲保證語義透明緩存,源服務器必須避免爲兩個不一樣的實體重用某個特定的強實體標籤值,也不能重用某特定弱實體標籤爲兩個語義不一樣的實體。緩存項應該能保持任意長的時間,而無論過時時間(expiraton time),因此不能假設緩存歷來不會嘗試利用之前得到的驗證器來驗證緩存項。HTTP/1.1 客戶端:- 若實體標籤被源服務器提供,HTTP/1.1客戶端必須在任何緩存條件請求(利用If-Match或If-None-Match)裏利用實體標籤.。- 僅Last-Modified值被源服務器提供時,HTTP/1.1客戶端應在非子範圍緩存條件請求(利用If-Modified-Since)裏利用此值。- 僅Last-Modified值被HTTP/1.0源服務器提供時,HTTP/1.1客戶端可能會在子範圍緩存條件請求(利用If-Unmodified-Since)裏利用此值。- 若是實體標籤和Last-Modified值都被源服務器提供,HTTP/1.1客戶端應該在緩存條件請求裏利用這兩個驗證器。這容許HTTP/1.0和HTTP/1.1緩存能合適地進行響應。HTTP/1.1 源服務器,當接收到一個條件請求並同時包含Last-Modifed 日期(例如,在If-Modified-Since,或If-Unmodified-Since 頭域裏)和一個或多個實體標籤(例如在If-Match,If-None-Match,或If-Range頭域裏)做爲緩存驗證器時,源服務器不能返回一個304狀態響應(沒有改變)除非這樣做能與請求裏全部的條件頭域一致。HTTP/1.1緩存,當接收到一個條件請求而且此請求裏同時包含Last-Modified日期和一個或多個實體標籤做爲緩存驗證器時,它不能返回一個本地已緩存的響應給客戶端,除非已緩存的響應與請求裏全部條件頭域一致。注意:這些原理背後的規則是HTTP/1.1服務器和客戶端應在請求和響應裏儘量傳輸非冗餘的信息。接收這些信息的HTTP/1.1系統將會對這些接收到的驗證器做最保守的假設。HTTP/1.0客戶端和緩存會忽略實體標籤。一般,Last-Modified值會被這些系統接收和利用,以提供透明性和高效緩存行爲,所以HTTP/1.1源服務器這時應提供Last-Modified值。在一下不多的狀況,一個Last-Modified值做爲驗證器被HTTP/1.0系統使用時會帶來嚴重的後果,這時HTTP/1.1服務器不該提供一個Last-Modified值。13.3.5 非驗證條件(Non-validating Conditionls)實體標籤背後的原則是隻有服務做者才知道資源的語義從而去選擇一個合適的緩存驗證機制,而且任何比字節相等(byte-equality)比較方法複雜的驗證器比較方法都會帶來風險。因此,任何其餘的頭域的比較(除了Last-Modified,爲了兼容HTTP/1.0)歷來不會被用於驗證一個緩存項。13.4 響應的可緩存性(Response Cacheability)除非被緩存控制(見14.9節)指令明確地限制,緩存系統能夠將一成功響應做爲緩存項,能夠返回緩存項裏的響應副本而不須要驗證它若是此副本是保鮮的,而且也能夠在驗證成功後返回它。若是響應既沒有緩存驗證器也沒有顯式過時時間,咱們認爲它不能被緩存,可是某些緩存可能會違反這個約定(例如,當處於脫機時)。客戶端能常常發現這種來自於緩存的響應,只需經過把Date頭域值同當前時間做比較。注意:某些HTTP1.0緩存可能違反這一假設而沒有提示任何警告。然而,在一些狀況下,緩存不適合保存實體,或使緩存的實體服務於後續請求。這可能由於服務的做者認爲絕對的語義透明性是有必要的,或着出於安全和隱私考慮。某些緩存控制指令所以被提供是爲了讓服務器能指示某些資源實體,或部分實體,不能被緩存。注意在14.8 節裏描述了防止一個共享緩存(shared cache)去保存和返回一個之前包含Authorization頭域請求的響應。除非緩存控制指令防止響應被緩存, 一個接收的響應若是它的狀態碼是200,203,206,300,301或410,那麼此響應應該被緩存保存並且可用於後續的請求,但這必須受過時機制決定。然而,若是緩存不支持Range和Content-Range頭域,那麼它不能緩存206響應(部份內容)響應。緩存接收到的響應若是是其餘的狀態碼(如,302和307),那麼此響應不能被用於服務於後續的請求,除非緩存控制指令或其餘的頭域顯式地容許它能這樣作。例如,這些頭域包含下面的頭域: Expires 頭域( 見14.21 ) ; 「 max-age」 , 「 s-maxage」 , 「 mustrevalidate」,「prox-revalidate」,「public」或「private」緩存控制指令(見14.9)。13.5 從緩存裏構造響應緩存的目的是爲了響應未來的請求而緩存請求的響應信息。在不少狀況下,緩存簡單地返回響應的某部分給請求者。然而,若是緩存擁有一個基於之前響應的緩存項,它可能必須把新響應的部分和它緩存項裏的內容合起來。13.5.1 End-to-end和Hop-by-hop頭域爲定義緩存和非緩存代理的行爲,咱們將HTTP頭域分紅兩類:- end-to-end頭域,他們被傳輸給最終請求或響應的接收者。響應裏end-to-end頭域必需做爲緩存項的一部分存儲,而且必須在任何緩存項構成響應裏被傳輸。- hop-by-hop頭域,他們只對傳輸層鏈接有意義,而且即不能被緩存保存也不能被代理轉發。下面的HTTP/1.1頭域是hop-by-hop頭域:- Connection- Keep-Alive- Proxy-Authenticate- Proxy-Authorization- TE- Trailers- Transfer-Encoding- Upgrade全部其它被HTTP/1.1定義的頭域均爲end-to-end頭域。其它hop-by-hop頭域必須在Connection頭域(14.10 節)裏列出,並將被引進於HTTP/1.1(或後來的版本)裏。13.5.2 不可更改的頭域 (Non-modifiable Headers)HTTP1.1的某些特徵,如數字認證(Digest Authentication),是基於某些end-to-end頭域。一個透明代理不該該改變end-to-end頭域,除非這些頭域的定義要求或容許這樣作。一個透明代理不能改變請求或響應裏的下面頭域,並且它不能添加這些頭域到沒有這些頭域的請求或響應裏:- Contents-location- Content-MD5- ETag- Last-Modified一個透明代理不能改變響應裏的下面頭域:- Expires但它能夠添加這些頭域若是響應裏沒有這些頭域時。若是一個Expires頭域被添加,它必須等於響應裏Date頭域的值。一個代理不能在包含no-transform緩存控制指令的消息中改變或添加下面的頭域。- Content-Encoding- Content-Range- Content-Type一個非透明代理可能會在一個消息裏改變或添加這些頭域若是消息不包含no-transform緩存控制指令,可是若是代理這樣作了,它必須添加一個警告214(轉換被應用)(見14.46節)。注意:end-to-end頭域的沒必要要更改可能會致使認證失敗,若是更強的認證機制被應用於後續的HTTP版本中。此認證機制可能依賴於沒有在此列舉的頭域值。請求或響應裏的Content-Length頭域會根據4.4節的規則被添加或被刪除。一個透明代理必須保留實體主體的entity-length(見7.2.2),雖然它能夠改變transfer-length(4.4節)。13.5.3 聯合頭域(Combining Headers)當一個緩存對服務器發出驗證請求時,並且服務器提供304(沒有改變)響應或206(部份內容)響應時,那麼緩存將構造一個響應發送給請求客戶端。若是狀態碼是304(沒有改變),緩存利用緩存項裏的實體主體(entity-body)做爲客戶端請求響應的實體主體。若是響應狀態碼是206(部份內容)而且Etag或Last-Modified頭域能精確匹配,那麼緩存可能把緩存項裏的內容和接收到的響應裏的新內容合併而且利用最後合併的結果做爲輸出響應(見13.5.4)。緩存項裏的end-to-end頭域被用於構造響應,除了:- 任何保存的警告碼是1xx(見14.46)的Warning頭域必須從緩存項和轉發的響應裏刪除。- 任何保存的警告碼是2xx的Warning頭域必需要在緩存項和轉發的響應裏保留。- 任何304或206響應提供的end-to-end頭域必須替換緩存項的相應頭域除非緩存決定去刪除緩存項,不然它必須一樣能用接收的響應裏的相應end-to-end頭域去替換緩存項裏的頭域,除了上面描述的Warning頭域。若是輸入響應裏的一個頭域匹配緩存項裏多個頭域,那麼全部這些舊的頭域必須被替換。也就是說,輸入響應的全部end-to-end頭域會覆蓋緩存項裏全部相應的end-to-end頭域(除了緩存的警告碼是1xx的Warning頭域,它將會被刪除即便沒有被覆蓋)。注意:此規則容許源服務器去利用304(沒有改變)或一個206(部份內容)響應去更新之前同一實體或子範圍實體響應的任何頭域,雖然它也許不老是有意義或正確。這條規則不容許源服務器去利用304(沒有改變)或206(部份內容)響應去徹底地刪除一個之前響應的頭域。13.5.4 聯合字節範圍(Combing Byte Ranges)一條響應可能僅傳送一個實體主體的某一部分,這是因爲請求包含一個或多個Range指定的範圍,或者因爲鏈接會被過早地斷開。在幾回這樣得傳輸後,緩存可能已經接收了同一個實體主體的多個範圍部分。若是緩存有一個實體的非空子範圍,而且一個輸入(incoming)響應(譯註:輸入響應是進入緩存的響應,輸出響應是從緩存出去的響應)攜帶了另外一子範圍,那麼緩存可能會把新的子範圍和已經存在的子範圍聯合起來若是下面二者同時知足:- 輸入響應和緩存項都有緩存驗證器。- 利用強比較方法使兩個緩存驗證器匹配(見13.3.3)。若是任何要求不能知足,緩存必須利用最接近如今(most recent)的部分響應(基於任何響應的Date頭域值,而且會利用輸入響應若是這些Date頭域值相等或丟失了),並且必須丟棄其它的部分信息。13.6 緩存已協商響應(Caching Negotiated Responses)使用服務器驅動內容協商(12.1節),會在響應裏添加Vary頭域,並改變緩存利用響應去服務後續請求的條件和過程。見14.44節關於服務器利用Vary頭域的描述。服務器應利用Vary頭域告訴緩存哪些請求頭域被服務器用於從響應(可緩存的)對應的多個表現形式裏進行選擇,響應由服務器驅動協商決定。Vary頭域裏指定的頭域被稱作選擇請求頭域(selecting request-header)。當緩存接收到一個後續請求,而且此請求的URI指定了一個或多個(包含一個Vary頭域的)緩存項時,緩存不能利用這個緩存項去構造響應從而服務於新的請求,除非全部出如今新請求裏的選擇請求頭域匹配來自於源請求裏已被緩存保存的選擇請求頭域。在兩個請求裏,咱們定義這兩個選擇請求頭域匹配,若是而且只有第一個請求的選擇請求頭域能被轉換爲第二個請求裏的頭域經過添加或刪除線性空白(被容許出如今相應的BNF裏的線性空白)和/或把多個消息頭域結合成一個頭域經過4.2節裏的規則。一個Vary頭域值是「*」老是不能匹配的,而且後續對那個資源的請求只能合適地被源服務器理解。若是緩存項裏的選擇請求頭域(selecting request-header)不能匹配新請求的選擇請求頭域,那麼緩存不能利用緩存項去知足請求除非它能以條件請求把此新請求接力到源服務器而且源服務器返回一個304(沒有改變)的狀態響應,幷包含一個實體標籤或一個指明被使用實體的Content-Location頭域。若是一個緩存的表現形式已擁有實體標籤,那麼轉發請求應是以條件請求發送而且應包含資源對應的全部緩存項的實體標籤於If-None-Match頭域(不匹配則執行方法)裏。這告訴了服務器當前緩存擁有的實體集,以便若是實體集裏的任何實體匹配請求的實體,那麼服務器能利用Etag頭域於304(沒有改變)響應裏,從而去告訴緩存哪一個緩存項是合適的。若是新響應的實體標籤匹配已存在的緩存項,那麼新響應應被利用去更新已經存在的緩存項的頭域,並且更新的最後結果必須返回給客戶端。若是任何已存的緩存項只包含相關實體的部份內容,那麼它的實體標籤不該被包含於If-None-Match頭域裏,除非這個請求是範圍請求而且緩存項能徹底知足請求。若是緩存接收到一成功響應,響應的Content-Location頭域匹配同一請求URI已存緩存項的Content-Location頭域,而且它的實體標籤不一樣於已存緩存項的實體標籤,並且它的Date頭域值比已存緩存項更接近當前,那麼已經存在的緩存項不能被返回去響應未來的請求而且將會從緩存裏刪除。13.7 共享和非共享緩存 (Shared and Non-Shared Caches)出於安全和保密考慮,有必要區分共享和非共享緩存。非共享緩存是僅供一個用戶訪問,此狀況下,訪問性(accessibility)應由適當的安全機制控制。全部其它緩存均被認爲是共享的。此協議的其它部分對共享緩存的操做添加限制以防止隱私丟失或訪問控制的失敗。13.8 錯誤和不徹底的響應緩存行爲緩存收到不完整響應(例如響應的字節數比Content-Length頭域指定的值要小)時也能夠保存,可是必須把此響應看做部分響應。部分相應能夠合併(見13.5.4);合併結果多是完整響應或還是部分響應。.緩存在沒有顯式標明響應是部分響應狀況下(例如利用206(部份內容)狀態響應)不能把部分響應返回給客戶端。緩存不能使用一個200(OK)狀態碼返回一個部分響應。若是緩存當試圖重驗證一個緩存項時收到一5xx響應,那麼它既能夠將此響應轉發給請求的客戶端,或者執行跟服務器響應失敗同樣。在後面的狀況下,它能夠返回一個之前的接收的響應,除非緩存項包含一個「must-revalidate」緩存控制指令(見14.9節)。13.9 GET 和 HEAD 的反作用(Side Effects of GET and HEAD)除非源服務器顯式地禁止緩存它們的響應,不然緩存對任何資源的GET和HEAD方法不該有致使錯誤的行爲的反作用(side effects)若是這些響應來自於緩存。他們能夠仍然有反作用,但緩存在決定緩存時沒必要考慮這些反作用。緩存老是被指望去觀察一源服務器對緩存的顯式限制(explicit restrictions)。咱們注意到此規則的一個例外:有些應用程序習慣於在在GETs 和HEADs 方法裏使用查詢URLs(在rel_path_part裏包含一個「?」)從而執行帶來很大的反作用的操做,緩存不能把此URIs的響應看做一個保鮮的,除非服務器提供一個顯式過時時間(explicit expiration time)。這就意味着,對這樣的URIs的,來自HTTP/1.0服務器的響應不該被緩存保存。見9.1.1節相關的信息。13.10 在更新或刪除後的無效性在源服務器上,某些方法對某資源執行的影響,可能會引發一個或多個已存緩存項的非透明的無效。也就是說,雖然他們可能會繼續是保鮮的,可是他們不能準確的反應出源服務器對那個資源的新請求的響應。HTTP協議沒法保證全部此類緩存項均被標明無效。例如,引發源服務器上資源變化的請求可能不會穿過存有一個緩存項的代理。然而,卻有一些規則幫助減小可能的錯誤行爲。在此節裏,短語「使實體無效(invalidata an entity)」意味着緩存要麼能夠刪除它保存的全部的實體的實例,要麼能夠把這些實體實例標記爲「無效」並在它們可做爲後續請求的響應以前進行重驗證。一些HTTP方法必須讓緩存去使一個實體無效(invalidate an entity) 。這些實體要麼被請求URI指定,要麼在Location或在Content-Location頭域裏被指定(若是出現的話)。這些方法是:- PUT- DELETE- POST爲了防止服務器攻擊拒絕,一個基於Location或Content-Location頭域裏的URI的無效處理必須只有在URI的host部分和請求URI裏的host部分相同時才被執行。一個緩存若是不能理解請求裏的方法,那麼它應該使請求URI指定的任何實體無效。13.11 強制寫經過( Write-Through Mandatory)全部可能對源服務器資源進行修改的方法都要寫經過(written through)給源服務器。這一般包括全部除了GET和HEAD的方法。緩存在將此種請求轉發給服務器並得到相應響應前不能對請求客戶端作出響應。 但這個不能阻礙代理緩存在服務器已發送最終響應(final replay)以前發送100(繼續)響應。相反的狀況(一般叫「寫回」或「拷貝回」緩存)在HTTP1.1中是不容許的,這是因爲保持一致的更新是很是困難的,而且在寫回以前也會存在服務器,緩存和網絡故障的問題。13.12 緩存替換 (Cache Replacement)若是一個新可緩存(見14.9.2, 13.2.5, 13.2.6 和 13.8)響應從一資源被緩存接收,而且同一資源的已存響應已經被緩存保存,那麼緩存應該利用新響應去響應當前請求。緩存可能會把這一新響應放進存儲裏,而且能夠,若是它知足全部其它要求,利用此響應來響應任何未來的請求。若是緩存想把此新響應加進緩存存儲,13.5.3的規則必須應用。說明:一個新響應若是其Date頭域值比已存已緩存的響應的Date頭域值要舊,那麼它是不可緩存的。13.13 歷史列表 (History Lists)用戶代理常用歷史機制(history mechanisms),如「後退」按鈕和歷史列表,來從新展現一個會話的先前實體。歷史機制和緩存機制是不一樣的。特別是歷史機制不該嘗試給資源當前狀態展現一語義透明視圖。其歷史機制只是爲了展現資源獲取當時用戶看到的東西。默認狀況,過時時間(expiration time)沒有應用於歷史機制(history mechanisms)。若是實體仍然在存儲裏,歷史機制應該對其顯示即便其實體已通過期了,除非用戶專門地設置代理去刷新已過時的歷史文檔。這不能防止歷史機制告訴用戶某視圖可能過時。注意:若是歷史機制不必地阻止了用戶查看陳舊資源,那麼這會強制服務做者避免利用HTTP過時控制和緩存控制當他們想利用時。服務做者能夠認爲用戶不被呈現錯誤消息或警告消息是很是重要的,當他們利用導向按鈕(如回退按鈕)去看之前得到的資源時。即便有時這些資源本不該被緩存保存,或應很快過時,用戶界面的考慮可能會強制服務做者去尋求其它防止緩存的方法(例如,「一次性」URLs)爲了不不正確的歷史機制功能的影響。14 頭域定義本節定義了全部HTTP/1.1種標準頭域的語法和語義。對於實體頭域來講,發送者和接收者都既能夠指客戶端也能夠指服務器,取決於誰發送和誰接收此實體。14.1 AcceptAccept請求頭域被用於指定哪些媒體類型的響應對請求端是可接受的。Accept頭域被用於指明請求只對某些指望的媒體類型有效,例如請求一個內嵌的圖像。Accept = "Accept" ":"#( media-range [ accept-params ] )media-range = ( "*/*"| ( type "/" "*" )| ( type "/" subtype )) *( ";" parameter )accept-params = ";" "q" "=" qvalue *( accept-extension )accept-extension = ";" token [ "=" ( token | quoted-string ) ]星號」*」字符用於把媒體類型組合成一個範圍,「*/*」指明瞭全部的媒體類型而「type/*」指明type類型的全部子類型。Media-range可能包含一個媒體類型參數。每個media-range可能會跟隨一個或多個accept-params,以「q」參數指明一個相對的喜好程度的質量因子。經過第一個「q」參數(若是有的話)把accept-params和media-range參數分離。喜好程度質量因子容許用戶或用戶代理去指明對那個media-range 的相對喜好程度,qvalue的範圍是從0到1(見3.9節)。缺省是q=1。注意:利用「q」參數名字將媒體類型參數(譯註:media-range裏的parameter)和acceptextension分離開來是基於歷史的實踐。儘管這能防止任何以「q」命名的媒體類型參數應用於media-range 裏,但在一個media-range 裏使用「q」被認爲是不可能發生的,這是由於在IANA的媒體類型註冊表裏是沒有「q」參數的而且在Accept頭域裏利用媒體類型參數也是不多見。未來的媒體類型不被鼓任何以「q」命名的參數註冊。例子::Accept :audio/*;q=0.2 , audio/basic該例應該被解釋成「我喜歡audio/basic,可是能夠給我發送任何audio類型若是它最容易獲得,但在喜好程度質量要降低80%」。若是沒有Accept頭域出現,那麼會假設客戶端能接受全部媒體類型。若是Accept頭域在請求消息裏出現,而且若是服務器根據聯合Accept頭域值發現它不能發送客戶端可接受的響應,那麼服務器應發送406(不可接受的)響應。一個更加詳盡的例子以下:Accept: text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c這可能被口頭地解釋成「text/html 和 text/x-c是更喜好的媒體類型,可是若是他們不存在,那麼發送text/x-dvi實體,但若是text/x-dvi也不存在,那麼發送text/plain實體。」Media-range能被更具備特殊性的media-range或媒體類型覆蓋。若是多個media-range應用了一個特指的類型,那麼最具備特殊性的應該優先。例如:Accept: text/*, text/html, text/html; level=1, */*擁有下面的優先順序:1)text/html; level=12)text/html3)text/*4)*/*一個媒體類型的喜好程度質量因子是和一個給定的媒體類型聯繫在一塊兒的,它是由查找能最高優先匹配那個媒體類型的media-range決定的。例如:Accept:: text/*; q=0.3, text/html; q=0.7, text/html; level=1,text/html; level=2; q=0.4, */*; q=0.5可能會引發下面值被聯繫:text/html;level=1 = 1text/html = 0.7text/plain = 0.3image/jpeg = 0.5text/html;level=2 = 0.4text/html;level=3 = 0.7注意:一個用戶代理可能會爲一個特定的media-range提供一個缺省的質量值的集合。然而,除非用戶代理是一個不能和其餘的呈現代理交互的封閉的系統,不然這個缺省的集合應該能夠被用戶可設置的。14.2 Accept-CharsetAccept-Charset 請求頭域能夠用來指名哪些字符集的響應對請求端是可接受的。Accept-Charset頭域使客戶端能通知服務器產生哪些能讓客戶端更理解的字符集響應。Accept-Charset = "Accept-Charset" ":"1#( ( charset | "*" )[ ";" "q" "=" qvalue ] )字符集值在3.4節裏描述。每個字符集可能被給於一個相聯繫的質量值用來表示用戶對那個字符集的喜好程度。缺省值是q=1.例如:Accept-Charset:: iso-8859-5, unicode-1-1;q=0.8若是特殊值「*」出如今Accept-Charset頭域裏,那麼將匹配任何Accept-Charset頭域裏沒有的字符集(包含ISO-8859-1)。若是Accept-Charset頭域裏沒有出現「*」出現,那麼全部沒有在Accept-Charset 頭域裏顯式聲明的字符集的質量值都爲0,可是有個例外,那就是若是ISO-8859-1沒有被顯式聲明,那麼它的質量值爲1。若是Accept-Charset頭域沒有出現,那麼缺省狀況是任何字符集會接受。若是Accept頭域出如今請求消息裏,而且若是服務器不能發送請求端指望的字符集(Accept-Charset頭域指定的)的響應,那麼服務器應發送一個406(不能接受的)錯誤狀態響應,儘管發送一個不可接受的響應也是容許的。14.3 Accept-EncodingAccept-Encoding請求頭域和Accept頭域類似,但Accept-Encoding是限定服務器返回給客戶端能夠接受的內容編碼(content-coding,見3.5節)。Accept-Encoding = "Accept-Encoding" ":"1#( codings [ ";" "q" "=" qvalue ] )codings = ( content-coding | "*" )使用的例子以下:Accept-Encoding: compress, gzipAccept-Encoding:Accept-Encoding: *Accept-Encoding: compress;q=0.5, gzip;q=1.0Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0服務器判斷一個內容編碼(content-coding)是不是可接受的,是根據Accept-Encoding頭域,並利用下面的規則來決定:1.若是一個內容編碼(content-coding)在Accept-Encoding頭域裏出現,那麼它是能夠接受的(acceptable),除非它的qvalue爲0。(這在3.9節裏定義,一個qvalue爲0說明是「不可接受的」)2.若是「*」出如今Accept-Encoding頭域裏,那麼它匹配任何沒有出如今Accept-Encoding頭域裏的可得內容編碼。3.若是多個內容編碼是可接受的,那麼qvalue爲最高的且非0的內容編碼是最喜歡的。4.「identity」內容編碼老是可接受的,除非qvalue 爲0,或者Accept-Encoding 頭域包含「*;q=0」而且同時沒有包含「identity」內容編碼。若是Accept-Encoding頭域值爲空,那麼只有「identity」編碼是可接受的。若是Accept-Encoding頭域在請求裏出現,而且若是服務器不能發送一個Accept-Encoding頭域裏指定的編碼響應,那麼服務器應該發送一個406(不接受的)錯誤的響應。若是沒有Accept-Encdong頭域出如今請求消息裏,服務器應該假設客戶端將接受任何內容編碼。在這種狀況下,若是「identity」是這些可得的內容編碼中的一個,那麼服務器應利用「identity」內容編碼,除非服務器有附加信息指明其它內容編碼對客戶端是有意義的。注意:若是請求沒有包含Accept-Encoding頭域,而且若是「identity」內容編碼是不可得,那麼一般能被HTTP/1.0客戶端容易理解的內容編碼(也就是說,「gzip」和「compress」)是更喜好的;一些不能合適展現消息的老客戶端會發送其它內容編碼。服務器也許一樣能以特定用戶代理或客戶端的信息來作決定。注意:大多數HTTP/1.0應用程序不能識別或遵循一個內容編碼跟隨一個qvalue。這意味着qvalue可能不能工做,而且不能被容許和x-gzip或x-compress在一塊兒。14.4 Accept-LanguageAccept-Language請求頭域和Accept請求頭域相似,可是它是限定服務器返回給客戶端喜好的天然語言。Accept-Language = "Accept-Language" ":"1#( language-range [ ";" "q" "=" qvalue ] )language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )每一個language-range均被賦以一個質量值,它表明用戶對此language-range裏涵蓋語言的喜好程度。質量值缺省爲1,例如:Accept-Language: da, en-gb;q=0.8, en;q=0.7好像在說:「我更喜歡Danish,可是也能夠接收British English和其餘的English的類型的語言。」一個language-range匹配一個語言標籤若是它能精確和語言標籤相等,或者它能精確匹配標籤前綴,標籤前綴是語言標籤裏字符「-」以前的部分。特殊的「*」字符出如今Accept-Language頭域裏,代表能匹配任何不在此頭域裏的語言標籤。注意:前綴匹配規則並非意味着:給語言標籤賦值時,若是用戶理解某一個標籤,那麼他一樣會理解全部以這個標籤做爲前綴的全部標籤。這種狀況下,前綴規則只是代表能夠容許使用前綴標籤匹配。語言標籤的質量因子是Accept-Language頭域裏匹配此語言標籤的language-range的質量值。若是沒有Accept-Language頭域裏language-range匹配的語言標籤,那麼此語言的質量因子被賦予0。若是沒有Accept-Language頭域出如今請求裏,那麼服務器應該假設全部語言將是請求端可接受的。若是一Accept-Language頭域出如今請求裏,那麼全部質量因子大於0的語言是可接受的。若是發送一個和用戶喜好的語言相反,這將在15.1.4裏討論。因爲各個用戶的理解程度不同,建議客戶端應用程序應讓用戶對語言的偏好進行選擇。若是客戶不能進行選擇,那麼Accept-Language頭域不能在請求裏給出。注意:當讓用戶做出選擇時,用戶可能不熟悉上述語言匹配的細節,因此應該提供合適的嚮導。例如,用戶可能會認爲選擇「en-gb」會提供任何類型的英語文檔若是British English不可得。在這種狀況下,用戶代理應該能建議用戶添加一個「en」去獲得最佳匹配行爲。14.5 Accept-RangeAccept-Range響應頭域容許服務器向客戶指明服務器對範圍請求的接受度。Accept-Ranges = "Accept-Ranges" ":" acceptable-rangesacceptable-ranges = 1#range-unit | "none"源服務器若是接受字節範圍請求(byte-range request)那麼能夠發送Accept-Ranges: bytes可是不是必須這樣作。客戶端在沒有接收此頭域時也能夠產生字節範圍請求(byte-rangerequest)。範圍單位(range units)被定義在3.12節。服務器若是不能接受任何類型的範圍請求(range request),將會發送Accept-Ranges:none去勸告客戶不要嘗試範圍請求(range request)。14.6 AgeAge響應頭域表示發送者對響應產生(或重驗證)時刻後通過的時間的估計。一個已緩存的響應是保鮮的(fresh)若是此響應的年齡沒有超過它的保鮮壽命(freshness response)。Age值怎樣計算在13.2.3節裏描述了。Age = "Age" ":" age-valueage-value = delta-secondsAge值是十進制非負整數,而且以秒爲單位.。若是緩存接收到一個Age值大於它所能表示的上限,或它的年齡計算出現溢出,那麼它必須傳送Age頭域的值爲2147483648 (2^31)。一個包含緩存的HTTP/1.1服務器必須在來自於自身緩存的響應裏包含一個Age頭域。緩存應利用一個至少31位的運算類型。14.7 AllowAllow實體頭域中列出了被請求URI(Request-URI)指定的資源所支持的方法。此頭域的目的是嚴格地讓接收端知道資源所適合的方法。在405(方法不被容許)響應中必須出現Allow頭域。Allow = "Allow" ":" #Method使用示例:Allow: GET, HEAD, PUT這一頭域不能阻止客戶端使用其餘方法。但在Allow頭域域中給出的方法應被執行。Allow頭域裏指定的方法是每次請求時被源服務器定義的方法。Allow頭域裏能夠和一PUT請求一塊兒使用,而爲了說明新的或改變的資源支持這些方法。服務器不須要去支持這些方法,服務器應包含一個Allow頭域在響應裏而且給出實際支持的方法。代理(proxy)不能改變Allow頭域即便它沒有理解此頭域裏指定的全部方法,由於用戶代理可能和源服務器通訊有其餘的意圖。14.8 Authorization (受權)用戶代理每每但願經過服務器給本身受權,用戶代理這樣作是經過在請求裏包含一個Authorization請求頭域,可是一般在接收了一個401響應後就沒有必要再讓服務器給本身受權了。Authorization頭域由包含用戶代理對請求資源域的受權信息的證書(credentials)組成。Authorization = "Authorization" ":" credentialsHTTP訪問受權在「HTTP Authenticatiion:Basic and Digest Access Authentication」[43]中描述。若是一個請求被受權而且一個域(realm)被指定,那麼這個證書應對此域裏全部的其餘請求是有效的(假設在此受權模式自己不須要其它例如根據激發值或利用同步時鐘而變化的證書)。當一個共享緩存(shared cache)(見13.7 節)接收一個請求,而且此請求包含一個Authorization頭域時,那麼緩存不能返回此請求相應的響應來響應任何其它的請求,除非下面指定的例外之一發生:1.若是此響應包含「s-maxage」緩存控制指令,那麼此緩存能夠利用此響應來響應後續請求。可是(若是指定的最大年齡過時了)代理緩存必須首先經過源服務器來重驗證此響應,同時利用新請求裏的Authorization請求頭域去讓源服務器給新請求受權。(這是s-maxage定義的行爲)。若是響應包含「s-maxage=0」,那麼代理在重利用此響應以前必須老是重驗證它。2.若是此響應包含「must-revalidate」緩存控制指令,那麼緩存能夠利用此響應來響應後續請求。可是若是此響應是陳舊的,那麼全部緩存必須首先經過源服務器重驗證那個響應,同時利用新請求裏的Authorization請求頭域去讓源服務器去給此新請求受權。3.若是此響應包含「public」緩存控制指令,那麼此響應能夠用來響應任何後續的請求。14.9 Cache-ControlCache-Control經常使用頭域被用於指定必須在請求/響應鏈上的被全部緩存機制遵照指令。這些指令指定了防止緩存去幹涉請求或響應的行爲。這些指令常常覆蓋缺省的緩存算法。緩存指令是單方向的,由於請求中指令的存在並不意味着一樣的指令必須在響應中出現。請注意HTTP/1.0緩存可能沒有實現Cache-Control,而且也沒有實現Pragma: no-cache(參見14.32節)。緩存指令必須被代理或網關經過,無論這些指令對應用程序有多重要,由於這些指令可能對請求/響應鏈上的全部接收者都適用。不可能爲一個特定緩存去指定一個緩存指令。Cache-Control = "Cache-Control" ":" 1#cache-directivecache-directive = cache-request-directive| cache-response-directivecache-request-directive ="no-cache" ; Section 14.9.1| "no-store" ; Section 14.9.2| "max-age" "=" delta-seconds ; Section 14.9.3, 14.9.4| "max-stale" [ "=" delta-seconds ] ; Section 14.9.3| "min-fresh" "=" delta-seconds ; Section 14.9.3| "no-transform" ; Section 14.9.5| "only-if-cached" ; Section 14.9.4| cache-extension ; Section 14.9.6cache-response-directive ="public" ; Section 14.9.1| "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1| "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1| "no-store" ; Section 14.9.2| "no-transform" ; Section 14.9.5| "must-revalidate" ; Section 14.9.4| "proxy-revalidate" ; Section 14.9.4| "max-age" "=" delta-seconds ; Section 14.9.3| "s-maxage" "=" delta-seconds ; Section 14.9.3| cache-extension ; Section 14.9.6cache-extension = token [ "=" ( token | quoted-string ) ]當指令不伴有1#field-name參數出現時,該指令適用於整個請求或響應。當一個指令伴有一個1#field-name參數時,此指令僅應用於被命名的頭域,而不能應用於請求或響應的其餘部分。這一機制支持可擴展性;HTTP協議未來的版本的實現能夠經過將指令應用於HTTP/1.1中未定義的頭域。緩存控制指令可分爲以下幾類:- 對什麼是可緩存的限制;這可能只由源服務器指定。- 對什麼能被緩存保存的限制;這可由源服務器或用戶代理指定。- 對基本過時機制的改進;這可能由源服務器或用戶代理指定。- 對緩存重驗證及重載的控制;這可能僅由用戶代理指定。- 對實體傳輸的控制- 緩存系統的擴展。14.9.1 什麼是可緩存的缺省狀況下,若請求方法、請求頭域和響應狀態碼指明響應爲可緩存的,則此響應就是能夠緩存的。13.4 節總結了可緩存性的這些缺省狀況。下列緩存控制響應指令(Cache-Controlresponse deirctives)容許源服務器覆蓋缺省的響應可緩存性:public指明響應可被任何緩存保存,即使該響應一般是不可緩存的或只在非共享緩存裏是可緩存的。(參見14.8節,關於Authorization頭域的更多詳述。)private指明響應消息的部分或全部部分是爲一個用戶準備的而且不得被共享緩存保存。能夠使源服務器能夠聲明響應的特定部分來針對某一用戶而且對其餘用戶的請求是無效的。一個私有(非共享)緩存能夠緩存此響應。注:詞語「私有」的使用僅用來控制響應在何處可被緩存,而且不能保證消息內容的隱私。no-cache若是no-cache緩存控制指令沒有指定一個field-name,那麼一個緩存不能利用此響應在沒有經過源服務器對它進行成功重驗證的狀況下去知足後續的請求。這容許源服務器去防止響應被緩存保存,即便此緩存已被設置能夠返回陳舊響應給客戶端。若是no-cache緩存控制指令指定一個或多個field-name,那麼緩存能夠利用此響應去知足後續的請求,但這要受限於對緩存的其它限制。然而,指定的filed-name必須不能在後續請求的響應裏被髮送若是此響應沒有在源服務器那裏獲得成功重驗證。這容許源服務器能防止緩存去重利用響應裏的某些頭域,但仍然容許緩存能保存響應剩餘部分。注意:大多數HTTP/1.0緩存將不能識別或遵循這個指令。14.9.2 什麼能被緩存保存no-storeno-store緩存控制指令的目的在於防止不經意地釋放或保留敏感信息(好比存放在備份磁帶的信息)。 no-store緩存控制指令應用於整個消息,而且能夠在響應裏或在請求裏被髮送。若是在請求裏被髮送,緩存不能保存此請求或此請求響應的任何部分。若是在響應裏被髮送,緩存不能保存此響應或保存此響應請求的任何部分。此緩存控制指令能應用於非共享緩存和共享緩存。「不能保存」在這個背景裏的意思是指緩存不能有意地把信息保存在非易失性存儲裏,並且必須盡力去刪除易失性存儲上的信息當它轉發完畢後。即便當此指令在一個響應裏時,用戶也可能會顯式地在緩存系統以外保存這個響應(例如利用一個「另存爲」對話框)的地方。歷史緩衝(History buffers)(見13.13節)可能保存這個響應做爲它們正常操做的一個部分。此指令的目的是爲了知足某些用戶聲明的要求,還有就是爲那些比較在乎經過訪問緩存數據結構而發生信息泄漏的做者提供方便。在一些狀況下,利用此緩存控制指令可能會加強隱私,可是咱們注意到它並非在任何狀況下都是可信任的或都能充分地保護隱私的。特別是,惡意的或被損壞的緩存可能不能識別到或遵循此指令,而且網絡通訊也容易隨時受到竊聽。14.9.3 對基本過時機制的改進實體的過時時間可由源服務器利用「Expires」頭域(參見14.21節)指定。 或者,也能夠在響應裏利用max-age緩存控制指令指定。當max-age緩存控制指令出如今一個已緩存的響應裏時,若是此響應的當前年齡(current age,譯註:見13.2.3節關於current age的定義)大於爲那個資源的一個新請求時max-age裏給定的年齡值(以秒),那麼這個已緩存的響應是陳舊的(stale)。對在一個響應裏應用max-age緩存控制指令意味着此響應是可緩存的(也就是說「公有的」)除非出現其它更具限制性的緩存控制指令於響應裏。若響應同時含有Expires頭域和max-age緩存控制指令,那麼max-age緩存控制指令應該覆蓋Expires頭域,即便Expires頭域更具限制性。此規則容許源服務器能夠爲一給定響應來爲一HTTP/1.1(或更遲)緩存提供一個比一HTTP/1.0緩存更長的過時時間(expiration time)。這個規則可能會頗有用,若是某個HTTP/1.0 緩存不恰當地計算了年齡(ages)或過時時間(expiration times),可能因爲不一樣步的時鐘。許多HTTP/1.0緩存實現可能會把響應裏小於或等於該響應裏Date頭域值的Expires頭域值當作與「no-cache」緩存控制響應指令等效。若是一個HTTP/1.1緩存接收到這樣一個響應,而且此響應沒有包含一個Cache-Control頭域,緩存應把此響應當作一個不可緩存的,這是爲了保持和HTTP/1.0服務器兼容。注意:一個源服務器可能但願把一個相對較新的HTTP緩存控制特性,例如「private」緩存控制指令,用於一個存有不能理解此特性的舊的緩存的網絡上。源服務器應該須要把新特性和響應裏值小於或等於Date值的Expires頭域聯合起來,這樣以便防止舊緩存不恰當地保存此響應。s-maxage若是一響應包含一s-maxage緩存控制指令,那麼對於一共享緩存(不能對私有緩存)來講,s-maxage指定的值將會覆蓋max-age緩存控制指令或Expires頭域。s-maxage緩存控制指令照樣意指proxy-revalidate緩存控制指令(見14.9.4節)的語義,也就是說,共享緩存在沒有經過源服務器首先重驗證這個已陳舊的緩存項時不能利用它來響應後續的請求。s-maxage緩存控制指令老是被私有緩存忽略。注意:大多數不遵循此規範的老的緩存沒有實現任何緩存控制指令。 一個源服務器若是但願利用一緩存控制指令去限制(但不能阻止)遵循HTTP/1.1的緩存去進行緩存處理,那麼它可能會採用max-age控制指令去覆蓋Expires頭域,而且它會認可HTTP/1.1之前版本的緩存不會去觀察max-age緩存控制指令。其它緩存控制指令容許一個用戶代理(user agent)去改變基本的過時機制。這些指令可能會被指定在請求裏:max-age代表客戶端願接受這樣一個響應,此響應的年齡不大於客戶端請求裏max-age指定時間(以秒爲單位)。除非max-stale緩存控制指令也包含在請求裏,不然客戶端是不能接收一個陳舊響應的。min-fresh代表客戶端願接受一個這樣的響應,其保鮮壽命不小於響應當前年齡(current age,見13.2.3節關於current_age的定義)與客戶端請求裏的min-fresh指定的時間之和(以秒爲單位)。也就是說,客戶端想要一個響應至少在min-fresh指定的時間內是保鮮的。max-stale代表客戶端願接受已通過期的響應。 若客戶端請求爲max-age指定了一個值,則代表客戶端願意接受過時時間不超過在max-stale裏指定秒數的響應。若max-stale沒有賦值,則客戶端願接受任意年齡的陳舊響應。因爲max-stale緩存控制指令出如今請求裏,或因爲此緩存被設置成能覆蓋響應的過時時間,致使緩存返回了一個陳舊響應,那麼緩存必須把一個Warning頭域放進這個陳舊響應裏,此Warning頭域裏應該是110警告碼(響應是陳舊的)。一個緩存能夠被設置爲能夠不須要驗證就能夠返回陳舊的響應,但這不該與任何關於緩存驗證(例如,一個「must-revalidate」緩存控制指令)的「必須」等級的要求相沖突。若新請求與緩存項都包含一個「max-age」緩存控制指令,那麼取兩個值的小者來爲此請求決定緩存項的保鮮程度。14.9.4 緩存重驗證和加載控制( Cache Revalidation and ReloadControls)有時,用戶代理可能但願或出於須要,堅持要求某緩存經過源服務器去重驗證其緩存項,或者要求其緩存從源服務器那裏從新加載其緩存項。End-to-end重驗證也許是有必要的,若是緩存或源服務器已太高估計已緩存的響應(cached response)的過時時間。End-to-end從新加載多是必要的,若是緩存項因爲某緣由已經變得陳舊了。End-to-end 重驗證可能被請求,當客戶端沒有本地緩存副本,此時咱們稱之爲「未指定的end-to-end重驗證(unspecified end-to-end revalidation)」,或者,當客戶端存有本地緩存副本,此時咱們稱之爲「指定的end-to-end重驗證(specific end-to-end revalidation)」。利用緩存控制請求指令,客戶端能指定下面三種動做:End-to-end reload (End-to-end從新加載)請求包含「no-cache」緩存控制指令,或,爲了兼容HTTP/1.0 客戶端,「Pragma: nocache」緩存控制指令。頭域名不能被包含在請求的no-cache緩存控制指令裏。服務器不能利用一個緩存副原本響應這樣一個請求。Specific end-to-end revalidation(指定的end-to-end重驗證)請求包含一個「max-age=0」緩存控制指令,它強制每一個途徑源服務器的緩存必須經過下一緩存或服務器來重驗證它所擁有的緩存項(若是有的話)。此初始請求包含一帶有客戶端當前驗證器的緩存驗證條件。Unspecified end-to-end revalidation(未指定的end-to-end重驗證)請求包含一個「max-age=0」緩存控制指令,它強制每一個途徑源服務器的緩存必須經過下一緩存或服務器來重驗證它所擁有的緩存項(若是有的話)。此初始請求沒有包含一緩存驗證條件;沿着路徑上的第一個擁有此資源緩存項的緩存(若是有的話)在請求裏包含一帶有其緩存當前驗證器的緩存驗證條件。max-age當一箇中間緩存被一個max-age=0的緩存控制指令強迫去重驗證它所擁有的緩存項,而且客戶端已經在請求裏包含了其自己擁有的驗證器,此驗證器可能不一樣於當前緩存項裏保存的驗證器。在這種狀況下,緩存應該在不影響語義透明性的狀況下利用任一驗證器去執行請求。然而,驗證器的選擇可能會影響性能。最好的辦法對中間緩存來講,就是當執行請求時利用它本身的驗證器。若是服務器以304(沒有改變)回覆,那麼此緩存能返回一個它本身如今已經驗證了的副本給客戶端同時以一200(OK)狀態碼。若是服務器以一新實體和一新緩存驗證器來回復請求,那麼此中間緩存會把返回的驗證器同客戶端請求裏的驗證器做比較並利用強比較方法。若是客戶端的驗證器和源服務器的相等,那麼此中間緩存器只是簡單的返回304(沒有改變)響應。不然,它返回一個新的實體而且狀態碼是200的響應。若是一個請求包含一個no-cache緩存控制指令,那麼它不該包含min-fresh,max-stale,或max-age緩存控制指令。only-if-cache在一些狀況下,例如糟糕的網絡鏈接,一客戶端可能但願一緩存只返回緩存當前保存的響應,而且不須要緩存經過源服務器對其緩存項進行從新加載或重驗證。若是這樣做,客戶端可能會包含一個only-if-cached緩存控制指令於請求裏。若是緩存接收了這樣的指令,那麼緩存應利用緩存項(但必須知足請求的其它方面的限制)去響應,或以504(網關超時)狀態碼響應。然而,若是一組緩存做爲一統一的具備良好內部鏈接性的系統來操做,那麼這個請求可能會轉發到緩存組的內部。must-revalidate因爲一個緩存可能被設置去忽略服務器指定的過時時間,而且又因爲一個客戶端請求可能包含一個max-stale緩存控制指令(具備類似的做用),因此此協議一樣包含一個讓源服務器強迫緩存項被重驗證的機制。當must-revalidate緩存控制指令出如今已被緩存接收的響應裏時,那麼此緩存不能利用此緩存項,若是在它變得陳舊而且沒有經過源服務器對它進行重驗證的狀況下,去響應一個後續的請求。(也就是說,緩存必須每次進行end-to-end重驗證,若是單獨地基於源服務器的Expire或max-age值,已緩存的響應是陳舊的話)must-revalidate緩存控制指令能夠爲某些協議特性提供可信賴性操做。在全部狀況下,一個HTTP/1.1緩存必須遵循must-revalidate緩存控制指令;特別地,若是此緩存不能直接和源服務器通訊,那麼它必須產生一個504(網關超時)響應。服務器應發送must-revalidate緩存控制指令,若是而且只有在服務器對實體的驗證請求失敗而致使不正確的操做時,例如一個不動聲息的未執行的金融事務。接收端不能採起任何違反此緩存控制指令的自動的行爲,而且不能自動地提供一個被驗證無效的實體副本若是此副本經過源服務器重驗證失敗。儘管這不被推薦,用戶代理(user agent)若是在糟糕的網絡鏈接限制下,可能會違反此緩存控制指令,可是,若是這樣的話,它必須顯式地警告用戶這是一個未驗證的響應。警告必須在每次未驗證的訪問時被提供,並且用戶代理應須要用戶顯式地確認信息。proxy-revalidateproxy-revalidate緩存控制指令和must-revalidate緩存控制指令具備相同的語義,但它不能應用於非共享(non-shared)的用戶代理緩存。它能被用於一已被受權請求的響應,去容許用戶緩存能保存或者事後能返回此響應而不須要去重驗證它(由於它已經被那個用戶受權了一次),可是服務於多個用戶的代理仍然須要每次去重驗證它(爲了保證每一個用戶已被受權)。注意這樣的受權響應一樣須要public緩存控制指令,這是爲了容許響應能徹底被緩存。14.9.5 No-Transform緩存控制指令no-ransform中間緩存(代理)的實現者們已發現轉換某個實體主體的媒體類型轉是頗有用的。一個非透明代理可能,例如,會在不一樣圖像格式之間進行轉換,這是爲了節約空間或在低速的鏈接上減小通訊流量。然而,當這些轉換應用於某些應用的實體主體時,會引起嚴重操做問題。好比,醫學圖象應用程序,科學數據分析應用程序和利用end-to-end認證的應用程序都必須保證接收到的實體主體與原實體主體每一bit都是一致的。因此,若是消息包括了no-ransform緩存控制指令, 那麼中間緩存或代理不能改變13.5.2節中列出的受限於no-transform緩存控制指令的頭域。這意味着緩存或代理不能改變由這些頭域指定的實體主體的任何方面(aspect),包括實體主體自己的值。14.9.6 緩存控制擴展(Cache control Extendions)Cache-Control頭域能被擴展,可經過一個或多個cache-extension標記,每一個標記能夠被賦於一個值。信息擴展(這些擴展無須緩存行爲的改變)能夠不經改變其它緩存控制指令的語義而被添加。行爲擴展是經過現有緩存控制指令的基本行爲的修飾來實現的。 新緩存控制指令與標準緩存控制指令二者都被提供,這樣,不理解新緩存控制指令的應用程序會缺省地採用標準緩存控制指令規定的行爲,而那些能理解新指令的應用程序會將其看作是修改了標準緩存控制指令的要求。這樣,緩存控制指令的擴展能夠在無須改變基本協議的狀況下就可以實現。擴展機制依賴於一HTTP緩存,此緩存聽從全部本地HTTP版本緩存定義的緩存控制指令,聽從必定的擴展,而且會忽略全部它不能理解的緩存控制指令。例如,考慮一個假設的名爲「community」的新緩存響應控制指令,此指令被當作是對private緩存控制指令的修飾。咱們定義此新緩存控制指令以代表:除共享緩存,任何被communit值命名的社區成員共享的緩存也可緩存此響應。例如,若是一個源服務器但願容許UCI社區裏的成員在他們共享緩存裏能夠使用一私有響應,那麼此源服務器應該包含:Cache-Control: private, commuity="UCI"一個見到此頭域的緩存將會正確執行,即便此緩存不能理解這個community緩存擴展,由於緩存一樣能看到而且能理解private緩存控制指令因此這樣能致使缺省的安全行爲。不能識別的緩存控制指令必須被忽略;咱們認爲不能被HTTP/1.1緩存識別的任一緩存控制指令會和標準緩存控制指令(或者響應的缺省緩存能力)聯合在一塊兒這樣緩存行爲會保持最小正確性即便緩存不理解此擴展。14.10 ConnectionConnection經常使用頭域容許發送者指定某些專屬於某特定鏈接的選項,而且Connection頭域不能被代理(proxy)在之後的鏈接中傳送。Connection頭域遵循以下語法:Connection = 「Connection」 「:」 1#(connection-token)connection-token = tokenHTTP/1.1 代理必須在轉發消息以前解析Connection 頭域而且,爲此頭域中每個connection-token,從消息中刪除任何與connection-token 裏同名頭域。 鏈接選項是由Connection頭域中出現connection-token而指明的,而不是由任何相應的附加頭域,由於附加頭域能夠不被髮送若是對應的那個鏈接沒有參數。Connection頭域裏列出的消息頭域不得包含end-to-end頭域,例如Cache-Control頭域。HTTP/1.1定義了「close」鏈接選項,這是爲了讓發送者指明在完成響應後鏈接將被關閉。例如Connection:close不管是出如今請求或響應的頭域裏都代表:在完成現有請求/響應後鏈接不該被視是「持續的(persistent)」(參見8.1節)。不支持持久鏈接的HTTP/1.1應用程序必須在每一消息中都加上「close」鏈接選項。接收到含有Connection 頭域的HTTP/1.0(或更低版本)消息的系統必需要爲每個connection-token去刪除或忽略消息中與之同名的頭域。這避免之前版本的HTTP/1.1代理錯誤轉發這些頭域。14.11 Content-Encoding「Content-Encoding」實體頭域是對媒體類型的修飾。當此頭域出現時,其值代表對實體主體採用了何種內容編碼,從而能夠知道採用何種解碼機制以獲取Content-Type頭域中指出的媒體類型。Content-Encoding頭域主要目的是能夠在不丟失下層媒體類型的標識下對文檔進行壓縮。Content-Encoding = "Content - Encoding" ":" 1#content-coding內容編碼在3.5節裏定義。下面是一個應用的例子:Content-Encoding:gzip內容編碼(content-coding)是請求URI 指定實體的特性。一般,實體主體之內容編碼(content-coding)的方式存儲,然而只有在此實體主體被呈現給用戶以前才能被解碼。然而,非透明代理可能會把實體主體的內容編碼(content-coding)改爲接收端能理解的內容編碼(content-coding),除非「no-transform」緩存控制指令出如今消息裏。若是實體的內容編碼不是「identity」,那麼此響應必須包含一個Content-Encoding實體頭域(見14.11節)而且列出非dentity的內容編碼。若實體的內容編碼(content-coding)是一不被源服務器接受的請求消息,則響應必須以415狀態碼響應(不支持的媒體類型)。若實體採用多種編碼,則內容編碼必須在Content-Encdoing頭域裏列出,並且還必須按他們被編碼的順序列出。額外的關於編碼參數的信息能夠在其它實體頭域裏提供,這在此規範裏沒有定義。14.12 Content-LanguageContent-Language實體頭域描述了實體面向用戶的天然語言。請注意,這不必定等同於實體主體中用到的全部語言。Content-Language = 「Content-Language」 「:」 1#language-tag語言標籤由3.10節定義。Content-Language頭域的主要目的在於讓用戶根據本身喜好的語言來識別和區分實體。這樣,若是實體主體的內容是面向丹麥語言的用戶,那麼下面的頭域是適合的:Content-Language: da若未指明Content-Language頭域,那麼此內容缺省是對全部語言的用戶都支持。這既可能意味着發送者認爲實體主體的內容與任意天然語言無關,也多是發送者不知道內容該針對哪一種語言。在Content-Language頭域裏能夠爲內容(content)列出多種語言。例如,同時用毛裏土語和英語呈現「Treaty of Waitangi」就能夠用下面表示:Content-Language: mi,en然而,有多種語言呈現於實體中並不表明此實體必定是爲多個國家語言的用戶準備的。好比《初學拉丁文》之類的語言啓蒙教程,顯然是針對英語用戶的。這裏,合適的Content-Language頭域裏應只包括「en」。Content-Language可應用於任意媒體類型(media type) -- 它不限於文本式的文檔。14.13 Content-LengthContent-Length實體頭域用於指明發送給接收者實體主體(entity-bidy)的大小(以十進制的字節數表示),或是在使用HEAD方法時,指明實體主體本應在GET方法時發送實體主體的大小。Content-Length = 「Content-Length」 「:」 1*DIGIT示例:Content-Length: 3495除非被4.4 節裏規定的規則禁止,不然應用程序應該利用此頭域指明消息主體(messagebody)的傳輸長度。任何大於或等於0的Content-Length均爲有效值。若是一個Content-Length沒有在消息裏給定,4.4節描述瞭如何判斷消息主體的長度。請注意Content-Length頭域的含義與MIME中的關於此頭域的定義有很大的區別,MIME中,它在content-type類型爲「message/external-body」的消息裏是可選的。在HTTP中,在消息被傳輸以前,若是消息的長度能被肯定,那麼消息裏應該包含Content-Length頭域,除非不被4.4節裏的規則容許。14.14 Content-LocationContent-Location實體頭域可用來爲消息裏的實體提供對應資源的位置,當此實體的訪問位置獨立於請求URI時。一服務器應該爲響應實體的變量(variant,譯註:見1.3節 術語)提供一個Content-Location頭域;尤爲是在資源有多個對應的實體時,而且這些實體擁有各自不一樣的位置,而且能夠經過這些位置單獨地訪問到各個實體,這時服務器應該爲一個特定的變量(variant)提供一個Content-Location頭域。Content – Location = 「Content-Location」 「:」 (absoluteURI | relativeURI)Content-Location的值一樣爲實體定義了基URI(base URI)。Content-Location的值並不能做爲源請求URI(original requested URI)的替代物;它只能是陳述了請求時相應於特定實體的資源位置。未來的請求也許會用Content-Location裏的URI做爲請求URI,若是請求指望指定那個特定實體源。若是一個實體含有一個Content-Location 頭域,而且此頭域裏的URI 不一樣於得到此實體的URI,那麼緩存不能認爲此實體能被用於去響應基於那個Content-Location裏URI的後續請求。然而,Content-Location能被用於區分同一請求資源的多個實體,這在13.6節裏描述了。若Content-Location擁有的是相對URI(relative URI),則此相對URI(relative URI)是相對於請求URI來解析的(Request-URI)。PUT或POST請求中含有Content-Location頭域是沒有定義的;服務器可自由忽略它。14.15 Content-MD5Content-MD5實體頭域,正如RFC1864[23]裏定義的同樣,提供實體主體(entity-body)的MD5摘要(digest),爲的是提供end-to-end消息完整性檢測(MIC)。(注:一MIC有利於檢測實體主體傳輸過程當中的偶然性變更,但不必定能防範惡意攻擊。)Content-MD5 = "Content-MD5" ":" md5-digestMD5-digest=< 由RFC 1864 定義的base64的128位MD5摘要>Content-MD5頭域可由源服務器或客戶端產生,用做實體主體的完整性檢驗。只有源服務器或客戶端可生成Content-MD5頭域;不得由代理和網關生成,不然會有悖於其做爲端到端完整性檢驗的價值。任何實體主體的接收者,包括代理和網關,均可以檢查此頭域裏的摘要值與接收到的實體主體的摘要值是否相符。MD5摘要的計算基於實體主體的內容,包括任何已應用的內容編碼(content-coding),但不包括應用於消息主體的任何傳輸編碼。若接收到的消息具備傳輸編碼,那麼傳輸編碼必須在用Content-MD5值與接收到的實體相檢測以前被解除。這樣作的結果是:摘要的計算是基於實體主體(entity-body)的字節的,就像一條命令:若是沒有傳輸編碼被應用,它們將會被髮送。HTTP 將RFC 1864拓寬到容許對MIME複合媒體類型(如multipart/*,message/rfc822)計算摘要,但這並不改變如前所述的摘要計算方法。有一些關於這個的後果。複合媒體類型(composite types)的實體主體可能包含許多bodypart,每個body-part 都有它本身的MIME 和HTTP 頭域(包括Content-MD5,Content-Transfer-Encoding,和Content-Encoding 頭域),若是一個body-part 有一個Content-Transfer-Encoding或Content-Encoding頭域,那麼應該認爲此body-part的內容已被應用此編碼,而且認爲此body-part 被包含於Content-MD5 摘要裏,就是說在應用編碼以後。Transfer-Encoding頭域不被容許出如今body-part裏。不可在計算或覈對摘要以前就將任何其它換行轉換爲CRLF:實際傳輸的文本中使用的換行必須原封不動的參與摘要計算。注:雖然HTTP的Content-MD5的定義和RFC 1864中關於MIME實體主體的徹底同樣, 但HTTP 實體主體在對Content-MD5 的應用上仍然有幾處與MIME 實體主體有所區別。首先,HTTP 不象MIME 會用Content-Transfer-Encoding 頭域,而是會使用Transfer-Encoding 和Content-Encoding頭域。 其次,HTTP比MIME更多地使用二進制內容類型,因此這種狀況要注意用於計算摘要的字節順序是由那個類型所定義的傳輸字節順序(transmission byteorder)。最後,HTTP容許文本類傳輸時採用數種換行,而不僅是規範的使用CRLF的的標準形式。14.16 Content-RangeContent-Range實體頭域與部分實體主體一塊兒發送,用於指明部分實體主體在完整實體主體裏哪部分被採用。 範圍的單位(Range unit)在3.12節中定義。Content-Range = "Content-Range" ":" content-range-speccontent-range-spec = byte-content-range-specbyte-content-range-spec = bytes-unit SPbyte-range-resp-spec "/"( instance-length | "*" )byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)| "*"instance-length = 1*DIGIT除非沒法或很難判斷,此頭域應指明完整實體主體的總長度。星號「*」表示生成響應時的instance-length未知。不像byte-ranges-specifier值(參見14.35.1節),byte-range-resp-spec必須只能指明一個範圍,而且必須包含首字節和尾字節的絕對位置。一個帶有byte-range-resp-spec 的byte-content-range-spec,若是它的last-byte-pos 值小於first-byte-pos值,或它的instance-length值小於或等於它的last-byte-pos值,那麼就說明是無效的。收到無效的byte-content-range-spec將被忽略,而且任何隨其傳輸的內容都將被忽略響應時發送狀態碼416(請求的範圍沒法知足)的服務器應包含一個Content-Range頭域,且裏面的byte-range-resp-spec的值爲「*」。instance-length指定當前選定資源的長度。狀態碼爲206(部份內容)的響應不該該包含一個byte-range-resp-sepc爲「*」的Content-Range頭域。假定實體共含1234字節,byte-content-range-spec值的例子以下:. The first 500 bytes:bytes 0-499/1234. The second 500 bytes:bytes 500-999/1234. All except for the first 500 bytes:bytes 500-1233/1234. The last 500 bytes:bytes 734-1233/1234當HTTP消息裏包含單個範圍時(好比,對單個範圍請求的響應,或對一組無縫相連的範圍請求的響應),那麼此內容必須跟隨一個Content-Range頭域,而且還應該包含一個Content-Length頭域來代表實際被傳輸字節的數量。例如,HTTP/1.1 206 Partial contentDate: Wed, 15 Nov 1995 06:25:24 GMTLast-Modified: Wed, 15 Nov 1995 04:58:08 GMTContent-Range: bytes 21010-47021/47022Content-Length: 26012Content-Type: image/gif當HTTP報文包含多個範圍時(好比,對多個無重疊範圍請求的響應),它們會被看成多部分類型的消息來傳送。基於爲此目的多部分媒體類型爲「multipart/byteranges」,它在附錄19.2裏介紹了。見19.6.3裏關於兼容性的問題描述。對單個範圍請求的響應不能使用multipart/byteranges媒體類型。若對多個範圍請求的響應結果爲一單個範圍,那麼能夠以一個multipart/byteranges媒體類型發送而且此媒體類型裏只有一個部分(part)。一個客戶端若是沒法對multipart/byteranges消息解碼,那麼它不能在一請求中請求多個字節範圍。當客戶端在一請求中申請多個字節範圍時,服務器應按他們在請求中出現順序的範圍返回他們所指定的範圍。若服務器出於句法無效的緣由忽略了byte-range-spec,它應把請求裏無效的Range頭域視爲不存在。(正常狀況下,這意味着返回一個包含完整實體的200響應。)若是服務器接收到一請求,此請求包含一沒法知足的Range 請求頭域(也即,全部byterange-spec 裏的first-byte-pos 值大於當前選擇資源的長度),那麼它將返回一個416 響應(請求的範圍沒法知足)(參見10.4.17節)。注: 客戶端對沒法知足Range請求頭域不能期望服務器必定返回416(請求的範圍沒法知足)響應而非200(OK)的響應,由於不是全部服務器都能處理Range請求頭域。14.17 Content-TypeContent-Type實體頭域指明發給接收者的實體主體的媒體類型,或在HEAD方法中指明若請求爲GET時將發送的媒體類型。Content-Type = "Content-Type" ":" media-type媒體類型有3.7節定義。 此頭域的示例以下:Content-Type: text/html; charset=ISO-8859-47.2.1節提供了關於肯定實體媒體類型方法的進一步論述。14.18 DateDate經常使用頭域代表產生消息的日期和時間,它和RFC822中的orig-date語義同樣。此頭域值是一個在3.3.1裏描述的HTTP-date;它必須用RFC1123[8]裏的date格式發送。Date="Date"":"HTTP-date舉個例子Date:Tue,15 Nov 1994 08:12:31GMT源服務器在全部的響應中必須包括一個日期頭域,除了下面這些狀況:1. 若是響應的狀態代碼是100(繼續)或101(轉換協議),那麼響應根據服務器的須要能夠包含一個Date頭域。2. 若是響應狀態代碼表達了服務器的錯誤,如500(內部服務器錯誤)或503(難以得到的服務),那麼源服務器就不適合或不能去產生一個有效的日期。3. 若是服務器沒有時鐘,不能提供合理的當前時間的近似值,這個響應不必包括Date頭域,但在這種狀況下必須遵守 14.18.1節中的規則。一個收到的消息若是沒有Date頭域的話就會被接收者加上一個,若是這條消息將要被接收者緩存或者將要經過一須要日期的網關。一個沒有時鐘的HTTP實現不能在沒有重驗證響應時去緩存(保存)此響應。一個HTTP 緩存,特別是一個共享緩存,應該使用一種機制,例如NTP[28],讓它的時鐘與外界可靠的時鐘保持同步。客戶端在包括實體主體(entity-body)的消息中應該包含一個Date 頭域,例如在PUT 和POST請求裏,即時這樣作是可選的。一個沒有時鐘的客戶端不能在請求中發送Date頭域。一個Date頭域中的HTTP-date不該該是一個消息產生時刻以後的日期和時間。它應該表示與消息產生時的日期和時間的最近似值,除非沒有辦法產生一個合理的精確日期和時間。理論上說,日期應該是在實體(entity)產生以前的那一刻,實際上,日期是在不影響其語義值的狀況下消息產生期間的任意時刻。14.18.1 沒有時鐘的源服務器運做一些源服務器實現可能沒有可得時鐘。一個沒有可得時鐘的源服務器不能給一個響應指定Expires或Last-Modified頭域值,除非經過一個具備可信賴時鐘的系統或用戶,把此值與此資源聯繫在一塊兒。能夠給Expires賦予一值,此值在服務器的配置時間之時或以前將被視爲過去。(這容許響應提早過時而不須要爲每一個資源保存單獨的Expires值)。14.19 ETagEtag響應頭域提供了請求對應變量(variant)的當前實體標籤。與實體標籤一塊兒使用的頭域在14.24,14.26和14.44節裏描述。實體標籤可用於比較來自同一資源的不一樣實體。(參見13.3.3節)Etag = "Etag" ":" entity-tag例:ETag: "xyzzy"ETag: W/"xyzzy"ETag: ""14.20 ExpectExpect請求頭域用於指明客戶端須要的特定服務器行爲。Expect = "Expect" ":" 1#expectationexpectation = "100-continue" | expectation-extensionexpectation-extension = token [ "=" ( token | quoted-string )*expect-params ]expect-params = ";" token [ "=" ( token | quoted-string ) ]一個服務器若是不能理解或遵循一個請求裏Expect頭域的任何expectation值,那麼它必須以合適的錯誤狀態碼響應。若是服務器不能知足任何expectation值,服務器必須以417(指望失敗)狀態碼響應,或者若是服務器知足請求時遇到其它問題,服務器必須發送4xx狀態碼。本頭域爲未來的擴展被定義成一個擴展的語法。若服務器接收到的請求含有它不支持的expectation-extension,那麼它必須以417(指望失敗)狀態響應。expectation值的比較對於未引用標記(unquoted token)(包括「100-contine」標記)是而言是不區分大小寫的,對引用字符串(quoted-string)的expectation-extension而言是區分大小寫的。Expect機制是hop-by-hop的:即HTTP/1.1代理(proxy)必須返回417(指望失敗)響應若是它接收了一個它不能知足的expectation。 然而,Expect請求頭域自己是end-to-end頭域;它必需要隨請求一塊兒轉發。許多舊版的HTTP/1.0和HTTP/1.1應用程序並不理解Expect頭域。參見8.2.3節中100(繼續)狀態的使用。14.21 ExpiresExpires實體頭域(entity-header)給出了在什麼時候以後響應即被視爲陳舊的。一個陳舊的緩存項不能被緩存(一個代理緩存或一個用戶代理的緩存)返回給客戶端,除非此緩存項被源服務器(或者被一個擁有實體的保鮮副本的中間緩存)驗證。見13.2節關於過時模型的進一步的討論。Expires頭域的出現並不意味着資源在Expire指定時間時、以前或以後將會改變或不存在。Expires頭域裏日期格式是絕對日期(absolute date)和時間,由3.3.1節中HTTP-date定義;它必須是RFC1123裏的日期格式:Expires="Expires " ":" HTTP-date使用示例爲:Expires: Thu, 01 Dec 1994 16:00:00 GMT注:若響應包含一個Cache-Control 頭域,而且含有max-age 緩存控制指令(參見14.9.3節),則此指令覆蓋Expires頭域。HTTP/1.1客戶端和緩存必須把其它無效的日期格式,特別是包含「0」的日期格式當作是過去的時間(也就是說,「已通過期」)。爲了將響應標爲「已通過期」,源服務器必須把Expires頭域裏的日期設爲與Date頭域值相等。(參見13.2.4節裏關於過時計算的規則。)爲標記響應爲「永不過時」,源服務器必須把Expires頭域裏的日期設爲晚於響應發送時間一年左右。HTTP/1.1服務器不該發送超過未來一年的過時日期。除非另外被Cache-Control頭域(見14.9節)指明,不然若是存在Expires頭域且頭域裏的日期值爲某響應(可能缺省是不可緩存的)未來時間,那麼就代表此響應是可緩存的。14.22 FromFrom請求頭域,若是有的話,應該包含用戶代理當前操做用戶的email地址。這個地址應該是機器可用的地址,這被RFC 822 [9]裏的「mailbox」定義的同時也在RFC 1123 [8]裏做了修訂:From = "From" ":" mailbox例如:From: webmaster@w3.orgFrom頭域能夠被用於記錄日誌和做爲識別無效或不指望請求的來源。他不該該被用做訪問保護的不可靠方法。這個頭域的解釋是:此請求是表明所指定人執行,此人應該承擔這個方法執行的責任。特別的,機器人代理(robot agents)應該包含這個頭域,這樣此人應該對運行此機器人代理程序負責,而且應該能被聯繫上若是在接收端出現問題的話。此頭域裏的網絡email地址是能夠和發出請求的網絡主機(host)不一樣。例如,當一個請求被經過一代理(proxy)時,源做者的地址應被使用。客戶端在沒有用戶的容許時是不該發出From頭域的,由於它可能和用戶的我的隱私或他們站點的安全策略(security policy)相沖突。強烈建議在任何一請求以前,用戶能取消,受權,和修改這個頭域的值。14.23 HostHost請求頭域指明瞭請求資源的網絡主機和端口號,這能夠從用戶或相關資源給定的源URI得到(一般是一個HTTP URL,在3.2.2節描述)。Host頭域值必須表明源服務器或網關(由那個源URL指定)的命名權限(naming authority)。這容許源服務器或網關去區分有內在歧義的URLS,例如,擁有一個IP地址對應有多個主機名服務器,它的根「/」URL。Host = "Host" ":" host [ ":" port ] ; 3.2.2節一個「host」若是沒有跟隨的端口信息,那麼就採用是請求服務的的默認端口(例如,對一個HTTP URL來講,就是80端口)。例如,一個對源服務器「http://www.w3.org/pub/WWW/」的請求,能夠用下面來表示:GET /pub/WWW/HTTP/1.1Host: www.w3.org一個客戶端必須在全部HTTP/1.1請求消息裏包含一個Host頭域。若是請求URI沒有包含請求服務的網絡主機名,那麼Host頭域必須給一個空值。一個HTTP/1.1代理必須確保任何它轉發的請求消息裏必須包含一個正確的Host 頭域,用於指定代理請求服務。全部基於網絡的HTTP/1.1服務器必須響應400(壞請求)狀態碼,若是請求消息裏缺乏Host頭域。見5.2和19.6.1.1節裏有針對Host頭域的其餘要求。14.24 If-MatchIf-Match請求頭域是用來讓方法成爲條件方法。若是一個客戶端已經從一個資源得到一個或多個實體(entity),那麼它能夠經過在If-Match頭域裏包含相應的實體標籤(entity tag)來驗證明體是否就是服務器當前實體。實體標籤(entity tag)在3.11節裏定義。這個特性使更新緩存信息只須要一個很小的事務開銷。當更新請求時,它照樣被用於防止對資源錯誤版本的不經意修改。做爲一種特殊狀況,「*」匹配資源的當前任何實體。If-Match = "If-Match" ":" ( "*" | 1#entity-tag )若是If-Match頭域裏任何一個實體標籤假設與一個類似GET請求(沒有If-Match頭域)返回響應裏實體的實體標籤相匹配,或者若是給出「*」而且請求資源的當前實體存在,那麼服務器能夠執行請求方法就好像If-Match頭域不存在同樣。服務器必須用強比較方法(見13.3.3)來比較If-Match裏的實體標籤(entity tag)。若是沒有一個實體標籤匹配,或者給出了「*」但服務器上沒有當前的實體,那麼服務器不能執行此請求的方法,而且返回412響應(先決條件失敗)。這種行爲是頗有用的,特別是在當客戶端但願防止一更新方法(updating method)(例如PUT方法)去修改此客戶端上次獲取但現已改變的資源時,若是請求假設在沒有If-Match頭域的狀況下致使了除2XX或412之外的其餘狀態碼響應,那麼If-Match頭域必須被接收端忽略。「If-Match: *」 的含義是:此方法將被執行,若是源服務器(或緩存,極可能使用Vary機制,見14.44節)選擇的表現形式(representation)存在的話,可是若是此表現形式不存在,那麼此方法不能被執行。若是一個請求想要更新一個資源(例如PUT)那麼它能夠包含一個If-Match頭域來指明:當相應於If-Match值(一個實體標籤)的實體再也不是那個資源的表現形式時,此請求方法不能被採用。這容許用戶代表:若是那個資源已經改變了而他們不知道的話,他們不但願請求成功。例如:If-Match: "xyzzy"If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"If-Match: *既有If-Match頭域又有If-None-Match或If-Modified-Since頭域的請求的結果在本規範沒有定義。14.25 If-Modified-SinceIf-Modified-Since請求頭域被用來讓方法成爲條件方法:若是請求變量(variant)自今後頭域裏指定的時間以後沒有改變,那麼服務器不該該返回實體;而是應該以304(沒有改變)狀態碼進行響應,同時返回的消息不須要消息主體(message-body)。If-Modified-Since = "If-Modified-Since" ":" HTTP-date一個例子是:If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT若是一個GET請求方法含有If-Modified-Since頭域但無Range頭域,那麼此方法請求的實體只有請求裏If-Modified-Since頭域中指定日期以後被改變才能被服務器返回。決定這個算法包括下列狀況:a)若是請求假設會致使除狀態200以外的任何其它狀態碼,或者若是If-Modified-Since日期是無效的,那麼響應就和正常的GET請求的響應徹底同樣。比服務器當前時間晚的日期是無效的。b)若是自從一個有效的If-Modified-Since日期以來,變量已經被修改了,那麼服務器應該返回一個響應同正常GET請求同樣。c)若是自從一個有效的If-Modified-Since日期以來,變量沒有被修改,那麼服務器應該返回一個304(沒有改變)響應。這種特徵的目的是以一個最小的事務開銷來更新緩存信息。注意:Range請求頭域改變了If-Modified-Since的含義;詳細信息見14.35。注意:If-Modified-Since的時間是由服務器解析的,它的時鐘可能和客戶端的不一樣步。注意:當處理一個If-Modified-Since頭域的時候,一些服務器使用精確的日期比較方法,而不是小於(less-than)比較方法,來決定是否發送304(沒有改變)響應。當爲緩存驗證而發送一個If-Modified-Since頭域的時候,爲了獲得最好的結果,客戶端被建議儘量地去利用之前Last-Modified頭域裏被接收的日期字符串。注意:若是客戶端,對同一請求,在If-Modified-Since 頭域中使用任意日期代替Last-Modified頭域裏獲得的日期,那麼客戶端應該知道這個日期應該能被服務器理解。因爲客戶端和服務器之間時間編碼的不一樣,客戶端應該考慮時鐘不一樣步和舍入的問題。若是在客戶端第一次請求時與後來請求裏頭域If-Modified-Since指定的日期之間,文檔發生改變,這就可能會出現競爭條件,還有,若是If-Modified-Since從客戶端獲得的日期沒有獲得服務器時鐘的矯正,就有可能出現時鐘誤差等問題的。客戶端和服務器時間的誤差最有多是因爲網絡的延遲形成的。既有If-Modified-Since頭域又有If-Match或If-Unmodified-Since頭域的請求的結果在本規範沒有定義。14.26 If-None-MatchIf-None-Match頭域被用於一個方法使之成爲條件的。一個客戶端若是擁有一個或多個從某資源得到的實體,那麼它能驗證在這些實體中有不存在於服務器當前實體中的實體,這經過在IfNone-Match頭域裏包含這些實體相關的實體標籤(entity tag)來達到此目的。這個特性容許經過一個最小事務開銷來更新緩存信息。它一樣被用於防止一個更新方法(如,PUT)不經意的改變一個客戶端認爲不存在但事實卻存在的資源。做爲特殊狀況,頭域值「*」匹配資源的任何當前實體。If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )若是If-None-Match頭域裏的任何實體標籤(entity tag)假設與一個類似的GET請求(假設沒有If-None-Match頭域)返回實體的實體標籤相匹配,或者,若是「*」被給出而且服務器關於那個資源的任何當前實體存在,那麼服務器不能執行此請求方法,除非資源的修改日期和請求裏If-Modified-Since頭域(假設有的話)裏提供的日期匹配失敗(譯註:匹配失敗說明資源改變了)。換言之,若是請求方法是GET或HEAD,那麼服務器應以304(沒有改變)來響應,而且包含匹配實體的相關緩存頭域(特別是Etag) 。對於全部其它方法,服務器必須以412(先決條件失敗)狀態碼響應。13.3節說明了如何判斷兩實體標籤是否匹配。弱比較方法只能用於GET或HEAD請求。若是If-None-Match頭域裏沒有實體標籤匹配,那麼服務器能夠執行此請求方法就像If-None-Match頭域不存在同樣,可是必須忽略請求裏的任何If-Modified-Since頭域。也就是說,若是沒有實體標籤匹配 ,那麼服務器不能返回304(沒有改變)響應。若是假設在沒有If-None-Match頭域存在的狀況下,請求會致使除2xx及304狀態碼以外響應,那麼If-None-Match頭域必須被忽略。(見13.3.4節關於假如同時存在If-Modified-Since和If-None-Match頭域時服務器的行爲的討論)「If-None-Match: *」的意思是:若是被源服務器(或被緩存,可能利用Vary機制,見14.44節)選擇的表現形式(representation)存在的話,請求方法不能被執行,然而,若是表現形式不存在的話,請求方法是能被執行的。這個特性能夠防止在多個PUT操做中的競爭。例:If-None-Match: "xyzzy"If-None-Match: W/"xyzzy"If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"If-None-Match: *若是一個請求含有If-None-Match頭域,還含有一個If-Match或If-Unmodified-Since頭域的話,此請求的指向結果在此規範裏沒有定義。14.27 If-Range若是客戶端在其緩存中有一實體的部分副本,並但願其整個緩存項是及時更新的,那麼客戶端能夠在一條件GET(conditional GET)(利用了If-Unmodified-Since和If-Match頭域二者或其中之一)請求裏利用Range請求頭域。然而,若是因爲實體被改變而使條件失敗,那麼客戶端可能會發出第二次請求從而去得到整個當前實體主體(entity-body)。If-Range頭域容許客戶端使第二次請求短路(short-circuit)。說的通俗一點,這意味着:若是實體沒有改變,發送我想要的部分;若是實體改變了,那就把整個新實體發過來。If-Range = 「if-Range」 「:」( entity-tag | HTTP-date)若客戶端沒有一實體標籤(entity tag),但有一個最後修改日期(Last-Modified date),它能夠在If-Range頭域裏利用此日期。(服務器經過檢查一兩個字符便可區分合法HTTP-date與任意形式的entity-tag。)If-Range頭域只應該與一Range頭域一塊兒使用,而且必須被忽略若是請求不包含一個Range頭域或者若是服務器不支持子範圍(sub-range)操做。若是If-Range頭域裏給定的實體標籤匹配服務器上當前實體的實體標籤(entity tag),那麼服務器應該提供此實體的指定範圍,並利用206(部份內容)響應。若是實體標籤(entitytag)不匹配,那麼服務器應該返回整個實體,並利用200(ok)響應。14.28 If-Unmodified-SinceIf-Unmodified-Since請求頭域被用於一個方法使之成爲條件方法。若是請求資源自今後頭域指定時間開始以後沒有改變,那麼服務器應該執行此請求就像If-Unmodified-Since頭域不存在同樣。若是請求變量(variant,譯註:見術語)在此頭域指定時間後之後已經改變,那麼服務器不能執行此請求,而且必須返回412(前提條件失敗)狀態碼。If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-日期此域的應用實例:If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT若是請求正常狀況下(即假設在沒有If-Unmodified-Since頭域的狀況下)致使任何非2xx或412狀態碼,那麼If-Unmodified-Since頭域將會忽略。若是此頭域中指定的日期無效,那麼此頭域會被忽略。在請求裏有If-Unmodified-Since頭域而且有If-None-Match或者If-Modified-Since頭域中的一個,這種請求的處理結果在此規範中沒有被定義。14.29 Last-ModifiedLast-Modified實體頭域(entity-header)指定了變量(variant)被源服務器所確信的最後修改的日期和時間。Last-Modified = 「Last-Modified」 「:」 HTTP-date應用示例以下:Last-Modified : Tue, 15 Nov 1994 12:45:26 GMT此頭域的確切含義取決於源服務器的實現和源資源(original resource)的性質。 對文件而言,它可能僅僅指示文件上次修改的時間。對於包含動態部分的實體而言,它多是組成其各個部分中最後修改時間最近的那個部分。對數據庫網關而言,它多是記錄的最新修改時間戳。對虛擬對象來講,它多是最後內部狀態改變的時間。源服務器不能發送一個遲於消息產生時間的Last-Modified日期。假如資源最後修改日期可能指示未來的某個時間,那麼服務器應該用消息產生的時間替換那個日期。源服務器得到實體Last-Modified值應儘可能靠近服務器產生響應的Date值。這容許接收者對實體修改時間做出準確的估計,特別是若是實體的改變時間接近響應產生的時間。HTTP/1.1服務器應該儘量地發送Last-Modified頭域。14.30 LocationLocation響應頭域被用於爲了完成請求或識別一個新資源,使接收者能重定向於Location指明的URI而不是請求URI。對於201(Created)響應而言,Location是請求創建新資源的位置。對於3xx響應而言,Location應被指定服務器爲自動重定向資源所喜好的URI。Location頭域值由一個絕對URI組成。Location = 「Location」 「:」 absoluteURI一個例子以下:Location : http://www.w3.org/pub/WWW/People.html注: Content-Location頭域(14.14節)不一樣於Location頭域,Content-Location頭域指定了請求裏封裝實體的源位置。有可能一個響應即包含location也包含Content-Location頭域。在13.10節裏有關於一些方法的要求。14.31 Max-ForwardsMax-Forwards請求頭域爲TRACE(9.8節)和OPTIONS(9.2節)提供一種機制去限制轉發請求的代理或網關的數量。當客戶端嘗試去跟蹤一個好像陷入失敗或陷入循環的請求鏈時,這是很是有幫助的。Max-Forwards = 「Max – Forwards」 「:」 1*DIGITMax-Forwards值是十進制的整數,它指定了請求消息能夠剩餘轉發的次數。對於一個TRACE或OPTIONS請求,若是包含一個Max-Forwards頭域,那麼接收此請求的代理或網關必須能在轉發(forwarding)此請求以前檢查和更新Max-Forwards頭域值。若是接收的值爲0,那麼接收者不能轉發此請求;而是,它必須做爲最後的接收者響應。若是接收的Max-Forwards值比0大,那麼此轉發的消息必須包含一個更新了的Max-Forwards頭域,更新的值是在接收時的值上減去1。對本規範定義的全部其它方法以及任何沒有明確做爲方法定義部分的擴展方法的請求裏,Max-Forwards頭域可能會被忽略。14.32 PragmaPragma經常使用頭域被用於包含特定執行指令,這些指令可能被應用於請求/響應鏈中任何接收者。從協議的觀點來看,pragma指令指定的行爲是可選的;然而,一些系統可能要求行爲必須知足指令的要求。Pragma = 「Pragma」 「:」 1#pragma-directivepragma-directive =」no-cache」 | extension-pragmaextension-pragma =token [ 「=」 ( token | quoted-string) ]當no-cache指令出如今請求消息中,應用程序應該轉發(forward)此請求到源服務器,即便它擁有此請求響應的緩存副本。pragma指令和no-cache緩存控制指令(見14.9)有相同的語義,而且它是爲同HTTP/1.0 向後兼容而被定義。當一個no-cache 請求發送給一個不遵循HTTP/1.1的服務器時,客戶端應該既包含pragma指令也包含no-cache緩存控制指令。pragma指令必須能穿過代理和網關應用程序,無論對於那些應用程序有沒有意義。由於這些指令可能對請求/響應鏈上的全部接受者有用。不可能爲一個特定的接收者定義一個pragma;然而,任何對接收者不相關的pragma指令都應該被接收者忽略。HTTP/1.1 緩存應該把「Pragma:no-cache」看成好像客戶端發送了「cache-control:nocache」。在HTTP中不會有新的pragma指令會被定義。14.33 Proxy-AuthenticateProxy-Authenticate 響應頭域必須被包含在407 響應(代理受權)裏。此頭域值由一個challenge和parameters組成,challenge指明瞭受權模式,而parameters應用於請求URI的代理。Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge關於HTTP訪問受權過程的描述在「HTTP Authentication:Basic and Digest AccessAuthentication」[43]中介紹了。不像WWW-Authenticate頭域,Proxy-Authenticate頭域只能應用於當前鏈接,而且不該該傳遞給下游(downstrem)客戶端。然而,一箇中間代理可能須要從請求下游客戶端而得到它本身的證書(credentials),這在一些狀況下就好像代理正在轉發Proxy-Authenticate頭域同樣。14.34 Proxy-AuthorizationProxy-Authorization請求頭域容許客戶端讓一代理能給客戶端本身(或客戶端的用戶)受權。Proxy-Authorization頭域值由包含用戶代理(爲代理和/或請求資源域)的受權信息的證書組成。Proxy-Authorization = 「Proxy-Authorization」 「:」 credentialsHTTP訪問受權過程在「HTTP Authentication: Basic and Digest Access Authentication」[43]中描述。不像Authorization頭域,Proxy-Authorization頭域只能應用於下一個指望利用Proxy-Authenticate頭域受權的外向(outbound)代理。。14.35 Range14.35.1 字節範圍 (Byte Ranges)既然全部的HTTP 實體都以字節序列形式的HTTP 消息表示,那麼字節範圍的概念對任何HTTP實體都是有意義的.(不過並非全部的客戶和服務器都須要支持字節範圍操做.。)HTTP裏的字節範圍應用於實體主體的字節序列(沒必要和消息主體同樣)。字節範圍操做可能會在一個實體裏指定一個字節範圍或多個字節範圍。ranges-specifier = byte-ranges-specifierbyte-ranges-specifier = bytes-unit "=" byte-range-setbyte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )byte-range-spec = first-byte-pos "-" [last-byte-pos]first-byte-pos = 1*DIGITlast-byte-pos = 1*DIGITbyte-range-spec裏的first-byte-pos值給出了一個範圍裏第一個字節的偏移量.。last-byte-pos值給出了這個範圍裏最後一個字節的偏移量;也就是說,肯定的字節位置必須在實體的範圍以內。字節偏移是以0爲基準(譯註:0表明第一個字節,1表明第二個字節)。若是存在last-byte-pos值,那麼它必定大於或等於那個byte-range-spec裏的first-byte-pos,不然byte-range-spec在句法上是非法的。接收者接收到包括一個或多個無效的byte-rangespec值的byte-range-set時,它必須忽略包含那個byte-range-set的頭域.。若是last-byte-pos值不存在,或者大於或等於實體主體的當前長度,則認爲last-byte-pos等於當前實體主體長度減一。經過選擇last-byte-pos,客戶可以限制得到實體的字節數量而不須要知道實體的大小。suffix-byte-range-spec = 「-「 suffix-lengthsuffix-length = 1*DIGITsuffix-byte-range-spec用來表示實體主體的後綴,其長度由suffix-length值給出.。(也就是說,這種形式規定了實體正文的最後N個字節。)若是實體短於指定的suffix-length,則使用整個實體主體。若是一個句法正確的byte-range-set 至少包括一個這樣的byte-range-spec,它的first-bytepos比實體主體的當前長度要小,或至少包括一個suffix-length 非零的 suffix-byte-rangespec,那麼byte-range-set是能夠知足的,不然是不可知足的。若是byte-range-set不能知足,那麼服務器應該返回一個416響應(請求範圍不能知足)。不然,服務器應該返回一個206響應(部份內容)byte-ranges-specifier(字節-範圍-說明符)值的例子(假定實體主體的長度爲10000):-- 第一個500字節(字節偏移量0-499,包括0和499): bytes=0-499-- 第二個500字節(字節偏移量500-999,包括500和999): bytes=500-999-- 最後500字節(字節偏移量9500-9999,包括9500和9999): bytes=-500 或 bytes=9500--- 僅僅第一個和最後一個字節(字節0和9999): bytes=0-0,-1-- 關於第二個500字節(字節偏移量500-999,包括500和999)的幾種合法但不規範的敘述:bytes=500-600,601-999bytes=500-700,601-99914.35.2 範圍請求(Range Retrieval Requests)使用條件或無條件GET方法能夠請求實體的一個或多個字節範圍,而不是整個實體,這利用Range請求頭域,請求返回的結果就是Range頭域指示的請求資源實體的範圍。Range = "Range" ":" ranges-specifier服務器能夠忽略Range頭域。然而,.HTTP/1.1源服務器和中間緩存應該儘量支持字節範圍,由於Range支持從部分失敗傳輸中有效地恢復,而且支持從大的實體中有效地獲取部份內容。若是服務器支持Range頭域,而且指定的範圍或多個範圍對實體來講是適合的:1. 若是在無條件GET請求裏出現Range頭域,那麼這將會改變沒有Range頭域時的GET請求返回的結果。換句話說,返回的狀態碼不是200(ok)而是206(部分響應)。2. 若是在條件GET(請求裏利用了If-Modified-Since和If-None-Match中任意一個或二者,或者利用了If-Unmodified-Since和If-Match中的任意一個或二者)請求裏出現Range頭域,那麼這將改變返回的結果,若是GET請求假設在沒有Range頭域時被服務器成功響應而且條件爲真。但若是條件爲假,它不會影響304(沒有改變)響應被返回。某些情形下,除了使用Range頭域外,可能還要同時使用If-Range頭域(見14.27節)。若是支持範圍請求的代理接收了一個範圍請求,並轉發(forward)請求到內向(inbound)服務器,而且接收到了一個完整實體,那麼它只應該返回給客戶請求的範圍。代理將接收的整個響應存儲到它的緩存裏若是此響應知足緩存分配策略。14.36 RefererReferer請求頭域容許客戶端,爲了讓服務器受益,指定請求URI來源的資源URI。(Referer頭域的Referer本應該寫成Referrer,出現了筆誤)。Referer請求頭域容許服務器爲了我的興趣,記錄日誌,優化緩存等來產生回退連接列表。它照樣容許服務器爲維護而跟蹤過期或寫錯的連接。Referer頭域不能被髮送若是請求URI從一個沒有自身URI的資源得到,例如用戶從鍵盤輸入。Referer = "Referer" ":" ( absoluteURI | relativeURI )例如:Referer: http://www.w3.org/hypertext/DataSources/Overview.html若是Referer頭域的域值是相對URI,那麼它將被解析爲相對於請求URI。URI不能包含一個片斷(fragment)。見15.1.3關於安全的考慮。14.37 Retry-AfterRetry-After響應頭域能被用於一個503(服務不可得)響應,服務器用它來向請求端指明服務不可得的時長。此頭域可能被用於3xx(重定向)響應,服務器用它來(如web瀏覽器)指明用戶代理再次提交已重定向請求以前的最小等待時間。Retry-After頭域值多是HTTP-date或者也多是一個響應時間後的十進制整數秒。Retry-After = 「Retry-After」 「:」 ( HTTP-date | delta-seconds )下面是它的兩個例子Retry-After: Fri,31 Dec 1999 23:59:59 GMTRetry-After:120在後一例子中,延遲時間是2分鐘。14.38 ServerServer響應頭域包含了源服務器用於處理請求的軟件信息。 此域可包含多個產品標記(3.8節),以及鑑別服務器與其餘重要子產品的註釋。產品標記按它們的重要性來排列,並鑑別應用程序。Server = 「Server」例:服務器:CERN/3.0 libwww/2.17若響應是經過代理轉發的,則代理程序不得修改Server響應頭域。做爲替代,它應該包含一個Via頭域(在14.45節裏描述)。注:揭示特定的軟件版本可能會使服務器易於受到那些針對已知安全漏洞的軟件的攻擊。 建議服務器實現者將此域做爲可設置項。14.39 TETE請求頭域指明客戶端能夠接受哪些傳輸編碼(transfer-coding)的響應,和是否願意接受塊(chunked)傳輸編碼響應的尾部(trailer)(譯註:TE 頭域和Accept-Encoding 頭域與Content-Encoding 頭域很類似,但TE 應用於傳輸編碼(transfer coding),而Content-Encoding應用於內容編碼(content coding,見3.5節))。 TE請求頭域的值可能由包含關鍵字「trailers」 和/或用逗號分隔的擴展傳輸編碼名(擴展傳輸編碼名可能會攜帶可選的接受參數的列表)(在3.6節描述)組成。TE = "TE" ":" #( t-codings )t-codings = "trailers" | ( transfer-extension [ accept-params ] )若是出現關鍵字「trailers」,那麼它指明客戶端願意接受(chunked)傳輸編碼響應的尾部(trailer)。 此關鍵字爲傳輸編碼(transfer-coding)值而保留,但它自己不表明一種傳輸編碼。舉例:TE: deflateTE:TE: trailers, deflate;q=0.5TE請求頭域僅適用於當即鏈接。因此不管什麼時候,只要在HTTP/1.1消息中存在TE頭域,鏈接頭域(Connection header filed)(參見14.10節)中就必須指明。經過TE頭域,服務器能利用下述規則來測試傳輸編碼(transfer-coding)是不是可被客戶端接受的:1.塊(chunked)傳輸編碼老是能夠接受的。若是在TE頭域裏出現關鍵字「trailers」,那麼客戶端指明它願意表明本身或任意下游(downstream)客戶端去接受塊(chunked)傳輸編碼響應裏的尾部(trailer)。這意味着,若是「trailers」給定,客戶端正在聲明全部下游(downstream)客戶端願意接收塊(chunked)傳輸編碼響應裏的尾部(trailer),或聲明它願意表明下游接收端去嘗試緩存響應。注意:HTTP/1.1並無定義任何方法去限制塊傳輸編碼響應的大小,這是爲了方便客戶端能緩存整個響應。2.只要是出如今TE 頭域裏的傳輸編碼都是可被請求端接受的,除非此傳輸編碼跟隨的qvalue 值爲0(根據3.9 節中定義,qvalue 爲0 代表是「不可接受的」(notacceptable)))3.若是在TE頭域裏有指明多個傳輸編碼是可接受的,那麼傳輸編碼(transfer-coding)的qvalue值最大的是最容易被被接受的。塊傳輸編碼的qvalue值爲1。若是TE頭域值是空的或者TE頭域沒有出如今消息裏,那麼服務器只能認爲塊(chunked)傳輸編碼的響應是請求端能夠接受的。沒有傳輸編碼的消息老是可接受的。14.40 TrailerTrailer經常使用頭域值指明瞭以塊(chunked)傳輸編碼的消息裏尾部(trailer)用到的頭域。Trailer = "Trailer" ":" 1#field-name一個HTTP/1.1消息會包含一個Trailer頭域,若是消息利用了塊(chunked)傳輸編碼而且編碼裏的尾部(trailer)不爲空。這樣作是爲了使接收端知道塊(chunked)傳輸編碼響應消息尾部(trailer)有哪些頭域。若是具備塊傳輸編碼的消息,但沒有Trailer頭域存在,則此消息的尾部(trailer)將不能包括任何頭域。3.6.1節展現了塊傳輸編碼的尾部(trailer)的利用限制。Trailer頭域中指示的消息頭域不能包括下面的頭域:.Transfer-Encoding.Content-Length.Trailer14.41 Transfer-Encoding傳輸譯碼(Transfer-Encoding)經常使用頭域指示了消息主體(message body)的編碼轉換,這是爲了實如今接收端和發送端之間的安全數據傳輸。它不一樣於內容編碼(content-coding),傳輸代碼是消息的屬性,而不是實體(entity)的屬性。Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding傳輸編碼(transfer-coding)在3.6節中被定義了。一個例子是:Transfer-Encoding: chunked若是一個實體應用了多種傳輸編碼,傳輸編碼(transfer-coding)必須以應用的順序列出。傳輸編碼(transfer-coding)可能會提供編碼參數(譯註:看傳輸編碼的定義,3.6節),這些編碼參數額外的信息可能會被其它實體頭域(entity-header)提供,但這並無在規範裏定義。許多老的HTTP/1.1應用程序不能理解傳輸譯碼(Transfer-Encoding)頭域。14.42 UpgradeUpgrade經常使用頭域容許客戶端指定它所支持的附加通訊協議,而且可能會使用若是服務器以爲能夠進行協議切換。服務器必須利用Upgrade頭域於一個101(切換協議)響應裏,用來指明哪一個協議被切換了。Upgrade = 「Upgrade」 「:」 1#product例如,Upgrade: HTTP/2.0,SHTTP/1.3, IRC/6.9, RTA/x11Upgrade頭域的目的是爲了提供一個從HTTP/1.1到其它不兼容協議的簡單遷移機制。這經過容許客戶端告訴服務器客戶端指望利用另外一種協議,例如主版本號更高的最新HTTP協議,即便當前請求仍然使用HTTP/1.1。這能下降不兼容協議之間遷移的難度,只須要客戶端以一個更廣泛被支持協議發起一個請求,同時告訴服務器客戶端想利用「更好的」協議若是能夠的話(「更好的」由服務器決定,可能根據方法和/或請求資源的性質決定)。Upgrade頭域只能應用於應用程序層(application –layer)協議之間的切換,應用程序層協議在傳輸層(transport-layer)鏈接之上。Upgrade頭域並不意味着協議必定要改變;而且服務器接受和使用是可選的。在協議改變後應用程序層(apllication-layer)的通訊能力和性質,徹底依賴於新協議的選擇,儘管在改變協議後的第一個動做必須是對初始HTTP 請求(包含Upgrade頭域)的響應。Upgrade頭域只能應用於當即鏈接(immediate connection)。所以,upgrade關鍵字必須被提供在Connection頭域裏(見14.10節),只要Upgrade頭域呈如今HTTP/1.1消息裏。Upgrade頭域不能被用來指定切換到一個不一樣鏈接的協議。爲這個目的,使用301,302,303重定向響應更合適。這個規範定義了本協議的名字爲「HTTP」,它在3.1節的HTTP版本規則中定義的超文本傳輸協議家族中被使用。任何一個標記均可被用來作協議名字,然而,只有當客戶端和服務器認爲這個名字對應同一協議纔有用。14.43 User-AgentUser-Agent請求頭域包含關於發起請求的用戶代理的信息。這是爲了統計,跟蹤協議違反的狀況,和爲了識別用戶代理從而爲特定用戶代理自動定製響應。用戶代理應該包含User-Agent頭域在請求中。此頭域包含多個識別代理和子產品的產品標記(見3.8節)和解釋。一般,爲了識別應用程序,產品標記按重要性排列。User-Agent = "User-Agent" ":" 1*( product | comment )例子:User-Agent: CERN-LineMode/2.15 libwww/2.17b314.44 VaryVary響應頭域值指定了一些請求頭域,所有去決定某緩存是否被容許去利用此響應(而且此響應仍然保鮮)去回覆後續請求而不須要重驗證(revalidation)。對於不可緩存或已陳舊的響應,Vary頭域值用於告訴用戶代理(user agent)選擇表現形式(reprentation)的標準。一個Vary頭域值是「*」意味着緩存不能根據後續請求的請求頭域來決定此響應是合適的表現形式。見13.6節關於緩存如何利用Vary頭域。Vary = "Vary" ":" ( "*" | 1#field-name )一個HTTP/1.1的服務器應該包含一個Vary頭域於任何可緩存的受限於服務器驅動協商的響應裏。這樣作是容許緩存恰當去理解關於那個資源的未來請求,並通知用戶代理關於那個資源的協商出現。一個服務器可能包含一個Vary頭域於一個不可緩存的受限於服務器驅動協商的響應裏,由於這樣作可能爲用戶代理提供有用的關於響應變化的維度的信息。一個Vary頭域值由域名(filed-name)組成,響應的表現形式是基於Vary頭域裏列舉的請求頭域來選擇的。一個緩存可能會假設爲未來請求進行相同的選擇,若是Vary頭域例舉了相同的域名,但必須是此響應在此期間是保鮮的。Vary頭域裏的域名並非侷限於本規範裏定義的標準請求頭域。域名是大小寫不敏感的。Vary域值爲「*」指明不受限於請求頭域的非特指參數(例如,客戶端的網絡地址)做用於響應表現形式中進行選擇 。「*」值不能被代理產生;它可能只能被源服務器產生。14.45 ViaVia經常使用頭域必須被網關(gateways)和代理(proxies)使用,用來指明在用戶代理和服務器之間關於請求的中間協議和接收者,和在源服務器和客戶端之間關於響應的中間協議和接收者。它和RFC822[9]裏的「Received」頭域類似,而且它用於跟蹤消息的轉發,避免請求循環,和指定沿着請求/響應鏈的全部發送者的協議能力。Via = "Via" ":" 1#( received-protocol received-by [ comment ] )received-protocol = [ protocol-name "/" ] protocol-versionprotocol-name = tokenprotocol-version = tokenreceived-by = ( host [ ":" port ] ) | pseudonympseudonym = tokenreceived-protocol 指出沿着請求/響應鏈每一段的服務器或客戶端所接收消息的協議版本。protocol-version被追加於Via頭域值後面,當消息被轉發時。只要協議是HTTP,那麼protocol-name是無關緊要的。received-by頭域一般是接收的轉發服務器的host(主機)和可選的port(端口)號,或接收的轉發客戶端的host(主機)和可選的port(端口)號。然而,若是真實host(主機)被看做是信息敏感的,那麼此主機可能會被別名代替。若是port(端口號)沒有被給定,那麼它可能被假設爲received-protocol 的缺省port(端口)號。Via頭域裏若是有多個域值,則每一個值分別表明一個已經轉發消息的代理或網關。每個接收者必須把它的信息追加到最後,因此最後的結果是按照轉發應用程序的順序來的。comment(註釋)可能被用於Via頭域是爲了指定接收者代理或網關的軟件,這個比如User-Agent和Server頭域。然而,Via頭域裏全部的comment是可選的(譯註:無關緊要的),而且能夠被接收者在轉發消息以前移去。例如,有一個請求消息來自於一個HTTP/1.0用戶代理,被髮送到代號爲「fred」的內部代理,此內部代理利用HTTP/1.1協議轉發此請求給一個站點爲nowhere.com的公共代理,而此公共代理爲了完成此請求經過把它轉發到站點爲「 www.ics.uci,edu」的源服務器。被「www.ics.uci.edu」站點接收後的請求這時可能有下面的Via頭域:Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)被用做通向網絡防火牆的入口的代理和網關在缺省狀況下不該該轉發host(主機)的名字和端口到防火牆區域裏。若是這些信息顯示地指定要被傳送,那麼就應該被傳送。若是此信息顯示地指定不能被傳送,那麼任何穿過防火牆而被接收的host(主機)應該用一個合適的別名替換。爲了隱藏組織結構的內部結構須要,一個代理(proxy)可能會在一個Via 頭域中把相同received-protocal值的項合成一個項。例如,Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy將被摺疊成Via: 1.0 ricky, 1.1 mertz, 1.0 lucy應用程序不該該合併多個項,除非他們都在相同組織的控制下而且host(主機)已經被別名代替了。應用程序不能合併不一樣received-protocaol值的項。14.46 WarningWarning經常使用頭域被用於攜帶額外關於消息狀態或消息轉換的信息,而這些信息是不能在消息裏反應出來的。這些信息一般被用於去警告因爲緩存操做或消息主體轉換帶來的透明性(semantic transparency)的缺失。Warning頭域被用於響應裏,這裏有以下語法:Warning = "Warning" ":" 1#warning-valuewarning-value = warn-code SP warn-agent SP warn-text[SP warn-date]warn-code = 3DIGITwarn-agent = ( host [ ":" port ] ) | pseudonym; the name or pseudonym of the server adding; the Warning header, for use in debuggingwarn-text = quoted-stringwarn-date = <"> HTTP-date <">一個響應可能攜帶多個Warning頭域。warn-text必須使用對於接收響應的用戶來講儘量理解的天然語言和字符集。找到用戶自能理解的天然語言和字符集,必須基於任何可能的知識,如緩存或用戶的位置,請求裏的Accept-Language頭域,響應裏的Content-Language頭域,等等。缺省語言是英語,缺省字符集是ISO-8859-1。若是字符集不是ISO-8859-1,那麼它必須利用RFC2047裏描述的來在warn-text裏進行編碼。Warning頭域能被應用於任何消息,然而,一些warn-codes是特定於緩存的,而且只能被應用於響應消息。新的Warning頭域應添加到任何已存Warning頭域的後面。緩存不能刪除任何它接收到的消息裏的Warning頭域。然而,若是一緩存成功驗證一緩存項,那麼它應移除任何之前依附於那個緩存項的Warning頭域除了特定警告碼(Warning codes)的Warning頭域。而後,它必須添加這個驗證響應裏的任何Warning頭域。換句話說,Warning頭域是依附於最近相關響應的Warning頭域。當多個Warning頭域被附加於一個響應裏,那麼用戶代理應該通知用戶儘量多的警告,而且以它們呈如今響應裏的順序。若是用戶代理不能通知用戶全部的警告,那麼用戶代理應該按照下面的規則:- 前面的響應裏的警告優於後面響應的警告- 用戶偏心的字符集的警告優於其它字符集的警告,但這除了warn-codes和warn-agents一致的狀況。產生多個Warning頭域的系統應該時刻記住利用用戶代理行爲來安排警告。關於警告的緩存行爲的要求在13.1.2裏描述。下面是當前定義的warn-codes,每個warn-code 都有一個建議性的以英語表示的warntext,和它的意思的描述。110 Response is stale不管什麼時候當返回響應是陳舊的時候,必須被包含。111 Revalidation failed若是一個緩存由於嘗試去重驗證響應失敗而返回一個陳舊的響應(因爲不能到達服務器),必須被包含。112 Disconnected operation若是緩存在一段時間被有意地斷開鏈接,應該被包含。113 Heuristic expiration若是緩存探索性地選擇了一個保鮮壽命大於24小時而且響應的年齡大於24小時時,必須被包含。199 Miscellaneous warning警告文本可能包含任意信息呈現給用戶。除了呈現給用戶警告,接收警告的系統不能採起任何自動行爲。214 Transformation applied若是一箇中間緩存或代理採用任何對響應的內容編碼(content-coding)(在Content-Encoding頭域裏指定)或媒體類型(media-type)(在Content-Type頭域裏指定)的改變變,或響應的實體主體(entity-body)的改變,那麼此響應碼必須被中間緩存或代理添加,除非此警告碼(warning code)已經在響應裏出現。299 Miscellaneous persistent warning警告文本應該包含任意呈現給用戶的任意信息。接收警告的系統不能採起任何自動行爲。若是一個實如今一個消息裏發送多個版本是HTTP/1.0或更早的HTTP協議版本的Warning頭域,那麼發送者必須包含一個和響應日期(date)相等的warn-date到每個Warning頭域值中。若是一個實現收到一條warning-value裏包含一個warn-date的消息,而且那個warn-date不一樣於響應裏的Date值,那麼warning-value必須在保存,轉發,或利用消息以前從消息裏刪除。(這回防止本地緩存去緩存Warning頭域的惡果。)若是全部warning-value由於這個緣由而被刪除,Warning頭域必須也要被刪除。14.47 WWW-AuthenticateWWW-Authenticate響應頭域必須包含在401(沒有被受權)響應消息中。此域值至少應該包含一個callenge,此callenge指明受權模式(schemes)和適用於請求URI的參數。WWW-Authenticate =「WWW-Authenticate」 「:」 1#challengeHTTP訪問受權過程在「HTTP Authentication: Basic and Digest Access Authentication」[43]裏描述。用戶代理被建議特別當心去解析WWW-Authenticate 頭域值,當此頭域值包含多個challenge,或若是多個WWW-Authenticate頭域被提供且challenge的內容能包含逗號分隔的受權參數的時候。15.安全考慮 (Security Consideration)這一部分是用來提醒程序開發人員,信息提供者,和用戶關於HTTP/1.1安全方面的限制。討論並不包含對被披露問題的明確的解決辦法,然而,它卻對減小安全風險提供了一些建議。15.1 我的信息 (Personal Information)HTTP的客戶端常常要對大量的我的信息保密(例如用戶的名字,域,郵件地址,口令,密匙等。),而且應當很是當心地防止這些信息無心識地經過HTTP協議泄露到其餘的資源。咱們很是強烈地建議應該給用戶提供一個方便的界面來控制這種信息的傳播,而且設計者和實現者在這方面應該特別注意。歷史告訴咱們在這方面的錯誤常常引發嚴重的安全和/或者隱私問題,並致使對設計或實現者的公司產生很是不利的影響。15.1.1服務器日誌信息的濫用 (Abuse of Server Log Information)服務器是用來保存用來指定用戶讀模型或感興趣主題的請求的。這些信息一般顯然是需保密的,而且它的使用在某些國家被法律保護。利用HTTP協議提供數據的人們必須保證在這些數據被許可的狀況下分發。15.1.2敏感信息的傳輸 (Transfer of Sensitive Inforamtion)就像任何數據傳輸協議同樣,HTTP不能調整傳輸數據的內容,也沒有任何經驗方法在任意給定請求的背景裏去判斷特定信息的敏感性。所以,應用程序應該儘量爲此信息提供者提供對此信息的控制。在此背景裏,有四個頭域須要提出來,這四個頭域是:Server,Via,Referer和From。揭露服務器特定軟件版本信息可能會使服務器的機器更容易受到經過軟件安全漏洞來進行攻擊的攻擊。實現者應該使Server頭域成爲可設置的選項。用做穿過網絡防火牆入口的代理應該特別當心防火牆後能夠辨別主機信息的頭域信息被傳輸。特別是,代理應移除在防火牆以後產生的任何Via頭域。Referer頭域容許被學習的讀模式和反向連接的跟蹤。雖然它很是有用,但也會被濫用若是用戶細節沒有從包含在Referer頭域裏信息裏分離開來。即便當我的信息已經被移除了,Referer頭域也可能指定私有文檔的URI(不能被公開)。From頭域裏的信息可能會和用戶的私有興趣或他們站點的安全策略相沖突,所以From頭域不該被傳輸在用戶沒有能使此頭域的內容失效、有效和更改的狀況下。用戶必須能在用戶的喜好或應用程序的缺省設置範圍內設置此頭域的內容。咱們建議,儘管不須要,給用戶提供一個方便的開關界面來使發送From和Referer頭域有效或失效。User-Agent(14.4節)或Server(14.38節)頭域有時候能被用來去判斷一個特定的客戶端或服務器是否存在安全漏洞。不幸的是,一樣的信息常常被用於其它有價值的目的,由於HTTP當前沒有更好的機制。15.1.3 URI 中敏感信息的編碼(Encoding Sensitive Information inURI’s)由於一個連接的源多是私有信息或者可能揭露其它私有信息源,因此強烈建議用戶能選擇是否須要發送Referer頭域。例如,瀏覽器客戶端可能爲了開放/匿名方式提供一個觸發開關,此開關可能使Referer頭域和From頭域信息的發送有效/無效。若是參考頁面在一個安全的協議上傳輸,客戶端不該該包含一個Referer頭域在一個非安全HTTP請求裏。利用HTTP協議的服務做者不該該利用基於窗體GET提交敏感數據,由於這個能引發數據在請求URI裏被編碼。許多已存在的服務,代理,和用戶代理將在對第三方可見的地方記錄請求URI。服務器能利用基於窗體POST提交來取代基於窗體GET提交。15.1.4 鏈接到Accept頭域的隱私問題Accept請求頭域能揭露用戶的信息給全部被訪問的服務器。Accept-Language頭域能揭露用戶的私有信息,由於能理解特定語言的人常常被認爲就是某個特定種族裏的成員。提供選項在每次請求裏去設置Accept-Language頭域的用戶代理被強烈鼓勵讓設置過程應包含一個讓用戶知道本身隱私可能被會泄漏的消息。一種限制隱私丟失的方法多是缺省爲用戶代理去遺漏Accept-Language頭域的發送,而且詢問用戶是否給開始給服務器發送Accept-Language頭域,若是用戶代理經過查看任何由服務器產生的Vary響應頭域時發現這個發送能提升服務的質量。每個請求裏的用戶可配置的接受頭域(accept header fields),特別是若是這些接受頭域(accept header fileds)包含質量值,那麼應該被服務器用做相對信賴和長久的用戶標識符(user identifiers)。這樣的用戶標識符將會容許內容提供者進行點擊跟蹤以及容許合做內容提供者匹配跨服務器點擊跟蹤或者造成單個用戶窗體提交。注意對於許多並不在代理後面的用戶,運行用戶代理的主機的網絡地址也將做爲長久用戶的標識符。在代理被用做加強隱私的環境裏,用戶代理應保守地提供接受(accept)頭域配置選項給終端用戶上。做爲一種高度隱私的方式,用戶代理可能在接力的(relayed)的請求裏的過濾接受頭域。提供高度可配置性的用戶代理應警告用戶會有隱私的泄漏。15.2 基於文件和路徑名稱的攻擊HTTP的源服務器的實現應該限制HTTP請求返回的文檔應是服務器管理員有意圖的文檔。若是HTTP服務器要把HTTP URIs翻譯成文件系統的調用,那麼服務器必須當心去對待提供給HTTP客戶端的文件傳輸。例如,UNIX,微軟Windows,和其餘操做系統都利用「..」去指示當前的父目錄。對於這樣一個系統,一HTTP服務器不容許任何這樣的構造(construct)在請求URI裏,若是這個構造能在經過HTTP服務器訪問以外能訪問這個資源。一樣的,用做對服務器內部引用的文件(如訪問控制文件,配置文件,腳本代碼)必須受到保護而不讓其被不合適的獲取,由於他們可能包含敏感的信息。經驗告訴咱們一個在HTTP服務器實現裏的一個小小的錯誤會帶來安全風險。15.3 DNS欺騙使用HTTP的客戶端嚴重依賴於域名服務,所以這會致使基於IP和DNS名稱的不關聯的攻擊。客戶端須要當心關注IP地址/DNS名稱關聯的持久合法性。特別是,HTTP客戶端爲了確認IP地址/DNS名稱關聯性,應該依賴於客戶端本身的的名稱解析器,而不該依賴緩存之前主機(host)名稱查找(host name lookups)結果。許多平臺在恰當的時候可在本地緩存主機名稱查找(host name lookups),而且他們應被配置爲可這樣作。然而,只有當被名稱服務器報告的TTL(Time To Live)信息指明被緩存的信息仍然有用時,才能夠緩存查找(lookups)。若是HTTP客戶端爲了提升性能去緩存主機名稱查找(host name lookups)的結果,那麼他必須觀察被DNS報告的TTL信息。若是HTTP客戶端不能看到這條規則,那麼,當之前訪問的IP地址改變時,他們就會被欺騙。由於網絡地址的改變變得很日常,因此這種形式的攻擊在不斷增長。看到這個規則能減小潛在的安全攻擊的可能性。此要求一樣能改進客戶端負載均衡(load-balancing)行爲,由於重複的服務器能利用同一個DNS名稱,此要求能下降用戶在訪問利用策略(strategy)的站點中的體驗失敗。15.4 Location頭域和欺騙若是單個的服務器支持互不信任的多個組織,那麼它必須檢查響應(在據稱的組織的控制下產生)裏Location和Content-Location頭域值,以確信這些頭域不會使它們沒有權限的資源無效。15.5 Content-Disposition的問題RFC 1806 [35],在HTTP中常用的Content-Disposition(見19.5.1節)頭域就源於此文檔,有許多很是認真的安全考慮在此文檔裏說明。Content-Disposition並非HTTP標準版本中的一部分,但自從它被普遍應用以來,咱們正在證實它對使用者的價值和風險。詳細資料見RFC 2183 [49](對RFC 1806的升級)。15.6 受權證書和空閒客戶端現有的HTTP客戶端和用戶代理一般會不明確地保留受權信息。HTTP/1.1並無爲服務器提供一個方法讓服務器去指導客戶端丟棄這些緩存的證書(credentials)。這是一個重大缺陷,此缺陷須要擴展HTTP協議來解決。在某些情形下,緩存證書會干涉應用程序的安全模型,這些情形包含但不侷限於: 這樣的客戶端。此客戶端空閒已到達必定時間,服務器可能但願再次使客戶端讓用戶出示證書。 這樣的應用程序。此應用程序包括了一個會話中斷指令(例如在一頁上有「退出」或者「提交」的按鈕),根據此指令,服務器端「知道」不須要更多理爲客戶端保留證書。這是做爲當前獨立研究的。有不少解決這個問題的社區,而且咱們鼓勵在屏幕保護程序、空閒超時、和其餘能減輕安全問題的方法裏利用密碼保護。特別是,能緩存證書的用戶代理被鼓勵去提供一個容易的訪問控制機制,讓在用戶控制下丟棄緩存的證書。15.7 代理和緩存 (Proxies and Caching)本質上說,HTTP代理是中間人(men-in-the-middle),而且存在中間人攻擊(man-in-themiddleattacks)危險。系統(代理運行於其上)的缺陷能致使嚴重的安全和隱私問題。代理擁有對相關安全信息、用戶和組織的我的信息、和屬於用戶和內容提供者的專有信息的訪問權限。一個有缺陷的代理,或一個沒有考慮安全性和隱私性的代理可能會被委託用來攻擊。代理操做者應該保護代理運行其上的系統,正如他們保護任何包含或傳輸敏感信息的系統同樣。特別是,代理上收集的日誌信息常常包含較高的我的敏感信息,和/或關於組織的信息。日誌信息應該被當心的保護,而且要合適地開發利用。(見15.1.1)節。代理的設計者應當考慮到設計和編碼斷定所涉及到的隱私和安全問題,以及他們提供給代理操做人員配置選項(尤爲是缺省配置)所牽涉到的隱私和安全問題。代理的用戶須要知道他們自比運行代理的操做員更不值得信賴;HTTP協議自身不能解決這個問題。在合適的時候,對密碼學的正確應用,可能會保護普遍的安全和隱私攻擊。密碼學的討論不在本協議文檔的範圍內。15.7.1 關於代理的服務攻擊的拒絕代理是存在的。代理很難被保護。關於此研究正在進行。16 感謝(Acknowledgment)這份規範大量使用了擴展BNF和David爲RFC 822 [9]定義的經常使用結構。一樣的,它繼續使用了不少Nathaniel Borenestein和Ned Freed爲MIME [7]提供的定義。咱們但願在此規範裏他們的結論有助於減小過去在HTTP和互聯網郵件消息格式關係上的混淆。HTTP協議在這幾年已經有了至關的發展。它受益於大量積極的開發人員的社區--許多人已經經過www-talk郵件列表參與進來--而且一般就是那個社區對HTTP和萬維網的成功做了重大貢獻。Marc Andreessen, Robert Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois Groff , Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob McCool, LouMontulli, Dave Raggett, Tony Sanders, 和 Marc VanHeyningen由於他們在定義協議早期方面的貢獻應該獲得特別的讚譽。這篇文檔從全部那些參加HTTP-WG的人員的註釋中得到了很大的益處。除了已經提到的那些人之外,下列人士對這個規範作出了貢獻:Gary Adams Ross PattersonHarald Tveit Alvestrand Albert LundeKeith Ball John C. MalleryBrian Behlendorf Jean-Philippe Martin-FlatinPaul Burchard MitraMaurizio Codogno David MorrisMike Cowlishaw Gavin NicolRoman Czyborra Bill PerryMichael A. Dolan Jeffrey PerryDavid J. Fiander Scott PowersAlan Freier Owen ReesMarc Hedlund Luigi RizzoGreg Herlihy David RobinsonKoen Holtman Marc SalomonAlex Hopmann Rich SalzBob Jernigan Allan M. SchiffmanShel Kaphan Jim SeidmanRohit Khare Chuck ShottonJohn Klensin Eric W. SinkMartijn Koster Simon E. SperoAlexei Kosut Richard N. TaylorDavid M. Kristol Robert S. ThauDaniel LaLiberte Bill (BearHeart) WeinmanBen Laurie Francois YergeauPaul J. Leach Mary Ellen ZurkoDaniel DuBois Josh Cohen緩存設計的許多內容和介紹應歸於如下人士的建議和註釋:Shel Kaphan, Paul Leach, KoenHoltman, David Morris, 和 Larry Masinter。大部分規範的範圍是基於Ari Luotonen和John Franks早期作的工做,以及從Steve Zilles另外加入的內容。感謝Palo Alto的"cave men"。大家知道大家是誰。Jim Gettys(這篇文檔如今的編者)特別但願感謝Roy Fielding,這篇文檔之前的編者,連同John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen Holtman, John Franks, JoshCohen, Alex Hopmann, Scott Lawrence, 和Larry Masinter一塊兒感謝他們的幫助。還要特別感謝Jeff Mogul和Scott Lawrence對「MUST/MAY/ SHOULD」使用的檢查。Apache 組,Anselm Baird-Smith,Jigsaw 的做者,和Henrik Frystyk 在早期實現了RFC2068,咱們但願感謝他們發現了許多這篇文檔正嘗試糾正的問題。19 附錄19.1 互聯網媒體類型message/http和application/http這篇文檔除了定義HTTP/1.1 協議外,同時還被做爲互聯網媒體類型「message/http」和「application/http」的規範。此類型用於封裝一個HTTP請求消息或響應消息,這假設此類型遵循MIME 對 全部「消息」類型關於行長度和編碼的限制。application/http類型能夠用來封裝一個或者更多HTTP請求或響應信息(非混合的)的管線(pipeline)。下列是在IANA[17]註冊的。媒體類型名稱: message媒體子類型名稱: http必須參數: 無可選參數: 版本,信息類型版本:封裝信息的HTTP版本號(例如,"1.1")。若是不存在,版本能夠從消息的第一行肯定。信息類型:信息類型--"請求"或者"響應"。若是不存在,類型能夠從報文的第一行肯定。編碼考慮:只有"7bit","8bit",或者"二進制"是容許的。安全考慮:無媒體類型名稱: application媒體子類型名稱: http必須參數: 無可選參數: 版本,信息類型版本:封裝信息的HTTP版本號(例如,"1.1")。若是不存在,版本能夠從報文的第一行肯定。信息類型:信息類型--"request"或者"response"。若是不存在,類型能夠從報文的第一行肯定。編碼考慮:用這種類型封裝的HTTP信息是"二進制"的格式;當經過E-mail傳遞的時候一種合適的內容傳輸編碼是必須的。安全考慮:無19.2 互聯網媒體類型multipart/byteranges當一個HTTP 206(部份內容)響應信息包含多個範圍的內容(請求響應的內容有多個非重疊的範圍),這些是做爲一個多部分消息主體來被傳送的。這種用途的媒體類型被稱做"multipart/byteranges"。multipart/byteranges 媒體類型包括兩個或者更多的部分,每個都有本身Content-type 和Content-Range頭域。必需的分界參數(boundary parameter)指定分界字符串,此分界字符串用來隔離每一部分。媒體類型名稱: multipart媒體子類型名稱: byteranges必須參數: boundary可選參數: 無編碼考慮:只有"7bit","8bit",或者"二進制"是容許的。安全考慮:無例如:HTTP/1.1 206 Partial ContentDate: Wed, 15 Nov 1995 06:25:24 GMTLast-Modified: Wed, 15 Nov 1995 04:58:08 GMTContent-type:multipart/byteranges;boundary=THIS_STRING_SEPARATES--THIS_STRING_SEPARATESContent-type: application/pdfContent-range: bytes 500-999/8000...第一部分...--THIS_STRING_SEPARATESContent-type: application/pdfContent-range: bytes 7000-7999/8000...第二部分--THIS_STRING_SEPARATES--注意:1)在實體(entity)中,在第一個分界字符串以前能夠有多餘的CRLFs。2)雖然RFC 2046 [40]容許分界字符串加引號,可是一些現有的實現會不正確的處理分界字符串3)許多瀏覽器和服務器是按照字節範圍標準的早期草案關於使用multipart/x-byteranges媒體類型來進行編碼的的,這個草案不老是徹底和HTTP/1.1中描述的版本兼容。19.3 放鬆的應用程序 (Tolerent Applications)雖然這篇文檔列出了HTTP/1.1消息所必須的元素,可是並非全部的應用程序都能正確地實現。所以咱們建議運行程序能夠容忍誤差只要這些誤差能被無歧義的理解。客戶端應該放鬆地解析Status-Line(狀態行);服務器也應該放鬆地解析Request-Line(請求行)。特別的,他們應該能夠接受頭域之間任何數量的SP或HT字符,即便協議規定只有一個SP。消息頭域的行終結符是CRLF。然而,當解析這樣的頭域時,咱們建議應用程序能識別單一LF做爲行終結符並能忽略CR。實體主體(entity-body)的字符集應該被標記爲應用於實體主體字符編碼的最小公分母,而且指望不對實體進行標記要優於對實體標記爲US-ASCII或ISO-8859-1。見3.7.1和3.4.1。對關於日期分析和編碼的要求的額外規則以及其它對日期編碼的潛在問題包含: HTTP/1.1客戶端和緩存應該假定一個彷佛是50多年之後的RFC-850日期其實是過去的(這有助於解決"2000年"問題)。 一個HTTP/1.1的實現能夠內部地表示一個比正確日期值更早的已解析後的Expires日期,可是必定不要(MUST NOT)內部地表示一個比正確日期值更遲的已解析過的Expires日期。 全部過時日期相關的計算必須用GMT時間。本地時區必定不能(MUST NOT)影響年齡或過時時間的計算。 若是一個HTTP頭域不正確的攜帶了一個非GMT時間區的日期值,那麼必須利用最保守的可能轉換把此日期值轉換成GMT時間值。19.4 HTTP實體和RFC 2045實體之間的區別HTTP/1.1 使用了許多Internet Mail ( RFC 822 [9] ) 和Multipurpose Internet MailExtensions(MIME [7])裏定義的結構,去容許實體以多種表現形式和擴展機制去傳輸。然而,RFC2045討論郵件,而且HTTP有許多不一樣於RFC2045裏描述的特徵。這些不一樣被當心地挑選出來優化二進制鏈接的性能,爲了容許使用新的媒體類型有更大的靈活性,爲了使時間比較變得容易,和爲了認可一些早期HTTP服務器和客戶端的實效。本附錄描述了HTTP協議不一樣於RFC 2045的特殊區域。在嚴格的MIME環境中的代理和網關應該意識到這些不一樣而且在必要的時候要提供合適地轉換。從MIME環境到HTTP的代理和網關也須要意識到這些不一樣由於一些轉換多是須要的。19.4.1 MIME版本(MIME-Version)HTTP不是一個遵照MIME的協議。然而HTTP/1.1消息能夠包含一個單獨的MIME-Version經常使用頭域用來指出什麼樣的MIME協議版本被用於去構造消息。利用MIME-Version頭域指明徹底遵循MIME協議的消息(在RFC2045[7])。代理/網關要保證徹底遵照MIME協議當把HTTP消息輸出到嚴格MIME環境的時候。MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT在HTTP/1.1用的缺省值是MIME1.0版本。然而,HTTP/1.1消息的解析和語義是由本文檔而不是MIME規範定義的。19.4.2 轉換到規範化形式 (Conversion to Canoical Form)RFC 2045 [7]要求一互聯網郵件實體在被傳輸以前要被轉換成一個規範化的形式,這在RFC2049[48]裏第四章裏描述的。本文檔的3.7.1節描述了當用HTTP協議傳輸時容許使用的「text」子媒體類型的形式。RFC2046要求類型爲「text」的內容要用CRLF表示爲換行符,以及在換行符外禁止使用CR或LF。RFC 2046須要像在「text」類型的內容裏同樣,用CRLF表示行間隔符並禁止在行間隔符序列之外使用CR或者LF。HTTP容許CRLF,單個CR,和單個LF來表示一個換行符在一個文本內容消息中。在可能的地方,從HTTP到MIME嚴格環境的代理或網關應該把RFC2049裏描述的text媒體類型裏全部換行符轉換成RFC2049 裏CRLF 的規範形式。然而,注意這可能在Content-Encoding出現的時候,以及HTTP容許利用一些沒有利用13和10表明CR和LF的字符集時候都會變得複雜。實現者應該注意轉換將會破壞任何應用於源內容(original content)的密碼校驗和,除非源內容已是規範化形式。所以,對任何在HTTP中使用校驗和的內容被建議要表示爲規範化形式。19.4.3 日期格式的轉換 (Conversion of Date Formate)爲了簡化日期比較的過程,HTTP/1.1使用了一個限制的日期格式(3.3.1節)。其它協議的代理和網關應該保證任何消息裏出現的Date頭域應該遵循HTTP/1.1規定的格式,若是有必要須要重寫此日期。19.4.4 Content-Encoding頭域介紹 (Introduction of Content-Encoding)RFC 2045不包含任何等價於HTTP/1.1裏Content-Encoding頭域的概念。由於這個頭域做爲媒體類型(media type)的修飾,從HTTP協議到MIME遵照協議的代理和網關在轉發消息以前必須既能改變Content-Type頭域的值,也能解碼實體主體(entity-body).。(一些爲互聯網郵件類型的Content-Type 的實驗性應用有使用一個媒體類型參數「; conversions=」去執行等價於Content-Encoding的功能。然而,此參數並非RFC2045的部分)19.4.5 沒有Content-Transfer-Encoding頭域HTTP不使用RFC 2045裏的Content-Transfer-Encoding(CTE)頭域。從使用MIME協議到HTTP 的代理和網關在把響應消息發送給HTTP 客戶端以前必須刪除任何非等價(nonidentity, 譯註: identity 編碼, 表示沒有進行任何編碼) CTE ( "quotedprintable"或"base64")編碼。從HTTP到MIME協議遵循的代理和網關要確保消息在那個協議安全傳輸上是用正確的格式和正確的編碼,「安全傳輸」是經過使用的協議的限制而被定義的。這樣一個代理或網關應該用合適的Content-Transfer-Encoding頭域來標記數據若是這樣作將提升安全傳輸的可能性。19.4.6 Transfer-Encoding頭域的介紹HTTP/1.1介紹了Transfer-Encoding頭域(14.41節)。代理/網關在轉發經由MIME協議的消息以前必須移除任何傳輸編碼。一個解碼"chunked"傳輸代碼(3.6節)的程序能夠用代碼表示以下:length := 0read chunk-size, chunk-extension (if any) and CRLFwhile (chunk-size > 0) {read chunk-data and CRLFappend chunk-data to entity-bodylength := length + chunk-sizeread chunk-size and CRLF}read entity-headerwhile (entity-header not empty) {append entity-header to existing header fieldsread entity-header}Content-Length := lengthRemove "chunked" from Transfer-Encoding19.4.7 MHTML和行長度限制和MHTML實現共享代碼的HTTP實現須要瞭解MIME行長度限制。由於HTTP沒有這個限制,HTTP並不摺疊長行。用HTTP傳輸的MHTML消息遵照全部MHTML的規定,包括行長度的限制和摺疊,規範化等,由於HTTP傳輸全部消息主體(見3.7.2)而且不解析消息的內容和消息中包含任何MIME頭域。19.5 其它特徵RFC 1945和RFC 2068裏一些協議元素被一些已經存在的HTTP實現使用,可是這些協議元素對於大多數HTTP/1.1應用程序既不兼容也不正確。實現者被建議去了解這些特徵,可是不能依賴於它們的出現或不依賴於與其它HTTP/1.1應用程序的互操做性。這些特徵中的一些特徵描述了實驗性的特徵,以及還有一些特徵描述了沒有在基本HTTP/1.1規範裏被描述的實驗性部署特徵。一些其它頭域,如Content-Dispositon和Title頭域,他們來自於SMTP和MIME協議,他們一樣常常被實現(見2076[37]).19.5.1 Content-DispositionContent-Disposition響應頭域被建議做爲一個這樣的用途,那就是若是用戶請求要使內容被保存爲一個文件,那麼此頭域被源服務器使用去建議的一個缺省的文件名。此用途來自於RFC1806[35]關於對Content-Disposition的定義。content-disposition = "Content-Disposition" ":"disposition-type *( ";" disposition-parm )disposition-type = "attachment" | disp-extension-tokendisposition-parm = filename-parm | disp-extension-parmfilename-parm = "filename" "=" quoted-stringdisp-extension-token = tokendisp-extension-parm = token "=" ( token | quoted-string )一個例子是:Content-Disposition: attachment; filename="fname.ext"接收用戶的代理不該該(SHOULD NOT)關注任何在filename-parm參數中出現的文件路徑信息,這個參數被認爲在此次僅僅是應用於HTTP實現。文件名應該(SHOULD)只被看成一個終端組件。若是此頭域用於一個Content-Type爲application/octet-stream響應裏,那麼含義就是用戶代理不該該展示響應,可是它應該直接進入一個‘保存響應爲…’對話框。見15.5節關於Content-Disposition的的安全問題。19.6 和之前版本的兼容要求和之前的版本的兼容超出了協議規範的範圍。然而HTTP/1.1有意設計成很容易支持之前的版本。必須值得注意的是,在寫這份規範的時候,咱們但願商業的HTTP/1.1服務器去:--接受HTTP/0.9,1.0和1.1請求的請求行(Request-Line)格式;--理解HTTP/0.9,1.0或1.1格式中的任何有效請求;--恰當地用客戶端使用的主要版原本響應。而且咱們但願HTTP/1.1的客戶端:--接受HTTP/1.0和1.1響應的狀態行(Status-Line)格式;--懂得HTTP/0.9,1.0或1.1的格式的任何有效的響應。對大多數HTTP/1.0的實現,每個鏈接要在請求以前被客戶端創建,而且在發送響應以後要被服務器關閉。一些實現了在RFC 2068 [33]的19.7.1節描述的持久鏈接的Keep-Alive版本。19.6.1 對HTTP/1.0的改變這一部分總結HTTP/1.0和HTTP/1.1之間主要的區別。19.6.1.1 對多主機web服務器和保留IP地址簡化的改變客戶端和服務器都支持Host請求頭域,而且若是Host請求頭域在HTTP/1.1請求裏沒有出現必須報告一錯誤,而且服務器能接受一個絕對URIs(5.1.2節),這些要求是此規範裏最重要的改變。舊的HTTP/1.0客戶端會認爲IP地址和服務器是一對一關係;沒有其它機制去區分IP地址和目標服務器。上面的改變將容許互聯網,一旦舊客戶端再也不廣泛使用時,能夠去支持一個IP地址對應多個web站點的狀況,這大大簡化了大型的web運行服務器,在那上面上分配多個IP地址給一個主機(host)會產生嚴重問題。互聯網照樣能恢復這樣一個IP地址,此IP地址做爲特殊目的被分配給被用於根級(root-level)HTTP URLs的域名。給定web的增加速度和服務器的部署數量,那麼全部HTTP實現(包括對已存HTTP/1.0應用程序)應該正確地知足下面這些需求:--客戶端和服務器都必須支持Host請求頭域。--發送HTTP/1.1請求的客戶端必須發送Host頭域。--若是HTTP/1.1請求不包括Host請求頭域,服務器必須報告錯誤400(Bad Request)。--服務器必須接受絕對URIs(absolute URIs)。19.6.2 和HTTP/1.0持久鏈接的兼容一些客戶端和服務器可能但願和一些之前持久鏈接實現的HTTP/1.0客戶端和服務器保持兼容。HTTP/1.0持久鏈接須要顯式地協商,由於持久鏈接不是HTTP/1.0的缺省行爲。關於持久鏈接的HTTP/1.0實驗性實現存在缺陷,而且HTTP/1.1裏的新的功能被設計成去矯正這些問題。這個缺陷是:一些已經存在的1.0客戶端可能會發送Keep-Alive頭域給不理解持久鏈接的代理,而後代理會把此Keep-Alive轉發給下一個內向(inbound)服務器。結果是HTTP/1.0客戶端必須禁止利用Keep-Alive,當和代理會話的時候。然而,和代理進行會話最重要是利用持久鏈接,因此那個禁止很顯然不能被接受。所以,咱們須要一些其它的機制去指明須要一個持久鏈接,而且它必須能安全地被使用甚至是當和忽略持久鏈接的舊代理會話。持久鏈接缺省是爲HTTP/1.1消息的;爲了聲明非持久鏈接(見14.10節),咱們介紹一個新的關鍵字(Connection:close)。持久鏈接的源HTTP/1.0的形式(Connection: Keep-Alive 和 Keep-Alive 頭域)在RFC2068裏說明19.6.3 對RFC 2068的改變這篇規範已經被仔細的審查來糾正關鍵字的用法和消除它們的歧義;RFC 2068在遵照RFC2119 [34] 制定的協定方面有不少問題。澄清哪一個錯誤代碼將會使入流服務器失靈(例如DNS失靈)。(10.5.5節)CREATE有一個特色當一個資源第一次被建立的時候必須須要一個Etag。(10.2.2節)Content-Base頭域今後規範裏刪除了:它沒法普遍的實現,而且在沒有健壯的擴展機制的狀況下,沒有簡單的,安全的方式去介紹它。而且,它以一種類似的而不是相同的方式在MHTML[45]裏被使用。略…..20 索引 (Index)21 所有版權聲明略…..web