Closed
Description
It seems like ResponseEntityResultHandler behaves differently compared to ServerResponseResultHandler regarding their handling of already present HTTP headers.
For example: Github
@SpringBootApplication
public class ResponseHandlerIssueApplication {
public static void main(String[] args) {
SpringApplication.run(ResponseHandlerIssueApplication.class, args);
}
}
@Component
class DefaultNoCacheHeaderFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
var headers = exchange.getResponse().getHeaders();
if (headers.getCacheControl() == null) {
headers.setCacheControl(CacheControl.noCache());
}
return chain.filter(exchange);
}
}
@RestController
class TestController {
@GetMapping("/responseEntity")
public Mono<ResponseEntity<String>> cached() {
var rsp = ResponseEntity
.status(HttpStatus.OK)
.cacheControl(CacheControl.maxAge(Duration.ofHours(1)))
.body("supposed to be cached");
return Mono.just(rsp);
}
}
@Configuration
class RouterConfig {
@Bean
public RouterFunction<ServerResponse> routerFunction() {
return route(GET("serverResponse"),
req -> ServerResponse.ok()
.cacheControl(CacheControl.maxAge(Duration.ofHours(1)))
.body(BodyInserters.fromValue("supposed to be cached")
));
}
}
Testing using curl
:
curl -v 'http://localhost:8080/responseEntity'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /responseEntity HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Cache-Control: max-age=3600
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 21
<
* Connection #0 to host localhost left intact
supposed to be cached* Closing connection 0
curl -v 'http://localhost:8080/serverResponse'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /serverResponse HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 21
<
* Connection #0 to host localhost left intact
supposed to be cached* Closing connection 0
As we can see the /responseEntity
endpoint returns max-age=3600
for our Cache-Control header. However, /serverResponse
returns no-cache
.
ResponseEntityResultHandler seems to be overriding existing headers and DefaultServerResponseBuilder not to.
The fix might be trivial, but maybe the intended behavior should be discussed.