Index: net/http/http_cache_unittest.cc |
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc |
index 519936829b735347b954a8506a88a24891391e0a..30720ae76f78126289421ff193d75c793af4722c 100644 |
--- a/net/http/http_cache_unittest.cc |
+++ b/net/http/http_cache_unittest.cc |
@@ -185,6 +185,12 @@ void RunTransactionTest(net::HttpCache* cache, |
RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL); |
} |
+void RunTransactionTestWithLog(net::HttpCache* cache, |
+ const MockTransaction& trans_info, |
+ const net::BoundNetLog& log) { |
+ RunTransactionTestAndGetTiming(cache, trans_info, log, NULL); |
+} |
+ |
void RunTransactionTestWithResponseInfo(net::HttpCache* cache, |
const MockTransaction& trans_info, |
net::HttpResponseInfo* response) { |
@@ -287,6 +293,10 @@ class RangeTransactionServer { |
// Returns 200 instead of 206 (a malformed response overall). |
void set_bad_200(bool value) { bad_200_ = value; } |
+ // Other than regular range related behavior (and the flags mentioned above), |
+ // the server reacts to requests headers like so: |
+ // X-Require-Mock-Auth -> return 401. |
+ // X-Return-Default-Range -> assume 40-49 was requested. |
static void RangeHandler(const net::HttpRequestInfo* request, |
std::string* response_status, |
std::string* response_headers, |
@@ -356,6 +366,12 @@ void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, |
// We can handle this range request. |
net::HttpByteRange byte_range = ranges[0]; |
+ |
+ if (request->extra_headers.HasHeader("X-Return-Default-Range")) { |
+ byte_range.set_first_byte_position(40); |
+ byte_range.set_last_byte_position(49); |
+ } |
+ |
if (byte_range.first_byte_position() > 79) { |
response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); |
response_data->clear(); |
@@ -420,6 +436,10 @@ const MockTransaction kRangeGET_TransactionOK = { |
net::OK |
}; |
+const char kFullRangeData[] = |
+ "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 " |
+ "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ |
// Verifies the response headers (|response|) match a partial content |
// response for the range starting at |start| and ending at |end|. |
void Verify206Response(std::string response, int start, int end) { |
@@ -534,6 +554,17 @@ void FilterLogEntries(net::CapturingNetLog::CapturedEntryList* entries) { |
entries->end()); |
} |
+bool LogContainsEventType(const net::CapturingBoundNetLog& log, |
+ net::NetLog::EventType expected) { |
+ net::CapturingNetLog::CapturedEntryList entries; |
+ log.GetEntries(&entries); |
+ for (size_t i = 0; i < entries.size(); i++) { |
+ if (entries[i].type == expected) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
} // namespace |
@@ -3627,6 +3658,52 @@ TEST(HttpCache, RangeGET_SkipsCache2) { |
EXPECT_EQ(0, cache.disk_cache()->create_count()); |
} |
+TEST(HttpCache, SimpleGET_DoesntLogHeaders) { |
+ MockHttpCache cache; |
+ |
+ net::CapturingBoundNetLog log; |
+ RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction, |
+ log.bound()); |
+ |
+ EXPECT_FALSE(LogContainsEventType( |
+ log, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS)); |
+} |
+ |
+TEST(HttpCache, RangeGET_LogsHeaders) { |
+ MockHttpCache cache; |
+ |
+ net::CapturingBoundNetLog log; |
+ RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction, |
+ log.bound()); |
+ |
+ EXPECT_TRUE(LogContainsEventType( |
+ log, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS)); |
+} |
+ |
+TEST(HttpCache, ExternalValidation_LogsHeaders) { |
+ MockHttpCache cache; |
+ |
+ net::CapturingBoundNetLog log; |
+ MockTransaction transaction(kSimpleGET_Transaction); |
+ transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER; |
+ RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound()); |
+ |
+ EXPECT_TRUE(LogContainsEventType( |
+ log, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS)); |
+} |
+ |
+TEST(HttpCache, SpecialHeaders_LogsHeaders) { |
+ MockHttpCache cache; |
+ |
+ net::CapturingBoundNetLog log; |
+ MockTransaction transaction(kSimpleGET_Transaction); |
+ transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER; |
+ RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound()); |
+ |
+ EXPECT_TRUE(LogContainsEventType( |
+ log, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS)); |
+} |
+ |
// Tests that receiving 206 for a regular request is handled correctly. |
TEST(HttpCache, GET_Crazy206) { |
MockHttpCache cache; |
@@ -3668,15 +3745,13 @@ TEST(HttpCache, GET_Crazy416) { |
RemoveMockTransaction(&transaction); |
} |
-// Tests that we store partial responses that can't be validated, as they can |
-// be used for requests that don't require revalidation. |
+// Tests that we don't store partial responses that can't be validated. |
TEST(HttpCache, RangeGET_NoStrongValidators) { |
MockHttpCache cache; |
std::string headers; |
- // Write to the cache (40-49). |
- MockTransaction transaction(kRangeGET_TransactionOK); |
- AddMockTransaction(&transaction); |
+ // Attempt to write to the cache (40-49). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
transaction.response_headers = "Content-Length: 10\n" |
"Cache-Control: max-age=3600\n" |
"ETag: w/\"foo\"\n"; |
@@ -3687,29 +3762,75 @@ TEST(HttpCache, RangeGET_NoStrongValidators) { |
EXPECT_EQ(0, cache.disk_cache()->open_count()); |
EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- // Now verify that there's cached data. |
+ // Now verify that there's no cached data. |
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, |
&headers); |
Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests failures to conditionalize byte range requests. |
+TEST(HttpCache, RangeGET_NoConditionalization) { |
+ MockHttpCache cache; |
+ cache.FailConditionalizations(); |
+ std::string headers; |
+ |
+ // Write to the cache (40-49). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.response_headers = "Content-Length: 10\n" |
+ "ETag: \"foo\"\n"; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 40, 49); |
EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
- EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- RemoveMockTransaction(&transaction); |
+ // Now verify that the cached data is not used. |
+ RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, |
+ &headers); |
+ |
+ Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that restarting a partial request when the cached data cannot be |
+// revalidated logs an event. |
+TEST(HttpCache, RangeGET_NoValidation_LogsRestart) { |
+ MockHttpCache cache; |
+ cache.FailConditionalizations(); |
+ |
+ // Write to the cache (40-49). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.response_headers = "Content-Length: 10\n" |
+ "ETag: \"foo\"\n"; |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ |
+ // Now verify that the cached data is not used. |
+ net::CapturingBoundNetLog log; |
+ RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK, |
+ log.bound()); |
+ |
+ EXPECT_TRUE(LogContainsEventType( |
+ log, net::NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST)); |
} |
-// Tests failures to validate cache partial responses that lack strong |
-// validators. |
-TEST(HttpCache, RangeGET_NoValidation) { |
+// Tests that a failure to conditionalize a regular request (no range) with a |
+// sparse entry results in a full response. |
+TEST(HttpCache, GET_NoConditionalization) { |
MockHttpCache cache; |
+ cache.FailConditionalizations(); |
std::string headers; |
// Write to the cache (40-49). |
- MockTransaction transaction(kRangeGET_TransactionOK); |
- AddMockTransaction(&transaction); |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
transaction.response_headers = "Content-Length: 10\n" |
- "ETag: w/\"foo\"\n"; |
+ "ETag: \"foo\"\n"; |
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
Verify206Response(headers, 40, 49); |
@@ -3718,15 +3839,63 @@ TEST(HttpCache, RangeGET_NoValidation) { |
EXPECT_EQ(1, cache.disk_cache()->create_count()); |
// Now verify that the cached data is not used. |
- RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, |
- &headers); |
+ // Don't ask for a range. The cache will attempt to use the cached data but |
+ // should discard it as it cannot be validated. A regular request should go |
+ // to the server and a new entry should be created. |
+ transaction.request_headers = EXTRA_HEADER; |
+ transaction.data = "Not a range"; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+ |
+ // The last response was saved. |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Verifies that conditionalization failures when asking for a range that would |
+// require the cache to modify the range to ask, result in a network request |
+// that matches the user's one. |
+TEST(HttpCache, RangeGET_NoConditionalization2) { |
+ MockHttpCache cache; |
+ cache.FailConditionalizations(); |
+ std::string headers; |
+ |
+ // Write to the cache (40-49). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.response_headers = "Content-Length: 10\n" |
+ "ETag: \"foo\"\n"; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // Now verify that the cached data is not used. |
+ // Ask for a range that extends before and after the cached data so that the |
+ // cache would normally mix data from three sources. After deleting the entry, |
+ // the response will come from a single network request. |
+ transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; |
+ transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; |
+ transaction.response_headers = kRangeGET_TransactionOK.response_headers; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 20, 59); |
EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
EXPECT_EQ(1, cache.disk_cache()->open_count()); |
EXPECT_EQ(2, cache.disk_cache()->create_count()); |
- RemoveMockTransaction(&transaction); |
+ // The last response was saved. |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
} |
// Tests that we cache partial responses that lack content-length. |
@@ -3820,78 +3989,6 @@ TEST(HttpCache, RangeGET_OK) { |
RemoveMockTransaction(&kRangeGET_TransactionOK); |
} |
-// Checks that with a cache backend having Sparse IO unimplementes the cache |
-// entry would be doomed after a range request. |
-// TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO. |
-TEST(HttpCache, RangeGET_SparseNotImplemented) { |
- MockHttpCache cache; |
- cache.disk_cache()->set_fail_sparse_requests(); |
- |
- // Run a cacheable request to prime the cache. |
- MockTransaction transaction(kTypicalGET_Transaction); |
- transaction.url = kRangeGET_TransactionOK.url; |
- AddMockTransaction(&transaction); |
- RunTransactionTest(cache.http_cache(), transaction); |
- EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
- EXPECT_EQ(0, cache.disk_cache()->open_count()); |
- EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- |
- // Verify that we added the entry. |
- disk_cache::Entry* entry; |
- net::TestCompletionCallback cb; |
- int rv = cache.disk_cache()->OpenEntry(transaction.url, |
- &entry, |
- cb.callback()); |
- ASSERT_EQ(net::OK, cb.GetResult(rv)); |
- EXPECT_EQ(1, cache.disk_cache()->open_count()); |
- entry->Close(); |
- RemoveMockTransaction(&transaction); |
- |
- // Request the range with the backend that does not support it. |
- MockTransaction transaction2(kRangeGET_TransactionOK); |
- std::string headers; |
- AddMockTransaction(&transaction2); |
- RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); |
- EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
- EXPECT_EQ(2, cache.disk_cache()->open_count()); |
- EXPECT_EQ(2, cache.disk_cache()->create_count()); |
- |
- // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even |
- // if it was re-created later, so this effectively checks that the old data is |
- // gone. |
- disk_cache::Entry* entry2; |
- rv = cache.disk_cache()->OpenEntry(transaction2.url, |
- &entry2, |
- cb.callback()); |
- ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv)); |
- RemoveMockTransaction(&transaction2); |
-} |
- |
-TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) { |
- MockHttpCache cache; |
- cache.disk_cache()->set_fail_sparse_requests(); |
- |
- // Request the range with the backend that does not support it. |
- MockTransaction transaction(kRangeGET_TransactionOK); |
- std::string headers; |
- AddMockTransaction(&transaction); |
- RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
- EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
- EXPECT_EQ(0, cache.disk_cache()->open_count()); |
- EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- |
- // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even |
- // if it was re-created later, so this effectively checks that the old data is |
- // gone as a result of a failed range write. |
- disk_cache::Entry* entry; |
- net::TestCompletionCallback cb; |
- int rv = cache.disk_cache()->OpenEntry(transaction.url, |
- &entry, |
- cb.callback()); |
- ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv)); |
- RemoveMockTransaction(&transaction); |
-} |
- |
// Tests that we can cache range requests and fetch random blocks from the |
// cache and the network, with synchronous responses. |
TEST(HttpCache, RangeGET_SyncOK) { |
@@ -4099,6 +4196,251 @@ TEST(HttpCache, RangeGET_ModifiedResult) { |
RemoveMockTransaction(&kRangeGET_TransactionOK); |
} |
+// Tests that when a server returns 206 with a sub-range of the requested range, |
+// and there is nothing stored in the cache, the returned response is passed to |
+// the caller as is. In this context, a subrange means a response that starts |
+// with the same byte that was requested, but that is not the whole range that |
+// was requested. |
+TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_NoCachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Request a large range (40-59). The server sends 40-49. |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER; |
+ transaction.response_headers = |
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
+ "ETag: \"foo\"\n" |
+ "Accept-Ranges: bytes\n" |
+ "Content-Length: 10\n" |
+ "Content-Range: bytes 40-49/80\n"; |
+ transaction.handler = nullptr; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that when a server returns 206 with a sub-range of the requested range, |
+// and there was an entry stored in the cache, the cache gets out of the way. |
+TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_CachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Write to the cache (70-79). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; |
+ transaction.data = "rg: 70-79 "; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ Verify206Response(headers, 70, 79); |
+ |
+ // Request a large range (40-79). The cache will ask the server for 40-59. |
+ // The server returns 40-49. The cache should consider the server confused and |
+ // abort caching, restarting the request without caching. |
+ transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER; |
+ transaction.response_headers = |
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
+ "ETag: \"foo\"\n" |
+ "Accept-Ranges: bytes\n" |
+ "Content-Length: 10\n" |
+ "Content-Range: bytes 40-49/80\n"; |
+ transaction.handler = nullptr; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ // Two new network requests were issued, one from the cache and another after |
+ // deleting the entry. |
+ Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // The entry was deleted. |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(4, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that when a server returns 206 with a sub-range of the requested range, |
+// and there was an entry stored in the cache, the cache gets out of the way, |
+// when the caller is not using ranges. |
+TEST(HttpCache, GET_206ReturnsSubrangeRange_CachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Write to the cache (70-79). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; |
+ transaction.data = "rg: 70-79 "; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ Verify206Response(headers, 70, 79); |
+ |
+ // Don't ask for a range. The cache will ask the server for 0-69. |
+ // The server returns 40-49. The cache should consider the server confused and |
+ // abort caching, restarting the request. |
+ // The second network request should not be a byte range request so the server |
+ // should return 200 + "Not a range" |
+ transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER; |
+ transaction.data = "Not a range"; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
+ EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // The entry was deleted. |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(4, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that when a server returns 206 with a random range and there is |
+// nothing stored in the cache, the returned response is passed to the caller |
+// as is. In this context, a WrongRange means that the returned range may or may |
+// not have any relationship with the requested range (may or may not be |
+// contained). The important part is that the first byte doesn't match the first |
+// requested byte. |
+TEST(HttpCache, RangeGET_206ReturnsWrongRange_NoCachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Request a large range (30-59). The server sends (40-49). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER; |
+ transaction.response_headers = |
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
+ "ETag: \"foo\"\n" |
+ "Accept-Ranges: bytes\n" |
+ "Content-Length: 10\n" |
+ "Content-Range: bytes 40-49/80\n"; |
+ transaction.handler = nullptr; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // The entry was deleted. |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that when a server returns 206 with a random range and there is |
+// an entry stored in the cache, the cache gets out of the way. |
+TEST(HttpCache, RangeGET_206ReturnsWrongRange_CachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Write to the cache (70-79). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; |
+ transaction.data = "rg: 70-79 "; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ Verify206Response(headers, 70, 79); |
+ |
+ // Request a large range (30-79). The cache will ask the server for 30-69. |
+ // The server returns 40-49. The cache should consider the server confused and |
+ // abort caching, returning the weird range to the caller. |
+ transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER; |
+ transaction.response_headers = |
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
+ "ETag: \"foo\"\n" |
+ "Accept-Ranges: bytes\n" |
+ "Content-Length: 10\n" |
+ "Content-Range: bytes 40-49/80\n"; |
+ transaction.handler = nullptr; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 40, 49); |
+ EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // The entry was deleted. |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(4, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that when a caller asks for a range beyond EOF, with an empty cache, |
+// the response matches the one provided by the server. |
+TEST(HttpCache, RangeGET_206ReturnsSmallerFile_NoCachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Request a large range (70-99). The server sends 70-79. |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER; |
+ transaction.data = "rg: 70-79 "; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 70, 79); |
+ EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+} |
+ |
+// Tests that when a caller asks for a range beyond EOF, with a cached entry, |
+// the cache automatically fixes the request. |
+TEST(HttpCache, RangeGET_206ReturnsSmallerFile_CachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Write to the cache (40-49). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ // Request a large range (70-99). The server sends 70-79. |
+ transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER; |
+ transaction.data = "rg: 70-79 "; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ Verify206Response(headers, 70, 79); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // The entry was not deleted (the range was automatically fixed). |
+ RunTransactionTest(cache.http_cache(), transaction); |
+ EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+} |
+ |
+// Tests that when a caller asks for a not-satisfiable range, the server's |
+// response is forwarded to the caller. |
+TEST(HttpCache, RangeGET_416_NoCachedContent) { |
+ MockHttpCache cache; |
+ std::string headers; |
+ |
+ // Request a range beyond EOF (80-99). |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
+ transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER; |
+ transaction.data = ""; |
+ transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable"; |
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
+ |
+ EXPECT_EQ(0U, headers.find(transaction.status)); |
+ EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
+ EXPECT_EQ(0, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(1, cache.disk_cache()->create_count()); |
+ |
+ // The entry was deleted. |
+ RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
+} |
+ |
// Tests that we cache 301s for range requests. |
TEST(HttpCache, RangeGET_301) { |
MockHttpCache cache; |
@@ -4107,7 +4449,6 @@ TEST(HttpCache, RangeGET_301) { |
transaction.response_headers = "Location: http://www.bar.com/\n"; |
transaction.data = ""; |
transaction.handler = NULL; |
- AddMockTransaction(&transaction); |
// Write to the cache. |
RunTransactionTest(cache.http_cache(), transaction); |
@@ -4120,8 +4461,6 @@ TEST(HttpCache, RangeGET_301) { |
EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
EXPECT_EQ(1, cache.disk_cache()->open_count()); |
EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- |
- RemoveMockTransaction(&transaction); |
} |
// Tests that we can cache range requests when the start or end is unknown. |
@@ -4248,8 +4587,7 @@ TEST(HttpCache, GET_Previous206) { |
// Write and read from the cache (0-79), when not asked for a range. |
MockTransaction transaction(kRangeGET_TransactionOK); |
transaction.request_headers = EXTRA_HEADER; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
RunTransactionTestWithResponseAndGetTiming( |
cache.http_cache(), transaction, &headers, log.bound(), |
&load_timing_info); |
@@ -4299,8 +4637,7 @@ TEST(HttpCache, GET_Previous206_NotModified) { |
// Read from the cache (0-9), write and read from cache (10 - 79). |
transaction.load_flags |= net::LOAD_VALIDATE_CACHE; |
transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
RunTransactionTestWithResponseAndGetTiming( |
cache.http_cache(), transaction, &headers, log.bound(), |
&load_timing_info); |
@@ -4500,8 +4837,7 @@ TEST(HttpCache, RangeGET_Previous200) { |
// Store the whole thing with status 200. |
MockTransaction transaction(kTypicalGET_Transaction); |
transaction.url = kRangeGET_TransactionOK.url; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
AddMockTransaction(&transaction); |
RunTransactionTest(cache.http_cache(), transaction); |
EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
@@ -4834,7 +5170,7 @@ TEST(HttpCache, RangeGET_InvalidResponse2) { |
} |
// Tests that if a server tells us conflicting information about a resource we |
-// ignore the response. |
+// drop the entry. |
TEST(HttpCache, RangeGET_InvalidResponse3) { |
MockHttpCache cache; |
std::string headers; |
@@ -4866,17 +5202,10 @@ TEST(HttpCache, RangeGET_InvalidResponse3) { |
EXPECT_EQ(1, cache.disk_cache()->open_count()); |
EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- // Verify that we cached the first response but not the second one. |
- disk_cache::Entry* en; |
- ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en)); |
- |
- int64 cached_start = 0; |
- net::TestCompletionCallback cb; |
- int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback()); |
- EXPECT_EQ(10, cb.GetResult(rv)); |
- EXPECT_EQ(50, cached_start); |
- en->Close(); |
- |
+ // Verify that the entry is gone. |
+ RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
+ EXPECT_EQ(1, cache.disk_cache()->open_count()); |
+ EXPECT_EQ(2, cache.disk_cache()->create_count()); |
RemoveMockTransaction(&kRangeGET_TransactionOK); |
} |
@@ -4954,11 +5283,10 @@ TEST(HttpCache, RangeHEAD) { |
TEST(HttpCache, RangeGET_FastFlakyServer) { |
MockHttpCache cache; |
- MockTransaction transaction(kRangeGET_TransactionOK); |
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; |
transaction.test_mode = TEST_MODE_SYNC_NET_START; |
transaction.load_flags |= net::LOAD_VALIDATE_CACHE; |
- AddMockTransaction(&transaction); |
// Write to the cache. |
RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
@@ -4967,13 +5295,14 @@ TEST(HttpCache, RangeGET_FastFlakyServer) { |
RangeTransactionServer handler; |
handler.set_bad_200(true); |
transaction.data = "Not a range"; |
- RunTransactionTest(cache.http_cache(), transaction); |
+ net::CapturingBoundNetLog log; |
+ RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound()); |
EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
EXPECT_EQ(1, cache.disk_cache()->open_count()); |
EXPECT_EQ(1, cache.disk_cache()->create_count()); |
- |
- RemoveMockTransaction(&transaction); |
+ EXPECT_TRUE(LogContainsEventType( |
+ log, net::NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST)); |
} |
// Tests that when the server gives us less data than expected, we don't keep |
@@ -5334,8 +5663,7 @@ TEST(HttpCache, GET_IncompleteResource) { |
std::string headers; |
MockTransaction transaction(kRangeGET_TransactionOK); |
transaction.request_headers = EXTRA_HEADER; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
// We update the headers with the ones received while revalidating. |
@@ -5383,8 +5711,7 @@ TEST(HttpCache, GET_IncompleteResource_NoStore) { |
std::string response_headers(transaction.response_headers); |
response_headers += ("Cache-Control: no-store\n"); |
transaction.response_headers = response_headers.c_str(); |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
AddMockTransaction(&transaction); |
std::string headers; |
@@ -5429,8 +5756,7 @@ TEST(HttpCache, GET_IncompleteResource_Cancel) { |
std::string response_headers(transaction.response_headers); |
response_headers += ("Cache-Control: no-store\n"); |
transaction.response_headers = response_headers.c_str(); |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
AddMockTransaction(&transaction); |
MockHttpRequest request(transaction); |
@@ -5524,8 +5850,7 @@ TEST(HttpCache, GET_IncompleteResource3) { |
std::string headers; |
MockTransaction transaction(kRangeGET_TransactionOK); |
transaction.request_headers = EXTRA_HEADER; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
scoped_ptr<Context> c(new Context); |
int rv = cache.CreateTransaction(&c->trans); |
@@ -5559,8 +5884,7 @@ TEST(HttpCache, GET_IncompleteResourceWithAuth) { |
MockTransaction transaction(kRangeGET_TransactionOK); |
transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n" |
EXTRA_HEADER; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
RangeTransactionServer handler; |
scoped_ptr<Context> c(new Context); |
@@ -6650,8 +6974,7 @@ TEST(HttpCache, SetPriorityNewTransaction) { |
std::string headers; |
MockTransaction transaction(kRangeGET_TransactionOK); |
transaction.request_headers = EXTRA_HEADER; |
- transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
- "rg: 50-59 rg: 60-69 rg: 70-79 "; |
+ transaction.data = kFullRangeData; |
scoped_ptr<net::HttpTransaction> trans; |
ASSERT_EQ(net::OK, |