feign
feign copied to clipboard
GET request with empty body has Content-Length header with 0
I am using the following code to make a request to an endpoint fronted with an ALB.
Feign.builder()
.logger(Slf4jLogger(MyApi::class.java))
.logLevel(feign.Logger.Level.FULL)
.encoder(JacksonEncoder(objectMapper))
.decoder(JacksonDecoder(objectMapper))
.requestInterceptor { template -> template.header("X-Api-Key", apiKey) }
.client(ApacheHttp5Client())
.target(Target.HardCodedTarget(MyApi::class.java, apiUrl))
I am using the client to send GET requests to my endpoint /api/service/account/xxxx with an empty request body. In the receiving end, I am noticing that there is a header Content-Length with value 0, which makes the request non-compliant with rfc7230. I am using feign 12.3 and httpclient5 5.2.1. How can I get rid of this unwanted header?
I have tested this case as I have code from another task #2064
I run queries for java11, Apache HC 5 and its async variant. I have run it with Jackson encodings and without it.
All requests do not have the Content-Length header:
# Apache HC5
DEBUG feign.Logger - [Http2Server#get] ---> GET https://api.github.com/ HTTP/1.1
DEBUG feign.Logger - [Http2Server#get] Accept: */*
DEBUG feign.Logger - [Http2Server#get] User-Agent: http2-test
DEBUG feign.Logger - [Http2Server#get] X-Api-Key: qwerty
DEBUG feign.Logger - [Http2Server#get] ---> END HTTP (0-byte body)
...
# Apache HC5, acync
DEBUG feign.Logger - [AsyncHttp2Server#get] ---> GET https://api.github.com/ HTTP/1.1
DEBUG feign.Logger - [AsyncHttp2Server#get] Accept: */*
DEBUG feign.Logger - [AsyncHttp2Server#get] User-Agent: http2-test
DEBUG feign.Logger - [AsyncHttp2Server#get] X-Api-Key: qwerty
DEBUG feign.Logger - [AsyncHttp2Server#get] ---> END HTTP (0-byte body)
...
# java11
DEBUG feign.Logger - [Http2Server#get] ---> GET https://api.github.com/ HTTP/1.1
DEBUG feign.Logger - [Http2Server#get] Accept: */*
DEBUG feign.Logger - [Http2Server#get] User-Agent: http2-test
DEBUG feign.Logger - [Http2Server#get] X-Api-Key: qwerty
...
# Apache HC5, json
DEBUG feign.Logger - [JsonHttp2Server#contributors] ---> GET https://api.github.com/repos/OpenFeign/feign/contributors HTTP/1.1
DEBUG feign.Logger - [JsonHttp2Server#contributors] Accept: */*
DEBUG feign.Logger - [JsonHttp2Server#contributors] User-Agent: http2-test
DEBUG feign.Logger - [JsonHttp2Server#contributors] X-Api-Key: qwerty
DEBUG feign.Logger - [JsonHttp2Server#contributors] ---> END HTTP (0-byte body)
...
# Apache HC5, async json
DEBUG feign.Logger - [JsonAsyncHttp2Server#contributors] ---> GET https://api.github.com/repos/OpenFeign/feign/contributors HTTP/1.1
DEBUG feign.Logger - [JsonAsyncHttp2Server#contributors] Accept: */*
DEBUG feign.Logger - [JsonAsyncHttp2Server#contributors] User-Agent: http2-test
DEBUG feign.Logger - [JsonAsyncHttp2Server#contributors] X-Api-Key: qwerty
DEBUG feign.Logger - [JsonAsyncHttp2Server#contributors] ---> END HTTP (0-byte body)
...
# java11, json
DEBUG feign.Logger - [JsonHttp2Server#contributors] ---> GET https://api.github.com/repos/OpenFeign/feign/contributors HTTP/1.1
DEBUG feign.Logger - [JsonHttp2Server#contributors] Accept: */*
DEBUG feign.Logger - [JsonHttp2Server#contributors] User-Agent: http2-test
DEBUG feign.Logger - [JsonHttp2Server#contributors] X-Api-Key: qwerty
DEBUG feign.Logger - [JsonHttp2Server#contributors] ---> END HTTP (0-byte body)
...
Could you re-check this case? Maybe there are other annotations in MyApi or additional interceptors.
Hi @radio-rogal ,
Thanks for checking this, I spent a lot of time going back and forth with this and could not figure out where the exact issue was. I did my testing in Java 17 and 19. As per my current observations, it works when I use OkHttpClient instead of ApacheHttpClient and ApacheHttp5Client. So I went ahead with using OkHttpClient. I also noticed that the issue does not happen when I send the request directly using ApacheHttpClient without Feign.
Hello @vitalijr2,
There is indeed other headers that are added to the request. If you try to ping a netcat, you will be able to see them:
public class Dummy {
public static void main(String[] args) {
var logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Main.class);
logger.setLevel(Level.TRACE);
var objectMapper = new ObjectMapper();
var client = Feign.builder()
.logger(new Slf4jLogger(logger))
.logLevel(feign.Logger.Level.FULL)
.encoder(new JacksonEncoder(objectMapper))
.decoder(new JacksonDecoder(objectMapper))
.requestInterceptor((template) -> template.header("X-Api-Key", "abc"))
.client(new ApacheHttpClient())
.target(HelloClient.class, "http://localhost:8888");
client.ping();
}
public static interface HelloClient {
@RequestLine("GET /ping")
Pong ping();
}
}
Produce:
14:51:45.690 [main] DEBUG dummy.Dummy -- [HelloClient#ping] ---> GET http://localhost:8888/ping HTTP/1.1
14:51:45.692 [main] DEBUG dummy.Dummy -- [HelloClient#ping] X-Api-Key: abc
14:51:45.693 [main] DEBUG dummy.Dummy -- [HelloClient#ping] ---> END HTTP (0-byte body)
And on the netcat:
$ nc -lkvn 8888
Connection received on 127.0.0.1 53643
GET /ping HTTP/1.1
X-Api-Key: abc
Accept: */*
Content-Length: 0
Host: localhost:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.14 (Java/21.0.2)
Accept-Encoding: gzip,deflate
And you can clearly see Content-Length: 0.