You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by jo...@apache.org on 2011/01/11 17:31:07 UTC
svn commit: r1057715 - in
/httpcomponents/httpclient/trunk/httpclient-cache/src:
main/java/org/apache/http/impl/client/cache/
test/java/org/apache/http/impl/client/cache/
Author: jonm
Date: Tue Jan 11 16:31:06 2011
New Revision: 1057715
URL: http://svn.apache.org/viewvc?rev=1057715&view=rev
Log:
Responses from HTTP/1.0 origins to requests containing query parameters
SHOULD NOT be taken from a cache.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
Modified:
httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseCachingPolicy.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCachingPolicy.java
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseCachingPolicy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseCachingPolicy.java?rev=1057715&r1=1057714&r2=1057715&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseCachingPolicy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseCachingPolicy.java Tue Jan 11 16:31:06 2011
@@ -201,7 +201,8 @@ class ResponseCachingPolicy {
return false;
}
- if (request.getRequestLine().getUri().contains("?") && !isExplicitlyCacheable(response)) {
+ if (request.getRequestLine().getUri().contains("?") &&
+ (!isExplicitlyCacheable(response) || from1_0Origin(response))) {
log.debug("Response was not cacheable.");
return false;
}
@@ -220,6 +221,21 @@ class ResponseCachingPolicy {
return isResponseCacheable(method, response);
}
+ private boolean from1_0Origin(HttpResponse response) {
+ Header via = response.getFirstHeader("Via");
+ if (via != null) {
+ for(HeaderElement elt : via.getElements()) {
+ String proto = elt.toString().split("\\s")[0];
+ if (proto.contains("/")) {
+ return proto.equals("HTTP/1.0");
+ } else {
+ return proto.equals("1.0");
+ }
+ }
+ }
+ return HttpVersion.HTTP_1_0.equals(response.getProtocolVersion());
+ }
+
private boolean requestProtocolGreaterThanAccepted(HttpRequest req) {
return req.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) > 0;
}
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java?rev=1057715&r1=1057714&r2=1057715&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java Tue Jan 11 16:31:06 2011
@@ -59,6 +59,7 @@ import org.junit.Test;
*/
public class TestProtocolRecommendations extends AbstractProtocolTest {
+ private Date tenSecondsFromNow;
private Date now;
private Date tenSecondsAgo;
@@ -68,6 +69,7 @@ public class TestProtocolRecommendations
super.setUp();
now = new Date();
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
+ tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
}
/* "identity: The default (identity) encoding; the use of no
@@ -1078,4 +1080,66 @@ public class TestProtocolRecommendations
impl.execute(host, req3);
verifyMocks();
}
+
+ /*
+ * "This specifically means that responses from HTTP/1.0 servers for such
+ * URIs [those containing a '?' in the rel_path part] SHOULD NOT be taken
+ * from a cache."
+ *
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
+ */
+ @Test
+ public void responseToGetWithQueryFrom1_0OriginIsNotCached()
+ throws Exception {
+ HttpRequest req1 = new HttpGet("http://foo.example.com/bar?baz=quux");
+ HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+ resp1.setEntity(HttpTestUtils.makeBody(200));
+ resp1.setHeader("Content-Length","200");
+ resp1.setHeader("Date", formatDate(now));
+ resp1.setHeader("Expires", formatDate(tenSecondsFromNow));
+
+ backendExpectsAnyRequest().andReturn(resp1);
+
+ HttpRequest req2 = new HttpGet("http://foo.example.com/bar?baz=quux");
+ HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+ resp2.setEntity(HttpTestUtils.makeBody(200));
+ resp2.setHeader("Content-Length","200");
+ resp2.setHeader("Date", formatDate(now));
+
+ backendExpectsAnyRequest().andReturn(resp2);
+
+ replayMocks();
+ impl.execute(host, req1);
+ impl.execute(host, req2);
+ verifyMocks();
+ }
+
+ @Test
+ public void responseToGetWithQueryFrom1_0OriginVia1_1ProxyIsNotCached()
+ throws Exception {
+ HttpRequest req1 = new HttpGet("http://foo.example.com/bar?baz=quux");
+ HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+ resp1.setEntity(HttpTestUtils.makeBody(200));
+ resp1.setHeader("Content-Length","200");
+ resp1.setHeader("Date", formatDate(now));
+ resp1.setHeader("Expires", formatDate(tenSecondsFromNow));
+ resp1.setHeader("Via","1.0 someproxy");
+
+ backendExpectsAnyRequest().andReturn(resp1);
+
+ HttpRequest req2 = new HttpGet("http://foo.example.com/bar?baz=quux");
+ HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+ resp2.setEntity(HttpTestUtils.makeBody(200));
+ resp2.setHeader("Content-Length","200");
+ resp2.setHeader("Date", formatDate(now));
+ resp2.setHeader("Via","1.0 someproxy");
+
+ backendExpectsAnyRequest().andReturn(resp2);
+
+ replayMocks();
+ impl.execute(host, req1);
+ impl.execute(host, req2);
+ verifyMocks();
+ }
+
}
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCachingPolicy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCachingPolicy.java?rev=1057715&r1=1057714&r2=1057715&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCachingPolicy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCachingPolicy.java Tue Jan 11 16:31:06 2011
@@ -32,8 +32,9 @@ import java.util.Random;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
import org.apache.http.ProtocolVersion;
-import org.apache.http.impl.cookie.DateUtils;
+import static org.apache.http.impl.cookie.DateUtils.formatDate;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
@@ -57,7 +58,7 @@ public class TestResponseCachingPolicy {
request = new BasicHttpRequest("GET","/",HTTP_1_1);
response = new BasicHttpResponse(
new BasicStatusLine(HTTP_1_1, HttpStatus.SC_OK, ""));
- response.setHeader("Date", DateUtils.formatDate(new Date()));
+ response.setHeader("Date", formatDate(new Date()));
response.setHeader("Content-Length", "0");
}
@@ -163,7 +164,7 @@ public class TestResponseCachingPolicy {
public void testNon206WithExplicitExpiresIsCacheable() {
int status = getRandomStatus();
response.setStatusCode(status);
- response.setHeader("Expires", DateUtils.formatDate(new Date()));
+ response.setHeader("Expires", formatDate(new Date()));
Assert.assertTrue(policy.isResponseCacheable("GET", response));
}
@@ -275,7 +276,7 @@ public class TestResponseCachingPolicy {
response = new BasicHttpResponse(
new BasicStatusLine(HTTP_1_1, HttpStatus.SC_OK, ""));
- response.setHeader("Date", DateUtils.formatDate(new Date()));
+ response.setHeader("Date", formatDate(new Date()));
response.addHeader("Cache-Control", "no-transform");
response.setHeader("Content-Length", "0");
@@ -333,8 +334,8 @@ public class TestResponseCachingPolicy {
public void testResponsesWithMultipleDateHeadersAreNotCacheable() {
Date now = new Date();
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
- response.addHeader("Date", DateUtils.formatDate(now));
- response.addHeader("Date", DateUtils.formatDate(sixSecondsAgo));
+ response.addHeader("Date", formatDate(now));
+ response.addHeader("Date", formatDate(sixSecondsAgo));
Assert.assertFalse(policy.isResponseCacheable("GET", response));
}
@@ -348,8 +349,8 @@ public class TestResponseCachingPolicy {
public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() {
Date now = new Date();
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
- response.addHeader("Expires", DateUtils.formatDate(now));
- response.addHeader("Expires", DateUtils.formatDate(sixSecondsAgo));
+ response.addHeader("Expires", formatDate(now));
+ response.addHeader("Expires", formatDate(sixSecondsAgo));
Assert.assertFalse(policy.isResponseCacheable("GET", response));
}
@@ -380,10 +381,69 @@ public class TestResponseCachingPolicy {
@Test
public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheable() {
request = new BasicHttpRequest("GET", "/foo?s=bar");
- response.setHeader("Expires", DateUtils.formatDate(new Date()));
+ response.setHeader("Expires", formatDate(new Date()));
Assert.assertTrue(policy.isResponseCacheable(request, response));
}
+ @Test
+ public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheable() {
+ request = new BasicHttpRequest("GET", "/foo?s=bar");
+ response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+ Assert.assertFalse(policy.isResponseCacheable(request, response));
+ }
+
+ @Test
+ public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheableEvenWithExpires() {
+ request = new BasicHttpRequest("GET", "/foo?s=bar");
+ response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+ Date now = new Date();
+ Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
+ response.setHeader("Date", formatDate(now));
+ response.setHeader("Expires", formatDate(tenSecondsFromNow));
+ Assert.assertFalse(policy.isResponseCacheable(request, response));
+ }
+
+ @Test
+ public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() {
+ request = new BasicHttpRequest("GET", "/foo?s=bar");
+ response.setHeader("Via", "1.0 someproxy");
+ Assert.assertFalse(policy.isResponseCacheable(request, response));
+ }
+
+ @Test
+ public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheableEvenWithExpires() {
+ request = new BasicHttpRequest("GET", "/foo?s=bar");
+ Date now = new Date();
+ Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
+ response.setHeader("Date", formatDate(now));
+ response.setHeader("Expires", formatDate(tenSecondsFromNow));
+ response.setHeader("Via", "1.0 someproxy");
+ Assert.assertFalse(policy.isResponseCacheable(request, response));
+ }
+
+ @Test
+ public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreNotCacheableEvenWithExpires() {
+ request = new BasicHttpRequest("GET", "/foo?s=bar");
+ Date now = new Date();
+ Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
+ response.setHeader("Date", formatDate(now));
+ response.setHeader("Expires", formatDate(tenSecondsFromNow));
+ response.setHeader("Via", "HTTP/1.0 someproxy");
+ Assert.assertFalse(policy.isResponseCacheable(request, response));
+ }
+
+ @Test
+ public void getsWithQueryParametersFrom1_1OriginsVia1_0ProxiesAreCacheableWithExpires() {
+ request = new BasicHttpRequest("GET", "/foo?s=bar");
+ Date now = new Date();
+ Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
+ response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK");
+ response.setHeader("Date", formatDate(now));
+ response.setHeader("Expires", formatDate(tenSecondsFromNow));
+ response.setHeader("Via", "1.1 someproxy");
+ Assert.assertTrue(policy.isResponseCacheable(request, response));
+ }
+
private int getRandomStatus() {
int rnd = (new Random()).nextInt(acceptableCodes.length);