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