HTTP1.1協議的chunked編碼(chunked transfer encoding分塊傳輸編碼)
一般情況HTTP的Header包含Content-Length域來指明報文體的長度。
有時候服務生成HTTP迴應是無法確定訊息大小的,比如大檔案的下載,或者後臺需要複雜的邏輯才能全部處理頁面的請求,這時用需要實時生成訊息長度,伺服器一般使用chunked編碼。採用chunked編碼有兩種選擇,一種是設定Server的IO buffer長度讓Server自動flush buffer中的內容,另一種是手動呼叫IO中的flush函式。不同的語言IO中都有flush功能:
- php: ob_flush(); flush();
- perl: STDOUT->autoflush(1);
- java: out.flush();
- python: sys.stdout.flush()
- ruby: stdout.flush
使用chunked編碼的Headers如下(可以利用FireFox的FireBug外掛或HttpWatch檢視Headers資訊,HttpWatch還可以檢視chunked的個數):
Chunked編碼一般使用若干個chunk串連而成,最後由一個標明長度為0的chunk標示結束。每個chunk分為頭部和正文兩部分,頭部內容指定下一段正文的字元總數(非零開頭的十六進位制的數字)和數量單位(一般不寫,表示位元組).正文部分就是指定長度的實際內容,兩部分之間用回車換行(CRLF)隔開。在最後一個長度為0的chunk中的內容是稱為footer的內容,是一些附加的Header資訊(通常可以直接忽略)。
上述解釋過於官方,簡而言之,chunked編碼的基本方法是將大塊資料分解成多塊小資料,每塊都可以自指定長度,其具體格式如下(BNF文法):
<pre name="code" class="java">Chunked-Body = *chunk //0至多個chunk <span style="white-space:pre"> </span>last-chunk //最後一個chunk <span style="white-space:pre"> </span>trailer //尾部 <span style="white-space:pre"> </span>CRLF //結束標記符 chunk = chunk-size [ chunk-extension ] CRLF <span style="white-space:pre"> </span>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)
解釋:
Chunked-Body表示經過chunked編碼後的報文體。報文體可以分為chunk, last-chunk,trailer和結束符四部分。chunk的數量在報文體中最少可以為0,無上限;
每個chunk的長度是自指定的,即,起始的資料必然是16進位制數字的字串,代表後面chunk-data的長度(位元組數)。這個16進位制的字串第一個字元如果是“0”,則表示chunk-size為0,該chunk為last-chunk,無chunk-data部分。
可選的chunk-extension由通訊雙方自行確定,如果接收者不理解它的意義,可以忽略。
trailer是附加的在尾部的額外頭域,通常包含一些元資料(metadata, meta means "about information"),這些頭域可以在解碼後附加在現有頭域之後
看一個wireshark抓包的結果:
這裡面只有一個有意義的chunke以及一個footer。第一個chunk,頭部是3134這兩個位元組,表示的是1和4這兩個ascii字元,被http協議解釋為十六進位制數14,也就是十進位制的20。後面緊跟0d0a,再接著是20個位元組的chunk正文(圖中的011e~0131)。
後面再接著0d0a,然後就是footer了,30表示ascii字元0,http解釋為長度是0(也說明了這是最後一個chunk),後面緊跟0d0a,然後正文部分為空,再接0d 0a表示結束
轉載文章:
1)http://blog.csdn.net/zhangboyj/article/details/6236780
2)http://www.cnblogs.com/jhxk/articles/2715848.html
3)http://www.cnblogs.com/jhxk/articles/2715848.html