Affects: Spring Framework 6.1.0-M5 (via Spring Boot 3.2.0-M3)
With an @HttpExchange
interface that only has @RequestParam
parameters similar to
public interface MyClient {
@PostExchange("/path")
ResponseEntity<String> someCall(@RequestParam("param") String param);
}
and a RestClient
configured with a BufferingClientHttpRequestFactory
:
var restClient = RestClient.builder()
.url("url")
.requestFactory(new BufferingClientHttpRequestFactory(new JdkClientHttpRequestFactory()))
.build();
calls to the service result error out with the message non-positive contentLength: 0
.
The call can be made to work by either removing the requestFactory
call to the RestClient
builder or by adding a dummy @RequestBody
parameter to the interface
public interface MyClient {
@PostExchange("/path")
ResponseEntity<String> someCall(@RequestParam("param") String param,
@RequestBody String dummy);
}
The problem, I believe, is in the content length check in org.springframework.http.client.JdkClientHttpRequest#bodyPublisher:
private HttpRequest.BodyPublisher bodyPublisher(HttpHeaders headers, @Nullable Body body) {
if (body != null) {
Flow.Publisher<ByteBuffer> outputStreamPublisher = OutputStreamPublisher.create(
outputStream -> body.writeTo(StreamUtils.nonClosing(outputStream)),
BYTE_MAPPER, this.executor);
long contentLength = headers.getContentLength();
if (contentLength != -1) {
return HttpRequest.BodyPublishers.fromPublisher(outputStreamPublisher, contentLength);
}
else {
return HttpRequest.BodyPublishers.fromPublisher(outputStreamPublisher);
}
}
else {
return HttpRequest.BodyPublishers.noBody();
}
}
If, with a debugger, I change the value of contentLength
to -1, the call also succeeds which suggests that the check should be if(contentLength <= 0)