私はApacheCommonsHttpClientとRestletを使用して安らかなWebサービスを呼び出しています。残念ながら、私のサーバー(Ruby on Railsに基づく)はTransfer-Encoding: chunked
、HttpClientがデフォルトで使用しているものを好みません。
クライアントからのPOSTのチャンクエンコーディングの使用を無効にする方法はありますか?
私はApacheCommonsHttpClientとRestletを使用して安らかなWebサービスを呼び出しています。残念ながら、私のサーバー(Ruby on Railsに基づく)はTransfer-Encoding: chunked
、HttpClientがデフォルトで使用しているものを好みません。
クライアントからのPOSTのチャンクエンコーディングの使用を無効にする方法はありますか?
原則として、リクエストがチャンクされないようにするには、投稿本文の正確なサイズを指定する必要があります。これは、動的に生成されたデータの場合、応答全体をメモリにバッファリングし、そのサイズを確認してから送信する必要があることを意味します。
Apache クライアントのドキュメントはこれを確認しているようですAbstractHttpEntity.setChunked()
:
チャンク設定はヒントのみであることに注意してください。HTTP/1.0 を使用している場合、チャンクは実行されません。それ以外の場合、chunked が false であっても、エンティティ コンテンツの長さが不明 (-1) の場合、HttpClient はチャンク コーディングを使用する必要があります。
Restletメーリングリストで述べたように、Restletバージョン2.1では、ClientResource#entityBufferingプロパティをtrueに設定して、コンテンツをメモリにキャッシュし、チャンク化されたエンコーディングを防ぐことができます。
@Slartibartfast が彼の回答で示唆したように、最も信頼できる方法は、明示的にHttpPost を HTTP 1.0 プロトコルに切り替えることです。
Apache HttpPost リクエストを HTTP 1.0 プロトコルに設定します (これが必要な場合は、HttpGet についても同じです...):
HttpPost httpPost = new HttpPost(someUrl); httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); // Apache HttpClient の v.4.3 以降
マルチパート ポスト リクエストを作成するときは、添付ファイルの入力として InputStream ではなく (HTTP 1.1 の場合はチャンク エンコーディングが発生します)、事前に同じストリームから作成する必要があるバイト配列を提供します。これが、コンテンツの長さがわかっている理由です。org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody(String, byte[], ContentType, String) を参照してください。
私はこれをAndroid開発用にテストしましたが、これにはわずかに異なるクラス名が必要でした... ( https://github.com/andstatus/andstatus/issues/249を参照)