| 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,
|
|
|