summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 01:43:16 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 01:43:16 +0000
commit9bb9f99499ea9e60b3269c9e6053b5a3af1d51eb (patch)
tree4e0216652d20afd74e48f25c1e61c0d8662ac820 /net
parent930512c170b552b3f718ad947a05ec306ce6271d (diff)
downloadchromium_src-9bb9f99499ea9e60b3269c9e6053b5a3af1d51eb.zip
chromium_src-9bb9f99499ea9e60b3269c9e6053b5a3af1d51eb.tar.gz
chromium_src-9bb9f99499ea9e60b3269c9e6053b5a3af1d51eb.tar.bz2
Http cache: Don't attempt to revalidate entries after a vary header mismatch
if there is no etag. BUG=79758 TEST=net_unittests Review URL: https://codereview.chromium.org/11692013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176229 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_cache_transaction.cc15
-rw-r--r--net/http/http_cache_transaction.h1
-rw-r--r--net/http/http_cache_unittest.cc133
3 files changed, 142 insertions, 7 deletions
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 27792a1..624c08f 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -145,6 +145,7 @@ HttpCache::Transaction::Transaction(
handling_206_(false),
cache_pending_(false),
done_reading_(false),
+ vary_mismatch_(false),
io_buf_len_(0),
read_offset_(0),
effective_load_flags_(0),
@@ -732,7 +733,6 @@ int HttpCache::Transaction::DoGetBackendComplete(int result) {
if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) {
mode_ = READ;
} else if (effective_load_flags_ & LOAD_BYPASS_CACHE) {
- UpdateTransactionPattern(PATTERN_NOT_COVERED);
mode_ = WRITE;
} else {
mode_ = READ_WRITE;
@@ -1917,6 +1917,7 @@ bool HttpCache::Transaction::RequiresValidation() {
if (response_.vary_data.is_valid() &&
!response_.vary_data.MatchesRequest(*request_, *response_.headers)) {
+ vary_mismatch_ = true;
return true;
}
@@ -1957,14 +1958,14 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
// TODO(darin): Or should we use the last?
std::string etag_value;
- response_.headers->EnumerateHeader(NULL, "etag", &etag_value);
+ if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1))
+ response_.headers->EnumerateHeader(NULL, "etag", &etag_value);
std::string last_modified_value;
- response_.headers->EnumerateHeader(NULL, "last-modified",
- &last_modified_value);
-
- if (response_.headers->GetHttpVersion() < HttpVersion(1, 1))
- etag_value.clear();
+ if (!vary_mismatch_) {
+ response_.headers->EnumerateHeader(NULL, "last-modified",
+ &last_modified_value);
+ }
if (etag_value.empty() && last_modified_value.empty())
return false;
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index 85d485e..86e42f6 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -405,6 +405,7 @@ class HttpCache::Transaction : public HttpTransaction {
bool handling_206_; // We must deal with this 206 response.
bool cache_pending_; // We are waiting for the HttpCache.
bool done_reading_;
+ bool vary_mismatch_; // The request doesn't match the stored vary data.
scoped_refptr<IOBuffer> read_buf_;
int io_buf_len_;
int read_offset_;
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index d42ee56..51098b4 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -1712,6 +1712,139 @@ TEST(HttpCache, ETagGET_ConditionalRequest_304) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
}
+class RevalidationServer {
+ public:
+ RevalidationServer() {
+ s_etag_used_ = false;
+ s_last_modified_used_ = false;
+ }
+
+ bool EtagUsed() { return s_etag_used_; }
+ bool LastModifiedUsed() { return s_last_modified_used_; }
+
+ static void Handler(const net::HttpRequestInfo* request,
+ std::string* response_status,
+ std::string* response_headers,
+ std::string* response_data);
+
+ private:
+ static bool s_etag_used_;
+ static bool s_last_modified_used_;
+};
+bool RevalidationServer::s_etag_used_ = false;
+bool RevalidationServer::s_last_modified_used_ = false;
+
+void RevalidationServer::Handler(const net::HttpRequestInfo* request,
+ std::string* response_status,
+ std::string* response_headers,
+ std::string* response_data) {
+ if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
+ s_etag_used_ = true;
+
+ if (request->extra_headers.HasHeader(
+ net::HttpRequestHeaders::kIfModifiedSince)) {
+ s_last_modified_used_ = true;
+ }
+
+ if (s_etag_used_ || s_last_modified_used_) {
+ response_status->assign("HTTP/1.1 304 Not Modified");
+ response_headers->assign(kTypicalGET_Transaction.response_headers);
+ response_data->clear();
+ } else {
+ response_status->assign(kTypicalGET_Transaction.status);
+ response_headers->assign(kTypicalGET_Transaction.response_headers);
+ response_data->assign(kTypicalGET_Transaction.data);
+ }
+}
+
+// Tests revalidation after a vary match.
+TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
+ MockHttpCache cache;
+
+ // Write to the cache.
+ MockTransaction transaction(kTypicalGET_Transaction);
+ transaction.request_headers = "Foo: bar\n";
+ transaction.response_headers =
+ "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
+ "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
+ "Etag: \"foopy\"\n"
+ "Cache-Control: max-age=0\n"
+ "Vary: Foo\n";
+ AddMockTransaction(&transaction);
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ // Read from the cache.
+ RevalidationServer server;
+ transaction.handler = server.Handler;
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ EXPECT_TRUE(server.EtagUsed());
+ EXPECT_TRUE(server.LastModifiedUsed());
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+ RemoveMockTransaction(&transaction);
+}
+
+// Tests revalidation after a vary mismatch if etag is present.
+TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
+ MockHttpCache cache;
+
+ // Write to the cache.
+ MockTransaction transaction(kTypicalGET_Transaction);
+ transaction.request_headers = "Foo: bar\n";
+ transaction.response_headers =
+ "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
+ "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
+ "Etag: \"foopy\"\n"
+ "Cache-Control: max-age=0\n"
+ "Vary: Foo\n";
+ AddMockTransaction(&transaction);
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ // Read from the cache and revalidate the entry.
+ RevalidationServer server;
+ transaction.handler = server.Handler;
+ transaction.request_headers = "Foo: none\n";
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ EXPECT_TRUE(server.EtagUsed());
+ EXPECT_FALSE(server.LastModifiedUsed());
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+ RemoveMockTransaction(&transaction);
+}
+
+// Tests lack of revalidation after a vary mismatch and no etag.
+TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
+ MockHttpCache cache;
+
+ // Write to the cache.
+ MockTransaction transaction(kTypicalGET_Transaction);
+ transaction.request_headers = "Foo: bar\n";
+ transaction.response_headers =
+ "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
+ "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
+ "Cache-Control: max-age=0\n"
+ "Vary: Foo\n";
+ AddMockTransaction(&transaction);
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ // Read from the cache and don't revalidate the entry.
+ RevalidationServer server;
+ transaction.handler = server.Handler;
+ transaction.request_headers = "Foo: none\n";
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ EXPECT_FALSE(server.EtagUsed());
+ EXPECT_FALSE(server.LastModifiedUsed());
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+ RemoveMockTransaction(&transaction);
+}
+
static void ETagGet_UnconditionalRequest_Handler(
const net::HttpRequestInfo* request,
std::string* response_status,