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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> |
10 | 11 |
11 #include "base/bind.h" | 12 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/format_macros.h" |
13 #include "base/memory/scoped_vector.h" | 15 #include "base/memory/scoped_vector.h" |
14 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
16 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
17 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
18 #include "base/test/simple_test_clock.h" | 20 #include "base/test/simple_test_clock.h" |
19 #include "net/base/cache_type.h" | 21 #include "net/base/cache_type.h" |
20 #include "net/base/elements_upload_data_stream.h" | 22 #include "net/base/elements_upload_data_stream.h" |
21 #include "net/base/host_port_pair.h" | 23 #include "net/base/host_port_pair.h" |
22 #include "net/base/load_flags.h" | 24 #include "net/base/load_flags.h" |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 base::Time(), | 275 base::Time(), |
274 "", | 276 "", |
275 LOAD_VALIDATE_CACHE, | 277 LOAD_VALIDATE_CACHE, |
276 "HTTP/1.1 200 OK", | 278 "HTTP/1.1 200 OK", |
277 "Cache-Control: max-age=10000\n", | 279 "Cache-Control: max-age=10000\n", |
278 base::Time(), | 280 base::Time(), |
279 "<html><body>Google Blah Blah</body></html>", | 281 "<html><body>Google Blah Blah</body></html>", |
280 TEST_MODE_SYNC_NET_START, | 282 TEST_MODE_SYNC_NET_START, |
281 &FastTransactionServer::FastNoStoreHandler, | 283 &FastTransactionServer::FastNoStoreHandler, |
282 nullptr, | 284 nullptr, |
| 285 nullptr, |
283 0, | 286 0, |
284 0, | 287 0, |
285 OK}; | 288 OK}; |
286 | 289 |
287 // This class provides a handler for kRangeGET_TransactionOK so that the range | 290 // This class provides a handler for kRangeGET_TransactionOK so that the range |
288 // request can be served on demand. | 291 // request can be served on demand. |
289 class RangeTransactionServer { | 292 class RangeTransactionServer { |
290 public: | 293 public: |
291 RangeTransactionServer() { | 294 RangeTransactionServer() { |
292 not_modified_ = false; | 295 not_modified_ = false; |
(...skipping 13 matching lines...) Expand all Loading... |
306 void set_modified(bool value) { modified_ = value; } | 309 void set_modified(bool value) { modified_ = value; } |
307 | 310 |
308 // Returns 200 instead of 206 (a malformed response overall). | 311 // Returns 200 instead of 206 (a malformed response overall). |
309 void set_bad_200(bool value) { bad_200_ = value; } | 312 void set_bad_200(bool value) { bad_200_ = value; } |
310 | 313 |
311 // Other than regular range related behavior (and the flags mentioned above), | 314 // Other than regular range related behavior (and the flags mentioned above), |
312 // the server reacts to requests headers like so: | 315 // the server reacts to requests headers like so: |
313 // X-Require-Mock-Auth -> return 401. | 316 // X-Require-Mock-Auth -> return 401. |
314 // X-Require-Mock-Auth-Alt -> return 401. | 317 // X-Require-Mock-Auth-Alt -> return 401. |
315 // X-Return-Default-Range -> assume 40-49 was requested. | 318 // X-Return-Default-Range -> assume 40-49 was requested. |
| 319 // X-No-Ranges -> Returns "Not a range" if the request is not a valid range |
| 320 // request. |
316 // The -Alt variant doesn't cause the MockNetworkTransaction to | 321 // The -Alt variant doesn't cause the MockNetworkTransaction to |
317 // report that it IsReadyToRestartForAuth(). | 322 // report that it IsReadyToRestartForAuth(). |
318 static void RangeHandler(const HttpRequestInfo* request, | 323 static void RangeHandler(const HttpRequestInfo* request, |
319 std::string* response_status, | 324 std::string* response_status, |
320 std::string* response_headers, | 325 std::string* response_headers, |
321 std::string* response_data); | 326 std::string* response_data); |
322 | 327 |
323 private: | 328 private: |
324 static bool not_modified_; | 329 static bool not_modified_; |
325 static bool modified_; | 330 static bool modified_; |
326 static bool bad_200_; | 331 static bool bad_200_; |
327 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); | 332 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); |
328 }; | 333 }; |
329 bool RangeTransactionServer::not_modified_ = false; | 334 bool RangeTransactionServer::not_modified_ = false; |
330 bool RangeTransactionServer::modified_ = false; | 335 bool RangeTransactionServer::modified_ = false; |
331 bool RangeTransactionServer::bad_200_ = false; | 336 bool RangeTransactionServer::bad_200_ = false; |
332 | 337 |
333 // A dummy extra header that must be preserved on a given request. | 338 // A dummy extra header that must be preserved on a given request. |
334 | 339 |
335 // EXTRA_HEADER_LINE doesn't include a line terminator because it | 340 // EXTRA_HEADER_LINE doesn't include a line terminator because it |
336 // will be passed to AddHeaderFromString() which doesn't accept them. | 341 // will be passed to AddHeaderFromString() which doesn't accept them. |
337 #define EXTRA_HEADER_LINE "Extra: header" | 342 #define EXTRA_HEADER_LINE "Extra: header" |
338 | 343 |
339 // EXTRA_HEADER contains a line terminator, as expected by | 344 // EXTRA_HEADER contains a line terminator, as expected by |
340 // AddHeadersFromString() (_not_ AddHeaderFromString()). | 345 // AddHeadersFromString() (_not_ AddHeaderFromString()). |
341 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" | 346 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" |
342 | 347 |
343 static const char kExtraHeaderKey[] = "Extra"; | 348 #define RETURN_DEFAULT_RANGE_HEADER "X-Return-Default-Range: 1\r\n" |
| 349 |
| 350 #define INDICATE_NO_RANGES_HEADER "X-No-Ranges: 1\r\n" |
| 351 |
| 352 const char kExtraHeaderKey[] = "Extra"; |
| 353 |
| 354 const char kFullRangeData[] = |
| 355 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 " |
| 356 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 "; |
344 | 357 |
345 // Static. | 358 // Static. |
346 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request, | 359 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request, |
347 std::string* response_status, | 360 std::string* response_status, |
348 std::string* response_headers, | 361 std::string* response_headers, |
349 std::string* response_data) { | 362 std::string* response_data) { |
| 363 SCOPED_TRACE(testing::Message() << "Request headers: \n" |
| 364 << request->extra_headers.ToString()); |
350 if (request->extra_headers.IsEmpty()) { | 365 if (request->extra_headers.IsEmpty()) { |
351 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); | 366 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); |
352 response_data->clear(); | 367 response_data->clear(); |
353 return; | 368 return; |
354 } | 369 } |
355 | 370 |
356 // We want to make sure we don't delete extra headers. | 371 // We want to make sure we don't delete extra headers. |
357 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); | 372 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); |
358 | 373 |
359 bool require_auth = | 374 bool require_auth = |
(...skipping 13 matching lines...) Expand all Loading... |
373 } | 388 } |
374 | 389 |
375 std::vector<HttpByteRange> ranges; | 390 std::vector<HttpByteRange> ranges; |
376 std::string range_header; | 391 std::string range_header; |
377 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange, | 392 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange, |
378 &range_header) || | 393 &range_header) || |
379 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || | 394 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || |
380 ranges.size() != 1) { | 395 ranges.size() != 1) { |
381 // This is not a byte range request. We return 200. | 396 // This is not a byte range request. We return 200. |
382 response_status->assign("HTTP/1.1 200 OK"); | 397 response_status->assign("HTTP/1.1 200 OK"); |
383 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); | 398 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); |
384 response_data->assign("Not a range"); | 399 if (request->extra_headers.HasHeader("X-No-Ranges")) { |
| 400 response_data->assign("Not a range"); |
| 401 return; |
| 402 } |
| 403 response_headers->append( |
| 404 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 405 "ETag: \"foo\"\n" |
| 406 "Accept-Ranges: bytes\n" |
| 407 "Content-Length: 80\n"); |
| 408 response_data->assign(kFullRangeData); |
385 return; | 409 return; |
386 } | 410 } |
387 | 411 |
388 // We can handle this range request. | 412 // We can handle this range request. |
389 HttpByteRange byte_range = ranges[0]; | 413 HttpByteRange byte_range = ranges[0]; |
390 | 414 |
391 if (request->extra_headers.HasHeader("X-Return-Default-Range")) { | 415 if (request->extra_headers.HasHeader("X-Return-Default-Range")) { |
392 byte_range.set_first_byte_position(40); | 416 byte_range.set_first_byte_position(40); |
393 byte_range.set_last_byte_position(49); | 417 byte_range.set_last_byte_position(49); |
394 } | 418 } |
395 | 419 |
396 if (byte_range.first_byte_position() > 79) { | 420 if (byte_range.first_byte_position() > 79) { |
397 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); | 421 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); |
398 response_data->clear(); | 422 response_data->clear(); |
399 return; | 423 return; |
400 } | 424 } |
| 425 response_status->assign("HTTP/1.1 206 Partial"); |
401 | 426 |
402 EXPECT_TRUE(byte_range.ComputeBounds(80)); | 427 EXPECT_TRUE(byte_range.ComputeBounds(80)); |
403 int start = static_cast<int>(byte_range.first_byte_position()); | 428 int start = static_cast<int>(byte_range.first_byte_position()); |
404 int end = static_cast<int>(byte_range.last_byte_position()); | 429 int end = static_cast<int>(byte_range.last_byte_position()); |
405 | 430 |
406 EXPECT_LT(end, 80); | 431 EXPECT_LT(end, 80); |
407 | 432 |
408 std::string content_range = base::StringPrintf( | 433 std::string content_range = base::StringPrintf( |
409 "Content-Range: bytes %d-%d/80\n", start, end); | 434 "Content-Range: bytes %d-%d/80\n", start, end); |
410 response_headers->append(content_range); | 435 response_headers->append(content_range); |
(...skipping 20 matching lines...) Expand all Loading... |
431 response_headers->replace(response_headers->find("Content-Length:"), | 456 response_headers->replace(response_headers->find("Content-Length:"), |
432 content_length.size(), content_length); | 457 content_length.size(), content_length); |
433 } | 458 } |
434 } else { | 459 } else { |
435 response_status->assign("HTTP/1.1 304 Not Modified"); | 460 response_status->assign("HTTP/1.1 304 Not Modified"); |
436 response_data->clear(); | 461 response_data->clear(); |
437 } | 462 } |
438 } | 463 } |
439 | 464 |
440 const MockTransaction kRangeGET_TransactionOK = { | 465 const MockTransaction kRangeGET_TransactionOK = { |
441 "http://www.google.com/range", | 466 "http://www.google.com/range", "GET", base::Time(), |
442 "GET", | 467 "Range: bytes = 40-49\r\n" EXTRA_HEADER, LOAD_NORMAL, |
443 base::Time(), | |
444 "Range: bytes = 40-49\r\n" EXTRA_HEADER, | |
445 LOAD_NORMAL, | |
446 "HTTP/1.1 206 Partial Content", | 468 "HTTP/1.1 206 Partial Content", |
447 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 469 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
448 "ETag: \"foo\"\n" | 470 "ETag: \"foo\"\n" |
449 "Accept-Ranges: bytes\n" | 471 "Accept-Ranges: bytes\n" |
450 "Content-Length: 10\n", | 472 "Content-Length: 10\n", |
451 base::Time(), | 473 base::Time(), "rg: 40-49 ", TEST_MODE_NORMAL, |
452 "rg: 40-49 ", | 474 &RangeTransactionServer::RangeHandler, nullptr, nullptr, 0, 0, OK}; |
453 TEST_MODE_NORMAL, | |
454 &RangeTransactionServer::RangeHandler, | |
455 nullptr, | |
456 0, | |
457 0, | |
458 OK}; | |
459 | 475 |
460 const char kFullRangeData[] = | 476 const MockTransaction kResumableGET_Transaction = { |
461 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 " | 477 kRangeGET_TransactionOK.url, "GET", base::Time(), EXTRA_HEADER, LOAD_NORMAL, |
462 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 "; | 478 "HTTP/1.1 200 OK", |
| 479 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 480 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n" |
| 481 "ETag: \"foo\"\n" |
| 482 "Accept-Ranges: bytes\n" |
| 483 "Content-Length: 80\n", |
| 484 base::Time(), kFullRangeData, TEST_MODE_NORMAL, |
| 485 &RangeTransactionServer::RangeHandler, nullptr, nullptr, 0, 0, OK}; |
463 | 486 |
464 // Verifies the response headers (|response|) match a partial content | 487 // Verifies the response headers (|response|) match a partial content |
465 // response for the range starting at |start| and ending at |end|. | 488 // response for the range starting at |start| and ending at |end|. |
466 void Verify206Response(std::string response, int start, int end) { | 489 void Verify206Response(std::string response, int start, int end) { |
467 std::string raw_headers( | 490 std::string raw_headers( |
468 HttpUtil::AssembleRawHeaders(response.data(), response.size())); | 491 HttpUtil::AssembleRawHeaders(response.data(), response.size())); |
469 scoped_refptr<HttpResponseHeaders> headers( | 492 scoped_refptr<HttpResponseHeaders> headers( |
470 new HttpResponseHeaders(raw_headers)); | 493 new HttpResponseHeaders(raw_headers)); |
471 | 494 |
472 ASSERT_EQ(206, headers->response_code()); | 495 ASSERT_EQ(206, headers->response_code()); |
(...skipping 1625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" | 2121 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" |
2099 "Cache-Control: max-age=0\n" | 2122 "Cache-Control: max-age=0\n" |
2100 "Vary: Foo\n"; | 2123 "Vary: Foo\n"; |
2101 AddMockTransaction(&transaction); | 2124 AddMockTransaction(&transaction); |
2102 RunTransactionTest(cache.http_cache(), transaction); | 2125 RunTransactionTest(cache.http_cache(), transaction); |
2103 | 2126 |
2104 // Read from the cache and don't revalidate the entry. | 2127 // Read from the cache and don't revalidate the entry. |
2105 RevalidationServer server; | 2128 RevalidationServer server; |
2106 transaction.handler = server.Handler; | 2129 transaction.handler = server.Handler; |
2107 transaction.request_headers = "Foo: none\r\n"; | 2130 transaction.request_headers = "Foo: none\r\n"; |
| 2131 |
2108 BoundTestNetLog log; | 2132 BoundTestNetLog log; |
2109 LoadTimingInfo load_timing_info; | 2133 LoadTimingInfo load_timing_info; |
2110 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), | 2134 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), |
2111 &load_timing_info); | 2135 &load_timing_info); |
2112 | 2136 |
2113 EXPECT_FALSE(server.EtagUsed()); | 2137 EXPECT_FALSE(server.EtagUsed()); |
2114 EXPECT_FALSE(server.LastModifiedUsed()); | 2138 EXPECT_FALSE(server.LastModifiedUsed()); |
2115 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2139 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
2116 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 2140 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
2117 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2141 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
(...skipping 1778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3896 | 3920 |
3897 Verify206Response(headers, 40, 49); | 3921 Verify206Response(headers, 40, 49); |
3898 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 3922 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
3899 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 3923 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
3900 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 3924 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
3901 | 3925 |
3902 // Now verify that the cached data is not used. | 3926 // Now verify that the cached data is not used. |
3903 // Don't ask for a range. The cache will attempt to use the cached data but | 3927 // Don't ask for a range. The cache will attempt to use the cached data but |
3904 // should discard it as it cannot be validated. A regular request should go | 3928 // should discard it as it cannot be validated. A regular request should go |
3905 // to the server and a new entry should be created. | 3929 // to the server and a new entry should be created. |
3906 transaction.request_headers = EXTRA_HEADER; | 3930 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
3907 transaction.data = "Not a range"; | 3931 transaction.data = "Not a range"; |
3908 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 3932 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
3909 | 3933 |
3910 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); | 3934 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
3911 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 3935 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
3912 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 3936 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
3913 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 3937 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
3914 | 3938 |
3915 // The last response was saved. | 3939 // The last response was saved. |
3916 RunTransactionTest(cache.http_cache(), transaction); | 3940 RunTransactionTest(cache.http_cache(), transaction); |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4364 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; | 4388 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; |
4365 transaction.data = "rg: 70-79 "; | 4389 transaction.data = "rg: 70-79 "; |
4366 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 4390 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
4367 Verify206Response(headers, 70, 79); | 4391 Verify206Response(headers, 70, 79); |
4368 | 4392 |
4369 // Don't ask for a range. The cache will ask the server for 0-69. | 4393 // Don't ask for a range. The cache will ask the server for 0-69. |
4370 // The server returns 40-49. The cache should consider the server confused and | 4394 // The server returns 40-49. The cache should consider the server confused and |
4371 // abort caching, restarting the request. | 4395 // abort caching, restarting the request. |
4372 // The second network request should not be a byte range request so the server | 4396 // The second network request should not be a byte range request so the server |
4373 // should return 200 + "Not a range" | 4397 // should return 200 + "Not a range" |
4374 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER; | 4398 transaction.request_headers = |
| 4399 RETURN_DEFAULT_RANGE_HEADER INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
4375 transaction.data = "Not a range"; | 4400 transaction.data = "Not a range"; |
4376 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 4401 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
4377 | 4402 |
4378 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); | 4403 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
4379 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | 4404 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
4380 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 4405 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
4381 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4406 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
4382 | 4407 |
4383 // The entry was deleted. | 4408 // The entry was deleted. |
4384 RunTransactionTest(cache.http_cache(), transaction); | 4409 RunTransactionTest(cache.http_cache(), transaction); |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4756 Verify206Response(headers, 0, 9); | 4781 Verify206Response(headers, 0, 9); |
4757 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 4782 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
4758 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 4783 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
4759 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4784 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
4760 | 4785 |
4761 // Now we'll issue a request without any range that should result first in a | 4786 // Now we'll issue a request without any range that should result first in a |
4762 // 206 (when revalidating), and then in a weird standard answer: the test | 4787 // 206 (when revalidating), and then in a weird standard answer: the test |
4763 // server will not modify the response so we'll get the default range... a | 4788 // server will not modify the response so we'll get the default range... a |
4764 // real server will answer with 200. | 4789 // real server will answer with 200. |
4765 MockTransaction transaction2(kRangeGET_TransactionOK); | 4790 MockTransaction transaction2(kRangeGET_TransactionOK); |
4766 transaction2.request_headers = EXTRA_HEADER; | 4791 transaction2.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
4767 transaction2.load_flags |= LOAD_VALIDATE_CACHE; | 4792 transaction2.load_flags |= LOAD_VALIDATE_CACHE; |
4768 transaction2.data = "Not a range"; | 4793 transaction2.data = "Not a range"; |
4769 RangeTransactionServer handler; | 4794 RangeTransactionServer handler; |
4770 handler.set_modified(true); | 4795 handler.set_modified(true); |
4771 BoundTestNetLog log; | 4796 BoundTestNetLog log; |
4772 LoadTimingInfo load_timing_info; | 4797 LoadTimingInfo load_timing_info; |
4773 RunTransactionTestWithResponseAndGetTiming( | 4798 RunTransactionTestWithResponseAndGetTiming( |
4774 cache.http_cache(), transaction2, &headers, log.bound(), | 4799 cache.http_cache(), transaction2, &headers, log.bound(), |
4775 &load_timing_info); | 4800 &load_timing_info); |
4776 | 4801 |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5366 | 5391 |
5367 RemoveMockTransaction(&kRangeGET_TransactionOK); | 5392 RemoveMockTransaction(&kRangeGET_TransactionOK); |
5368 } | 5393 } |
5369 | 5394 |
5370 // Tests that we don't crash when after reading from the cache we issue a | 5395 // Tests that we don't crash when after reading from the cache we issue a |
5371 // request for the next range and the server gives us a 200 synchronously. | 5396 // request for the next range and the server gives us a 200 synchronously. |
5372 TEST(HttpCache, RangeGET_FastFlakyServer) { | 5397 TEST(HttpCache, RangeGET_FastFlakyServer) { |
5373 MockHttpCache cache; | 5398 MockHttpCache cache; |
5374 | 5399 |
5375 ScopedMockTransaction transaction(kRangeGET_TransactionOK); | 5400 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
5376 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; | 5401 transaction.request_headers = |
| 5402 "Range: bytes = 40-\r\n" INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
5377 transaction.test_mode = TEST_MODE_SYNC_NET_START; | 5403 transaction.test_mode = TEST_MODE_SYNC_NET_START; |
5378 transaction.load_flags |= LOAD_VALIDATE_CACHE; | 5404 transaction.load_flags |= LOAD_VALIDATE_CACHE; |
5379 | 5405 |
5380 // Write to the cache. | 5406 // Write to the cache. |
5381 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); | 5407 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
5382 | 5408 |
5383 // And now read from the cache and the network. | 5409 // And now read from the cache and the network. |
5384 RangeTransactionServer handler; | 5410 RangeTransactionServer handler; |
5385 handler.set_bad_200(true); | 5411 handler.set_bad_200(true); |
5386 transaction.data = "Not a range"; | 5412 transaction.data = "Not a range"; |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5941 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 5967 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
5942 "ETag: \"foo\"\n" | 5968 "ETag: \"foo\"\n" |
5943 "Accept-Ranges: bytes\n" | 5969 "Accept-Ranges: bytes\n" |
5944 "Content-Length: 50\n"); | 5970 "Content-Length: 50\n"); |
5945 CreateTruncatedEntry(raw_headers, &cache); | 5971 CreateTruncatedEntry(raw_headers, &cache); |
5946 | 5972 |
5947 // Now make a regular request. We expect the code to fail the validation and | 5973 // Now make a regular request. We expect the code to fail the validation and |
5948 // retry the request without using byte ranges. | 5974 // retry the request without using byte ranges. |
5949 std::string headers; | 5975 std::string headers; |
5950 MockTransaction transaction(kRangeGET_TransactionOK); | 5976 MockTransaction transaction(kRangeGET_TransactionOK); |
5951 transaction.request_headers = EXTRA_HEADER; | 5977 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
5952 transaction.data = "Not a range"; | 5978 transaction.data = "Not a range"; |
5953 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 5979 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
5954 | 5980 |
5955 // The server will return 200 instead of a byte range. | 5981 // The server will return 200 instead of a byte range. |
5956 std::string expected_headers( | 5982 std::string expected_headers( |
5957 "HTTP/1.1 200 OK\n" | 5983 "HTTP/1.1 200 OK\n" |
5958 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); | 5984 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); |
5959 | 5985 |
5960 EXPECT_EQ(expected_headers, headers); | 5986 EXPECT_EQ(expected_headers, headers); |
5961 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 5987 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6095 | 6121 |
6096 std::string raw_headers("HTTP/1.1 200 OK\n" | 6122 std::string raw_headers("HTTP/1.1 200 OK\n" |
6097 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 6123 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
6098 "ETag: \"foo\"\n" | 6124 "ETag: \"foo\"\n" |
6099 "Accept-Ranges: bytes\n" | 6125 "Accept-Ranges: bytes\n" |
6100 "Content-Length: 80\n"); | 6126 "Content-Length: 80\n"); |
6101 CreateTruncatedEntry(raw_headers, &cache); | 6127 CreateTruncatedEntry(raw_headers, &cache); |
6102 | 6128 |
6103 // Now make a regular request. | 6129 // Now make a regular request. |
6104 std::string headers; | 6130 std::string headers; |
6105 transaction.request_headers = EXTRA_HEADER; | 6131 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER; |
6106 transaction.data = "Not a range"; | 6132 transaction.data = "Not a range"; |
6107 RangeTransactionServer handler; | 6133 RangeTransactionServer handler; |
6108 handler.set_bad_200(true); | 6134 handler.set_bad_200(true); |
6109 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 6135 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
6110 | 6136 |
6111 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6137 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
6112 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6138 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
6113 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 6139 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
6114 | 6140 |
6115 // Verify that the disk entry was updated. | 6141 // Verify that the disk entry was updated. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6250 | 6276 |
6251 MockHttpRequest request(kTestTransaction); | 6277 MockHttpRequest request(kTestTransaction); |
6252 TestCompletionCallback callback; | 6278 TestCompletionCallback callback; |
6253 | 6279 |
6254 // Write to the cache. | 6280 // Write to the cache. |
6255 { | 6281 { |
6256 scoped_ptr<HttpTransaction> trans; | 6282 scoped_ptr<HttpTransaction> trans; |
6257 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6283 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
6258 | 6284 |
6259 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6285 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
6260 if (rv == ERR_IO_PENDING) | 6286 ASSERT_EQ(OK, callback.GetResult(rv)); |
6261 rv = callback.WaitForResult(); | |
6262 ASSERT_EQ(OK, rv); | |
6263 | 6287 |
6264 const HttpResponseInfo* info = trans->GetResponseInfo(); | 6288 const HttpResponseInfo* info = trans->GetResponseInfo(); |
6265 ASSERT_TRUE(info); | 6289 ASSERT_TRUE(info); |
6266 | 6290 |
6267 EXPECT_EQ(info->headers->response_code(), 301); | 6291 EXPECT_EQ(info->headers->response_code(), 301); |
6268 | 6292 |
6269 std::string location; | 6293 std::string location; |
6270 info->headers->EnumerateHeader(NULL, "Location", &location); | 6294 info->headers->EnumerateHeader(NULL, "Location", &location); |
6271 EXPECT_EQ(location, "http://www.bar.com/"); | 6295 EXPECT_EQ(location, "http://www.bar.com/"); |
6272 | 6296 |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6929 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0); | 6953 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0); |
6930 } | 6954 } |
6931 | 6955 |
6932 // Tests that we handle truncated enries when StopCaching is called. | 6956 // Tests that we handle truncated enries when StopCaching is called. |
6933 TEST(HttpCache, StopCachingTruncatedEntry) { | 6957 TEST(HttpCache, StopCachingTruncatedEntry) { |
6934 MockHttpCache cache; | 6958 MockHttpCache cache; |
6935 TestCompletionCallback callback; | 6959 TestCompletionCallback callback; |
6936 MockHttpRequest request(kRangeGET_TransactionOK); | 6960 MockHttpRequest request(kRangeGET_TransactionOK); |
6937 request.extra_headers.Clear(); | 6961 request.extra_headers.Clear(); |
6938 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); | 6962 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); |
6939 AddMockTransaction(&kRangeGET_TransactionOK); | 6963 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
6940 | 6964 |
6941 std::string raw_headers("HTTP/1.1 200 OK\n" | 6965 std::string raw_headers("HTTP/1.1 200 OK\n" |
6942 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 6966 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
6943 "ETag: \"foo\"\n" | 6967 "ETag: \"foo\"\n" |
6944 "Accept-Ranges: bytes\n" | 6968 "Accept-Ranges: bytes\n" |
6945 "Content-Length: 80\n"); | 6969 "Content-Length: 80\n"); |
6946 CreateTruncatedEntry(raw_headers, &cache); | 6970 CreateTruncatedEntry(raw_headers, &cache); |
6947 | 6971 |
6948 { | 6972 { |
6949 // Now make a regular request. | 6973 // Now make a regular request. |
6950 scoped_ptr<HttpTransaction> trans; | 6974 scoped_ptr<HttpTransaction> trans; |
6951 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); | 6975 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); |
6952 | 6976 |
6953 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); | 6977 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
6954 EXPECT_EQ(OK, callback.GetResult(rv)); | 6978 EXPECT_EQ(OK, callback.GetResult(rv)); |
6955 | 6979 |
6956 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | 6980 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); |
6957 rv = trans->Read(buf.get(), 10, callback.callback()); | 6981 rv = trans->Read(buf.get(), 10, callback.callback()); |
6958 EXPECT_EQ(callback.GetResult(rv), 10); | 6982 EXPECT_EQ(callback.GetResult(rv), 10); |
6959 | 6983 |
6960 // This is actually going to do nothing. | |
6961 trans->StopCaching(); | 6984 trans->StopCaching(); |
6962 | 6985 |
6963 // We should be able to keep reading. | 6986 // We should be able to keep reading. |
6964 rv = trans->Read(buf.get(), 256, callback.callback()); | 6987 rv = trans->Read(buf.get(), 256, callback.callback()); |
6965 EXPECT_GT(callback.GetResult(rv), 0); | 6988 EXPECT_EQ(70, callback.GetResult(rv)); |
6966 rv = trans->Read(buf.get(), 256, callback.callback()); | 6989 rv = trans->Read(buf.get(), 256, callback.callback()); |
6967 EXPECT_GT(callback.GetResult(rv), 0); | 6990 EXPECT_EQ(0, callback.GetResult(rv)); |
6968 rv = trans->Read(buf.get(), 256, callback.callback()); | |
6969 EXPECT_EQ(callback.GetResult(rv), 0); | |
6970 } | 6991 } |
6971 | 6992 |
6972 // Verify that the disk entry was updated. | 6993 // Verify that the disk entry is still intact and contains the truncated data |
6973 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80); | 6994 // from before the request. |
6974 RemoveMockTransaction(&kRangeGET_TransactionOK); | 6995 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, true, 20); |
| 6996 } |
| 6997 |
| 6998 TEST(HttpCache, StopCachingKeepsSparseEntry) { |
| 6999 MockHttpCache cache; |
| 7000 TestCompletionCallback callback; |
| 7001 |
| 7002 // Create a sparse entry which contains 10 bytes at offset 20 out of an 80 |
| 7003 // byte resource. |
| 7004 MockTransaction mock_transaction(kRangeGET_TransactionOK); |
| 7005 mock_transaction.handler = nullptr; |
| 7006 mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER; |
| 7007 mock_transaction.response_headers = |
| 7008 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7009 "ETag: \"foo\"\n" |
| 7010 "Accept-Ranges: bytes\n" |
| 7011 "Content-Range: bytes 20-29/80\n" |
| 7012 "Content-Length: 10\n"; |
| 7013 mock_transaction.data = "rg: 20-29 "; |
| 7014 AddMockTransaction(&mock_transaction); |
| 7015 std::string headers; |
| 7016 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction, |
| 7017 &headers); |
| 7018 |
| 7019 // Verify our assumptions. There should be sparse entry here. |
| 7020 disk_cache::Entry* cache_entry; |
| 7021 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); |
| 7022 EXPECT_TRUE(cache_entry->CouldBeSparse()); |
| 7023 cache_entry->Close(); |
| 7024 RemoveMockTransaction(&mock_transaction); |
| 7025 |
| 7026 cache.ResetCounts(); |
| 7027 |
| 7028 // Prepare a request to read the entire contents of the resource. This should |
| 7029 // usually hope between network -> cache -> network. But not today. |
| 7030 mock_transaction.request_headers = EXTRA_HEADER; |
| 7031 mock_transaction.handler = kRangeGET_TransactionOK.handler; |
| 7032 mock_transaction.response_headers = |
| 7033 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7034 "ETag: \"foo\"\n" |
| 7035 "Accept-Ranges: bytes\n" |
| 7036 "Content-Length: 80\n"; |
| 7037 AddMockTransaction(&mock_transaction); |
| 7038 MockHttpRequest request(mock_transaction); |
| 7039 |
| 7040 scoped_ptr<HttpTransaction> transaction; |
| 7041 ASSERT_EQ(OK, cache.CreateTransaction(&transaction)); |
| 7042 int rv = transaction->Start(&request, callback.callback(), BoundNetLog()); |
| 7043 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7044 |
| 7045 const size_t kBufferSize = 256; |
| 7046 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); |
| 7047 |
| 7048 rv = transaction->Read(buffer.get(), 10, callback.callback()); |
| 7049 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7050 |
| 7051 // This should've caused a network read of 10 bytes. |
| 7052 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 7053 |
| 7054 // StopCaching() should cause the transaction to switch entirely to the |
| 7055 // network for the remainder of the response. Since the existing network |
| 7056 // transaction doesn't cover the entirety of the resource, the cache creates a |
| 7057 // new network transaction. |
| 7058 transaction->StopCaching(); |
| 7059 |
| 7060 // Since it's coming from a single network request, we can slurp the remainder |
| 7061 // of the resource in one request. |
| 7062 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); |
| 7063 EXPECT_EQ(70, callback.GetResult(rv)); |
| 7064 |
| 7065 // And we hit EOF. |
| 7066 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); |
| 7067 EXPECT_EQ(0, callback.GetResult(rv)); |
| 7068 |
| 7069 // Another network transaction is issued for the remainder of the resource |
| 7070 // following the StopCaching call. |
| 7071 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 7072 |
| 7073 // And the sparse entry is still here. |
| 7074 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); |
| 7075 cache_entry->Close(); |
| 7076 RemoveMockTransaction(&mock_transaction); |
| 7077 } |
| 7078 |
| 7079 // If StopCaching() is called while serving the entire request out of cache, the |
| 7080 // transaction is expected to ignore the StopCaching() call and continue serving |
| 7081 // the remainder of the resource out of the cache. |
| 7082 TEST(HttpCache, StopCachingKeepsFullEntry) { |
| 7083 MockHttpCache cache; |
| 7084 TestCompletionCallback callback; |
| 7085 |
| 7086 MockTransaction mock_transaction(kRangeGET_TransactionOK); |
| 7087 mock_transaction.handler = nullptr; |
| 7088 mock_transaction.request_headers = EXTRA_HEADER; |
| 7089 mock_transaction.status = "HTTP/1.1 200 OK"; |
| 7090 mock_transaction.response_headers = |
| 7091 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7092 "ETag: \"foo\"\n" |
| 7093 "Content-Length: 80\n"; |
| 7094 mock_transaction.data = kFullRangeData; |
| 7095 AddMockTransaction(&mock_transaction); |
| 7096 std::string headers; |
| 7097 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction, |
| 7098 &headers); |
| 7099 |
| 7100 cache.ResetCounts(); |
| 7101 |
| 7102 mock_transaction.request_headers = EXTRA_HEADER; |
| 7103 mock_transaction.handler = kRangeGET_TransactionOK.handler; |
| 7104 mock_transaction.response_headers = |
| 7105 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7106 "ETag: \"foo\"\n" |
| 7107 "Accept-Ranges: bytes\n" |
| 7108 "Content-Length: 80\n"; |
| 7109 AddMockTransaction(&mock_transaction); |
| 7110 MockHttpRequest request(mock_transaction); |
| 7111 |
| 7112 scoped_ptr<HttpTransaction> transaction; |
| 7113 ASSERT_EQ(OK, cache.CreateTransaction(&transaction)); |
| 7114 int rv = transaction->Start(&request, callback.callback(), BoundNetLog()); |
| 7115 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7116 |
| 7117 const size_t kBufferSize = 256; |
| 7118 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); |
| 7119 |
| 7120 rv = transaction->Read(buffer.get(), 10, callback.callback()); |
| 7121 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7122 |
| 7123 // This should've caused a cache read of 10 bytes. No new network transactions |
| 7124 // are expected. |
| 7125 EXPECT_EQ(0, cache.network_layer()->transaction_count()); |
| 7126 |
| 7127 // StopCaching() doesn't do anything because the entire resource is cached |
| 7128 // already. We proceed with the cache read. |
| 7129 transaction->StopCaching(); |
| 7130 |
| 7131 // Since it's all coming from a single network request, we can slurp the |
| 7132 // remainder of the resource in one request. |
| 7133 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); |
| 7134 EXPECT_EQ(70, callback.GetResult(rv)); |
| 7135 |
| 7136 // And we hit EOF. |
| 7137 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback()); |
| 7138 EXPECT_EQ(0, callback.GetResult(rv)); |
| 7139 |
| 7140 // We should've only seen one network transactions at this point. |
| 7141 EXPECT_EQ(0, cache.network_layer()->transaction_count()); |
| 7142 |
| 7143 // And the entry is still here. |
| 7144 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 7145 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
| 7146 disk_cache::Entry* cache_entry; |
| 7147 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); |
| 7148 cache_entry->Close(); |
| 7149 |
| 7150 RemoveMockTransaction(&mock_transaction); |
| 7151 } |
| 7152 |
| 7153 TEST(HttpCache, StopCachingReleasesCacheLockForNewCacheEntry) { |
| 7154 MockHttpCache cache; |
| 7155 TestCompletionCallback callback; |
| 7156 ScopedMockTransaction mock_transaction(kResumableGET_Transaction); |
| 7157 MockHttpRequest mock_request(mock_transaction); |
| 7158 |
| 7159 scoped_ptr<HttpTransaction> first_transaction; |
| 7160 ASSERT_EQ(OK, cache.CreateTransaction(&first_transaction)); |
| 7161 |
| 7162 int rv = first_transaction->Start(&mock_request, callback.callback(), |
| 7163 BoundNetLog()); |
| 7164 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7165 |
| 7166 const size_t kBufferSize = 1024; |
| 7167 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7168 rv = first_transaction->Read(buf.get(), 10, callback.callback()); |
| 7169 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7170 |
| 7171 first_transaction->StopCaching(); |
| 7172 |
| 7173 rv = first_transaction->Read(buf.get(), 10, callback.callback()); |
| 7174 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7175 |
| 7176 // Since the cache entry is no longer locked by |first_transaction|, we can |
| 7177 // start another transaction without blocking. The test should time out if |
| 7178 // this is not the case (i.e. the Start() call has to wait indefinitely[*] |
| 7179 // for the previous transaction to release the lock). |
| 7180 // |
| 7181 // [*]: The wait isn't really indefinite since the Start() call times out |
| 7182 // (currently after 20 seconds) and proceeds without the cache entry. Failure |
| 7183 // to release the cahe entry is accounted for by the previous |
| 7184 // disk_cache()->GetEntryCount() expectation. |
| 7185 scoped_ptr<HttpTransaction> second_transaction; |
| 7186 ASSERT_EQ(OK, cache.CreateTransaction(&second_transaction)); |
| 7187 rv = second_transaction->Start(&mock_request, callback.callback(), |
| 7188 BoundNetLog()); |
| 7189 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7190 |
| 7191 rv = second_transaction->Read(buf.get(), 10, callback.callback()); |
| 7192 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7193 |
| 7194 // First transaction creates a cache entry which the second transaction opens. |
| 7195 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 7196 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 7197 |
| 7198 // One network request for each cache transaction. |
| 7199 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 7200 |
| 7201 first_transaction.reset(); |
| 7202 second_transaction.reset(); |
| 7203 |
| 7204 // The cache entry is still around. It should be truncated and contain the 10 |
| 7205 // bytes that were written before the first StopCaching() call was made. |
| 7206 VerifyTruncatedFlag(&cache, kResumableGET_Transaction.url, true, 10); |
| 7207 } |
| 7208 |
| 7209 TEST(HttpCache, StopCachingReleasesCacheLockForTruncatedEntry) { |
| 7210 MockHttpCache cache; |
| 7211 TestCompletionCallback callback; |
| 7212 ScopedMockTransaction mock_transaction(kResumableGET_Transaction); |
| 7213 MockHttpRequest mock_request(kResumableGET_Transaction); |
| 7214 std::string raw_headers( |
| 7215 "HTTP/1.1 200 OK\n" |
| 7216 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7217 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n" |
| 7218 "ETag: \"foo\"\n" |
| 7219 "Accept-Ranges: bytes\n" |
| 7220 "Content-Length: 80\n"); |
| 7221 CreateTruncatedEntry(raw_headers, &cache); |
| 7222 cache.ResetCounts(); |
| 7223 |
| 7224 scoped_ptr<HttpTransaction> first_transaction; |
| 7225 int rv = cache.CreateTransaction(&first_transaction); |
| 7226 ASSERT_EQ(OK, rv); |
| 7227 ASSERT_TRUE(first_transaction.get()); |
| 7228 |
| 7229 rv = first_transaction->Start(&mock_request, callback.callback(), |
| 7230 BoundNetLog()); |
| 7231 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7232 |
| 7233 first_transaction->StopCaching(); |
| 7234 |
| 7235 const int kBufferSize = 1024; |
| 7236 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7237 rv = first_transaction->Read(buf.get(), 10, callback.callback()); |
| 7238 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7239 |
| 7240 // Now that the cache lock is released, another transaction can begin. The |
| 7241 // Start() call should complete without delay. The test should timeout if this |
| 7242 // is not the case (i.e. the Start() call has to wait indefinitely[*] for the |
| 7243 // previous transaction to release the lock). |
| 7244 // |
| 7245 // [*]: The wait isn't really indefinite since the Start() call times out |
| 7246 // (currently after 20 seconds) and proceeds without the cache entry. This |
| 7247 // case is accounted for by the network_layer()->transaction_count() |
| 7248 // expectation below. |
| 7249 scoped_ptr<HttpTransaction> second_transaction; |
| 7250 rv = cache.CreateTransaction(&second_transaction); |
| 7251 ASSERT_EQ(OK, rv); |
| 7252 ASSERT_TRUE(second_transaction); |
| 7253 rv = second_transaction->Start(&mock_request, callback.callback(), |
| 7254 BoundNetLog()); |
| 7255 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7256 |
| 7257 rv = second_transaction->Read(buf.get(), 10, callback.callback()); |
| 7258 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7259 |
| 7260 // first_transaction: |
| 7261 // 1 open cache entry. |
| 7262 // 1 network fetch for validation. |
| 7263 // 1 network fetch for switching to the network. |
| 7264 // second_transaction: |
| 7265 // 1 open cache entry. |
| 7266 // 1 network fetch for validation. |
| 7267 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
| 7268 EXPECT_EQ(2, cache.disk_cache()->open_count()); |
| 7269 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 7270 |
| 7271 first_transaction.reset(); |
| 7272 second_transaction.reset(); |
| 7273 VerifyTruncatedFlag(&cache, kResumableGET_Transaction.url, true, 20); |
| 7274 } |
| 7275 |
| 7276 TEST(HttpCache, StopCachingReleasesCacheLockForSparseEntry) { |
| 7277 MockHttpCache cache; |
| 7278 TestCompletionCallback callback; |
| 7279 |
| 7280 // Create a sparse entry which contains 10 bytes at offset 20 out of an 80 |
| 7281 // byte resource. |
| 7282 MockTransaction mock_transaction(kRangeGET_TransactionOK); |
| 7283 mock_transaction.handler = nullptr; |
| 7284 mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER; |
| 7285 mock_transaction.response_headers = |
| 7286 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7287 "ETag: \"foo\"\n" |
| 7288 "Accept-Ranges: bytes\n" |
| 7289 "Content-Range: bytes 20-29/80\n" |
| 7290 "Content-Length: 10\n"; |
| 7291 mock_transaction.data = "rg: 20-29 "; |
| 7292 AddMockTransaction(&mock_transaction); |
| 7293 std::string headers; |
| 7294 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction, |
| 7295 &headers); |
| 7296 |
| 7297 // Verify our assumptions. There should be sparse entry here. |
| 7298 disk_cache::Entry* cache_entry; |
| 7299 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); |
| 7300 EXPECT_TRUE(cache_entry->CouldBeSparse()); |
| 7301 cache_entry->Close(); |
| 7302 RemoveMockTransaction(&mock_transaction); |
| 7303 |
| 7304 cache.ResetCounts(); |
| 7305 |
| 7306 // Prepare a request to read the entire contents of the resource. This should |
| 7307 // usually hope between network -> cache -> network. But not today. |
| 7308 mock_transaction.request_headers = EXTRA_HEADER; |
| 7309 mock_transaction.handler = kRangeGET_TransactionOK.handler; |
| 7310 mock_transaction.response_headers = |
| 7311 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7312 "ETag: \"foo\"\n" |
| 7313 "Accept-Ranges: bytes\n" |
| 7314 "Content-Length: 10\n"; |
| 7315 AddMockTransaction(&mock_transaction); |
| 7316 MockHttpRequest request(mock_transaction); |
| 7317 |
| 7318 scoped_ptr<HttpTransaction> first_transaction; |
| 7319 ASSERT_EQ(OK, cache.CreateTransaction(&first_transaction)); |
| 7320 int rv = |
| 7321 first_transaction->Start(&request, callback.callback(), BoundNetLog()); |
| 7322 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7323 |
| 7324 const size_t kBufferSize = 256; |
| 7325 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); |
| 7326 |
| 7327 rv = first_transaction->Read(buffer.get(), 10, callback.callback()); |
| 7328 EXPECT_EQ(10, callback.GetResult(rv)); |
| 7329 |
| 7330 // Create another cache transaction. This one is blocked on the first |
| 7331 // transaction's cache lock. |
| 7332 scoped_ptr<HttpTransaction> second_transaction; |
| 7333 TestCompletionCallback second_callback; |
| 7334 ASSERT_EQ(OK, cache.CreateTransaction(&second_transaction)); |
| 7335 rv = second_transaction->Start(&request, second_callback.callback(), |
| 7336 BoundNetLog()); |
| 7337 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 7338 |
| 7339 // StopCaching() should cause the transaction to switch entirely to the |
| 7340 // network for the remainder of the response. Since the existing network |
| 7341 // transaction doesn't cover the entirety of the resource, the cache creates a |
| 7342 // new network transaction. |
| 7343 first_transaction->StopCaching(); |
| 7344 |
| 7345 // Since it's coming from a single network request, we can slurp the remaining |
| 7346 // 70 bytes of the resource in one request. Let's leave a little bit on the |
| 7347 // pipe so that the stream doesn't hit EOF. |
| 7348 rv = first_transaction->Read(buffer.get(), 60, callback.callback()); |
| 7349 EXPECT_EQ(60, callback.GetResult(rv)); |
| 7350 |
| 7351 // The second transaction should become unblocked at this point. |
| 7352 EXPECT_EQ(OK, second_callback.GetResult(ERR_IO_PENDING)); |
| 7353 |
| 7354 // And it can read the entire resource too, but needs to alternate between |
| 7355 // cache and network.. |
| 7356 // 0-9 from cache (due to the first Read() on first_transaction). |
| 7357 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read( |
| 7358 buffer.get(), kBufferSize, second_callback.callback()))); |
| 7359 |
| 7360 // 10-19 From network: |
| 7361 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read( |
| 7362 buffer.get(), kBufferSize, second_callback.callback()))); |
| 7363 |
| 7364 // 20-29 From cache (due to test setup): |
| 7365 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read( |
| 7366 buffer.get(), kBufferSize, second_callback.callback()))); |
| 7367 |
| 7368 // 30-79 From network again: |
| 7369 EXPECT_EQ(50, second_callback.GetResult(second_transaction->Read( |
| 7370 buffer.get(), kBufferSize, second_callback.callback()))); |
| 7371 EXPECT_EQ(0, second_callback.GetResult(second_transaction->Read( |
| 7372 buffer.get(), kBufferSize, second_callback.callback()))); |
| 7373 |
| 7374 // Now drain first_transaction as well. |
| 7375 EXPECT_EQ(10, callback.GetResult(first_transaction->Read( |
| 7376 buffer.get(), kBufferSize, callback.callback()))); |
| 7377 EXPECT_EQ(0, callback.GetResult(first_transaction->Read( |
| 7378 buffer.get(), kBufferSize, callback.callback()))); |
| 7379 |
| 7380 // first_transaction: |
| 7381 // 1 open cache entry. |
| 7382 // 2 network fetches (0-19 and 10-79). |
| 7383 // second_transaction: |
| 7384 // 1 open cache entry. |
| 7385 // 2 network fetches (10-19 and 30-79). |
| 7386 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
| 7387 EXPECT_EQ(4, cache.network_layer()->transaction_count()); |
| 7388 |
| 7389 // Even though there are two HttpCache::OpenEntry() calls, there's only one |
| 7390 // DiskCache::OpenEntry call because HttpCache already has an active entry. |
| 7391 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 7392 |
| 7393 // And the sparse entry is still here. |
| 7394 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry)); |
| 7395 cache_entry->Close(); |
| 7396 RemoveMockTransaction(&mock_transaction); |
| 7397 } |
| 7398 |
| 7399 TEST(HttpCache, StopCachingAfterStartForLoadPreferringCacheWithInvalidation) { |
| 7400 MockHttpCache cache; |
| 7401 TestCompletionCallback callback; |
| 7402 MockTransaction transaction(kSimpleGET_Transaction); |
| 7403 |
| 7404 AddMockTransaction(&transaction); |
| 7405 RunTransactionTest(cache.http_cache(), transaction); |
| 7406 RemoveMockTransaction(&transaction); |
| 7407 cache.ResetCounts(); |
| 7408 |
| 7409 transaction.load_flags |= LOAD_PREFERRING_CACHE; |
| 7410 AddMockTransaction(&transaction); |
| 7411 |
| 7412 scoped_ptr<HttpTransaction> http_transaction; |
| 7413 |
| 7414 int rv = cache.CreateTransaction(&http_transaction); |
| 7415 ASSERT_EQ(OK, rv); |
| 7416 |
| 7417 MockHttpRequest request(transaction); |
| 7418 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog()); |
| 7419 ASSERT_EQ(OK, callback.GetResult(rv)); |
| 7420 |
| 7421 http_transaction->StopCaching(); |
| 7422 |
| 7423 ReadAndVerifyTransaction(http_transaction.get(), transaction); |
| 7424 RemoveMockTransaction(&transaction); |
| 7425 |
| 7426 EXPECT_EQ(0, cache.network_layer()->transaction_count()); |
| 7427 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 7428 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
| 7429 } |
| 7430 |
| 7431 namespace { |
| 7432 |
| 7433 enum class TransactionPhase { |
| 7434 BEFORE_FIRST_READ, |
| 7435 AFTER_FIRST_READ, |
| 7436 AFTER_NETWORK_READ |
| 7437 }; |
| 7438 |
| 7439 using CacheInitializer = void (*)(MockHttpCache*); |
| 7440 using HugeCacheTestConfiguration = |
| 7441 std::pair<TransactionPhase, CacheInitializer>; |
| 7442 |
| 7443 class HttpCacheHugeResourceTest |
| 7444 : public ::testing::TestWithParam<HugeCacheTestConfiguration> { |
| 7445 public: |
| 7446 static std::list<HugeCacheTestConfiguration> GetTestModes(); |
| 7447 static std::list<HugeCacheTestConfiguration> kTestModes; |
| 7448 |
| 7449 // CacheInitializer callbacks. These are used to initialize the cache |
| 7450 // depending on the test run configuration. |
| 7451 |
| 7452 // Initializes a cache containing a truncated entry containing the first 20 |
| 7453 // bytes of the reponse body. |
| 7454 static void SetupTruncatedCacheEntry(MockHttpCache* cache); |
| 7455 |
| 7456 // Initializes a cache containing a sparse entry. The first 10 bytes are |
| 7457 // present in the cache. |
| 7458 static void SetupPrefixSparseCacheEntry(MockHttpCache* cache); |
| 7459 |
| 7460 // Initializes a cache containing a sparse entry. The 10 bytes at offset |
| 7461 // 99999990 are present in the cache. |
| 7462 static void SetupInfixSparseCacheEntry(MockHttpCache* cache); |
| 7463 |
| 7464 protected: |
| 7465 static void ExpectByteRangeTransactionHandler( |
| 7466 const net::HttpRequestInfo* request, |
| 7467 std::string* response_status, |
| 7468 std::string* response_headers, |
| 7469 std::string* response_data); |
| 7470 static int LargeBufferReader(int64 content_length, |
| 7471 int64 offset, |
| 7472 net::IOBuffer* buf, |
| 7473 int buf_len); |
| 7474 |
| 7475 static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */); |
| 7476 |
| 7477 // Size of resource to be tested. |
| 7478 static const int64 kTotalSize = |
| 7479 5000000000LL; // Five beeeeeelllliooonn bytes! |
| 7480 }; |
| 7481 |
| 7482 const int64 HttpCacheHugeResourceTest::kTotalSize; |
| 7483 |
| 7484 // static |
| 7485 void HttpCacheHugeResourceTest::ExpectByteRangeTransactionHandler( |
| 7486 const net::HttpRequestInfo* request, |
| 7487 std::string* response_status, |
| 7488 std::string* response_headers, |
| 7489 std::string* response_data) { |
| 7490 std::string if_range; |
| 7491 EXPECT_TRUE(request->extra_headers.GetHeader( |
| 7492 net::HttpRequestHeaders::kIfRange, &if_range)); |
| 7493 EXPECT_EQ("\"foo\"", if_range); |
| 7494 |
| 7495 std::string range_header; |
| 7496 EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange, |
| 7497 &range_header)); |
| 7498 std::vector<net::HttpByteRange> ranges; |
| 7499 |
| 7500 EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges)); |
| 7501 ASSERT_EQ(1u, ranges.size()); |
| 7502 |
| 7503 net::HttpByteRange range = ranges[0]; |
| 7504 EXPECT_TRUE(range.HasFirstBytePosition()); |
| 7505 int64 last_byte_position = |
| 7506 range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1; |
| 7507 |
| 7508 response_status->assign("HTTP/1.1 206 Partial"); |
| 7509 response_headers->assign(base::StringPrintf( |
| 7510 "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64 |
| 7511 "\n" |
| 7512 "Content-Length: %" PRId64 "\n", |
| 7513 range.first_byte_position(), last_byte_position, kTotalSize, |
| 7514 last_byte_position - range.first_byte_position() + 1)); |
| 7515 } |
| 7516 |
| 7517 // static |
| 7518 int HttpCacheHugeResourceTest::LargeBufferReader(int64 content_length, |
| 7519 int64 offset, |
| 7520 net::IOBuffer* buf, |
| 7521 int buf_len) { |
| 7522 // This test involves reading multiple gigabytes of data. To make it run in a |
| 7523 // reasonable amount of time, we are going to skip filling the buffer with |
| 7524 // data. Instead the test relies on verifying that the count of bytes expected |
| 7525 // at the end is correct. |
| 7526 EXPECT_LT(0, content_length); |
| 7527 EXPECT_LE(offset, content_length); |
| 7528 int num = std::min(static_cast<int64>(buf_len), content_length - offset); |
| 7529 return num; |
| 7530 } |
| 7531 |
| 7532 // static |
| 7533 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started, |
| 7534 bool* /* defer */) { |
| 7535 *started = true; |
| 7536 } |
| 7537 |
| 7538 // static |
| 7539 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) { |
| 7540 ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK); |
| 7541 std::string cached_headers = base::StringPrintf( |
| 7542 "HTTP/1.1 200 OK\n" |
| 7543 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7544 "ETag: \"foo\"\n" |
| 7545 "Accept-Ranges: bytes\n" |
| 7546 "Content-Length: %" PRId64 "\n", |
| 7547 kTotalSize); |
| 7548 CreateTruncatedEntry(cached_headers, cache); |
| 7549 } |
| 7550 |
| 7551 // static |
| 7552 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry( |
| 7553 MockHttpCache* cache) { |
| 7554 MockTransaction transaction(kRangeGET_TransactionOK); |
| 7555 transaction.handler = nullptr; |
| 7556 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; |
| 7557 transaction.response_headers = |
| 7558 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7559 "ETag: \"foo\"\n" |
| 7560 "Accept-Ranges: bytes\n" |
| 7561 "Content-Range: bytes 0-9/5000000000\n" |
| 7562 "Content-Length: 10\n"; |
| 7563 AddMockTransaction(&transaction); |
| 7564 std::string headers; |
| 7565 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers); |
| 7566 RemoveMockTransaction(&transaction); |
| 7567 } |
| 7568 |
| 7569 // static |
| 7570 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry( |
| 7571 MockHttpCache* cache) { |
| 7572 MockTransaction transaction(kRangeGET_TransactionOK); |
| 7573 transaction.handler = nullptr; |
| 7574 transaction.request_headers = |
| 7575 "Range: bytes = 99999990-99999999\r\n" EXTRA_HEADER; |
| 7576 transaction.response_headers = |
| 7577 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" |
| 7578 "ETag: \"foo\"\n" |
| 7579 "Accept-Ranges: bytes\n" |
| 7580 "Content-Range: bytes 99999990-99999999/5000000000\n" |
| 7581 "Content-Length: 10\n"; |
| 7582 AddMockTransaction(&transaction); |
| 7583 std::string headers; |
| 7584 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers); |
| 7585 RemoveMockTransaction(&transaction); |
| 7586 } |
| 7587 |
| 7588 // static |
| 7589 std::list<HugeCacheTestConfiguration> |
| 7590 HttpCacheHugeResourceTest::GetTestModes() { |
| 7591 std::list<HugeCacheTestConfiguration> test_modes; |
| 7592 const TransactionPhase kTransactionPhases[] = { |
| 7593 TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ, |
| 7594 TransactionPhase::AFTER_NETWORK_READ}; |
| 7595 const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry, |
| 7596 &SetupPrefixSparseCacheEntry, |
| 7597 &SetupInfixSparseCacheEntry}; |
| 7598 |
| 7599 for (const auto phase : kTransactionPhases) |
| 7600 for (const auto initializer : kInitializers) |
| 7601 test_modes.push_back(std::make_pair(phase, initializer)); |
| 7602 |
| 7603 return test_modes; |
| 7604 } |
| 7605 |
| 7606 // static |
| 7607 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes = |
| 7608 HttpCacheHugeResourceTest::GetTestModes(); |
| 7609 |
| 7610 INSTANTIATE_TEST_CASE_P( |
| 7611 _, |
| 7612 HttpCacheHugeResourceTest, |
| 7613 ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes)); |
| 7614 |
| 7615 } // namespace |
| 7616 |
| 7617 // Test what happens when StopCaching() is called while reading a huge resource |
| 7618 // fetched via GET. Various combinations of cache state and when StopCaching() |
| 7619 // is called is controlled by the parameter passed into the test via the |
| 7620 // INSTANTIATE_TEST_CASE_P invocation above. |
| 7621 TEST_P(HttpCacheHugeResourceTest, |
| 7622 StopCachingFollowedByReadForHugeTruncatedResource) { |
| 7623 // This test is going to be repeated for all combinations of TransactionPhase |
| 7624 // and CacheInitializers returned by GetTestModes(). |
| 7625 const TransactionPhase stop_caching_phase = GetParam().first; |
| 7626 const CacheInitializer cache_initializer = GetParam().second; |
| 7627 |
| 7628 MockHttpCache cache; |
| 7629 (*cache_initializer)(&cache); |
| 7630 |
| 7631 MockTransaction transaction(kSimpleGET_Transaction); |
| 7632 transaction.url = kRangeGET_TransactionOK.url; |
| 7633 transaction.handler = &ExpectByteRangeTransactionHandler; |
| 7634 transaction.read_handler = &LargeBufferReader; |
| 7635 ScopedMockTransaction scoped_transaction(transaction); |
| 7636 |
| 7637 MockHttpRequest request(transaction); |
| 7638 net::TestCompletionCallback callback; |
| 7639 scoped_ptr<net::HttpTransaction> http_transaction; |
| 7640 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, |
| 7641 &http_transaction); |
| 7642 ASSERT_EQ(net::OK, rv); |
| 7643 ASSERT_TRUE(http_transaction.get()); |
| 7644 |
| 7645 bool network_transaction_started = false; |
| 7646 if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) { |
| 7647 http_transaction->SetBeforeNetworkStartCallback( |
| 7648 base::Bind(&SetFlagOnBeforeNetworkStart, &network_transaction_started)); |
| 7649 } |
| 7650 |
| 7651 rv = http_transaction->Start(&request, callback.callback(), |
| 7652 net::BoundNetLog()); |
| 7653 rv = callback.GetResult(rv); |
| 7654 ASSERT_EQ(net::OK, rv); |
| 7655 |
| 7656 if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ) |
| 7657 http_transaction->StopCaching(); |
| 7658 |
| 7659 int64 total_bytes_received = 0; |
| 7660 |
| 7661 EXPECT_EQ(kTotalSize, |
| 7662 http_transaction->GetResponseInfo()->headers->GetContentLength()); |
| 7663 do { |
| 7664 // This test simulates reading Gigabytes of data. Buffer size is set to 1MB |
| 7665 // to reduce the number of reads and speedup the test. |
| 7666 const int kBufferSize = 1024 * 1024; |
| 7667 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize)); |
| 7668 rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback()); |
| 7669 rv = callback.GetResult(rv); |
| 7670 |
| 7671 if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ && |
| 7672 total_bytes_received == 0) { |
| 7673 http_transaction->StopCaching(); |
| 7674 } |
| 7675 |
| 7676 if (rv > 0) |
| 7677 total_bytes_received += rv; |
| 7678 |
| 7679 if (network_transaction_started && |
| 7680 stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) { |
| 7681 http_transaction->StopCaching(); |
| 7682 network_transaction_started = false; |
| 7683 } |
| 7684 } while (rv > 0); |
| 7685 |
| 7686 // The only verification we are going to do is that the received resource has |
| 7687 // the correct size. This is sufficient to verify that the state machine |
| 7688 // didn't terminate abruptly due to the StopCaching() call. |
| 7689 EXPECT_EQ(kTotalSize, total_bytes_received); |
6975 } | 7690 } |
6976 | 7691 |
6977 // Tests that we detect truncated resources from the net when there is | 7692 // Tests that we detect truncated resources from the net when there is |
6978 // a Content-Length header. | 7693 // a Content-Length header. |
6979 TEST(HttpCache, TruncatedByContentLength) { | 7694 TEST(HttpCache, TruncatedByContentLength) { |
6980 MockHttpCache cache; | 7695 MockHttpCache cache; |
6981 TestCompletionCallback callback; | 7696 TestCompletionCallback callback; |
6982 | 7697 |
6983 MockTransaction transaction(kSimpleGET_Transaction); | 7698 MockTransaction transaction(kSimpleGET_Transaction); |
6984 AddMockTransaction(&transaction); | 7699 AddMockTransaction(&transaction); |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7653 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 8368 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
7654 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 8369 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
7655 EXPECT_TRUE(response_info.was_cached); | 8370 EXPECT_TRUE(response_info.was_cached); |
7656 | 8371 |
7657 // The new SSL state is reported. | 8372 // The new SSL state is reported. |
7658 EXPECT_EQ(status2, response_info.ssl_info.connection_status); | 8373 EXPECT_EQ(status2, response_info.ssl_info.connection_status); |
7659 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); | 8374 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); |
7660 } | 8375 } |
7661 | 8376 |
7662 } // namespace net | 8377 } // namespace net |
OLD | NEW |