Chromium Code Reviews| 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")) { |
|
rvargas (doing something else)
2015/09/15 01:07:38
nit: maybe X-No-Ranges ?
rvargas (doing something else)
2015/09/15 01:07:39
Document new headers at line 311.
asanka
2015/09/17 21:59:41
Done. And documented the header at line 311.
| |
| 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); | |
|
rvargas (doing something else)
2015/09/15 01:07:39
I'm worried that returning "correct" data by defau
| |
| 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 | |
|
rvargas (doing something else)
2015/09/15 01:07:39
nit: keep this line.
asanka
2015/09/17 21:59:41
Done.
| |
| 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; | |
|
rvargas (doing something else)
2015/09/15 01:07:39
nit: do we really need the new #defines? I feel li
asanka
2015/09/17 21:59:41
Hmm. I see what you mean. Should I remove the othe
rvargas (doing something else)
2015/09/19 01:09:34
Do you mean EXTRA_HEADER? I think that was added t
| |
| 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6217 | 6235 |
| 6218 MockHttpRequest request(kTestTransaction); | 6236 MockHttpRequest request(kTestTransaction); |
| 6219 TestCompletionCallback callback; | 6237 TestCompletionCallback callback; |
| 6220 | 6238 |
| 6221 // Write to the cache. | 6239 // Write to the cache. |
| 6222 { | 6240 { |
| 6223 scoped_ptr<HttpTransaction> trans; | 6241 scoped_ptr<HttpTransaction> trans; |
| 6224 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6242 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
| 6225 | 6243 |
| 6226 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6244 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
| 6227 if (rv == ERR_IO_PENDING) | 6245 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 6228 rv = callback.WaitForResult(); | |
| 6229 ASSERT_EQ(OK, rv); | |
| 6230 | 6246 |
| 6231 const HttpResponseInfo* info = trans->GetResponseInfo(); | 6247 const HttpResponseInfo* info = trans->GetResponseInfo(); |
| 6232 ASSERT_TRUE(info); | 6248 ASSERT_TRUE(info); |
| 6233 | 6249 |
| 6234 EXPECT_EQ(info->headers->response_code(), 301); | 6250 EXPECT_EQ(info->headers->response_code(), 301); |
| 6235 | 6251 |
| 6236 std::string location; | 6252 std::string location; |
| 6237 info->headers->EnumerateHeader(NULL, "Location", &location); | 6253 info->headers->EnumerateHeader(NULL, "Location", &location); |
| 6238 EXPECT_EQ(location, "http://www.bar.com/"); | 6254 EXPECT_EQ(location, "http://www.bar.com/"); |
| 6239 | 6255 |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6739 base::MessageLoop::current()->RunUntilIdle(); | 6755 base::MessageLoop::current()->RunUntilIdle(); |
| 6740 | 6756 |
| 6741 // Read from the cache. This should not deadlock. | 6757 // Read from the cache. This should not deadlock. |
| 6742 RunTransactionTest(cache.http_cache(), transaction); | 6758 RunTransactionTest(cache.http_cache(), transaction); |
| 6743 | 6759 |
| 6744 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6760 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6745 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6761 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 6746 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 6762 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 6747 } | 6763 } |
| 6748 | 6764 |
| 6749 // Tests that we stop caching when told. | 6765 // Tests that we stop caching when told, even if DoneReading is called after |
| 6750 TEST(HttpCache, StopCachingDeletesEntry) { | 6766 // StopCaching. |
|
rvargas (doing something else)
2015/09/15 01:07:39
I'm curious about what fails with this test now. O
asanka
2015/09/17 21:59:41
It was testing whether StopCaching() deletes non-r
| |
| 6751 MockHttpCache cache; | |
| 6752 TestCompletionCallback callback; | |
| 6753 MockHttpRequest request(kSimpleGET_Transaction); | |
| 6754 | |
| 6755 { | |
| 6756 scoped_ptr<HttpTransaction> trans; | |
| 6757 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | |
| 6758 | |
| 6759 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | |
| 6760 EXPECT_EQ(OK, callback.GetResult(rv)); | |
| 6761 | |
| 6762 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | |
| 6763 rv = trans->Read(buf.get(), 10, callback.callback()); | |
| 6764 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 6765 | |
| 6766 trans->StopCaching(); | |
| 6767 | |
| 6768 // We should be able to keep reading. | |
| 6769 rv = trans->Read(buf.get(), 256, callback.callback()); | |
| 6770 EXPECT_GT(callback.GetResult(rv), 0); | |
| 6771 rv = trans->Read(buf.get(), 256, callback.callback()); | |
| 6772 EXPECT_EQ(0, callback.GetResult(rv)); | |
| 6773 } | |
| 6774 | |
| 6775 // Make sure that the ActiveEntry is gone. | |
| 6776 base::MessageLoop::current()->RunUntilIdle(); | |
| 6777 | |
| 6778 // Verify that the entry is gone. | |
| 6779 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | |
| 6780 | |
| 6781 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | |
| 6782 EXPECT_EQ(0, cache.disk_cache()->open_count()); | |
| 6783 EXPECT_EQ(2, cache.disk_cache()->create_count()); | |
| 6784 } | |
| 6785 | |
| 6786 // Tests that we stop caching when told, even if DoneReading is called | |
| 6787 // after StopCaching. | |
| 6788 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) { | 6767 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) { |
| 6789 MockHttpCache cache; | 6768 MockHttpCache cache; |
| 6790 TestCompletionCallback callback; | 6769 TestCompletionCallback callback; |
| 6791 MockHttpRequest request(kSimpleGET_Transaction); | 6770 MockHttpRequest request(kSimpleGET_Transaction); |
| 6792 | 6771 |
| 6793 { | 6772 { |
| 6794 scoped_ptr<HttpTransaction> trans; | 6773 scoped_ptr<HttpTransaction> trans; |
| 6795 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6774 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
| 6796 | 6775 |
| 6797 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6776 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6852 base::MessageLoop::current()->RunUntilIdle(); | 6831 base::MessageLoop::current()->RunUntilIdle(); |
| 6853 | 6832 |
| 6854 // Verify that the entry is gone. | 6833 // Verify that the entry is gone. |
| 6855 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 6834 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 6856 | 6835 |
| 6857 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6836 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 6858 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 6837 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 6859 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 6838 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 6860 } | 6839 } |
| 6861 | 6840 |
| 6862 // Tests that when we are told to stop caching we don't throw away valid data. | 6841 // Even if the request is resumable, the cache is still going to throw away the |
| 6863 TEST(HttpCache, StopCachingSavesEntry) { | 6842 // partial entry if StopCaching() is called. This is done on the assumption that |
| 6843 // such an entry is unlikely to be consumed from the cache again. | |
| 6844 TEST(HttpCache, StopCachingDeletesNewEntry) { | |
| 6864 MockHttpCache cache; | 6845 MockHttpCache cache; |
| 6865 TestCompletionCallback callback; | 6846 TestCompletionCallback callback; |
| 6866 MockHttpRequest request(kSimpleGET_Transaction); | 6847 MockHttpRequest request(kSimpleGET_Transaction); |
| 6867 | 6848 |
| 6868 { | 6849 scoped_ptr<HttpTransaction> transaction; |
| 6869 scoped_ptr<HttpTransaction> trans; | 6850 ASSERT_EQ(OK, cache.CreateTransaction(&transaction)); |
| 6870 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | |
| 6871 | 6851 |
| 6872 // Force a response that can be resumed. | 6852 MockTransaction mock_transaction(kSimpleGET_Transaction); |
| 6873 MockTransaction mock_transaction(kSimpleGET_Transaction); | 6853 AddMockTransaction(&mock_transaction); |
| 6874 AddMockTransaction(&mock_transaction); | 6854 mock_transaction.response_headers = |
| 6875 mock_transaction.response_headers = "Cache-Control: max-age=10000\n" | 6855 "Cache-Control: max-age=10000\n" |
| 6876 "Content-Length: 42\n" | 6856 "Content-Length: 42\n" |
| 6877 "Etag: \"foo\"\n"; | 6857 "Accept-Ranges: bytes\n" |
| 6858 "Etag: \"foo\"\n"; | |
| 6859 int rv = transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 6860 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 6878 | 6861 |
| 6879 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6862 const size_t kBufferSize = 256; |
| 6880 EXPECT_EQ(OK, callback.GetResult(rv)); | 6863 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufferSize)); |
| 6864 rv = transaction->Read(buf.get(), 10, callback.callback()); | |
| 6865 EXPECT_EQ(callback.GetResult(rv), 10); | |
| 6881 | 6866 |
| 6882 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | 6867 transaction->StopCaching(); |
| 6883 rv = trans->Read(buf.get(), 10, callback.callback()); | |
| 6884 EXPECT_EQ(callback.GetResult(rv), 10); | |
| 6885 | 6868 |
| 6886 trans->StopCaching(); | 6869 // Should still be able to read the remainder of the resource. Data should |
| 6870 // still be coming from the same network request, which as asserted by the | |
| 6871 // network_layer()->transaction_count() test below. | |
| 6872 rv = transaction->Read(buf.get(), kBufferSize, callback.callback()); | |
| 6873 EXPECT_EQ(32, callback.GetResult(rv)); | |
| 6874 rv = transaction->Read(buf.get(), kBufferSize, callback.callback()); | |
| 6875 EXPECT_EQ(0, callback.GetResult(rv)); | |
| 6887 | 6876 |
| 6888 // We should be able to keep reading. | 6877 RemoveMockTransaction(&mock_transaction); |
| 6889 rv = trans->Read(buf.get(), 256, callback.callback()); | |
| 6890 EXPECT_GT(callback.GetResult(rv), 0); | |
| 6891 rv = trans->Read(buf.get(), 256, callback.callback()); | |
| 6892 EXPECT_EQ(callback.GetResult(rv), 0); | |
| 6893 | 6878 |
| 6894 RemoveMockTransaction(&mock_transaction); | 6879 // At this point, the cache entry should be gone. It should've been doomed and |
| 6895 } | 6880 // released during the previous Read() cycles. |
| 6881 disk_cache::Entry* cache_entry = nullptr; | |
| 6882 ASSERT_FALSE( | |
| 6883 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &cache_entry)); | |
| 6884 EXPECT_EQ(1, cache.disk_cache()->create_count()); | |
| 6885 EXPECT_EQ(0, cache.disk_cache()->open_count()); | |
| 6896 | 6886 |
| 6897 // Verify that the entry is marked as incomplete. | 6887 // StopCaching shouldn't cause any additional network requests. |
| 6898 disk_cache::Entry* entry; | 6888 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6899 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); | |
| 6900 HttpResponseInfo response; | |
| 6901 bool truncated = false; | |
| 6902 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); | |
| 6903 EXPECT_TRUE(truncated); | |
| 6904 entry->Close(); | |
| 6905 } | 6889 } |
| 6906 | 6890 |
| 6907 // Tests that we handle truncated enries when StopCaching is called. | 6891 // If the request was being fulfilled via a truncated cache entry, and the |
| 6908 TEST(HttpCache, StopCachingTruncatedEntry) { | 6892 // client calls StopCaching(), the transaction should remove the truncated cache |
| 6893 // entry. | |
| 6894 TEST(HttpCache, StopCachingRemovesPreviousTruncatedEntry) { | |
| 6909 MockHttpCache cache; | 6895 MockHttpCache cache; |
| 6910 TestCompletionCallback callback; | 6896 TestCompletionCallback callback; |
| 6911 MockHttpRequest request(kRangeGET_TransactionOK); | 6897 MockHttpRequest request(kRangeGET_TransactionOK); |
| 6912 request.extra_headers.Clear(); | 6898 request.extra_headers.Clear(); |
| 6913 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); | 6899 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); |
| 6914 AddMockTransaction(&kRangeGET_TransactionOK); | 6900 AddMockTransaction(&kRangeGET_TransactionOK); |
| 6915 | 6901 |
| 6916 std::string raw_headers("HTTP/1.1 200 OK\n" | 6902 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 6917 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 6903 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 6918 "ETag: \"foo\"\n" | 6904 "ETag: \"foo\"\n" |
| 6919 "Accept-Ranges: bytes\n" | 6905 "Accept-Ranges: bytes\n" |
| 6920 "Content-Length: 80\n"); | 6906 "Content-Length: 80\n"); |
| 6921 CreateTruncatedEntry(raw_headers, &cache); | 6907 CreateTruncatedEntry(raw_headers, &cache); |
| 6922 | 6908 cache.ResetCounts(); |
| 6923 { | 6909 |
| 6924 // Now make a regular request. | 6910 // Now make a regular request. |
| 6925 scoped_ptr<HttpTransaction> trans; | 6911 scoped_ptr<HttpTransaction> transaction; |
| 6926 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6912 ASSERT_EQ(OK, cache.CreateTransaction(&transaction)); |
| 6927 | 6913 |
| 6928 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6914 int rv = transaction->Start(&request, callback.callback(), BoundNetLog()); |
| 6929 EXPECT_EQ(OK, callback.GetResult(rv)); | 6915 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 6930 | 6916 // Start() should send a single byte range request to validate the truncated |
| 6931 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | 6917 // cache entry. |
| 6932 rv = trans->Read(buf.get(), 10, callback.callback()); | 6918 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6933 EXPECT_EQ(callback.GetResult(rv), 10); | 6919 |
| 6934 | 6920 const size_t kBufferSize = 256; |
| 6935 // This is actually going to do nothing. | 6921 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufferSize)); |
| 6936 trans->StopCaching(); | 6922 |
| 6937 | 6923 // The size of the resource is 80 bytes. The first 20 should be available in |
| 6938 // We should be able to keep reading. | 6924 // the truncated cache entry. Let's read the first 10 bytes which should all |
| 6939 rv = trans->Read(buf.get(), 256, callback.callback()); | 6925 // come from the cache. |
| 6940 EXPECT_GT(callback.GetResult(rv), 0); | 6926 rv = transaction->Read(buf.get(), 10, callback.callback()); |
| 6941 rv = trans->Read(buf.get(), 256, callback.callback()); | 6927 EXPECT_EQ(callback.GetResult(rv), 10); |
| 6942 EXPECT_GT(callback.GetResult(rv), 0); | 6928 |
| 6943 rv = trans->Read(buf.get(), 256, callback.callback()); | 6929 transaction->StopCaching(); |
| 6944 EXPECT_EQ(callback.GetResult(rv), 0); | 6930 |
| 6931 // We should be able to keep reading. The previous StopCaching() call switches | |
| 6932 // the transaction over to a network read. Hence the next read should slurp in | |
| 6933 // the remainder of the resource from the network. | |
| 6934 rv = transaction->Read(buf.get(), kBufferSize, callback.callback()); | |
| 6935 EXPECT_EQ(callback.GetResult(rv), 70); | |
| 6936 rv = transaction->Read(buf.get(), kBufferSize, callback.callback()); | |
| 6937 EXPECT_EQ(callback.GetResult(rv), 0); | |
| 6938 | |
| 6939 // The cache entry should be gone now. | |
| 6940 disk_cache::Entry* entry = nullptr; | |
| 6941 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); | |
| 6942 | |
| 6943 // Transaction opens existing entry, but doesn't create any new entries. | |
| 6944 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 6945 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 6946 | |
| 6947 // Two network requests: | |
| 6948 // - 1 request for validation. | |
| 6949 // - 1 request for the range 10-. | |
| 6950 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | |
| 6951 RemoveMockTransaction(&kRangeGET_TransactionOK); | |
| 6952 } | |
| 6953 | |
| 6954 TEST(HttpCache, StopCachingKeepsSparseEntry) { | |
| 6955 MockHttpCache cache; | |
| 6956 TestCompletionCallback callback; | |
| 6957 | |
| 6958 // Create a sparse entry which contains 10 bytes at offset 20 out of an 80 | |
| 6959 // byte resource. | |
| 6960 MockTransaction mock_transaction(kRangeGET_TransactionOK); | |
| 6961 mock_transaction.handler = nullptr; | |
| 6962 mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER; | |
| 6963 mock_transaction.response_headers = | |
| 6964 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 6965 "ETag: \"foo\"\n" | |
| 6966 "Accept-Ranges: bytes\n" | |
| 6967 "Content-Range: bytes 20-29/80\n" | |
| 6968 "Content-Length: 10\n"; | |
| 6969 mock_transaction.data = "rg: 20-29 "; | |
| 6970 AddMockTransaction(&mock_transaction); | |
| 6971 std::string headers; | |
| 6972 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction, | |
| 6973 &headers); | |
| 6974 | |
| 6975 // Verify our assumptions. There should be sparse entry here. | |
| 6976 disk_cache::Entry* cache_entry; | |
| 6977 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); | |
| 6978 EXPECT_TRUE(cache_entry->CouldBeSparse()); | |
| 6979 cache_entry->Close(); | |
| 6980 RemoveMockTransaction(&mock_transaction); | |
| 6981 | |
| 6982 cache.ResetCounts(); | |
| 6983 | |
| 6984 // Prepare a request to read the entire contents of the resource. This should | |
| 6985 // usually hope between network -> cache -> network. But not today. | |
| 6986 mock_transaction.request_headers = EXTRA_HEADER; | |
| 6987 mock_transaction.handler = kRangeGET_TransactionOK.handler; | |
| 6988 mock_transaction.response_headers = | |
| 6989 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 6990 "ETag: \"foo\"\n" | |
| 6991 "Accept-Ranges: bytes\n" | |
| 6992 "Content-Length: 80\n"; | |
| 6993 AddMockTransaction(&mock_transaction); | |
| 6994 MockHttpRequest request(mock_transaction); | |
| 6995 | |
| 6996 scoped_ptr<HttpTransaction> transaction; | |
| 6997 ASSERT_EQ(OK, cache.CreateTransaction(&transaction)); | |
| 6998 int rv = transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 6999 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7000 | |
| 7001 const size_t kBufferSize = 256; | |
| 7002 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); | |
| 7003 | |
| 7004 rv = transaction->Read(buffer.get(), 10, callback.callback()); | |
| 7005 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 7006 | |
| 7007 // This should've caused a network read of 10 bytes. | |
| 7008 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | |
| 7009 | |
| 7010 // StopCaching() should cause the transaction to switch entirely to the | |
| 7011 // network for the remainder of the response. Since the existing network | |
| 7012 // transaction doesn't cover the entirety of the resource, the cache creates a | |
| 7013 // new network transaction. | |
| 7014 transaction->StopCaching(); | |
| 7015 | |
| 7016 // Since it's coming from a single network request, we can slurp the remainder | |
| 7017 // of the resource in one request. | |
| 7018 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); | |
| 7019 EXPECT_EQ(70, callback.GetResult(rv)); | |
| 7020 | |
| 7021 // And we hit EOF. | |
| 7022 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); | |
| 7023 EXPECT_EQ(0, callback.GetResult(rv)); | |
| 7024 | |
| 7025 // Another network transaction is issued for the remainder of the resource | |
| 7026 // following the StopCaching call. | |
| 7027 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | |
| 7028 | |
| 7029 // And the sparse entry is still here. | |
| 7030 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); | |
| 7031 cache_entry->Close(); | |
| 7032 RemoveMockTransaction(&mock_transaction); | |
| 7033 } | |
| 7034 | |
| 7035 // If StopCaching() is called while serving the entire request out of cache, the | |
| 7036 // transaction is expected to ignore the StopCaching() call and continue serving | |
| 7037 // the remainder of the resource out of the cache. | |
| 7038 TEST(HttpCache, StopCachingKeepsFullEntry) { | |
| 7039 MockHttpCache cache; | |
| 7040 TestCompletionCallback callback; | |
| 7041 | |
| 7042 MockTransaction mock_transaction(kRangeGET_TransactionOK); | |
| 7043 mock_transaction.handler = nullptr; | |
| 7044 mock_transaction.request_headers = EXTRA_HEADER; | |
| 7045 mock_transaction.status = "HTTP/1.1 200 OK"; | |
| 7046 mock_transaction.response_headers = | |
| 7047 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7048 "ETag: \"foo\"\n" | |
| 7049 "Content-Length: 80\n"; | |
| 7050 mock_transaction.data = kFullRangeData; | |
| 7051 AddMockTransaction(&mock_transaction); | |
| 7052 std::string headers; | |
| 7053 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction, | |
| 7054 &headers); | |
| 7055 | |
| 7056 cache.ResetCounts(); | |
| 7057 | |
| 7058 mock_transaction.request_headers = EXTRA_HEADER; | |
| 7059 mock_transaction.handler = kRangeGET_TransactionOK.handler; | |
| 7060 mock_transaction.response_headers = | |
| 7061 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7062 "ETag: \"foo\"\n" | |
| 7063 "Accept-Ranges: bytes\n" | |
| 7064 "Content-Length: 80\n"; | |
| 7065 AddMockTransaction(&mock_transaction); | |
| 7066 MockHttpRequest request(mock_transaction); | |
| 7067 | |
| 7068 scoped_ptr<HttpTransaction> transaction; | |
| 7069 ASSERT_EQ(OK, cache.CreateTransaction(&transaction)); | |
| 7070 int rv = transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7071 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7072 | |
| 7073 const size_t kBufferSize = 256; | |
| 7074 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); | |
| 7075 | |
| 7076 rv = transaction->Read(buffer.get(), 10, callback.callback()); | |
| 7077 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 7078 | |
| 7079 // This should've caused a cache read of 10 bytes. No new network transactions | |
| 7080 // are expected. | |
| 7081 EXPECT_EQ(0, cache.network_layer()->transaction_count()); | |
| 7082 | |
| 7083 // StopCaching() doesn't do anything because the entire resource is cached | |
| 7084 // already. We proceed with the cache read. | |
| 7085 transaction->StopCaching(); | |
| 7086 | |
| 7087 // Since it's all coming from a single network request, we can slurp the | |
| 7088 // remainder of the resource in one request. | |
| 7089 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); | |
| 7090 EXPECT_EQ(70, callback.GetResult(rv)); | |
| 7091 | |
| 7092 // And we hit EOF. | |
| 7093 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); | |
| 7094 EXPECT_EQ(0, callback.GetResult(rv)); | |
| 7095 | |
| 7096 // We should've only seen one network transactions at this point. | |
| 7097 EXPECT_EQ(0, cache.network_layer()->transaction_count()); | |
| 7098 | |
| 7099 // And the entry is still here. | |
| 7100 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7101 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7102 disk_cache::Entry* cache_entry; | |
| 7103 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); | |
| 7104 cache_entry->Close(); | |
| 7105 | |
| 7106 RemoveMockTransaction(&mock_transaction); | |
| 7107 } | |
| 7108 | |
| 7109 namespace { | |
| 7110 | |
| 7111 const MockTransaction kResumableGET_Transaction = { | |
| 7112 kRangeGET_TransactionOK.url, "GET", base::Time(), EXTRA_HEADER, 0, | |
|
rvargas (doing something else)
2015/09/15 01:07:39
nit: can we use one line per member here?
asanka
2015/09/17 21:59:41
git cl format.
| |
| 7113 "HTTP/1.1 200 OK", | |
| 7114 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7115 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n" | |
| 7116 "ETag: \"foo\"\n" | |
| 7117 "Accept-Ranges: bytes\n" | |
| 7118 "Content-Length: 80\n", | |
| 7119 base::Time(), kFullRangeData, TEST_MODE_NORMAL, | |
| 7120 &RangeTransactionServer::RangeHandler}; | |
|
rvargas (doing something else)
2015/09/15 01:07:39
declare all members.
| |
| 7121 | |
| 7122 } // namespace | |
| 7123 | |
| 7124 TEST(HttpCache, StopCachingReleasesCacheLockForNewCacheEntry) { | |
| 7125 MockHttpCache cache; | |
| 7126 TestCompletionCallback callback; | |
| 7127 ScopedMockTransaction mock_transaction(kResumableGET_Transaction); | |
| 7128 MockHttpRequest mock_request(mock_transaction); | |
| 7129 | |
| 7130 scoped_ptr<HttpTransaction> first_transaction; | |
| 7131 ASSERT_EQ(OK, cache.CreateTransaction(&first_transaction)); | |
| 7132 | |
| 7133 int rv = first_transaction->Start(&mock_request, callback.callback(), | |
| 7134 BoundNetLog()); | |
| 7135 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7136 | |
| 7137 const size_t kBufferSize = 1024; | |
| 7138 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); | |
| 7139 rv = first_transaction->Read(buf.get(), 10, callback.callback()); | |
| 7140 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 7141 | |
| 7142 first_transaction->StopCaching(); | |
| 7143 | |
| 7144 rv = first_transaction->Read(buf.get(), 10, callback.callback()); | |
| 7145 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 7146 | |
| 7147 // Since the cache entry is no longer locked by |first_transaction|, we can | |
| 7148 // start another transaction without blocking. The test should time out if | |
| 7149 // this is not the case (i.e. the Start() call has to wait indefinitely[*] | |
| 7150 // for the previous transaction to release the lock). | |
| 7151 // | |
| 7152 // [*]: The wait isn't really indefinite since the Start() call times out | |
| 7153 // (currently after 20 seconds) and proceeds without the cache entry. Failure | |
| 7154 // to release the cahe entry is accounted for by the previous | |
| 7155 // disk_cache()->GetEntryCount() expectation. | |
| 7156 scoped_ptr<HttpTransaction> second_transaction; | |
| 7157 ASSERT_EQ(OK, cache.CreateTransaction(&second_transaction)); | |
| 7158 rv = second_transaction->Start(&mock_request, callback.callback(), | |
| 7159 BoundNetLog()); | |
| 7160 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7161 | |
| 7162 // The first cache entry was gone by the time second_transaction started. | |
| 7163 // Hence each transaction creates a cache entry. | |
| 7164 EXPECT_EQ(2, cache.disk_cache()->create_count()); | |
| 7165 EXPECT_EQ(0, cache.disk_cache()->open_count()); | |
| 7166 | |
| 7167 // The cache entry from second_transaction is still around. | |
| 7168 disk_cache::Entry* cache_entry = nullptr; | |
| 7169 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); | |
| 7170 cache_entry->Close(); | |
| 7171 | |
| 7172 // One network request for each cache transaction. | |
| 7173 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | |
| 7174 } | |
| 7175 | |
| 7176 TEST(HttpCache, StopCachingReleasesCacheLockForTruncatedEntry) { | |
| 7177 MockHttpCache cache; | |
| 7178 TestCompletionCallback callback; | |
| 7179 ScopedMockTransaction mock_transaction(kResumableGET_Transaction); | |
| 7180 MockHttpRequest mock_request(kResumableGET_Transaction); | |
| 7181 std::string raw_headers( | |
| 7182 "HTTP/1.1 200 OK\n" | |
| 7183 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7184 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n" | |
| 7185 "ETag: \"foo\"\n" | |
| 7186 "Accept-Ranges: bytes\n" | |
| 7187 "Content-Length: 80\n"); | |
| 7188 CreateTruncatedEntry(raw_headers, &cache); | |
| 7189 cache.ResetCounts(); | |
| 7190 | |
| 7191 scoped_ptr<HttpTransaction> first_transaction; | |
| 7192 int rv = cache.CreateTransaction(&first_transaction); | |
| 7193 ASSERT_EQ(OK, rv); | |
| 7194 ASSERT_TRUE(first_transaction.get()); | |
| 7195 | |
| 7196 rv = first_transaction->Start(&mock_request, callback.callback(), | |
| 7197 BoundNetLog()); | |
| 7198 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7199 | |
| 7200 first_transaction->StopCaching(); | |
| 7201 | |
| 7202 const int kBufferSize = 1024; | |
| 7203 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); | |
| 7204 rv = first_transaction->Read(buf.get(), 10, callback.callback()); | |
| 7205 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 7206 | |
| 7207 // Now that the cache lock is released, another transaction can begin. The | |
| 7208 // Start() call should complete without delay. The test should timeout if this | |
| 7209 // is not the case (i.e. the Start() call has to wait indefinitely[*] for the | |
| 7210 // previous transaction to release the lock). | |
| 7211 // | |
| 7212 // [*]: The wait isn't really indefinite since the Start() call times out | |
| 7213 // (currently after 20 seconds) and proceeds without the cache entry. This | |
| 7214 // case is accounted for by the network_layer()->transaction_count() | |
| 7215 // expectation below. | |
| 7216 scoped_ptr<HttpTransaction> second_transaction; | |
| 7217 rv = cache.CreateTransaction(&second_transaction); | |
| 7218 ASSERT_EQ(OK, rv); | |
| 7219 ASSERT_TRUE(second_transaction); | |
| 7220 rv = second_transaction->Start(&mock_request, callback.callback(), | |
| 7221 BoundNetLog()); | |
| 7222 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7223 | |
| 7224 // first_transaction: 1 open cache entry + 2 network fetches. | |
| 7225 // second_transaction: 1 create cache entry + 1 network fetch. | |
| 7226 EXPECT_EQ(1, cache.disk_cache()->create_count()); | |
| 7227 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7228 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | |
| 7229 } | |
| 7230 | |
| 7231 TEST(HttpCache, StopCachingReleasesCacheLockForSparseEntry) { | |
| 7232 MockHttpCache cache; | |
| 7233 TestCompletionCallback callback; | |
| 7234 | |
| 7235 // Create a sparse entry which contains 10 bytes at offset 20 out of an 80 | |
| 7236 // byte resource. | |
| 7237 MockTransaction mock_transaction(kRangeGET_TransactionOK); | |
| 7238 mock_transaction.handler = nullptr; | |
| 7239 mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER; | |
| 7240 mock_transaction.response_headers = | |
| 7241 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7242 "ETag: \"foo\"\n" | |
| 7243 "Accept-Ranges: bytes\n" | |
| 7244 "Content-Range: bytes 20-29/80\n" | |
| 7245 "Content-Length: 10\n"; | |
| 7246 mock_transaction.data = "rg: 20-29 "; | |
| 7247 AddMockTransaction(&mock_transaction); | |
| 7248 std::string headers; | |
| 7249 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction, | |
| 7250 &headers); | |
| 7251 | |
| 7252 // Verify our assumptions. There should be sparse entry here. | |
| 7253 disk_cache::Entry* cache_entry; | |
| 7254 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); | |
| 7255 EXPECT_TRUE(cache_entry->CouldBeSparse()); | |
| 7256 cache_entry->Close(); | |
| 7257 RemoveMockTransaction(&mock_transaction); | |
| 7258 | |
| 7259 cache.ResetCounts(); | |
| 7260 | |
| 7261 // Prepare a request to read the entire contents of the resource. This should | |
| 7262 // usually hope between network -> cache -> network. But not today. | |
| 7263 mock_transaction.request_headers = EXTRA_HEADER; | |
| 7264 mock_transaction.handler = kRangeGET_TransactionOK.handler; | |
| 7265 mock_transaction.response_headers = | |
| 7266 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7267 "ETag: \"foo\"\n" | |
| 7268 "Accept-Ranges: bytes\n" | |
| 7269 "Content-Length: 10\n"; | |
| 7270 AddMockTransaction(&mock_transaction); | |
| 7271 MockHttpRequest request(mock_transaction); | |
| 7272 | |
| 7273 scoped_ptr<HttpTransaction> first_transaction; | |
| 7274 ASSERT_EQ(OK, cache.CreateTransaction(&first_transaction)); | |
| 7275 int rv = | |
| 7276 first_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7277 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7278 | |
| 7279 const size_t kBufferSize = 256; | |
| 7280 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); | |
| 7281 | |
| 7282 rv = first_transaction->Read(buffer.get(), 10, callback.callback()); | |
| 7283 EXPECT_EQ(10, callback.GetResult(rv)); | |
| 7284 | |
| 7285 // Create another cache transaction. This one is blocked on the first | |
| 7286 // transaction's cache lock. | |
| 7287 scoped_ptr<HttpTransaction> second_transaction; | |
| 7288 TestCompletionCallback second_callback; | |
| 7289 ASSERT_EQ(OK, cache.CreateTransaction(&second_transaction)); | |
| 7290 rv = second_transaction->Start(&request, second_callback.callback(), | |
| 7291 BoundNetLog()); | |
| 7292 ASSERT_EQ(ERR_IO_PENDING, rv); | |
| 7293 | |
| 7294 // StopCaching() should cause the transaction to switch entirely to the | |
| 7295 // network for the remainder of the response. Since the existing network | |
| 7296 // transaction doesn't cover the entirety of the resource, the cache creates a | |
| 7297 // new network transaction. | |
| 7298 first_transaction->StopCaching(); | |
| 7299 | |
| 7300 // Since it's coming from a single network request, we can slurp the remaining | |
| 7301 // 70 bytes of the resource in one request. Let's leave a little bit on the | |
| 7302 // pipe so that the stream doesn't hit EOF. | |
| 7303 rv = first_transaction->Read(buffer.get(), 60, callback.callback()); | |
| 7304 EXPECT_EQ(60, callback.GetResult(rv)); | |
| 7305 | |
| 7306 // The second transaction should become unblocked at this point. | |
| 7307 EXPECT_EQ(OK, second_callback.GetResult(ERR_IO_PENDING)); | |
| 7308 | |
| 7309 // And it can read the entire resource too, but needs to alternate between | |
| 7310 // cache and network.. | |
| 7311 // 0-9 from cache (due to the first Read() on first_transaction). | |
| 7312 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read( | |
| 7313 buffer.get(), kBufferSize, second_callback.callback()))); | |
| 7314 | |
| 7315 // 10-19 From network: | |
| 7316 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read( | |
| 7317 buffer.get(), kBufferSize, second_callback.callback()))); | |
| 7318 | |
| 7319 // 20-29 From cache (due to test setup): | |
| 7320 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read( | |
| 7321 buffer.get(), kBufferSize, second_callback.callback()))); | |
| 7322 | |
| 7323 // 30-79 From network again: | |
| 7324 EXPECT_EQ(50, second_callback.GetResult(second_transaction->Read( | |
| 7325 buffer.get(), kBufferSize, second_callback.callback()))); | |
| 7326 EXPECT_EQ(0, second_callback.GetResult(second_transaction->Read( | |
| 7327 buffer.get(), kBufferSize, second_callback.callback()))); | |
| 7328 | |
| 7329 // Now drain first_transaction as well. | |
| 7330 EXPECT_EQ(10, callback.GetResult(first_transaction->Read( | |
| 7331 buffer.get(), kBufferSize, callback.callback()))); | |
| 7332 EXPECT_EQ(0, callback.GetResult(first_transaction->Read( | |
| 7333 buffer.get(), kBufferSize, callback.callback()))); | |
| 7334 | |
| 7335 // first_transaction: | |
| 7336 // 1 open cache entry + 2 network fetches (0-19 and 10-79). | |
| 7337 // second_transaction: | |
| 7338 // 1 open cache entry + 2 network fetches (10-19 and 30-79). | |
| 7339 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7340 EXPECT_EQ(4, cache.network_layer()->transaction_count()); | |
| 7341 | |
| 7342 // Even though there are two HttpCache::OpenEntry() calls, there's only one | |
| 7343 // DiskCache::OpenEntry call because HttpCache already has an active entry. | |
| 7344 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7345 | |
| 7346 // And the sparse entry is still here. | |
| 7347 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); | |
| 7348 cache_entry->Close(); | |
| 7349 RemoveMockTransaction(&mock_transaction); | |
| 7350 } | |
| 7351 | |
| 7352 TEST(HttpCache, StopCachingBeforeStartNoCacheEntry) { | |
| 7353 MockHttpCache cache; | |
| 7354 TestCompletionCallback callback; | |
| 7355 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7356 cache.ResetCounts(); | |
| 7357 | |
| 7358 AddMockTransaction(&transaction); | |
| 7359 scoped_ptr<HttpTransaction> http_transaction; | |
| 7360 | |
| 7361 int rv = cache.CreateTransaction(&http_transaction); | |
| 7362 ASSERT_EQ(OK, rv); | |
| 7363 | |
| 7364 MockHttpRequest request(transaction); | |
| 7365 http_transaction->StopCaching(); | |
| 7366 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7367 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7368 | |
| 7369 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7370 RemoveMockTransaction(&transaction); | |
| 7371 | |
| 7372 // If StopCaching() is called before Start(), then the cache should not try to | |
| 7373 // create an entry. | |
| 7374 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | |
| 7375 EXPECT_EQ(0, cache.disk_cache()->open_count()); | |
| 7376 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7377 } | |
| 7378 | |
| 7379 TEST(HttpCache, StopCachingBeforeStartOnlyFromCache) { | |
| 7380 MockHttpCache cache; | |
| 7381 TestCompletionCallback callback; | |
| 7382 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7383 | |
| 7384 AddMockTransaction(&transaction); | |
| 7385 RunTransactionTest(cache.http_cache(), transaction); | |
| 7386 RemoveMockTransaction(&transaction); | |
| 7387 cache.ResetCounts(); | |
| 7388 | |
| 7389 transaction.load_flags |= LOAD_ONLY_FROM_CACHE; | |
| 7390 AddMockTransaction(&transaction); | |
| 7391 | |
| 7392 scoped_ptr<HttpTransaction> http_transaction; | |
| 7393 | |
| 7394 int rv = cache.CreateTransaction(&http_transaction); | |
| 7395 ASSERT_EQ(OK, rv); | |
| 7396 | |
| 7397 MockHttpRequest request(transaction); | |
| 7398 http_transaction->StopCaching(); | |
| 7399 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7400 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7401 | |
| 7402 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7403 RemoveMockTransaction(&transaction); | |
| 7404 | |
| 7405 EXPECT_EQ(0, cache.network_layer()->transaction_count()); | |
| 7406 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7407 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7408 } | |
| 7409 | |
| 7410 TEST(HttpCache, StopCachingBeforeStartOnlyNonexistentCacheEntry) { | |
| 7411 MockHttpCache cache; | |
| 7412 TestCompletionCallback callback; | |
| 7413 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7414 cache.ResetCounts(); | |
| 7415 | |
| 7416 transaction.load_flags |= LOAD_ONLY_FROM_CACHE; | |
| 7417 AddMockTransaction(&transaction); | |
| 7418 | |
| 7419 scoped_ptr<HttpTransaction> http_transaction; | |
| 7420 | |
| 7421 int rv = cache.CreateTransaction(&http_transaction); | |
| 7422 ASSERT_EQ(OK, rv); | |
| 7423 | |
| 7424 MockHttpRequest request(transaction); | |
| 7425 http_transaction->StopCaching(); | |
| 7426 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7427 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv)); | |
| 7428 RemoveMockTransaction(&transaction); | |
| 7429 | |
| 7430 EXPECT_EQ(0, cache.network_layer()->transaction_count()); | |
| 7431 EXPECT_EQ(0, cache.disk_cache()->open_count()); | |
| 7432 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7433 } | |
| 7434 | |
| 7435 TEST(HttpCache, StopCachingBeforeStartPreferringNonexistentCacheEntry) { | |
| 7436 MockHttpCache cache; | |
| 7437 TestCompletionCallback callback; | |
| 7438 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7439 cache.ResetCounts(); | |
| 7440 | |
| 7441 transaction.load_flags |= LOAD_PREFERRING_CACHE; | |
| 7442 AddMockTransaction(&transaction); | |
| 7443 | |
| 7444 scoped_ptr<HttpTransaction> http_transaction; | |
| 7445 | |
| 7446 int rv = cache.CreateTransaction(&http_transaction); | |
| 7447 ASSERT_EQ(OK, rv); | |
| 7448 | |
| 7449 MockHttpRequest request(transaction); | |
| 7450 http_transaction->StopCaching(); | |
| 7451 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7452 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7453 | |
| 7454 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7455 RemoveMockTransaction(&transaction); | |
| 7456 | |
| 7457 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | |
| 7458 EXPECT_EQ(0, cache.disk_cache()->open_count()); | |
| 7459 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7460 } | |
| 7461 | |
| 7462 TEST(HttpCache, StopCachingBeforeStartPreferringCacheEntry) { | |
| 7463 MockHttpCache cache; | |
| 7464 TestCompletionCallback callback; | |
| 7465 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7466 | |
| 7467 AddMockTransaction(&transaction); | |
| 7468 RunTransactionTest(cache.http_cache(), transaction); | |
| 7469 RemoveMockTransaction(&transaction); | |
| 7470 cache.ResetCounts(); | |
| 7471 | |
| 7472 transaction.load_flags |= LOAD_PREFERRING_CACHE; | |
| 7473 AddMockTransaction(&transaction); | |
| 7474 | |
| 7475 scoped_ptr<HttpTransaction> http_transaction; | |
| 7476 | |
| 7477 int rv = cache.CreateTransaction(&http_transaction); | |
| 7478 ASSERT_EQ(OK, rv); | |
| 7479 | |
| 7480 MockHttpRequest request(transaction); | |
| 7481 http_transaction->StopCaching(); | |
| 7482 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7483 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7484 | |
| 7485 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7486 RemoveMockTransaction(&transaction); | |
| 7487 | |
| 7488 EXPECT_EQ(0, cache.network_layer()->transaction_count()); | |
| 7489 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7490 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7491 } | |
| 7492 | |
| 7493 TEST(HttpCache, StopCachingBeforeStartPreferringTruncatedCacheEntry) { | |
| 7494 MockHttpCache cache; | |
| 7495 TestCompletionCallback callback; | |
| 7496 MockTransaction transaction(kRangeGET_TransactionOK); | |
| 7497 transaction.load_flags |= LOAD_PREFERRING_CACHE; | |
| 7498 transaction.request_headers = EXTRA_HEADER; | |
| 7499 transaction.data = kFullRangeData; | |
| 7500 AddMockTransaction(&transaction); | |
| 7501 | |
| 7502 std::string raw_headers( | |
| 7503 "HTTP/1.1 200 OK\n" | |
| 7504 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7505 "ETag: \"foo\"\n" | |
| 7506 "Accept-Ranges: bytes\n" | |
| 7507 "Content-Length: 80\n"); | |
| 7508 CreateTruncatedEntry(raw_headers, &cache); | |
| 7509 cache.ResetCounts(); | |
| 7510 | |
| 7511 scoped_ptr<HttpTransaction> http_transaction; | |
| 7512 | |
| 7513 int rv = cache.CreateTransaction(&http_transaction); | |
| 7514 ASSERT_EQ(OK, rv); | |
| 7515 | |
| 7516 MockHttpRequest request(transaction); | |
| 7517 http_transaction->StopCaching(); | |
| 7518 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7519 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7520 | |
| 7521 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7522 RemoveMockTransaction(&transaction); | |
| 7523 | |
| 7524 // 1 validation request + 1 request for entire range = 2 network reqeusts. | |
| 7525 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | |
| 7526 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7527 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7528 } | |
| 7529 | |
| 7530 TEST(HttpCache, | |
| 7531 StopCachingBeforeStartForExternallyConditionalizedTruncatedEntry) { | |
| 7532 MockHttpCache cache; | |
| 7533 TestCompletionCallback callback; | |
| 7534 RangeTransactionServer range_transaction_server; | |
| 7535 range_transaction_server.set_not_modified(true); | |
| 7536 MockTransaction transaction(kRangeGET_TransactionOK); | |
| 7537 transaction.request_headers = "If-None-Match: \"foo\"\r\n" EXTRA_HEADER, | |
| 7538 transaction.data = ""; | |
| 7539 transaction.load_flags |= LOAD_PREFERRING_CACHE; | |
| 7540 AddMockTransaction(&transaction); | |
| 7541 | |
| 7542 std::string raw_headers( | |
| 7543 "HTTP/1.1 200 OK\n" | |
| 7544 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7545 "ETag: \"foo\"\n" | |
| 7546 "Accept-Ranges: bytes\n" | |
| 7547 "Content-Length: 80\n"); | |
| 7548 CreateTruncatedEntry(raw_headers, &cache); | |
| 7549 cache.ResetCounts(); | |
| 7550 | |
| 7551 scoped_ptr<HttpTransaction> http_transaction; | |
| 7552 | |
| 7553 int rv = cache.CreateTransaction(&http_transaction); | |
| 7554 ASSERT_EQ(OK, rv); | |
| 7555 | |
| 7556 MockHttpRequest request(transaction); | |
| 7557 http_transaction->StopCaching(); | |
| 7558 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7559 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7560 | |
| 7561 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7562 RemoveMockTransaction(&transaction); | |
| 7563 | |
| 7564 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | |
| 7565 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7566 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7567 } | |
| 7568 | |
| 7569 TEST(HttpCache, StopCachingAfterStartForLoadPreferringCacheWithInvalidation) { | |
| 7570 MockHttpCache cache; | |
| 7571 TestCompletionCallback callback; | |
| 7572 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7573 | |
| 7574 AddMockTransaction(&transaction); | |
| 7575 RunTransactionTest(cache.http_cache(), transaction); | |
| 7576 RemoveMockTransaction(&transaction); | |
| 7577 cache.ResetCounts(); | |
| 7578 | |
| 7579 transaction.load_flags |= LOAD_PREFERRING_CACHE; | |
| 7580 AddMockTransaction(&transaction); | |
| 7581 | |
| 7582 scoped_ptr<HttpTransaction> http_transaction; | |
| 7583 | |
| 7584 int rv = cache.CreateTransaction(&http_transaction); | |
| 7585 ASSERT_EQ(OK, rv); | |
| 7586 | |
| 7587 MockHttpRequest request(transaction); | |
| 7588 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); | |
| 7589 ASSERT_EQ(OK, callback.GetResult(rv)); | |
| 7590 | |
| 7591 http_transaction->StopCaching(); | |
| 7592 | |
| 7593 ReadAndVerifyTransaction(http_transaction.get(), transaction); | |
| 7594 RemoveMockTransaction(&transaction); | |
| 7595 | |
| 7596 EXPECT_EQ(0, cache.network_layer()->transaction_count()); | |
| 7597 EXPECT_EQ(1, cache.disk_cache()->open_count()); | |
| 7598 EXPECT_EQ(0, cache.disk_cache()->create_count()); | |
| 7599 } | |
| 7600 | |
| 7601 namespace { | |
| 7602 | |
| 7603 enum class TransactionPhase { | |
| 7604 BEFORE_FIRST_READ, | |
| 7605 AFTER_FIRST_READ, | |
| 7606 AFTER_NETWORK_READ | |
| 7607 }; | |
| 7608 | |
| 7609 using CacheInitializer = void (*)(MockHttpCache*); | |
| 7610 using HugeCacheTestConfiguration = | |
| 7611 std::pair<TransactionPhase, CacheInitializer>; | |
| 7612 | |
| 7613 class HttpCacheHugeResourceTest | |
| 7614 : public ::testing::TestWithParam<HugeCacheTestConfiguration> { | |
| 7615 public: | |
| 7616 static std::list<HugeCacheTestConfiguration> GetTestModes(); | |
| 7617 static std::list<HugeCacheTestConfiguration> kTestModes; | |
| 7618 | |
| 7619 // CacheInitializer callbacks. These are used to initialize the cache | |
| 7620 // depending on the test run configuration. | |
| 7621 | |
| 7622 // Initializes a cache containing a truncated entry containing the first 20 | |
| 7623 // bytes of the reponse body. | |
| 7624 static void SetupTruncatedCacheEntry(MockHttpCache* cache); | |
| 7625 | |
| 7626 // Initializes a cache containing a sparse entry. The first 10 bytes are | |
| 7627 // present in the cache. | |
| 7628 static void SetupPrefixSparseCacheEntry(MockHttpCache* cache); | |
| 7629 | |
| 7630 // Initializes a cache containing a sparse entry. The 10 bytes at offset | |
| 7631 // 99999990 are present in the cache. | |
| 7632 static void SetupInfixSparseCacheEntry(MockHttpCache* cache); | |
| 7633 | |
| 7634 protected: | |
| 7635 static void ExpectByteRangeTransactionHandler( | |
| 7636 const net::HttpRequestInfo* request, | |
| 7637 std::string* response_status, | |
| 7638 std::string* response_headers, | |
| 7639 std::string* response_data); | |
| 7640 static int LargeBufferReader(int64 content_length, | |
| 7641 int64 offset, | |
| 7642 net::IOBuffer* buf, | |
| 7643 int buf_len); | |
| 7644 | |
| 7645 static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */); | |
| 7646 | |
| 7647 // Size of resource to be tested. | |
| 7648 static const int64 kTotalSize = | |
| 7649 5000000000LL; // Five beeeeeelllliooonn bytes! | |
| 7650 }; | |
| 7651 | |
| 7652 const int64 HttpCacheHugeResourceTest::kTotalSize; | |
| 7653 | |
| 7654 // static | |
| 7655 void HttpCacheHugeResourceTest::ExpectByteRangeTransactionHandler( | |
| 7656 const net::HttpRequestInfo* request, | |
| 7657 std::string* response_status, | |
| 7658 std::string* response_headers, | |
| 7659 std::string* response_data) { | |
| 7660 std::string if_range; | |
| 7661 EXPECT_TRUE(request->extra_headers.GetHeader( | |
| 7662 net::HttpRequestHeaders::kIfRange, &if_range)); | |
| 7663 EXPECT_EQ("\"foo\"", if_range); | |
| 7664 | |
| 7665 std::string range_header; | |
| 7666 EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange, | |
| 7667 &range_header)); | |
| 7668 std::vector<net::HttpByteRange> ranges; | |
| 7669 | |
| 7670 EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges)); | |
| 7671 ASSERT_EQ(1u, ranges.size()); | |
| 7672 | |
| 7673 net::HttpByteRange range = ranges[0]; | |
| 7674 EXPECT_TRUE(range.HasFirstBytePosition()); | |
| 7675 int64 last_byte_position = | |
| 7676 range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1; | |
| 7677 | |
| 7678 response_status->assign("HTTP/1.1 206 Partial"); | |
| 7679 response_headers->assign(base::StringPrintf( | |
| 7680 "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64 | |
| 7681 "\n" | |
| 7682 "Content-Length: %" PRId64 "\n", | |
| 7683 range.first_byte_position(), last_byte_position, kTotalSize, | |
| 7684 last_byte_position - range.first_byte_position() + 1)); | |
| 7685 } | |
| 7686 | |
| 7687 // static | |
| 7688 int HttpCacheHugeResourceTest::LargeBufferReader(int64 content_length, | |
| 7689 int64 offset, | |
| 7690 net::IOBuffer* buf, | |
| 7691 int buf_len) { | |
| 7692 // This test involves reading multiple gigabytes of data. To make it run in a | |
| 7693 // reasonable amount of time, we are going to skip filling the buffer with | |
| 7694 // data. Instead the test relies on verifying that the count of bytes expected | |
| 7695 // at the end is correct. | |
| 7696 EXPECT_LT(0, content_length); | |
| 7697 EXPECT_LE(offset, content_length); | |
| 7698 int num = std::min(static_cast<int64>(buf_len), content_length - offset); | |
| 7699 return num; | |
| 7700 } | |
| 7701 | |
| 7702 // static | |
| 7703 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started, | |
| 7704 bool* /* defer */) { | |
| 7705 *started = true; | |
| 7706 } | |
| 7707 | |
| 7708 // static | |
| 7709 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) { | |
| 7710 ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK); | |
| 7711 std::string cached_headers = base::StringPrintf( | |
| 7712 "HTTP/1.1 200 OK\n" | |
| 7713 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7714 "ETag: \"foo\"\n" | |
| 7715 "Accept-Ranges: bytes\n" | |
| 7716 "Content-Length: %" PRId64 "\n", | |
| 7717 kTotalSize); | |
| 7718 CreateTruncatedEntry(cached_headers, cache); | |
| 7719 } | |
| 7720 | |
| 7721 // static | |
| 7722 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry( | |
| 7723 MockHttpCache* cache) { | |
| 7724 MockTransaction transaction(kRangeGET_TransactionOK); | |
| 7725 transaction.handler = nullptr; | |
| 7726 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; | |
| 7727 transaction.response_headers = | |
| 7728 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7729 "ETag: \"foo\"\n" | |
| 7730 "Accept-Ranges: bytes\n" | |
| 7731 "Content-Range: bytes 0-9/5000000000\n" | |
| 7732 "Content-Length: 10\n"; | |
| 7733 AddMockTransaction(&transaction); | |
| 7734 std::string headers; | |
| 7735 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers); | |
| 7736 RemoveMockTransaction(&transaction); | |
| 7737 } | |
| 7738 | |
| 7739 // static | |
| 7740 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry( | |
| 7741 MockHttpCache* cache) { | |
| 7742 MockTransaction transaction(kRangeGET_TransactionOK); | |
| 7743 transaction.handler = nullptr; | |
| 7744 transaction.request_headers = | |
| 7745 "Range: bytes = 99999990-99999999\r\n" EXTRA_HEADER; | |
| 7746 transaction.response_headers = | |
| 7747 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
| 7748 "ETag: \"foo\"\n" | |
| 7749 "Accept-Ranges: bytes\n" | |
| 7750 "Content-Range: bytes 99999990-99999999/5000000000\n" | |
| 7751 "Content-Length: 10\n"; | |
| 7752 AddMockTransaction(&transaction); | |
| 7753 std::string headers; | |
| 7754 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers); | |
| 7755 RemoveMockTransaction(&transaction); | |
| 7756 } | |
| 7757 | |
| 7758 // static | |
| 7759 std::list<HugeCacheTestConfiguration> | |
| 7760 HttpCacheHugeResourceTest::GetTestModes() { | |
| 7761 std::list<HugeCacheTestConfiguration> test_modes; | |
| 7762 const TransactionPhase kTransactionPhases[] = { | |
| 7763 TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ, | |
| 7764 TransactionPhase::AFTER_NETWORK_READ}; | |
| 7765 const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry, | |
| 7766 &SetupPrefixSparseCacheEntry, | |
| 7767 &SetupInfixSparseCacheEntry}; | |
| 7768 | |
| 7769 for (const auto phase : kTransactionPhases) | |
| 7770 for (const auto initializer : kInitializers) | |
| 7771 test_modes.push_back(std::make_pair(phase, initializer)); | |
| 7772 | |
| 7773 return test_modes; | |
| 7774 } | |
| 7775 | |
| 7776 // static | |
| 7777 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes = | |
| 7778 HttpCacheHugeResourceTest::GetTestModes(); | |
| 7779 | |
| 7780 INSTANTIATE_TEST_CASE_P( | |
| 7781 _, | |
| 7782 HttpCacheHugeResourceTest, | |
| 7783 ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes)); | |
| 7784 | |
| 7785 } // namespace | |
| 7786 | |
| 7787 // Test what happens when StopCaching() is called while reading a huge resource | |
| 7788 // fetched via GET. Various combinations of cache state and when StopCaching() | |
| 7789 // is called is controlled by the parameter passed into the test via the | |
| 7790 // INSTANTIATE_TEST_CASE_P invocation above. | |
| 7791 TEST_P(HttpCacheHugeResourceTest, | |
| 7792 StopCachingFollowedByReadForHugeTruncatedResource) { | |
| 7793 // This test is going to be repeated for all combinations of TransactionPhase | |
| 7794 // and CacheInitializers returned by GetTestModes(). | |
| 7795 const TransactionPhase stop_caching_phase = GetParam().first; | |
| 7796 const CacheInitializer cache_initializer = GetParam().second; | |
| 7797 | |
| 7798 MockHttpCache cache; | |
| 7799 (*cache_initializer)(&cache); | |
| 7800 | |
| 7801 MockTransaction transaction(kSimpleGET_Transaction); | |
| 7802 transaction.url = kRangeGET_TransactionOK.url; | |
| 7803 transaction.handler = &ExpectByteRangeTransactionHandler; | |
| 7804 transaction.read_handler = &LargeBufferReader; | |
| 7805 ScopedMockTransaction scoped_transaction(transaction); | |
| 7806 | |
| 7807 MockHttpRequest request(transaction); | |
| 7808 net::TestCompletionCallback callback; | |
| 7809 scoped_ptr<net::HttpTransaction> http_transaction; | |
| 7810 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, | |
| 7811 &http_transaction); | |
| 7812 ASSERT_EQ(net::OK, rv); | |
| 7813 ASSERT_TRUE(http_transaction.get()); | |
| 7814 | |
| 7815 bool network_transaction_started = false; | |
| 7816 if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) { | |
| 7817 http_transaction->SetBeforeNetworkStartCallback( | |
| 7818 base::Bind(&SetFlagOnBeforeNetworkStart, &network_transaction_started)); | |
| 6945 } | 7819 } |
| 6946 | 7820 |
| 6947 // Verify that the disk entry was updated. | 7821 rv = http_transaction->Start(&request, callback.callback(), |
| 6948 disk_cache::Entry* entry; | 7822 net::BoundNetLog()); |
| 6949 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); | 7823 rv = callback.GetResult(rv); |
| 6950 EXPECT_EQ(80, entry->GetDataSize(1)); | 7824 ASSERT_EQ(net::OK, rv); |
| 6951 bool truncated = true; | 7825 |
| 6952 HttpResponseInfo response; | 7826 if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ) |
| 6953 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); | 7827 http_transaction->StopCaching(); |
| 6954 EXPECT_FALSE(truncated); | 7828 |
| 6955 entry->Close(); | 7829 int64 total_bytes_received = 0; |
| 6956 | 7830 |
| 6957 RemoveMockTransaction(&kRangeGET_TransactionOK); | 7831 EXPECT_EQ(kTotalSize, |
| 7832 http_transaction->GetResponseInfo()->headers->GetContentLength()); | |
| 7833 do { | |
| 7834 // This test simulates reading Gigabytes of data. Buffer size is set to 1MB | |
| 7835 // to reduce the number of reads and speedup the test. | |
| 7836 const int kBufferSize = 1024 * 1024; | |
| 7837 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); | |
| 7838 rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback()); | |
| 7839 rv = callback.GetResult(rv); | |
| 7840 | |
| 7841 if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ && | |
| 7842 total_bytes_received == 0) { | |
| 7843 http_transaction->StopCaching(); | |
| 7844 } | |
| 7845 | |
| 7846 if (rv > 0) | |
| 7847 total_bytes_received += rv; | |
| 7848 | |
| 7849 if (network_transaction_started && | |
| 7850 stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) { | |
| 7851 http_transaction->StopCaching(); | |
| 7852 network_transaction_started = false; | |
| 7853 } | |
| 7854 } while (rv > 0); | |
| 7855 | |
| 7856 // The only verification we are going to do is that the received resource has | |
| 7857 // the correct size. This is sufficient to verify that the state machine | |
| 7858 // didn't terminate abruptly due to the StopCaching() call. | |
| 7859 EXPECT_EQ(kTotalSize, total_bytes_received); | |
| 6958 } | 7860 } |
| 6959 | 7861 |
| 6960 // Tests that we detect truncated resources from the net when there is | 7862 // Tests that we detect truncated resources from the net when there is |
| 6961 // a Content-Length header. | 7863 // a Content-Length header. |
| 6962 TEST(HttpCache, TruncatedByContentLength) { | 7864 TEST(HttpCache, TruncatedByContentLength) { |
| 6963 MockHttpCache cache; | 7865 MockHttpCache cache; |
| 6964 TestCompletionCallback callback; | 7866 TestCompletionCallback callback; |
| 6965 | 7867 |
| 6966 MockTransaction transaction(kSimpleGET_Transaction); | 7868 MockTransaction transaction(kSimpleGET_Transaction); |
| 6967 AddMockTransaction(&transaction); | 7869 AddMockTransaction(&transaction); |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7631 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 8533 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 7632 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 8534 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 7633 EXPECT_TRUE(response_info.was_cached); | 8535 EXPECT_TRUE(response_info.was_cached); |
| 7634 | 8536 |
| 7635 // The new SSL state is reported. | 8537 // The new SSL state is reported. |
| 7636 EXPECT_EQ(status2, response_info.ssl_info.connection_status); | 8538 EXPECT_EQ(status2, response_info.ssl_info.connection_status); |
| 7637 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); | 8539 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); |
| 7638 } | 8540 } |
| 7639 | 8541 |
| 7640 } // namespace net | 8542 } // namespace net |
| OLD | NEW |