http chunked編碼格式

http的響應數據由下面2部分構成:
響應頭 + 數據部分
數據部分的格式由響應頭說明
一般情況下,HTTP的響應頭包含Content-Length域來指明數據的長度,例如:
有時候,服務器生成HTTP響應時,不好確定響應數據的大小,可能是大文件的下載或后臺需要復雜的邏輯處理生成頁面,這樣一般就使用chunked編碼進行傳輸。使用chunked編碼進行傳輸不用事先說明要傳輸的頁面內容的大小,通過一定的規則指明傳輸結束。

通常使用chunked編碼進行傳輸的時候,會先將數據進行壓縮。HTTP響應頭中的Content-Encoding域指明了壓縮格式。


當數據很大的時候,還會分多個塊(chunk)傳輸。chunked編碼的格式如下:

注意chunk數據長度的單位是字節,不包括后面的\r\n。以一個長度為0的塊作為結尾。
把所有的chunk數據部分組合起來存入文件,就是一個標準的gzip壓縮文件。

怎么樣把所有chunk數據部分提取出來呢?明白了上面的格式,其實就很簡單了。
如果我們是通過TCP接收的數據,首先要解決一個問題:找到chunk數據開始的地方,上面提到chunk前面是HTTP響應頭。其它先不管,響應頭是以連續的\r\n\r\n結尾的,這之后就是響應的數據部分。
假設我們有一個buffer
char *m_contentData;
里面存儲著按序收到的所有響應數據。
可以通過如下方式移動到數據部分,即chunked數據開始的地方(下圖所示:從A移動到B)

 int n=0;
while(*m_contentData)
{
                 if (*m_contentData=='\r' || *m_contentData=='\n')
                                n++;
                 else
                                n=0;
                 if (n==4)
                                 break;
                m_contentData++;
}

定義char *m_gzipContentData保存gzip數據,可以通過如下方式獲取到gzip數據,然后寫入文件。

 int len=0;
char ss[10];
char *p = m_contentData;
char *q = m_gzipData;
int gzip_len = 0;
while(1)
{
                sscanf(p, "%s", ss);
                 //read chunk-size
                len = HexToDecimal(ss); //convert hex to decimal
                 if (len == 0) //to chunk end
                                 break;
                p+=2; //read \r\n
                memcpy(q, p, len);
                q += len;
                p += len;
                gzip_len += len;
                p += 2; //read \r\n
}

fwrite(m_gzipData, 1, gzip_len, fp);
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容