Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JdkClientHttpRequest does not support Content-Length 0 #31451

Closed
dciarniello opened this issue Oct 18, 2023 · 0 comments
Closed

JdkClientHttpRequest does not support Content-Length 0 #31451

dciarniello opened this issue Oct 18, 2023 · 0 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@dciarniello
Copy link

dciarniello commented Oct 18, 2023

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)

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 18, 2023
@poutsma poutsma self-assigned this Oct 23, 2023
@poutsma poutsma added in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug labels Oct 23, 2023
@poutsma poutsma added this to the 6.1.0-RC2 milestone Oct 23, 2023
@poutsma poutsma removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 23, 2023
@poutsma poutsma changed the title BufferingClientHttpRequestFactory not usable with empty request body JdkClientHttpRequest does not support Content-Length 0 Oct 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants