Should not add Content-Type and Content-Length headers to requests with empty body
Hi, first of all thanks for this great library! I'm glad for this great alternative after Zuul is no longer supported by Spring.
One minor issue we noticed: When sending an HTTP requests without body (for example a simple HTTP GET request) Charon adds two headers: Content-Type: application/octet-stream and ContentLength: 0. I guess this behaviour is not intended as these headers wouldn't make any sense if there is not any content available. Moreover in our special case it causes a third-party API to reject such a request, because content type application/octet-stream is not supported by this application.
This is what I found out:
-
ReverseProxyFilterreceives Request with emtpy body -
ReverseProxyFiltercallsHttpRequestMapper.mapto create aRequestEntity. Thebodyparameter of thisRequestEntityis initialized with an empty byte array. - In
ReverseProxyFilterthe request is passed to theexchangemethod of theRestTemplate - Spring's
ByteArrayHttpMessageConverteris called which adds theContent-TypeandContent-Lenghtheaders!
Suggestion:
If in step 2 the HttpRequestMapper would not initialize the body with an empty array but with null then RestTemplate would handle the request appropriately. In this case ByteArrayHttpMessageConverter won't be called and the Content-Type and Content-Length headers won't be added.
Hi, just ran into this issue myself. The server rejects the GET request because of the Content-Length=0 header. Any workaround for now?
Our workaround was to implement a RequestForwardingInterceptor and remove the headers when the body is empty:
override fun forward(request: HttpRequest, execution: HttpRequestExecution): HttpResponse {
if (request.body.isEmpty()) {
request.headers.remove("Content-Type")
request.headers.remove("Content-Length")
}
return execution.execute(request)
}
Thanks for the snippet. Maybe it's my version of Spring/Boot but after I remove the headers Spring sets the Content-Length header back to 0 via the class org.springframework.http.client.AbstractBufferingClientHttpRequest. I'll see if I can find an alernative solution.
I tried to debug a bit, but the setting of content-length occurs up the stack, outside of Charon' scope. I tried write an immutable HttpHeader implementation but Spring makes a copy of the headers upstream. Are you sure the content-length isn['t set again? I used Fiddler to monitor the network traffic from my machine to the server and the content-length header is still there. Content-type has been removed though. Holding thumbs Charon' dev can find a solution.
My analysis: package: okhttp.internal.http class: BridgeInterceptor method: intercept
In my case the problem is that the Host header is added without my permission. It seems that with current version of okhttp we're stuck. RealCall is final and there is no simple option to remove BridgeInterceptor from the list of auto added interceptors. Maybe upgrade to higher versions of okhttp could help us solve that issue.
The the Content-Type and Content-Length headers aren't added for empty body any more starting from version 5.2.0.