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 620b326f0f7..6b5e688848d 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
@@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
+import org.springframework.http.HttpMethod;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;
import org.springframework.util.StreamUtils;
@@ -51,6 +52,10 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
+ private static final String HEADER_CACHE_CONTROL = "Cache-Control";
+
+ private static final String DIRECTIVE_NO_STORE = "no-store";
+
/**
* The default value is "false" so that the filter may delay the generation of
@@ -122,7 +127,13 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
/**
* Indicates whether the given request and response are eligible for ETag generation.
- *
The default implementation returns {@code true} for response status codes in the {@code 2xx} series.
+ *
The default implementation returns {@code true} if all conditions match:
+ *
+ * - response status codes in the {@code 2xx} series
+ * - request method is a GET
+ * - response Cache-Control header is null or does not contain a "no-store" directive
+ *
+ *
* @param request the HTTP request
* @param response the HTTP response
* @param responseStatusCode the HTTP response status code
@@ -132,7 +143,10 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
protected boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response,
int responseStatusCode, byte[] responseBody) {
- return (responseStatusCode >= 200 && responseStatusCode < 300);
+ return (responseStatusCode >= 200 && responseStatusCode < 300)
+ && HttpMethod.GET.name().equals(request.getMethod())
+ && (response.getHeader(HEADER_CACHE_CONTROL) == null
+ || !response.getHeader(HEADER_CACHE_CONTROL).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 8ff31eb224a..8c0318312c3 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -48,6 +48,13 @@ public class ShallowEtagHeaderFilterTests {
assertTrue(filter.isEligibleForEtag(request, response, 200, new byte[0]));
assertFalse(filter.isEligibleForEtag(request, response, 300, new byte[0]));
+
+ request = new MockHttpServletRequest("POST", "/hotels");
+ assertFalse(filter.isEligibleForEtag(request, response, 200, new byte[0]));
+
+ request = new MockHttpServletRequest("POST", "/hotels");
+ request.addHeader("Cache-Control","must-revalidate, no-store");
+ assertFalse(filter.isEligibleForEtag(request, response, 200, new byte[0]));
}
@Test