summaryrefslogtreecommitdiff
path: root/chromium/net/http/http_cache_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/http/http_cache_unittest.cc')
-rw-r--r--chromium/net/http/http_cache_unittest.cc196
1 files changed, 148 insertions, 48 deletions
diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc
index 09f1f94f4a6..931e1322fc7 100644
--- a/chromium/net/http/http_cache_unittest.cc
+++ b/chromium/net/http/http_cache_unittest.cc
@@ -174,8 +174,8 @@ void DeferCallback(bool* defer) {
class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
public:
- explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
- : cache_(cache) {}
+ explicit DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)
+ : cache_(std::move(cache)) {}
DeleteCacheCompletionCallback(const DeleteCacheCompletionCallback&) = delete;
DeleteCacheCompletionCallback& operator=(
@@ -188,11 +188,11 @@ class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
private:
void OnComplete(int result) {
- delete cache_;
+ cache_.reset();
SetResult(result);
}
- raw_ptr<MockHttpCache> cache_;
+ std::unique_ptr<MockHttpCache> cache_;
};
//-----------------------------------------------------------------------------
@@ -772,7 +772,7 @@ std::string GenerateCacheKey(const std::string& url) {
using HttpCacheTest = TestWithTaskEnvironment;
class HttpCacheIOCallbackTest : public HttpCacheTest {
public:
- HttpCacheIOCallbackTest() {}
+ HttpCacheIOCallbackTest() = default;
~HttpCacheIOCallbackTest() override = default;
// HttpCache::ActiveEntry is private, doing this allows tests to use it
@@ -814,7 +814,7 @@ class HttpCacheIOCallbackTest : public HttpCacheTest {
class HttpSplitCacheKeyTest : public HttpCacheTest {
public:
- HttpSplitCacheKeyTest() {}
+ HttpSplitCacheKeyTest() = default;
~HttpSplitCacheKeyTest() override = default;
std::string ComputeCacheKey(const std::string& url_string) {
@@ -825,7 +825,7 @@ class HttpSplitCacheKeyTest : public HttpCacheTest {
request_info.method = "GET";
request_info.network_isolation_key = net::NetworkIsolationKey(site, site);
MockHttpCache cache;
- return cache.http_cache()->GenerateCacheKeyForTest(&request_info);
+ return *cache.http_cache()->GenerateCacheKeyForRequest(&request_info);
}
};
@@ -1075,6 +1075,73 @@ TEST_F(HttpCacheTest,
}
}
+// This test verifies that when the callback passed to SetConnectedCallback()
+// returns
+// `ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY`, the
+// cache entry is invalidated, and we'll retry the connection from the network.
+TEST_F(
+ HttpCacheTest,
+ SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
+ mock_transaction.transport_info = TestTransportInfo();
+
+ // Populate the cache.
+ RunTransactionTest(cache.http_cache(), mock_transaction);
+
+ MockHttpRequest request(kSimpleGET_Transaction);
+
+ {
+ // Attempt to read from cache entry, but abort transaction due to a
+ // connected callback error.
+ ConnectedHandler connected_handler;
+ connected_handler.set_result(
+ ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY);
+
+ std::unique_ptr<HttpTransaction> transaction;
+ EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
+ ASSERT_THAT(transaction, NotNull());
+
+ transaction->SetConnectedCallback(connected_handler.Callback());
+
+ TestCompletionCallback callback;
+ ASSERT_THAT(
+ transaction->Start(&request, callback.callback(), NetLogWithSource()),
+ IsError(ERR_IO_PENDING));
+ EXPECT_THAT(
+ callback.WaitForResult(),
+ IsError(
+ ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY));
+
+ // Used the cache entry only.
+ EXPECT_THAT(connected_handler.transports(),
+ ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
+ }
+
+ {
+ // Request the same resource once more, observe that it is not read from
+ // cache.
+ ConnectedHandler connected_handler;
+
+ std::unique_ptr<HttpTransaction> transaction;
+ EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
+ ASSERT_THAT(transaction, NotNull());
+
+ transaction->SetConnectedCallback(connected_handler.Callback());
+
+ TestCompletionCallback callback;
+ ASSERT_THAT(
+ transaction->Start(&request, callback.callback(), NetLogWithSource()),
+ IsError(ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsOk());
+
+ // Used the network only.
+ EXPECT_THAT(connected_handler.transports(),
+ ElementsAre(TestTransportInfo()));
+ }
+}
+
// This test verifies that the callback passed to SetConnectedCallback() is
// called with the right transport type when the cached entry was originally
// fetched via proxy.
@@ -3804,12 +3871,11 @@ TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch1) {
EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
}
- for (size_t i = 0; i < context_list.size(); i++) {
- if (context_list[i]->result == ERR_IO_PENDING)
- context_list[i]->result = context_list[i]->callback.WaitForResult();
+ for (auto& context : context_list) {
+ if (context->result == ERR_IO_PENDING)
+ context->result = context->callback.WaitForResult();
- ReadAndVerifyTransaction(context_list[i]->trans.get(),
- kSimpleGET_Transaction);
+ ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
}
EXPECT_EQ(2, cache.network_layer()->transaction_count());
@@ -5336,7 +5402,8 @@ TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelFirst) {
// Allow all requests to move from the Create queue to the active entry.
// All would have been added to writers.
base::RunLoop().RunUntilIdle();
- std::string cache_key = cache.http_cache()->GenerateCacheKeyForTest(&request);
+ std::string cache_key =
+ *cache.http_cache()->GenerateCacheKeyForRequest(&request);
EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
// The second transaction skipped validation, thus only one network
@@ -5601,8 +5668,9 @@ TEST_F(HttpCacheTest, SimpleGET_ManyWriters_DeleteCache) {
// Tests that we queue requests when initializing the backend.
TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(base::WrapUnique(factory));
+ auto factory = std::make_unique<MockBlockingBackendFactory>();
+ MockBlockingBackendFactory* factory_ptr = factory.get();
+ MockHttpCache cache(std::move(factory));
MockHttpRequest request0(kSimpleGET_Transaction);
MockHttpRequest request1(kTypicalGET_Transaction);
@@ -5632,7 +5700,7 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
// The first request should be creating the disk cache.
EXPECT_FALSE(context_list[0]->callback.have_result());
- factory->FinishCreation();
+ factory_ptr->FinishCreation();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3, cache.network_layer()->transaction_count());
@@ -5647,8 +5715,9 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
// Tests that we can cancel requests that are queued waiting for the backend
// to be initialized.
TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(base::WrapUnique(factory));
+ auto factory = std::make_unique<MockBlockingBackendFactory>();
+ MockBlockingBackendFactory* factory_ptr = factory.get();
+ MockHttpCache cache(std::move(factory));
MockHttpRequest request0(kSimpleGET_Transaction);
MockHttpRequest request1(kTypicalGET_Transaction);
@@ -5685,7 +5754,7 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
context_list[0].reset();
// Complete the last transaction.
- factory->FinishCreation();
+ factory_ptr->FinishCreation();
context_list[2]->result =
context_list[2]->callback.GetResult(context_list[2]->result);
@@ -5695,10 +5764,11 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
}
-// Tests that we can delete the cache while creating the backend.
+// Tests that we can delete the HttpCache while creating the backend.
TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) {
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- auto cache = std::make_unique<MockHttpCache>(base::WrapUnique(factory));
+ auto factory = std::make_unique<MockBlockingBackendFactory>();
+ MockBlockingBackendFactory* factory_ptr = factory.get();
+ auto cache = std::make_unique<MockHttpCache>(std::move(factory));
MockHttpRequest request(kSimpleGET_Transaction);
@@ -5714,45 +5784,43 @@ TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) {
// The request should be creating the disk cache.
EXPECT_FALSE(c->callback.have_result());
- // We cannot call FinishCreation because the factory itself will go away with
- // the cache.
- CompletionOnceCallback callback = factory->ReleaseCallback();
- std::unique_ptr<disk_cache::Backend>* backend = factory->backend();
+ // Manually arrange for completion to happen after ~HttpCache.
+ // This can't be done via FinishCreation() since that's in `factory`, and
+ // that's owned by `cache`.
+ disk_cache::BackendResultCallback callback = factory_ptr->ReleaseCallback();
cache.reset();
base::RunLoop().RunUntilIdle();
- // Even though |HttpCache| is destroyed, the Backend that was passed in to
- // disk_cache::CreateCacheBackend() must still be valid until the callback is
- // called.
- backend->reset();
- // |callback| will destroy |backend|.
- std::move(callback).Run(ERR_ABORTED);
+ // Simulate the backend completion callback running now the HttpCache is gone.
+ std::move(callback).Run(disk_cache::BackendResult::MakeError(ERR_ABORTED));
}
// Tests that we can delete the cache while creating the backend, from within
// one of the callbacks.
TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) {
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache* cache = new MockHttpCache(base::WrapUnique(factory));
+ auto factory = std::make_unique<MockBlockingBackendFactory>();
+ MockBlockingBackendFactory* factory_ptr = factory.get();
+ auto cache = std::make_unique<MockHttpCache>(std::move(factory));
+ auto* cache_ptr = cache.get();
- DeleteCacheCompletionCallback cb(cache);
+ DeleteCacheCompletionCallback cb(std::move(cache));
disk_cache::Backend* backend;
- int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
+ int rv = cache_ptr->http_cache()->GetBackend(&backend, cb.callback());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
// Now let's queue a regular transaction
MockHttpRequest request(kSimpleGET_Transaction);
auto c = std::make_unique<Context>();
- c->result = cache->CreateTransaction(&c->trans);
+ c->result = cache_ptr->CreateTransaction(&c->trans);
ASSERT_THAT(c->result, IsOk());
c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
// And another direct backend request.
TestCompletionCallback cb2;
- rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
+ rv = cache_ptr->http_cache()->GetBackend(&backend, cb2.callback());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
// Just to make sure that everything is still pending.
@@ -5762,7 +5830,7 @@ TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) {
EXPECT_FALSE(c->callback.have_result());
// Generate the callback.
- factory->FinishCreation();
+ factory_ptr->FinishCreation();
rv = cb.WaitForResult();
// The cache should be gone by now.
@@ -8309,7 +8377,8 @@ TEST_F(HttpCacheTest, Sparse_WaitForEntry) {
// Simulate a previous transaction being cancelled.
disk_cache::Entry* entry;
MockHttpRequest request(transaction);
- std::string cache_key = cache.http_cache()->GenerateCacheKeyForTest(&request);
+ std::string cache_key =
+ *cache.http_cache()->GenerateCacheKeyForRequest(&request);
ASSERT_TRUE(cache.OpenBackendEntry(cache_key, &entry));
entry->CancelSparseIO();
@@ -9737,7 +9806,8 @@ TEST_F(HttpCacheTest, PersistHttpResponseInfo) {
HttpResponseInfo response1;
response1.was_cached = false;
response1.remote_endpoint = expected_endpoint;
- response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK");
+ response1.headers =
+ base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
// Pickle.
base::Pickle pickle;
@@ -10916,7 +10986,7 @@ TEST_F(HttpCacheTest, SplitCacheWithNetworkIsolationKey) {
// Now make a request with an opaque subframe site. It shouldn't be
// cached.
trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_data);
- EXPECT_TRUE(trans_info.network_isolation_key.ToString().empty());
+ EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
trans_info, &response);
EXPECT_FALSE(response.was_cached);
@@ -11140,7 +11210,7 @@ TEST_F(HttpCacheTest, SplitCache) {
// Now make a request with an opaque top frame origin. It shouldn't be
// cached.
trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data);
- EXPECT_TRUE(trans_info.network_isolation_key.ToString().empty());
+ EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
trans_info, &response);
EXPECT_FALSE(response.was_cached);
@@ -11811,7 +11881,7 @@ HttpCacheHugeResourceTest::GetTestModes() {
for (const auto phase : kTransactionPhases)
for (const auto initializer : kInitializers)
- test_modes.push_back(std::make_pair(phase, initializer));
+ test_modes.emplace_back(phase, initializer);
return test_modes;
}
@@ -12754,7 +12824,7 @@ TEST_F(HttpCacheTest, GetResourceURLFromHttpCacheKey) {
class TestCompletionCallbackForHttpCache : public TestCompletionCallbackBase {
public:
- TestCompletionCallbackForHttpCache() {}
+ TestCompletionCallbackForHttpCache() = default;
~TestCompletionCallbackForHttpCache() override = default;
CompletionRepeatingCallback callback() {
@@ -13516,10 +13586,8 @@ class HttpCacheSingleKeyedCacheTest : public HttpCacheTest {
const MockTransaction& trans_info,
const NetworkIsolationKey& network_isolation_key,
const std::string& checksum) {
- MockTransaction transaction(trans_info);
- transaction.load_flags |= LOAD_USE_SINGLE_KEYED_CACHE;
+ ScopedMockTransaction transaction(trans_info);
- AddMockTransaction(&transaction);
MockHttpRequest request(transaction);
request.network_isolation_key = network_isolation_key;
request.checksum = checksum;
@@ -13640,6 +13708,38 @@ TEST_F(HttpCacheSingleKeyedCacheTest, GETWithBadResponseCode) {
}
}
+// This is identical to GETWithBadResponseCode but with a different response
+// code. It's not very realistic as it doesn't call DoneReading(), but it covers
+// the relevant code path.
+TEST_F(HttpCacheSingleKeyedCacheTest, RedirectUnusable) {
+ MockHttpCache cache;
+ MockTransaction transaction = kSimpleGET_Transaction;
+ transaction.status = "HTTP/1.1 301 Moved Permanently";
+ const auto site_a = SchemefulSite(GURL("https://a.com/"));
+ // The first request adds the item to the single-keyed cache.
+ {
+ RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
+ NetworkIsolationKey(site_a, site_a),
+ kChecksumForSimpleGET);
+
+ 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 second request verifies that the cache entry is not re-used
+ // but a new one is created in the split cache.
+ {
+ RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
+ NetworkIsolationKey(site_a, site_a),
+ kChecksumForSimpleGET);
+
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(2, cache.disk_cache()->create_count());
+ }
+}
+
TEST_F(HttpCacheSingleKeyedCacheTest, SuccessfulRevalidation) {
MockHttpCache cache;
MockTransaction transaction = kSimpleGET_Transaction;