Http響應chunked格式分析

來源:互聯網
上載者:User

有的時候伺服器產生HTTP回應是無法確定資訊大小的,這時用Content-Length就無法事先寫入長度,而需要即時產生訊息長度,這時伺服器一般採用Chunked編碼。

在進行Chunked編碼傳輸時,在回複訊息的頭部有transfer-coding並定義為Chunked,表示將用Chunked編碼傳輸內容。

 

Chunked編碼使用若干個Chunk串聯而成,由一個標明長度為0的chunk標示結束。每個Chunk分為頭部和本文兩部分,頭部內容指定下一段本文的字元總數(十六進位的數字)和數量單位(一般不寫),本文部分就是指定長度的實際內容,兩部分之間用斷行符號換行(CRLF)隔開。在最後一個長度為0的Chunk中的內容是稱為footer的內容,是一些附加的Header資訊(通常可以直接忽略)。

 

我們來類比一下資料結構:
[Chunk大小][斷行符號][Chunk資料體][斷行符號][Chunk大小][斷行符號][Chunk資料體][斷行符號][0][斷行符號][footer內容(有的話)][斷行符號]

注意chunk-size是以十六進位的ASCII碼錶示的,比如86AE(實際的十六進位應該是:38366165),計算成長度應該是:34478,表示從斷行符號之後有連續的34478位元組的資料。
跟蹤了www.yahoo.com的返回資料,發現在chunk-size中,還會多一些空格。可能是固定長度為7個位元組,不滿7個位元組的,就以空格補足,空格的ASCII碼是0x20。

 

    解碼流程:
    對chunked編碼進行解碼的目的是將分塊的chunk-data整合恢複成一塊作為報文體,同時記錄此塊體的長度。
    RFC2616中附帶的解碼流程如下:(虛擬碼)
    length := 0         //長度計數器置0
    read chunk-size, chunk-extension (if any) and CRLF      //讀取chunk-size, chunk-extension
                                                          //和CRLF
    while(chunk-size > 0 )   {            //表明不是last-chunk
          read chunk-data and CRLF            //讀chunk-size大小的chunk-data,skip CRLF
          append chunk-data to entity-body     //將此塊chunk-data追加到entity-body後
          read chunk-size and CRLF          //讀取新chunk的chunk-size 和 CRLF
    }
    read entity-header      //entity-header的格式為name:valueCRLF,如果為空白即只有CRLF
    while (entity-header not empty)   //即,不是只有CRLF的空行
    {
       append entity-header to existing header fields
       read entity-header
    }
    Content-Length:=length      //將整個解碼流程結束後計算得到的新報文體length
                                 //作為Content-Length域的值寫入報文中
    Remove "chunked" from Transfer-Encoding  //同時從Transfer-Encoding中域值去除chunked這個標記

 

SampleEncoded response
HTTP/1.1 200 OKContent-Type: text/plainTransfer-Encoding: chunked25This is the data in the first chunk1Aand this is the second one0
same as above, raw bytes in hex
0000-000F   48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d   HTTP/1.1 200 OK.0010-001F   0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74   .Content-Type: t0020-002F   65 78 74 2f 70 6c 61 69 6e 0d 0a 54 72 61 6e 73   ext/plain..Trans0030-003F   66 65 72 2d 45 6e 63 6f 64 69 6e 67 3a 20 63 68   fer-Encoding: ch0040-004F   75 6e 6b 65 64 0d 0a 0d 0a 32 35 0d 0a 54 68 69   unked....25..Thi0050-005F   73 20 69 73 20 74 68 65 20 64 61 74 61 20 69 6e   s is the data in0060-006F   20 74 68 65 20 66 69 72 73 74 20 63 68 75 6e 6b    the first chunk0070-007F   0d 0a 0d 0a 31 41 0d 0a 61 6e 64 20 74 68 69 73   ....1A..and this0080-008F   20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20 6f    is the second o0090-009F   6e 65 0d 0a 30 0d 0a 0d 0a                        ne..0....
same as above, in Java code
public static final byte[] CHUNKED_RESPONSE;static { StringBuilder sb = new StringBuilder();sb.append("HTTP/1.1 200 OK/r/n");sb.append("Content-Type: text/plain/r/n");sb.append("Transfer-Encoding: chunked/r/n/r/n");sb.append("25/r/n");sb.append("This is the data in the first chunk/r/n"); // 37 bytes of payload// (conveniently consisting of ASCII characters only)sb.append("/r/n1A/r/n");sb.append("and this is the second one"); // 26 bytes of payload// (conveniently consisting of ASCII characters only)sb.append("/r/n0/r/n/r/n");CHUNKED_RESPONSE = sb.toString().getBytes(java.nio.charset.Charset.forName("US-ASCII"));}
Decoded data
This is the data in the first chunkand this is the second one
基本上checked的編碼方式。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.