From b732251b093552812d7457608d422e899241ca04 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 20 Feb 2017 11:58:22 +0100 Subject: [PATCH] Ignore HEAD requests in ShallowEtagHeaderFilter Prior to this commit, the `ShallowEtagHeaderFilter` could participate in the response and set its ETag/Content-Length headers, even for HEAD requests. Since the response body is empty, the filter implementation would set a `"Content-Length: 0"`. The RFC states that responses to HEAD requests should exhibit identical response headers to GET (with the possible exception of payload related headers such as Content-Length. With this commit, `ShallowEtagHeaderFilter` now ignores HEAD requests since the proper values may be set already for payload related headers by the handler. The filter has no way to generate a proper ETag value nor calculate the content length without the actual body. Issue: SPR-15261 --- .../web/filter/ShallowEtagHeaderFilter.java | 7 ++++--- .../web/filter/ShallowEtagHeaderFilterTests.java | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java index 79bca0ca7aa..5d29d1c59be 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.springframework.web.filter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; + import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; @@ -168,8 +169,8 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { int responseStatusCode, InputStream inputStream) { String method = request.getMethod(); - if (responseStatusCode >= 200 && responseStatusCode < 300 && - (HttpMethod.GET.matches(method) || HttpMethod.HEAD.matches(method))) { + if (responseStatusCode >= 200 && responseStatusCode < 300 + && HttpMethod.GET.matches(method)) { String cacheControl = response.getHeader(HEADER_CACHE_CONTROL); if (cacheControl == null || !cacheControl.contains(DIRECTIVE_NO_STORE)) { diff --git a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java index 893501b23ee..d5961ce112c 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java @@ -46,6 +46,9 @@ public class ShallowEtagHeaderFilterTests { assertTrue(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); assertFalse(filter.isEligibleForEtag(request, response, 300, StreamUtils.emptyInput())); + request = new MockHttpServletRequest("HEAD", "/hotels"); + assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); + request = new MockHttpServletRequest("POST", "/hotels"); assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput()));