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/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "net/base/load_flags.h" | 11 #include "net/base/load_flags.h" |
12 #include "net/disk_cache/disk_cache.h" | 12 #include "net/disk_cache/disk_cache.h" |
| 13 #include "net/http/http_byte_range.h" |
13 #include "net/http/http_request_info.h" | 14 #include "net/http/http_request_info.h" |
14 #include "net/http/http_response_info.h" | 15 #include "net/http/http_response_info.h" |
15 #include "net/http/http_transaction.h" | 16 #include "net/http/http_transaction.h" |
16 #include "net/http/http_transaction_unittest.h" | 17 #include "net/http/http_transaction_unittest.h" |
| 18 #include "net/http/http_util.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
18 | 20 |
19 using base::Time; | 21 using base::Time; |
20 | 22 |
21 namespace { | 23 namespace { |
22 | 24 |
23 //----------------------------------------------------------------------------- | 25 //----------------------------------------------------------------------------- |
24 // mock disk cache (a very basic memory cache implementation) | 26 // mock disk cache (a very basic memory cache implementation) |
25 | 27 |
26 class MockDiskEntry : public disk_cache::Entry, | 28 class MockDiskEntry : public disk_cache::Entry, |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 "", | 407 "", |
406 net::LOAD_VALIDATE_CACHE, | 408 net::LOAD_VALIDATE_CACHE, |
407 "HTTP/1.1 200 OK", | 409 "HTTP/1.1 200 OK", |
408 "Cache-Control: max-age=10000\n", | 410 "Cache-Control: max-age=10000\n", |
409 "<html><body>Google Blah Blah</body></html>", | 411 "<html><body>Google Blah Blah</body></html>", |
410 TEST_MODE_SYNC_NET_START, | 412 TEST_MODE_SYNC_NET_START, |
411 &FastTransactionServer::FastNoStoreHandler, | 413 &FastTransactionServer::FastNoStoreHandler, |
412 0 | 414 0 |
413 }; | 415 }; |
414 | 416 |
| 417 // This class provides a handler for kRangeGET_TransactionOK so that the range |
| 418 // request can be served on demand. |
| 419 class RangeTransactionServer { |
| 420 public: |
| 421 RangeTransactionServer() { |
| 422 no_store = false; |
| 423 } |
| 424 ~RangeTransactionServer() {} |
| 425 |
| 426 void set_no_store(bool value) { no_store = value; } |
| 427 |
| 428 static void RangeHandler(const net::HttpRequestInfo* request, |
| 429 std::string* response_status, |
| 430 std::string* response_headers, |
| 431 std::string* response_data); |
| 432 |
| 433 private: |
| 434 static bool no_store; |
| 435 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); |
| 436 }; |
| 437 |
| 438 // Static. |
| 439 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, |
| 440 std::string* response_status, |
| 441 std::string* response_headers, |
| 442 std::string* response_data) { |
| 443 if (request->extra_headers.empty()) |
| 444 return; |
| 445 |
| 446 std::vector<net::HttpByteRange> ranges; |
| 447 if (!net::HttpUtil::ParseRanges(request->extra_headers, &ranges) || |
| 448 ranges.size() != 1) |
| 449 return; |
| 450 // We can handle this range request. |
| 451 net::HttpByteRange byte_range = ranges[0]; |
| 452 EXPECT_TRUE(byte_range.ComputeBounds(80)); |
| 453 int start = static_cast<int>(byte_range.first_byte_position()); |
| 454 int end = static_cast<int>(byte_range.last_byte_position()); |
| 455 |
| 456 EXPECT_LT(end, 80); |
| 457 |
| 458 std::string content_range = StringPrintf("Content-Range: bytes %d-%d/80\n", |
| 459 start, end); |
| 460 response_headers->append(content_range); |
| 461 |
| 462 if (request->extra_headers.find("If-None-Match") == std::string::npos) { |
| 463 EXPECT_EQ(9, end - start); |
| 464 std::string data = StringPrintf("rg: %d-%d ", start, end); |
| 465 *response_data = data; |
| 466 } else { |
| 467 response_status->assign("HTTP/1.1 304 Not Modified"); |
| 468 response_data->clear(); |
| 469 } |
| 470 } |
| 471 |
| 472 const MockTransaction kRangeGET_TransactionOK = { |
| 473 "http://www.google.com/range", |
| 474 "GET", |
| 475 "Range: bytes = 40-49\r\n", |
| 476 net::LOAD_NORMAL, |
| 477 "HTTP/1.1 206 Partial Content", |
| 478 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 479 "ETag: \"foo\"\n" |
| 480 "Accept-Ranges: bytes\n" |
| 481 "Content-Length: 10\n", |
| 482 "rg: 40-49 ", |
| 483 TEST_MODE_NORMAL, |
| 484 &RangeTransactionServer::RangeHandler, |
| 485 0 |
| 486 }; |
| 487 |
415 } // namespace | 488 } // namespace |
416 | 489 |
417 | 490 |
418 //----------------------------------------------------------------------------- | 491 //----------------------------------------------------------------------------- |
419 // tests | 492 // tests |
420 | 493 |
421 | 494 |
422 TEST(HttpCache, CreateThenDestroy) { | 495 TEST(HttpCache, CreateThenDestroy) { |
423 MockHttpCache cache; | 496 MockHttpCache cache; |
424 | 497 |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 RunTransactionTestWithRequest(cache.http_cache(), transaction, request); | 1114 RunTransactionTestWithRequest(cache.http_cache(), transaction, request); |
1042 | 1115 |
1043 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1116 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
1044 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 1117 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
1045 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1118 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
1046 } | 1119 } |
1047 | 1120 |
1048 TEST(HttpCache, RangeGET_SkipsCache) { | 1121 TEST(HttpCache, RangeGET_SkipsCache) { |
1049 MockHttpCache cache; | 1122 MockHttpCache cache; |
1050 | 1123 |
1051 // Test that we skip the cache for POST requests. Eventually, we will want | 1124 // Test that we skip the cache for range GET requests. Eventually, we will |
1052 // to cache these, but we'll still have cases where skipping the cache makes | 1125 // want to cache these, but we'll still have cases where skipping the cache |
1053 // sense, so we want to make sure that it works properly. | 1126 // makes sense, so we want to make sure that it works properly. |
1054 | 1127 |
1055 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction); | 1128 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction); |
1056 | 1129 |
1057 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1130 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
1058 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1131 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1059 EXPECT_EQ(0, cache.disk_cache()->create_count()); | 1132 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
1060 | 1133 |
1061 MockTransaction transaction(kSimpleGET_Transaction); | 1134 MockTransaction transaction(kSimpleGET_Transaction); |
1062 transaction.request_headers = "If-None-Match: foo"; | 1135 transaction.request_headers = "If-None-Match: foo"; |
1063 RunTransactionTest(cache.http_cache(), transaction); | 1136 RunTransactionTest(cache.http_cache(), transaction); |
1064 | 1137 |
1065 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 1138 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
1066 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1139 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1067 EXPECT_EQ(0, cache.disk_cache()->create_count()); | 1140 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
1068 | 1141 |
1069 transaction.request_headers = | 1142 transaction.request_headers = |
1070 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT"; | 1143 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT"; |
1071 RunTransactionTest(cache.http_cache(), transaction); | 1144 RunTransactionTest(cache.http_cache(), transaction); |
1072 | 1145 |
1073 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | 1146 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
1074 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1147 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1075 EXPECT_EQ(0, cache.disk_cache()->create_count()); | 1148 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
1076 } | 1149 } |
1077 | 1150 |
| 1151 TEST(HttpCache, DISABLED_RangeGET_OK) { |
| 1152 MockHttpCache cache; |
| 1153 AddMockTransaction(&kRangeGET_TransactionOK); |
| 1154 |
| 1155 // Test that we can cache range requests and fetch random blocks from the |
| 1156 // cache and the network. |
| 1157 |
| 1158 // Write to the cache (40-49). |
| 1159 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
| 1160 |
| 1161 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1162 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1163 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1164 |
| 1165 // Read from the cache (40-49). |
| 1166 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
| 1167 |
| 1168 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1169 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 1170 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1171 |
| 1172 // Make sure we are done with the previous transaction. |
| 1173 MessageLoop::current()->RunAllPending(); |
| 1174 |
| 1175 // Write to the cache (30-39). |
| 1176 MockTransaction transaction(kRangeGET_TransactionOK); |
| 1177 transaction.request_headers = "Range: bytes = 30-39\r\n"; |
| 1178 transaction.data = "rg: 30-39 "; |
| 1179 RunTransactionTest(cache.http_cache(), transaction); |
| 1180 |
| 1181 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 1182 EXPECT_EQ(2, cache.disk_cache()->open_count()); |
| 1183 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1184 |
| 1185 // Make sure we are done with the previous transaction. |
| 1186 MessageLoop::current()->RunAllPending(); |
| 1187 |
| 1188 // Write and read from the cache (20-59). |
| 1189 transaction.request_headers = "Range: bytes = 20-59\r\n"; |
| 1190 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; |
| 1191 RunTransactionTest(cache.http_cache(), transaction); |
| 1192 |
| 1193 EXPECT_EQ(6, cache.network_layer()->transaction_count()); |
| 1194 EXPECT_EQ(3, cache.disk_cache()->open_count()); |
| 1195 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1196 |
| 1197 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 1198 } |
| 1199 |
1078 TEST(HttpCache, SyncRead) { | 1200 TEST(HttpCache, SyncRead) { |
1079 MockHttpCache cache; | 1201 MockHttpCache cache; |
1080 | 1202 |
1081 // This test ensures that a read that completes synchronously does not cause | 1203 // This test ensures that a read that completes synchronously does not cause |
1082 // any problems. | 1204 // any problems. |
1083 | 1205 |
1084 ScopedMockTransaction transaction(kSimpleGET_Transaction); | 1206 ScopedMockTransaction transaction(kSimpleGET_Transaction); |
1085 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START | | 1207 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START | |
1086 TEST_MODE_SYNC_CACHE_READ); | 1208 TEST_MODE_SYNC_CACHE_READ); |
1087 | 1209 |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 | 1449 |
1328 // force this transaction to write to the cache again | 1450 // force this transaction to write to the cache again |
1329 MockTransaction transaction(kSimpleGET_Transaction); | 1451 MockTransaction transaction(kSimpleGET_Transaction); |
1330 | 1452 |
1331 RunTransactionTest(cache.http_cache(), transaction); | 1453 RunTransactionTest(cache.http_cache(), transaction); |
1332 | 1454 |
1333 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 1455 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
1334 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1456 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
1335 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1457 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
1336 } | 1458 } |
OLD | NEW |