When using Spring Cloud Gateway with custom request decorators that cache request bodies, the EncoderHttpMessageWriter::write class (invoked by BodyInserters.insert() automatically calculates and sets the Content-Length header based on the buffered body content, even when the original request intentionally did not include this header.
The EncoderHttpMessageWriter always sets Content-Length for the upstream request, regardless of whether: - The original client request had Content-Length - The body is empty (length = 0) - The request method is GET
Environment: Spring Cloud Gateway version: 2023.0.3 Spring Boot version: 3.2.11 Java version: 17
Suggested fix: Update the logic in EncoderHttpMessageWriter to check byte count. ```if (inputStream instanceof Mono) { return body .singleOrEmpty() .switchIfEmpty( Mono.defer(() -> { message.getHeaders().setContentLength(0); return message.setComplete().then(Mono.empty()); }) ) .flatMap(buffer -> { Hints.touchDataBuffer(buffer, hints, logger); int contentLength = buffer.readableByteCount(); if (contentLength > 0) { message.getHeaders().setContentLength(contentLength); } return message.writeWith( Mono.just(buffer) .doOnDiscard(DataBuffer.class, DataBufferUtils::release) ); }) .doOnDiscard(DataBuffer.class, DataBufferUtils::release); }
Comment From: AtharvUrunkar
Hi @PawelTo, thanks for the detailed report.
Before I start working on a PR, I’d like to make sure I fully understand the expected behavior so the fix goes in the right direction.
Based on your description, can you please confirm the following?
-
GET requests Should EncoderHttpMessageWriter avoid setting the Content-Length header for GET requests entirely, even if a custom decorator ends up buffering a non-empty body?
-
Zero-length bodies If the encoded body size is 0 bytes, should the writer skip setting the Content-Length header (and not override an intentionally missing header)?
-
Non-zero bodies For methods like POST/PUT/PATCH, the writer should set Content-Length only when the body has a positive size, and should avoid overwriting an intentionally omitted header — is that correct?
I plan to update EncoderHttpMessageWriter accordingly and include test coverage for these cases. Once you confirm the expected behavior, I’ll proceed with the implementation.
Thanks!
Comment From: bclozel
@AtharvUrunkar the issue is not triaged yet.