HTTP協議<5>

          Posted on 2005-09-23 11:51 英雄 閱讀(1374) 評論(0)  編輯  收藏 所屬分類: HTTP1.1協議中文翻譯

          5 請求

          一個從clientserverrequest,在第一行,包含應用于資源的方法,資源標志,和使用的協議版本。

          Request = Request-Line ; Section 5.1

          *(( general-header ; Section 4.5

          | request-header ; Section 5.3

          | entity-header ) CRLF) ; Section 7.1

          CRLF

          [ message-body ] ; Section 4.3

          51請求行

          以一個方法標記開始,跟著URI,和版本協議,以CRLF結束。SP分隔。除了在最后的CRLF不能有CRLF

          Request-Line = Method SP Request-URI SP HTTP-Version CRLF

          5.1.1方法

          方法標記表示將會用在請求資源上的方法,是大小寫敏感的。

          Method = "OPTIONS" ; Section 9.2

          | "GET" ; Section 9.3

          | "HEAD" ; Section 9.4

          | "POST" ; Section 9.5

          | "PUT" ; Section 9.6

          | "DELETE" ; Section 9.7

          | "TRACE" ; Section 9.8

          | "CONNECT" ; Section 9.9

          | extension-method

          extension-method = token

          一個資源可以允許的方法列表可以在ALLOW頭區給出。Response的返回代碼總是告訴client一個方法可否應用到一個資源,因為總是在變。一個server應該返回405如果方法可以識別但不能用于請求資源,返回501如果方法不可識別或沒有被origin server實現。方法gethead必須被所有的通用目的的server實現。所有其他方法是可選的;但是,如果上面的方法被實現,他們必須具備sec9定義的語義。

          512URI

          是一個統一資源標記(3。2)標記了request請求的資源。

          Request-URI = "*" | absoluteURI | abs_path | authority

          4個選項取決于request的性質。星號意思是request并不指定某一特定資源,而是server本身,只在方法并不一定針對資源時。一個例子:

          OPTIONS * HTTP/1.1

          如果請求是發給一個代理,absoluteURI形式是必須的。代理被請求來傳遞request或從一個有效緩存中服務,返回response。注意代理可以傳遞這個request給另外一個代理或直接給被absoluteURI指定的server。為了避免request循環,一個代理必須能夠識別所有它的server名,包括別名,局部變量,和IP地址。里:

          GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1

          為了允許傳遞所有的未來的HTTP版本中的request,所有的HTTP/1。1server必須接收requestabsoluteURI,即使HTTP/11client只產生他們用來代理。

          Authority形式只被CONNECT方法使用。(sec9.9)

          最通用的URI形式是用來標記在一個origin servergateway上的資源。在這種情況下,URI的絕對路徑(abs_path)必須作為URI被傳遞,而且URI的網絡路徑(authority)也必須被作為一個Host頭區被傳遞。例如,一個希望直接從origin server得到上面指定資源的request會創建一個到“www.w3.org80端口的TCP連接并且發送這一行:

          GET /pub/WWW/TheProject.html HTTP/1.1

          Host: www.w3.org

          跟著的是request的其他剩余部分。注意絕對路徑不能是空的;如果確實沒有,必須作為“/”給出。

          URISEC3。2。1給出的格式傳送。如果URI使用”%HEX HEX”編碼[42]的形式編碼,origin server必須解碼URI一合適的解釋requestServer應該對無效的URI給出合適的狀態碼返回。

          一個transparent proxy當把request傳遞給內部server時絕對不能重寫接收到的URI的“abs_path”部分,除非把null abs_path用“/”替換。

          注意:“no rewrite”阻止了proxy改變request的原本意義,當origin server使用非保留URI字符對應保留目的時。實現者應該意識到一些HTTP/1。1proxy可能重寫uri

          52 Request標記的資源

          被一個request請求的資源由urihost頭區精確確定。

          當決定一個HTTP/1/1request請求的資源時,一個origin server如果不允許使用host來區別資源,那么可以忽略host頭區。(sec19.6.1

          而一個確實使用host(又叫虛擬主機)區分資源的origin server使用下面原則處理HTTP/11request請求的資源:

           

            1.如果URIabsoluteURI,那么主機名是其中一部分,任何其他主機名頭區被忽略。

            2.如果URI不是,并且包含HOST頭區,那么host被頭區決定。

            3400反饋12無效的。

          HTTP/1。0是沒有HOST頭區的,可以使用直觀推測方法來決定請求的精確資源。

          53請求頭區

          頭區允許client傳遞額外的關于requestclient的自身信息給server。這些區就算request的描述符,就象程序語言的參數一樣。

          request-header = Accept ; Section 14.1

          | Accept-Charset ; Section 14.2

          | Accept-Encoding ; Section 14.3

          | Accept-Language ; Section 14.4

          | Authorization ; Section 14.8

          | Expect ; Section 14.20

          | From ; Section 14.22

          | Host ; Section 14.23

          | If-Match ; Section 14.24

          | If-Modified-Since ; Section 14.25

          | If-None-Match ; Section 14.26

          | If-Range ; Section 14.27

          | If-Unmodified-Since ; Section 14.28

          | Max-Forwards ; Section 14.31

          | Proxy-Authorization ; Section 14.34

          | Range ; Section 14.35

          | Referer ; Section 14.36

          | TE ; Section 14.39

          | User-Agent ; Section 14.43

          s頭區的名字可以跟隨一個改變的版本號而被擴展。但是,新的或實驗的頭區可以被給通用頭區的語義如果通訊雙方都認同。認不出的頭區被認為是實體頭區。

          6 Response

          當接收和解析一個request message后,一個server用一個HTTPresponse messge返回。

          Response = Status-Line ; Section 6.1

          *(( general-header ; Section 4.5

          | response-header ; Section 6.2

          | entity-header ) CRLF) ; Section 7.1

          CRLF

          [ message-body ] ; Section 7.2

          61狀態行

          一個response message的第一行是狀態行,由協議版本,跟狀態碼,跟對應文本段,每一個用SP分隔。沒有CRLF被允許除了最后的CRLF

          Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

          611狀態碼和原因段

          狀態碼是一個3數字位結果編碼,去理解和滿足請求。Sec10完全定義。原因段是給一個簡短的文本描述給status-code。狀態碼是自動使用而原因段是人工使用。Client并不需要去檢查和表示原因段。

          第一位定義了response的分類。后2位沒有分類的意思。第一位有5個值。

          · 1xx: request收到,繼續處理

          · 2xx: action被成功接收,理解,接受

          · 3xx:還有其他action要做

          · 4xx: request有問題

          · 5xx: server有問題不能解決有效request的請求。

          下面是定義的值和推薦原因段,當然可以自己定義。

          Status-Code =

          "100" ; Section 10.1.1: Continue

          | "101" ; Section 10.1.2: Switching Protocols

          | "200" ; Section 10.2.1: OK

          | "201" ; Section 10.2.2: Created

          | "202" ; Section 10.2.3: Accepted

          | "203" ; Section 10.2.4: Non-Authoritative Information

          | "204" ; Section 10.2.5: No Content

          | "205" ; Section 10.2.6: Reset Content

          | "206" ; Section 10.2.7: Partial Content

          | "300" ; Section 10.3.1: Multiple Choices

          | "301" ; Section 10.3.2: Moved Permanently

          | "302" ; Section 10.3.3: Found

          | "303" ; Section 10.3.4: See Other

          | "304" ; Section 10.3.5: Not Modified

          | "305" ; Section 10.3.6: Use Proxy

          | "307" ; Section 10.3.8: Temporary Redirect

          | "400" ; Section 10.4.1: Bad Request

          | "401" ; Section 10.4.2: Unauthorized

          | "402" ; Section 10.4.3: Payment Required

          | "403" ; Section 10.4.4: Forbidden

          | "404" ; Section 10.4.5: Not Found

          | "405" ; Section 10.4.6: Method Not Allowed

          | "406" ; Section 10.4.7: Not Acceptable

          | "407" ; Section 10.4.8: Proxy Authentication Required

          | "408" ; Section 10.4.9: Request Time-out

          | "409" ; Section 10.4.10: Conflict

          | "410" ; Section 10.4.11: Gone

          | "411" ; Section 10.4.12: Length Required

          | "412" ; Section 10.4.13: Precondition Failed

          | "413" ; Section 10.4.14: Request Entity Too Large

          | "414" ; Section 10.4.15: Request-URI Too Large

          | "415" ; Section 10.4.16: Unsupported Media Type

          | "416" ; Section 10.4.17: Requested range not satisfiable

          | "417" ; Section 10.4.18: Expectation Failed

          | "500" ; Section 10.5.1: Internal Server Error

          | "501" ; Section 10.5.2: Not Implemented

          | "502" ; Section 10.5.3: Bad Gateway

          | "503" ; Section 10.5.4: Service Unavailable

          | "504" ; Section 10.5.5: Gateway Time-out

          | "505" ; Section 10.5.6: HTTP Version not supported

          | extension-code

          extension-code = 3DIGIT

          Reason-Phrase = *<TEXT, excluding CR, LF>

          HTTP狀態碼是可擴展的。HTTP應用并沒有被要求去理解他們但很明顯是需要的。但是,應用必須理解代碼的分類,也就是第一位,并且對任何不認識的response等同于對應類別的x00,但是不緩存它。例如,如果一個431client接收到但不識別,它可以認為它的request本身并沒有錯,并且把response作為400處理。在這種情況下,user agent應該給user展現response返回的整個entity,因為entity可能包含人可以識別的信息來解釋不尋常的狀態。

          62 Response 頭區

          用來讓server放在status-line中不能放的關于response的額外信息。這些頭區給出了server的信息和更深入的關于REQUEST-URI指定的資源進入。

          response-header = Accept-Ranges ; Section 14.5

          | Age ; Section 14.6

          | ETag ; Section 14.19

          | Location ; Section 14.30

          | Proxy-Authenticate ; Section 14.33

          | Retry-After ; Section 14.37

          | Server ; Section 14.38

          | Vary ; Section 14.44

          | WWW-Authenticate ; Section 14.47

          s頭區的名字可以跟隨一個改變的版本號而被擴展。但是,新的或實驗的頭區可以被給通用頭區的語義如果通訊雙方都認同。認不出的頭區被認為是實體頭區。

          7  Entity

          requestresponse可以傳遞一個實體如果request方法和response狀態碼未加限制的話。一個entity由頭區和體組成,雖然一些response只包含頭區。

          在這個段中,發送者和接收者可以是clientserver,看誰發送和接收實體。

          71實體頭區

          定義了實體的描述數據,如果沒有實體,那就是request指定資源的描述數據。一些是可選的,一些是必須的。

          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-header

          extension-header = message-header

          擴展頭區機制允許額外的頭區定義而不用改變協議,但是這些區并不能假定會被接收者識別出。沒有識別的要被接收者忽略而且必須被透明proxy傳遞。

          7.2 Entity Body

          它是以實體頭區定義的形式和編碼形成的伴隨requestresponse發送的。

          entity-body = *OCTET

          一個Entity Body只存在于一個存在消息體的消息中,(sec4.3)。通過解碼傳輸編碼從message-body中得到entity-body。

          721類別

          當一個entity-body被一個消息包含時,通過頭區Content-TypeContent-Encoding決定類型。這些定義了一個兩層的 有序的編碼模型。

          entity-body := Content-Encoding( Content-Type( data ) )

          Content-Type聲明了數據的類型。Content-Encoding用來給出額外的內容編碼,通常是用來數據壓縮的,是被request資源的屬性。沒有默認的編碼。

          任何包含一個實體的HTTP/1。1消息應該包含一個Content-Type頭區來定義那個體的media type。如果media type沒有在一個content-type區被給出,接收著可以通過內容或uri的名字擴展來猜。如果還是未知,那就應該作為application/octetstream

          722 實體長度

          即使消息體被任何傳輸編碼應用前的長度。Sec4.4定義了怎么確定一個消息體的傳輸長度。

          8 連接

          81持久連接

          811目的

          持久連接之前,一個單獨的TCP連接需要每次取得URL來建立,增大了HTTP server的負載并且引起internet的擁擠。使用聯機圖片和其他相關數據資源通常要求一個client在極短時間向相同的server發送多個request。關于這些性能問題的分析和對一個實驗性實現的結果是可用的[26][30]。實現經驗和實際的HTTP/1。1RFC2068)的測量顯示了很好的結果。也產生了可選的代替,例如,T/TCP[27]。

          持久的HTTP連接有很多優點:

          l         打開和關閉更少的TCP連接,節省了通訊鏈路上路由器和主機(clients,servers,proxies,gateways,tunnels,caches)上的CPU消耗,也節省了主機上對TCP控制塊的內存消耗

          l         HTTP連接和請求可以在一次連接上pipeline。這允許一個client發送多個request而不用等response,允許單個TCP連接被更有效地使用而節省了大量時間。

          l         網絡擁塞被降低了,因為減少了TCP打開的PACKETS,和允許TCP有更多的時間決定網絡擁擠狀態

          l         等待下一個request時間被降低了,應為可以花費更少的時間在TCP握手上

          l         HTTP可以更好地發展,因為錯誤在不關閉TCP連接的情況下被報告。HTTP的未來版本的client可以樂觀地使用一個新特征,但是要和一個舊server通訊就要在錯誤被報告時嘗試舊語義。

          HTTP應用應該實現持久連接。

          812整體流程

          HTTP/11和其他早期HTTP的重要區別就是持久化連接是所有HTTP連接的默認連接。也就是,除非有另外指明,client應該假定server保持一個持久連接,即使server發送一個error。

          持久化連接提供了一個機制,通過它一個client和一個server能夠表示tcp連接的關閉,就是使用connection 頭區。一旦一個close被標記,client不能在connection上發送任何request。

          8121 Negotiation

          一個HTTP/1。1server可以假定一個HTTP/1。1client想要保持一個持久化連接直到一個connection區被指定為“close”,并且被以request發送。如果server想在response之后關閉連接,它應該這樣指明。

          一個HTTP/11client可以期待連接保持,但是通過responseconnection頭區來決定是否保持;而如果不想連接保持,就應該發一個closeconnection頭區。

          如果clientserver有一個發了,那么request是連接的最后一個。

          Clientserver不應該假定低于HTTP1。1的版本會維持一個持久化連接。Sec19.6.2提供更多兼容信息。

          為了保持持久,所有在連接中的消息必須有一個自定義的消息長度,sec4.4。

          8122流水線

          一個支持持久化連接的client可以流水它的request(也就是說,發送多個request而不必等待response)。一個server必須發送它的response給那些requestrequest應該接收到的順序。

          Client在連接建立后馬上假定持久化連接和流水線存在的如果第一次流水線試圖失敗要準備重新建立連接。如果一個client做這樣的重試,它在知道連接是持久化之前絕對不能pipeline。如果server在發送所有對應response之前關閉連接,client也必須要準備重發所有的請求。

          Client不應該發送非等冪(或序列)方法的request。否則一個運輸連接的過早終結可能會導致結果的不確定。一個希望發送一個非等冪requestclient應該等到前一個request對應的response到了后再發。

          813代理服務器

          proxy正確實現connection頭區(sec14.10)的屬性是非常重要的。

          Proxy必須分別給它的clientorigin server(或其他proxy server)標記持久化連接。每一個持久化連接對應一個鏈。

          一個proxy絕對不能建立HTTP/1。1持久連接和一個HTTP/10client(RFC2068)

          814實踐考慮

          server通常有一些超時值,超過了這些值就不會維持一個活動連接。Proxy可以設得更高因為可能一個client可能會和它r做更多的連接。這個值本身的大小沒有限制。

          當一個clientserver想要超時,它應該給那個連接發一個優美的中斷。Clientserver都應該經常地觀察傳輸的另一端,合適地給以處理。如果相反的話會導致網絡資源耗盡。

          一個client,serverproxy可以在任何時候關閉傳輸連接。例如,一個client會開始發送一個新的request同時一個server決定關閉這個看似空閑的連接。從server的角度看,連接就要被關閉,從client的角度看,一個request正在被發送。

          這意味著client ,server,proxy必須能夠從異步關閉事件中恢復。Client軟件應該從新打開連接從新發送失敗的request,只要request序列是等冪的(sec9.1.2)就不需要用戶交互。不等冪的方法或序列絕對不能被自動重發,雖然user agent可以提供一個手工操作來選擇重新發送。User-agent軟件的確認回代替用戶的確認。如果第2次請求序列失敗自動重發不應該繼續。

          Server應該總是對一個連接至少發一個response,如果可能的話。Server不應該在發送一個response的過程中關閉一個連接,除非預測到一個網絡連接或client失敗。

          使用持久連接的client應該限制他們維持到同一個server的并行連接數。一個單個的user client不應該對任何serverproxy保持對于2個連接。一個proxy應該使用最多2*N個連接到另一個serverproxy,N是同時活躍的users個數。這些原則被用來提高http response時間并且避免擁塞。

          82消息傳送要求

          821持久連接和流控制

          HTTP/1.1server應該保持持久連接并且使用TCP的流控制機制來解決臨時過載的問題,而不是知道clientretry還終止連接。后者會加重網絡租塞。

          8.2.2 監視連接中的錯誤狀態信息

          一個HTTP/11(或之后的)正在發送消息體的 client當它正在傳遞request時應該監視網絡連接的錯誤狀態。如果client看到一個錯誤狀態,它應該迅速終止消息體的發送。如果正在用“chunked”(sec3.6)編碼發送,一個0長度的chunk和空尾部可以被使用用來標志消息的結束。如果消息體先于一個Content-Length頭部,client必須關閉連接。

          8.2.3使用100status

          100狀態的存在是為了允許一個正在發送帶bodyrequest messageclient來決定是否一個origin server想要接收request(基于request header),這發生在實際發送request body之前。在某些情況下,發送一個不被server看就拒絕的消息體是不合適和浪費效率的。

          HTTP/1。1client的要求:

          。如果一個client愿意在發送一個request body前等待100response,它必須發送一個期待100的頭區。

          。一個client決不能發送一個期待100的頭區如果它不想發request body

          由于更老板本的存在,協議允許一個client發了期待100頭區后沒有受到417,100。因此,一個client發了期待100頭區后就不應該無限等待request。

          HTTP/1。1server的要求:

          l         當接收到一個包含expect 100-continue”頭區的request時,origin server必須要么一100Continue)狀態返回并且繼續從輸入流中讀,要么返回一個終止狀態編碼。Origin server 絕對不能在發送100response之前等待request body。如果它返回一個終止狀態,它可以關閉連接或可以繼續讀但放棄request的剩余部分。它決不能執行request的方法如果它返回一個終止符。

          l         一個origin server不應該發送一個100continueresponse,如果request 消息沒有包含expect 100-continue”頭區,并且也絕對不能發送這樣的response如果request是來自一個HTTP/10(或更早版本的)client。有一個意外:為了和RFC2068兼容,一個server可以發送一個100狀態在response中給一個HTTP/11putpost request,盡管沒有包含expect 100-continue”頭區。這個異常,只適用于HTTP/1。1request,并不適用于其他HTTP版本,目的就是減少client的等待時間。

          l         一個origin server可以可以忽略100如果它已經接收到一些或全部的request body.

          l         一個發送了一個100origin server必須在收完body并且處理后發送一個final status code,除非它過早地終止連接。

          l         如果一個origin server接收到一個未包含Expect 100頭區的request,而又包含一個body,server在從連接讀整個body前回以一個final status,那么server不應該關閉連接直到它讀了整個request或直到client關閉了連接。否則,client不能可靠地接收response。然而,這個要求并不是說保護server免受服務拒絕攻擊或錯誤的client實現。

          HTTP/11proxy的要求:

          。如果一個代理接收到一個包含100期待的頭區的request,代理要么知道要么不知道下一個serverHTTP1。1的兼容,它必須轉發request,包括expect頭區。

          。如果proxy知道下一個server 支持http/1.0或更低,它決不能轉發,而必須發揮417

          。Proxy應該維護一個關于最近接收的下一個serverHTTP版本號的緩存。

          。一個proxy決不能返回100response給一個HTTP/1。0client(不包含100-continue期待)。這個請求覆蓋了轉發1xx response的規則。

          824 clientserver過早關閉連接后的行為

          如果一個HTTP/1。1client發送一個包含bodyrequest,但是沒有包含100頭區期待,而且并不是直接連HTTP/1。1origin server,而且看到了從server過來的連接關閉,應該重試request。如果重試,它可以采用下面的2等冪算法來確保得到可靠連接:

          1.  初始化一個到server的新連接

          2.  發送request-headers

          3.  初始化一個R,來存放到server 的來回是,如果不可得就設置成5s。

          4.  計算T=R*2**N),N是之前嘗試重發的次數。

          5.  等一個錯誤responseTs

          6.  如果沒有接收到error response,Ts后發送requestbody。

          7.  Client看到連接被過早關閉,重復1步直到request被接收,或收到一個錯誤response,或client不耐煩關閉了嘗試進程。

          在任何錯誤狀態被接收的點,client

          l         不應該繼續

          l         應該關閉連接如果還沒有完成發送request message

          主站蜘蛛池模板: 沿河| 天等县| 渝中区| 利川市| 芦溪县| 汽车| 阿尔山市| 盐边县| 麦盖提县| 建德市| 肇庆市| 鹤山市| 兴隆县| 鹿泉市| 碌曲县| 开阳县| 盐源县| 马山县| 东海县| 唐山市| 循化| 东乡县| 呼和浩特市| 鹤山市| 浮山县| 洞口县| 南安市| 师宗县| 象山县| 花垣县| 柯坪县| 寿阳县| 海阳市| 嘉鱼县| 古交市| 辽源市| 枞阳县| 防城港市| 景洪市| 宝鸡市| 轮台县|