質問: とある組み込みマイコン向けの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とは限りませんが、おかしな挙動をするクライアント対策が施されていることを期待してということです。)