OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/hash_tables.h" | 7 #include "base/hash_tables.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/platform_file.h" | |
10 #include "base/string_util.h" | 9 #include "base/string_util.h" |
11 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
12 #include "net/base/load_flags.h" | 11 #include "net/base/load_flags.h" |
13 #include "net/disk_cache/disk_cache.h" | 12 #include "net/disk_cache/disk_cache.h" |
14 #include "net/http/http_request_info.h" | 13 #include "net/http/http_request_info.h" |
15 #include "net/http/http_response_info.h" | 14 #include "net/http/http_response_info.h" |
16 #include "net/http/http_transaction.h" | 15 #include "net/http/http_transaction.h" |
17 #include "net/http/http_transaction_unittest.h" | 16 #include "net/http/http_transaction_unittest.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
19 | 18 |
20 using base::Time; | 19 using base::Time; |
21 | 20 |
22 namespace { | 21 namespace { |
23 | 22 |
24 //----------------------------------------------------------------------------- | 23 //----------------------------------------------------------------------------- |
25 // mock disk cache (a very basic memory cache implementation) | 24 // mock disk cache (a very basic memory cache implementation) |
26 | 25 |
27 class MockDiskEntry : public disk_cache::Entry, | 26 class MockDiskEntry : public disk_cache::Entry, |
28 public base::RefCounted<MockDiskEntry> { | 27 public base::RefCounted<MockDiskEntry> { |
29 public: | 28 public: |
30 MockDiskEntry() | 29 MockDiskEntry() |
31 : test_mode_(0), doomed_(false), platform_file_(global_platform_file_) { | 30 : test_mode_(0), doomed_(false) { |
32 } | 31 } |
33 | 32 |
34 MockDiskEntry(const std::string& key) | 33 MockDiskEntry(const std::string& key) |
35 : key_(key), doomed_(false), platform_file_(global_platform_file_) { | 34 : key_(key), doomed_(false) { |
36 // | 35 // |
37 // 'key' is prefixed with an identifier if it corresponds to a cached POST. | 36 // 'key' is prefixed with an identifier if it corresponds to a cached POST. |
38 // Skip past that to locate the actual URL. | 37 // Skip past that to locate the actual URL. |
39 // | 38 // |
40 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an | 39 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an |
41 // URL corresponding to a registered MockTransaction. It would be good to | 40 // URL corresponding to a registered MockTransaction. It would be good to |
42 // have another way to access the test_mode. | 41 // have another way to access the test_mode. |
43 // | 42 // |
44 GURL url; | 43 GURL url; |
45 if (isdigit(key[0])) { | 44 if (isdigit(key[0])) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 | 109 |
111 if (offset < 0 || offset > static_cast<int>(data_[index].size())) | 110 if (offset < 0 || offset > static_cast<int>(data_[index].size())) |
112 return net::ERR_FAILED; | 111 return net::ERR_FAILED; |
113 | 112 |
114 data_[index].resize(offset + buf_len); | 113 data_[index].resize(offset + buf_len); |
115 if (buf_len) | 114 if (buf_len) |
116 memcpy(&data_[index][offset], buf->data(), buf_len); | 115 memcpy(&data_[index][offset], buf->data(), buf_len); |
117 return buf_len; | 116 return buf_len; |
118 } | 117 } |
119 | 118 |
120 base::PlatformFile UseExternalFile(int index) { | |
121 return platform_file_; | |
122 } | |
123 | |
124 base::PlatformFile GetPlatformFile(int index) { | |
125 return platform_file_; | |
126 } | |
127 | |
128 static void set_global_platform_file(base::PlatformFile platform_file) { | |
129 global_platform_file_ = platform_file; | |
130 } | |
131 | |
132 private: | 119 private: |
133 // Unlike the callbacks for MockHttpTransaction, we want this one to run even | 120 // Unlike the callbacks for MockHttpTransaction, we want this one to run even |
134 // if the consumer called Close on the MockDiskEntry. We achieve that by | 121 // if the consumer called Close on the MockDiskEntry. We achieve that by |
135 // leveraging the fact that this class is reference counted. | 122 // leveraging the fact that this class is reference counted. |
136 void CallbackLater(net::CompletionCallback* callback, int result) { | 123 void CallbackLater(net::CompletionCallback* callback, int result) { |
137 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, | 124 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, |
138 &MockDiskEntry::RunCallback, callback, result)); | 125 &MockDiskEntry::RunCallback, callback, result)); |
139 } | 126 } |
140 void RunCallback(net::CompletionCallback* callback, int result) { | 127 void RunCallback(net::CompletionCallback* callback, int result) { |
141 callback->Run(result); | 128 callback->Run(result); |
142 } | 129 } |
143 | 130 |
144 std::string key_; | 131 std::string key_; |
145 std::vector<char> data_[2]; | 132 std::vector<char> data_[2]; |
146 int test_mode_; | 133 int test_mode_; |
147 bool doomed_; | 134 bool doomed_; |
148 base::PlatformFile platform_file_; | |
149 static base::PlatformFile global_platform_file_; | |
150 }; | 135 }; |
151 | 136 |
152 base::PlatformFile MockDiskEntry::global_platform_file_ = | |
153 base::kInvalidPlatformFileValue; | |
154 | |
155 class MockDiskCache : public disk_cache::Backend { | 137 class MockDiskCache : public disk_cache::Backend { |
156 public: | 138 public: |
157 MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(0) { | 139 MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(0) { |
158 } | 140 } |
159 | 141 |
160 ~MockDiskCache() { | 142 ~MockDiskCache() { |
161 EntryMap::iterator it = entries_.begin(); | 143 EntryMap::iterator it = entries_.begin(); |
162 for (; it != entries_.end(); ++it) | 144 for (; it != entries_.end(); ++it) |
163 it->second->Release(); | 145 it->second->Release(); |
164 } | 146 } |
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 } | 1232 } |
1251 | 1233 |
1252 // Ensure that we don't crash by if left-behind transactions. | 1234 // Ensure that we don't crash by if left-behind transactions. |
1253 TEST(HttpCache, OutlivedTransactions) { | 1235 TEST(HttpCache, OutlivedTransactions) { |
1254 MockHttpCache* cache = new MockHttpCache; | 1236 MockHttpCache* cache = new MockHttpCache; |
1255 | 1237 |
1256 net::HttpTransaction* trans = cache->http_cache()->CreateTransaction(); | 1238 net::HttpTransaction* trans = cache->http_cache()->CreateTransaction(); |
1257 delete cache; | 1239 delete cache; |
1258 delete trans; | 1240 delete trans; |
1259 } | 1241 } |
1260 | |
1261 // Make sure Entry::UseExternalFile is called when a new entry is created in | |
1262 // a HttpCache with MEDIA type. Also make sure Entry::GetPlatformFile is called | |
1263 // when an entry is loaded from a HttpCache with MEDIA type. Also confirm we | |
1264 // will receive a file handle in ResponseInfo from a media cache. | |
1265 TEST(HttpCache, SimpleGET_MediaCache) { | |
1266 // Initialize the HttpCache with MEDIA_CACHE type. | |
1267 MockHttpCache cache; | |
1268 cache.http_cache()->set_type(net::MEDIA_CACHE); | |
1269 | |
1270 // Define some fake file handles for testing. | |
1271 base::PlatformFile kFakePlatformFile1, kFakePlatformFile2; | |
1272 #if defined(OS_WIN) | |
1273 kFakePlatformFile1 = reinterpret_cast<base::PlatformFile>(1); | |
1274 kFakePlatformFile2 = reinterpret_cast<base::PlatformFile>(2); | |
1275 #else | |
1276 kFakePlatformFile1 = 1; | |
1277 kFakePlatformFile2 = 2; | |
1278 #endif | |
1279 | |
1280 ScopedMockTransaction trans_info(kSimpleGET_Transaction); | |
1281 trans_info.load_flags |= net::LOAD_ENABLE_DOWNLOAD_FILE; | |
1282 TestCompletionCallback callback; | |
1283 | |
1284 { | |
1285 // Set the fake file handle to MockDiskEntry so cache is written with an | |
1286 // entry created with our fake file handle. | |
1287 MockDiskEntry::set_global_platform_file(kFakePlatformFile1); | |
1288 | |
1289 scoped_ptr<net::HttpTransaction> trans( | |
1290 cache.http_cache()->CreateTransaction()); | |
1291 ASSERT_TRUE(trans.get()); | |
1292 | |
1293 MockHttpRequest request(trans_info); | |
1294 | |
1295 int rv = trans->Start(&request, &callback); | |
1296 if (rv == net::ERR_IO_PENDING) | |
1297 rv = callback.WaitForResult(); | |
1298 ASSERT_EQ(net::OK, rv); | |
1299 | |
1300 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | |
1301 ASSERT_TRUE(response); | |
1302 | |
1303 ASSERT_EQ(kFakePlatformFile1, response->response_data_file); | |
1304 | |
1305 ReadAndVerifyTransaction(trans.get(), trans_info); | |
1306 } | |
1307 | |
1308 // Load only from cache so we would get the same file handle. | |
1309 trans_info.load_flags |= net::LOAD_ONLY_FROM_CACHE; | |
1310 | |
1311 { | |
1312 // Set a different file handle value to MockDiskEntry so any new entry | |
1313 // created in the cache won't have the same file handle value. | |
1314 MockDiskEntry::set_global_platform_file(kFakePlatformFile2); | |
1315 | |
1316 scoped_ptr<net::HttpTransaction> trans( | |
1317 cache.http_cache()->CreateTransaction()); | |
1318 ASSERT_TRUE(trans.get()); | |
1319 | |
1320 MockHttpRequest request(trans_info); | |
1321 | |
1322 int rv = trans->Start(&request, &callback); | |
1323 if (rv == net::ERR_IO_PENDING) | |
1324 rv = callback.WaitForResult(); | |
1325 ASSERT_EQ(net::OK, rv); | |
1326 | |
1327 const net::HttpResponseInfo* response = trans->GetResponseInfo(); | |
1328 ASSERT_TRUE(response); | |
1329 | |
1330 // Make sure we get the same file handle as in the first request. | |
1331 ASSERT_EQ(kFakePlatformFile1, response->response_data_file); | |
1332 | |
1333 ReadAndVerifyTransaction(trans.get(), trans_info); | |
1334 } | |
1335 } | |
OLD | NEW |