Affects: Spring: 5.3.9 and early version

Problem: SimpleClientHttpRequestFactory.setBufferRequestBody(false) is not working when RestTemplate has interceptor (i.e. BasicAuthenticationInterceptor), OutOfMemoryError occurs while upload large file using RestTemplate with both SimpleClientHttpRequestFactory.setBufferRequestBody(false) and interceptor.

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3236)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at org.springframework.util.StreamUtils.copy(StreamUtils.java:167)
    at org.springframework.http.converter.ResourceHttpMessageConverter.writeContent(ResourceHttpMessageConverter.java:137)
    at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:129)
    at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:45)
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:227)
    at org.springframework.http.converter.FormHttpMessageConverter.writePart(FormHttpMessageConverter.java:541)
    at org.springframework.http.converter.FormHttpMessageConverter.writeParts(FormHttpMessageConverter.java:517)
    at org.springframework.http.converter.FormHttpMessageConverter.writeMultipart(FormHttpMessageConverter.java:497)
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:369)
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:156)
    at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:991)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:774)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:437)
    at com.andy.upload.service.RestTemplateService.uploadLargeFile(RestTemplateService.java:34)
    at com.andy.upload.UploadApplicationTests.restTemplateUploadWithInterceptor(UploadApplicationTests.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$115/23211803.apply(Unknown Source)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)

Root Cause: RestTemplate using SimpleClientHttpRequestFactory.setBufferRequestBody(false) will create SimpleStreamingClientHttpRequest, which is expected result.

RestTemplate with both SimpleClientHttpRequestFactory.setBufferRequestBody(false) and interceptor will use InterceptingClientHttpRequestFactory to create InterceptingClientHttpRequest which is a sub class of AbstractBufferingClientHttpRequest, in other worlds, SimpleClientHttpRequestFactory.setBufferRequestBody(false) is not working and causing OutOfMemoryError.

Expected Behavior:

SimpleClientHttpRequestFactory.setBufferRequestBody(false) should works with interceptor.

Example Application: https://github.com/AndyLvVip/upload.git You can easily reproduce the described Problem with UTs. All Info about how to run the UTs can be found on the project's readme.

Comment From: bclozel

Duplicates #21650