大きなファイルのRestTemplateに関する質問がありました。最大のコンテンツ長がありますか、明示的に設定されていても自動的に変更されますか?Spring RestTemplate大きなファイルContentLength Autoが変更されました
HTTP PUTコマンドでCDN(Akamai)に送信したいファイルが5GBあります。私は(Javaヒープスペースエラーを避けるために)以下のように設定しましたが、コマンドが実行されるとContent-Lengthが変更されることに気付きました。
@Autowired
@Qualifier("restTemplateUpload")
public void setRestTemplateUpload(RestTemplate restTemplateUpload)
{
this.restTemplateUpload = restTemplateUpload;
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplateUpload.setRequestFactory(requestFactory);
}
し、ファイルを送信するためにコール:
Resource resource = new FileSystemResource(localFile);
HttpHeaders headers = new HttpHeaders();
Map<String, String> headerValues = new HashMap<String, String>();
headerValues.put("X-Akamai...", value); //There are more headers, but you can assume this is correctly done as I've been able to transmit smaller files
headerValues.put("Host", host);
headers.setAll(headerValues);
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
//I've tried using this and not using this but the result is
//the same, the request sent changes the value to 1469622184
headers.setContentLength(resource.contentLength());
System.out.println(headers.getContentLength()); //Result is: 5764589480
HttpEntity<Resource> uploadRequest = new HttpEntity<Resource>(resource, headers);
response = restTemplateUpload.exchange(hostPath, HttpMethod.PUT, uploadRequest, String.class);
チャールズプロキシは、コンテンツ長1469622184を報告し、リクエストがその長さに達したときに接続が殺されます。
Javaがエラーを報告:
org.springframework.web.client.ResourceAccessException: I/O error on PUT request for "http://hidden.com/path/largefile.txt": too many bytes written;"
編集:私はそうのようなContent-Lengthをハードコーディング
いくつかのより多くの観測、:headerValues.put( "のContent-Length"、「3764589480 "); 実際にContent-Lengthフィールドは送信されず、代わりにTransfer-Encoding:chunkedヘッダーが送信されます。
だから私はより多くのテストを実行し、これは何が起こるかです:
ハードコードコンテンツの長さ:チャールズ
に"1064589480" の結果:コンテンツ長を送信:1064589480
"2064589480":コンテンツを送信-length:2064589480
"3064589480" は:コンテンツ長を削除し、転送エンコーディングを追加します: "3764589480"
チャンク:
"4294967295"
チャンク:コンテンツ長を削除し、転送エンコードが追加のContent-Lengthを送信します::"4294967296"
チャンク:コンテンツ長を削除し、転送エンコードが追加し、 "0"、即時クラッシュし、「4764589480」書かれてあまりにも多くのバイト:コンテンツ長を送信:「469622184」
「5764589480」:コンテンツ長を送信:私の知る限り推測できるよう「1469622184」
、一定で番号、RestTemplateはContent-Lenから転送符号化へのgth。 4294967295を通過すると、Content-Lengthを再び0に戻し始めます。 これは、4294967295より高い値を決して指定しないことです。そのしきい値を超えている場合は、単に4294967295に設定し、RestTemplateはそれを転送エンコーディング:とにかくチャンク。 オーバーフロー/精度ポイントの問題がありますか?