diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilter.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilter.java index 064d82a0..4fca8db0 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilter.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilter.java @@ -18,8 +18,9 @@ import java.io.PrintWriter; /** - * Sets {@code Cache-Control} only when HTTP cache is enabled and the request path plus - * query parameters match a mapping exactly. Unmatched requests get no cache header. + * When HTTP cache is enabled, sets {@code Cache-Control} on GET responses that do not + * already have one: a matching mapping's value, otherwise + * {@code no-store, no-cache, must-revalidate}. *
* Implemented as a filter (not a {@code HandlerInterceptor}) so the header is applied * before the response body is written. {@code postHandle} runs after {@code @ResponseBody} @@ -28,6 +29,8 @@ @Component public class HttpCacheControlFilter extends OncePerRequestFilter { + static final String NO_CACHE = "no-store, no-cache, must-revalidate"; + private final OgcApiProperties ogcApiProperties; public HttpCacheControlFilter(OgcApiProperties ogcApiProperties) { @@ -75,19 +78,19 @@ void applyIfEligible() { return; } applied = true; - if (getStatus() != HttpStatus.OK.value()) { - return; - } if (containsHeader(HttpHeaders.CACHE_CONTROL)) { return; } - String path = request.getRequestURI(); - for (OgcApiProperties.Mapping mapping : httpCache.mappings()) { - if (mapping.matches(path, request.getParameterMap())) { - setHeader(HttpHeaders.CACHE_CONTROL, mapping.cacheControlHeader()); - return; + if (getStatus() == HttpStatus.OK.value()) { + String path = request.getRequestURI(); + for (OgcApiProperties.Mapping mapping : httpCache.mappings()) { + if (mapping.matches(path, request.getParameterMap())) { + setHeader(HttpHeaders.CACHE_CONTROL, mapping.cacheControlHeader()); + return; + } } } + setHeader(HttpHeaders.CACHE_CONTROL, NO_CACHE); } @Override diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilterTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilterTest.java index c582426c..e66d6795 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilterTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/http/HttpCacheControlFilterTest.java @@ -77,7 +77,7 @@ void setsHeaderOnExactMatchBeforeBodyWrite() throws Exception { } @Test - void noHeaderWhenPathDiffers() throws Exception { + void noCacheWhenPathDiffers() throws Exception { HttpCacheControlFilter filter = new HttpCacheControlFilter(properties(true)); MockHttpServletRequest request = matchingGet(); request.setRequestURI("/api/v1/ogc/collections/other"); @@ -85,11 +85,11 @@ void noHeaderWhenPathDiffers() throws Exception { run(filter, request, response, statusThenWrite(200)); - assertNull(response.getHeader(HttpHeaders.CACHE_CONTROL)); + assertEquals(HttpCacheControlFilter.NO_CACHE, response.getHeader(HttpHeaders.CACHE_CONTROL)); } @Test - void noHeaderWhenExtraQueryParamPresent() throws Exception { + void noCacheWhenExtraQueryParamPresent() throws Exception { HttpCacheControlFilter filter = new HttpCacheControlFilter(properties(true)); MockHttpServletRequest request = matchingGet(); request.setParameter("q", "fish"); @@ -97,11 +97,11 @@ void noHeaderWhenExtraQueryParamPresent() throws Exception { run(filter, request, response, statusThenWrite(200)); - assertNull(response.getHeader(HttpHeaders.CACHE_CONTROL)); + assertEquals(HttpCacheControlFilter.NO_CACHE, response.getHeader(HttpHeaders.CACHE_CONTROL)); } @Test - void noHeaderWhenExpectedParamValueDiffers() throws Exception { + void noCacheWhenExpectedParamValueDiffers() throws Exception { HttpCacheControlFilter filter = new HttpCacheControlFilter(properties(true)); MockHttpServletRequest request = matchingGet(); request.setParameter("sortby", "-score"); @@ -109,17 +109,17 @@ void noHeaderWhenExpectedParamValueDiffers() throws Exception { run(filter, request, response, statusThenWrite(200)); - assertNull(response.getHeader(HttpHeaders.CACHE_CONTROL)); + assertEquals(HttpCacheControlFilter.NO_CACHE, response.getHeader(HttpHeaders.CACHE_CONTROL)); } @Test - void noHeaderWhenNotOk() throws Exception { + void noCacheWhenNotOk() throws Exception { HttpCacheControlFilter filter = new HttpCacheControlFilter(properties(true)); MockHttpServletResponse response = new MockHttpServletResponse(); run(filter, matchingGet(), response, statusThenWrite(500)); - assertNull(response.getHeader(HttpHeaders.CACHE_CONTROL)); + assertEquals(HttpCacheControlFilter.NO_CACHE, response.getHeader(HttpHeaders.CACHE_CONTROL)); } @Test