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 #include <list> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/format_macros.h" |
11 #include "base/memory/scoped_vector.h" | 13 #include "base/memory/scoped_vector.h" |
12 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
13 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
14 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
16 #include "base/test/simple_test_clock.h" | 18 #include "base/test/simple_test_clock.h" |
17 #include "net/base/cache_type.h" | 19 #include "net/base/cache_type.h" |
18 #include "net/base/elements_upload_data_stream.h" | 20 #include "net/base/elements_upload_data_stream.h" |
19 #include "net/base/host_port_pair.h" | 21 #include "net/base/host_port_pair.h" |
20 #include "net/base/load_flags.h" | 22 #include "net/base/load_flags.h" |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 "", | 271 "", |
270 LOAD_VALIDATE_CACHE, | 272 LOAD_VALIDATE_CACHE, |
271 "HTTP/1.1 200 OK", | 273 "HTTP/1.1 200 OK", |
272 "Cache-Control: max-age=10000\n", | 274 "Cache-Control: max-age=10000\n", |
273 base::Time(), | 275 base::Time(), |
274 "<html><body>Google Blah Blah</body></html>", | 276 "<html><body>Google Blah Blah</body></html>", |
275 TEST_MODE_SYNC_NET_START, | 277 TEST_MODE_SYNC_NET_START, |
276 &FastTransactionServer::FastNoStoreHandler, | 278 &FastTransactionServer::FastNoStoreHandler, |
277 nullptr, | 279 nullptr, |
278 0, | 280 0, |
279 0, | |
280 OK}; | 281 OK}; |
281 | 282 |
282 // This class provides a handler for kRangeGET_TransactionOK so that the range | 283 // This class provides a handler for kRangeGET_TransactionOK so that the range |
283 // request can be served on demand. | 284 // request can be served on demand. |
284 class RangeTransactionServer { | 285 class RangeTransactionServer { |
285 public: | 286 public: |
286 RangeTransactionServer() { | 287 RangeTransactionServer() { |
287 not_modified_ = false; | 288 not_modified_ = false; |
288 modified_ = false; | 289 modified_ = false; |
289 bad_200_ = false; | 290 bad_200_ = false; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 // A dummy extra header that must be preserved on a given request. | 329 // A dummy extra header that must be preserved on a given request. |
329 | 330 |
330 // EXTRA_HEADER_LINE doesn't include a line terminator because it | 331 // EXTRA_HEADER_LINE doesn't include a line terminator because it |
331 // will be passed to AddHeaderFromString() which doesn't accept them. | 332 // will be passed to AddHeaderFromString() which doesn't accept them. |
332 #define EXTRA_HEADER_LINE "Extra: header" | 333 #define EXTRA_HEADER_LINE "Extra: header" |
333 | 334 |
334 // EXTRA_HEADER contains a line terminator, as expected by | 335 // EXTRA_HEADER contains a line terminator, as expected by |
335 // AddHeadersFromString() (_not_ AddHeaderFromString()). | 336 // AddHeadersFromString() (_not_ AddHeaderFromString()). |
336 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" | 337 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" |
337 | 338 |
338 static const char kExtraHeaderKey[] = "Extra"; | 339 #define RETURN_DEFAULT_RANGE_HEADER "X-Return-Default-Range: 1\r\n" |
| 340 |
| 341 #define INDICATE_NO_RANGES_HEADER "X-Indicate-No-Ranges: 1\r\n" |
| 342 |
| 343 const char kExtraHeaderKey[] = "Extra"; |
| 344 |
| 345 const char kFullRangeData[] = |
| 346 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 " |
| 347 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 "; |
339 | 348 |
340 // Static. | 349 // Static. |
341 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request, | 350 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request, |
342 std::string* response_status, | 351 std::string* response_status, |
343 std::string* response_headers, | 352 std::string* response_headers, |
344 std::string* response_data) { | 353 std::string* response_data) { |
| 354 SCOPED_TRACE(testing::Message() << "Request headers: \n" |
| 355 << request->extra_headers.ToString()); |
345 if (request->extra_headers.IsEmpty()) { | 356 if (request->extra_headers.IsEmpty()) { |
346 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); | 357 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); |
347 response_data->clear(); | 358 response_data->clear(); |
348 return; | 359 return; |
349 } | 360 } |
350 | 361 |
351 // We want to make sure we don't delete extra headers. | 362 // We want to make sure we don't delete extra headers. |
352 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); | 363 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); |
353 | 364 |
354 bool require_auth = | 365 bool require_auth = |
(...skipping 13 matching lines...) Expand all Loading... |
368 } | 379 } |
369 | 380 |
370 std::vector<HttpByteRange> ranges; | 381 std::vector<HttpByteRange> ranges; |
371 std::string range_header; | 382 std::string range_header; |
372 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange, | 383 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange, |
373 &range_header) || | 384 &range_header) || |
374 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || | 385 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || |
375 ranges.size() != 1) { | 386 ranges.size() != 1) { |
376 // This is not a byte range request. We return 200. | 387 // This is not a byte range request. We return 200. |
377 response_status->assign("HTTP/1.1 200 OK"); | 388 response_status->assign("HTTP/1.1 200 OK"); |
378 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); | 389 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); |
379 response_data->assign("Not a range"); | 390 if (request->extra_headers.HasHeader("X-Indicate-No-Ranges")) { |
| 391 response_data->assign("Not a range"); |
| 392 return; |
| 393 } |
| 394 response_headers->append( |
| 395 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 396 "ETag: \"foo\"\n" |
| 397 "Accept-Ranges: bytes\n" |
| 398 "Content-Length: 80\n"); |
| 399 response_data->assign(kFullRangeData); |
380 return; | 400 return; |
381 } | 401 } |
382 | 402 |
383 // We can handle this range request. | 403 // We can handle this range request. |
384 HttpByteRange byte_range = ranges[0]; | 404 HttpByteRange byte_range = ranges[0]; |
385 | 405 |
386 if (request->extra_headers.HasHeader("X-Return-Default-Range")) { | 406 if (request->extra_headers.HasHeader("X-Return-Default-Range")) { |
387 byte_range.set_first_byte_position(40); | 407 byte_range.set_first_byte_position(40); |
388 byte_range.set_last_byte_position(49); | 408 byte_range.set_last_byte_position(49); |
389 } | 409 } |
390 | 410 |
391 if (byte_range.first_byte_position() > 79) { | 411 if (byte_range.first_byte_position() > 79) { |
392 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); | 412 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); |
393 response_data->clear(); | 413 response_data->clear(); |
394 return; | 414 return; |
395 } | 415 } |
| 416 response_status->assign("HTTP/1.1 206 Partial"); |
396 | 417 |
397 EXPECT_TRUE(byte_range.ComputeBounds(80)); | 418 EXPECT_TRUE(byte_range.ComputeBounds(80)); |
398 int start = static_cast<int>(byte_range.first_byte_position()); | 419 int start = static_cast<int>(byte_range.first_byte_position()); |
399 int end = static_cast<int>(byte_range.last_byte_position()); | 420 int end = static_cast<int>(byte_range.last_byte_position()); |
400 | 421 |
401 EXPECT_LT(end, 80); | 422 EXPECT_LT(end, 80); |
402 | 423 |
403 std::string content_range = base::StringPrintf( | 424 std::string content_range = base::StringPrintf( |
404 "Content-Range: bytes %d-%d/80\n", start, end); | 425 "Content-Range: bytes %d-%d/80\n", start, end); |
405 response_headers->append(content_range); | 426 response_headers->append(content_range); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 463 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
443 "ETag: \"foo\"\n" | 464 "ETag: \"foo\"\n" |
444 "Accept-Ranges: bytes\n" | 465 "Accept-Ranges: bytes\n" |
445 "Content-Length: 10\n", | 466 "Content-Length: 10\n", |
446 base::Time(), | 467 base::Time(), |
447 "rg: 40-49 ", | 468 "rg: 40-49 ", |
448 TEST_MODE_NORMAL, | 469 TEST_MODE_NORMAL, |
449 &RangeTransactionServer::RangeHandler, | 470 &RangeTransactionServer::RangeHandler, |
450 nullptr, | 471 nullptr, |
451 0, | 472 0, |
452 0, | |
453 OK}; | 473 OK}; |
454 | 474 |
455 const char kFullRangeData[] = | |
456 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 " | |
457 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 "; | |
458 | |
459 // Verifies the response headers (|response|) match a partial content | 475 // Verifies the response headers (|response|) match a partial content |
460 // response for the range starting at |start| and ending at |end|. | 476 // response for the range starting at |start| and ending at |end|. |
461 void Verify206Response(std::string response, int start, int end) { | 477 void Verify206Response(std::string response, int start, int end) { |
462 std::string raw_headers( | 478 std::string raw_headers( |
463 HttpUtil::AssembleRawHeaders(response.data(), response.size())); | 479 HttpUtil::AssembleRawHeaders(response.data(), response.size())); |
464 scoped_refptr<HttpResponseHeaders> headers( | 480 scoped_refptr<HttpResponseHeaders> headers( |
465 new HttpResponseHeaders(raw_headers)); | 481 new HttpResponseHeaders(raw_headers)); |
466 | 482 |
467 ASSERT_EQ(206, headers->response_code()); | 483 ASSERT_EQ(206, headers->response_code()); |
468 | 484 |
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2088 // Write to the cache. | 2104 // Write to the cache. |
2089 MockTransaction transaction(kTypicalGET_Transaction); | 2105 MockTransaction transaction(kTypicalGET_Transaction); |
2090 transaction.request_headers = "Foo: bar\r\n"; | 2106 transaction.request_headers = "Foo: bar\r\n"; |
2091 transaction.response_headers = | 2107 transaction.response_headers = |
2092 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" | 2108 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" |
2093 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" | 2109 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" |
2094 "Cache-Control: max-age=0\n" | 2110 "Cache-Control: max-age=0\n" |
2095 "Vary: Foo\n"; | 2111 "Vary: Foo\n"; |
2096 AddMockTransaction(&transaction); | 2112 AddMockTransaction(&transaction); |
2097 RunTransactionTest(cache.http_cache(), transaction); | 2113 RunTransactionTest(cache.http_cache(), transaction); |
2098 | |
2099 // Read from the cache and don't revalidate the entry. | 2114 // Read from the cache and don't revalidate the entry. |
2100 RevalidationServer server; | 2115 RevalidationServer server; |
2101 transaction.handler = server.Handler; | 2116 transaction.handler = server.Handler; |
2102 transaction.request_headers = "Foo: none\r\n"; | 2117 transaction.request_headers = "Foo: none\r\n"; |
| 2118 |
2103 BoundTestNetLog log; | 2119 BoundTestNetLog log; |
2104 LoadTimingInfo load_timing_info; | 2120 LoadTimingInfo load_timing_info; |
2105 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), | 2121 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), |
2106 &load_timing_info); | 2122 &load_timing_info); |
2107 | 2123 |
2108 EXPECT_FALSE(server.EtagUsed()); | 2124 EXPECT_FALSE(server.EtagUsed()); |
2109 EXPECT_FALSE(server.LastModifiedUsed()); | 2125 EXPECT_FALSE(server.LastModifiedUsed()); |
2110 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2126 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
2111 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 2127 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
2112 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2128 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
(...skipping 1778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3891 | 3907 |
3892 Verify206Response(headers, 40, 49); | 3908 Verify206Response(headers, 40, 49); |
3893 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 3909 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
3894 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 3910 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
3895 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 3911 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
3896 | 3912 |
3897 // Now verify that the cached data is not used. | 3913 // Now verify that the cached data is not used. |
3898 // Don't ask for a range. The cache will attempt to use the cached data but | 3914 // Don't ask for a range. The cache will attempt to use the cached data but |
3899 // should discard it as it cannot be validated. A regular request should go | 3915 // should discard it as it cannot be validated. A regular request should go |
3900 // to the server and a new entry should be created. | 3916 // to the server and a new entry should be created. |
3901 transaction.request_headers = EXTRA_HEADER; | 3917 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
3902 transaction.data = "Not a range"; | 3918 transaction.data = "Not a range"; |
3903 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 3919 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
3904 | 3920 |
3905 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); | 3921 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
3906 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 3922 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
3907 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 3923 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
3908 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 3924 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
3909 | 3925 |
3910 // The last response was saved. | 3926 // The last response was saved. |
3911 RunTransactionTest(cache.http_cache(), transaction); | 3927 RunTransactionTest(cache.http_cache(), transaction); |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4359 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; | 4375 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; |
4360 transaction.data = "rg: 70-79 "; | 4376 transaction.data = "rg: 70-79 "; |
4361 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 4377 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
4362 Verify206Response(headers, 70, 79); | 4378 Verify206Response(headers, 70, 79); |
4363 | 4379 |
4364 // Don't ask for a range. The cache will ask the server for 0-69. | 4380 // Don't ask for a range. The cache will ask the server for 0-69. |
4365 // The server returns 40-49. The cache should consider the server confused and | 4381 // The server returns 40-49. The cache should consider the server confused and |
4366 // abort caching, restarting the request. | 4382 // abort caching, restarting the request. |
4367 // The second network request should not be a byte range request so the server | 4383 // The second network request should not be a byte range request so the server |
4368 // should return 200 + "Not a range" | 4384 // should return 200 + "Not a range" |
4369 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER; | 4385 transaction.request_headers = |
| 4386 RETURN_DEFAULT_RANGE_HEADER INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
4370 transaction.data = "Not a range"; | 4387 transaction.data = "Not a range"; |
4371 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 4388 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
4372 | 4389 |
4373 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); | 4390 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
4374 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | 4391 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
4375 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 4392 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
4376 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4393 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
4377 | 4394 |
4378 // The entry was deleted. | 4395 // The entry was deleted. |
4379 RunTransactionTest(cache.http_cache(), transaction); | 4396 RunTransactionTest(cache.http_cache(), transaction); |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4751 Verify206Response(headers, 0, 9); | 4768 Verify206Response(headers, 0, 9); |
4752 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 4769 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
4753 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 4770 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
4754 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4771 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
4755 | 4772 |
4756 // Now we'll issue a request without any range that should result first in a | 4773 // Now we'll issue a request without any range that should result first in a |
4757 // 206 (when revalidating), and then in a weird standard answer: the test | 4774 // 206 (when revalidating), and then in a weird standard answer: the test |
4758 // server will not modify the response so we'll get the default range... a | 4775 // server will not modify the response so we'll get the default range... a |
4759 // real server will answer with 200. | 4776 // real server will answer with 200. |
4760 MockTransaction transaction2(kRangeGET_TransactionOK); | 4777 MockTransaction transaction2(kRangeGET_TransactionOK); |
4761 transaction2.request_headers = EXTRA_HEADER; | 4778 transaction2.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
4762 transaction2.load_flags |= LOAD_VALIDATE_CACHE; | 4779 transaction2.load_flags |= LOAD_VALIDATE_CACHE; |
4763 transaction2.data = "Not a range"; | 4780 transaction2.data = "Not a range"; |
4764 RangeTransactionServer handler; | 4781 RangeTransactionServer handler; |
4765 handler.set_modified(true); | 4782 handler.set_modified(true); |
4766 BoundTestNetLog log; | 4783 BoundTestNetLog log; |
4767 LoadTimingInfo load_timing_info; | 4784 LoadTimingInfo load_timing_info; |
4768 RunTransactionTestWithResponseAndGetTiming( | 4785 RunTransactionTestWithResponseAndGetTiming( |
4769 cache.http_cache(), transaction2, &headers, log.bound(), | 4786 cache.http_cache(), transaction2, &headers, log.bound(), |
4770 &load_timing_info); | 4787 &load_timing_info); |
4771 | 4788 |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5361 | 5378 |
5362 RemoveMockTransaction(&kRangeGET_TransactionOK); | 5379 RemoveMockTransaction(&kRangeGET_TransactionOK); |
5363 } | 5380 } |
5364 | 5381 |
5365 // Tests that we don't crash when after reading from the cache we issue a | 5382 // Tests that we don't crash when after reading from the cache we issue a |
5366 // request for the next range and the server gives us a 200 synchronously. | 5383 // request for the next range and the server gives us a 200 synchronously. |
5367 TEST(HttpCache, RangeGET_FastFlakyServer) { | 5384 TEST(HttpCache, RangeGET_FastFlakyServer) { |
5368 MockHttpCache cache; | 5385 MockHttpCache cache; |
5369 | 5386 |
5370 ScopedMockTransaction transaction(kRangeGET_TransactionOK); | 5387 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
5371 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; | 5388 transaction.request_headers = |
| 5389 "Range: bytes = 40-\r\n" INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
5372 transaction.test_mode = TEST_MODE_SYNC_NET_START; | 5390 transaction.test_mode = TEST_MODE_SYNC_NET_START; |
5373 transaction.load_flags |= LOAD_VALIDATE_CACHE; | 5391 transaction.load_flags |= LOAD_VALIDATE_CACHE; |
5374 | 5392 |
5375 // Write to the cache. | 5393 // Write to the cache. |
5376 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); | 5394 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
5377 | 5395 |
5378 // And now read from the cache and the network. | 5396 // And now read from the cache and the network. |
5379 RangeTransactionServer handler; | 5397 RangeTransactionServer handler; |
5380 handler.set_bad_200(true); | 5398 handler.set_bad_200(true); |
5381 transaction.data = "Not a range"; | 5399 transaction.data = "Not a range"; |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5889 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 5907 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
5890 "ETag: \"foo\"\n" | 5908 "ETag: \"foo\"\n" |
5891 "Accept-Ranges: bytes\n" | 5909 "Accept-Ranges: bytes\n" |
5892 "Content-Length: 50\n"); | 5910 "Content-Length: 50\n"); |
5893 CreateTruncatedEntry(raw_headers, &cache); | 5911 CreateTruncatedEntry(raw_headers, &cache); |
5894 | 5912 |
5895 // Now make a regular request. We expect the code to fail the validation and | 5913 // Now make a regular request. We expect the code to fail the validation and |
5896 // retry the request without using byte ranges. | 5914 // retry the request without using byte ranges. |
5897 std::string headers; | 5915 std::string headers; |
5898 MockTransaction transaction(kRangeGET_TransactionOK); | 5916 MockTransaction transaction(kRangeGET_TransactionOK); |
5899 transaction.request_headers = EXTRA_HEADER; | 5917 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
5900 transaction.data = "Not a range"; | 5918 transaction.data = "Not a range"; |
5901 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 5919 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
5902 | 5920 |
5903 // The server will return 200 instead of a byte range. | 5921 // The server will return 200 instead of a byte range. |
5904 std::string expected_headers( | 5922 std::string expected_headers( |
5905 "HTTP/1.1 200 OK\n" | 5923 "HTTP/1.1 200 OK\n" |
5906 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); | 5924 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); |
5907 | 5925 |
5908 EXPECT_EQ(expected_headers, headers); | 5926 EXPECT_EQ(expected_headers, headers); |
5909 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 5927 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6044 std::string raw_headers("HTTP/1.1 200 OK\n" | 6062 std::string raw_headers("HTTP/1.1 200 OK\n" |
6045 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 6063 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
6046 "ETag: \"foo\"\n" | 6064 "ETag: \"foo\"\n" |
6047 "Accept-Ranges: bytes\n" | 6065 "Accept-Ranges: bytes\n" |
6048 "Content-Length: 80\n"); | 6066 "Content-Length: 80\n"); |
6049 CreateTruncatedEntry(raw_headers, &cache); | 6067 CreateTruncatedEntry(raw_headers, &cache); |
6050 | 6068 |
6051 // Now make a regular request. | 6069 // Now make a regular request. |
6052 std::string headers; | 6070 std::string headers; |
6053 MockTransaction transaction(kRangeGET_TransactionOK); | 6071 MockTransaction transaction(kRangeGET_TransactionOK); |
6054 transaction.request_headers = EXTRA_HEADER; | 6072 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
6055 transaction.data = "Not a range"; | 6073 transaction.data = "Not a range"; |
6056 RangeTransactionServer handler; | 6074 RangeTransactionServer handler; |
6057 handler.set_bad_200(true); | 6075 handler.set_bad_200(true); |
6058 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 6076 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
6059 | 6077 |
6060 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6078 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
6061 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6079 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
6062 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 6080 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
6063 | 6081 |
6064 // Verify that the disk entry was updated. | 6082 // Verify that the disk entry was updated. |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6739 base::MessageLoop::current()->RunUntilIdle(); | 6757 base::MessageLoop::current()->RunUntilIdle(); |
6740 | 6758 |
6741 // Read from the cache. This should not deadlock. | 6759 // Read from the cache. This should not deadlock. |
6742 RunTransactionTest(cache.http_cache(), transaction); | 6760 RunTransactionTest(cache.http_cache(), transaction); |
6743 | 6761 |
6744 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6762 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
6745 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6763 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
6746 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 6764 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
6747 } | 6765 } |
6748 | 6766 |
6749 // Tests that we stop caching when told. | 6767 // Tests that calling StopCaching() causes the cache entry to be deleted if the |
6750 TEST(HttpCache, StopCachingDeletesEntry) { | 6768 // request cannot be resumed. |
| 6769 TEST(HttpCache, StopCachingDeletesEntryIfRequestIsNotResumable) { |
6751 MockHttpCache cache; | 6770 MockHttpCache cache; |
6752 TestCompletionCallback callback; | 6771 TestCompletionCallback callback; |
6753 MockHttpRequest request(kSimpleGET_Transaction); | 6772 MockHttpRequest request(kSimpleGET_Transaction); |
6754 | 6773 |
6755 { | 6774 { |
6756 scoped_ptr<HttpTransaction> trans; | 6775 scoped_ptr<HttpTransaction> trans; |
6757 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6776 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
6758 | 6777 |
6759 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6778 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
6760 EXPECT_EQ(OK, callback.GetResult(rv)); | 6779 EXPECT_EQ(OK, callback.GetResult(rv)); |
6761 | 6780 |
6762 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | 6781 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); |
6763 rv = trans->Read(buf.get(), 10, callback.callback()); | 6782 rv = trans->Read(buf.get(), 10, callback.callback()); |
6764 EXPECT_EQ(10, callback.GetResult(rv)); | 6783 EXPECT_EQ(10, callback.GetResult(rv)); |
6765 | 6784 |
6766 trans->StopCaching(); | 6785 trans->StopCaching(); |
6767 | 6786 |
6768 // We should be able to keep reading. | 6787 // We should be able to keep reading. |
6769 rv = trans->Read(buf.get(), 256, callback.callback()); | 6788 rv = trans->Read(buf.get(), 256, callback.callback()); |
6770 EXPECT_GT(callback.GetResult(rv), 0); | 6789 EXPECT_GT(callback.GetResult(rv), 0); |
6771 rv = trans->Read(buf.get(), 256, callback.callback()); | 6790 rv = trans->Read(buf.get(), 256, callback.callback()); |
6772 EXPECT_EQ(0, callback.GetResult(rv)); | 6791 EXPECT_EQ(0, callback.GetResult(rv)); |
6773 } | 6792 } |
6774 | 6793 |
6775 // Make sure that the ActiveEntry is gone. | 6794 // Make sure that the ActiveEntry is gone. |
6776 base::MessageLoop::current()->RunUntilIdle(); | 6795 base::MessageLoop::current()->RunUntilIdle(); |
6777 | 6796 |
6778 // Verify that the entry is gone. | 6797 // Verify that the entry is gone. The request is not resumeable, so the cache |
| 6798 // entry should be deleted if only part of the response was cached. |
6779 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 6799 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
6780 | 6800 |
6781 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6801 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
6782 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 6802 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
6783 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 6803 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
6784 } | 6804 } |
6785 | 6805 |
6786 // Tests that we stop caching when told, even if DoneReading is called | 6806 // Tests that we stop caching when told, even if DoneReading is called |
6787 // after StopCaching. | 6807 // after StopCaching. |
6788 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) { | 6808 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6853 | 6873 |
6854 // Verify that the entry is gone. | 6874 // Verify that the entry is gone. |
6855 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 6875 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
6856 | 6876 |
6857 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6877 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
6858 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 6878 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
6859 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 6879 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
6860 } | 6880 } |
6861 | 6881 |
6862 // Tests that when we are told to stop caching we don't throw away valid data. | 6882 // Tests that when we are told to stop caching we don't throw away valid data. |
6863 TEST(HttpCache, StopCachingSavesEntry) { | 6883 // If the request is resumable (i.e. has strong validators), then the cache |
| 6884 // should hold on to the partial response. |
| 6885 TEST(HttpCache, StopCachingSavesEntryIfRequestIsResumable) { |
6864 MockHttpCache cache; | 6886 MockHttpCache cache; |
6865 TestCompletionCallback callback; | 6887 TestCompletionCallback callback; |
6866 MockHttpRequest request(kSimpleGET_Transaction); | 6888 MockHttpRequest request(kSimpleGET_Transaction); |
6867 | 6889 |
6868 { | 6890 { |
6869 scoped_ptr<HttpTransaction> trans; | 6891 scoped_ptr<HttpTransaction> trans; |
6870 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6892 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
6871 | 6893 |
6872 // Force a response that can be resumed. | 6894 // Force a response that can be resumed. |
6873 MockTransaction mock_transaction(kSimpleGET_Transaction); | 6895 MockTransaction mock_transaction(kSimpleGET_Transaction); |
(...skipping 24 matching lines...) Expand all Loading... |
6898 disk_cache::Entry* entry; | 6920 disk_cache::Entry* entry; |
6899 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); | 6921 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); |
6900 HttpResponseInfo response; | 6922 HttpResponseInfo response; |
6901 bool truncated = false; | 6923 bool truncated = false; |
6902 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); | 6924 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); |
6903 EXPECT_TRUE(truncated); | 6925 EXPECT_TRUE(truncated); |
6904 entry->Close(); | 6926 entry->Close(); |
6905 } | 6927 } |
6906 | 6928 |
6907 // Tests that we handle truncated enries when StopCaching is called. | 6929 // Tests that we handle truncated enries when StopCaching is called. |
6908 TEST(HttpCache, StopCachingTruncatedEntry) { | 6930 TEST(HttpCache, StopCachingPreservesAlreadyTruncatedEntry) { |
6909 MockHttpCache cache; | 6931 MockHttpCache cache; |
6910 TestCompletionCallback callback; | 6932 TestCompletionCallback callback; |
6911 MockHttpRequest request(kRangeGET_TransactionOK); | 6933 MockHttpRequest request(kRangeGET_TransactionOK); |
6912 request.extra_headers.Clear(); | 6934 request.extra_headers.Clear(); |
6913 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); | 6935 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); |
6914 AddMockTransaction(&kRangeGET_TransactionOK); | 6936 AddMockTransaction(&kRangeGET_TransactionOK); |
6915 | 6937 |
6916 std::string raw_headers("HTTP/1.1 200 OK\n" | 6938 std::string raw_headers("HTTP/1.1 200 OK\n" |
6917 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 6939 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
6918 "ETag: \"foo\"\n" | 6940 "ETag: \"foo\"\n" |
6919 "Accept-Ranges: bytes\n" | 6941 "Accept-Ranges: bytes\n" |
6920 "Content-Length: 80\n"); | 6942 "Content-Length: 80\n"); |
6921 CreateTruncatedEntry(raw_headers, &cache); | 6943 CreateTruncatedEntry(raw_headers, &cache); |
6922 | 6944 |
6923 { | 6945 { |
6924 // Now make a regular request. | 6946 // Now make a regular request. |
6925 scoped_ptr<HttpTransaction> trans; | 6947 scoped_ptr<HttpTransaction> trans; |
6926 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6948 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
6927 | 6949 |
6928 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6950 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
6929 EXPECT_EQ(OK, callback.GetResult(rv)); | 6951 EXPECT_EQ(OK, callback.GetResult(rv)); |
6930 | 6952 |
6931 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | 6953 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); |
6932 rv = trans->Read(buf.get(), 10, callback.callback()); | 6954 rv = trans->Read(buf.get(), 10, callback.callback()); |
6933 EXPECT_EQ(callback.GetResult(rv), 10); | 6955 EXPECT_EQ(callback.GetResult(rv), 10); |
6934 | 6956 |
6935 // This is actually going to do nothing. | 6957 // This prevents any further writes to the cache entry, but doesn't discard |
| 6958 // the existing entry. |
6936 trans->StopCaching(); | 6959 trans->StopCaching(); |
6937 | 6960 |
6938 // We should be able to keep reading. | 6961 // We should be able to keep reading. |
6939 rv = trans->Read(buf.get(), 256, callback.callback()); | 6962 rv = trans->Read(buf.get(), 256, callback.callback()); |
6940 EXPECT_GT(callback.GetResult(rv), 0); | 6963 EXPECT_GT(callback.GetResult(rv), 0); |
6941 rv = trans->Read(buf.get(), 256, callback.callback()); | 6964 rv = trans->Read(buf.get(), 256, callback.callback()); |
6942 EXPECT_GT(callback.GetResult(rv), 0); | 6965 EXPECT_GT(callback.GetResult(rv), 0); |
6943 rv = trans->Read(buf.get(), 256, callback.callback()); | 6966 rv = trans->Read(buf.get(), 256, callback.callback()); |
6944 EXPECT_EQ(callback.GetResult(rv), 0); | 6967 EXPECT_EQ(callback.GetResult(rv), 0); |
6945 } | 6968 } |
6946 | 6969 |
6947 // Verify that the disk entry was updated. | 6970 // Verify that the disk entry was not updated. |
6948 disk_cache::Entry* entry; | 6971 disk_cache::Entry* entry; |
6949 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); | 6972 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); |
6950 EXPECT_EQ(80, entry->GetDataSize(1)); | 6973 EXPECT_EQ(20, entry->GetDataSize(1)); |
6951 bool truncated = true; | 6974 bool truncated = false; |
6952 HttpResponseInfo response; | 6975 HttpResponseInfo response; |
6953 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); | 6976 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); |
6954 EXPECT_FALSE(truncated); | 6977 EXPECT_TRUE(truncated); |
6955 entry->Close(); | 6978 entry->Close(); |
6956 | 6979 |
6957 RemoveMockTransaction(&kRangeGET_TransactionOK); | 6980 RemoveMockTransaction(&kRangeGET_TransactionOK); |
6958 } | 6981 } |
6959 | 6982 |
| 6983 namespace { |
| 6984 |
| 6985 enum TransactionPhases { |
| 6986 TRANSACTION_PHASE_BEFORE_FIRST_READ, |
| 6987 TRANSACTION_PHASE_ON_BEFORE_NETWORK_START, |
| 6988 TRANSACTION_PHASE_AFTER_FIRST_READ, |
| 6989 TRANSACTION_PHASE_AFTER_NETWORK_READ |
| 6990 }; |
| 6991 |
| 6992 using CacheInitializer = void (*)(MockHttpCache*); |
| 6993 using HugeCacheTestConfiguration = |
| 6994 std::pair<TransactionPhases, CacheInitializer>; |
| 6995 |
| 6996 class HttpCacheHugeResourceTest |
| 6997 : public ::testing::TestWithParam<HugeCacheTestConfiguration> { |
| 6998 public: |
| 6999 static std::list<HugeCacheTestConfiguration> GetTestModes(); |
| 7000 static std::list<HugeCacheTestConfiguration> kTestModes; |
| 7001 |
| 7002 protected: |
| 7003 static void ExpectByteRangeTransactionHandler( |
| 7004 const net::HttpRequestInfo* request, |
| 7005 std::string* response_status, |
| 7006 std::string* response_headers, |
| 7007 std::string* response_data); |
| 7008 static int LargeBufferReader(int64 content_length, |
| 7009 int64 offset, |
| 7010 net::IOBuffer* buf, |
| 7011 int buf_len); |
| 7012 |
| 7013 static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */); |
| 7014 static void StopCachingOnBeforeNetworkStart(HttpTransaction* transaction, |
| 7015 bool* /* defer */); |
| 7016 |
| 7017 // CacheInitializer callbacks. These are used to initialize the cache |
| 7018 // depending on the test run configuration. |
| 7019 |
| 7020 // Initializes a cache containing a truncated entry containing the first 20 |
| 7021 // bytes of the reponse body. |
| 7022 static void SetupTruncatedCacheEntry(MockHttpCache* cache); |
| 7023 |
| 7024 // Initializes a cache containing a sparse entry. The first 10 bytes are |
| 7025 // present in the cache. |
| 7026 static void SetupPrefixSparseCacheEntry(MockHttpCache* cache); |
| 7027 |
| 7028 // Initializes a cache containing a sparse entry. The 10 bytes at offset |
| 7029 // 99999990 are present in the cache. |
| 7030 static void SetupInfixSparseCacheEntry(MockHttpCache* cache); |
| 7031 |
| 7032 // Size of resource to be tested. |
| 7033 static const int64 kTotalSize = |
| 7034 5000000000LL; // Five beeeeeelllliooonn bytes! |
| 7035 }; |
| 7036 |
| 7037 const int64 HttpCacheHugeResourceTest::kTotalSize; |
| 7038 |
| 7039 // static |
| 7040 void HttpCacheHugeResourceTest::ExpectByteRangeTransactionHandler( |
| 7041 const net::HttpRequestInfo* request, |
| 7042 std::string* response_status, |
| 7043 std::string* response_headers, |
| 7044 std::string* response_data) { |
| 7045 std::string if_range; |
| 7046 EXPECT_TRUE(request->extra_headers.GetHeader( |
| 7047 net::HttpRequestHeaders::kIfRange, &if_range)); |
| 7048 EXPECT_EQ("\"foo\"", if_range); |
| 7049 |
| 7050 std::string range_header; |
| 7051 EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange, |
| 7052 &range_header)); |
| 7053 std::vector<net::HttpByteRange> ranges; |
| 7054 |
| 7055 EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges)); |
| 7056 ASSERT_EQ(1u, ranges.size()); |
| 7057 |
| 7058 net::HttpByteRange range = ranges[0]; |
| 7059 EXPECT_TRUE(range.HasFirstBytePosition()); |
| 7060 int64 last_byte_position = |
| 7061 range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1; |
| 7062 |
| 7063 response_status->assign("HTTP/1.1 206 Partial"); |
| 7064 response_headers->assign(base::StringPrintf( |
| 7065 "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64 |
| 7066 "\n" |
| 7067 "Content-Length: %" PRId64 "\n", |
| 7068 range.first_byte_position(), last_byte_position, kTotalSize, |
| 7069 last_byte_position - range.first_byte_position() + 1)); |
| 7070 } |
| 7071 |
| 7072 // static |
| 7073 int HttpCacheHugeResourceTest::LargeBufferReader(int64 content_length, |
| 7074 int64 offset, |
| 7075 net::IOBuffer* buf, |
| 7076 int buf_len) { |
| 7077 // This test involves reading multiple gigabytes of data. To make it run in a |
| 7078 // reasonable amount of time, we are going to skip filling the buffer with |
| 7079 // data. Instead the test relies on verifying that the count of bytes expected |
| 7080 // at the end is correct. |
| 7081 EXPECT_LT(0, content_length); |
| 7082 EXPECT_LE(offset, content_length); |
| 7083 int num = std::min(static_cast<int64>(buf_len), content_length - offset); |
| 7084 return num; |
| 7085 } |
| 7086 |
| 7087 // static |
| 7088 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started, |
| 7089 bool* /* defer */) { |
| 7090 *started = true; |
| 7091 } |
| 7092 |
| 7093 // static |
| 7094 void HttpCacheHugeResourceTest::StopCachingOnBeforeNetworkStart( |
| 7095 HttpTransaction* transaction, |
| 7096 bool* /* defer */) { |
| 7097 transaction->StopCaching(); |
| 7098 } |
| 7099 |
| 7100 // static |
| 7101 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) { |
| 7102 ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK); |
| 7103 std::string cached_headers = base::StringPrintf( |
| 7104 "HTTP/1.1 200 OK\n" |
| 7105 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7106 "ETag: \"foo\"\n" |
| 7107 "Accept-Ranges: bytes\n" |
| 7108 "Content-Length: %" PRId64 "\n", |
| 7109 kTotalSize); |
| 7110 CreateTruncatedEntry(cached_headers, cache); |
| 7111 } |
| 7112 |
| 7113 // static |
| 7114 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry( |
| 7115 MockHttpCache* cache) { |
| 7116 MockTransaction transaction(kRangeGET_TransactionOK); |
| 7117 transaction.handler = nullptr; |
| 7118 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; |
| 7119 transaction.response_headers = |
| 7120 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7121 "ETag: \"foo\"\n" |
| 7122 "Accept-Ranges: bytes\n" |
| 7123 "Content-Range: bytes 0-9/5000000000\n" |
| 7124 "Content-Length: 10\n"; |
| 7125 AddMockTransaction(&transaction); |
| 7126 std::string headers; |
| 7127 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers); |
| 7128 RemoveMockTransaction(&transaction); |
| 7129 } |
| 7130 |
| 7131 // static |
| 7132 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry( |
| 7133 MockHttpCache* cache) { |
| 7134 MockTransaction transaction(kRangeGET_TransactionOK); |
| 7135 transaction.handler = nullptr; |
| 7136 transaction.request_headers = |
| 7137 "Range: bytes = 99999990-99999999\r\n" EXTRA_HEADER; |
| 7138 transaction.response_headers = |
| 7139 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7140 "ETag: \"foo\"\n" |
| 7141 "Accept-Ranges: bytes\n" |
| 7142 "Content-Range: bytes 99999990-99999999/5000000000\n" |
| 7143 "Content-Length: 10\n"; |
| 7144 AddMockTransaction(&transaction); |
| 7145 std::string headers; |
| 7146 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers); |
| 7147 RemoveMockTransaction(&transaction); |
| 7148 } |
| 7149 |
| 7150 // static |
| 7151 std::list<HugeCacheTestConfiguration> |
| 7152 HttpCacheHugeResourceTest::GetTestModes() { |
| 7153 std::list<HugeCacheTestConfiguration> test_modes; |
| 7154 const TransactionPhases kTransactionPhases[] = { |
| 7155 TRANSACTION_PHASE_BEFORE_FIRST_READ, |
| 7156 TRANSACTION_PHASE_ON_BEFORE_NETWORK_START, |
| 7157 TRANSACTION_PHASE_AFTER_FIRST_READ, TRANSACTION_PHASE_AFTER_NETWORK_READ}; |
| 7158 |
| 7159 const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry, |
| 7160 &SetupPrefixSparseCacheEntry, |
| 7161 &SetupInfixSparseCacheEntry}; |
| 7162 |
| 7163 for (const auto phase : kTransactionPhases) |
| 7164 for (const auto initializer : kInitializers) |
| 7165 test_modes.push_back(std::make_pair(phase, initializer)); |
| 7166 |
| 7167 return test_modes; |
| 7168 } |
| 7169 |
| 7170 // static |
| 7171 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes = |
| 7172 HttpCacheHugeResourceTest::GetTestModes(); |
| 7173 |
| 7174 INSTANTIATE_TEST_CASE_P( |
| 7175 _, |
| 7176 HttpCacheHugeResourceTest, |
| 7177 ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes)); |
| 7178 |
| 7179 } // namespace |
| 7180 |
| 7181 // Test what happens when StopCaching() is called while reading a huge resource |
| 7182 // fetched via GET. Various combinations of cache state and when StopCaching() |
| 7183 // is called is controlled by the parameter passed into the test via the |
| 7184 // INSTANTIATE_TEST_CASE_P invocation above. |
| 7185 TEST_P(HttpCacheHugeResourceTest, |
| 7186 StopCachingFollowedByReadForHugeTruncatedResource) { |
| 7187 // This test is going to be repeated for all combinations of TransactionPhases |
| 7188 // and CacheInitializers returned by GetTestModes(). |
| 7189 TransactionPhases stop_caching_phase = GetParam().first; |
| 7190 CacheInitializer cache_initializer = GetParam().second; |
| 7191 |
| 7192 MockHttpCache cache; |
| 7193 (*cache_initializer)(&cache); |
| 7194 |
| 7195 MockTransaction transaction(kSimpleGET_Transaction); |
| 7196 transaction.url = kRangeGET_TransactionOK.url; |
| 7197 transaction.handler = &ExpectByteRangeTransactionHandler; |
| 7198 transaction.read_handler = &LargeBufferReader; |
| 7199 ScopedMockTransaction scoped_transaction(transaction); |
| 7200 |
| 7201 MockHttpRequest request(transaction); |
| 7202 net::TestCompletionCallback callback; |
| 7203 scoped_ptr<net::HttpTransaction> http_transaction; |
| 7204 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, |
| 7205 &http_transaction); |
| 7206 ASSERT_EQ(net::OK, rv); |
| 7207 ASSERT_TRUE(http_transaction.get()); |
| 7208 |
| 7209 if (stop_caching_phase == TRANSACTION_PHASE_ON_BEFORE_NETWORK_START) |
| 7210 http_transaction->SetBeforeNetworkStartCallback( |
| 7211 base::Bind(&StopCachingOnBeforeNetworkStart, http_transaction.get())); |
| 7212 |
| 7213 bool network_transaction_started = false; |
| 7214 if (stop_caching_phase == TRANSACTION_PHASE_AFTER_NETWORK_READ) |
| 7215 http_transaction->SetBeforeNetworkStartCallback( |
| 7216 base::Bind(&SetFlagOnBeforeNetworkStart, &network_transaction_started)); |
| 7217 |
| 7218 rv = http_transaction->Start(&request, callback.callback(), |
| 7219 net::BoundNetLog()); |
| 7220 rv = callback.GetResult(rv); |
| 7221 ASSERT_EQ(net::OK, rv); |
| 7222 |
| 7223 if (stop_caching_phase == TRANSACTION_PHASE_BEFORE_FIRST_READ) |
| 7224 http_transaction->StopCaching(); |
| 7225 |
| 7226 int64 total_bytes_received = 0; |
| 7227 |
| 7228 EXPECT_EQ(kTotalSize, |
| 7229 http_transaction->GetResponseInfo()->headers->GetContentLength()); |
| 7230 do { |
| 7231 // This test simulates reading Gigabytes of data. Buffer size is set to 1MB |
| 7232 // to reduce the number of reads and speedup the test. |
| 7233 const int kBufferSize = 1024 * 1024; |
| 7234 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7235 rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback()); |
| 7236 rv = callback.GetResult(rv); |
| 7237 |
| 7238 if (stop_caching_phase == TRANSACTION_PHASE_AFTER_FIRST_READ && |
| 7239 total_bytes_received == 0) |
| 7240 http_transaction->StopCaching(); |
| 7241 |
| 7242 if (rv > 0) |
| 7243 total_bytes_received += rv; |
| 7244 |
| 7245 if (network_transaction_started && |
| 7246 stop_caching_phase == TRANSACTION_PHASE_AFTER_NETWORK_READ) { |
| 7247 http_transaction->StopCaching(); |
| 7248 network_transaction_started = false; |
| 7249 } |
| 7250 } while (rv > 0); |
| 7251 |
| 7252 // The only verification we are going to do is that the received resource has |
| 7253 // the correct size. This is sufficient to verify that the state machine |
| 7254 // didn't terminate abruptly due to the StopCaching() call. |
| 7255 EXPECT_EQ(kTotalSize, total_bytes_received); |
| 7256 } |
| 7257 |
| 7258 TEST(HttpCache, StopCachingReleasesCacheLockForNonResumableRequest) { |
| 7259 MockHttpCache cache; |
| 7260 TestCompletionCallback callback; |
| 7261 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction); |
| 7262 MockHttpRequest mock_request(mock_transaction); |
| 7263 const int kContentLength = std::string(mock_transaction.data).size(); |
| 7264 |
| 7265 scoped_ptr<HttpTransaction> transaction; |
| 7266 int rv = cache.CreateTransaction(&transaction); |
| 7267 ASSERT_EQ(OK, rv); |
| 7268 ASSERT_TRUE(transaction.get()); |
| 7269 |
| 7270 rv = transaction->Start(&mock_request, callback.callback(), BoundNetLog()); |
| 7271 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7272 |
| 7273 transaction->StopCaching(); |
| 7274 |
| 7275 const int kBufferSize = 1024; |
| 7276 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7277 rv = transaction->Read(buf.get(), 10, callback.callback()); |
| 7278 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7279 |
| 7280 // The cache entry should be gone by now because the request can't be resumed. |
| 7281 // |transaction| is still active and hasn't reached EOF. The test fails if the |
| 7282 // previous Read() or Start() didn't result in the cache entry being released |
| 7283 // and destroyed. |
| 7284 disk_cache::Entry* entry = nullptr; |
| 7285 EXPECT_FALSE(cache.OpenBackendEntry(mock_transaction.url, &entry)); |
| 7286 EXPECT_EQ(0, cache.disk_cache()->GetEntryCount()); |
| 7287 |
| 7288 // The transaction should still be able to continue reading till the end of |
| 7289 // the resource is reached. |
| 7290 rv = transaction->Read(buf.get(), kBufferSize, callback.callback()); |
| 7291 |
| 7292 // The final read should return the remainder of the resource excluding the 10 |
| 7293 // bytes already read. |
| 7294 EXPECT_EQ(kContentLength - 10, callback.GetResult(rv)); |
| 7295 |
| 7296 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 7297 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 7298 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 7299 } |
| 7300 |
| 7301 namespace { |
| 7302 |
| 7303 const MockTransaction kResumableGET_Transaction = { |
| 7304 kRangeGET_TransactionOK.url, "GET", base::Time(), EXTRA_HEADER, 0, |
| 7305 "HTTP/1.1 200 OK", |
| 7306 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7307 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n" |
| 7308 "ETag: \"foo\"\n" |
| 7309 "Accept-Ranges: bytes\n" |
| 7310 "Content-Length: 80\n", |
| 7311 base::Time(), kFullRangeData, TEST_MODE_NORMAL, |
| 7312 &RangeTransactionServer::RangeHandler}; |
| 7313 |
| 7314 } // namespace |
| 7315 |
| 7316 TEST(HttpCache, StopCachingReleasesCacheLockForResumableNotCachedRequest) { |
| 7317 MockHttpCache cache; |
| 7318 TestCompletionCallback callback; |
| 7319 ScopedMockTransaction mock_transaction(kResumableGET_Transaction); |
| 7320 MockHttpRequest mock_request(mock_transaction); |
| 7321 |
| 7322 scoped_ptr<HttpTransaction> transaction; |
| 7323 int rv = cache.CreateTransaction(&transaction); |
| 7324 ASSERT_EQ(OK, rv); |
| 7325 ASSERT_TRUE(transaction.get()); |
| 7326 |
| 7327 rv = transaction->Start(&mock_request, callback.callback(), BoundNetLog()); |
| 7328 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7329 |
| 7330 const int kBufferSize = 1024; |
| 7331 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7332 rv = transaction->Read(buf.get(), 10, callback.callback()); |
| 7333 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7334 |
| 7335 transaction->StopCaching(); |
| 7336 |
| 7337 rv = transaction->Read(buf.get(), 10, callback.callback()); |
| 7338 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7339 |
| 7340 // Similar to the above test, but the cache entry still exists at this point |
| 7341 // because the request is resumable. The expectation is that the cache entry |
| 7342 // has been released at this point due the earlier Start()/Read() calls. Since |
| 7343 // the cache is released, we can start another transaction. The Start() call |
| 7344 // should succeed without any delay. The test should timeout if this is not |
| 7345 // the case (i.e. the Start() call has to wait indefinitely[*] for the |
| 7346 // previuos transaction to release the lock). |
| 7347 // |
| 7348 // [*]: The wait isn't really indefinite since the Start() call times out |
| 7349 // (currently after 20 seconds) and proceeds without the cache entry. This |
| 7350 // case is accounted for by the network_layer()->transaction_count() |
| 7351 // expectation below. |
| 7352 |
| 7353 scoped_ptr<HttpTransaction> second_transaction; |
| 7354 rv = cache.CreateTransaction(&second_transaction); |
| 7355 ASSERT_EQ(OK, rv); |
| 7356 ASSERT_TRUE(second_transaction); |
| 7357 rv = second_transaction->Start(&mock_request, callback.callback(), |
| 7358 BoundNetLog()); |
| 7359 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7360 |
| 7361 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 7362 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 7363 EXPECT_EQ(1, cache.disk_cache()->GetEntryCount()); |
| 7364 |
| 7365 // Initial network request + validation request for the second transaction. |
| 7366 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 7367 } |
| 7368 |
| 7369 TEST(HttpCache, StopCachingReleasesCacheLockForResumableTruncatedEntry) { |
| 7370 MockHttpCache cache; |
| 7371 TestCompletionCallback callback; |
| 7372 ScopedMockTransaction mock_transaction(kResumableGET_Transaction); |
| 7373 MockHttpRequest mock_request(kResumableGET_Transaction); |
| 7374 std::string raw_headers( |
| 7375 "HTTP/1.1 200 OK\n" |
| 7376 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7377 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n" |
| 7378 "ETag: \"foo\"\n" |
| 7379 "Accept-Ranges: bytes\n" |
| 7380 "Content-Length: 80\n"); |
| 7381 CreateTruncatedEntry(raw_headers, &cache); |
| 7382 |
| 7383 scoped_ptr<HttpTransaction> transaction; |
| 7384 int rv = cache.CreateTransaction(&transaction); |
| 7385 ASSERT_EQ(OK, rv); |
| 7386 ASSERT_TRUE(transaction.get()); |
| 7387 |
| 7388 rv = transaction->Start(&mock_request, callback.callback(), BoundNetLog()); |
| 7389 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7390 |
| 7391 transaction->StopCaching(); |
| 7392 |
| 7393 const int kBufferSize = 1024; |
| 7394 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7395 rv = transaction->Read(buf.get(), 20, callback.callback()); |
| 7396 EXPECT_EQ(20, callback.GetResult(rv)); |
| 7397 |
| 7398 // This request hits the network and causes the cache lock to be released. We |
| 7399 // don't expect the cache lock to be released until the final network range |
| 7400 // request is issued and begins streaming the body. |
| 7401 rv = transaction->Read(buf.get(), 10, callback.callback()); |
| 7402 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7403 |
| 7404 // Now that the cache lock is released, another transaction can begin. The |
| 7405 // Start() call should complete without delay. The test should timeout if this |
| 7406 // is not the case (i.e. the Start() call has to wait indefinitely[*] for the |
| 7407 // previous transaction to release the lock). |
| 7408 // |
| 7409 // [*]: The wait isn't really indefinite since the Start() call times out |
| 7410 // (currently after 20 seconds) and proceeds without the cache entry. This |
| 7411 // case is accounted for by the network_layer()->transaction_count() |
| 7412 // expectation below. |
| 7413 |
| 7414 scoped_ptr<HttpTransaction> second_transaction; |
| 7415 rv = cache.CreateTransaction(&second_transaction); |
| 7416 ASSERT_EQ(OK, rv); |
| 7417 ASSERT_TRUE(second_transaction); |
| 7418 rv = second_transaction->Start(&mock_request, callback.callback(), |
| 7419 BoundNetLog()); |
| 7420 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7421 |
| 7422 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 7423 EXPECT_EQ(2, cache.disk_cache()->open_count()); |
| 7424 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 7425 EXPECT_EQ(1, cache.disk_cache()->GetEntryCount()); |
| 7426 } |
| 7427 |
6960 // Tests that we detect truncated resources from the net when there is | 7428 // Tests that we detect truncated resources from the net when there is |
6961 // a Content-Length header. | 7429 // a Content-Length header. |
6962 TEST(HttpCache, TruncatedByContentLength) { | 7430 TEST(HttpCache, TruncatedByContentLength) { |
6963 MockHttpCache cache; | 7431 MockHttpCache cache; |
6964 TestCompletionCallback callback; | 7432 TestCompletionCallback callback; |
6965 | 7433 |
6966 MockTransaction transaction(kSimpleGET_Transaction); | 7434 MockTransaction transaction(kSimpleGET_Transaction); |
6967 AddMockTransaction(&transaction); | 7435 AddMockTransaction(&transaction); |
6968 transaction.response_headers = "Cache-Control: max-age=10000\n" | 7436 transaction.response_headers = "Cache-Control: max-age=10000\n" |
6969 "Content-Length: 100\n"; | 7437 "Content-Length: 100\n"; |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7554 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 8022 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
7555 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 8023 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
7556 EXPECT_TRUE(response_info.was_cached); | 8024 EXPECT_TRUE(response_info.was_cached); |
7557 | 8025 |
7558 // The new SSL state is reported. | 8026 // The new SSL state is reported. |
7559 EXPECT_EQ(status2, response_info.ssl_info.connection_status); | 8027 EXPECT_EQ(status2, response_info.ssl_info.connection_status); |
7560 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); | 8028 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); |
7561 } | 8029 } |
7562 | 8030 |
7563 } // namespace net | 8031 } // namespace net |
OLD | NEW |