2017年3月10日星期五

HTTP 標頭 Transfer-Encoding: chunked 的處理方法

最近在下自行建立了一個 REST Server 並透過 Web API 的方式傳回 XML 資料
發現當遇到獲取的資料很長時, XML 的前後都會有一些非 XML 的資料顯示,令 XML Parser 等工具出錯……

使用如 Curl 等傳送 HTTP Request 的軟件並不會產生非 XML 資料,而在瀏覽器則會
仔細留意發現
當傳回的 XML 資料短時,會有 Content-Length 的標頭
但當傳回的 XML 資料很長時,不會出現 Content-Length 的標頭
被取代成 Transfer-Encoding: chunked 稱為 分塊傳輸編碼(Chunked transfer encoding)

分塊傳輸編碼的結構
<hex-value>
<part of body>

<hex-value>
<part of body>

.
.
.
0

hex-value 為一個 0 或以上的十六進制數值
每一個區塊由 hex-value 及 part of body 組成
hex-value 及 part of body 之間會以 CR (Carriage Return 或 \r) 及 LF (Line Feed 或 \n) 分隔
區塊之間會以兩組 CR 及 LF (即 CR LF CR LF) 分隔
最後的區塊的 hex-value 會以 0 作結束

在下利用 PHP 將分割的區塊合併
$rebuiltResponseBody = '';
$length = 0;
do {
    $fields = explode("\r\n", $originalResponseBody, 2);
    if (($length = hexdec($fields[0])) > 0) {
        $rebuiltResponseBody .= substr($fields[1], 0, $length);
        $originalResponseBody = substr($originalResponseBody, $length + 4);
    }
} while ($length > 0);

沒有留言 :

發佈留言