mirror of
https://github.com/apache/httpcomponents-client.git
synced 2025-02-17 07:26:47 +00:00
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 git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1057715 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
020d303ec5
commit
e95a80b7a2
@ -201,7 +201,8 @@ public boolean isResponseCacheable(HttpRequest request, HttpResponse response) {
|
|||||||
return false;
|
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.");
|
log.debug("Response was not cacheable.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -220,6 +221,21 @@ public boolean isResponseCacheable(HttpRequest request, HttpResponse response) {
|
|||||||
return isResponseCacheable(method, response);
|
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) {
|
private boolean requestProtocolGreaterThanAccepted(HttpRequest req) {
|
||||||
return req.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) > 0;
|
return req.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) > 0;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
*/
|
*/
|
||||||
public class TestProtocolRecommendations extends AbstractProtocolTest {
|
public class TestProtocolRecommendations extends AbstractProtocolTest {
|
||||||
|
|
||||||
|
private Date tenSecondsFromNow;
|
||||||
private Date now;
|
private Date now;
|
||||||
private Date tenSecondsAgo;
|
private Date tenSecondsAgo;
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ public void setUp() {
|
|||||||
super.setUp();
|
super.setUp();
|
||||||
now = new Date();
|
now = new Date();
|
||||||
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||||
|
tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "identity: The default (identity) encoding; the use of no
|
/* "identity: The default (identity) encoding; the use of no
|
||||||
@ -1078,4 +1080,66 @@ public void cachedEntryShouldNotBeUsedIfMoreRecentMentionInContentLocation()
|
|||||||
impl.execute(host, req3);
|
impl.execute(host, req3);
|
||||||
verifyMocks();
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,9 @@
|
|||||||
import org.apache.http.HttpRequest;
|
import org.apache.http.HttpRequest;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.HttpVersion;
|
||||||
import org.apache.http.ProtocolVersion;
|
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.BasicHttpRequest;
|
||||||
import org.apache.http.message.BasicHttpResponse;
|
import org.apache.http.message.BasicHttpResponse;
|
||||||
import org.apache.http.message.BasicStatusLine;
|
import org.apache.http.message.BasicStatusLine;
|
||||||
@ -57,7 +58,7 @@ public void setUp() throws Exception {
|
|||||||
request = new BasicHttpRequest("GET","/",HTTP_1_1);
|
request = new BasicHttpRequest("GET","/",HTTP_1_1);
|
||||||
response = new BasicHttpResponse(
|
response = new BasicHttpResponse(
|
||||||
new BasicStatusLine(HTTP_1_1, HttpStatus.SC_OK, ""));
|
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");
|
response.setHeader("Content-Length", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ public void testPlain307ResponseCodeIsNotCacheable() {
|
|||||||
public void testNon206WithExplicitExpiresIsCacheable() {
|
public void testNon206WithExplicitExpiresIsCacheable() {
|
||||||
int status = getRandomStatus();
|
int status = getRandomStatus();
|
||||||
response.setStatusCode(status);
|
response.setStatusCode(status);
|
||||||
response.setHeader("Expires", DateUtils.formatDate(new Date()));
|
response.setHeader("Expires", formatDate(new Date()));
|
||||||
Assert.assertTrue(policy.isResponseCacheable("GET", response));
|
Assert.assertTrue(policy.isResponseCacheable("GET", response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +276,7 @@ public void testIsGetWithAnyCacheControlCacheable() {
|
|||||||
|
|
||||||
response = new BasicHttpResponse(
|
response = new BasicHttpResponse(
|
||||||
new BasicStatusLine(HTTP_1_1, HttpStatus.SC_OK, ""));
|
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.addHeader("Cache-Control", "no-transform");
|
||||||
response.setHeader("Content-Length", "0");
|
response.setHeader("Content-Length", "0");
|
||||||
|
|
||||||
@ -333,8 +334,8 @@ public void testResponsesWithMultipleAgeHeadersAreNotCacheable() {
|
|||||||
public void testResponsesWithMultipleDateHeadersAreNotCacheable() {
|
public void testResponsesWithMultipleDateHeadersAreNotCacheable() {
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||||
response.addHeader("Date", DateUtils.formatDate(now));
|
response.addHeader("Date", formatDate(now));
|
||||||
response.addHeader("Date", DateUtils.formatDate(sixSecondsAgo));
|
response.addHeader("Date", formatDate(sixSecondsAgo));
|
||||||
Assert.assertFalse(policy.isResponseCacheable("GET", response));
|
Assert.assertFalse(policy.isResponseCacheable("GET", response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,8 +349,8 @@ public void testResponsesWithMalformedDateHeadersAreNotCacheable() {
|
|||||||
public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() {
|
public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() {
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
|
||||||
response.addHeader("Expires", DateUtils.formatDate(now));
|
response.addHeader("Expires", formatDate(now));
|
||||||
response.addHeader("Expires", DateUtils.formatDate(sixSecondsAgo));
|
response.addHeader("Expires", formatDate(sixSecondsAgo));
|
||||||
Assert.assertFalse(policy.isResponseCacheable("GET", response));
|
Assert.assertFalse(policy.isResponseCacheable("GET", response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +381,66 @@ public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheable
|
|||||||
@Test
|
@Test
|
||||||
public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheable() {
|
public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheable() {
|
||||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
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));
|
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user