1. 程式人生 > >Http Chunked Transfer Coding

Http Chunked Transfer Coding

分塊傳輸編碼 Chunked Transfer Coding

是超文字傳輸協議(HTTP)中的一種資料傳輸機制,允許HTTP由網頁伺服器傳送給客戶端應用( 通常是網頁瀏覽器)的資料可以分成多個部分。分塊傳輸編碼只在HTTP協議1.1版本(HTTP/1.1)中提供。

通常,HTTP應答訊息中傳送的資料是整個傳送的,Content-Length訊息頭欄位表示資料的長度。資料的長度很重要,因為客戶端需要知道哪裡是應答訊息的結束,以及後續應答訊息的開始。然而,使用分塊傳輸編碼,資料分解成一系列資料塊,並以一個或多個塊傳送,這樣伺服器可以傳送資料而不需要預先知道傳送內容的總大小。通常資料塊的大小是一致的,但也不總是這種情況。



原理

HTTP 1.1引入分塊傳輸編碼提供了以下幾點好處:


HTTP分塊傳輸編碼允許伺服器為動態生成的內容維持HTTP持久連結。通常,持久連結需要伺服器在開始傳送訊息體前傳送Content-Length訊息頭欄位,但是對於動態生成的內容來說,在內容建立完之前是不可知的。[1]
分塊傳輸編碼允許伺服器在最後傳送訊息頭欄位。對於那些頭欄位值在內容被生成之前無法知道的情形非常重要,例如訊息的內容要使用雜湊進行簽名,雜湊的結果通過HTTP訊息頭欄位進行傳輸。沒有分塊傳輸編碼時,伺服器必須緩衝內容直到完成後計算頭欄位的值並在傳送內容前傳送這些頭欄位的值。

HTTP伺服器有時使用壓縮 (gzip或deflate)以縮短傳輸花費的時間。分塊傳輸編碼可以用來分隔壓縮物件的多個部分。在這種情況下,塊不是分別壓縮的,而是整個負載進行壓縮,壓縮的輸出使用本文描述的方案進行分塊傳輸。在壓縮的情形中,分塊編碼有利於一邊進行壓縮一邊傳送資料,而不是先完成壓縮過程以得知壓縮後資料的大小。

格式

如果一個HTTP訊息(請求訊息或應答訊息)的Transfer-Encoding訊息頭的值為chunked,那麼,訊息體由數量未定的塊組成,並以最後一個大小為0的塊為結束。

每一個非空的塊都以該塊包含資料的位元組數(位元組數以十六進位制表示)開始,跟隨一個CRLF (回車及換行),然後是資料本身,最後塊CRLF結束。在一些實現中,塊大小和CRLF之間填充有白空格(0x20)。

最後一塊是單行,由塊大小(0),一些可選的填充白空格,以及CRLF。最後一塊不再包含任何資料,但是可以傳送可選的尾部,包括訊息頭欄位。

訊息最後以CRLF結尾。

例子

編碼的應答

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

25
This is the data in the first chunk

1C
and this is the second one

3
con

8
sequence

0

編碼應答的解釋

前兩個塊的資料中包含有顯式的\r\n字元。

"This is the data in the first chunk\r\n"      (37 字元 => 十六進位制: 0x25)
"and this is the second one\r\n"               (28 字元 => 十六進位制: 0x1C)
"con"                                          (3  字元 => 十六進位制: 0x03)
"sequence"                                     (8  字元 => 十六進位制: 0x08)

應答需要以0長度的塊( "0\r\n\r\n".)結束。

解碼的資料

This is the data in the first chunk
and this is the second one
consequence

下面是RFC中的說明:

附加解釋:1、中括號表示可有可無的;2、星號是正則表示式的用法,表示任意多個;3、CRLF表示回車換行,英文為:Carriage-Return Line-Feed;

4、 chunk-ext-name = token  chunk-ext-val  = token | quoted-string,可以和hashMap中的key和value類比; 5、trailer        = *(entity-header CRLF)中的entity-header,指的是response的頭資訊,也是key-value形式的,比如Content-type:text/html 。

Chunked Transfer Coding


   The chunked encoding modifies the body of a message in order to
   transfer it as a series of chunks, each with its own size indicator,
   followed by an OPTIONAL trailer containing entity-header fields. This
   allows dynamically produced content to be transferred along with the
   information necessary for the recipient to verify that it has
   received the full message.


       Chunked-Body   = *chunk
                        last-chunk
                        trailer
                        CRLF
       chunk          = chunk-size [ chunk-extension ] CRLF
                        chunk-data CRLF
       chunk-size     = 1*HEX
       last-chunk     = 1*("0") [ chunk-extension ] CRLF
       chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
       chunk-ext-name = token
       chunk-ext-val  = token | quoted-string
       chunk-data     = chunk-size(OCTET)
       trailer        = *(entity-header CRLF)

   The chunk-size field is a string of hex digits indicating the size of
   the chunk. The chunked encoding is ended by any chunk whose size is
   zero, followed by the trailer, which is terminated by an empty line.

   The trailer allows the sender to include additional HTTP header
   fields at the end of the message. The Trailer header field can be
   used to indicate which header fields are included in a trailer

下面是chunked中的trailer中的解釋:


1、RFC中的解釋:

Trailer

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.40
The Trailer general field value indicates that the given set of header fields is present in the trailer of a message encoded with chunked transfer-coding.

       Trailer  = "Trailer" ":" 1#field-name
An HTTP/1.1 message SHOULD include a Trailer header field in a message using chunked transfer-coding with a non-empty trailer. Doing so allows the recipient to know which header fields to expect in the trailer.
If no Trailer header field is present, the trailer SHOULD NOT include any header fields. See section 3.6.1 for restrictions on the use of trailer fields in a "chunked" transfer-coding.
Message header fields listed in the Trailer header field MUST NOT include the following header fields:
      . Transfer-Encoding
      . Content-Length
      . Trailer


2、通俗的解釋:

Trailer:
lists the headers that will be transmitted after the message body, in a trailer block. This allows servers to compute some values, like Content-MD5: while transmitting the data. 

大意是:在響應(response)訊息的尾部列舉將要傳送的頭資訊。在傳輸訊息的時候這個允許伺服器計算一些值,比如MD5加密的內容。

Message header fields listed in the Trailer header field MUST NOT include the following header fields:
      . Transfer-Encoding
      . Content-Length
      . Trailer

Trailer中的header-entity不能包含.Transfer-Encoding、Content-Length、Trailer這三個header