| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_cache.h" | 5 #include "net/http/http_cache.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 7215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7226 } | 7226 } |
| 7227 | 7227 |
| 7228 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) { | 7228 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) { |
| 7229 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH)); | 7229 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH)); |
| 7230 AdvanceTime(kRequireValidationSecs); | 7230 AdvanceTime(kRequireValidationSecs); |
| 7231 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH)); | 7231 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH)); |
| 7232 AdvanceTime(kRequireValidationSecs); | 7232 AdvanceTime(kRequireValidationSecs); |
| 7233 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL)); | 7233 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL)); |
| 7234 } | 7234 } |
| 7235 | 7235 |
| 7236 // Framework for tests of stale-while-revalidate related functionality. With | |
| 7237 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it | |
| 7238 // will trigger the stale-while-revalidate asynchronous revalidation. Setting | |
| 7239 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause | |
| 7240 // synchronous revalidation. | |
| 7241 class HttpCacheStaleWhileRevalidateTest : public ::testing::Test { | |
| 7242 protected: | |
| 7243 HttpCacheStaleWhileRevalidateTest() | |
| 7244 : transaction_(kSimpleGET_Transaction), | |
| 7245 age_(3601), | |
| 7246 stale_while_revalidate_(7200), | |
| 7247 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") { | |
| 7248 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true); | |
| 7249 } | |
| 7250 | |
| 7251 // RunTransactionTest() with the arguments from this fixture. | |
| 7252 void RunFixtureTransactionTest() { | |
| 7253 std::string response_headers = base::StringPrintf( | |
| 7254 "%s\n" | |
| 7255 "Age: %d\n" | |
| 7256 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n", | |
| 7257 validator_.c_str(), | |
| 7258 age_, | |
| 7259 stale_while_revalidate_); | |
| 7260 transaction_.response_headers = response_headers.c_str(); | |
| 7261 RunTransactionTest(cache_.http_cache(), transaction_); | |
| 7262 transaction_.response_headers = ""; | |
| 7263 } | |
| 7264 | |
| 7265 // How many times this test has sent requests to the (fake) origin | |
| 7266 // server. Every test case needs to make at least one request to initialise | |
| 7267 // the cache. | |
| 7268 int transaction_count() { | |
| 7269 return cache_.network_layer()->transaction_count(); | |
| 7270 } | |
| 7271 | |
| 7272 // How many times an existing cache entry was opened during the test case. | |
| 7273 int open_count() { return cache_.disk_cache()->open_count(); } | |
| 7274 | |
| 7275 MockHttpCache cache_; | |
| 7276 ScopedMockTransaction transaction_; | |
| 7277 int age_; | |
| 7278 int stale_while_revalidate_; | |
| 7279 std::string validator_; | |
| 7280 }; | |
| 7281 | |
| 7282 static void CheckResourceFreshnessHeader(const HttpRequestInfo* request, | 7236 static void CheckResourceFreshnessHeader(const HttpRequestInfo* request, |
| 7283 std::string* response_status, | 7237 std::string* response_status, |
| 7284 std::string* response_headers, | 7238 std::string* response_headers, |
| 7285 std::string* response_data) { | 7239 std::string* response_data) { |
| 7286 std::string value; | 7240 std::string value; |
| 7287 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value)); | 7241 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value)); |
| 7288 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value); | 7242 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value); |
| 7289 } | 7243 } |
| 7290 | 7244 |
| 7291 // Verify that the Resource-Freshness header is sent on a revalidation if the | 7245 // Verify that the Resource-Freshness header is sent on a revalidation if the |
| 7292 // stale-while-revalidate directive was on the response. | 7246 // stale-while-revalidate directive was on the response. |
| 7293 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) { | 7247 TEST(HttpCache, ResourceFreshnessHeaderSent) { |
| 7294 age_ = 10801; // Outside the stale-while-revalidate window. | 7248 MockHttpCache cache; |
| 7249 |
| 7250 ScopedMockTransaction stale_while_revalidate_transaction( |
| 7251 kSimpleGET_Transaction); |
| 7252 stale_while_revalidate_transaction.response_headers = |
| 7253 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7254 "Age: 10801\n" |
| 7255 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n"; |
| 7295 | 7256 |
| 7296 // Write to the cache. | 7257 // Write to the cache. |
| 7297 RunFixtureTransactionTest(); | 7258 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); |
| 7298 | 7259 |
| 7299 EXPECT_EQ(1, transaction_count()); | 7260 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 7300 | 7261 |
| 7301 // Send the request again and check that Resource-Freshness header is added. | 7262 // Send the request again and check that Resource-Freshness header is added. |
| 7302 transaction_.handler = CheckResourceFreshnessHeader; | 7263 stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader; |
| 7303 | 7264 |
| 7304 RunFixtureTransactionTest(); | 7265 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); |
| 7305 | 7266 |
| 7306 EXPECT_EQ(2, transaction_count()); | 7267 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 7307 } | 7268 } |
| 7308 | 7269 |
| 7309 static void CheckResourceFreshnessAbsent(const HttpRequestInfo* request, | 7270 static void CheckResourceFreshnessAbsent(const HttpRequestInfo* request, |
| 7310 std::string* response_status, | 7271 std::string* response_status, |
| 7311 std::string* response_headers, | 7272 std::string* response_headers, |
| 7312 std::string* response_data) { | 7273 std::string* response_data) { |
| 7313 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness")); | 7274 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness")); |
| 7314 } | 7275 } |
| 7315 | 7276 |
| 7316 // Verify that the Resource-Freshness header is not sent when | 7277 // Verify that the Resource-Freshness header is not sent when |
| 7317 // stale-while-revalidate is 0. | 7278 // stale-while-revalidate is 0. |
| 7318 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) { | 7279 TEST(HttpCache, ResourceFreshnessHeaderNotSent) { |
| 7319 age_ = 10801; | 7280 MockHttpCache cache; |
| 7320 stale_while_revalidate_ = 0; | 7281 |
| 7282 ScopedMockTransaction stale_while_revalidate_transaction( |
| 7283 kSimpleGET_Transaction); |
| 7284 stale_while_revalidate_transaction.response_headers = |
| 7285 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7286 "Age: 10801\n" |
| 7287 "Cache-Control: max-age=3600,stale-while-revalidate=0\n"; |
| 7321 | 7288 |
| 7322 // Write to the cache. | 7289 // Write to the cache. |
| 7323 RunFixtureTransactionTest(); | 7290 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); |
| 7324 | 7291 |
| 7325 EXPECT_EQ(1, transaction_count()); | 7292 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 7326 | 7293 |
| 7327 // Send the request again and check that Resource-Freshness header is absent. | 7294 // Send the request again and check that Resource-Freshness header is absent. |
| 7328 transaction_.handler = CheckResourceFreshnessAbsent; | 7295 stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent; |
| 7329 | 7296 |
| 7330 RunFixtureTransactionTest(); | 7297 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); |
| 7331 | 7298 |
| 7332 EXPECT_EQ(2, transaction_count()); | 7299 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 7333 } | |
| 7334 | |
| 7335 // Verify that when stale-while-revalidate applies the response is read from | |
| 7336 // cache. | |
| 7337 TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) { | |
| 7338 // Write to the cache. | |
| 7339 RunFixtureTransactionTest(); | |
| 7340 | |
| 7341 EXPECT_EQ(0, open_count()); | |
| 7342 EXPECT_EQ(1, transaction_count()); | |
| 7343 | |
| 7344 // Read back from the cache. | |
| 7345 RunFixtureTransactionTest(); | |
| 7346 | |
| 7347 EXPECT_EQ(1, open_count()); | |
| 7348 EXPECT_EQ(1, transaction_count()); | |
| 7349 } | |
| 7350 | |
| 7351 // Verify that when stale-while-revalidate applies an asynchronous request is | |
| 7352 // sent. | |
| 7353 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) { | |
| 7354 // Write to the cache. | |
| 7355 RunFixtureTransactionTest(); | |
| 7356 | |
| 7357 EXPECT_EQ(1, transaction_count()); | |
| 7358 | |
| 7359 // Read back from the cache. | |
| 7360 RunFixtureTransactionTest(); | |
| 7361 | |
| 7362 EXPECT_EQ(1, transaction_count()); | |
| 7363 | |
| 7364 // Let the async request execute. | |
| 7365 base::RunLoop().RunUntilIdle(); | |
| 7366 EXPECT_EQ(2, transaction_count()); | |
| 7367 } | |
| 7368 | |
| 7369 // Verify that tearing down the HttpCache with an async revalidation in progress | |
| 7370 // does not break anything (this test is most likely to find problems when run | |
| 7371 // with a memory checker such as AddressSanitizer). | |
| 7372 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) { | |
| 7373 // Write to the cache. | |
| 7374 RunFixtureTransactionTest(); | |
| 7375 | |
| 7376 // Read back from the cache. | |
| 7377 RunFixtureTransactionTest(); | |
| 7378 } | |
| 7379 | |
| 7380 static void CheckIfModifiedSinceHeader(const HttpRequestInfo* request, | |
| 7381 std::string* response_status, | |
| 7382 std::string* response_headers, | |
| 7383 std::string* response_data) { | |
| 7384 std::string value; | |
| 7385 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value)); | |
| 7386 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value); | |
| 7387 } | |
| 7388 | |
| 7389 // Verify that the async revalidation contains an If-Modified-Since header. | |
| 7390 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) { | |
| 7391 // Write to the cache. | |
| 7392 RunFixtureTransactionTest(); | |
| 7393 | |
| 7394 transaction_.handler = CheckIfModifiedSinceHeader; | |
| 7395 | |
| 7396 // Read back from the cache. | |
| 7397 RunFixtureTransactionTest(); | |
| 7398 } | |
| 7399 | |
| 7400 static void CheckIfNoneMatchHeader(const HttpRequestInfo* request, | |
| 7401 std::string* response_status, | |
| 7402 std::string* response_headers, | |
| 7403 std::string* response_data) { | |
| 7404 std::string value; | |
| 7405 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value)); | |
| 7406 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value); | |
| 7407 } | |
| 7408 | |
| 7409 // If the response had ETag rather than Last-Modified, then that is used to | |
| 7410 // conditionalise the response. | |
| 7411 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) { | |
| 7412 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\""; | |
| 7413 | |
| 7414 // Write to the cache. | |
| 7415 RunFixtureTransactionTest(); | |
| 7416 | |
| 7417 transaction_.handler = CheckIfNoneMatchHeader; | |
| 7418 | |
| 7419 // Read back from the cache. | |
| 7420 RunFixtureTransactionTest(); | |
| 7421 } | |
| 7422 | |
| 7423 static void CheckResourceFreshnessHeaderPresent(const HttpRequestInfo* request, | |
| 7424 std::string* response_status, | |
| 7425 std::string* response_headers, | |
| 7426 std::string* response_data) { | |
| 7427 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness")); | |
| 7428 } | |
| 7429 | |
| 7430 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) { | |
| 7431 // Write to the cache. | |
| 7432 RunFixtureTransactionTest(); | |
| 7433 | |
| 7434 transaction_.handler = CheckResourceFreshnessHeaderPresent; | |
| 7435 | |
| 7436 // Read back from the cache. | |
| 7437 RunFixtureTransactionTest(); | |
| 7438 } | |
| 7439 | |
| 7440 // Verify that when age > max-age + stale-while-revalidate stale results are | |
| 7441 // not returned. | |
| 7442 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) { | |
| 7443 age_ = 10801; | |
| 7444 | |
| 7445 // Write to the cache. | |
| 7446 RunFixtureTransactionTest(); | |
| 7447 | |
| 7448 EXPECT_EQ(0, open_count()); | |
| 7449 EXPECT_EQ(1, transaction_count()); | |
| 7450 | |
| 7451 // Reading back reads from the network. | |
| 7452 RunFixtureTransactionTest(); | |
| 7453 | |
| 7454 EXPECT_EQ(1, open_count()); | |
| 7455 EXPECT_EQ(2, transaction_count()); | |
| 7456 } | |
| 7457 | |
| 7458 // HEAD requests should be able to take advantage of stale-while-revalidate. | |
| 7459 TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) { | |
| 7460 // Write to the cache. This has to be a GET request; HEAD requests don't | |
| 7461 // create new cache entries. | |
| 7462 RunFixtureTransactionTest(); | |
| 7463 | |
| 7464 EXPECT_EQ(0, open_count()); | |
| 7465 EXPECT_EQ(1, transaction_count()); | |
| 7466 | |
| 7467 // Read back from the cache, and trigger an asynchronous HEAD request. | |
| 7468 transaction_.method = "HEAD"; | |
| 7469 transaction_.data = ""; | |
| 7470 | |
| 7471 RunFixtureTransactionTest(); | |
| 7472 | |
| 7473 EXPECT_EQ(1, open_count()); | |
| 7474 EXPECT_EQ(1, transaction_count()); | |
| 7475 | |
| 7476 // Let the network request proceed. | |
| 7477 base::RunLoop().RunUntilIdle(); | |
| 7478 | |
| 7479 EXPECT_EQ(2, transaction_count()); | |
| 7480 } | |
| 7481 | |
| 7482 // POST requests should not use stale-while-revalidate. | |
| 7483 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) { | |
| 7484 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction); | |
| 7485 | |
| 7486 // Write to the cache. | |
| 7487 RunFixtureTransactionTest(); | |
| 7488 | |
| 7489 EXPECT_EQ(0, open_count()); | |
| 7490 EXPECT_EQ(1, transaction_count()); | |
| 7491 | |
| 7492 // Reading back reads from the network. | |
| 7493 RunFixtureTransactionTest(); | |
| 7494 | |
| 7495 EXPECT_EQ(0, open_count()); | |
| 7496 EXPECT_EQ(2, transaction_count()); | |
| 7497 } | |
| 7498 | |
| 7499 static void CheckUrlMatches(const HttpRequestInfo* request, | |
| 7500 std::string* response_status, | |
| 7501 std::string* response_headers, | |
| 7502 std::string* response_data) { | |
| 7503 EXPECT_EQ("http://www.google.com/", request->url.spec()); | |
| 7504 } | |
| 7505 | |
| 7506 // Async revalidation is issued to the original URL. | |
| 7507 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) { | |
| 7508 transaction_.url = "http://www.google.com/"; | |
| 7509 // Write to the cache. | |
| 7510 RunFixtureTransactionTest(); | |
| 7511 | |
| 7512 // Read back from the cache. | |
| 7513 RunFixtureTransactionTest(); | |
| 7514 | |
| 7515 EXPECT_EQ(1, transaction_count()); | |
| 7516 | |
| 7517 transaction_.handler = CheckUrlMatches; | |
| 7518 | |
| 7519 // Let the async request execute and perform the check. | |
| 7520 base::RunLoop().RunUntilIdle(); | |
| 7521 EXPECT_EQ(2, transaction_count()); | |
| 7522 } | |
| 7523 | |
| 7524 class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest, | |
| 7525 public ::testing::WithParamInterface<int> {}; | |
| 7526 | |
| 7527 // Flags which should always cause the request to be synchronous. | |
| 7528 TEST_P(SyncLoadFlagTest, MustBeSynchronous) { | |
| 7529 transaction_.load_flags |= GetParam(); | |
| 7530 // Write to the cache. | |
| 7531 RunFixtureTransactionTest(); | |
| 7532 | |
| 7533 EXPECT_EQ(1, transaction_count()); | |
| 7534 | |
| 7535 // Reading back reads from the network. | |
| 7536 RunFixtureTransactionTest(); | |
| 7537 | |
| 7538 EXPECT_EQ(2, transaction_count()); | |
| 7539 } | |
| 7540 | |
| 7541 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate, | |
| 7542 SyncLoadFlagTest, | |
| 7543 ::testing::Values(LOAD_VALIDATE_CACHE, | |
| 7544 LOAD_BYPASS_CACHE, | |
| 7545 LOAD_DISABLE_CACHE)); | |
| 7546 | |
| 7547 TEST_F(HttpCacheStaleWhileRevalidateTest, | |
| 7548 PreferringCacheDoesNotTriggerAsyncRequest) { | |
| 7549 transaction_.load_flags |= LOAD_PREFERRING_CACHE; | |
| 7550 // Write to the cache. | |
| 7551 RunFixtureTransactionTest(); | |
| 7552 | |
| 7553 EXPECT_EQ(1, transaction_count()); | |
| 7554 | |
| 7555 // Reading back reads from the cache. | |
| 7556 RunFixtureTransactionTest(); | |
| 7557 | |
| 7558 EXPECT_EQ(1, transaction_count()); | |
| 7559 | |
| 7560 // If there was an async transaction created, it would run now. | |
| 7561 base::RunLoop().RunUntilIdle(); | |
| 7562 | |
| 7563 // There was no async transaction. | |
| 7564 EXPECT_EQ(1, transaction_count()); | |
| 7565 } | |
| 7566 | |
| 7567 TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) { | |
| 7568 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false); | |
| 7569 // Write to the cache. | |
| 7570 RunFixtureTransactionTest(); | |
| 7571 | |
| 7572 EXPECT_EQ(1, transaction_count()); | |
| 7573 | |
| 7574 // A synchronous revalidation is performed. | |
| 7575 RunFixtureTransactionTest(); | |
| 7576 | |
| 7577 EXPECT_EQ(2, transaction_count()); | |
| 7578 } | |
| 7579 | |
| 7580 TEST_F(HttpCacheStaleWhileRevalidateTest, | |
| 7581 OnlyFromCacheDoesNotTriggerAsyncRequest) { | |
| 7582 transaction_.load_flags |= LOAD_ONLY_FROM_CACHE; | |
| 7583 transaction_.return_code = ERR_CACHE_MISS; | |
| 7584 | |
| 7585 // Writing to the cache should fail, because we are avoiding the network. | |
| 7586 RunFixtureTransactionTest(); | |
| 7587 | |
| 7588 EXPECT_EQ(0, transaction_count()); | |
| 7589 | |
| 7590 base::RunLoop().RunUntilIdle(); | |
| 7591 | |
| 7592 // Still nothing. | |
| 7593 EXPECT_EQ(0, transaction_count()); | |
| 7594 } | |
| 7595 | |
| 7596 // A certificate error during an asynchronous fetch should cause the next fetch | |
| 7597 // to proceed synchronously. | |
| 7598 // TODO(ricea): In future, only certificate errors which require user | |
| 7599 // interaction should fail the asynchronous revalidation, and they should cause | |
| 7600 // the next revalidation to be synchronous rather than requiring a total | |
| 7601 // refetch. This test will need to be updated appropriately. | |
| 7602 TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) { | |
| 7603 // Write to the cache. | |
| 7604 RunFixtureTransactionTest(); | |
| 7605 | |
| 7606 EXPECT_EQ(1, transaction_count()); | |
| 7607 | |
| 7608 // Now read back. RunTransactionTestBase() expects to receive the network | |
| 7609 // error back from the HttpCache::Transaction, but since the cache request | |
| 7610 // will return OK we need to duplicate some of its implementation here. | |
| 7611 transaction_.return_code = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | |
| 7612 TestCompletionCallback callback; | |
| 7613 scoped_ptr<HttpTransaction> trans; | |
| 7614 int rv = cache_.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans); | |
| 7615 EXPECT_EQ(OK, rv); | |
| 7616 ASSERT_TRUE(trans.get()); | |
| 7617 | |
| 7618 MockHttpRequest request(transaction_); | |
| 7619 rv = trans->Start(&request, callback.callback(), BoundNetLog()); | |
| 7620 ASSERT_EQ(ERR_IO_PENDING, rv); | |
| 7621 ASSERT_EQ(OK, callback.WaitForResult()); | |
| 7622 ReadAndVerifyTransaction(trans.get(), transaction_); | |
| 7623 | |
| 7624 EXPECT_EQ(1, transaction_count()); | |
| 7625 | |
| 7626 // Allow the asynchronous fetch to run. | |
| 7627 base::RunLoop().RunUntilIdle(); | |
| 7628 | |
| 7629 EXPECT_EQ(2, transaction_count()); | |
| 7630 | |
| 7631 // Now run the transaction again. It should run synchronously. | |
| 7632 transaction_.return_code = OK; | |
| 7633 RunFixtureTransactionTest(); | |
| 7634 | |
| 7635 EXPECT_EQ(3, transaction_count()); | |
| 7636 } | |
| 7637 | |
| 7638 // Ensure that the response cached by the asynchronous request is not truncated, | |
| 7639 // even if the server is slow. | |
| 7640 TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) { | |
| 7641 transaction_.test_mode = TEST_MODE_SLOW_READ; | |
| 7642 // Write to the cache. | |
| 7643 RunFixtureTransactionTest(); | |
| 7644 | |
| 7645 // Read back from the cache. | |
| 7646 RunFixtureTransactionTest(); | |
| 7647 | |
| 7648 // Let the async request execute. | |
| 7649 base::RunLoop().RunUntilIdle(); | |
| 7650 | |
| 7651 // The cache entry should still be complete. | |
| 7652 transaction_.load_flags = LOAD_ONLY_FROM_CACHE; | |
| 7653 RunFixtureTransactionTest(); | |
| 7654 } | |
| 7655 | |
| 7656 // Verify that there are no race conditions in the completely synchronous case. | |
| 7657 TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) { | |
| 7658 transaction_.test_mode = TEST_MODE_SYNC_ALL; | |
| 7659 // Write to the cache. | |
| 7660 RunFixtureTransactionTest(); | |
| 7661 | |
| 7662 EXPECT_EQ(1, transaction_count()); | |
| 7663 | |
| 7664 // Read back from the cache. | |
| 7665 RunFixtureTransactionTest(); | |
| 7666 | |
| 7667 EXPECT_EQ(1, transaction_count()); | |
| 7668 | |
| 7669 // Let the async request execute. | |
| 7670 base::RunLoop().RunUntilIdle(); | |
| 7671 EXPECT_EQ(2, transaction_count()); | |
| 7672 } | |
| 7673 | |
| 7674 static void CheckLoadFlagsAsyncRevalidation(const HttpRequestInfo* request, | |
| 7675 std::string* response_status, | |
| 7676 std::string* response_headers, | |
| 7677 std::string* response_data) { | |
| 7678 EXPECT_EQ(LOAD_ASYNC_REVALIDATION, request->load_flags); | |
| 7679 } | |
| 7680 | |
| 7681 // Check that the load flags on the async request are the same as the load flags | |
| 7682 // on the original request, plus LOAD_ASYNC_REVALIDATION. | |
| 7683 TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) { | |
| 7684 transaction_.load_flags = LOAD_NORMAL; | |
| 7685 // Write to the cache. | |
| 7686 RunFixtureTransactionTest(); | |
| 7687 | |
| 7688 EXPECT_EQ(1, transaction_count()); | |
| 7689 | |
| 7690 // Read back from the cache. | |
| 7691 RunFixtureTransactionTest(); | |
| 7692 | |
| 7693 EXPECT_EQ(1, transaction_count()); | |
| 7694 | |
| 7695 transaction_.handler = CheckLoadFlagsAsyncRevalidation; | |
| 7696 // Let the async request execute. | |
| 7697 base::RunLoop().RunUntilIdle(); | |
| 7698 EXPECT_EQ(2, transaction_count()); | |
| 7699 } | |
| 7700 | |
| 7701 static void SimpleMockAuthHandler(const HttpRequestInfo* request, | |
| 7702 std::string* response_status, | |
| 7703 std::string* response_headers, | |
| 7704 std::string* response_data) { | |
| 7705 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") && | |
| 7706 !request->extra_headers.HasHeader("Authorization")) { | |
| 7707 response_status->assign("HTTP/1.1 401 Unauthorized"); | |
| 7708 response_headers->assign("WWW-Authenticate: Basic realm=\"mars\"\n"); | |
| 7709 return; | |
| 7710 } | |
| 7711 response_status->assign("HTTP/1.1 200 OK"); | |
| 7712 } | |
| 7713 | |
| 7714 TEST_F(HttpCacheStaleWhileRevalidateTest, RestartForAuth) { | |
| 7715 // Write to the cache. | |
| 7716 RunFixtureTransactionTest(); | |
| 7717 | |
| 7718 EXPECT_EQ(1, transaction_count()); | |
| 7719 | |
| 7720 // Now make the transaction require auth. | |
| 7721 transaction_.request_headers = "X-Require-Mock-Auth: dummy\r\n\r\n"; | |
| 7722 transaction_.handler = SimpleMockAuthHandler; | |
| 7723 | |
| 7724 // Read back from the cache. | |
| 7725 RunFixtureTransactionTest(); | |
| 7726 | |
| 7727 EXPECT_EQ(1, transaction_count()); | |
| 7728 | |
| 7729 // Let the async request execute. | |
| 7730 base::RunLoop().RunUntilIdle(); | |
| 7731 | |
| 7732 EXPECT_EQ(2, transaction_count()); | |
| 7733 } | 7300 } |
| 7734 | 7301 |
| 7735 // Tests that we allow multiple simultaneous, non-overlapping transactions to | 7302 // Tests that we allow multiple simultaneous, non-overlapping transactions to |
| 7736 // take place on a sparse entry. | 7303 // take place on a sparse entry. |
| 7737 TEST(HttpCache, RangeGET_MultipleRequests) { | 7304 TEST(HttpCache, RangeGET_MultipleRequests) { |
| 7738 MockHttpCache cache; | 7305 MockHttpCache cache; |
| 7739 | 7306 |
| 7740 // Create a transaction for bytes 0-9. | 7307 // Create a transaction for bytes 0-9. |
| 7741 MockHttpRequest request(kRangeGET_TransactionOK); | 7308 MockHttpRequest request(kRangeGET_TransactionOK); |
| 7742 MockTransaction transaction(kRangeGET_TransactionOK); | 7309 MockTransaction transaction(kRangeGET_TransactionOK); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7801 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState()); | 7368 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState()); |
| 7802 base::MessageLoop::current()->RunUntilIdle(); | 7369 base::MessageLoop::current()->RunUntilIdle(); |
| 7803 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState()); | 7370 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState()); |
| 7804 ASSERT_TRUE(second->trans->GetResponseInfo()); | 7371 ASSERT_TRUE(second->trans->GetResponseInfo()); |
| 7805 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue( | 7372 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue( |
| 7806 "Cache-Control", "no-store")); | 7373 "Cache-Control", "no-store")); |
| 7807 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction); | 7374 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction); |
| 7808 } | 7375 } |
| 7809 | 7376 |
| 7810 } // namespace net | 7377 } // namespace net |
| OLD | NEW |