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" |
11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/run_loop.h" |
13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "net/base/cache_type.h" | 16 #include "net/base/cache_type.h" |
16 #include "net/base/host_port_pair.h" | 17 #include "net/base/host_port_pair.h" |
17 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
18 #include "net/base/load_timing_info.h" | 19 #include "net/base/load_timing_info.h" |
19 #include "net/base/load_timing_info_test_util.h" | 20 #include "net/base/load_timing_info_test_util.h" |
20 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
21 #include "net/base/net_log_unittest.h" | 22 #include "net/base/net_log_unittest.h" |
22 #include "net/base/upload_bytes_element_reader.h" | 23 #include "net/base/upload_bytes_element_reader.h" |
(...skipping 6727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6750 | 6751 |
6751 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache. | 6752 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache. |
6752 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; | 6753 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; |
6753 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; | 6754 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; |
6754 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); | 6755 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); |
6755 EXPECT_EQ(range_response_size * 2, received_bytes); | 6756 EXPECT_EQ(range_response_size * 2, received_bytes); |
6756 | 6757 |
6757 RemoveMockTransaction(&kRangeGET_TransactionOK); | 6758 RemoveMockTransaction(&kRangeGET_TransactionOK); |
6758 } | 6759 } |
6759 | 6760 |
| 6761 // Framework for tests of stale-while-revalidate related functionality. With |
| 6762 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it |
| 6763 // will trigger the stale-while-revalidate asynchronous revalidation. Setting |
| 6764 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause |
| 6765 // synchronous revalidation. |
| 6766 class HttpCacheStaleWhileRevalidateTest : public ::testing::Test { |
| 6767 protected: |
| 6768 HttpCacheStaleWhileRevalidateTest() |
| 6769 : transaction_(kSimpleGET_Transaction), |
| 6770 age_(3601), |
| 6771 stale_while_revalidate_(7200), |
| 6772 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") { |
| 6773 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true); |
| 6774 } |
| 6775 |
| 6776 // RunTransactionTest() with the arguments from this fixture. |
| 6777 void RunFixtureTransactionTest() { |
| 6778 std::string response_headers = base::StringPrintf( |
| 6779 "%s\n" |
| 6780 "Age: %d\n" |
| 6781 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n", |
| 6782 validator_.c_str(), |
| 6783 age_, |
| 6784 stale_while_revalidate_); |
| 6785 transaction_.response_headers = response_headers.c_str(); |
| 6786 RunTransactionTest(cache_.http_cache(), transaction_); |
| 6787 transaction_.response_headers = ""; |
| 6788 } |
| 6789 |
| 6790 // How many times this test has sent requests to the (fake) origin |
| 6791 // server. Every test case needs to make at least one request to initialise |
| 6792 // the cache. |
| 6793 int transaction_count() { |
| 6794 return cache_.network_layer()->transaction_count(); |
| 6795 } |
| 6796 |
| 6797 // How many times an existing cache entry was opened during the test case. |
| 6798 int open_count() { return cache_.disk_cache()->open_count(); } |
| 6799 |
| 6800 MockHttpCache cache_; |
| 6801 ScopedMockTransaction transaction_; |
| 6802 int age_; |
| 6803 int stale_while_revalidate_; |
| 6804 std::string validator_; |
| 6805 }; |
| 6806 |
6760 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request, | 6807 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request, |
6761 std::string* response_status, | 6808 std::string* response_status, |
6762 std::string* response_headers, | 6809 std::string* response_headers, |
6763 std::string* response_data) { | 6810 std::string* response_data) { |
6764 std::string value; | 6811 std::string value; |
6765 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value)); | 6812 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value)); |
6766 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value); | 6813 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value); |
6767 } | 6814 } |
6768 | 6815 |
6769 // Verify that the Resource-Freshness header is sent on a revalidation if the | 6816 // Verify that the Resource-Freshness header is sent on a revalidation if the |
6770 // stale-while-revalidate directive was on the response. | 6817 // stale-while-revalidate directive was on the response. |
6771 TEST(HttpCache, ResourceFreshnessHeaderSent) { | 6818 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) { |
6772 MockHttpCache cache; | 6819 age_ = 10801; // Outside the stale-while-revalidate window. |
6773 | |
6774 ScopedMockTransaction stale_while_revalidate_transaction( | |
6775 kSimpleGET_Transaction); | |
6776 stale_while_revalidate_transaction.response_headers = | |
6777 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
6778 "Age: 10801\n" | |
6779 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n"; | |
6780 | 6820 |
6781 // Write to the cache. | 6821 // Write to the cache. |
6782 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | 6822 RunFixtureTransactionTest(); |
6783 | 6823 |
6784 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6824 EXPECT_EQ(1, transaction_count()); |
6785 | 6825 |
6786 // Send the request again and check that Resource-Freshness header is added. | 6826 // Send the request again and check that Resource-Freshness header is added. |
6787 stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader; | 6827 transaction_.handler = CheckResourceFreshnessHeader; |
6788 | 6828 |
6789 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | 6829 RunFixtureTransactionTest(); |
6790 | 6830 |
6791 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6831 EXPECT_EQ(2, transaction_count()); |
6792 } | 6832 } |
6793 | 6833 |
6794 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request, | 6834 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request, |
6795 std::string* response_status, | 6835 std::string* response_status, |
6796 std::string* response_headers, | 6836 std::string* response_headers, |
6797 std::string* response_data) { | 6837 std::string* response_data) { |
6798 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness")); | 6838 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness")); |
6799 } | 6839 } |
6800 | 6840 |
6801 // Verify that the Resource-Freshness header is not sent when | 6841 // Verify that the Resource-Freshness header is not sent when |
6802 // stale-while-revalidate is 0. | 6842 // stale-while-revalidate is 0. |
6803 TEST(HttpCache, ResourceFreshnessHeaderNotSent) { | 6843 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) { |
6804 MockHttpCache cache; | 6844 age_ = 10801; |
6805 | 6845 stale_while_revalidate_ = 0; |
6806 ScopedMockTransaction stale_while_revalidate_transaction( | 6846 |
6807 kSimpleGET_Transaction); | 6847 // Write to the cache. |
6808 stale_while_revalidate_transaction.response_headers = | 6848 RunFixtureTransactionTest(); |
6809 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 6849 |
6810 "Age: 10801\n" | 6850 EXPECT_EQ(1, transaction_count()); |
6811 "Cache-Control: max-age=3600,stale-while-revalidate=0\n"; | |
6812 | |
6813 // Write to the cache. | |
6814 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | |
6815 | |
6816 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | |
6817 | 6851 |
6818 // Send the request again and check that Resource-Freshness header is absent. | 6852 // Send the request again and check that Resource-Freshness header is absent. |
6819 stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent; | 6853 transaction_.handler = CheckResourceFreshnessAbsent; |
6820 | 6854 |
6821 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | 6855 RunFixtureTransactionTest(); |
6822 | 6856 |
6823 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6857 EXPECT_EQ(2, transaction_count()); |
| 6858 } |
| 6859 |
| 6860 // Verify that when stale-while-revalidate applies the response is read from |
| 6861 // cache. |
| 6862 TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) { |
| 6863 // Write to the cache. |
| 6864 RunFixtureTransactionTest(); |
| 6865 |
| 6866 EXPECT_EQ(0, open_count()); |
| 6867 EXPECT_EQ(1, transaction_count()); |
| 6868 |
| 6869 // Read back from the cache. |
| 6870 RunFixtureTransactionTest(); |
| 6871 |
| 6872 EXPECT_EQ(1, open_count()); |
| 6873 EXPECT_EQ(1, transaction_count()); |
| 6874 } |
| 6875 |
| 6876 // Verify that when stale-while-revalidate applies an asynchronous request is |
| 6877 // sent. |
| 6878 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) { |
| 6879 // Write to the cache. |
| 6880 RunFixtureTransactionTest(); |
| 6881 |
| 6882 EXPECT_EQ(1, transaction_count()); |
| 6883 |
| 6884 // Read back from the cache. |
| 6885 RunFixtureTransactionTest(); |
| 6886 |
| 6887 EXPECT_EQ(1, transaction_count()); |
| 6888 |
| 6889 // Let the async request execute. |
| 6890 base::RunLoop().RunUntilIdle(); |
| 6891 EXPECT_EQ(2, transaction_count()); |
| 6892 } |
| 6893 |
| 6894 // Verify that tearing down the HttpCache with an async revalidation in progress |
| 6895 // does not break anything (this test is most likely to find problems when run |
| 6896 // with a memory checker such as AddressSanitizer). |
| 6897 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) { |
| 6898 // Write to the cache. |
| 6899 RunFixtureTransactionTest(); |
| 6900 |
| 6901 // Read back from the cache. |
| 6902 RunFixtureTransactionTest(); |
| 6903 } |
| 6904 |
| 6905 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo* request, |
| 6906 std::string* response_status, |
| 6907 std::string* response_headers, |
| 6908 std::string* response_data) { |
| 6909 std::string value; |
| 6910 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value)); |
| 6911 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value); |
| 6912 } |
| 6913 |
| 6914 // Verify that the async revalidation contains an If-Modified-Since header. |
| 6915 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) { |
| 6916 // Write to the cache. |
| 6917 RunFixtureTransactionTest(); |
| 6918 |
| 6919 transaction_.handler = CheckIfModifiedSinceHeader; |
| 6920 |
| 6921 // Read back from the cache. |
| 6922 RunFixtureTransactionTest(); |
| 6923 } |
| 6924 |
| 6925 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo* request, |
| 6926 std::string* response_status, |
| 6927 std::string* response_headers, |
| 6928 std::string* response_data) { |
| 6929 std::string value; |
| 6930 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value)); |
| 6931 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value); |
| 6932 } |
| 6933 |
| 6934 // If the response had ETag rather than Last-Modified, then that is used to |
| 6935 // conditionalise the response. |
| 6936 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) { |
| 6937 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\""; |
| 6938 |
| 6939 // Write to the cache. |
| 6940 RunFixtureTransactionTest(); |
| 6941 |
| 6942 transaction_.handler = CheckIfNoneMatchHeader; |
| 6943 |
| 6944 // Read back from the cache. |
| 6945 RunFixtureTransactionTest(); |
| 6946 } |
| 6947 |
| 6948 static void CheckResourceFreshnessHeaderPresent( |
| 6949 const net::HttpRequestInfo* request, |
| 6950 std::string* response_status, |
| 6951 std::string* response_headers, |
| 6952 std::string* response_data) { |
| 6953 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness")); |
| 6954 } |
| 6955 |
| 6956 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) { |
| 6957 // Write to the cache. |
| 6958 RunFixtureTransactionTest(); |
| 6959 |
| 6960 transaction_.handler = CheckResourceFreshnessHeaderPresent; |
| 6961 |
| 6962 // Read back from the cache. |
| 6963 RunFixtureTransactionTest(); |
| 6964 } |
| 6965 |
| 6966 // Verify that when age > max-age + stale-while-revalidate stale results are |
| 6967 // not returned. |
| 6968 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) { |
| 6969 age_ = 10801; |
| 6970 |
| 6971 // Write to the cache. |
| 6972 RunFixtureTransactionTest(); |
| 6973 |
| 6974 EXPECT_EQ(0, open_count()); |
| 6975 EXPECT_EQ(1, transaction_count()); |
| 6976 |
| 6977 // Reading back reads from the network. |
| 6978 RunFixtureTransactionTest(); |
| 6979 |
| 6980 EXPECT_EQ(1, open_count()); |
| 6981 EXPECT_EQ(2, transaction_count()); |
| 6982 } |
| 6983 |
| 6984 // HEAD requests should be able to take advantage of stale-while-revalidate. |
| 6985 TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) { |
| 6986 // Write to the cache. This has to be a GET request; HEAD requests don't |
| 6987 // create new cache entries. |
| 6988 RunFixtureTransactionTest(); |
| 6989 |
| 6990 EXPECT_EQ(0, open_count()); |
| 6991 EXPECT_EQ(1, transaction_count()); |
| 6992 |
| 6993 // Read back from the cache, and trigger an asynchronous HEAD request. |
| 6994 transaction_.method = "HEAD"; |
| 6995 transaction_.data = ""; |
| 6996 |
| 6997 RunFixtureTransactionTest(); |
| 6998 |
| 6999 EXPECT_EQ(1, open_count()); |
| 7000 EXPECT_EQ(1, transaction_count()); |
| 7001 |
| 7002 // Let the network request proceed. |
| 7003 base::RunLoop().RunUntilIdle(); |
| 7004 |
| 7005 EXPECT_EQ(2, transaction_count()); |
| 7006 } |
| 7007 |
| 7008 // POST requests should not use stale-while-revalidate. |
| 7009 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) { |
| 7010 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction); |
| 7011 |
| 7012 // Write to the cache. |
| 7013 RunFixtureTransactionTest(); |
| 7014 |
| 7015 EXPECT_EQ(0, open_count()); |
| 7016 EXPECT_EQ(1, transaction_count()); |
| 7017 |
| 7018 // Reading back reads from the network. |
| 7019 RunFixtureTransactionTest(); |
| 7020 |
| 7021 EXPECT_EQ(0, open_count()); |
| 7022 EXPECT_EQ(2, transaction_count()); |
| 7023 } |
| 7024 |
| 7025 static void CheckUrlMatches(const net::HttpRequestInfo* request, |
| 7026 std::string* response_status, |
| 7027 std::string* response_headers, |
| 7028 std::string* response_data) { |
| 7029 EXPECT_EQ("http://www.google.com/", request->url.spec()); |
| 7030 } |
| 7031 |
| 7032 // Async revalidation is issued to the original URL. |
| 7033 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) { |
| 7034 transaction_.url = "http://www.google.com/"; |
| 7035 // Write to the cache. |
| 7036 RunFixtureTransactionTest(); |
| 7037 |
| 7038 // Read back from the cache. |
| 7039 RunFixtureTransactionTest(); |
| 7040 |
| 7041 EXPECT_EQ(1, transaction_count()); |
| 7042 |
| 7043 transaction_.handler = CheckUrlMatches; |
| 7044 |
| 7045 // Let the async request execute and perform the check. |
| 7046 base::RunLoop().RunUntilIdle(); |
| 7047 EXPECT_EQ(2, transaction_count()); |
| 7048 } |
| 7049 |
| 7050 class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest, |
| 7051 public ::testing::WithParamInterface<int> {}; |
| 7052 |
| 7053 // Flags which should always cause the request to be synchronous. |
| 7054 TEST_P(SyncLoadFlagTest, MustBeSynchronous) { |
| 7055 transaction_.load_flags |= GetParam(); |
| 7056 // Write to the cache. |
| 7057 RunFixtureTransactionTest(); |
| 7058 |
| 7059 EXPECT_EQ(1, transaction_count()); |
| 7060 |
| 7061 // Reading back reads from the network. |
| 7062 RunFixtureTransactionTest(); |
| 7063 |
| 7064 EXPECT_EQ(2, transaction_count()); |
| 7065 } |
| 7066 |
| 7067 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate, |
| 7068 SyncLoadFlagTest, |
| 7069 ::testing::Values(net::LOAD_VALIDATE_CACHE, |
| 7070 net::LOAD_BYPASS_CACHE, |
| 7071 net::LOAD_DISABLE_CACHE)); |
| 7072 |
| 7073 TEST_F(HttpCacheStaleWhileRevalidateTest, |
| 7074 PreferringCacheDoesNotTriggerAsyncRequest) { |
| 7075 transaction_.load_flags |= net::LOAD_PREFERRING_CACHE; |
| 7076 // Write to the cache. |
| 7077 RunFixtureTransactionTest(); |
| 7078 |
| 7079 EXPECT_EQ(1, transaction_count()); |
| 7080 |
| 7081 // Reading back reads from the cache. |
| 7082 RunFixtureTransactionTest(); |
| 7083 |
| 7084 EXPECT_EQ(1, transaction_count()); |
| 7085 |
| 7086 // If there was an async transaction created, it would run now. |
| 7087 base::RunLoop().RunUntilIdle(); |
| 7088 |
| 7089 // There was no async transaction. |
| 7090 EXPECT_EQ(1, transaction_count()); |
| 7091 } |
| 7092 |
| 7093 TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) { |
| 7094 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false); |
| 7095 // Write to the cache. |
| 7096 RunFixtureTransactionTest(); |
| 7097 |
| 7098 EXPECT_EQ(1, transaction_count()); |
| 7099 |
| 7100 // A synchronous revalidation is performed. |
| 7101 RunFixtureTransactionTest(); |
| 7102 |
| 7103 EXPECT_EQ(2, transaction_count()); |
| 7104 } |
| 7105 |
| 7106 TEST_F(HttpCacheStaleWhileRevalidateTest, |
| 7107 OnlyFromCacheDoesNotTriggerAsyncRequest) { |
| 7108 transaction_.load_flags |= net::LOAD_ONLY_FROM_CACHE; |
| 7109 transaction_.return_code = net::ERR_CACHE_MISS; |
| 7110 |
| 7111 // Writing to the cache should fail, because we are avoiding the network. |
| 7112 RunFixtureTransactionTest(); |
| 7113 |
| 7114 EXPECT_EQ(0, transaction_count()); |
| 7115 |
| 7116 base::RunLoop().RunUntilIdle(); |
| 7117 |
| 7118 // Still nothing. |
| 7119 EXPECT_EQ(0, transaction_count()); |
| 7120 } |
| 7121 |
| 7122 // A certificate error during an asynchronous fetch should cause the next fetch |
| 7123 // to proceed synchronously. |
| 7124 // TODO(ricea): In future, only certificate errors which require user |
| 7125 // interaction should fail the asynchronous revalidation, and they should cause |
| 7126 // the next revalidation to be synchronous rather than requiring a total |
| 7127 // refetch. This test will need to be updated appropriately. |
| 7128 TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) { |
| 7129 // Write to the cache. |
| 7130 RunFixtureTransactionTest(); |
| 7131 |
| 7132 EXPECT_EQ(1, transaction_count()); |
| 7133 |
| 7134 // Now read back. RunTransactionTestBase() expects to receive the network |
| 7135 // error back from the HttpCache::Transaction, but since the cache request |
| 7136 // will return OK we need to duplicate some of its implementation here. |
| 7137 transaction_.return_code = net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 7138 net::TestCompletionCallback callback; |
| 7139 scoped_ptr<net::HttpTransaction> trans; |
| 7140 int rv = |
| 7141 cache_.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans); |
| 7142 EXPECT_EQ(net::OK, rv); |
| 7143 ASSERT_TRUE(trans.get()); |
| 7144 |
| 7145 MockHttpRequest request(transaction_); |
| 7146 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); |
| 7147 ASSERT_EQ(net::ERR_IO_PENDING, rv); |
| 7148 ASSERT_EQ(net::OK, callback.WaitForResult()); |
| 7149 ReadAndVerifyTransaction(trans.get(), transaction_); |
| 7150 |
| 7151 EXPECT_EQ(1, transaction_count()); |
| 7152 |
| 7153 // Allow the asynchronous fetch to run. |
| 7154 base::RunLoop().RunUntilIdle(); |
| 7155 |
| 7156 EXPECT_EQ(2, transaction_count()); |
| 7157 |
| 7158 // Now run the transaction again. It should run synchronously. |
| 7159 transaction_.return_code = net::OK; |
| 7160 RunFixtureTransactionTest(); |
| 7161 |
| 7162 EXPECT_EQ(3, transaction_count()); |
| 7163 } |
| 7164 |
| 7165 // Ensure that the response cached by the asynchronous request is not truncated, |
| 7166 // even if the server is slow. |
| 7167 TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) { |
| 7168 transaction_.test_mode = TEST_MODE_SLOW_READ; |
| 7169 // Write to the cache. |
| 7170 RunFixtureTransactionTest(); |
| 7171 |
| 7172 // Read back from the cache. |
| 7173 RunFixtureTransactionTest(); |
| 7174 |
| 7175 // Let the async request execute. |
| 7176 base::RunLoop().RunUntilIdle(); |
| 7177 |
| 7178 // The cache entry should still be complete. |
| 7179 transaction_.load_flags = net::LOAD_ONLY_FROM_CACHE; |
| 7180 RunFixtureTransactionTest(); |
| 7181 } |
| 7182 |
| 7183 // Verify that there are no race conditions in the completely synchronous case. |
| 7184 TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) { |
| 7185 transaction_.test_mode = TEST_MODE_SYNC_ALL; |
| 7186 // Write to the cache. |
| 7187 RunFixtureTransactionTest(); |
| 7188 |
| 7189 EXPECT_EQ(1, transaction_count()); |
| 7190 |
| 7191 // Read back from the cache. |
| 7192 RunFixtureTransactionTest(); |
| 7193 |
| 7194 EXPECT_EQ(1, transaction_count()); |
| 7195 |
| 7196 // Let the async request execute. |
| 7197 base::RunLoop().RunUntilIdle(); |
| 7198 EXPECT_EQ(2, transaction_count()); |
| 7199 } |
| 7200 |
| 7201 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo* request, |
| 7202 std::string* response_status, |
| 7203 std::string* response_headers, |
| 7204 std::string* response_data) { |
| 7205 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION, request->load_flags); |
| 7206 } |
| 7207 |
| 7208 // Check that the load flags on the async request are the same as the load flags |
| 7209 // on the original request, plus LOAD_ASYNC_REVALIDATION. |
| 7210 TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) { |
| 7211 transaction_.load_flags = net::LOAD_NORMAL; |
| 7212 // Write to the cache. |
| 7213 RunFixtureTransactionTest(); |
| 7214 |
| 7215 EXPECT_EQ(1, transaction_count()); |
| 7216 |
| 7217 // Read back from the cache. |
| 7218 RunFixtureTransactionTest(); |
| 7219 |
| 7220 EXPECT_EQ(1, transaction_count()); |
| 7221 |
| 7222 transaction_.handler = CheckLoadFlagsAsyncRevalidation; |
| 7223 // Let the async request execute. |
| 7224 base::RunLoop().RunUntilIdle(); |
| 7225 EXPECT_EQ(2, transaction_count()); |
| 7226 } |
| 7227 |
| 7228 static void SimpleMockAuthHandler(const net::HttpRequestInfo* request, |
| 7229 std::string* response_status, |
| 7230 std::string* response_headers, |
| 7231 std::string* response_data) { |
| 7232 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") && |
| 7233 !request->extra_headers.HasHeader("Authorization")) { |
| 7234 response_status->assign("HTTP/1.1 401 Unauthorized"); |
| 7235 response_headers->assign("WWW-Authenticate: Basic realm=\"mars\"\n"); |
| 7236 return; |
| 7237 } |
| 7238 response_status->assign("HTTP/1.1 200 OK"); |
| 7239 } |
| 7240 |
| 7241 TEST_F(HttpCacheStaleWhileRevalidateTest, RestartForAuth) { |
| 7242 // Write to the cache. |
| 7243 RunFixtureTransactionTest(); |
| 7244 |
| 7245 EXPECT_EQ(1, transaction_count()); |
| 7246 |
| 7247 // Now make the transaction require auth. |
| 7248 transaction_.request_headers = "X-Require-Mock-Auth: dummy\r\n\r\n"; |
| 7249 transaction_.handler = SimpleMockAuthHandler; |
| 7250 |
| 7251 // Read back from the cache. |
| 7252 RunFixtureTransactionTest(); |
| 7253 |
| 7254 EXPECT_EQ(1, transaction_count()); |
| 7255 |
| 7256 // Let the async request execute. |
| 7257 base::RunLoop().RunUntilIdle(); |
| 7258 |
| 7259 EXPECT_EQ(2, transaction_count()); |
6824 } | 7260 } |
6825 | 7261 |
6826 // Tests that we allow multiple simultaneous, non-overlapping transactions to | 7262 // Tests that we allow multiple simultaneous, non-overlapping transactions to |
6827 // take place on a sparse entry. | 7263 // take place on a sparse entry. |
6828 TEST(HttpCache, RangeGET_MultipleRequests) { | 7264 TEST(HttpCache, RangeGET_MultipleRequests) { |
6829 MockHttpCache cache; | 7265 MockHttpCache cache; |
6830 | 7266 |
6831 // Create a transaction for bytes 0-9. | 7267 // Create a transaction for bytes 0-9. |
6832 MockHttpRequest request(kRangeGET_TransactionOK); | 7268 MockHttpRequest request(kRangeGET_TransactionOK); |
6833 MockTransaction transaction(kRangeGET_TransactionOK); | 7269 MockTransaction transaction(kRangeGET_TransactionOK); |
(...skipping 13 matching lines...) Expand all Loading... |
6847 // A second transaction on a different part of the file (the default | 7283 // A second transaction on a different part of the file (the default |
6848 // kRangeGET_TransactionOK requests 40-49) should not be blocked by | 7284 // kRangeGET_TransactionOK requests 40-49) should not be blocked by |
6849 // the already pending transaction. | 7285 // the already pending transaction. |
6850 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); | 7286 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
6851 | 7287 |
6852 // Let the first transaction complete. | 7288 // Let the first transaction complete. |
6853 callback.WaitForResult(); | 7289 callback.WaitForResult(); |
6854 | 7290 |
6855 RemoveMockTransaction(&transaction); | 7291 RemoveMockTransaction(&transaction); |
6856 } | 7292 } |
OLD | NEW |