HTTP 1.1でChunked transfer encodingを拒否する方法

投稿者: Anonymous

とある組み込みマイコン向けのHTTPライブラリで難儀しています。
ライブラリにgetという関数があり、これを実行すると指定したURLにHTTP 1.1でGETを発行して、応答の本文を文字列として返してくるのですが、
サーバーがChunked transfer encodingで応答すると(即ち、応答ヘッダに Transfer-Encoding: Chunked が含まれた状態)、これをデコードせずに生の文字列を返してしまうのです。

応答ヘッダを取得することはできないので、プログラム側でチャンクをデコードすることはできません。(チャンク化されているかどうかを一意に判別できないため)
また、TCPやHTTPを含めた一切の通信処理は、完全に独立したMCU内で処理されるため、自分でsocketを使ってHTTPを実装することもできません。「

但し、get関数の引数として、要求ヘッダに1行だけ任意のヘッダを追加できる機能があるので、これを利用して、サーバーに、チャンク化しないように要求できないかと考えているのですが・・・
何か方法はないでしょうか?

解決

OOPerさんのコメントにあるようにHTTP/1.1においてTransfer-Encoding: chunkedへの対応は必須ですので、未対応ということは不正なクライアントであるとしか言いようがありません。
補足をしておくと、HTTP/1.0ではコンテンツ長が不明な場合、コネクション切断をもってコンテンツの終端を表していましたが、これでは異常終了と区別できません。HTTP/1.1でchunkedが導入され必須となっているのもコンテンツ長が不明なコンテンツを正確に扱うためです。

get関数の引数として、要求ヘッダに1行だけ任意のヘッダを追加できる機能があるので、これを利用して、サーバーに、チャンク化しないように要求できないか

TEヘッダーを用いることでクライアント側が解釈可能なTransfer-Encodingを事前通知することができます。この機能が正攻法ではありますが、既に説明しているようにchunkedは必須なためこれを拒否するようなリクエストは認められていません。

期待通りの動作をするか確実ではありませんが、WebサーバーApacheのデフォルト設定にはおかしな挙動をするクライアントに対してプロトコルの動作を変更するというものがあります。設定内容としては

BrowserMatch "MSIE 4.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4.0" force-response-1.0
BrowserMatch "Java/1.0" force-response-1.0
BrowserMatch "JDK/1.0" force-response-1.0

等があります。これを逆手にとって、User-Agent: MSIE 4.0b2;等を送信することで、Webサーバーに対してHTTP/1.0で応答するように求めることができるかもしれません。HTTP/1.0であればchunkedは存在しませんのでTransfer-Encoding: chunkedが返されることはないはずです。
(WebサーバーがApacheとは限りませんが、おかしな挙動をするクライアント対策が施されていることを期待してということです。)

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *