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 3 // found in the LICENSE file. 4 5 #include "net/http/http_cache.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/memory/scoped_vector.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/stringprintf.h" 13 #include "net/base/cache_type.h" 14 #include "net/base/host_port_pair.h" 15 #include "net/base/load_flags.h" 16 #include "net/base/load_timing_info.h" 17 #include "net/base/load_timing_info_test_util.h" 18 #include "net/base/net_errors.h" 19 #include "net/base/net_log_unittest.h" 20 #include "net/base/upload_bytes_element_reader.h" 21 #include "net/base/upload_data_stream.h" 22 #include "net/cert/cert_status_flags.h" 23 #include "net/disk_cache/disk_cache.h" 24 #include "net/http/http_byte_range.h" 25 #include "net/http/http_request_headers.h" 26 #include "net/http/http_request_info.h" 27 #include "net/http/http_response_headers.h" 28 #include "net/http/http_response_info.h" 29 #include "net/http/http_transaction.h" 30 #include "net/http/http_transaction_delegate.h" 31 #include "net/http/http_transaction_unittest.h" 32 #include "net/http/http_util.h" 33 #include "net/http/mock_http_cache.h" 34 #include "net/ssl/ssl_cert_request_info.h" 35 #include "testing/gtest/include/gtest/gtest.h" 36 37 using base::Time; 38 39 namespace { 40 41 // Tests the load timing values of a request that goes through a 42 // MockNetworkTransaction. 43 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) { 44 EXPECT_FALSE(load_timing_info.socket_reused); 45 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 46 47 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 48 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 49 50 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 51 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); 52 EXPECT_LE(load_timing_info.connect_timing.connect_end, 53 load_timing_info.send_start); 54 55 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); 56 57 // Set by URLRequest / URLRequestHttpJob, at a higher level. 58 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 59 EXPECT_TRUE(load_timing_info.request_start.is_null()); 60 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 61 } 62 63 // Tests the load timing values of a request that receives a cached response. 64 void TestLoadTimingCachedResponse(const net::LoadTimingInfo& load_timing_info) { 65 EXPECT_FALSE(load_timing_info.socket_reused); 66 EXPECT_EQ(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 67 68 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); 69 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); 70 71 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 72 73 // Only the send start / end times should be sent, and they should have the 74 // same value. 75 EXPECT_FALSE(load_timing_info.send_start.is_null()); 76 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end); 77 78 // Set by URLRequest / URLRequestHttpJob, at a higher level. 79 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 80 EXPECT_TRUE(load_timing_info.request_start.is_null()); 81 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 82 } 83 84 class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase { 85 public: 86 explicit DeleteCacheCompletionCallback(MockHttpCache* cache) 87 : cache_(cache), 88 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, 89 base::Unretained(this))) { 90 } 91 92 const net::CompletionCallback& callback() const { return callback_; } 93 94 private: 95 void OnComplete(int result) { 96 delete cache_; 97 SetResult(result); 98 } 99 100 MockHttpCache* cache_; 101 net::CompletionCallback callback_; 102 103 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback); 104 }; 105 106 //----------------------------------------------------------------------------- 107 // helpers 108 109 class TestHttpTransactionDelegate : public net::HttpTransactionDelegate { 110 public: 111 TestHttpTransactionDelegate(int num_cache_actions_to_observe, 112 int num_network_actions_to_observe) 113 : num_callbacks_observed_(0), 114 num_remaining_cache_actions_to_observe_(num_cache_actions_to_observe), 115 num_remaining_network_actions_to_observe_( 116 num_network_actions_to_observe), 117 cache_action_in_progress_(false), 118 network_action_in_progress_(false) { 119 } 120 virtual ~TestHttpTransactionDelegate() { 121 EXPECT_EQ(0, num_remaining_cache_actions_to_observe_); 122 EXPECT_EQ(0, num_remaining_network_actions_to_observe_); 123 EXPECT_FALSE(cache_action_in_progress_); 124 EXPECT_FALSE(network_action_in_progress_); 125 } 126 virtual void OnCacheActionStart() OVERRIDE { 127 num_callbacks_observed_++; 128 EXPECT_FALSE(cache_action_in_progress_); 129 EXPECT_FALSE(network_action_in_progress_); 130 EXPECT_GT(num_remaining_cache_actions_to_observe_, 0); 131 num_remaining_cache_actions_to_observe_--; 132 cache_action_in_progress_ = true; 133 } 134 virtual void OnCacheActionFinish() OVERRIDE { 135 num_callbacks_observed_++; 136 EXPECT_TRUE(cache_action_in_progress_); 137 cache_action_in_progress_ = false; 138 } 139 virtual void OnNetworkActionStart() OVERRIDE { 140 num_callbacks_observed_++; 141 EXPECT_FALSE(cache_action_in_progress_); 142 EXPECT_FALSE(network_action_in_progress_); 143 EXPECT_GT(num_remaining_network_actions_to_observe_, 0); 144 num_remaining_network_actions_to_observe_--; 145 network_action_in_progress_ = true; 146 } 147 virtual void OnNetworkActionFinish() OVERRIDE { 148 num_callbacks_observed_++; 149 EXPECT_TRUE(network_action_in_progress_); 150 network_action_in_progress_ = false; 151 } 152 153 int num_callbacks_observed() { return num_callbacks_observed_; } 154 155 private: 156 int num_callbacks_observed_; 157 int num_remaining_cache_actions_to_observe_; 158 int num_remaining_network_actions_to_observe_; 159 bool cache_action_in_progress_; 160 bool network_action_in_progress_; 161 }; 162 163 void ReadAndVerifyTransaction(net::HttpTransaction* trans, 164 const MockTransaction& trans_info) { 165 std::string content; 166 int rv = ReadTransaction(trans, &content); 167 168 EXPECT_EQ(net::OK, rv); 169 std::string expected(trans_info.data); 170 EXPECT_EQ(expected, content); 171 } 172 173 const int kNoDelegateTransactionCheck = -1; 174 175 void RunTransactionTestWithRequestAndDelegateAndGetTiming( 176 net::HttpCache* cache, 177 const MockTransaction& trans_info, 178 const MockHttpRequest& request, 179 net::HttpResponseInfo* response_info, 180 int num_cache_delegate_actions, 181 int num_network_delegate_actions, 182 const net::BoundNetLog& net_log, 183 net::LoadTimingInfo* load_timing_info) { 184 net::TestCompletionCallback callback; 185 186 // write to the cache 187 188 scoped_ptr<TestHttpTransactionDelegate> delegate; 189 if (num_cache_delegate_actions != kNoDelegateTransactionCheck && 190 num_network_delegate_actions != kNoDelegateTransactionCheck) { 191 delegate.reset( 192 new TestHttpTransactionDelegate(num_cache_delegate_actions, 193 num_network_delegate_actions)); 194 } 195 scoped_ptr<net::HttpTransaction> trans; 196 int rv = cache->CreateTransaction( 197 net::DEFAULT_PRIORITY, &trans, delegate.get()); 198 EXPECT_EQ(net::OK, rv); 199 ASSERT_TRUE(trans.get()); 200 201 rv = trans->Start(&request, callback.callback(), net_log); 202 if (rv == net::ERR_IO_PENDING) 203 rv = callback.WaitForResult(); 204 ASSERT_EQ(trans_info.return_code, rv); 205 206 if (net::OK != rv) 207 return; 208 209 const net::HttpResponseInfo* response = trans->GetResponseInfo(); 210 ASSERT_TRUE(response); 211 212 if (response_info) 213 *response_info = *response; 214 215 if (load_timing_info) { 216 // If a fake network connection is used, need a NetLog to get a fake socket 217 // ID. 218 EXPECT_TRUE(net_log.net_log()); 219 *load_timing_info = net::LoadTimingInfo(); 220 trans->GetLoadTimingInfo(load_timing_info); 221 } 222 223 ReadAndVerifyTransaction(trans.get(), trans_info); 224 } 225 226 void RunTransactionTestWithRequestAndDelegate( 227 net::HttpCache* cache, 228 const MockTransaction& trans_info, 229 const MockHttpRequest& request, 230 net::HttpResponseInfo* response_info, 231 int num_cache_delegate_actions, 232 int num_network_delegate_actions) { 233 RunTransactionTestWithRequestAndDelegateAndGetTiming( 234 cache, trans_info, request, response_info, num_cache_delegate_actions, 235 num_network_delegate_actions, net::BoundNetLog(), NULL); 236 } 237 238 void RunTransactionTestWithRequest(net::HttpCache* cache, 239 const MockTransaction& trans_info, 240 const MockHttpRequest& request, 241 net::HttpResponseInfo* response_info) { 242 RunTransactionTestWithRequestAndDelegate( 243 cache, trans_info, request, response_info, kNoDelegateTransactionCheck, 244 kNoDelegateTransactionCheck); 245 } 246 247 void RunTransactionTestAndGetTiming( 248 net::HttpCache* cache, 249 const MockTransaction& trans_info, 250 const net::BoundNetLog& log, 251 net::LoadTimingInfo* load_timing_info) { 252 RunTransactionTestWithRequestAndDelegateAndGetTiming( 253 cache, trans_info, MockHttpRequest(trans_info), NULL, 254 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log, 255 load_timing_info); 256 } 257 258 void RunTransactionTestWithDelegate(net::HttpCache* cache, 259 const MockTransaction& trans_info, 260 int num_cache_delegate_actions, 261 int num_network_delegate_actions) { 262 RunTransactionTestWithRequestAndDelegate( 263 cache, trans_info, MockHttpRequest(trans_info), NULL, 264 num_cache_delegate_actions, num_network_delegate_actions); 265 } 266 267 void RunTransactionTest(net::HttpCache* cache, 268 const MockTransaction& trans_info) { 269 RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL); 270 } 271 272 void RunTransactionTestWithResponseInfo(net::HttpCache* cache, 273 const MockTransaction& trans_info, 274 net::HttpResponseInfo* response) { 275 RunTransactionTestWithRequest( 276 cache, trans_info, MockHttpRequest(trans_info), response); 277 } 278 279 void RunTransactionTestWithResponseInfoAndGetTiming( 280 net::HttpCache* cache, 281 const MockTransaction& trans_info, 282 net::HttpResponseInfo* response, 283 const net::BoundNetLog& log, 284 net::LoadTimingInfo* load_timing_info) { 285 RunTransactionTestWithRequestAndDelegateAndGetTiming( 286 cache, trans_info, MockHttpRequest(trans_info), response, 287 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log, 288 load_timing_info); 289 } 290 291 void RunTransactionTestWithResponse(net::HttpCache* cache, 292 const MockTransaction& trans_info, 293 std::string* response_headers) { 294 net::HttpResponseInfo response; 295 RunTransactionTestWithResponseInfo(cache, trans_info, &response); 296 response.headers->GetNormalizedHeaders(response_headers); 297 } 298 299 void RunTransactionTestWithResponseAndGetTiming( 300 net::HttpCache* cache, 301 const MockTransaction& trans_info, 302 std::string* response_headers, 303 const net::BoundNetLog& log, 304 net::LoadTimingInfo* load_timing_info) { 305 net::HttpResponseInfo response; 306 RunTransactionTestWithRequestAndDelegateAndGetTiming( 307 cache, trans_info, MockHttpRequest(trans_info), &response, 308 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, 309 log, load_timing_info); 310 response.headers->GetNormalizedHeaders(response_headers); 311 } 312 313 // This class provides a handler for kFastNoStoreGET_Transaction so that the 314 // no-store header can be included on demand. 315 class FastTransactionServer { 316 public: 317 FastTransactionServer() { 318 no_store = false; 319 } 320 ~FastTransactionServer() {} 321 322 void set_no_store(bool value) { no_store = value; } 323 324 static void FastNoStoreHandler(const net::HttpRequestInfo* request, 325 std::string* response_status, 326 std::string* response_headers, 327 std::string* response_data) { 328 if (no_store) 329 *response_headers = "Cache-Control: no-store\n"; 330 } 331 332 private: 333 static bool no_store; 334 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer); 335 }; 336 bool FastTransactionServer::no_store; 337 338 const MockTransaction kFastNoStoreGET_Transaction = { 339 "http://www.google.com/nostore", 340 "GET", 341 base::Time(), 342 "", 343 net::LOAD_VALIDATE_CACHE, 344 "HTTP/1.1 200 OK", 345 "Cache-Control: max-age=10000\n", 346 base::Time(), 347 "<html><body>Google Blah Blah</body></html>", 348 TEST_MODE_SYNC_NET_START, 349 &FastTransactionServer::FastNoStoreHandler, 350 0, 351 net::OK 352 }; 353 354 // This class provides a handler for kRangeGET_TransactionOK so that the range 355 // request can be served on demand. 356 class RangeTransactionServer { 357 public: 358 RangeTransactionServer() { 359 not_modified_ = false; 360 modified_ = false; 361 bad_200_ = false; 362 } 363 ~RangeTransactionServer() { 364 not_modified_ = false; 365 modified_ = false; 366 bad_200_ = false; 367 } 368 369 // Returns only 416 or 304 when set. 370 void set_not_modified(bool value) { not_modified_ = value; } 371 372 // Returns 206 when revalidating a range (instead of 304). 373 void set_modified(bool value) { modified_ = value; } 374 375 // Returns 200 instead of 206 (a malformed response overall). 376 void set_bad_200(bool value) { bad_200_ = value; } 377 378 static void RangeHandler(const net::HttpRequestInfo* request, 379 std::string* response_status, 380 std::string* response_headers, 381 std::string* response_data); 382 383 private: 384 static bool not_modified_; 385 static bool modified_; 386 static bool bad_200_; 387 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); 388 }; 389 bool RangeTransactionServer::not_modified_ = false; 390 bool RangeTransactionServer::modified_ = false; 391 bool RangeTransactionServer::bad_200_ = false; 392 393 // A dummy extra header that must be preserved on a given request. 394 395 // EXTRA_HEADER_LINE doesn't include a line terminator because it 396 // will be passed to AddHeaderFromString() which doesn't accept them. 397 #define EXTRA_HEADER_LINE "Extra: header" 398 399 // EXTRA_HEADER contains a line terminator, as expected by 400 // AddHeadersFromString() (_not_ AddHeaderFromString()). 401 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" 402 403 static const char kExtraHeaderKey[] = "Extra"; 404 405 // Static. 406 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, 407 std::string* response_status, 408 std::string* response_headers, 409 std::string* response_data) { 410 if (request->extra_headers.IsEmpty()) { 411 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); 412 response_data->clear(); 413 return; 414 } 415 416 // We want to make sure we don't delete extra headers. 417 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); 418 419 if (not_modified_) { 420 response_status->assign("HTTP/1.1 304 Not Modified"); 421 response_data->clear(); 422 return; 423 } 424 425 std::vector<net::HttpByteRange> ranges; 426 std::string range_header; 427 if (!request->extra_headers.GetHeader( 428 net::HttpRequestHeaders::kRange, &range_header) || 429 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || 430 ranges.size() != 1) { 431 // This is not a byte range request. We return 200. 432 response_status->assign("HTTP/1.1 200 OK"); 433 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); 434 response_data->assign("Not a range"); 435 return; 436 } 437 438 // We can handle this range request. 439 net::HttpByteRange byte_range = ranges[0]; 440 if (byte_range.first_byte_position() > 79) { 441 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); 442 response_data->clear(); 443 return; 444 } 445 446 EXPECT_TRUE(byte_range.ComputeBounds(80)); 447 int start = static_cast<int>(byte_range.first_byte_position()); 448 int end = static_cast<int>(byte_range.last_byte_position()); 449 450 EXPECT_LT(end, 80); 451 452 std::string content_range = base::StringPrintf( 453 "Content-Range: bytes %d-%d/80\n", start, end); 454 response_headers->append(content_range); 455 456 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) { 457 std::string data; 458 if (end == start) { 459 EXPECT_EQ(0, end % 10); 460 data = "r"; 461 } else { 462 EXPECT_EQ(9, (end - start) % 10); 463 for (int block_start = start; block_start < end; block_start += 10) { 464 base::StringAppendF(&data, "rg: %02d-%02d ", 465 block_start, block_start + 9); 466 } 467 } 468 *response_data = data; 469 470 if (end - start != 9) { 471 // We also have to fix content-length. 472 int len = end - start + 1; 473 std::string content_length = base::StringPrintf("Content-Length: %d\n", 474 len); 475 response_headers->replace(response_headers->find("Content-Length:"), 476 content_length.size(), content_length); 477 } 478 } else { 479 response_status->assign("HTTP/1.1 304 Not Modified"); 480 response_data->clear(); 481 } 482 } 483 484 const MockTransaction kRangeGET_TransactionOK = { 485 "http://www.google.com/range", 486 "GET", 487 base::Time(), 488 "Range: bytes = 40-49\r\n" 489 EXTRA_HEADER, 490 net::LOAD_NORMAL, 491 "HTTP/1.1 206 Partial Content", 492 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 493 "ETag: \"foo\"\n" 494 "Accept-Ranges: bytes\n" 495 "Content-Length: 10\n", 496 base::Time(), 497 "rg: 40-49 ", 498 TEST_MODE_NORMAL, 499 &RangeTransactionServer::RangeHandler, 500 0, 501 net::OK 502 }; 503 504 // Verifies the response headers (|response|) match a partial content 505 // response for the range starting at |start| and ending at |end|. 506 void Verify206Response(std::string response, int start, int end) { 507 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), 508 response.size())); 509 scoped_refptr<net::HttpResponseHeaders> headers( 510 new net::HttpResponseHeaders(raw_headers)); 511 512 ASSERT_EQ(206, headers->response_code()); 513 514 int64 range_start, range_end, object_size; 515 ASSERT_TRUE( 516 headers->GetContentRange(&range_start, &range_end, &object_size)); 517 int64 content_length = headers->GetContentLength(); 518 519 int length = end - start + 1; 520 ASSERT_EQ(length, content_length); 521 ASSERT_EQ(start, range_start); 522 ASSERT_EQ(end, range_end); 523 } 524 525 // Creates a truncated entry that can be resumed using byte ranges. 526 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) { 527 // Create a disk cache entry that stores an incomplete resource. 528 disk_cache::Entry* entry; 529 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, 530 NULL)); 531 532 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 533 raw_headers.size()); 534 535 net::HttpResponseInfo response; 536 response.response_time = base::Time::Now(); 537 response.request_time = base::Time::Now(); 538 response.headers = new net::HttpResponseHeaders(raw_headers); 539 // Set the last argument for this to be an incomplete request. 540 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); 541 542 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); 543 int len = static_cast<int>(base::strlcpy(buf->data(), 544 "rg: 00-09 rg: 10-19 ", 100)); 545 net::TestCompletionCallback cb; 546 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true); 547 EXPECT_EQ(len, cb.GetResult(rv)); 548 entry->Close(); 549 } 550 551 // Helper to represent a network HTTP response. 552 struct Response { 553 // Set this response into |trans|. 554 void AssignTo(MockTransaction* trans) const { 555 trans->status = status; 556 trans->response_headers = headers; 557 trans->data = body; 558 } 559 560 std::string status_and_headers() const { 561 return std::string(status) + "\n" + std::string(headers); 562 } 563 564 const char* status; 565 const char* headers; 566 const char* body; 567 }; 568 569 struct Context { 570 Context() : result(net::ERR_IO_PENDING) {} 571 572 int result; 573 net::TestCompletionCallback callback; 574 scoped_ptr<net::HttpTransaction> trans; 575 }; 576 577 } // namespace 578 579 580 //----------------------------------------------------------------------------- 581 // Tests. 582 583 TEST(HttpCache, CreateThenDestroy) { 584 MockHttpCache cache; 585 586 scoped_ptr<net::HttpTransaction> trans; 587 int rv = cache.http_cache()->CreateTransaction( 588 net::DEFAULT_PRIORITY, &trans, NULL); 589 EXPECT_EQ(net::OK, rv); 590 ASSERT_TRUE(trans.get()); 591 } 592 593 TEST(HttpCache, GetBackend) { 594 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0)); 595 596 disk_cache::Backend* backend; 597 net::TestCompletionCallback cb; 598 // This will lazily initialize the backend. 599 int rv = cache.http_cache()->GetBackend(&backend, cb.callback()); 600 EXPECT_EQ(net::OK, cb.GetResult(rv)); 601 } 602 603 TEST(HttpCache, SimpleGET) { 604 MockHttpCache cache; 605 net::CapturingBoundNetLog log; 606 net::LoadTimingInfo load_timing_info; 607 608 // Write to the cache. 609 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction, 610 log.bound(), &load_timing_info); 611 612 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 613 EXPECT_EQ(0, cache.disk_cache()->open_count()); 614 EXPECT_EQ(1, cache.disk_cache()->create_count()); 615 TestLoadTimingNetworkRequest(load_timing_info); 616 } 617 618 TEST(HttpCache, SimpleGETNoDiskCache) { 619 MockHttpCache cache; 620 621 cache.disk_cache()->set_fail_requests(); 622 623 net::CapturingBoundNetLog log; 624 log.SetLogLevel(net::NetLog::LOG_BASIC); 625 net::LoadTimingInfo load_timing_info; 626 627 // Read from the network, and don't use the cache. 628 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction, 629 log.bound(), &load_timing_info); 630 631 // Check that the NetLog was filled as expected. 632 // (We attempted to both Open and Create entries, but both failed). 633 net::CapturingNetLog::CapturedEntryList entries; 634 log.GetEntries(&entries); 635 636 EXPECT_EQ(6u, entries.size()); 637 EXPECT_TRUE(net::LogContainsBeginEvent( 638 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 639 EXPECT_TRUE(net::LogContainsEndEvent( 640 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 641 EXPECT_TRUE(net::LogContainsBeginEvent( 642 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 643 EXPECT_TRUE(net::LogContainsEndEvent( 644 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 645 EXPECT_TRUE(net::LogContainsBeginEvent( 646 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 647 EXPECT_TRUE(net::LogContainsEndEvent( 648 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 649 650 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 651 EXPECT_EQ(0, cache.disk_cache()->open_count()); 652 EXPECT_EQ(0, cache.disk_cache()->create_count()); 653 TestLoadTimingNetworkRequest(load_timing_info); 654 } 655 656 TEST(HttpCache, SimpleGETNoDiskCache2) { 657 // This will initialize a cache object with NULL backend. 658 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 659 factory->set_fail(true); 660 factory->FinishCreation(); // We'll complete synchronously. 661 MockHttpCache cache(factory); 662 663 // Read from the network, and don't use the cache. 664 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 665 666 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 667 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend()); 668 } 669 670 // Tests that IOBuffers are not referenced after IO completes. 671 TEST(HttpCache, ReleaseBuffer) { 672 MockHttpCache cache; 673 674 // Write to the cache. 675 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 676 677 MockHttpRequest request(kSimpleGET_Transaction); 678 scoped_ptr<net::HttpTransaction> trans; 679 int rv = cache.http_cache()->CreateTransaction( 680 net::DEFAULT_PRIORITY, &trans, NULL); 681 ASSERT_EQ(net::OK, rv); 682 683 const int kBufferSize = 10; 684 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); 685 net::ReleaseBufferCompletionCallback cb(buffer.get()); 686 687 rv = trans->Start(&request, cb.callback(), net::BoundNetLog()); 688 EXPECT_EQ(net::OK, cb.GetResult(rv)); 689 690 rv = trans->Read(buffer.get(), kBufferSize, cb.callback()); 691 EXPECT_EQ(kBufferSize, cb.GetResult(rv)); 692 } 693 694 TEST(HttpCache, SimpleGETWithDiskFailures) { 695 MockHttpCache cache; 696 697 cache.disk_cache()->set_soft_failures(true); 698 699 // Read from the network, and fail to write to the cache. 700 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 701 702 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 703 EXPECT_EQ(0, cache.disk_cache()->open_count()); 704 EXPECT_EQ(1, cache.disk_cache()->create_count()); 705 706 // This one should see an empty cache again. 707 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 708 709 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 710 EXPECT_EQ(0, cache.disk_cache()->open_count()); 711 EXPECT_EQ(2, cache.disk_cache()->create_count()); 712 } 713 714 // Tests that disk failures after the transaction has started don't cause the 715 // request to fail. 716 TEST(HttpCache, SimpleGETWithDiskFailures2) { 717 MockHttpCache cache; 718 719 MockHttpRequest request(kSimpleGET_Transaction); 720 721 scoped_ptr<Context> c(new Context()); 722 int rv = cache.http_cache()->CreateTransaction( 723 net::DEFAULT_PRIORITY, &c->trans, NULL); 724 EXPECT_EQ(net::OK, rv); 725 726 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 727 EXPECT_EQ(net::ERR_IO_PENDING, rv); 728 rv = c->callback.WaitForResult(); 729 730 // Start failing request now. 731 cache.disk_cache()->set_soft_failures(true); 732 733 // We have to open the entry again to propagate the failure flag. 734 disk_cache::Entry* en; 735 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en)); 736 en->Close(); 737 738 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 739 c.reset(); 740 741 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 742 EXPECT_EQ(1, cache.disk_cache()->open_count()); 743 EXPECT_EQ(1, cache.disk_cache()->create_count()); 744 745 // This one should see an empty cache again. 746 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 747 748 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 749 EXPECT_EQ(1, cache.disk_cache()->open_count()); 750 EXPECT_EQ(2, cache.disk_cache()->create_count()); 751 } 752 753 // Tests that we handle failures to read from the cache. 754 TEST(HttpCache, SimpleGETWithDiskFailures3) { 755 MockHttpCache cache; 756 757 // Read from the network, and write to the cache. 758 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 759 760 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 761 EXPECT_EQ(0, cache.disk_cache()->open_count()); 762 EXPECT_EQ(1, cache.disk_cache()->create_count()); 763 764 cache.disk_cache()->set_soft_failures(true); 765 766 // Now fail to read from the cache. 767 scoped_ptr<Context> c(new Context()); 768 int rv = cache.http_cache()->CreateTransaction( 769 net::DEFAULT_PRIORITY, &c->trans, NULL); 770 EXPECT_EQ(net::OK, rv); 771 772 MockHttpRequest request(kSimpleGET_Transaction); 773 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 774 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 775 776 // Now verify that the entry was removed from the cache. 777 cache.disk_cache()->set_soft_failures(false); 778 779 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 780 EXPECT_EQ(1, cache.disk_cache()->open_count()); 781 EXPECT_EQ(2, cache.disk_cache()->create_count()); 782 783 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 784 785 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 786 EXPECT_EQ(1, cache.disk_cache()->open_count()); 787 EXPECT_EQ(3, cache.disk_cache()->create_count()); 788 } 789 790 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) { 791 MockHttpCache cache; 792 793 net::CapturingBoundNetLog log; 794 795 // This prevents a number of write events from being logged. 796 log.SetLogLevel(net::NetLog::LOG_BASIC); 797 798 net::LoadTimingInfo load_timing_info; 799 800 // Write to the cache. 801 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction, 802 log.bound(), &load_timing_info); 803 804 // Check that the NetLog was filled as expected. 805 net::CapturingNetLog::CapturedEntryList entries; 806 log.GetEntries(&entries); 807 808 EXPECT_EQ(8u, entries.size()); 809 EXPECT_TRUE(net::LogContainsBeginEvent( 810 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 811 EXPECT_TRUE(net::LogContainsEndEvent( 812 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 813 EXPECT_TRUE(net::LogContainsBeginEvent( 814 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 815 EXPECT_TRUE(net::LogContainsEndEvent( 816 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 817 EXPECT_TRUE(net::LogContainsBeginEvent( 818 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 819 EXPECT_TRUE(net::LogContainsEndEvent( 820 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 821 EXPECT_TRUE(net::LogContainsBeginEvent( 822 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 823 EXPECT_TRUE(net::LogContainsEndEvent( 824 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 825 826 TestLoadTimingNetworkRequest(load_timing_info); 827 828 // Force this transaction to read from the cache. 829 MockTransaction transaction(kSimpleGET_Transaction); 830 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 831 832 log.Clear(); 833 834 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 835 &load_timing_info); 836 837 // Check that the NetLog was filled as expected. 838 log.GetEntries(&entries); 839 840 EXPECT_EQ(8u, entries.size()); 841 EXPECT_TRUE(net::LogContainsBeginEvent( 842 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 843 EXPECT_TRUE(net::LogContainsEndEvent( 844 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 845 EXPECT_TRUE(net::LogContainsBeginEvent( 846 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 847 EXPECT_TRUE(net::LogContainsEndEvent( 848 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 849 EXPECT_TRUE(net::LogContainsBeginEvent( 850 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 851 EXPECT_TRUE(net::LogContainsEndEvent( 852 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 853 EXPECT_TRUE(net::LogContainsBeginEvent( 854 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO)); 855 EXPECT_TRUE(net::LogContainsEndEvent( 856 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO)); 857 858 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 859 EXPECT_EQ(1, cache.disk_cache()->open_count()); 860 EXPECT_EQ(1, cache.disk_cache()->create_count()); 861 TestLoadTimingCachedResponse(load_timing_info); 862 } 863 864 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) { 865 MockHttpCache cache; 866 867 // force this transaction to read from the cache 868 MockTransaction transaction(kSimpleGET_Transaction); 869 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 870 871 MockHttpRequest request(transaction); 872 net::TestCompletionCallback callback; 873 874 scoped_ptr<net::HttpTransaction> trans; 875 int rv = cache.http_cache()->CreateTransaction( 876 net::DEFAULT_PRIORITY, &trans, NULL); 877 EXPECT_EQ(net::OK, rv); 878 ASSERT_TRUE(trans.get()); 879 880 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 881 if (rv == net::ERR_IO_PENDING) 882 rv = callback.WaitForResult(); 883 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 884 885 trans.reset(); 886 887 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 888 EXPECT_EQ(0, cache.disk_cache()->open_count()); 889 EXPECT_EQ(0, cache.disk_cache()->create_count()); 890 } 891 892 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) { 893 MockHttpCache cache; 894 895 // write to the cache 896 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 897 898 // force this transaction to read from the cache if valid 899 MockTransaction transaction(kSimpleGET_Transaction); 900 transaction.load_flags |= net::LOAD_PREFERRING_CACHE; 901 902 RunTransactionTest(cache.http_cache(), transaction); 903 904 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 905 EXPECT_EQ(1, cache.disk_cache()->open_count()); 906 EXPECT_EQ(1, cache.disk_cache()->create_count()); 907 } 908 909 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) { 910 MockHttpCache cache; 911 912 // force this transaction to read from the cache if valid 913 MockTransaction transaction(kSimpleGET_Transaction); 914 transaction.load_flags |= net::LOAD_PREFERRING_CACHE; 915 916 RunTransactionTest(cache.http_cache(), transaction); 917 918 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 919 EXPECT_EQ(0, cache.disk_cache()->open_count()); 920 EXPECT_EQ(1, cache.disk_cache()->create_count()); 921 } 922 923 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers. 924 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) { 925 MockHttpCache cache; 926 927 // Write to the cache. 928 MockTransaction transaction(kSimpleGET_Transaction); 929 transaction.request_headers = "Foo: bar\r\n"; 930 transaction.response_headers = "Cache-Control: max-age=10000\n" 931 "Vary: Foo\n"; 932 AddMockTransaction(&transaction); 933 RunTransactionTest(cache.http_cache(), transaction); 934 935 // Read from the cache. 936 transaction.load_flags |= net::LOAD_PREFERRING_CACHE; 937 RunTransactionTest(cache.http_cache(), transaction); 938 939 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 940 EXPECT_EQ(1, cache.disk_cache()->open_count()); 941 EXPECT_EQ(1, cache.disk_cache()->create_count()); 942 RemoveMockTransaction(&transaction); 943 } 944 945 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers. 946 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) { 947 MockHttpCache cache; 948 949 // Write to the cache. 950 MockTransaction transaction(kSimpleGET_Transaction); 951 transaction.request_headers = "Foo: bar\r\n"; 952 transaction.response_headers = "Cache-Control: max-age=10000\n" 953 "Vary: Foo\n"; 954 AddMockTransaction(&transaction); 955 RunTransactionTest(cache.http_cache(), transaction); 956 957 // Attempt to read from the cache... this is a vary mismatch that must reach 958 // the network again. 959 transaction.load_flags |= net::LOAD_PREFERRING_CACHE; 960 transaction.request_headers = "Foo: none\r\n"; 961 net::CapturingBoundNetLog log; 962 net::LoadTimingInfo load_timing_info; 963 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 964 &load_timing_info); 965 966 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 967 EXPECT_EQ(1, cache.disk_cache()->open_count()); 968 EXPECT_EQ(1, cache.disk_cache()->create_count()); 969 TestLoadTimingNetworkRequest(load_timing_info); 970 RemoveMockTransaction(&transaction); 971 } 972 973 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on 974 // network success 975 TEST(HttpCache, SimpleGET_CacheOverride_Network) { 976 MockHttpCache cache; 977 978 // Prime cache. 979 MockTransaction transaction(kSimpleGET_Transaction); 980 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE; 981 transaction.response_headers = "Cache-Control: no-cache\n"; 982 983 AddMockTransaction(&transaction); 984 RunTransactionTest(cache.http_cache(), transaction); 985 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 986 EXPECT_EQ(1, cache.disk_cache()->create_count()); 987 RemoveMockTransaction(&transaction); 988 989 // Re-run transaction; make sure the result came from the network, 990 // not the cache. 991 transaction.data = "Changed data."; 992 AddMockTransaction(&transaction); 993 net::HttpResponseInfo response_info; 994 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction, 995 &response_info); 996 997 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 998 EXPECT_FALSE(response_info.server_data_unavailable); 999 EXPECT_TRUE(response_info.network_accessed); 1000 1001 RemoveMockTransaction(&transaction); 1002 } 1003 1004 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on 1005 // offline failure 1006 TEST(HttpCache, SimpleGET_CacheOverride_Offline) { 1007 MockHttpCache cache; 1008 1009 // Prime cache. 1010 MockTransaction transaction(kSimpleGET_Transaction); 1011 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE; 1012 transaction.response_headers = "Cache-Control: no-cache\n"; 1013 1014 AddMockTransaction(&transaction); 1015 RunTransactionTest(cache.http_cache(), transaction); 1016 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1017 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1018 RemoveMockTransaction(&transaction); 1019 1020 // Network failure with offline error; should return cache entry above + 1021 // flag signalling stale data. 1022 transaction.return_code = net::ERR_NAME_NOT_RESOLVED; 1023 AddMockTransaction(&transaction); 1024 1025 MockHttpRequest request(transaction); 1026 net::TestCompletionCallback callback; 1027 scoped_ptr<net::HttpTransaction> trans; 1028 int rv = cache.http_cache()->CreateTransaction( 1029 net::DEFAULT_PRIORITY, &trans, NULL); 1030 EXPECT_EQ(net::OK, rv); 1031 ASSERT_TRUE(trans.get()); 1032 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 1033 EXPECT_EQ(net::OK, callback.GetResult(rv)); 1034 1035 const net::HttpResponseInfo* response_info = trans->GetResponseInfo(); 1036 ASSERT_TRUE(response_info); 1037 EXPECT_TRUE(response_info->server_data_unavailable); 1038 EXPECT_TRUE(response_info->was_cached); 1039 EXPECT_FALSE(response_info->network_accessed); 1040 ReadAndVerifyTransaction(trans.get(), transaction); 1041 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1042 1043 RemoveMockTransaction(&transaction); 1044 } 1045 1046 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on 1047 // non-offline failure. 1048 TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) { 1049 MockHttpCache cache; 1050 1051 // Prime cache. 1052 MockTransaction transaction(kSimpleGET_Transaction); 1053 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE; 1054 transaction.response_headers = "Cache-Control: no-cache\n"; 1055 1056 AddMockTransaction(&transaction); 1057 RunTransactionTest(cache.http_cache(), transaction); 1058 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1059 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1060 RemoveMockTransaction(&transaction); 1061 1062 // Network failure with non-offline error; should fail with that error. 1063 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED; 1064 AddMockTransaction(&transaction); 1065 1066 net::HttpResponseInfo response_info2; 1067 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction, 1068 &response_info2); 1069 1070 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1071 EXPECT_FALSE(response_info2.server_data_unavailable); 1072 1073 RemoveMockTransaction(&transaction); 1074 } 1075 1076 // Confirm if we have an empty cache, a read is marked as network verified. 1077 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) { 1078 MockHttpCache cache; 1079 1080 // write to the cache 1081 net::HttpResponseInfo response_info; 1082 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 1083 &response_info); 1084 1085 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1086 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1087 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1088 EXPECT_TRUE(response_info.network_accessed); 1089 } 1090 1091 // Confirm if we have a fresh entry in cache, it isn't marked as 1092 // network verified. 1093 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) { 1094 MockHttpCache cache; 1095 1096 // Prime cache. 1097 MockTransaction transaction(kSimpleGET_Transaction); 1098 1099 RunTransactionTest(cache.http_cache(), transaction); 1100 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1101 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1102 1103 // Re-run transaction; make sure we don't mark the network as accessed. 1104 net::HttpResponseInfo response_info; 1105 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction, 1106 &response_info); 1107 1108 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1109 EXPECT_FALSE(response_info.server_data_unavailable); 1110 EXPECT_FALSE(response_info.network_accessed); 1111 } 1112 1113 TEST(HttpCache, SimpleGET_LoadBypassCache) { 1114 MockHttpCache cache; 1115 1116 // Write to the cache. 1117 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1118 1119 // Force this transaction to write to the cache again. 1120 MockTransaction transaction(kSimpleGET_Transaction); 1121 transaction.load_flags |= net::LOAD_BYPASS_CACHE; 1122 1123 net::CapturingBoundNetLog log; 1124 1125 // This prevents a number of write events from being logged. 1126 log.SetLogLevel(net::NetLog::LOG_BASIC); 1127 net::LoadTimingInfo load_timing_info; 1128 1129 // Write to the cache. 1130 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 1131 &load_timing_info); 1132 1133 // Check that the NetLog was filled as expected. 1134 net::CapturingNetLog::CapturedEntryList entries; 1135 log.GetEntries(&entries); 1136 1137 EXPECT_EQ(8u, entries.size()); 1138 EXPECT_TRUE(net::LogContainsBeginEvent( 1139 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1140 EXPECT_TRUE(net::LogContainsEndEvent( 1141 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1142 EXPECT_TRUE(net::LogContainsBeginEvent( 1143 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY)); 1144 EXPECT_TRUE(net::LogContainsEndEvent( 1145 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY)); 1146 EXPECT_TRUE(net::LogContainsBeginEvent( 1147 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1148 EXPECT_TRUE(net::LogContainsEndEvent( 1149 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1150 EXPECT_TRUE(net::LogContainsBeginEvent( 1151 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1152 EXPECT_TRUE(net::LogContainsEndEvent( 1153 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1154 1155 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1156 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1157 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1158 TestLoadTimingNetworkRequest(load_timing_info); 1159 } 1160 1161 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) { 1162 MockHttpCache cache; 1163 1164 // write to the cache 1165 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1166 1167 // force this transaction to write to the cache again 1168 MockTransaction transaction(kSimpleGET_Transaction); 1169 transaction.request_headers = "pragma: no-cache\r\n"; 1170 1171 RunTransactionTest(cache.http_cache(), transaction); 1172 1173 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1174 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1175 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1176 } 1177 1178 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) { 1179 MockHttpCache cache; 1180 1181 // write to the cache 1182 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1183 1184 // force this transaction to write to the cache again 1185 MockTransaction transaction(kSimpleGET_Transaction); 1186 transaction.request_headers = "cache-control: no-cache\r\n"; 1187 1188 RunTransactionTest(cache.http_cache(), transaction); 1189 1190 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1191 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1192 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1193 } 1194 1195 TEST(HttpCache, SimpleGET_LoadValidateCache) { 1196 MockHttpCache cache; 1197 1198 // Write to the cache. 1199 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1200 1201 // Read from the cache. 1202 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1203 1204 // Force this transaction to validate the cache. 1205 MockTransaction transaction(kSimpleGET_Transaction); 1206 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 1207 1208 net::HttpResponseInfo response_info; 1209 net::CapturingBoundNetLog log; 1210 net::LoadTimingInfo load_timing_info; 1211 RunTransactionTestWithResponseInfoAndGetTiming( 1212 cache.http_cache(), transaction, &response_info, log.bound(), 1213 &load_timing_info); 1214 1215 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1216 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1217 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1218 EXPECT_TRUE(response_info.network_accessed); 1219 TestLoadTimingNetworkRequest(load_timing_info); 1220 } 1221 1222 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) { 1223 MockHttpCache cache; 1224 1225 // write to the cache 1226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1227 1228 // read from the cache 1229 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1230 1231 // force this transaction to validate the cache 1232 MockTransaction transaction(kSimpleGET_Transaction); 1233 transaction.request_headers = "cache-control: max-age=0\r\n"; 1234 1235 RunTransactionTest(cache.http_cache(), transaction); 1236 1237 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1238 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1239 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1240 } 1241 1242 static void PreserveRequestHeaders_Handler( 1243 const net::HttpRequestInfo* request, 1244 std::string* response_status, 1245 std::string* response_headers, 1246 std::string* response_data) { 1247 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); 1248 } 1249 1250 // Tests that we don't remove extra headers for simple requests. 1251 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) { 1252 MockHttpCache cache; 1253 1254 MockTransaction transaction(kSimpleGET_Transaction); 1255 transaction.handler = PreserveRequestHeaders_Handler; 1256 transaction.request_headers = EXTRA_HEADER; 1257 transaction.response_headers = "Cache-Control: max-age=0\n"; 1258 AddMockTransaction(&transaction); 1259 1260 // Write, then revalidate the entry. 1261 RunTransactionTest(cache.http_cache(), transaction); 1262 RunTransactionTest(cache.http_cache(), transaction); 1263 1264 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1265 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1266 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1267 RemoveMockTransaction(&transaction); 1268 } 1269 1270 // Tests that we don't remove extra headers for conditionalized requests. 1271 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) { 1272 MockHttpCache cache; 1273 1274 // Write to the cache. 1275 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 1276 1277 MockTransaction transaction(kETagGET_Transaction); 1278 transaction.handler = PreserveRequestHeaders_Handler; 1279 transaction.request_headers = "If-None-Match: \"foopy\"\r\n" 1280 EXTRA_HEADER; 1281 AddMockTransaction(&transaction); 1282 1283 RunTransactionTest(cache.http_cache(), transaction); 1284 1285 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1286 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1287 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1288 RemoveMockTransaction(&transaction); 1289 } 1290 1291 TEST(HttpCache, SimpleGET_ManyReaders) { 1292 MockHttpCache cache; 1293 1294 MockHttpRequest request(kSimpleGET_Transaction); 1295 1296 std::vector<Context*> context_list; 1297 const int kNumTransactions = 5; 1298 1299 for (int i = 0; i < kNumTransactions; ++i) { 1300 context_list.push_back(new Context()); 1301 Context* c = context_list[i]; 1302 1303 c->result = cache.http_cache()->CreateTransaction( 1304 net::DEFAULT_PRIORITY, &c->trans, NULL); 1305 EXPECT_EQ(net::OK, c->result); 1306 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState()); 1307 1308 c->result = c->trans->Start( 1309 &request, c->callback.callback(), net::BoundNetLog()); 1310 } 1311 1312 // All requests are waiting for the active entry. 1313 for (int i = 0; i < kNumTransactions; ++i) { 1314 Context* c = context_list[i]; 1315 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); 1316 } 1317 1318 // Allow all requests to move from the Create queue to the active entry. 1319 base::MessageLoop::current()->RunUntilIdle(); 1320 1321 // The first request should be a writer at this point, and the subsequent 1322 // requests should be pending. 1323 1324 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1325 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1326 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1327 1328 // All requests depend on the writer, and the writer is between Start and 1329 // Read, i.e. idle. 1330 for (int i = 0; i < kNumTransactions; ++i) { 1331 Context* c = context_list[i]; 1332 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState()); 1333 } 1334 1335 for (int i = 0; i < kNumTransactions; ++i) { 1336 Context* c = context_list[i]; 1337 if (c->result == net::ERR_IO_PENDING) 1338 c->result = c->callback.WaitForResult(); 1339 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1340 } 1341 1342 // We should not have had to re-open the disk entry 1343 1344 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1345 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1346 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1347 1348 for (int i = 0; i < kNumTransactions; ++i) { 1349 Context* c = context_list[i]; 1350 delete c; 1351 } 1352 } 1353 1354 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. 1355 // If cancelling a request is racing with another request for the same resource 1356 // finishing, we have to make sure that we remove both transactions from the 1357 // entry. 1358 TEST(HttpCache, SimpleGET_RacingReaders) { 1359 MockHttpCache cache; 1360 1361 MockHttpRequest request(kSimpleGET_Transaction); 1362 MockHttpRequest reader_request(kSimpleGET_Transaction); 1363 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE; 1364 1365 std::vector<Context*> context_list; 1366 const int kNumTransactions = 5; 1367 1368 for (int i = 0; i < kNumTransactions; ++i) { 1369 context_list.push_back(new Context()); 1370 Context* c = context_list[i]; 1371 1372 c->result = cache.http_cache()->CreateTransaction( 1373 net::DEFAULT_PRIORITY, &c->trans, NULL); 1374 EXPECT_EQ(net::OK, c->result); 1375 1376 MockHttpRequest* this_request = &request; 1377 if (i == 1 || i == 2) 1378 this_request = &reader_request; 1379 1380 c->result = c->trans->Start( 1381 this_request, c->callback.callback(), net::BoundNetLog()); 1382 } 1383 1384 // Allow all requests to move from the Create queue to the active entry. 1385 base::MessageLoop::current()->RunUntilIdle(); 1386 1387 // The first request should be a writer at this point, and the subsequent 1388 // requests should be pending. 1389 1390 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1391 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1392 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1393 1394 Context* c = context_list[0]; 1395 ASSERT_EQ(net::ERR_IO_PENDING, c->result); 1396 c->result = c->callback.WaitForResult(); 1397 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1398 1399 // Now we have 2 active readers and two queued transactions. 1400 1401 EXPECT_EQ(net::LOAD_STATE_IDLE, 1402 context_list[2]->trans->GetLoadState()); 1403 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, 1404 context_list[3]->trans->GetLoadState()); 1405 1406 c = context_list[1]; 1407 ASSERT_EQ(net::ERR_IO_PENDING, c->result); 1408 c->result = c->callback.WaitForResult(); 1409 if (c->result == net::OK) 1410 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1411 1412 // At this point we have one reader, two pending transactions and a task on 1413 // the queue to move to the next transaction. Now we cancel the request that 1414 // is the current reader, and expect the queued task to be able to start the 1415 // next request. 1416 1417 c = context_list[2]; 1418 c->trans.reset(); 1419 1420 for (int i = 3; i < kNumTransactions; ++i) { 1421 Context* c = context_list[i]; 1422 if (c->result == net::ERR_IO_PENDING) 1423 c->result = c->callback.WaitForResult(); 1424 if (c->result == net::OK) 1425 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1426 } 1427 1428 // We should not have had to re-open the disk entry. 1429 1430 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1431 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1432 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1433 1434 for (int i = 0; i < kNumTransactions; ++i) { 1435 Context* c = context_list[i]; 1436 delete c; 1437 } 1438 } 1439 1440 // Tests that we can doom an entry with pending transactions and delete one of 1441 // the pending transactions before the first one completes. 1442 // See http://code.google.com/p/chromium/issues/detail?id=25588 1443 TEST(HttpCache, SimpleGET_DoomWithPending) { 1444 // We need simultaneous doomed / not_doomed entries so let's use a real cache. 1445 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024)); 1446 1447 MockHttpRequest request(kSimpleGET_Transaction); 1448 MockHttpRequest writer_request(kSimpleGET_Transaction); 1449 writer_request.load_flags = net::LOAD_BYPASS_CACHE; 1450 1451 ScopedVector<Context> context_list; 1452 const int kNumTransactions = 4; 1453 1454 for (int i = 0; i < kNumTransactions; ++i) { 1455 context_list.push_back(new Context()); 1456 Context* c = context_list[i]; 1457 1458 c->result = cache.http_cache()->CreateTransaction( 1459 net::DEFAULT_PRIORITY, &c->trans, NULL); 1460 EXPECT_EQ(net::OK, c->result); 1461 1462 MockHttpRequest* this_request = &request; 1463 if (i == 3) 1464 this_request = &writer_request; 1465 1466 c->result = c->trans->Start( 1467 this_request, c->callback.callback(), net::BoundNetLog()); 1468 } 1469 1470 // The first request should be a writer at this point, and the two subsequent 1471 // requests should be pending. The last request doomed the first entry. 1472 1473 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1474 1475 // Cancel the first queued transaction. 1476 delete context_list[1]; 1477 context_list.get()[1] = NULL; 1478 1479 for (int i = 0; i < kNumTransactions; ++i) { 1480 if (i == 1) 1481 continue; 1482 Context* c = context_list[i]; 1483 ASSERT_EQ(net::ERR_IO_PENDING, c->result); 1484 c->result = c->callback.WaitForResult(); 1485 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1486 } 1487 } 1488 1489 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731. 1490 // We may attempt to delete an entry synchronously with the act of adding a new 1491 // transaction to said entry. 1492 TEST(HttpCache, FastNoStoreGET_DoneWithPending) { 1493 MockHttpCache cache; 1494 1495 // The headers will be served right from the call to Start() the request. 1496 MockHttpRequest request(kFastNoStoreGET_Transaction); 1497 FastTransactionServer request_handler; 1498 AddMockTransaction(&kFastNoStoreGET_Transaction); 1499 1500 std::vector<Context*> context_list; 1501 const int kNumTransactions = 3; 1502 1503 for (int i = 0; i < kNumTransactions; ++i) { 1504 context_list.push_back(new Context()); 1505 Context* c = context_list[i]; 1506 1507 c->result = cache.http_cache()->CreateTransaction( 1508 net::DEFAULT_PRIORITY, &c->trans, NULL); 1509 EXPECT_EQ(net::OK, c->result); 1510 1511 c->result = c->trans->Start( 1512 &request, c->callback.callback(), net::BoundNetLog()); 1513 } 1514 1515 // Allow all requests to move from the Create queue to the active entry. 1516 base::MessageLoop::current()->RunUntilIdle(); 1517 1518 // The first request should be a writer at this point, and the subsequent 1519 // requests should be pending. 1520 1521 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1522 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1523 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1524 1525 // Now, make sure that the second request asks for the entry not to be stored. 1526 request_handler.set_no_store(true); 1527 1528 for (int i = 0; i < kNumTransactions; ++i) { 1529 Context* c = context_list[i]; 1530 if (c->result == net::ERR_IO_PENDING) 1531 c->result = c->callback.WaitForResult(); 1532 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); 1533 delete c; 1534 } 1535 1536 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 1537 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1538 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1539 1540 RemoveMockTransaction(&kFastNoStoreGET_Transaction); 1541 } 1542 1543 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) { 1544 MockHttpCache cache; 1545 1546 MockHttpRequest request(kSimpleGET_Transaction); 1547 1548 std::vector<Context*> context_list; 1549 const int kNumTransactions = 2; 1550 1551 for (int i = 0; i < kNumTransactions; ++i) { 1552 context_list.push_back(new Context()); 1553 Context* c = context_list[i]; 1554 1555 c->result = cache.http_cache()->CreateTransaction( 1556 net::DEFAULT_PRIORITY, &c->trans, NULL); 1557 EXPECT_EQ(net::OK, c->result); 1558 1559 c->result = c->trans->Start( 1560 &request, c->callback.callback(), net::BoundNetLog()); 1561 } 1562 1563 // Allow all requests to move from the Create queue to the active entry. 1564 base::MessageLoop::current()->RunUntilIdle(); 1565 1566 // The first request should be a writer at this point, and the subsequent 1567 // requests should be pending. 1568 1569 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1570 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1571 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1572 1573 for (int i = 0; i < kNumTransactions; ++i) { 1574 Context* c = context_list[i]; 1575 if (c->result == net::ERR_IO_PENDING) 1576 c->result = c->callback.WaitForResult(); 1577 // Destroy only the first transaction. 1578 if (i == 0) { 1579 delete c; 1580 context_list[i] = NULL; 1581 } 1582 } 1583 1584 // Complete the rest of the transactions. 1585 for (int i = 1; i < kNumTransactions; ++i) { 1586 Context* c = context_list[i]; 1587 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1588 } 1589 1590 // We should have had to re-open the disk entry. 1591 1592 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1593 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1594 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1595 1596 for (int i = 1; i < kNumTransactions; ++i) { 1597 Context* c = context_list[i]; 1598 delete c; 1599 } 1600 } 1601 1602 // Tests that we can cancel requests that are queued waiting to open the disk 1603 // cache entry. 1604 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) { 1605 MockHttpCache cache; 1606 1607 MockHttpRequest request(kSimpleGET_Transaction); 1608 1609 std::vector<Context*> context_list; 1610 const int kNumTransactions = 5; 1611 1612 for (int i = 0; i < kNumTransactions; i++) { 1613 context_list.push_back(new Context()); 1614 Context* c = context_list[i]; 1615 1616 c->result = cache.http_cache()->CreateTransaction( 1617 net::DEFAULT_PRIORITY, &c->trans, NULL); 1618 EXPECT_EQ(net::OK, c->result); 1619 1620 c->result = c->trans->Start( 1621 &request, c->callback.callback(), net::BoundNetLog()); 1622 } 1623 1624 // The first request should be creating the disk cache entry and the others 1625 // should be pending. 1626 1627 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 1628 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1629 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1630 1631 // Cancel a request from the pending queue. 1632 delete context_list[3]; 1633 context_list[3] = NULL; 1634 1635 // Cancel the request that is creating the entry. This will force the pending 1636 // operations to restart. 1637 delete context_list[0]; 1638 context_list[0] = NULL; 1639 1640 // Complete the rest of the transactions. 1641 for (int i = 1; i < kNumTransactions; i++) { 1642 Context* c = context_list[i]; 1643 if (c) { 1644 c->result = c->callback.GetResult(c->result); 1645 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1646 } 1647 } 1648 1649 // We should have had to re-create the disk entry. 1650 1651 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1652 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1653 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1654 1655 for (int i = 1; i < kNumTransactions; ++i) { 1656 delete context_list[i]; 1657 } 1658 } 1659 1660 // Tests that we can cancel a single request to open a disk cache entry. 1661 TEST(HttpCache, SimpleGET_CancelCreate) { 1662 MockHttpCache cache; 1663 1664 MockHttpRequest request(kSimpleGET_Transaction); 1665 1666 Context* c = new Context(); 1667 1668 c->result = cache.http_cache()->CreateTransaction( 1669 net::DEFAULT_PRIORITY, &c->trans, NULL); 1670 EXPECT_EQ(net::OK, c->result); 1671 1672 c->result = c->trans->Start( 1673 &request, c->callback.callback(), net::BoundNetLog()); 1674 EXPECT_EQ(net::ERR_IO_PENDING, c->result); 1675 1676 // Release the reference that the mock disk cache keeps for this entry, so 1677 // that we test that the http cache handles the cancellation correctly. 1678 cache.disk_cache()->ReleaseAll(); 1679 delete c; 1680 1681 base::MessageLoop::current()->RunUntilIdle(); 1682 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1683 } 1684 1685 // Tests that we delete/create entries even if multiple requests are queued. 1686 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) { 1687 MockHttpCache cache; 1688 1689 MockHttpRequest request(kSimpleGET_Transaction); 1690 request.load_flags = net::LOAD_BYPASS_CACHE; 1691 1692 std::vector<Context*> context_list; 1693 const int kNumTransactions = 5; 1694 1695 for (int i = 0; i < kNumTransactions; i++) { 1696 context_list.push_back(new Context()); 1697 Context* c = context_list[i]; 1698 1699 c->result = cache.http_cache()->CreateTransaction( 1700 net::DEFAULT_PRIORITY, &c->trans, NULL); 1701 EXPECT_EQ(net::OK, c->result); 1702 1703 c->result = c->trans->Start( 1704 &request, c->callback.callback(), net::BoundNetLog()); 1705 } 1706 1707 // The first request should be deleting the disk cache entry and the others 1708 // should be pending. 1709 1710 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 1711 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1712 EXPECT_EQ(0, cache.disk_cache()->create_count()); 1713 1714 // Complete the transactions. 1715 for (int i = 0; i < kNumTransactions; i++) { 1716 Context* c = context_list[i]; 1717 c->result = c->callback.GetResult(c->result); 1718 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1719 } 1720 1721 // We should have had to re-create the disk entry multiple times. 1722 1723 EXPECT_EQ(5, cache.network_layer()->transaction_count()); 1724 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1725 EXPECT_EQ(5, cache.disk_cache()->create_count()); 1726 1727 for (int i = 0; i < kNumTransactions; ++i) { 1728 delete context_list[i]; 1729 } 1730 } 1731 1732 TEST(HttpCache, SimpleGET_AbandonedCacheRead) { 1733 MockHttpCache cache; 1734 1735 // write to the cache 1736 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1737 1738 MockHttpRequest request(kSimpleGET_Transaction); 1739 net::TestCompletionCallback callback; 1740 1741 scoped_ptr<net::HttpTransaction> trans; 1742 int rv = cache.http_cache()->CreateTransaction( 1743 net::DEFAULT_PRIORITY, &trans, NULL); 1744 EXPECT_EQ(net::OK, rv); 1745 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 1746 if (rv == net::ERR_IO_PENDING) 1747 rv = callback.WaitForResult(); 1748 ASSERT_EQ(net::OK, rv); 1749 1750 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 1751 rv = trans->Read(buf.get(), 256, callback.callback()); 1752 EXPECT_EQ(net::ERR_IO_PENDING, rv); 1753 1754 // Test that destroying the transaction while it is reading from the cache 1755 // works properly. 1756 trans.reset(); 1757 1758 // Make sure we pump any pending events, which should include a call to 1759 // HttpCache::Transaction::OnCacheReadCompleted. 1760 base::MessageLoop::current()->RunUntilIdle(); 1761 } 1762 1763 // Tests that we can delete the HttpCache and deal with queued transactions 1764 // ("waiting for the backend" as opposed to Active or Doomed entries). 1765 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) { 1766 scoped_ptr<MockHttpCache> cache(new MockHttpCache( 1767 new MockBackendNoCbFactory())); 1768 1769 MockHttpRequest request(kSimpleGET_Transaction); 1770 1771 std::vector<Context*> context_list; 1772 const int kNumTransactions = 5; 1773 1774 for (int i = 0; i < kNumTransactions; i++) { 1775 context_list.push_back(new Context()); 1776 Context* c = context_list[i]; 1777 1778 c->result = cache->http_cache()->CreateTransaction( 1779 net::DEFAULT_PRIORITY, &c->trans, NULL); 1780 EXPECT_EQ(net::OK, c->result); 1781 1782 c->result = c->trans->Start( 1783 &request, c->callback.callback(), net::BoundNetLog()); 1784 } 1785 1786 // The first request should be creating the disk cache entry and the others 1787 // should be pending. 1788 1789 EXPECT_EQ(0, cache->network_layer()->transaction_count()); 1790 EXPECT_EQ(0, cache->disk_cache()->open_count()); 1791 EXPECT_EQ(0, cache->disk_cache()->create_count()); 1792 1793 cache.reset(); 1794 1795 // There is not much to do with the transactions at this point... they are 1796 // waiting for a callback that will not fire. 1797 for (int i = 0; i < kNumTransactions; ++i) { 1798 delete context_list[i]; 1799 } 1800 } 1801 1802 // Tests that we queue requests when initializing the backend. 1803 TEST(HttpCache, SimpleGET_WaitForBackend) { 1804 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 1805 MockHttpCache cache(factory); 1806 1807 MockHttpRequest request0(kSimpleGET_Transaction); 1808 MockHttpRequest request1(kTypicalGET_Transaction); 1809 MockHttpRequest request2(kETagGET_Transaction); 1810 1811 std::vector<Context*> context_list; 1812 const int kNumTransactions = 3; 1813 1814 for (int i = 0; i < kNumTransactions; i++) { 1815 context_list.push_back(new Context()); 1816 Context* c = context_list[i]; 1817 1818 c->result = cache.http_cache()->CreateTransaction( 1819 net::DEFAULT_PRIORITY, &c->trans, NULL); 1820 EXPECT_EQ(net::OK, c->result); 1821 } 1822 1823 context_list[0]->result = context_list[0]->trans->Start( 1824 &request0, context_list[0]->callback.callback(), net::BoundNetLog()); 1825 context_list[1]->result = context_list[1]->trans->Start( 1826 &request1, context_list[1]->callback.callback(), net::BoundNetLog()); 1827 context_list[2]->result = context_list[2]->trans->Start( 1828 &request2, context_list[2]->callback.callback(), net::BoundNetLog()); 1829 1830 // Just to make sure that everything is still pending. 1831 base::MessageLoop::current()->RunUntilIdle(); 1832 1833 // The first request should be creating the disk cache. 1834 EXPECT_FALSE(context_list[0]->callback.have_result()); 1835 1836 factory->FinishCreation(); 1837 1838 base::MessageLoop::current()->RunUntilIdle(); 1839 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 1840 EXPECT_EQ(3, cache.disk_cache()->create_count()); 1841 1842 for (int i = 0; i < kNumTransactions; ++i) { 1843 EXPECT_TRUE(context_list[i]->callback.have_result()); 1844 delete context_list[i]; 1845 } 1846 } 1847 1848 // Tests that we can cancel requests that are queued waiting for the backend 1849 // to be initialized. 1850 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) { 1851 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 1852 MockHttpCache cache(factory); 1853 1854 MockHttpRequest request0(kSimpleGET_Transaction); 1855 MockHttpRequest request1(kTypicalGET_Transaction); 1856 MockHttpRequest request2(kETagGET_Transaction); 1857 1858 std::vector<Context*> context_list; 1859 const int kNumTransactions = 3; 1860 1861 for (int i = 0; i < kNumTransactions; i++) { 1862 context_list.push_back(new Context()); 1863 Context* c = context_list[i]; 1864 1865 c->result = cache.http_cache()->CreateTransaction( 1866 net::DEFAULT_PRIORITY, &c->trans, NULL); 1867 EXPECT_EQ(net::OK, c->result); 1868 } 1869 1870 context_list[0]->result = context_list[0]->trans->Start( 1871 &request0, context_list[0]->callback.callback(), net::BoundNetLog()); 1872 context_list[1]->result = context_list[1]->trans->Start( 1873 &request1, context_list[1]->callback.callback(), net::BoundNetLog()); 1874 context_list[2]->result = context_list[2]->trans->Start( 1875 &request2, context_list[2]->callback.callback(), net::BoundNetLog()); 1876 1877 // Just to make sure that everything is still pending. 1878 base::MessageLoop::current()->RunUntilIdle(); 1879 1880 // The first request should be creating the disk cache. 1881 EXPECT_FALSE(context_list[0]->callback.have_result()); 1882 1883 // Cancel a request from the pending queue. 1884 delete context_list[1]; 1885 context_list[1] = NULL; 1886 1887 // Cancel the request that is creating the entry. 1888 delete context_list[0]; 1889 context_list[0] = NULL; 1890 1891 // Complete the last transaction. 1892 factory->FinishCreation(); 1893 1894 context_list[2]->result = 1895 context_list[2]->callback.GetResult(context_list[2]->result); 1896 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction); 1897 1898 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1899 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1900 1901 delete context_list[2]; 1902 } 1903 1904 // Tests that we can delete the cache while creating the backend. 1905 TEST(HttpCache, DeleteCacheWaitingForBackend) { 1906 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 1907 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory)); 1908 1909 MockHttpRequest request(kSimpleGET_Transaction); 1910 1911 scoped_ptr<Context> c(new Context()); 1912 c->result = cache->http_cache()->CreateTransaction( 1913 net::DEFAULT_PRIORITY, &c->trans, NULL); 1914 EXPECT_EQ(net::OK, c->result); 1915 1916 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 1917 1918 // Just to make sure that everything is still pending. 1919 base::MessageLoop::current()->RunUntilIdle(); 1920 1921 // The request should be creating the disk cache. 1922 EXPECT_FALSE(c->callback.have_result()); 1923 1924 // We cannot call FinishCreation because the factory itself will go away with 1925 // the cache, so grab the callback and attempt to use it. 1926 net::CompletionCallback callback = factory->callback(); 1927 scoped_ptr<disk_cache::Backend>* backend = factory->backend(); 1928 1929 cache.reset(); 1930 base::MessageLoop::current()->RunUntilIdle(); 1931 1932 backend->reset(); 1933 callback.Run(net::ERR_ABORTED); 1934 } 1935 1936 // Tests that we can delete the cache while creating the backend, from within 1937 // one of the callbacks. 1938 TEST(HttpCache, DeleteCacheWaitingForBackend2) { 1939 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 1940 MockHttpCache* cache = new MockHttpCache(factory); 1941 1942 DeleteCacheCompletionCallback cb(cache); 1943 disk_cache::Backend* backend; 1944 int rv = cache->http_cache()->GetBackend(&backend, cb.callback()); 1945 EXPECT_EQ(net::ERR_IO_PENDING, rv); 1946 1947 // Now let's queue a regular transaction 1948 MockHttpRequest request(kSimpleGET_Transaction); 1949 1950 scoped_ptr<Context> c(new Context()); 1951 c->result = cache->http_cache()->CreateTransaction( 1952 net::DEFAULT_PRIORITY, &c->trans, NULL); 1953 EXPECT_EQ(net::OK, c->result); 1954 1955 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 1956 1957 // And another direct backend request. 1958 net::TestCompletionCallback cb2; 1959 rv = cache->http_cache()->GetBackend(&backend, cb2.callback()); 1960 EXPECT_EQ(net::ERR_IO_PENDING, rv); 1961 1962 // Just to make sure that everything is still pending. 1963 base::MessageLoop::current()->RunUntilIdle(); 1964 1965 // The request should be queued. 1966 EXPECT_FALSE(c->callback.have_result()); 1967 1968 // Generate the callback. 1969 factory->FinishCreation(); 1970 rv = cb.WaitForResult(); 1971 1972 // The cache should be gone by now. 1973 base::MessageLoop::current()->RunUntilIdle(); 1974 EXPECT_EQ(net::OK, c->callback.GetResult(c->result)); 1975 EXPECT_FALSE(cb2.have_result()); 1976 } 1977 1978 TEST(HttpCache, TypicalGET_ConditionalRequest) { 1979 MockHttpCache cache; 1980 1981 // write to the cache 1982 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction); 1983 1984 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1985 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1986 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1987 1988 // Get the same URL again, but this time we expect it to result 1989 // in a conditional request. 1990 net::CapturingBoundNetLog log; 1991 net::LoadTimingInfo load_timing_info; 1992 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction, 1993 log.bound(), &load_timing_info); 1994 1995 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1996 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1997 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1998 TestLoadTimingNetworkRequest(load_timing_info); 1999 } 2000 2001 static void ETagGet_ConditionalRequest_Handler( 2002 const net::HttpRequestInfo* request, 2003 std::string* response_status, 2004 std::string* response_headers, 2005 std::string* response_data) { 2006 EXPECT_TRUE( 2007 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch)); 2008 response_status->assign("HTTP/1.1 304 Not Modified"); 2009 response_headers->assign(kETagGET_Transaction.response_headers); 2010 response_data->clear(); 2011 } 2012 2013 TEST(HttpCache, ETagGET_ConditionalRequest_304) { 2014 MockHttpCache cache; 2015 2016 ScopedMockTransaction transaction(kETagGET_Transaction); 2017 2018 // write to the cache 2019 RunTransactionTest(cache.http_cache(), transaction); 2020 2021 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2022 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2023 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2024 2025 // Get the same URL again, but this time we expect it to result 2026 // in a conditional request. 2027 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 2028 transaction.handler = ETagGet_ConditionalRequest_Handler; 2029 net::CapturingBoundNetLog log; 2030 net::LoadTimingInfo load_timing_info; 2031 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 2032 &load_timing_info); 2033 2034 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2035 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2036 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2037 TestLoadTimingNetworkRequest(load_timing_info); 2038 } 2039 2040 class RevalidationServer { 2041 public: 2042 RevalidationServer() { 2043 s_etag_used_ = false; 2044 s_last_modified_used_ = false; 2045 } 2046 2047 bool EtagUsed() { return s_etag_used_; } 2048 bool LastModifiedUsed() { return s_last_modified_used_; } 2049 2050 static void Handler(const net::HttpRequestInfo* request, 2051 std::string* response_status, 2052 std::string* response_headers, 2053 std::string* response_data); 2054 2055 private: 2056 static bool s_etag_used_; 2057 static bool s_last_modified_used_; 2058 }; 2059 bool RevalidationServer::s_etag_used_ = false; 2060 bool RevalidationServer::s_last_modified_used_ = false; 2061 2062 void RevalidationServer::Handler(const net::HttpRequestInfo* request, 2063 std::string* response_status, 2064 std::string* response_headers, 2065 std::string* response_data) { 2066 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch)) 2067 s_etag_used_ = true; 2068 2069 if (request->extra_headers.HasHeader( 2070 net::HttpRequestHeaders::kIfModifiedSince)) { 2071 s_last_modified_used_ = true; 2072 } 2073 2074 if (s_etag_used_ || s_last_modified_used_) { 2075 response_status->assign("HTTP/1.1 304 Not Modified"); 2076 response_headers->assign(kTypicalGET_Transaction.response_headers); 2077 response_data->clear(); 2078 } else { 2079 response_status->assign(kTypicalGET_Transaction.status); 2080 response_headers->assign(kTypicalGET_Transaction.response_headers); 2081 response_data->assign(kTypicalGET_Transaction.data); 2082 } 2083 } 2084 2085 // Tests revalidation after a vary match. 2086 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) { 2087 MockHttpCache cache; 2088 2089 // Write to the cache. 2090 MockTransaction transaction(kTypicalGET_Transaction); 2091 transaction.request_headers = "Foo: bar\r\n"; 2092 transaction.response_headers = 2093 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" 2094 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 2095 "Etag: \"foopy\"\n" 2096 "Cache-Control: max-age=0\n" 2097 "Vary: Foo\n"; 2098 AddMockTransaction(&transaction); 2099 RunTransactionTest(cache.http_cache(), transaction); 2100 2101 // Read from the cache. 2102 RevalidationServer server; 2103 transaction.handler = server.Handler; 2104 net::CapturingBoundNetLog log; 2105 net::LoadTimingInfo load_timing_info; 2106 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 2107 &load_timing_info); 2108 2109 EXPECT_TRUE(server.EtagUsed()); 2110 EXPECT_TRUE(server.LastModifiedUsed()); 2111 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2112 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2113 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2114 TestLoadTimingNetworkRequest(load_timing_info); 2115 RemoveMockTransaction(&transaction); 2116 } 2117 2118 // Tests revalidation after a vary mismatch if etag is present. 2119 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) { 2120 MockHttpCache cache; 2121 2122 // Write to the cache. 2123 MockTransaction transaction(kTypicalGET_Transaction); 2124 transaction.request_headers = "Foo: bar\r\n"; 2125 transaction.response_headers = 2126 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" 2127 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 2128 "Etag: \"foopy\"\n" 2129 "Cache-Control: max-age=0\n" 2130 "Vary: Foo\n"; 2131 AddMockTransaction(&transaction); 2132 RunTransactionTest(cache.http_cache(), transaction); 2133 2134 // Read from the cache and revalidate the entry. 2135 RevalidationServer server; 2136 transaction.handler = server.Handler; 2137 transaction.request_headers = "Foo: none\r\n"; 2138 net::CapturingBoundNetLog log; 2139 net::LoadTimingInfo load_timing_info; 2140 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 2141 &load_timing_info); 2142 2143 EXPECT_TRUE(server.EtagUsed()); 2144 EXPECT_FALSE(server.LastModifiedUsed()); 2145 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2146 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2147 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2148 TestLoadTimingNetworkRequest(load_timing_info); 2149 RemoveMockTransaction(&transaction); 2150 } 2151 2152 // Tests lack of revalidation after a vary mismatch and no etag. 2153 TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) { 2154 MockHttpCache cache; 2155 2156 // Write to the cache. 2157 MockTransaction transaction(kTypicalGET_Transaction); 2158 transaction.request_headers = "Foo: bar\r\n"; 2159 transaction.response_headers = 2160 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" 2161 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 2162 "Cache-Control: max-age=0\n" 2163 "Vary: Foo\n"; 2164 AddMockTransaction(&transaction); 2165 RunTransactionTest(cache.http_cache(), transaction); 2166 2167 // Read from the cache and don't revalidate the entry. 2168 RevalidationServer server; 2169 transaction.handler = server.Handler; 2170 transaction.request_headers = "Foo: none\r\n"; 2171 net::CapturingBoundNetLog log; 2172 net::LoadTimingInfo load_timing_info; 2173 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 2174 &load_timing_info); 2175 2176 EXPECT_FALSE(server.EtagUsed()); 2177 EXPECT_FALSE(server.LastModifiedUsed()); 2178 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2179 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2180 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2181 TestLoadTimingNetworkRequest(load_timing_info); 2182 RemoveMockTransaction(&transaction); 2183 } 2184 2185 static void ETagGet_UnconditionalRequest_Handler( 2186 const net::HttpRequestInfo* request, 2187 std::string* response_status, 2188 std::string* response_headers, 2189 std::string* response_data) { 2190 EXPECT_FALSE( 2191 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch)); 2192 } 2193 2194 TEST(HttpCache, ETagGET_Http10) { 2195 MockHttpCache cache; 2196 2197 ScopedMockTransaction transaction(kETagGET_Transaction); 2198 transaction.status = "HTTP/1.0 200 OK"; 2199 2200 // Write to the cache. 2201 RunTransactionTest(cache.http_cache(), transaction); 2202 2203 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2204 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2205 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2206 2207 // Get the same URL again, without generating a conditional request. 2208 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 2209 transaction.handler = ETagGet_UnconditionalRequest_Handler; 2210 RunTransactionTest(cache.http_cache(), transaction); 2211 2212 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2213 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2214 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2215 } 2216 2217 TEST(HttpCache, ETagGET_Http10_Range) { 2218 MockHttpCache cache; 2219 2220 ScopedMockTransaction transaction(kETagGET_Transaction); 2221 transaction.status = "HTTP/1.0 200 OK"; 2222 2223 // Write to the cache. 2224 RunTransactionTest(cache.http_cache(), transaction); 2225 2226 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2227 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2228 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2229 2230 // Get the same URL again, but use a byte range request. 2231 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 2232 transaction.handler = ETagGet_UnconditionalRequest_Handler; 2233 transaction.request_headers = "Range: bytes = 5-\r\n"; 2234 RunTransactionTest(cache.http_cache(), transaction); 2235 2236 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2237 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2238 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2239 } 2240 2241 static void ETagGet_ConditionalRequest_NoStore_Handler( 2242 const net::HttpRequestInfo* request, 2243 std::string* response_status, 2244 std::string* response_headers, 2245 std::string* response_data) { 2246 EXPECT_TRUE( 2247 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch)); 2248 response_status->assign("HTTP/1.1 304 Not Modified"); 2249 response_headers->assign("Cache-Control: no-store\n"); 2250 response_data->clear(); 2251 } 2252 2253 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) { 2254 MockHttpCache cache; 2255 2256 ScopedMockTransaction transaction(kETagGET_Transaction); 2257 2258 // Write to the cache. 2259 RunTransactionTest(cache.http_cache(), transaction); 2260 2261 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2262 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2263 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2264 2265 // Get the same URL again, but this time we expect it to result 2266 // in a conditional request. 2267 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 2268 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler; 2269 RunTransactionTest(cache.http_cache(), transaction); 2270 2271 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2272 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2273 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2274 2275 ScopedMockTransaction transaction2(kETagGET_Transaction); 2276 2277 // Write to the cache again. This should create a new entry. 2278 RunTransactionTest(cache.http_cache(), transaction2); 2279 2280 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2281 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2282 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2283 } 2284 2285 // Helper that does 4 requests using HttpCache: 2286 // 2287 // (1) loads |kUrl| -- expects |net_response_1| to be returned. 2288 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. 2289 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to 2290 // be returned. 2291 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be 2292 // returned. 2293 static void ConditionalizedRequestUpdatesCacheHelper( 2294 const Response& net_response_1, 2295 const Response& net_response_2, 2296 const Response& cached_response_2, 2297 const char* extra_request_headers) { 2298 MockHttpCache cache; 2299 2300 // The URL we will be requesting. 2301 const char* kUrl = "http://foobar.com/main.css"; 2302 2303 // Junk network response. 2304 static const Response kUnexpectedResponse = { 2305 "HTTP/1.1 500 Unexpected", 2306 "Server: unexpected_header", 2307 "unexpected body" 2308 }; 2309 2310 // We will control the network layer's responses for |kUrl| using 2311 // |mock_network_response|. 2312 MockTransaction mock_network_response = { 0 }; 2313 mock_network_response.url = kUrl; 2314 AddMockTransaction(&mock_network_response); 2315 2316 // Request |kUrl| for the first time. It should hit the network and 2317 // receive |kNetResponse1|, which it saves into the HTTP cache. 2318 2319 MockTransaction request = { 0 }; 2320 request.url = kUrl; 2321 request.method = "GET"; 2322 request.request_headers = ""; 2323 2324 net_response_1.AssignTo(&mock_network_response); // Network mock. 2325 net_response_1.AssignTo(&request); // Expected result. 2326 2327 std::string response_headers; 2328 RunTransactionTestWithResponse( 2329 cache.http_cache(), request, &response_headers); 2330 2331 EXPECT_EQ(net_response_1.status_and_headers(), response_headers); 2332 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2333 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2334 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2335 2336 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP 2337 // cache, so we don't hit the network. 2338 2339 request.load_flags = net::LOAD_ONLY_FROM_CACHE; 2340 2341 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock. 2342 net_response_1.AssignTo(&request); // Expected result. 2343 2344 RunTransactionTestWithResponse( 2345 cache.http_cache(), request, &response_headers); 2346 2347 EXPECT_EQ(net_response_1.status_and_headers(), response_headers); 2348 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2349 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2350 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2351 2352 // Request |kUrl| yet again, but this time give the request an 2353 // "If-Modified-Since" header. This will cause the request to re-hit the 2354 // network. However now the network response is going to be 2355 // different -- this simulates a change made to the CSS file. 2356 2357 request.request_headers = extra_request_headers; 2358 request.load_flags = net::LOAD_NORMAL; 2359 2360 net_response_2.AssignTo(&mock_network_response); // Network mock. 2361 net_response_2.AssignTo(&request); // Expected result. 2362 2363 RunTransactionTestWithResponse( 2364 cache.http_cache(), request, &response_headers); 2365 2366 EXPECT_EQ(net_response_2.status_and_headers(), response_headers); 2367 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2368 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2369 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2370 2371 // Finally, request |kUrl| again. This request should be serviced from 2372 // the cache. Moreover, the value in the cache should be |kNetResponse2| 2373 // and NOT |kNetResponse1|. The previous step should have replaced the 2374 // value in the cache with the modified response. 2375 2376 request.request_headers = ""; 2377 request.load_flags = net::LOAD_ONLY_FROM_CACHE; 2378 2379 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock. 2380 cached_response_2.AssignTo(&request); // Expected result. 2381 2382 RunTransactionTestWithResponse( 2383 cache.http_cache(), request, &response_headers); 2384 2385 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers); 2386 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2387 EXPECT_EQ(2, cache.disk_cache()->open_count()); 2388 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2389 2390 RemoveMockTransaction(&mock_network_response); 2391 } 2392 2393 // Check that when an "if-modified-since" header is attached 2394 // to the request, the result still updates the cached entry. 2395 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) { 2396 // First network response for |kUrl|. 2397 static const Response kNetResponse1 = { 2398 "HTTP/1.1 200 OK", 2399 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2400 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2401 "body1" 2402 }; 2403 2404 // Second network response for |kUrl|. 2405 static const Response kNetResponse2 = { 2406 "HTTP/1.1 200 OK", 2407 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2408 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2409 "body2" 2410 }; 2411 2412 const char* extra_headers = 2413 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"; 2414 2415 ConditionalizedRequestUpdatesCacheHelper( 2416 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers); 2417 } 2418 2419 // Check that when an "if-none-match" header is attached 2420 // to the request, the result updates the cached entry. 2421 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) { 2422 // First network response for |kUrl|. 2423 static const Response kNetResponse1 = { 2424 "HTTP/1.1 200 OK", 2425 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2426 "Etag: \"ETAG1\"\n" 2427 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire. 2428 "body1" 2429 }; 2430 2431 // Second network response for |kUrl|. 2432 static const Response kNetResponse2 = { 2433 "HTTP/1.1 200 OK", 2434 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2435 "Etag: \"ETAG2\"\n" 2436 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire. 2437 "body2" 2438 }; 2439 2440 const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n"; 2441 2442 ConditionalizedRequestUpdatesCacheHelper( 2443 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers); 2444 } 2445 2446 // Check that when an "if-modified-since" header is attached 2447 // to a request, the 304 (not modified result) result updates the cached 2448 // headers, and the 304 response is returned rather than the cached response. 2449 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) { 2450 // First network response for |kUrl|. 2451 static const Response kNetResponse1 = { 2452 "HTTP/1.1 200 OK", 2453 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2454 "Server: server1\n" 2455 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2456 "body1" 2457 }; 2458 2459 // Second network response for |kUrl|. 2460 static const Response kNetResponse2 = { 2461 "HTTP/1.1 304 Not Modified", 2462 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2463 "Server: server2\n" 2464 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2465 "" 2466 }; 2467 2468 static const Response kCachedResponse2 = { 2469 "HTTP/1.1 200 OK", 2470 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2471 "Server: server2\n" 2472 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2473 "body1" 2474 }; 2475 2476 const char* extra_headers = 2477 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"; 2478 2479 ConditionalizedRequestUpdatesCacheHelper( 2480 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers); 2481 } 2482 2483 // Test that when doing an externally conditionalized if-modified-since 2484 // and there is no corresponding cache entry, a new cache entry is NOT 2485 // created (304 response). 2486 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) { 2487 MockHttpCache cache; 2488 2489 const char* kUrl = "http://foobar.com/main.css"; 2490 2491 static const Response kNetResponse = { 2492 "HTTP/1.1 304 Not Modified", 2493 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2494 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2495 "" 2496 }; 2497 2498 const char* kExtraRequestHeaders = 2499 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"; 2500 2501 // We will control the network layer's responses for |kUrl| using 2502 // |mock_network_response|. 2503 MockTransaction mock_network_response = { 0 }; 2504 mock_network_response.url = kUrl; 2505 AddMockTransaction(&mock_network_response); 2506 2507 MockTransaction request = { 0 }; 2508 request.url = kUrl; 2509 request.method = "GET"; 2510 request.request_headers = kExtraRequestHeaders; 2511 2512 kNetResponse.AssignTo(&mock_network_response); // Network mock. 2513 kNetResponse.AssignTo(&request); // Expected result. 2514 2515 std::string response_headers; 2516 RunTransactionTestWithResponse( 2517 cache.http_cache(), request, &response_headers); 2518 2519 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers); 2520 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2521 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2522 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2523 2524 RemoveMockTransaction(&mock_network_response); 2525 } 2526 2527 // Test that when doing an externally conditionalized if-modified-since 2528 // and there is no corresponding cache entry, a new cache entry is NOT 2529 // created (200 response). 2530 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) { 2531 MockHttpCache cache; 2532 2533 const char* kUrl = "http://foobar.com/main.css"; 2534 2535 static const Response kNetResponse = { 2536 "HTTP/1.1 200 OK", 2537 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2538 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2539 "foobar!!!" 2540 }; 2541 2542 const char* kExtraRequestHeaders = 2543 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"; 2544 2545 // We will control the network layer's responses for |kUrl| using 2546 // |mock_network_response|. 2547 MockTransaction mock_network_response = { 0 }; 2548 mock_network_response.url = kUrl; 2549 AddMockTransaction(&mock_network_response); 2550 2551 MockTransaction request = { 0 }; 2552 request.url = kUrl; 2553 request.method = "GET"; 2554 request.request_headers = kExtraRequestHeaders; 2555 2556 kNetResponse.AssignTo(&mock_network_response); // Network mock. 2557 kNetResponse.AssignTo(&request); // Expected result. 2558 2559 std::string response_headers; 2560 RunTransactionTestWithResponse( 2561 cache.http_cache(), request, &response_headers); 2562 2563 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers); 2564 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2565 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2566 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2567 2568 RemoveMockTransaction(&mock_network_response); 2569 } 2570 2571 // Test that when doing an externally conditionalized if-modified-since 2572 // if the date does not match the cache entry's last-modified date, 2573 // then we do NOT use the response (304) to update the cache. 2574 // (the if-modified-since date is 2 days AFTER the cache's modification date). 2575 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) { 2576 static const Response kNetResponse1 = { 2577 "HTTP/1.1 200 OK", 2578 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2579 "Server: server1\n" 2580 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2581 "body1" 2582 }; 2583 2584 // Second network response for |kUrl|. 2585 static const Response kNetResponse2 = { 2586 "HTTP/1.1 304 Not Modified", 2587 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2588 "Server: server2\n" 2589 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2590 "" 2591 }; 2592 2593 // This is two days in the future from the original response's last-modified 2594 // date! 2595 const char* kExtraRequestHeaders = 2596 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"; 2597 2598 ConditionalizedRequestUpdatesCacheHelper( 2599 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2600 } 2601 2602 // Test that when doing an externally conditionalized if-none-match 2603 // if the etag does not match the cache entry's etag, then we do not use the 2604 // response (304) to update the cache. 2605 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) { 2606 static const Response kNetResponse1 = { 2607 "HTTP/1.1 200 OK", 2608 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2609 "Etag: \"Foo1\"\n" 2610 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2611 "body1" 2612 }; 2613 2614 // Second network response for |kUrl|. 2615 static const Response kNetResponse2 = { 2616 "HTTP/1.1 304 Not Modified", 2617 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2618 "Etag: \"Foo2\"\n" 2619 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2620 "" 2621 }; 2622 2623 // Different etag from original response. 2624 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n"; 2625 2626 ConditionalizedRequestUpdatesCacheHelper( 2627 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2628 } 2629 2630 // Test that doing an externally conditionalized request with both if-none-match 2631 // and if-modified-since updates the cache. 2632 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) { 2633 static const Response kNetResponse1 = { 2634 "HTTP/1.1 200 OK", 2635 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2636 "Etag: \"Foo1\"\n" 2637 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2638 "body1" 2639 }; 2640 2641 // Second network response for |kUrl|. 2642 static const Response kNetResponse2 = { 2643 "HTTP/1.1 200 OK", 2644 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2645 "Etag: \"Foo2\"\n" 2646 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2647 "body2" 2648 }; 2649 2650 const char* kExtraRequestHeaders = 2651 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n" 2652 "If-None-Match: \"Foo1\"\r\n"; 2653 2654 ConditionalizedRequestUpdatesCacheHelper( 2655 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders); 2656 } 2657 2658 // Test that doing an externally conditionalized request with both if-none-match 2659 // and if-modified-since does not update the cache with only one match. 2660 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) { 2661 static const Response kNetResponse1 = { 2662 "HTTP/1.1 200 OK", 2663 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2664 "Etag: \"Foo1\"\n" 2665 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2666 "body1" 2667 }; 2668 2669 // Second network response for |kUrl|. 2670 static const Response kNetResponse2 = { 2671 "HTTP/1.1 200 OK", 2672 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2673 "Etag: \"Foo2\"\n" 2674 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2675 "body2" 2676 }; 2677 2678 // The etag doesn't match what we have stored. 2679 const char* kExtraRequestHeaders = 2680 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n" 2681 "If-None-Match: \"Foo2\"\r\n"; 2682 2683 ConditionalizedRequestUpdatesCacheHelper( 2684 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2685 } 2686 2687 // Test that doing an externally conditionalized request with both if-none-match 2688 // and if-modified-since does not update the cache with only one match. 2689 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) { 2690 static const Response kNetResponse1 = { 2691 "HTTP/1.1 200 OK", 2692 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2693 "Etag: \"Foo1\"\n" 2694 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2695 "body1" 2696 }; 2697 2698 // Second network response for |kUrl|. 2699 static const Response kNetResponse2 = { 2700 "HTTP/1.1 200 OK", 2701 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2702 "Etag: \"Foo2\"\n" 2703 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2704 "body2" 2705 }; 2706 2707 // The modification date doesn't match what we have stored. 2708 const char* kExtraRequestHeaders = 2709 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n" 2710 "If-None-Match: \"Foo1\"\r\n"; 2711 2712 ConditionalizedRequestUpdatesCacheHelper( 2713 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2714 } 2715 2716 TEST(HttpCache, UrlContainingHash) { 2717 MockHttpCache cache; 2718 2719 // Do a typical GET request -- should write an entry into our cache. 2720 MockTransaction trans(kTypicalGET_Transaction); 2721 RunTransactionTest(cache.http_cache(), trans); 2722 2723 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2724 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2725 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2726 2727 // Request the same URL, but this time with a reference section (hash). 2728 // Since the cache key strips the hash sections, this should be a cache hit. 2729 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes"; 2730 trans.url = url_with_hash.c_str(); 2731 trans.load_flags = net::LOAD_ONLY_FROM_CACHE; 2732 2733 RunTransactionTest(cache.http_cache(), trans); 2734 2735 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2736 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2737 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2738 } 2739 2740 // Tests that we skip the cache for POST requests that do not have an upload 2741 // identifier. 2742 TEST(HttpCache, SimplePOST_SkipsCache) { 2743 MockHttpCache cache; 2744 2745 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction); 2746 2747 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2748 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2749 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2750 } 2751 2752 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) { 2753 MockHttpCache cache; 2754 2755 MockTransaction transaction(kSimplePOST_Transaction); 2756 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 2757 2758 MockHttpRequest request(transaction); 2759 net::TestCompletionCallback callback; 2760 2761 scoped_ptr<net::HttpTransaction> trans; 2762 int rv = cache.http_cache()->CreateTransaction( 2763 net::DEFAULT_PRIORITY, &trans, NULL); 2764 EXPECT_EQ(net::OK, rv); 2765 ASSERT_TRUE(trans.get()); 2766 2767 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 2768 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv)); 2769 2770 trans.reset(); 2771 2772 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 2773 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2774 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2775 } 2776 2777 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) { 2778 MockHttpCache cache; 2779 2780 // Test that we hit the cache for POST requests. 2781 2782 MockTransaction transaction(kSimplePOST_Transaction); 2783 2784 const int64 kUploadId = 1; // Just a dummy value. 2785 2786 ScopedVector<net::UploadElementReader> element_readers; 2787 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2788 net::UploadDataStream upload_data_stream(&element_readers, kUploadId); 2789 MockHttpRequest request(transaction); 2790 request.upload_data_stream = &upload_data_stream; 2791 2792 // Populate the cache. 2793 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 2794 2795 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2796 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2797 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2798 2799 // Load from cache. 2800 request.load_flags |= net::LOAD_ONLY_FROM_CACHE; 2801 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 2802 2803 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2804 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2805 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2806 } 2807 2808 // Test that we don't hit the cache for POST requests if there is a byte range. 2809 TEST(HttpCache, SimplePOST_WithRanges) { 2810 MockHttpCache cache; 2811 2812 MockTransaction transaction(kSimplePOST_Transaction); 2813 transaction.request_headers = "Range: bytes = 0-4\r\n"; 2814 2815 const int64 kUploadId = 1; // Just a dummy value. 2816 2817 ScopedVector<net::UploadElementReader> element_readers; 2818 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2819 net::UploadDataStream upload_data_stream(&element_readers, kUploadId); 2820 2821 MockHttpRequest request(transaction); 2822 request.upload_data_stream = &upload_data_stream; 2823 2824 // Attempt to populate the cache. 2825 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 2826 2827 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2828 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2829 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2830 } 2831 2832 // Tests that a POST is cached separately from a previously cached GET. 2833 TEST(HttpCache, SimplePOST_SeparateCache) { 2834 MockHttpCache cache; 2835 2836 ScopedVector<net::UploadElementReader> element_readers; 2837 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2838 net::UploadDataStream upload_data_stream(&element_readers, 1); 2839 2840 MockTransaction transaction(kSimplePOST_Transaction); 2841 MockHttpRequest req1(transaction); 2842 req1.upload_data_stream = &upload_data_stream; 2843 2844 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2845 2846 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2847 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2848 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2849 2850 transaction.method = "GET"; 2851 MockHttpRequest req2(transaction); 2852 2853 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 2854 2855 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2856 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2857 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2858 } 2859 2860 // Tests that a successful POST invalidates a previously cached GET. 2861 TEST(HttpCache, SimplePOST_Invalidate_205) { 2862 MockHttpCache cache; 2863 2864 MockTransaction transaction(kSimpleGET_Transaction); 2865 AddMockTransaction(&transaction); 2866 MockHttpRequest req1(transaction); 2867 2868 // Attempt to populate the cache. 2869 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2870 2871 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2872 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2873 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2874 2875 ScopedVector<net::UploadElementReader> element_readers; 2876 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2877 net::UploadDataStream upload_data_stream(&element_readers, 1); 2878 2879 transaction.method = "POST"; 2880 transaction.status = "HTTP/1.1 205 No Content"; 2881 MockHttpRequest req2(transaction); 2882 req2.upload_data_stream = &upload_data_stream; 2883 2884 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 2885 2886 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2887 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2888 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2889 2890 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2891 2892 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2893 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2894 EXPECT_EQ(3, cache.disk_cache()->create_count()); 2895 RemoveMockTransaction(&transaction); 2896 } 2897 2898 // Tests that we don't invalidate entries as a result of a failed POST. 2899 TEST(HttpCache, SimplePOST_DontInvalidate_100) { 2900 MockHttpCache cache; 2901 2902 MockTransaction transaction(kSimpleGET_Transaction); 2903 AddMockTransaction(&transaction); 2904 MockHttpRequest req1(transaction); 2905 2906 // Attempt to populate the cache. 2907 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2908 2909 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2910 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2911 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2912 2913 ScopedVector<net::UploadElementReader> element_readers; 2914 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2915 net::UploadDataStream upload_data_stream(&element_readers, 1); 2916 2917 transaction.method = "POST"; 2918 transaction.status = "HTTP/1.1 100 Continue"; 2919 MockHttpRequest req2(transaction); 2920 req2.upload_data_stream = &upload_data_stream; 2921 2922 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 2923 2924 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2925 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2926 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2927 2928 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2929 2930 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2931 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2932 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2933 RemoveMockTransaction(&transaction); 2934 } 2935 2936 // Tests that we do not cache the response of a PUT. 2937 TEST(HttpCache, SimplePUT_Miss) { 2938 MockHttpCache cache; 2939 2940 MockTransaction transaction(kSimplePOST_Transaction); 2941 transaction.method = "PUT"; 2942 2943 ScopedVector<net::UploadElementReader> element_readers; 2944 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2945 net::UploadDataStream upload_data_stream(&element_readers, 0); 2946 2947 MockHttpRequest request(transaction); 2948 request.upload_data_stream = &upload_data_stream; 2949 2950 // Attempt to populate the cache. 2951 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 2952 2953 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2954 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2955 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2956 } 2957 2958 // Tests that we invalidate entries as a result of a PUT. 2959 TEST(HttpCache, SimplePUT_Invalidate) { 2960 MockHttpCache cache; 2961 2962 MockTransaction transaction(kSimpleGET_Transaction); 2963 MockHttpRequest req1(transaction); 2964 2965 // Attempt to populate the cache. 2966 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2967 2968 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2969 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2970 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2971 2972 ScopedVector<net::UploadElementReader> element_readers; 2973 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 2974 net::UploadDataStream upload_data_stream(&element_readers, 0); 2975 2976 transaction.method = "PUT"; 2977 MockHttpRequest req2(transaction); 2978 req2.upload_data_stream = &upload_data_stream; 2979 2980 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 2981 2982 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2983 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2984 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2985 2986 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 2987 2988 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2989 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2990 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2991 } 2992 2993 // Tests that we invalidate entries as a result of a PUT. 2994 TEST(HttpCache, SimplePUT_Invalidate_305) { 2995 MockHttpCache cache; 2996 2997 MockTransaction transaction(kSimpleGET_Transaction); 2998 AddMockTransaction(&transaction); 2999 MockHttpRequest req1(transaction); 3000 3001 // Attempt to populate the cache. 3002 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 3003 3004 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3005 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3006 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3007 3008 ScopedVector<net::UploadElementReader> element_readers; 3009 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 3010 net::UploadDataStream upload_data_stream(&element_readers, 0); 3011 3012 transaction.method = "PUT"; 3013 transaction.status = "HTTP/1.1 305 Use Proxy"; 3014 MockHttpRequest req2(transaction); 3015 req2.upload_data_stream = &upload_data_stream; 3016 3017 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 3018 3019 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3020 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3021 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3022 3023 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 3024 3025 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3026 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3027 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3028 RemoveMockTransaction(&transaction); 3029 } 3030 3031 // Tests that we don't invalidate entries as a result of a failed PUT. 3032 TEST(HttpCache, SimplePUT_DontInvalidate_404) { 3033 MockHttpCache cache; 3034 3035 MockTransaction transaction(kSimpleGET_Transaction); 3036 AddMockTransaction(&transaction); 3037 MockHttpRequest req1(transaction); 3038 3039 // Attempt to populate the cache. 3040 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 3041 3042 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3043 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3044 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3045 3046 ScopedVector<net::UploadElementReader> element_readers; 3047 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 3048 net::UploadDataStream upload_data_stream(&element_readers, 0); 3049 3050 transaction.method = "PUT"; 3051 transaction.status = "HTTP/1.1 404 Not Found"; 3052 MockHttpRequest req2(transaction); 3053 req2.upload_data_stream = &upload_data_stream; 3054 3055 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 3056 3057 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3058 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3059 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3060 3061 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 3062 3063 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3064 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3065 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3066 RemoveMockTransaction(&transaction); 3067 } 3068 3069 // Tests that we do not cache the response of a DELETE. 3070 TEST(HttpCache, SimpleDELETE_Miss) { 3071 MockHttpCache cache; 3072 3073 MockTransaction transaction(kSimplePOST_Transaction); 3074 transaction.method = "DELETE"; 3075 3076 ScopedVector<net::UploadElementReader> element_readers; 3077 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 3078 net::UploadDataStream upload_data_stream(&element_readers, 0); 3079 3080 MockHttpRequest request(transaction); 3081 request.upload_data_stream = &upload_data_stream; 3082 3083 // Attempt to populate the cache. 3084 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 3085 3086 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3087 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3088 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3089 } 3090 3091 // Tests that we invalidate entries as a result of a DELETE. 3092 TEST(HttpCache, SimpleDELETE_Invalidate) { 3093 MockHttpCache cache; 3094 3095 MockTransaction transaction(kSimpleGET_Transaction); 3096 MockHttpRequest req1(transaction); 3097 3098 // Attempt to populate the cache. 3099 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 3100 3101 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3102 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3103 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3104 3105 ScopedVector<net::UploadElementReader> element_readers; 3106 element_readers.push_back(new net::UploadBytesElementReader("hello", 5)); 3107 net::UploadDataStream upload_data_stream(&element_readers, 0); 3108 3109 transaction.method = "DELETE"; 3110 MockHttpRequest req2(transaction); 3111 req2.upload_data_stream = &upload_data_stream; 3112 3113 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL); 3114 3115 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3116 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3117 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3118 3119 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL); 3120 3121 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3122 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3123 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3124 } 3125 3126 // Tests that we invalidate entries as a result of a DELETE. 3127 TEST(HttpCache, SimpleDELETE_Invalidate_301) { 3128 MockHttpCache cache; 3129 3130 MockTransaction transaction(kSimpleGET_Transaction); 3131 AddMockTransaction(&transaction); 3132 3133 // Attempt to populate the cache. 3134 RunTransactionTest(cache.http_cache(), transaction); 3135 3136 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3137 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3138 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3139 3140 transaction.method = "DELETE"; 3141 transaction.status = "HTTP/1.1 301 Moved Permanently "; 3142 3143 RunTransactionTest(cache.http_cache(), transaction); 3144 3145 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3146 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3147 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3148 3149 transaction.method = "GET"; 3150 RunTransactionTest(cache.http_cache(), transaction); 3151 3152 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3153 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3154 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3155 RemoveMockTransaction(&transaction); 3156 } 3157 3158 // Tests that we don't invalidate entries as a result of a failed DELETE. 3159 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) { 3160 MockHttpCache cache; 3161 3162 MockTransaction transaction(kSimpleGET_Transaction); 3163 AddMockTransaction(&transaction); 3164 3165 // Attempt to populate the cache. 3166 RunTransactionTest(cache.http_cache(), transaction); 3167 3168 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3169 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3170 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3171 3172 transaction.method = "DELETE"; 3173 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable"; 3174 3175 RunTransactionTest(cache.http_cache(), transaction); 3176 3177 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3178 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3179 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3180 3181 transaction.method = "GET"; 3182 transaction.status = "HTTP/1.1 200 OK"; 3183 RunTransactionTest(cache.http_cache(), transaction); 3184 3185 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3186 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3187 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3188 RemoveMockTransaction(&transaction); 3189 } 3190 3191 // Tests that we don't invalidate entries after a failed network transaction. 3192 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) { 3193 MockHttpCache cache; 3194 3195 // Populate the cache. 3196 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 3197 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3198 3199 // Fail the network request. 3200 MockTransaction transaction(kSimpleGET_Transaction); 3201 transaction.return_code = net::ERR_FAILED; 3202 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3203 3204 AddMockTransaction(&transaction); 3205 RunTransactionTest(cache.http_cache(), transaction); 3206 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3207 RemoveMockTransaction(&transaction); 3208 3209 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE; 3210 transaction.return_code = net::OK; 3211 AddMockTransaction(&transaction); 3212 RunTransactionTest(cache.http_cache(), transaction); 3213 3214 // Make sure the transaction didn't reach the network. 3215 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3216 RemoveMockTransaction(&transaction); 3217 } 3218 3219 TEST(HttpCache, RangeGET_SkipsCache) { 3220 MockHttpCache cache; 3221 3222 // Test that we skip the cache for range GET requests. Eventually, we will 3223 // want to cache these, but we'll still have cases where skipping the cache 3224 // makes sense, so we want to make sure that it works properly. 3225 3226 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction); 3227 3228 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3229 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3230 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3231 3232 MockTransaction transaction(kSimpleGET_Transaction); 3233 transaction.request_headers = "If-None-Match: foo\r\n"; 3234 RunTransactionTest(cache.http_cache(), transaction); 3235 3236 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3237 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3238 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3239 3240 transaction.request_headers = 3241 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"; 3242 RunTransactionTest(cache.http_cache(), transaction); 3243 3244 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3245 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3246 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3247 } 3248 3249 // Test that we skip the cache for range requests that include a validation 3250 // header. 3251 TEST(HttpCache, RangeGET_SkipsCache2) { 3252 MockHttpCache cache; 3253 3254 MockTransaction transaction(kRangeGET_Transaction); 3255 transaction.request_headers = "If-None-Match: foo\r\n" 3256 EXTRA_HEADER 3257 "Range: bytes = 40-49\r\n"; 3258 RunTransactionTest(cache.http_cache(), transaction); 3259 3260 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3261 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3262 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3263 3264 transaction.request_headers = 3265 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n" 3266 EXTRA_HEADER 3267 "Range: bytes = 40-49\r\n"; 3268 RunTransactionTest(cache.http_cache(), transaction); 3269 3270 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3271 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3272 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3273 3274 transaction.request_headers = "If-Range: bla\r\n" 3275 EXTRA_HEADER 3276 "Range: bytes = 40-49\r\n"; 3277 RunTransactionTest(cache.http_cache(), transaction); 3278 3279 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3280 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3281 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3282 } 3283 3284 // Tests that receiving 206 for a regular request is handled correctly. 3285 TEST(HttpCache, GET_Crazy206) { 3286 MockHttpCache cache; 3287 3288 // Write to the cache. 3289 MockTransaction transaction(kRangeGET_TransactionOK); 3290 AddMockTransaction(&transaction); 3291 transaction.request_headers = EXTRA_HEADER; 3292 transaction.handler = NULL; 3293 RunTransactionTest(cache.http_cache(), transaction); 3294 3295 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3296 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3297 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3298 3299 // This should read again from the net. 3300 RunTransactionTest(cache.http_cache(), transaction); 3301 3302 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3303 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3304 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3305 RemoveMockTransaction(&transaction); 3306 } 3307 3308 // Tests that we don't cache partial responses that can't be validated. 3309 TEST(HttpCache, RangeGET_NoStrongValidators) { 3310 MockHttpCache cache; 3311 std::string headers; 3312 3313 // Attempt to write to the cache (40-49). 3314 MockTransaction transaction(kRangeGET_TransactionOK); 3315 AddMockTransaction(&transaction); 3316 transaction.response_headers = "Content-Length: 10\n" 3317 "ETag: w/\"foo\"\n"; 3318 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3319 3320 Verify206Response(headers, 40, 49); 3321 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3322 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3323 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3324 3325 // Now verify that there's no cached data. 3326 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3327 &headers); 3328 3329 Verify206Response(headers, 40, 49); 3330 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3331 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3332 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3333 3334 RemoveMockTransaction(&transaction); 3335 } 3336 3337 // Tests that we can cache range requests and fetch random blocks from the 3338 // cache and the network. 3339 TEST(HttpCache, RangeGET_OK) { 3340 MockHttpCache cache; 3341 AddMockTransaction(&kRangeGET_TransactionOK); 3342 std::string headers; 3343 3344 // Write to the cache (40-49). 3345 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3346 &headers); 3347 3348 Verify206Response(headers, 40, 49); 3349 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3350 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3351 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3352 3353 // Read from the cache (40-49). 3354 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3355 &headers); 3356 3357 Verify206Response(headers, 40, 49); 3358 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3359 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3360 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3361 3362 // Make sure we are done with the previous transaction. 3363 base::MessageLoop::current()->RunUntilIdle(); 3364 3365 // Write to the cache (30-39). 3366 MockTransaction transaction(kRangeGET_TransactionOK); 3367 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER; 3368 transaction.data = "rg: 30-39 "; 3369 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3370 3371 Verify206Response(headers, 30, 39); 3372 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3373 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3374 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3375 3376 // Make sure we are done with the previous transaction. 3377 base::MessageLoop::current()->RunUntilIdle(); 3378 3379 // Write and read from the cache (20-59). 3380 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; 3381 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; 3382 net::CapturingBoundNetLog log; 3383 net::LoadTimingInfo load_timing_info; 3384 RunTransactionTestWithResponseAndGetTiming( 3385 cache.http_cache(), transaction, &headers, log.bound(), 3386 &load_timing_info); 3387 3388 Verify206Response(headers, 20, 59); 3389 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 3390 EXPECT_EQ(3, cache.disk_cache()->open_count()); 3391 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3392 TestLoadTimingNetworkRequest(load_timing_info); 3393 3394 RemoveMockTransaction(&kRangeGET_TransactionOK); 3395 } 3396 3397 #if defined(OS_ANDROID) 3398 3399 // Checks that with a cache backend having Sparse IO unimplementes the cache 3400 // entry would be doomed after a range request. 3401 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO. 3402 TEST(HttpCache, RangeGET_SparseNotImplemented) { 3403 MockHttpCache cache; 3404 cache.disk_cache()->set_fail_sparse_requests(); 3405 3406 // Run a cacheable request to prime the cache. 3407 MockTransaction transaction(kTypicalGET_Transaction); 3408 transaction.url = kRangeGET_TransactionOK.url; 3409 AddMockTransaction(&transaction); 3410 RunTransactionTest(cache.http_cache(), transaction); 3411 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3412 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3413 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3414 3415 // Verify that we added the entry. 3416 disk_cache::Entry* entry; 3417 net::TestCompletionCallback cb; 3418 int rv = cache.disk_cache()->OpenEntry(transaction.url, 3419 &entry, 3420 cb.callback()); 3421 ASSERT_EQ(net::OK, cb.GetResult(rv)); 3422 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3423 entry->Close(); 3424 RemoveMockTransaction(&transaction); 3425 3426 // Request the range with the backend that does not support it. 3427 MockTransaction transaction2(kRangeGET_TransactionOK); 3428 std::string headers; 3429 AddMockTransaction(&transaction2); 3430 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 3431 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3432 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3433 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3434 3435 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even 3436 // if it was re-created later, so this effectively checks that the old data is 3437 // gone. 3438 disk_cache::Entry* entry2; 3439 rv = cache.disk_cache()->OpenEntry(transaction2.url, 3440 &entry2, 3441 cb.callback()); 3442 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv)); 3443 RemoveMockTransaction(&transaction2); 3444 } 3445 3446 TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) { 3447 MockHttpCache cache; 3448 cache.disk_cache()->set_fail_sparse_requests(); 3449 3450 // Request the range with the backend that does not support it. 3451 MockTransaction transaction(kRangeGET_TransactionOK); 3452 std::string headers; 3453 AddMockTransaction(&transaction); 3454 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3455 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3456 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3457 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3458 3459 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even 3460 // if it was re-created later, so this effectively checks that the old data is 3461 // gone as a result of a failed range write. 3462 disk_cache::Entry* entry; 3463 net::TestCompletionCallback cb; 3464 int rv = cache.disk_cache()->OpenEntry(transaction.url, 3465 &entry, 3466 cb.callback()); 3467 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv)); 3468 RemoveMockTransaction(&transaction); 3469 } 3470 3471 #endif // OS_ANDROID 3472 3473 // Tests that we can cache range requests and fetch random blocks from the 3474 // cache and the network, with synchronous responses. 3475 TEST(HttpCache, RangeGET_SyncOK) { 3476 MockHttpCache cache; 3477 3478 MockTransaction transaction(kRangeGET_TransactionOK); 3479 transaction.test_mode = TEST_MODE_SYNC_ALL; 3480 AddMockTransaction(&transaction); 3481 3482 // Write to the cache (40-49). 3483 std::string headers; 3484 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3485 3486 Verify206Response(headers, 40, 49); 3487 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3488 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3489 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3490 3491 // Read from the cache (40-49). 3492 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3493 3494 Verify206Response(headers, 40, 49); 3495 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3496 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3497 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3498 3499 // Make sure we are done with the previous transaction. 3500 base::MessageLoop::current()->RunUntilIdle(); 3501 3502 // Write to the cache (30-39). 3503 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER; 3504 transaction.data = "rg: 30-39 "; 3505 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3506 3507 Verify206Response(headers, 30, 39); 3508 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3509 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3510 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3511 3512 // Make sure we are done with the previous transaction. 3513 base::MessageLoop::current()->RunUntilIdle(); 3514 3515 // Write and read from the cache (20-59). 3516 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; 3517 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; 3518 net::CapturingBoundNetLog log; 3519 net::LoadTimingInfo load_timing_info; 3520 RunTransactionTestWithResponseAndGetTiming( 3521 cache.http_cache(), transaction, &headers, log.bound(), 3522 &load_timing_info); 3523 3524 Verify206Response(headers, 20, 59); 3525 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 3526 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3527 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3528 TestLoadTimingNetworkRequest(load_timing_info); 3529 3530 RemoveMockTransaction(&transaction); 3531 } 3532 3533 // Tests that we don't revalidate an entry unless we are required to do so. 3534 TEST(HttpCache, RangeGET_Revalidate1) { 3535 MockHttpCache cache; 3536 std::string headers; 3537 3538 // Write to the cache (40-49). 3539 MockTransaction transaction(kRangeGET_TransactionOK); 3540 transaction.response_headers = 3541 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 3542 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire. 3543 "ETag: \"foo\"\n" 3544 "Accept-Ranges: bytes\n" 3545 "Content-Length: 10\n"; 3546 AddMockTransaction(&transaction); 3547 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3548 3549 Verify206Response(headers, 40, 49); 3550 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3551 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3552 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3553 3554 // Read from the cache (40-49). 3555 net::CapturingBoundNetLog log; 3556 net::LoadTimingInfo load_timing_info; 3557 RunTransactionTestWithResponseAndGetTiming( 3558 cache.http_cache(), transaction, &headers, log.bound(), 3559 &load_timing_info); 3560 3561 Verify206Response(headers, 40, 49); 3562 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3563 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3564 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3565 TestLoadTimingCachedResponse(load_timing_info); 3566 3567 // Read again forcing the revalidation. 3568 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3569 RunTransactionTestWithResponseAndGetTiming( 3570 cache.http_cache(), transaction, &headers, log.bound(), 3571 &load_timing_info); 3572 3573 Verify206Response(headers, 40, 49); 3574 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3575 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3576 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3577 TestLoadTimingNetworkRequest(load_timing_info); 3578 3579 RemoveMockTransaction(&transaction); 3580 } 3581 3582 // Checks that we revalidate an entry when the headers say so. 3583 TEST(HttpCache, RangeGET_Revalidate2) { 3584 MockHttpCache cache; 3585 std::string headers; 3586 3587 // Write to the cache (40-49). 3588 MockTransaction transaction(kRangeGET_TransactionOK); 3589 transaction.response_headers = 3590 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 3591 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired. 3592 "ETag: \"foo\"\n" 3593 "Accept-Ranges: bytes\n" 3594 "Content-Length: 10\n"; 3595 AddMockTransaction(&transaction); 3596 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3597 3598 Verify206Response(headers, 40, 49); 3599 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3600 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3601 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3602 3603 // Read from the cache (40-49). 3604 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3605 Verify206Response(headers, 40, 49); 3606 3607 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3608 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3609 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3610 3611 RemoveMockTransaction(&transaction); 3612 } 3613 3614 // Tests that we deal with 304s for range requests. 3615 TEST(HttpCache, RangeGET_304) { 3616 MockHttpCache cache; 3617 AddMockTransaction(&kRangeGET_TransactionOK); 3618 std::string headers; 3619 3620 // Write to the cache (40-49). 3621 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3622 &headers); 3623 3624 Verify206Response(headers, 40, 49); 3625 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3626 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3627 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3628 3629 // Read from the cache (40-49). 3630 RangeTransactionServer handler; 3631 handler.set_not_modified(true); 3632 MockTransaction transaction(kRangeGET_TransactionOK); 3633 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3634 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3635 3636 Verify206Response(headers, 40, 49); 3637 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3638 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3639 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3640 3641 RemoveMockTransaction(&kRangeGET_TransactionOK); 3642 } 3643 3644 // Tests that we deal with 206s when revalidating range requests. 3645 TEST(HttpCache, RangeGET_ModifiedResult) { 3646 MockHttpCache cache; 3647 AddMockTransaction(&kRangeGET_TransactionOK); 3648 std::string headers; 3649 3650 // Write to the cache (40-49). 3651 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3652 &headers); 3653 3654 Verify206Response(headers, 40, 49); 3655 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3656 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3657 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3658 3659 // Attempt to read from the cache (40-49). 3660 RangeTransactionServer handler; 3661 handler.set_modified(true); 3662 MockTransaction transaction(kRangeGET_TransactionOK); 3663 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3664 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3665 3666 Verify206Response(headers, 40, 49); 3667 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3668 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3669 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3670 3671 // And the entry should be gone. 3672 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3673 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3674 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3675 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3676 3677 RemoveMockTransaction(&kRangeGET_TransactionOK); 3678 } 3679 3680 // Tests that we cache 301s for range requests. 3681 TEST(HttpCache, RangeGET_301) { 3682 MockHttpCache cache; 3683 ScopedMockTransaction transaction(kRangeGET_TransactionOK); 3684 transaction.status = "HTTP/1.1 301 Moved Permanently"; 3685 transaction.response_headers = "Location: http://www.bar.com/\n"; 3686 transaction.data = ""; 3687 transaction.handler = NULL; 3688 AddMockTransaction(&transaction); 3689 3690 // Write to the cache. 3691 RunTransactionTest(cache.http_cache(), transaction); 3692 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3693 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3694 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3695 3696 // Read from the cache. 3697 RunTransactionTest(cache.http_cache(), transaction); 3698 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3699 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3700 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3701 3702 RemoveMockTransaction(&transaction); 3703 } 3704 3705 // Tests that we can cache range requests when the start or end is unknown. 3706 // We start with one suffix request, followed by a request from a given point. 3707 TEST(HttpCache, UnknownRangeGET_1) { 3708 MockHttpCache cache; 3709 AddMockTransaction(&kRangeGET_TransactionOK); 3710 std::string headers; 3711 3712 // Write to the cache (70-79). 3713 MockTransaction transaction(kRangeGET_TransactionOK); 3714 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER; 3715 transaction.data = "rg: 70-79 "; 3716 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3717 3718 Verify206Response(headers, 70, 79); 3719 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3720 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3721 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3722 3723 // Make sure we are done with the previous transaction. 3724 base::MessageLoop::current()->RunUntilIdle(); 3725 3726 // Write and read from the cache (60-79). 3727 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER; 3728 transaction.data = "rg: 60-69 rg: 70-79 "; 3729 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3730 3731 Verify206Response(headers, 60, 79); 3732 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3733 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3734 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3735 3736 RemoveMockTransaction(&kRangeGET_TransactionOK); 3737 } 3738 3739 // Tests that we can cache range requests when the start or end is unknown. 3740 // We start with one request from a given point, followed by a suffix request. 3741 // We'll also verify that synchronous cache responses work as intended. 3742 TEST(HttpCache, UnknownRangeGET_2) { 3743 MockHttpCache cache; 3744 std::string headers; 3745 3746 MockTransaction transaction(kRangeGET_TransactionOK); 3747 transaction.test_mode = TEST_MODE_SYNC_CACHE_START | 3748 TEST_MODE_SYNC_CACHE_READ | 3749 TEST_MODE_SYNC_CACHE_WRITE; 3750 AddMockTransaction(&transaction); 3751 3752 // Write to the cache (70-79). 3753 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER; 3754 transaction.data = "rg: 70-79 "; 3755 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3756 3757 Verify206Response(headers, 70, 79); 3758 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3759 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3760 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3761 3762 // Make sure we are done with the previous transaction. 3763 base::MessageLoop::current()->RunUntilIdle(); 3764 3765 // Write and read from the cache (60-79). 3766 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER; 3767 transaction.data = "rg: 60-69 rg: 70-79 "; 3768 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3769 3770 Verify206Response(headers, 60, 79); 3771 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3772 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3773 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3774 3775 RemoveMockTransaction(&transaction); 3776 } 3777 3778 // Tests that receiving Not Modified when asking for an open range doesn't mess 3779 // up things. 3780 TEST(HttpCache, UnknownRangeGET_304) { 3781 MockHttpCache cache; 3782 std::string headers; 3783 3784 MockTransaction transaction(kRangeGET_TransactionOK); 3785 AddMockTransaction(&transaction); 3786 3787 RangeTransactionServer handler; 3788 handler.set_not_modified(true); 3789 3790 // Ask for the end of the file, without knowing the length. 3791 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER; 3792 transaction.data = ""; 3793 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3794 3795 // We just bypass the cache. 3796 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n")); 3797 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3798 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3799 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3800 3801 RunTransactionTest(cache.http_cache(), transaction); 3802 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3803 3804 RemoveMockTransaction(&transaction); 3805 } 3806 3807 // Tests that we can handle non-range requests when we have cached a range. 3808 TEST(HttpCache, GET_Previous206) { 3809 MockHttpCache cache; 3810 AddMockTransaction(&kRangeGET_TransactionOK); 3811 std::string headers; 3812 net::CapturingBoundNetLog log; 3813 net::LoadTimingInfo load_timing_info; 3814 3815 // Write to the cache (40-49). 3816 RunTransactionTestWithResponseAndGetTiming( 3817 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(), 3818 &load_timing_info); 3819 3820 Verify206Response(headers, 40, 49); 3821 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3822 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3823 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3824 TestLoadTimingNetworkRequest(load_timing_info); 3825 3826 // Write and read from the cache (0-79), when not asked for a range. 3827 MockTransaction transaction(kRangeGET_TransactionOK); 3828 transaction.request_headers = EXTRA_HEADER; 3829 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 3830 "rg: 50-59 rg: 60-69 rg: 70-79 "; 3831 RunTransactionTestWithResponseAndGetTiming( 3832 cache.http_cache(), transaction, &headers, log.bound(), 3833 &load_timing_info); 3834 3835 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3836 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3837 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3838 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3839 TestLoadTimingNetworkRequest(load_timing_info); 3840 3841 RemoveMockTransaction(&kRangeGET_TransactionOK); 3842 } 3843 3844 // Tests that we can handle non-range requests when we have cached the first 3845 // part of the object and the server replies with 304 (Not Modified). 3846 TEST(HttpCache, GET_Previous206_NotModified) { 3847 MockHttpCache cache; 3848 3849 MockTransaction transaction(kRangeGET_TransactionOK); 3850 AddMockTransaction(&transaction); 3851 std::string headers; 3852 net::CapturingBoundNetLog log; 3853 net::LoadTimingInfo load_timing_info; 3854 3855 // Write to the cache (0-9). 3856 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; 3857 transaction.data = "rg: 00-09 "; 3858 RunTransactionTestWithResponseAndGetTiming( 3859 cache.http_cache(), transaction, &headers, log.bound(), 3860 &load_timing_info); 3861 Verify206Response(headers, 0, 9); 3862 TestLoadTimingNetworkRequest(load_timing_info); 3863 3864 // Write to the cache (70-79). 3865 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; 3866 transaction.data = "rg: 70-79 "; 3867 RunTransactionTestWithResponseAndGetTiming( 3868 cache.http_cache(), transaction, &headers, log.bound(), 3869 &load_timing_info); 3870 Verify206Response(headers, 70, 79); 3871 3872 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3873 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3874 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3875 TestLoadTimingNetworkRequest(load_timing_info); 3876 3877 // Read from the cache (0-9), write and read from cache (10 - 79). 3878 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3879 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER; 3880 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 3881 "rg: 50-59 rg: 60-69 rg: 70-79 "; 3882 RunTransactionTestWithResponseAndGetTiming( 3883 cache.http_cache(), transaction, &headers, log.bound(), 3884 &load_timing_info); 3885 3886 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3887 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 3888 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3889 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3890 TestLoadTimingNetworkRequest(load_timing_info); 3891 3892 RemoveMockTransaction(&transaction); 3893 } 3894 3895 // Tests that we can handle a regular request to a sparse entry, that results in 3896 // new content provided by the server (206). 3897 TEST(HttpCache, GET_Previous206_NewContent) { 3898 MockHttpCache cache; 3899 AddMockTransaction(&kRangeGET_TransactionOK); 3900 std::string headers; 3901 3902 // Write to the cache (0-9). 3903 MockTransaction transaction(kRangeGET_TransactionOK); 3904 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; 3905 transaction.data = "rg: 00-09 "; 3906 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3907 3908 Verify206Response(headers, 0, 9); 3909 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3910 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3911 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3912 3913 // Now we'll issue a request without any range that should result first in a 3914 // 206 (when revalidating), and then in a weird standard answer: the test 3915 // server will not modify the response so we'll get the default range... a 3916 // real server will answer with 200. 3917 MockTransaction transaction2(kRangeGET_TransactionOK); 3918 transaction2.request_headers = EXTRA_HEADER; 3919 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE; 3920 transaction2.data = "Not a range"; 3921 RangeTransactionServer handler; 3922 handler.set_modified(true); 3923 net::CapturingBoundNetLog log; 3924 net::LoadTimingInfo load_timing_info; 3925 RunTransactionTestWithResponseAndGetTiming( 3926 cache.http_cache(), transaction2, &headers, log.bound(), 3927 &load_timing_info); 3928 3929 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3930 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3931 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3932 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3933 TestLoadTimingNetworkRequest(load_timing_info); 3934 3935 // Verify that the previous request deleted the entry. 3936 RunTransactionTest(cache.http_cache(), transaction); 3937 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3938 3939 RemoveMockTransaction(&transaction); 3940 } 3941 3942 // Tests that we can handle cached 206 responses that are not sparse. 3943 TEST(HttpCache, GET_Previous206_NotSparse) { 3944 MockHttpCache cache; 3945 3946 // Create a disk cache entry that stores 206 headers while not being sparse. 3947 disk_cache::Entry* entry; 3948 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry, 3949 NULL)); 3950 3951 std::string raw_headers(kRangeGET_TransactionOK.status); 3952 raw_headers.append("\n"); 3953 raw_headers.append(kRangeGET_TransactionOK.response_headers); 3954 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 3955 raw_headers.size()); 3956 3957 net::HttpResponseInfo response; 3958 response.headers = new net::HttpResponseHeaders(raw_headers); 3959 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 3960 3961 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); 3962 int len = static_cast<int>(base::strlcpy(buf->data(), 3963 kRangeGET_TransactionOK.data, 500)); 3964 net::TestCompletionCallback cb; 3965 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true); 3966 EXPECT_EQ(len, cb.GetResult(rv)); 3967 entry->Close(); 3968 3969 // Now see that we don't use the stored entry. 3970 std::string headers; 3971 net::CapturingBoundNetLog log; 3972 net::LoadTimingInfo load_timing_info; 3973 RunTransactionTestWithResponseAndGetTiming( 3974 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(), 3975 &load_timing_info); 3976 3977 // We are expecting a 200. 3978 std::string expected_headers(kSimpleGET_Transaction.status); 3979 expected_headers.append("\n"); 3980 expected_headers.append(kSimpleGET_Transaction.response_headers); 3981 EXPECT_EQ(expected_headers, headers); 3982 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3983 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3984 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3985 TestLoadTimingNetworkRequest(load_timing_info); 3986 } 3987 3988 // Tests that we can handle cached 206 responses that are not sparse. This time 3989 // we issue a range request and expect to receive a range. 3990 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) { 3991 MockHttpCache cache; 3992 AddMockTransaction(&kRangeGET_TransactionOK); 3993 3994 // Create a disk cache entry that stores 206 headers while not being sparse. 3995 disk_cache::Entry* entry; 3996 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, 3997 NULL)); 3998 3999 std::string raw_headers(kRangeGET_TransactionOK.status); 4000 raw_headers.append("\n"); 4001 raw_headers.append(kRangeGET_TransactionOK.response_headers); 4002 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 4003 raw_headers.size()); 4004 4005 net::HttpResponseInfo response; 4006 response.headers = new net::HttpResponseHeaders(raw_headers); 4007 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 4008 4009 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); 4010 int len = static_cast<int>(base::strlcpy(buf->data(), 4011 kRangeGET_TransactionOK.data, 500)); 4012 net::TestCompletionCallback cb; 4013 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true); 4014 EXPECT_EQ(len, cb.GetResult(rv)); 4015 entry->Close(); 4016 4017 // Now see that we don't use the stored entry. 4018 std::string headers; 4019 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 4020 &headers); 4021 4022 // We are expecting a 206. 4023 Verify206Response(headers, 40, 49); 4024 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4025 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4026 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4027 4028 RemoveMockTransaction(&kRangeGET_TransactionOK); 4029 } 4030 4031 // Tests that we can handle cached 206 responses that can't be validated. 4032 TEST(HttpCache, GET_Previous206_NotValidation) { 4033 MockHttpCache cache; 4034 4035 // Create a disk cache entry that stores 206 headers. 4036 disk_cache::Entry* entry; 4037 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry, 4038 NULL)); 4039 4040 // Make sure that the headers cannot be validated with the server. 4041 std::string raw_headers(kRangeGET_TransactionOK.status); 4042 raw_headers.append("\n"); 4043 raw_headers.append("Content-Length: 80\n"); 4044 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 4045 raw_headers.size()); 4046 4047 net::HttpResponseInfo response; 4048 response.headers = new net::HttpResponseHeaders(raw_headers); 4049 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 4050 4051 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); 4052 int len = static_cast<int>(base::strlcpy(buf->data(), 4053 kRangeGET_TransactionOK.data, 500)); 4054 net::TestCompletionCallback cb; 4055 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true); 4056 EXPECT_EQ(len, cb.GetResult(rv)); 4057 entry->Close(); 4058 4059 // Now see that we don't use the stored entry. 4060 std::string headers; 4061 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction, 4062 &headers); 4063 4064 // We are expecting a 200. 4065 std::string expected_headers(kSimpleGET_Transaction.status); 4066 expected_headers.append("\n"); 4067 expected_headers.append(kSimpleGET_Transaction.response_headers); 4068 EXPECT_EQ(expected_headers, headers); 4069 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4070 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4071 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4072 } 4073 4074 // Tests that we can handle range requests with cached 200 responses. 4075 TEST(HttpCache, RangeGET_Previous200) { 4076 MockHttpCache cache; 4077 4078 // Store the whole thing with status 200. 4079 MockTransaction transaction(kTypicalGET_Transaction); 4080 transaction.url = kRangeGET_TransactionOK.url; 4081 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 4082 "rg: 50-59 rg: 60-69 rg: 70-79 "; 4083 AddMockTransaction(&transaction); 4084 RunTransactionTest(cache.http_cache(), transaction); 4085 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4086 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4087 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4088 4089 RemoveMockTransaction(&transaction); 4090 AddMockTransaction(&kRangeGET_TransactionOK); 4091 4092 // Now see that we use the stored entry. 4093 std::string headers; 4094 MockTransaction transaction2(kRangeGET_TransactionOK); 4095 RangeTransactionServer handler; 4096 handler.set_not_modified(true); 4097 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 4098 4099 // We are expecting a 206. 4100 Verify206Response(headers, 40, 49); 4101 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4102 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4103 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4104 4105 // The last transaction has finished so make sure the entry is deactivated. 4106 base::MessageLoop::current()->RunUntilIdle(); 4107 4108 // Make a request for an invalid range. 4109 MockTransaction transaction3(kRangeGET_TransactionOK); 4110 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER; 4111 transaction3.data = transaction.data; 4112 transaction3.load_flags = net::LOAD_PREFERRING_CACHE; 4113 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers); 4114 EXPECT_EQ(2, cache.disk_cache()->open_count()); 4115 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 ")); 4116 EXPECT_EQ(std::string::npos, headers.find("Content-Range:")); 4117 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80")); 4118 4119 // Make sure the entry is deactivated. 4120 base::MessageLoop::current()->RunUntilIdle(); 4121 4122 // Even though the request was invalid, we should have the entry. 4123 RunTransactionTest(cache.http_cache(), transaction2); 4124 EXPECT_EQ(3, cache.disk_cache()->open_count()); 4125 4126 // Make sure the entry is deactivated. 4127 base::MessageLoop::current()->RunUntilIdle(); 4128 4129 // Now we should receive a range from the server and drop the stored entry. 4130 handler.set_not_modified(false); 4131 transaction2.request_headers = kRangeGET_TransactionOK.request_headers; 4132 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 4133 Verify206Response(headers, 40, 49); 4134 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 4135 EXPECT_EQ(4, cache.disk_cache()->open_count()); 4136 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4137 4138 RunTransactionTest(cache.http_cache(), transaction2); 4139 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4140 4141 RemoveMockTransaction(&kRangeGET_TransactionOK); 4142 } 4143 4144 // Tests that we can handle a 200 response when dealing with sparse entries. 4145 TEST(HttpCache, RangeRequestResultsIn200) { 4146 MockHttpCache cache; 4147 AddMockTransaction(&kRangeGET_TransactionOK); 4148 std::string headers; 4149 4150 // Write to the cache (70-79). 4151 MockTransaction transaction(kRangeGET_TransactionOK); 4152 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER; 4153 transaction.data = "rg: 70-79 "; 4154 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4155 4156 Verify206Response(headers, 70, 79); 4157 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4158 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4159 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4160 4161 // Now we'll issue a request that results in a plain 200 response, but to 4162 // the to the same URL that we used to store sparse data, and making sure 4163 // that we ask for a range. 4164 RemoveMockTransaction(&kRangeGET_TransactionOK); 4165 MockTransaction transaction2(kSimpleGET_Transaction); 4166 transaction2.url = kRangeGET_TransactionOK.url; 4167 transaction2.request_headers = kRangeGET_TransactionOK.request_headers; 4168 AddMockTransaction(&transaction2); 4169 4170 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 4171 4172 std::string expected_headers(kSimpleGET_Transaction.status); 4173 expected_headers.append("\n"); 4174 expected_headers.append(kSimpleGET_Transaction.response_headers); 4175 EXPECT_EQ(expected_headers, headers); 4176 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4177 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4178 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4179 4180 RemoveMockTransaction(&transaction2); 4181 } 4182 4183 // Tests that a range request that falls outside of the size that we know about 4184 // only deletes the entry if the resource has indeed changed. 4185 TEST(HttpCache, RangeGET_MoreThanCurrentSize) { 4186 MockHttpCache cache; 4187 AddMockTransaction(&kRangeGET_TransactionOK); 4188 std::string headers; 4189 4190 // Write to the cache (40-49). 4191 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 4192 &headers); 4193 4194 Verify206Response(headers, 40, 49); 4195 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4196 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4197 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4198 4199 // A weird request should not delete this entry. Ask for bytes 120-. 4200 MockTransaction transaction(kRangeGET_TransactionOK); 4201 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER; 4202 transaction.data = ""; 4203 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4204 4205 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 ")); 4206 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4207 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4208 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4209 4210 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4211 EXPECT_EQ(2, cache.disk_cache()->open_count()); 4212 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4213 4214 RemoveMockTransaction(&kRangeGET_TransactionOK); 4215 } 4216 4217 // Tests that we don't delete a sparse entry when we cancel a request. 4218 TEST(HttpCache, RangeGET_Cancel) { 4219 MockHttpCache cache; 4220 AddMockTransaction(&kRangeGET_TransactionOK); 4221 4222 MockHttpRequest request(kRangeGET_TransactionOK); 4223 4224 Context* c = new Context(); 4225 int rv = cache.http_cache()->CreateTransaction( 4226 net::DEFAULT_PRIORITY, &c->trans, NULL); 4227 EXPECT_EQ(net::OK, rv); 4228 4229 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4230 if (rv == net::ERR_IO_PENDING) 4231 rv = c->callback.WaitForResult(); 4232 4233 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4234 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4235 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4236 4237 // Make sure that the entry has some data stored. 4238 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4239 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4240 if (rv == net::ERR_IO_PENDING) 4241 rv = c->callback.WaitForResult(); 4242 EXPECT_EQ(buf->size(), rv); 4243 4244 // Destroy the transaction. 4245 delete c; 4246 4247 // Verify that the entry has not been deleted. 4248 disk_cache::Entry* entry; 4249 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4250 entry->Close(); 4251 RemoveMockTransaction(&kRangeGET_TransactionOK); 4252 } 4253 4254 // Tests that we don't delete a sparse entry when we start a new request after 4255 // cancelling the previous one. 4256 TEST(HttpCache, RangeGET_Cancel2) { 4257 MockHttpCache cache; 4258 AddMockTransaction(&kRangeGET_TransactionOK); 4259 4260 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4261 MockHttpRequest request(kRangeGET_TransactionOK); 4262 request.load_flags |= net::LOAD_VALIDATE_CACHE; 4263 4264 Context* c = new Context(); 4265 int rv = cache.http_cache()->CreateTransaction( 4266 net::DEFAULT_PRIORITY, &c->trans, NULL); 4267 EXPECT_EQ(net::OK, rv); 4268 4269 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4270 if (rv == net::ERR_IO_PENDING) 4271 rv = c->callback.WaitForResult(); 4272 4273 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4274 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4275 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4276 4277 // Make sure that we revalidate the entry and read from the cache (a single 4278 // read will return while waiting for the network). 4279 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5)); 4280 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4281 EXPECT_EQ(5, c->callback.GetResult(rv)); 4282 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4283 EXPECT_EQ(net::ERR_IO_PENDING, rv); 4284 4285 // Destroy the transaction before completing the read. 4286 delete c; 4287 4288 // We have the read and the delete (OnProcessPendingQueue) waiting on the 4289 // message loop. This means that a new transaction will just reuse the same 4290 // active entry (no open or create). 4291 4292 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4293 4294 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4295 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4296 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4297 RemoveMockTransaction(&kRangeGET_TransactionOK); 4298 } 4299 4300 // A slight variation of the previous test, this time we cancel two requests in 4301 // a row, making sure that the second is waiting for the entry to be ready. 4302 TEST(HttpCache, RangeGET_Cancel3) { 4303 MockHttpCache cache; 4304 AddMockTransaction(&kRangeGET_TransactionOK); 4305 4306 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4307 MockHttpRequest request(kRangeGET_TransactionOK); 4308 request.load_flags |= net::LOAD_VALIDATE_CACHE; 4309 4310 Context* c = new Context(); 4311 int rv = cache.http_cache()->CreateTransaction( 4312 net::DEFAULT_PRIORITY, &c->trans, NULL); 4313 EXPECT_EQ(net::OK, rv); 4314 4315 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4316 EXPECT_EQ(net::ERR_IO_PENDING, rv); 4317 rv = c->callback.WaitForResult(); 4318 4319 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4320 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4321 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4322 4323 // Make sure that we revalidate the entry and read from the cache (a single 4324 // read will return while waiting for the network). 4325 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5)); 4326 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4327 EXPECT_EQ(5, c->callback.GetResult(rv)); 4328 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4329 EXPECT_EQ(net::ERR_IO_PENDING, rv); 4330 4331 // Destroy the transaction before completing the read. 4332 delete c; 4333 4334 // We have the read and the delete (OnProcessPendingQueue) waiting on the 4335 // message loop. This means that a new transaction will just reuse the same 4336 // active entry (no open or create). 4337 4338 c = new Context(); 4339 rv = cache.http_cache()->CreateTransaction( 4340 net::DEFAULT_PRIORITY, &c->trans, NULL); 4341 EXPECT_EQ(net::OK, rv); 4342 4343 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4344 EXPECT_EQ(net::ERR_IO_PENDING, rv); 4345 4346 MockDiskEntry::IgnoreCallbacks(true); 4347 base::MessageLoop::current()->RunUntilIdle(); 4348 MockDiskEntry::IgnoreCallbacks(false); 4349 4350 // The new transaction is waiting for the query range callback. 4351 delete c; 4352 4353 // And we should not crash when the callback is delivered. 4354 base::MessageLoop::current()->RunUntilIdle(); 4355 4356 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4357 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4358 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4359 RemoveMockTransaction(&kRangeGET_TransactionOK); 4360 } 4361 4362 // Tests that an invalid range response results in no cached entry. 4363 TEST(HttpCache, RangeGET_InvalidResponse1) { 4364 MockHttpCache cache; 4365 std::string headers; 4366 4367 MockTransaction transaction(kRangeGET_TransactionOK); 4368 transaction.handler = NULL; 4369 transaction.response_headers = "Content-Range: bytes 40-49/45\n" 4370 "Content-Length: 10\n"; 4371 AddMockTransaction(&transaction); 4372 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4373 4374 std::string expected(transaction.status); 4375 expected.append("\n"); 4376 expected.append(transaction.response_headers); 4377 EXPECT_EQ(expected, headers); 4378 4379 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4380 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4381 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4382 4383 // Verify that we don't have a cached entry. 4384 disk_cache::Entry* entry; 4385 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4386 4387 RemoveMockTransaction(&kRangeGET_TransactionOK); 4388 } 4389 4390 // Tests that we reject a range that doesn't match the content-length. 4391 TEST(HttpCache, RangeGET_InvalidResponse2) { 4392 MockHttpCache cache; 4393 std::string headers; 4394 4395 MockTransaction transaction(kRangeGET_TransactionOK); 4396 transaction.handler = NULL; 4397 transaction.response_headers = "Content-Range: bytes 40-49/80\n" 4398 "Content-Length: 20\n"; 4399 AddMockTransaction(&transaction); 4400 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4401 4402 std::string expected(transaction.status); 4403 expected.append("\n"); 4404 expected.append(transaction.response_headers); 4405 EXPECT_EQ(expected, headers); 4406 4407 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4408 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4409 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4410 4411 // Verify that we don't have a cached entry. 4412 disk_cache::Entry* entry; 4413 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4414 4415 RemoveMockTransaction(&kRangeGET_TransactionOK); 4416 } 4417 4418 // Tests that if a server tells us conflicting information about a resource we 4419 // ignore the response. 4420 TEST(HttpCache, RangeGET_InvalidResponse3) { 4421 MockHttpCache cache; 4422 std::string headers; 4423 4424 MockTransaction transaction(kRangeGET_TransactionOK); 4425 transaction.handler = NULL; 4426 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER; 4427 std::string response_headers(transaction.response_headers); 4428 response_headers.append("Content-Range: bytes 50-59/160\n"); 4429 transaction.response_headers = response_headers.c_str(); 4430 AddMockTransaction(&transaction); 4431 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4432 4433 Verify206Response(headers, 50, 59); 4434 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4435 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4436 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4437 4438 RemoveMockTransaction(&transaction); 4439 AddMockTransaction(&kRangeGET_TransactionOK); 4440 4441 // This transaction will report a resource size of 80 bytes, and we think it's 4442 // 160 so we should ignore the response. 4443 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 4444 &headers); 4445 4446 Verify206Response(headers, 40, 49); 4447 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4448 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4449 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4450 4451 // Verify that we cached the first response but not the second one. 4452 disk_cache::Entry* en; 4453 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en)); 4454 4455 int64 cached_start = 0; 4456 net::TestCompletionCallback cb; 4457 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback()); 4458 EXPECT_EQ(10, cb.GetResult(rv)); 4459 EXPECT_EQ(50, cached_start); 4460 en->Close(); 4461 4462 RemoveMockTransaction(&kRangeGET_TransactionOK); 4463 } 4464 4465 // Tests that we handle large range values properly. 4466 TEST(HttpCache, RangeGET_LargeValues) { 4467 // We need a real sparse cache for this test. 4468 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024)); 4469 std::string headers; 4470 4471 MockTransaction transaction(kRangeGET_TransactionOK); 4472 transaction.handler = NULL; 4473 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n" 4474 EXTRA_HEADER; 4475 transaction.response_headers = 4476 "ETag: \"foo\"\n" 4477 "Content-Range: bytes 4294967288-4294967297/4294967299\n" 4478 "Content-Length: 10\n"; 4479 AddMockTransaction(&transaction); 4480 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4481 4482 std::string expected(transaction.status); 4483 expected.append("\n"); 4484 expected.append(transaction.response_headers); 4485 EXPECT_EQ(expected, headers); 4486 4487 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4488 4489 // Verify that we have a cached entry. 4490 disk_cache::Entry* en; 4491 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en)); 4492 en->Close(); 4493 4494 RemoveMockTransaction(&kRangeGET_TransactionOK); 4495 } 4496 4497 // Tests that we don't crash with a range request if the disk cache was not 4498 // initialized properly. 4499 TEST(HttpCache, RangeGET_NoDiskCache) { 4500 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 4501 factory->set_fail(true); 4502 factory->FinishCreation(); // We'll complete synchronously. 4503 MockHttpCache cache(factory); 4504 4505 AddMockTransaction(&kRangeGET_TransactionOK); 4506 4507 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4508 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4509 4510 RemoveMockTransaction(&kRangeGET_TransactionOK); 4511 } 4512 4513 // Tests that we handle byte range requests that skip the cache. 4514 TEST(HttpCache, RangeHEAD) { 4515 MockHttpCache cache; 4516 AddMockTransaction(&kRangeGET_TransactionOK); 4517 4518 MockTransaction transaction(kRangeGET_TransactionOK); 4519 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER; 4520 transaction.method = "HEAD"; 4521 transaction.data = "rg: 70-79 "; 4522 4523 std::string headers; 4524 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4525 4526 Verify206Response(headers, 70, 79); 4527 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4528 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4529 EXPECT_EQ(0, cache.disk_cache()->create_count()); 4530 4531 RemoveMockTransaction(&kRangeGET_TransactionOK); 4532 } 4533 4534 // Tests that we don't crash when after reading from the cache we issue a 4535 // request for the next range and the server gives us a 200 synchronously. 4536 TEST(HttpCache, RangeGET_FastFlakyServer) { 4537 MockHttpCache cache; 4538 4539 MockTransaction transaction(kRangeGET_TransactionOK); 4540 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; 4541 transaction.test_mode = TEST_MODE_SYNC_NET_START; 4542 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 4543 AddMockTransaction(&transaction); 4544 4545 // Write to the cache. 4546 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4547 4548 // And now read from the cache and the network. 4549 RangeTransactionServer handler; 4550 handler.set_bad_200(true); 4551 transaction.data = "Not a range"; 4552 RunTransactionTest(cache.http_cache(), transaction); 4553 4554 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 4555 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4556 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4557 4558 RemoveMockTransaction(&transaction); 4559 } 4560 4561 // Tests that when the server gives us less data than expected, we don't keep 4562 // asking for more data. 4563 TEST(HttpCache, RangeGET_FastFlakyServer2) { 4564 MockHttpCache cache; 4565 4566 // First, check with an empty cache (WRITE mode). 4567 MockTransaction transaction(kRangeGET_TransactionOK); 4568 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER; 4569 transaction.data = "rg: 40-"; // Less than expected. 4570 transaction.handler = NULL; 4571 std::string headers(transaction.response_headers); 4572 headers.append("Content-Range: bytes 40-49/80\n"); 4573 transaction.response_headers = headers.c_str(); 4574 4575 AddMockTransaction(&transaction); 4576 4577 // Write to the cache. 4578 RunTransactionTest(cache.http_cache(), transaction); 4579 4580 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4581 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4582 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4583 4584 // Now verify that even in READ_WRITE mode, we forward the bad response to 4585 // the caller. 4586 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER; 4587 transaction.data = "rg: 60-"; // Less than expected. 4588 headers = kRangeGET_TransactionOK.response_headers; 4589 headers.append("Content-Range: bytes 60-69/80\n"); 4590 transaction.response_headers = headers.c_str(); 4591 4592 RunTransactionTest(cache.http_cache(), transaction); 4593 4594 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4595 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4596 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4597 4598 RemoveMockTransaction(&transaction); 4599 } 4600 4601 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) 4602 // This test hits a NOTREACHED so it is a release mode only test. 4603 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) { 4604 MockHttpCache cache; 4605 AddMockTransaction(&kRangeGET_TransactionOK); 4606 4607 // Write to the cache (40-49). 4608 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4609 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4610 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4611 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4612 4613 // Force this transaction to read from the cache. 4614 MockTransaction transaction(kRangeGET_TransactionOK); 4615 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 4616 4617 MockHttpRequest request(transaction); 4618 net::TestCompletionCallback callback; 4619 4620 scoped_ptr<net::HttpTransaction> trans; 4621 int rv = cache.http_cache()->CreateTransaction( 4622 net::DEFAULT_PRIORITY, &trans, NULL); 4623 EXPECT_EQ(net::OK, rv); 4624 ASSERT_TRUE(trans.get()); 4625 4626 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 4627 if (rv == net::ERR_IO_PENDING) 4628 rv = callback.WaitForResult(); 4629 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 4630 4631 trans.reset(); 4632 4633 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4634 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4635 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4636 4637 RemoveMockTransaction(&kRangeGET_TransactionOK); 4638 } 4639 #endif 4640 4641 // Tests the handling of the "truncation" flag. 4642 TEST(HttpCache, WriteResponseInfo_Truncated) { 4643 MockHttpCache cache; 4644 disk_cache::Entry* entry; 4645 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry, 4646 NULL)); 4647 4648 std::string headers("HTTP/1.1 200 OK"); 4649 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size()); 4650 net::HttpResponseInfo response; 4651 response.headers = new net::HttpResponseHeaders(headers); 4652 4653 // Set the last argument for this to be an incomplete request. 4654 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); 4655 bool truncated = false; 4656 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4657 EXPECT_TRUE(truncated); 4658 4659 // And now test the opposite case. 4660 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 4661 truncated = true; 4662 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4663 EXPECT_FALSE(truncated); 4664 entry->Close(); 4665 } 4666 4667 // Tests basic pickling/unpickling of HttpResponseInfo. 4668 TEST(HttpCache, PersistHttpResponseInfo) { 4669 // Set some fields (add more if needed.) 4670 net::HttpResponseInfo response1; 4671 response1.was_cached = false; 4672 response1.socket_address = net::HostPortPair("1.2.3.4", 80); 4673 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK"); 4674 4675 // Pickle. 4676 Pickle pickle; 4677 response1.Persist(&pickle, false, false); 4678 4679 // Unpickle. 4680 net::HttpResponseInfo response2; 4681 bool response_truncated; 4682 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated)); 4683 EXPECT_FALSE(response_truncated); 4684 4685 // Verify fields. 4686 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag. 4687 EXPECT_EQ("1.2.3.4", response2.socket_address.host()); 4688 EXPECT_EQ(80, response2.socket_address.port()); 4689 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 4690 } 4691 4692 // Tests that we delete an entry when the request is cancelled before starting 4693 // to read from the network. 4694 TEST(HttpCache, DoomOnDestruction) { 4695 MockHttpCache cache; 4696 4697 MockHttpRequest request(kSimpleGET_Transaction); 4698 4699 Context* c = new Context(); 4700 int rv = cache.http_cache()->CreateTransaction( 4701 net::DEFAULT_PRIORITY, &c->trans, NULL); 4702 EXPECT_EQ(net::OK, rv); 4703 4704 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4705 if (rv == net::ERR_IO_PENDING) 4706 c->result = c->callback.WaitForResult(); 4707 4708 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4709 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4710 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4711 4712 // Destroy the transaction. We only have the headers so we should delete this 4713 // entry. 4714 delete c; 4715 4716 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4717 4718 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4719 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4720 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4721 } 4722 4723 // Tests that we delete an entry when the request is cancelled if the response 4724 // does not have content-length and strong validators. 4725 TEST(HttpCache, DoomOnDestruction2) { 4726 MockHttpCache cache; 4727 4728 MockHttpRequest request(kSimpleGET_Transaction); 4729 4730 Context* c = new Context(); 4731 int rv = cache.http_cache()->CreateTransaction( 4732 net::DEFAULT_PRIORITY, &c->trans, NULL); 4733 EXPECT_EQ(net::OK, rv); 4734 4735 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4736 if (rv == net::ERR_IO_PENDING) 4737 rv = c->callback.WaitForResult(); 4738 4739 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4740 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4741 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4742 4743 // Make sure that the entry has some data stored. 4744 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4745 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4746 if (rv == net::ERR_IO_PENDING) 4747 rv = c->callback.WaitForResult(); 4748 EXPECT_EQ(buf->size(), rv); 4749 4750 // Destroy the transaction. 4751 delete c; 4752 4753 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4754 4755 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4756 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4757 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4758 } 4759 4760 // Tests that we delete an entry when the request is cancelled if the response 4761 // has an "Accept-Ranges: none" header. 4762 TEST(HttpCache, DoomOnDestruction3) { 4763 MockHttpCache cache; 4764 4765 MockTransaction transaction(kSimpleGET_Transaction); 4766 transaction.response_headers = 4767 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 4768 "Content-Length: 22\n" 4769 "Accept-Ranges: none\n" 4770 "Etag: \"foopy\"\n"; 4771 AddMockTransaction(&transaction); 4772 MockHttpRequest request(transaction); 4773 4774 Context* c = new Context(); 4775 int rv = cache.http_cache()->CreateTransaction( 4776 net::DEFAULT_PRIORITY, &c->trans, NULL); 4777 EXPECT_EQ(net::OK, rv); 4778 4779 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4780 if (rv == net::ERR_IO_PENDING) 4781 rv = c->callback.WaitForResult(); 4782 4783 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4784 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4785 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4786 4787 // Make sure that the entry has some data stored. 4788 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4789 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4790 if (rv == net::ERR_IO_PENDING) 4791 rv = c->callback.WaitForResult(); 4792 EXPECT_EQ(buf->size(), rv); 4793 4794 // Destroy the transaction. 4795 delete c; 4796 4797 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4798 4799 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4800 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4801 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4802 4803 RemoveMockTransaction(&transaction); 4804 } 4805 4806 // Tests that we mark an entry as incomplete when the request is cancelled. 4807 TEST(HttpCache, SetTruncatedFlag) { 4808 MockHttpCache cache; 4809 4810 MockTransaction transaction(kSimpleGET_Transaction); 4811 transaction.response_headers = 4812 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 4813 "Content-Length: 22\n" 4814 "Etag: \"foopy\"\n"; 4815 AddMockTransaction(&transaction); 4816 MockHttpRequest request(transaction); 4817 4818 scoped_ptr<Context> c(new Context()); 4819 // We use a test delegate to ensure that after initiating destruction 4820 // of the transaction, no further delegate callbacks happen. 4821 // We initialize the TestHttpTransactionDelegate with the correct number of 4822 // cache actions and network actions to be reported. 4823 scoped_ptr<TestHttpTransactionDelegate> delegate( 4824 new TestHttpTransactionDelegate(7, 3)); 4825 int rv = cache.http_cache()->CreateTransaction( 4826 net::DEFAULT_PRIORITY, &c->trans, delegate.get()); 4827 EXPECT_EQ(net::OK, rv); 4828 4829 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4830 if (rv == net::ERR_IO_PENDING) 4831 rv = c->callback.WaitForResult(); 4832 4833 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4834 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4835 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4836 4837 // Make sure that the entry has some data stored. 4838 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4839 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4840 if (rv == net::ERR_IO_PENDING) 4841 rv = c->callback.WaitForResult(); 4842 EXPECT_EQ(buf->size(), rv); 4843 4844 // We want to cancel the request when the transaction is busy. 4845 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4846 EXPECT_EQ(net::ERR_IO_PENDING, rv); 4847 EXPECT_FALSE(c->callback.have_result()); 4848 4849 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL); 4850 int num_delegate_callbacks_before_destruction = 4851 delegate->num_callbacks_observed(); 4852 4853 // Destroy the transaction. 4854 c->trans.reset(); 4855 MockHttpCache::SetTestMode(0); 4856 4857 // Ensure the delegate received no callbacks during destruction. 4858 EXPECT_EQ(num_delegate_callbacks_before_destruction, 4859 delegate->num_callbacks_observed()); 4860 4861 // Since the transaction was aborted in the middle of network I/O, we will 4862 // manually call the delegate so that its pending I/O operation will be 4863 // closed (which is what the test delegate is expecting). 4864 delegate->OnNetworkActionFinish(); 4865 4866 // Make sure that we don't invoke the callback. We may have an issue if the 4867 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we 4868 // could end up with the transaction being deleted twice if we send any 4869 // notification from the transaction destructor (see http://crbug.com/31723). 4870 EXPECT_FALSE(c->callback.have_result()); 4871 4872 // Verify that the entry is marked as incomplete. 4873 disk_cache::Entry* entry; 4874 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); 4875 net::HttpResponseInfo response; 4876 bool truncated = false; 4877 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4878 EXPECT_TRUE(truncated); 4879 entry->Close(); 4880 4881 RemoveMockTransaction(&transaction); 4882 } 4883 4884 // Tests that we don't mark an entry as truncated when we read everything. 4885 TEST(HttpCache, DontSetTruncatedFlag) { 4886 MockHttpCache cache; 4887 4888 MockTransaction transaction(kSimpleGET_Transaction); 4889 transaction.response_headers = 4890 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 4891 "Content-Length: 22\n" 4892 "Etag: \"foopy\"\n"; 4893 AddMockTransaction(&transaction); 4894 MockHttpRequest request(transaction); 4895 4896 scoped_ptr<Context> c(new Context()); 4897 int rv = cache.http_cache()->CreateTransaction( 4898 net::DEFAULT_PRIORITY, &c->trans, NULL); 4899 EXPECT_EQ(net::OK, rv); 4900 4901 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 4902 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 4903 4904 // Read everything. 4905 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22)); 4906 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 4907 EXPECT_EQ(buf->size(), c->callback.GetResult(rv)); 4908 4909 // Destroy the transaction. 4910 c->trans.reset(); 4911 4912 // Verify that the entry is not marked as truncated. 4913 disk_cache::Entry* entry; 4914 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); 4915 net::HttpResponseInfo response; 4916 bool truncated = true; 4917 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4918 EXPECT_FALSE(truncated); 4919 entry->Close(); 4920 4921 RemoveMockTransaction(&transaction); 4922 } 4923 4924 // Tests that we can continue with a request that was interrupted. 4925 TEST(HttpCache, GET_IncompleteResource) { 4926 MockHttpCache cache; 4927 AddMockTransaction(&kRangeGET_TransactionOK); 4928 4929 std::string raw_headers("HTTP/1.1 200 OK\n" 4930 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 4931 "ETag: \"foo\"\n" 4932 "Accept-Ranges: bytes\n" 4933 "Content-Length: 80\n"); 4934 CreateTruncatedEntry(raw_headers, &cache); 4935 4936 // Now make a regular request. 4937 std::string headers; 4938 MockTransaction transaction(kRangeGET_TransactionOK); 4939 transaction.request_headers = EXTRA_HEADER; 4940 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 4941 "rg: 50-59 rg: 60-69 rg: 70-79 "; 4942 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4943 4944 // We update the headers with the ones received while revalidating. 4945 std::string expected_headers( 4946 "HTTP/1.1 200 OK\n" 4947 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 4948 "Accept-Ranges: bytes\n" 4949 "ETag: \"foo\"\n" 4950 "Content-Length: 80\n"); 4951 4952 EXPECT_EQ(expected_headers, headers); 4953 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4954 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4955 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4956 4957 // Verify that the disk entry was updated. 4958 disk_cache::Entry* entry; 4959 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4960 EXPECT_EQ(80, entry->GetDataSize(1)); 4961 bool truncated = true; 4962 net::HttpResponseInfo response; 4963 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4964 EXPECT_FALSE(truncated); 4965 entry->Close(); 4966 4967 RemoveMockTransaction(&kRangeGET_TransactionOK); 4968 } 4969 4970 // Tests the handling of no-store when revalidating a truncated entry. 4971 TEST(HttpCache, GET_IncompleteResource_NoStore) { 4972 MockHttpCache cache; 4973 AddMockTransaction(&kRangeGET_TransactionOK); 4974 4975 std::string raw_headers("HTTP/1.1 200 OK\n" 4976 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 4977 "ETag: \"foo\"\n" 4978 "Accept-Ranges: bytes\n" 4979 "Content-Length: 80\n"); 4980 CreateTruncatedEntry(raw_headers, &cache); 4981 RemoveMockTransaction(&kRangeGET_TransactionOK); 4982 4983 // Now make a regular request. 4984 MockTransaction transaction(kRangeGET_TransactionOK); 4985 transaction.request_headers = EXTRA_HEADER; 4986 std::string response_headers(transaction.response_headers); 4987 response_headers += ("Cache-Control: no-store\n"); 4988 transaction.response_headers = response_headers.c_str(); 4989 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 4990 "rg: 50-59 rg: 60-69 rg: 70-79 "; 4991 AddMockTransaction(&transaction); 4992 4993 std::string headers; 4994 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4995 4996 // We update the headers with the ones received while revalidating. 4997 std::string expected_headers( 4998 "HTTP/1.1 200 OK\n" 4999 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 5000 "Accept-Ranges: bytes\n" 5001 "Cache-Control: no-store\n" 5002 "ETag: \"foo\"\n" 5003 "Content-Length: 80\n"); 5004 5005 EXPECT_EQ(expected_headers, headers); 5006 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5007 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5008 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5009 5010 // Verify that the disk entry was deleted. 5011 disk_cache::Entry* entry; 5012 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 5013 RemoveMockTransaction(&transaction); 5014 } 5015 5016 // Tests cancelling a request after the server sent no-store. 5017 TEST(HttpCache, GET_IncompleteResource_Cancel) { 5018 MockHttpCache cache; 5019 AddMockTransaction(&kRangeGET_TransactionOK); 5020 5021 std::string raw_headers("HTTP/1.1 200 OK\n" 5022 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 5023 "ETag: \"foo\"\n" 5024 "Accept-Ranges: bytes\n" 5025 "Content-Length: 80\n"); 5026 CreateTruncatedEntry(raw_headers, &cache); 5027 RemoveMockTransaction(&kRangeGET_TransactionOK); 5028 5029 // Now make a regular request. 5030 MockTransaction transaction(kRangeGET_TransactionOK); 5031 transaction.request_headers = EXTRA_HEADER; 5032 std::string response_headers(transaction.response_headers); 5033 response_headers += ("Cache-Control: no-store\n"); 5034 transaction.response_headers = response_headers.c_str(); 5035 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 5036 "rg: 50-59 rg: 60-69 rg: 70-79 "; 5037 AddMockTransaction(&transaction); 5038 5039 MockHttpRequest request(transaction); 5040 Context* c = new Context(); 5041 5042 int rv = cache.http_cache()->CreateTransaction( 5043 net::DEFAULT_PRIORITY, &c->trans, NULL); 5044 EXPECT_EQ(net::OK, rv); 5045 5046 // Queue another request to this transaction. We have to start this request 5047 // before the first one gets the response from the server and dooms the entry, 5048 // otherwise it will just create a new entry without being queued to the first 5049 // request. 5050 Context* pending = new Context(); 5051 EXPECT_EQ(net::OK, 5052 cache.http_cache()->CreateTransaction( 5053 net::DEFAULT_PRIORITY, &pending->trans, NULL)); 5054 5055 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog()); 5056 EXPECT_EQ(net::ERR_IO_PENDING, 5057 pending->trans->Start(&request, pending->callback.callback(), 5058 net::BoundNetLog())); 5059 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 5060 5061 // Make sure that the entry has some data stored. 5062 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5)); 5063 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); 5064 EXPECT_EQ(5, c->callback.GetResult(rv)); 5065 5066 // Cancel the requests. 5067 delete c; 5068 delete pending; 5069 5070 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5071 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5072 EXPECT_EQ(2, cache.disk_cache()->create_count()); 5073 5074 base::MessageLoop::current()->RunUntilIdle(); 5075 RemoveMockTransaction(&transaction); 5076 } 5077 5078 // Tests that we delete truncated entries if the server changes its mind midway. 5079 TEST(HttpCache, GET_IncompleteResource2) { 5080 MockHttpCache cache; 5081 AddMockTransaction(&kRangeGET_TransactionOK); 5082 5083 // Content-length will be intentionally bad. 5084 std::string raw_headers("HTTP/1.1 200 OK\n" 5085 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 5086 "ETag: \"foo\"\n" 5087 "Accept-Ranges: bytes\n" 5088 "Content-Length: 50\n"); 5089 CreateTruncatedEntry(raw_headers, &cache); 5090 5091 // Now make a regular request. We expect the code to fail the validation and 5092 // retry the request without using byte ranges. 5093 std::string headers; 5094 MockTransaction transaction(kRangeGET_TransactionOK); 5095 transaction.request_headers = EXTRA_HEADER; 5096 transaction.data = "Not a range"; 5097 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 5098 5099 // The server will return 200 instead of a byte range. 5100 std::string expected_headers( 5101 "HTTP/1.1 200 OK\n" 5102 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); 5103 5104 EXPECT_EQ(expected_headers, headers); 5105 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5106 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5107 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5108 5109 // Verify that the disk entry was deleted. 5110 disk_cache::Entry* entry; 5111 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 5112 RemoveMockTransaction(&kRangeGET_TransactionOK); 5113 } 5114 5115 // Tests that we always validate a truncated request. 5116 TEST(HttpCache, GET_IncompleteResource3) { 5117 MockHttpCache cache; 5118 AddMockTransaction(&kRangeGET_TransactionOK); 5119 5120 // This should not require validation for 10 hours. 5121 std::string raw_headers("HTTP/1.1 200 OK\n" 5122 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 5123 "ETag: \"foo\"\n" 5124 "Cache-Control: max-age= 36000\n" 5125 "Accept-Ranges: bytes\n" 5126 "Content-Length: 80\n"); 5127 CreateTruncatedEntry(raw_headers, &cache); 5128 5129 // Now make a regular request. 5130 std::string headers; 5131 MockTransaction transaction(kRangeGET_TransactionOK); 5132 transaction.request_headers = EXTRA_HEADER; 5133 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 5134 "rg: 50-59 rg: 60-69 rg: 70-79 "; 5135 5136 scoped_ptr<Context> c(new Context); 5137 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction( 5138 net::DEFAULT_PRIORITY, &c->trans, NULL)); 5139 5140 MockHttpRequest request(transaction); 5141 int rv = c->trans->Start( 5142 &request, c->callback.callback(), net::BoundNetLog()); 5143 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 5144 5145 // We should have checked with the server before finishing Start(). 5146 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5147 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5148 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5149 5150 RemoveMockTransaction(&kRangeGET_TransactionOK); 5151 } 5152 5153 // Tests that we cache a 200 response to the validation request. 5154 TEST(HttpCache, GET_IncompleteResource4) { 5155 MockHttpCache cache; 5156 AddMockTransaction(&kRangeGET_TransactionOK); 5157 5158 std::string raw_headers("HTTP/1.1 200 OK\n" 5159 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 5160 "ETag: \"foo\"\n" 5161 "Accept-Ranges: bytes\n" 5162 "Content-Length: 80\n"); 5163 CreateTruncatedEntry(raw_headers, &cache); 5164 5165 // Now make a regular request. 5166 std::string headers; 5167 MockTransaction transaction(kRangeGET_TransactionOK); 5168 transaction.request_headers = EXTRA_HEADER; 5169 transaction.data = "Not a range"; 5170 RangeTransactionServer handler; 5171 handler.set_bad_200(true); 5172 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 5173 5174 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5175 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5176 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5177 5178 // Verify that the disk entry was updated. 5179 disk_cache::Entry* entry; 5180 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 5181 EXPECT_EQ(11, entry->GetDataSize(1)); 5182 bool truncated = true; 5183 net::HttpResponseInfo response; 5184 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 5185 EXPECT_FALSE(truncated); 5186 entry->Close(); 5187 5188 RemoveMockTransaction(&kRangeGET_TransactionOK); 5189 } 5190 5191 // Tests that when we cancel a request that was interrupted, we mark it again 5192 // as truncated. 5193 TEST(HttpCache, GET_CancelIncompleteResource) { 5194 MockHttpCache cache; 5195 AddMockTransaction(&kRangeGET_TransactionOK); 5196 5197 std::string raw_headers("HTTP/1.1 200 OK\n" 5198 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 5199 "ETag: \"foo\"\n" 5200 "Accept-Ranges: bytes\n" 5201 "Content-Length: 80\n"); 5202 CreateTruncatedEntry(raw_headers, &cache); 5203 5204 // Now make a regular request. 5205 MockTransaction transaction(kRangeGET_TransactionOK); 5206 transaction.request_headers = EXTRA_HEADER; 5207 5208 MockHttpRequest request(transaction); 5209 Context* c = new Context(); 5210 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction( 5211 net::DEFAULT_PRIORITY, &c->trans, NULL)); 5212 5213 int rv = c->trans->Start( 5214 &request, c->callback.callback(), net::BoundNetLog()); 5215 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 5216 5217 // Read 20 bytes from the cache, and 10 from the net. 5218 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); 5219 rv = c->trans->Read(buf.get(), 20, c->callback.callback()); 5220 EXPECT_EQ(20, c->callback.GetResult(rv)); 5221 rv = c->trans->Read(buf.get(), 10, c->callback.callback()); 5222 EXPECT_EQ(10, c->callback.GetResult(rv)); 5223 5224 // At this point, we are already reading so canceling the request should leave 5225 // a truncated one. 5226 delete c; 5227 5228 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5229 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5230 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5231 5232 // Verify that the disk entry was updated: now we have 30 bytes. 5233 disk_cache::Entry* entry; 5234 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 5235 EXPECT_EQ(30, entry->GetDataSize(1)); 5236 bool truncated = false; 5237 net::HttpResponseInfo response; 5238 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 5239 EXPECT_TRUE(truncated); 5240 entry->Close(); 5241 RemoveMockTransaction(&kRangeGET_TransactionOK); 5242 } 5243 5244 // Tests that we can handle range requests when we have a truncated entry. 5245 TEST(HttpCache, RangeGET_IncompleteResource) { 5246 MockHttpCache cache; 5247 AddMockTransaction(&kRangeGET_TransactionOK); 5248 5249 // Content-length will be intentionally bogus. 5250 std::string raw_headers("HTTP/1.1 200 OK\n" 5251 "Last-Modified: something\n" 5252 "ETag: \"foo\"\n" 5253 "Accept-Ranges: bytes\n" 5254 "Content-Length: 10\n"); 5255 CreateTruncatedEntry(raw_headers, &cache); 5256 5257 // Now make a range request. 5258 std::string headers; 5259 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 5260 &headers); 5261 5262 Verify206Response(headers, 40, 49); 5263 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5264 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5265 EXPECT_EQ(2, cache.disk_cache()->create_count()); 5266 5267 RemoveMockTransaction(&kRangeGET_TransactionOK); 5268 } 5269 5270 TEST(HttpCache, SyncRead) { 5271 MockHttpCache cache; 5272 5273 // This test ensures that a read that completes synchronously does not cause 5274 // any problems. 5275 5276 ScopedMockTransaction transaction(kSimpleGET_Transaction); 5277 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START | 5278 TEST_MODE_SYNC_CACHE_READ | 5279 TEST_MODE_SYNC_CACHE_WRITE); 5280 5281 MockHttpRequest r1(transaction), 5282 r2(transaction), 5283 r3(transaction); 5284 5285 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()), 5286 c2(net::DEFAULT_PRIORITY, cache.http_cache()), 5287 c3(net::DEFAULT_PRIORITY, cache.http_cache()); 5288 5289 c1.Start(&r1, net::BoundNetLog()); 5290 5291 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE; 5292 c2.Start(&r2, net::BoundNetLog()); 5293 5294 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE; 5295 c3.Start(&r3, net::BoundNetLog()); 5296 5297 base::MessageLoop::current()->Run(); 5298 5299 EXPECT_TRUE(c1.is_done()); 5300 EXPECT_TRUE(c2.is_done()); 5301 EXPECT_TRUE(c3.is_done()); 5302 5303 EXPECT_EQ(net::OK, c1.error()); 5304 EXPECT_EQ(net::OK, c2.error()); 5305 EXPECT_EQ(net::OK, c3.error()); 5306 } 5307 5308 TEST(HttpCache, ValidationResultsIn200) { 5309 MockHttpCache cache; 5310 5311 // This test ensures that a conditional request, which results in a 200 5312 // instead of a 304, properly truncates the existing response data. 5313 5314 // write to the cache 5315 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 5316 5317 // force this transaction to validate the cache 5318 MockTransaction transaction(kETagGET_Transaction); 5319 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 5320 RunTransactionTest(cache.http_cache(), transaction); 5321 5322 // read from the cache 5323 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 5324 } 5325 5326 TEST(HttpCache, CachedRedirect) { 5327 MockHttpCache cache; 5328 5329 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction); 5330 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently"; 5331 kTestTransaction.response_headers = "Location: http://www.bar.com/\n"; 5332 5333 MockHttpRequest request(kTestTransaction); 5334 net::TestCompletionCallback callback; 5335 5336 // write to the cache 5337 { 5338 scoped_ptr<net::HttpTransaction> trans; 5339 int rv = cache.http_cache()->CreateTransaction( 5340 net::DEFAULT_PRIORITY, &trans, NULL); 5341 EXPECT_EQ(net::OK, rv); 5342 ASSERT_TRUE(trans.get()); 5343 5344 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5345 if (rv == net::ERR_IO_PENDING) 5346 rv = callback.WaitForResult(); 5347 ASSERT_EQ(net::OK, rv); 5348 5349 const net::HttpResponseInfo* info = trans->GetResponseInfo(); 5350 ASSERT_TRUE(info); 5351 5352 EXPECT_EQ(info->headers->response_code(), 301); 5353 5354 std::string location; 5355 info->headers->EnumerateHeader(NULL, "Location", &location); 5356 EXPECT_EQ(location, "http://www.bar.com/"); 5357 5358 // Destroy transaction when going out of scope. We have not actually 5359 // read the response body -- want to test that it is still getting cached. 5360 } 5361 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5362 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5363 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5364 5365 // read from the cache 5366 { 5367 scoped_ptr<net::HttpTransaction> trans; 5368 int rv = cache.http_cache()->CreateTransaction( 5369 net::DEFAULT_PRIORITY, &trans, NULL); 5370 EXPECT_EQ(net::OK, rv); 5371 ASSERT_TRUE(trans.get()); 5372 5373 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5374 if (rv == net::ERR_IO_PENDING) 5375 rv = callback.WaitForResult(); 5376 ASSERT_EQ(net::OK, rv); 5377 5378 const net::HttpResponseInfo* info = trans->GetResponseInfo(); 5379 ASSERT_TRUE(info); 5380 5381 EXPECT_EQ(info->headers->response_code(), 301); 5382 5383 std::string location; 5384 info->headers->EnumerateHeader(NULL, "Location", &location); 5385 EXPECT_EQ(location, "http://www.bar.com/"); 5386 5387 // Destroy transaction when going out of scope. We have not actually 5388 // read the response body -- want to test that it is still getting cached. 5389 } 5390 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5391 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5392 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5393 } 5394 5395 TEST(HttpCache, CacheControlNoStore) { 5396 MockHttpCache cache; 5397 5398 ScopedMockTransaction transaction(kSimpleGET_Transaction); 5399 transaction.response_headers = "cache-control: no-store\n"; 5400 5401 // initial load 5402 RunTransactionTest(cache.http_cache(), transaction); 5403 5404 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5405 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5406 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5407 5408 // try loading again; it should result in a network fetch 5409 RunTransactionTest(cache.http_cache(), transaction); 5410 5411 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5412 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5413 EXPECT_EQ(2, cache.disk_cache()->create_count()); 5414 5415 disk_cache::Entry* entry; 5416 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry)); 5417 } 5418 5419 TEST(HttpCache, CacheControlNoStore2) { 5420 // this test is similar to the above test, except that the initial response 5421 // is cachable, but when it is validated, no-store is received causing the 5422 // cached document to be deleted. 5423 MockHttpCache cache; 5424 5425 ScopedMockTransaction transaction(kETagGET_Transaction); 5426 5427 // initial load 5428 RunTransactionTest(cache.http_cache(), transaction); 5429 5430 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5431 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5432 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5433 5434 // try loading again; it should result in a network fetch 5435 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 5436 transaction.response_headers = "cache-control: no-store\n"; 5437 RunTransactionTest(cache.http_cache(), transaction); 5438 5439 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5440 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5441 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5442 5443 disk_cache::Entry* entry; 5444 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry)); 5445 } 5446 5447 TEST(HttpCache, CacheControlNoStore3) { 5448 // this test is similar to the above test, except that the response is a 304 5449 // instead of a 200. this should never happen in practice, but it seems like 5450 // a good thing to verify that we still destroy the cache entry. 5451 MockHttpCache cache; 5452 5453 ScopedMockTransaction transaction(kETagGET_Transaction); 5454 5455 // initial load 5456 RunTransactionTest(cache.http_cache(), transaction); 5457 5458 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5459 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5460 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5461 5462 // try loading again; it should result in a network fetch 5463 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 5464 transaction.response_headers = "cache-control: no-store\n"; 5465 transaction.status = "HTTP/1.1 304 Not Modified"; 5466 RunTransactionTest(cache.http_cache(), transaction); 5467 5468 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5469 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5470 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5471 5472 disk_cache::Entry* entry; 5473 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry)); 5474 } 5475 5476 // Ensure that we don't cache requests served over bad HTTPS. 5477 TEST(HttpCache, SimpleGET_SSLError) { 5478 MockHttpCache cache; 5479 5480 MockTransaction transaction = kSimpleGET_Transaction; 5481 transaction.cert_status = net::CERT_STATUS_REVOKED; 5482 ScopedMockTransaction scoped_transaction(transaction); 5483 5484 // write to the cache 5485 RunTransactionTest(cache.http_cache(), transaction); 5486 5487 // Test that it was not cached. 5488 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 5489 5490 MockHttpRequest request(transaction); 5491 net::TestCompletionCallback callback; 5492 5493 scoped_ptr<net::HttpTransaction> trans; 5494 int rv = cache.http_cache()->CreateTransaction( 5495 net::DEFAULT_PRIORITY, &trans, NULL); 5496 EXPECT_EQ(net::OK, rv); 5497 ASSERT_TRUE(trans.get()); 5498 5499 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5500 if (rv == net::ERR_IO_PENDING) 5501 rv = callback.WaitForResult(); 5502 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 5503 } 5504 5505 // Ensure that we don't crash by if left-behind transactions. 5506 TEST(HttpCache, OutlivedTransactions) { 5507 MockHttpCache* cache = new MockHttpCache; 5508 5509 scoped_ptr<net::HttpTransaction> trans; 5510 int rv = cache->http_cache()->CreateTransaction( 5511 net::DEFAULT_PRIORITY, &trans, NULL); 5512 EXPECT_EQ(net::OK, rv); 5513 5514 delete cache; 5515 trans.reset(); 5516 } 5517 5518 // Test that the disabled mode works. 5519 TEST(HttpCache, CacheDisabledMode) { 5520 MockHttpCache cache; 5521 5522 // write to the cache 5523 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 5524 5525 // go into disabled mode 5526 cache.http_cache()->set_mode(net::HttpCache::DISABLE); 5527 5528 // force this transaction to write to the cache again 5529 MockTransaction transaction(kSimpleGET_Transaction); 5530 5531 RunTransactionTest(cache.http_cache(), transaction); 5532 5533 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5534 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5535 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5536 } 5537 5538 // Other tests check that the response headers of the cached response 5539 // get updated on 304. Here we specifically check that the 5540 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time 5541 // fields also gets updated. 5542 // http://crbug.com/20594. 5543 TEST(HttpCache, UpdatesRequestResponseTimeOn304) { 5544 MockHttpCache cache; 5545 5546 const char* kUrl = "http://foobar"; 5547 const char* kData = "body"; 5548 5549 MockTransaction mock_network_response = { 0 }; 5550 mock_network_response.url = kUrl; 5551 5552 AddMockTransaction(&mock_network_response); 5553 5554 // Request |kUrl|, causing |kNetResponse1| to be written to the cache. 5555 5556 MockTransaction request = { 0 }; 5557 request.url = kUrl; 5558 request.method = "GET"; 5559 request.request_headers = "\r\n"; 5560 request.data = kData; 5561 5562 static const Response kNetResponse1 = { 5563 "HTTP/1.1 200 OK", 5564 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 5565 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 5566 kData 5567 }; 5568 5569 kNetResponse1.AssignTo(&mock_network_response); 5570 5571 RunTransactionTest(cache.http_cache(), request); 5572 5573 // Request |kUrl| again, this time validating the cache and getting 5574 // a 304 back. 5575 5576 request.load_flags = net::LOAD_VALIDATE_CACHE; 5577 5578 static const Response kNetResponse2 = { 5579 "HTTP/1.1 304 Not Modified", 5580 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n", 5581 "" 5582 }; 5583 5584 kNetResponse2.AssignTo(&mock_network_response); 5585 5586 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234); 5587 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235); 5588 5589 mock_network_response.request_time = request_time; 5590 mock_network_response.response_time = response_time; 5591 5592 net::HttpResponseInfo response; 5593 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response); 5594 5595 // The request and response times should have been updated. 5596 EXPECT_EQ(request_time.ToInternalValue(), 5597 response.request_time.ToInternalValue()); 5598 EXPECT_EQ(response_time.ToInternalValue(), 5599 response.response_time.ToInternalValue()); 5600 5601 std::string headers; 5602 response.headers->GetNormalizedHeaders(&headers); 5603 5604 EXPECT_EQ("HTTP/1.1 200 OK\n" 5605 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 5606 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 5607 headers); 5608 5609 RemoveMockTransaction(&mock_network_response); 5610 } 5611 5612 // Tests that we can write metadata to an entry. 5613 TEST(HttpCache, WriteMetadata_OK) { 5614 MockHttpCache cache; 5615 5616 // Write to the cache 5617 net::HttpResponseInfo response; 5618 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 5619 &response); 5620 EXPECT_TRUE(response.metadata.get() == NULL); 5621 5622 // Trivial call. 5623 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY, 5624 Time::Now(), NULL, 0); 5625 5626 // Write meta data to the same entry. 5627 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50)); 5628 memset(buf->data(), 0, buf->size()); 5629 base::strlcpy(buf->data(), "Hi there", buf->size()); 5630 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), 5631 net::DEFAULT_PRIORITY, 5632 response.response_time, 5633 buf.get(), 5634 buf->size()); 5635 5636 // Release the buffer before the operation takes place. 5637 buf = NULL; 5638 5639 // Makes sure we finish pending operations. 5640 base::MessageLoop::current()->RunUntilIdle(); 5641 5642 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 5643 &response); 5644 ASSERT_TRUE(response.metadata.get() != NULL); 5645 EXPECT_EQ(50, response.metadata->size()); 5646 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there")); 5647 5648 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5649 EXPECT_EQ(2, cache.disk_cache()->open_count()); 5650 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5651 } 5652 5653 // Tests that we only write metadata to an entry if the time stamp matches. 5654 TEST(HttpCache, WriteMetadata_Fail) { 5655 MockHttpCache cache; 5656 5657 // Write to the cache 5658 net::HttpResponseInfo response; 5659 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 5660 &response); 5661 EXPECT_TRUE(response.metadata.get() == NULL); 5662 5663 // Attempt to write meta data to the same entry. 5664 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50)); 5665 memset(buf->data(), 0, buf->size()); 5666 base::strlcpy(buf->data(), "Hi there", buf->size()); 5667 base::Time expected_time = response.response_time - 5668 base::TimeDelta::FromMilliseconds(20); 5669 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), 5670 net::DEFAULT_PRIORITY, 5671 expected_time, 5672 buf.get(), 5673 buf->size()); 5674 5675 // Makes sure we finish pending operations. 5676 base::MessageLoop::current()->RunUntilIdle(); 5677 5678 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 5679 &response); 5680 EXPECT_TRUE(response.metadata.get() == NULL); 5681 5682 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5683 EXPECT_EQ(2, cache.disk_cache()->open_count()); 5684 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5685 } 5686 5687 // Tests that we can read metadata after validating the entry and with READ mode 5688 // transactions. 5689 TEST(HttpCache, ReadMetadata) { 5690 MockHttpCache cache; 5691 5692 // Write to the cache 5693 net::HttpResponseInfo response; 5694 RunTransactionTestWithResponseInfo(cache.http_cache(), 5695 kTypicalGET_Transaction, &response); 5696 EXPECT_TRUE(response.metadata.get() == NULL); 5697 5698 // Write meta data to the same entry. 5699 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50)); 5700 memset(buf->data(), 0, buf->size()); 5701 base::strlcpy(buf->data(), "Hi there", buf->size()); 5702 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url), 5703 net::DEFAULT_PRIORITY, 5704 response.response_time, 5705 buf.get(), 5706 buf->size()); 5707 5708 // Makes sure we finish pending operations. 5709 base::MessageLoop::current()->RunUntilIdle(); 5710 5711 // Start with a READ mode transaction. 5712 MockTransaction trans1(kTypicalGET_Transaction); 5713 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE; 5714 5715 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response); 5716 ASSERT_TRUE(response.metadata.get() != NULL); 5717 EXPECT_EQ(50, response.metadata->size()); 5718 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there")); 5719 5720 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5721 EXPECT_EQ(2, cache.disk_cache()->open_count()); 5722 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5723 base::MessageLoop::current()->RunUntilIdle(); 5724 5725 // Now make sure that the entry is re-validated with the server. 5726 trans1.load_flags = net::LOAD_VALIDATE_CACHE; 5727 trans1.status = "HTTP/1.1 304 Not Modified"; 5728 AddMockTransaction(&trans1); 5729 5730 response.metadata = NULL; 5731 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response); 5732 EXPECT_TRUE(response.metadata.get() != NULL); 5733 5734 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5735 EXPECT_EQ(3, cache.disk_cache()->open_count()); 5736 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5737 base::MessageLoop::current()->RunUntilIdle(); 5738 RemoveMockTransaction(&trans1); 5739 5740 // Now return 200 when validating the entry so the metadata will be lost. 5741 MockTransaction trans2(kTypicalGET_Transaction); 5742 trans2.load_flags = net::LOAD_VALIDATE_CACHE; 5743 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response); 5744 EXPECT_TRUE(response.metadata.get() == NULL); 5745 5746 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 5747 EXPECT_EQ(4, cache.disk_cache()->open_count()); 5748 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5749 } 5750 5751 // Tests that we don't mark entries as truncated when a filter detects the end 5752 // of the stream. 5753 TEST(HttpCache, FilterCompletion) { 5754 MockHttpCache cache; 5755 net::TestCompletionCallback callback; 5756 5757 { 5758 scoped_ptr<net::HttpTransaction> trans; 5759 int rv = cache.http_cache()->CreateTransaction( 5760 net::DEFAULT_PRIORITY, &trans, NULL); 5761 EXPECT_EQ(net::OK, rv); 5762 5763 MockHttpRequest request(kSimpleGET_Transaction); 5764 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5765 EXPECT_EQ(net::OK, callback.GetResult(rv)); 5766 5767 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 5768 rv = trans->Read(buf.get(), 256, callback.callback()); 5769 EXPECT_GT(callback.GetResult(rv), 0); 5770 5771 // Now make sure that the entry is preserved. 5772 trans->DoneReading(); 5773 } 5774 5775 // Make sure that the ActiveEntry is gone. 5776 base::MessageLoop::current()->RunUntilIdle(); 5777 5778 // Read from the cache. 5779 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 5780 5781 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 5782 EXPECT_EQ(1, cache.disk_cache()->open_count()); 5783 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5784 } 5785 5786 // Tests that we stop cachining when told. 5787 TEST(HttpCache, StopCachingDeletesEntry) { 5788 MockHttpCache cache; 5789 net::TestCompletionCallback callback; 5790 MockHttpRequest request(kSimpleGET_Transaction); 5791 5792 { 5793 scoped_ptr<net::HttpTransaction> trans; 5794 int rv = cache.http_cache()->CreateTransaction( 5795 net::DEFAULT_PRIORITY, &trans, NULL); 5796 EXPECT_EQ(net::OK, rv); 5797 5798 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5799 EXPECT_EQ(net::OK, callback.GetResult(rv)); 5800 5801 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 5802 rv = trans->Read(buf.get(), 10, callback.callback()); 5803 EXPECT_EQ(callback.GetResult(rv), 10); 5804 5805 trans->StopCaching(); 5806 5807 // We should be able to keep reading. 5808 rv = trans->Read(buf.get(), 256, callback.callback()); 5809 EXPECT_GT(callback.GetResult(rv), 0); 5810 rv = trans->Read(buf.get(), 256, callback.callback()); 5811 EXPECT_EQ(callback.GetResult(rv), 0); 5812 } 5813 5814 // Make sure that the ActiveEntry is gone. 5815 base::MessageLoop::current()->RunUntilIdle(); 5816 5817 // Verify that the entry is gone. 5818 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 5819 5820 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5821 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5822 EXPECT_EQ(2, cache.disk_cache()->create_count()); 5823 } 5824 5825 // Tests that when we are told to stop caching we don't throw away valid data. 5826 TEST(HttpCache, StopCachingSavesEntry) { 5827 MockHttpCache cache; 5828 net::TestCompletionCallback callback; 5829 MockHttpRequest request(kSimpleGET_Transaction); 5830 5831 { 5832 scoped_ptr<net::HttpTransaction> trans; 5833 int rv = cache.http_cache()->CreateTransaction( 5834 net::DEFAULT_PRIORITY, &trans, NULL); 5835 EXPECT_EQ(net::OK, rv); 5836 5837 // Force a response that can be resumed. 5838 MockTransaction mock_transaction(kSimpleGET_Transaction); 5839 AddMockTransaction(&mock_transaction); 5840 mock_transaction.response_headers = "Cache-Control: max-age=10000\n" 5841 "Content-Length: 42\n" 5842 "Etag: \"foo\"\n"; 5843 5844 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5845 EXPECT_EQ(net::OK, callback.GetResult(rv)); 5846 5847 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 5848 rv = trans->Read(buf.get(), 10, callback.callback()); 5849 EXPECT_EQ(callback.GetResult(rv), 10); 5850 5851 trans->StopCaching(); 5852 5853 // We should be able to keep reading. 5854 rv = trans->Read(buf.get(), 256, callback.callback()); 5855 EXPECT_GT(callback.GetResult(rv), 0); 5856 rv = trans->Read(buf.get(), 256, callback.callback()); 5857 EXPECT_EQ(callback.GetResult(rv), 0); 5858 5859 RemoveMockTransaction(&mock_transaction); 5860 } 5861 5862 // Verify that the entry is marked as incomplete. 5863 disk_cache::Entry* entry; 5864 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); 5865 net::HttpResponseInfo response; 5866 bool truncated = false; 5867 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 5868 EXPECT_TRUE(truncated); 5869 entry->Close(); 5870 } 5871 5872 // Tests that we handle truncated enries when StopCaching is called. 5873 TEST(HttpCache, StopCachingTruncatedEntry) { 5874 MockHttpCache cache; 5875 net::TestCompletionCallback callback; 5876 MockHttpRequest request(kRangeGET_TransactionOK); 5877 request.extra_headers.Clear(); 5878 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); 5879 AddMockTransaction(&kRangeGET_TransactionOK); 5880 5881 std::string raw_headers("HTTP/1.1 200 OK\n" 5882 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 5883 "ETag: \"foo\"\n" 5884 "Accept-Ranges: bytes\n" 5885 "Content-Length: 80\n"); 5886 CreateTruncatedEntry(raw_headers, &cache); 5887 5888 { 5889 // Now make a regular request. 5890 scoped_ptr<net::HttpTransaction> trans; 5891 int rv = cache.http_cache()->CreateTransaction( 5892 net::DEFAULT_PRIORITY, &trans, NULL); 5893 EXPECT_EQ(net::OK, rv); 5894 5895 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); 5896 EXPECT_EQ(net::OK, callback.GetResult(rv)); 5897 5898 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 5899 rv = trans->Read(buf.get(), 10, callback.callback()); 5900 EXPECT_EQ(callback.GetResult(rv), 10); 5901 5902 // This is actually going to do nothing. 5903 trans->StopCaching(); 5904 5905 // We should be able to keep reading. 5906 rv = trans->Read(buf.get(), 256, callback.callback()); 5907 EXPECT_GT(callback.GetResult(rv), 0); 5908 rv = trans->Read(buf.get(), 256, callback.callback()); 5909 EXPECT_GT(callback.GetResult(rv), 0); 5910 rv = trans->Read(buf.get(), 256, callback.callback()); 5911 EXPECT_EQ(callback.GetResult(rv), 0); 5912 } 5913 5914 // Verify that the disk entry was updated. 5915 disk_cache::Entry* entry; 5916 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 5917 EXPECT_EQ(80, entry->GetDataSize(1)); 5918 bool truncated = true; 5919 net::HttpResponseInfo response; 5920 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 5921 EXPECT_FALSE(truncated); 5922 entry->Close(); 5923 5924 RemoveMockTransaction(&kRangeGET_TransactionOK); 5925 } 5926 5927 // Tests that we detect truncated resources from the net when there is 5928 // a Content-Length header. 5929 TEST(HttpCache, TruncatedByContentLength) { 5930 MockHttpCache cache; 5931 net::TestCompletionCallback callback; 5932 5933 MockTransaction transaction(kSimpleGET_Transaction); 5934 AddMockTransaction(&transaction); 5935 transaction.response_headers = "Cache-Control: max-age=10000\n" 5936 "Content-Length: 100\n"; 5937 RunTransactionTest(cache.http_cache(), transaction); 5938 RemoveMockTransaction(&transaction); 5939 5940 // Read from the cache. 5941 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 5942 5943 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5944 EXPECT_EQ(0, cache.disk_cache()->open_count()); 5945 EXPECT_EQ(2, cache.disk_cache()->create_count()); 5946 } 5947 5948 // Tests that we actually flag entries as truncated when we detect an error 5949 // from the net. 5950 TEST(HttpCache, TruncatedByContentLength2) { 5951 MockHttpCache cache; 5952 net::TestCompletionCallback callback; 5953 5954 MockTransaction transaction(kSimpleGET_Transaction); 5955 AddMockTransaction(&transaction); 5956 transaction.response_headers = "Cache-Control: max-age=10000\n" 5957 "Content-Length: 100\n" 5958 "Etag: \"foo\"\n"; 5959 RunTransactionTest(cache.http_cache(), transaction); 5960 RemoveMockTransaction(&transaction); 5961 5962 // Verify that the entry is marked as incomplete. 5963 disk_cache::Entry* entry; 5964 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); 5965 net::HttpResponseInfo response; 5966 bool truncated = false; 5967 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 5968 EXPECT_TRUE(truncated); 5969 entry->Close(); 5970 } 5971 5972 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit_TransactionDelegate) { 5973 MockHttpCache cache; 5974 5975 // Write to the cache. 5976 RunTransactionTestWithDelegate(cache.http_cache(), 5977 kSimpleGET_Transaction, 5978 8, 5979 3); 5980 5981 // Force this transaction to read from the cache. 5982 MockTransaction transaction(kSimpleGET_Transaction); 5983 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 5984 5985 RunTransactionTestWithDelegate(cache.http_cache(), 5986 kSimpleGET_Transaction, 5987 5, 5988 0); 5989 } 5990 5991 // Make sure that calling SetPriority on a cache transaction passes on 5992 // its priority updates to its underlying network transaction. 5993 TEST(HttpCache, SetPriority) { 5994 MockHttpCache cache; 5995 5996 scoped_ptr<net::HttpTransaction> trans; 5997 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction( 5998 net::IDLE, &trans, NULL)); 5999 ASSERT_TRUE(trans.get()); 6000 6001 // Shouldn't crash, but doesn't do anything either. 6002 trans->SetPriority(net::LOW); 6003 6004 EXPECT_FALSE(cache.network_layer()->last_transaction()); 6005 EXPECT_EQ(net::DEFAULT_PRIORITY, 6006 cache.network_layer()->last_create_transaction_priority()); 6007 6008 net::HttpRequestInfo info; 6009 info.url = GURL(kSimpleGET_Transaction.url); 6010 net::TestCompletionCallback callback; 6011 EXPECT_EQ(net::ERR_IO_PENDING, 6012 trans->Start(&info, callback.callback(), net::BoundNetLog())); 6013 6014 EXPECT_TRUE(cache.network_layer()->last_transaction()); 6015 if (cache.network_layer()->last_transaction()) { 6016 EXPECT_EQ(net::LOW, 6017 cache.network_layer()->last_create_transaction_priority()); 6018 EXPECT_EQ(net::LOW, 6019 cache.network_layer()->last_transaction()->priority()); 6020 } 6021 6022 trans->SetPriority(net::HIGHEST); 6023 6024 if (cache.network_layer()->last_transaction()) { 6025 EXPECT_EQ(net::LOW, 6026 cache.network_layer()->last_create_transaction_priority()); 6027 EXPECT_EQ(net::HIGHEST, 6028 cache.network_layer()->last_transaction()->priority()); 6029 } 6030 6031 EXPECT_EQ(net::OK, callback.WaitForResult()); 6032 } 6033 6034 // Make sure that a cache transaction passes on its priority to 6035 // newly-created network transactions. 6036 TEST(HttpCache, SetPriorityNewTransaction) { 6037 MockHttpCache cache; 6038 AddMockTransaction(&kRangeGET_TransactionOK); 6039 6040 std::string raw_headers("HTTP/1.1 200 OK\n" 6041 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 6042 "ETag: \"foo\"\n" 6043 "Accept-Ranges: bytes\n" 6044 "Content-Length: 80\n"); 6045 CreateTruncatedEntry(raw_headers, &cache); 6046 6047 // Now make a regular request. 6048 std::string headers; 6049 MockTransaction transaction(kRangeGET_TransactionOK); 6050 transaction.request_headers = EXTRA_HEADER; 6051 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 6052 "rg: 50-59 rg: 60-69 rg: 70-79 "; 6053 6054 scoped_ptr<net::HttpTransaction> trans; 6055 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction( 6056 net::MEDIUM, &trans, NULL)); 6057 ASSERT_TRUE(trans.get()); 6058 EXPECT_EQ(net::DEFAULT_PRIORITY, 6059 cache.network_layer()->last_create_transaction_priority()); 6060 6061 MockHttpRequest info(transaction); 6062 net::TestCompletionCallback callback; 6063 EXPECT_EQ(net::ERR_IO_PENDING, 6064 trans->Start(&info, callback.callback(), net::BoundNetLog())); 6065 EXPECT_EQ(net::OK, callback.WaitForResult()); 6066 6067 EXPECT_EQ(net::MEDIUM, 6068 cache.network_layer()->last_create_transaction_priority()); 6069 6070 trans->SetPriority(net::HIGHEST); 6071 // Should trigger a new network transaction and pick up the new 6072 // priority. 6073 ReadAndVerifyTransaction(trans.get(), transaction); 6074 6075 EXPECT_EQ(net::HIGHEST, 6076 cache.network_layer()->last_create_transaction_priority()); 6077 6078 RemoveMockTransaction(&kRangeGET_TransactionOK); 6079 } 6080