I am sending a request to a third-party API, and their server (PHP 5.5) requires that the content-length header be uppercased 'Content-Length'.
However, I'm using Spring webclient, and it is sending out the 'Content-Length' in lowercased 'content-length', however I tried to send it out as uppercased.
webClient
.method(method)
.uri(uri)
.headers(headersConsumer)
.header("Content-Length-Test", Integer.toString(objectMapper.writeValueAsBytes(reqBody).length))
.header("Content-Length", Integer.toString(objectMapper.writeValueAsBytes(reqBody).length))
.bodyValue(Optional.ofNullable(reqBody).orElse(""))
.retrieve()
.bodyToMono(returnType)
result
POST /test/test HTTP/1.1
user-agent: ReactorNetty/1.0.12
Content-Type: application/json
Authorization: Basic
Accept: */*
Host: 127.0.0.1:9999
Content-Length-Test: 202
content-length: 202
You can see that "Content-Length-Test" that I put in prints out as expected, but not for the actual "Content-Length" header.
I've read the following and related posts about how the HTTP standard specifies that all headers are case insensitive.
The problem is the API I need for my service is case-sensitive when it comes to processing headers. How to prevent of converting header name into lower case - Spring boot?
How can I prevent the Content-Length header from being lower cased?
Need help.
Thanks.
WebClient by default is using Reactor Netty underneath, and that inserts the Content-Length header itself; you don't need to provide it at the WebClient
level. As can be seen this is indeed in lower-case.
To fix this, you should configure a Netty HttpClient yourself and then pass it to the WebClient (via ReactorClientHttpConnector
).
The HttpClient
setup should include (note that it uses a fluent interface so you need to take the HttpClient
that is returned from doOnConnected
):
httpClient.doOnConnected(connection -> connection.addHandlerFirst(new MessageToMessageEncoder<HttpRequest>() {
@Override
protected void encode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) {
HttpHeaders requestHeaders = msg.headers();
String value = requestHeaders.get("content-length");
if (value != null) {
requestHeaders.remove("content-length")
.set("Content-Length", value);
}
if (msg instanceof ReferenceCounted)
((ReferenceCounted)msg).retain();
out.add(msg);
}
))