-
Notifications
You must be signed in to change notification settings - Fork 824
Description
Describe the bug
Hi, I noticed during upgrade of Spring Boot 4 and on Spring-Cloud-Open-Feign 5.0.1, the use of Feigns RequestInterceptor and making use of RequestTemplate.headers() method has changed. I apologize if this is not a Spring Cloud specific issue, so it's difficult to say but I'm starting here. Let me explain what's happening.
In our Feign interface we have the use of the Spring Framework HttpHeaders object to pass through headers to the target service. We use the Feign RequestInterceptor to override the Authorization header for basic auth.
We noticed the RequestTemplate.headers() method which returns a Map<String, Collection> interface, has changed the way the data is presented. In the past we would have received a map entry PER header with it's value. Now what is happening, is the map has blown up with a value for every single ENUM in the HttpHeaders class, which means a map entry for every known standard header as well as a map entry called "headers" with the value being a comma-delimited list of header/value entries. This is now all I have to work with where in the past I had a clean map of header / value.
Sample
Feign Client Method
@GetMapping(value = "/some-api")
ResponseEntity<List<SomeResponse>> findSomeData(@RequestHeader HttpHeaders headers);
Request Interceptor
@Bean
RequestInterceptor requestInterceptor(final FeignHeaders feignHeaders, final SecurityConfig securityConfig) {
return requestTemplate -> {
Map<String, Collection<String>> headers = requestTemplate.headers();
requestTemplate.headers(null);
requestTemplate.headers(headers);
requestTemplate.header(HttpHeaders.AUTHORIZATION, "Basic ********");
};
}
The requestTemplate.headers() line used to return a map entry for every header but now it returns a blown out map of every enum in the HttpHeaders.class along with a single map entry for all the headers that I used to get prior to the upgrade. Here's the toString result:
ACCEPT_ENCODING = feign.template.HeaderTemplate@2bbee363
ACCEPT_LANGUAGE = feign.template.HeaderTemplate@5a480741
ACCEPT_PATCH = feign.template.HeaderTemplate@5e74f259
ACCEPT_RANGES = feign.template.HeaderTemplate@596781b7
ACCESS_CONTROL_ALLOW_CREDENTIALS = feign.template.HeaderTemplate@51ed403
ACCESS_CONTROL_ALLOW_HEADERS = feign.template.HeaderTemplate@1f76b9ee
ACCESS_CONTROL_ALLOW_METHODS = feign.template.HeaderTemplate@66697663
ACCESS_CONTROL_ALLOW_ORIGIN = feign.template.HeaderTemplate@3662920
ACCESS_CONTROL_EXPOSE_HEADERS = feign.template.HeaderTemplate@70ab5b83
ACCEPT = feign.template.HeaderTemplate@67cc7e97
ACCEPT_CHARSET = feign.template.HeaderTemplate@ACCEPT_CHARSET = feign.template.HeaderTemplate@37760c4c
ACCESS_CONTROL_REQUEST_HEADERS = feign.template.HeaderTemplate@77cf9afb
ACCESS_CONTROL_REQUEST_METHOD = feign.template.HeaderTemplate@45d2920b
AGE = feign.template.HeaderTemplate@6f8fae71
ALLOW = feign.template.HeaderTemplate@74011b9c
AUTHORIZATION = feign.template.HeaderTemplate@7f125fa5
CACHE_CONTROL = feign.template.HeaderTemplate@2e81c886
CONNECTION = feign.template.HeaderTemplate@3c6f1701
CONTENT_DISPOSITION = feign.template.HeaderTemplate@404e36eb
CONTENT_ENCODING = feign.template.HeaderTemplate@2dccb630
CONTENT_LANGUAGE = feign.template.HeaderTemplate@d299ef7
CONTENT_LENGTH = feign.template.HeaderTemplate@49ba474c
CONTENT_LOCATION = feign.template.HeaderTemplate@78f2c9fe
CONTENT_RANGE = feign.template.HeaderTemplate@30478de6
CONTENT_TYPE = feign.template.HeaderTemplate@7158633f
COOKIE = feign.template.HeaderTemplate@6ac3ca7f
DATE = feign.template.HeaderTemplate@49043e0
DATE_FORMATTER = feign.template.HeaderTemplate@834c629
DATE_PARSERS = feign.template.HeaderTemplate@3ac71d8b
DECIMAL_FORMAT_SYMBOLS = feign.template.HeaderTemplate@4e23a89e
EMPTY = feign.template.HeaderTemplate@48aa7df9
ETAG = feign.template.HeaderTemplate@6601ef4b
EXPECT = feign.template.HeaderTemplate@64a88d45
EXPIRES = feign.template.HeaderTemplate@371cae16
FROM = feign.template.HeaderTemplate@2cc258b9
GMT = feign.template.HeaderTemplate@45d081dd
headers = feign.template.HeaderTemplate@65b2fe87
HOST = feign.template.HeaderTemplate@370c8039
IF_MATCH = feign.template.HeaderTemplate@9b501f1
IF_MODIFIED_SINCE = feign.template.HeaderTemplate@482ab773
IF_NONE_MATCH = feign.template.HeaderTemplate@3a9e3e37
IF_RANGE = feign.template.HeaderTemplate@69406c15
IF_UNMODIFIED_SINCE = feign.template.HeaderTemplate@485b5245
LAST_MODIFIED = feign.template.HeaderTemplate@55d7f512
LINK = feign.template.HeaderTemplate@1ef30619
LOCATION = feign.template.HeaderTemplate@74b9f116
MAX_FORWARDS = feign.template.HeaderTemplate@66625cbe
ORIGIN = feign.template.HeaderTemplate@c775a05
PRAGMA = feign.template.HeaderTemplate@ab2465c
PROXY_AUTHENTICATE = feign.template.HeaderTemplate@31b8275d
PROXY_AUTHORIZATION = feign.template.HeaderTemplate@45cb1a78
RANGE = feign.template.HeaderTemplate@735ac7b6
REFERER = feign.template.HeaderTemplate@6bc2ef27
RETRY_AFTER = feign.template.HeaderTemplate@1b30afcd
serialVersionUID = feign.template.HeaderTemplate@6356e09
SERVER = feign.template.HeaderTemplate@23f77e0e
SET_COOKIE = feign.template.HeaderTemplate@5f300680
SET_COOKIE2 = feign.template.HeaderTemplate@41e0946c
TE = feign.template.HeaderTemplate@6c08ff7f
TRAILER = feign.template.HeaderTemplate@7417ebfe
TRANSFER_ENCODING = feign.template.HeaderTemplate@2b4cf7fa
UPGRADE = feign.template.HeaderTemplate@6e4a550b
USER_AGENT = feign.template.HeaderTemplate@4512bcba
VARY = feign.template.HeaderTemplate@e11e7fd
VIA = feign.template.HeaderTemplate@422e32e2
WARNING = feign.template.HeaderTemplate@7e70c5a1
WWW_AUTHENTICATE = feign.template.HeaderTemplate@2e5751b9
Notice the map entry called "headers"......case sensitive...............the value of this actually contains the headers I'm looking for..........formatted like this in the map entries value:
[{Content-Type=[application/json], If-Match=[12345678], Authorization=[null], User-Agent=[PostmanRuntime/7.51.1], Accept=[/], Postman-Token=[06ccbb68-12eb-4e3b-bd69-0d3ceb6933c4], Host=[localhost:8080], Accept-Encoding=[gzip, deflate, br], Connection=[keep-alive]}]
Now I have to parse this string back into something processable so I can iterate on the headers and overwrite as needed. In the past, I would get a clean map entry for each of the headers and I can simple iterate through them as needed.