1 // Copyright (c) 2011 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/hash_tables.h" 8 #include "base/memory/scoped_vector.h" 9 #include "base/message_loop.h" 10 #include "base/string_util.h" 11 #include "base/stringprintf.h" 12 #include "net/base/cache_type.h" 13 #include "net/base/cert_status_flags.h" 14 #include "net/base/host_port_pair.h" 15 #include "net/base/load_flags.h" 16 #include "net/base/net_errors.h" 17 #include "net/base/net_log_unittest.h" 18 #include "net/base/ssl_cert_request_info.h" 19 #include "net/disk_cache/disk_cache.h" 20 #include "net/http/http_byte_range.h" 21 #include "net/http/http_request_headers.h" 22 #include "net/http/http_request_info.h" 23 #include "net/http/http_response_headers.h" 24 #include "net/http/http_response_info.h" 25 #include "net/http/http_transaction.h" 26 #include "net/http/http_transaction_unittest.h" 27 #include "net/http/http_util.h" 28 #include "testing/gtest/include/gtest/gtest.h" 29 30 using base::Time; 31 32 namespace { 33 34 int GetTestModeForEntry(const std::string& key) { 35 // 'key' is prefixed with an identifier if it corresponds to a cached POST. 36 // Skip past that to locate the actual URL. 37 // 38 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an 39 // URL corresponding to a registered MockTransaction. It would be good to 40 // have another way to access the test_mode. 41 GURL url; 42 if (isdigit(key[0])) { 43 size_t slash = key.find('/'); 44 DCHECK(slash != std::string::npos); 45 url = GURL(key.substr(slash + 1)); 46 } else { 47 url = GURL(key); 48 } 49 const MockTransaction* t = FindMockTransaction(url); 50 DCHECK(t); 51 return t->test_mode; 52 } 53 54 // We can override the test mode for a given operation by setting this global 55 // variable. Just remember to reset it after the test!. 56 int g_test_mode = 0; 57 58 // Returns the test mode after considering the global override. 59 int GetEffectiveTestMode(int test_mode) { 60 if (!g_test_mode) 61 return test_mode; 62 63 return g_test_mode; 64 } 65 66 //----------------------------------------------------------------------------- 67 // mock disk cache (a very basic memory cache implementation) 68 69 static const int kNumCacheEntryDataIndices = 3; 70 71 class MockDiskEntry : public disk_cache::Entry, 72 public base::RefCounted<MockDiskEntry> { 73 public: 74 MockDiskEntry() 75 : test_mode_(0), doomed_(false), sparse_(false), fail_requests_(false), 76 busy_(false), delayed_(false) { 77 } 78 79 explicit MockDiskEntry(const std::string& key) 80 : key_(key), doomed_(false), sparse_(false), fail_requests_(false), 81 busy_(false), delayed_(false) { 82 test_mode_ = GetTestModeForEntry(key); 83 } 84 85 bool is_doomed() const { return doomed_; } 86 87 virtual void Doom() { 88 doomed_ = true; 89 } 90 91 virtual void Close() { 92 Release(); 93 } 94 95 virtual std::string GetKey() const { 96 if (fail_requests_) 97 return std::string(); 98 return key_; 99 } 100 101 virtual Time GetLastUsed() const { 102 return Time::FromInternalValue(0); 103 } 104 105 virtual Time GetLastModified() const { 106 return Time::FromInternalValue(0); 107 } 108 109 virtual int32 GetDataSize(int index) const { 110 DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); 111 return static_cast<int32>(data_[index].size()); 112 } 113 114 virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, 115 net::CompletionCallback* callback) { 116 DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); 117 DCHECK(callback); 118 119 if (fail_requests_) 120 return net::ERR_CACHE_READ_FAILURE; 121 122 if (offset < 0 || offset > static_cast<int>(data_[index].size())) 123 return net::ERR_FAILED; 124 if (static_cast<size_t>(offset) == data_[index].size()) 125 return 0; 126 127 int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); 128 memcpy(buf->data(), &data_[index][offset], num); 129 130 if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) 131 return num; 132 133 CallbackLater(callback, num); 134 return net::ERR_IO_PENDING; 135 } 136 137 virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, 138 net::CompletionCallback* callback, bool truncate) { 139 DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); 140 DCHECK(callback); 141 DCHECK(truncate); 142 143 if (fail_requests_) { 144 CallbackLater(callback, net::ERR_CACHE_READ_FAILURE); 145 return net::ERR_IO_PENDING; 146 } 147 148 if (offset < 0 || offset > static_cast<int>(data_[index].size())) 149 return net::ERR_FAILED; 150 151 data_[index].resize(offset + buf_len); 152 if (buf_len) 153 memcpy(&data_[index][offset], buf->data(), buf_len); 154 155 if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE) 156 return buf_len; 157 158 CallbackLater(callback, buf_len); 159 return net::ERR_IO_PENDING; 160 } 161 162 virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, 163 net::CompletionCallback* callback) { 164 DCHECK(callback); 165 if (!sparse_ || busy_) 166 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 167 if (offset < 0) 168 return net::ERR_FAILED; 169 170 if (fail_requests_) 171 return net::ERR_CACHE_READ_FAILURE; 172 173 DCHECK(offset < kint32max); 174 int real_offset = static_cast<int>(offset); 175 if (!buf_len) 176 return 0; 177 178 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, 179 buf_len); 180 memcpy(buf->data(), &data_[1][real_offset], num); 181 182 if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) 183 return num; 184 185 CallbackLater(callback, num); 186 busy_ = true; 187 delayed_ = false; 188 return net::ERR_IO_PENDING; 189 } 190 191 virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, 192 net::CompletionCallback* callback) { 193 DCHECK(callback); 194 if (busy_) 195 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 196 if (!sparse_) { 197 if (data_[1].size()) 198 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 199 sparse_ = true; 200 } 201 if (offset < 0) 202 return net::ERR_FAILED; 203 if (!buf_len) 204 return 0; 205 206 if (fail_requests_) 207 return net::ERR_CACHE_READ_FAILURE; 208 209 DCHECK(offset < kint32max); 210 int real_offset = static_cast<int>(offset); 211 212 if (static_cast<int>(data_[1].size()) < real_offset + buf_len) 213 data_[1].resize(real_offset + buf_len); 214 215 memcpy(&data_[1][real_offset], buf->data(), buf_len); 216 if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE) 217 return buf_len; 218 219 CallbackLater(callback, buf_len); 220 return net::ERR_IO_PENDING; 221 } 222 223 virtual int GetAvailableRange(int64 offset, int len, int64* start, 224 net::CompletionCallback* callback) { 225 DCHECK(callback); 226 if (!sparse_ || busy_) 227 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 228 if (offset < 0) 229 return net::ERR_FAILED; 230 231 if (fail_requests_) 232 return net::ERR_CACHE_READ_FAILURE; 233 234 *start = offset; 235 DCHECK(offset < kint32max); 236 int real_offset = static_cast<int>(offset); 237 if (static_cast<int>(data_[1].size()) < real_offset) 238 return 0; 239 240 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len); 241 int count = 0; 242 for (; num > 0; num--, real_offset++) { 243 if (!count) { 244 if (data_[1][real_offset]) { 245 count++; 246 *start = real_offset; 247 } 248 } else { 249 if (!data_[1][real_offset]) 250 break; 251 count++; 252 } 253 } 254 if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE) 255 return count; 256 257 CallbackLater(callback, count); 258 return net::ERR_IO_PENDING; 259 } 260 261 virtual bool CouldBeSparse() const { 262 return sparse_; 263 } 264 265 virtual void CancelSparseIO() { cancel_ = true; } 266 267 virtual int ReadyForSparseIO(net::CompletionCallback* completion_callback) { 268 if (!cancel_) 269 return net::OK; 270 271 cancel_ = false; 272 DCHECK(completion_callback); 273 if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) 274 return net::OK; 275 276 // The pending operation is already in the message loop (and hopefuly 277 // already in the second pass). Just notify the caller that it finished. 278 CallbackLater(completion_callback, 0); 279 return net::ERR_IO_PENDING; 280 } 281 282 // Fail most subsequent requests. 283 void set_fail_requests() { fail_requests_ = true; } 284 285 // If |value| is true, don't deliver any completion callbacks until called 286 // again with |value| set to false. Caution: remember to enable callbacks 287 // again or all subsequent tests will fail. 288 static void IgnoreCallbacks(bool value) { 289 if (ignore_callbacks_ == value) 290 return; 291 ignore_callbacks_ = value; 292 if (!value) 293 StoreAndDeliverCallbacks(false, NULL, NULL, 0); 294 } 295 296 private: 297 friend class base::RefCounted<MockDiskEntry>; 298 299 struct CallbackInfo { 300 scoped_refptr<MockDiskEntry> entry; 301 net::CompletionCallback* callback; 302 int result; 303 }; 304 305 ~MockDiskEntry() {} 306 307 // Unlike the callbacks for MockHttpTransaction, we want this one to run even 308 // if the consumer called Close on the MockDiskEntry. We achieve that by 309 // leveraging the fact that this class is reference counted. 310 void CallbackLater(net::CompletionCallback* callback, int result) { 311 if (ignore_callbacks_) 312 return StoreAndDeliverCallbacks(true, this, callback, result); 313 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 314 this, &MockDiskEntry::RunCallback, callback, result)); 315 } 316 void RunCallback(net::CompletionCallback* callback, int result) { 317 if (busy_) { 318 // This is kind of hacky, but controlling the behavior of just this entry 319 // from a test is sort of complicated. What we really want to do is 320 // delay the delivery of a sparse IO operation a little more so that the 321 // request start operation (async) will finish without seeing the end of 322 // this operation (already posted to the message loop)... and without 323 // just delaying for n mS (which may cause trouble with slow bots). So 324 // we re-post this operation (all async sparse IO operations will take two 325 // trips trhough the message loop instead of one). 326 if (!delayed_) { 327 delayed_ = true; 328 return CallbackLater(callback, result); 329 } 330 } 331 busy_ = false; 332 callback->Run(result); 333 } 334 335 // When |store| is true, stores the callback to be delivered later; otherwise 336 // delivers any callback previously stored. 337 static void StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry, 338 net::CompletionCallback* callback, 339 int result) { 340 static std::vector<CallbackInfo> callback_list; 341 if (store) { 342 CallbackInfo c = {entry, callback, result}; 343 callback_list.push_back(c); 344 } else { 345 for (size_t i = 0; i < callback_list.size(); i++) { 346 CallbackInfo& c = callback_list[i]; 347 c.entry->CallbackLater(c.callback, c.result); 348 } 349 callback_list.clear(); 350 } 351 } 352 353 std::string key_; 354 std::vector<char> data_[kNumCacheEntryDataIndices]; 355 int test_mode_; 356 bool doomed_; 357 bool sparse_; 358 bool fail_requests_; 359 bool busy_; 360 bool delayed_; 361 static bool cancel_; 362 static bool ignore_callbacks_; 363 }; 364 365 // Statics. 366 bool MockDiskEntry::cancel_ = false; 367 bool MockDiskEntry::ignore_callbacks_ = false; 368 369 class MockDiskCache : public disk_cache::Backend { 370 public: 371 MockDiskCache() 372 : open_count_(0), create_count_(0), fail_requests_(false), 373 soft_failures_(false) { 374 } 375 376 ~MockDiskCache() { 377 ReleaseAll(); 378 } 379 380 virtual int32 GetEntryCount() const { 381 return static_cast<int32>(entries_.size()); 382 } 383 384 virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry, 385 net::CompletionCallback* callback) { 386 DCHECK(callback); 387 if (fail_requests_) 388 return net::ERR_CACHE_OPEN_FAILURE; 389 390 EntryMap::iterator it = entries_.find(key); 391 if (it == entries_.end()) 392 return net::ERR_CACHE_OPEN_FAILURE; 393 394 if (it->second->is_doomed()) { 395 it->second->Release(); 396 entries_.erase(it); 397 return net::ERR_CACHE_OPEN_FAILURE; 398 } 399 400 open_count_++; 401 402 it->second->AddRef(); 403 *entry = it->second; 404 405 if (soft_failures_) 406 it->second->set_fail_requests(); 407 408 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) 409 return net::OK; 410 411 CallbackLater(callback, net::OK); 412 return net::ERR_IO_PENDING; 413 } 414 415 virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, 416 net::CompletionCallback* callback) { 417 DCHECK(callback); 418 if (fail_requests_) 419 return net::ERR_CACHE_CREATE_FAILURE; 420 421 EntryMap::iterator it = entries_.find(key); 422 if (it != entries_.end()) { 423 DCHECK(it->second->is_doomed()); 424 it->second->Release(); 425 entries_.erase(it); 426 } 427 428 create_count_++; 429 430 MockDiskEntry* new_entry = new MockDiskEntry(key); 431 432 new_entry->AddRef(); 433 entries_[key] = new_entry; 434 435 new_entry->AddRef(); 436 *entry = new_entry; 437 438 if (soft_failures_) 439 new_entry->set_fail_requests(); 440 441 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) 442 return net::OK; 443 444 CallbackLater(callback, net::OK); 445 return net::ERR_IO_PENDING; 446 } 447 448 virtual int DoomEntry(const std::string& key, 449 net::CompletionCallback* callback) { 450 DCHECK(callback); 451 EntryMap::iterator it = entries_.find(key); 452 if (it != entries_.end()) { 453 it->second->Release(); 454 entries_.erase(it); 455 } 456 457 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) 458 return net::OK; 459 460 CallbackLater(callback, net::OK); 461 return net::ERR_IO_PENDING; 462 } 463 464 virtual int DoomAllEntries(net::CompletionCallback* callback) { 465 return net::ERR_NOT_IMPLEMENTED; 466 } 467 468 virtual int DoomEntriesBetween(const base::Time initial_time, 469 const base::Time end_time, 470 net::CompletionCallback* callback) { 471 return net::ERR_NOT_IMPLEMENTED; 472 } 473 474 virtual int DoomEntriesSince(const base::Time initial_time, 475 net::CompletionCallback* callback) { 476 return net::ERR_NOT_IMPLEMENTED; 477 } 478 479 virtual int OpenNextEntry(void** iter, disk_cache::Entry** next_entry, 480 net::CompletionCallback* callback) { 481 return net::ERR_NOT_IMPLEMENTED; 482 } 483 484 virtual void EndEnumeration(void** iter) {} 485 486 virtual void GetStats( 487 std::vector<std::pair<std::string, std::string> >* stats) { 488 } 489 490 // returns number of times a cache entry was successfully opened 491 int open_count() const { return open_count_; } 492 493 // returns number of times a cache entry was successfully created 494 int create_count() const { return create_count_; } 495 496 // Fail any subsequent CreateEntry and OpenEntry. 497 void set_fail_requests() { fail_requests_ = true; } 498 499 // Return entries that fail some of their requests. 500 void set_soft_failures(bool value) { soft_failures_ = value; } 501 502 void ReleaseAll() { 503 EntryMap::iterator it = entries_.begin(); 504 for (; it != entries_.end(); ++it) 505 it->second->Release(); 506 entries_.clear(); 507 } 508 509 private: 510 typedef base::hash_map<std::string, MockDiskEntry*> EntryMap; 511 512 class CallbackRunner : public Task { 513 public: 514 CallbackRunner(net::CompletionCallback* callback, int result) 515 : callback_(callback), result_(result) {} 516 virtual void Run() { 517 callback_->Run(result_); 518 } 519 520 private: 521 net::CompletionCallback* callback_; 522 int result_; 523 DISALLOW_COPY_AND_ASSIGN(CallbackRunner); 524 }; 525 526 void CallbackLater(net::CompletionCallback* callback, int result) { 527 MessageLoop::current()->PostTask(FROM_HERE, 528 new CallbackRunner(callback, result)); 529 } 530 531 EntryMap entries_; 532 int open_count_; 533 int create_count_; 534 bool fail_requests_; 535 bool soft_failures_; 536 }; 537 538 class MockBackendFactory : public net::HttpCache::BackendFactory { 539 public: 540 virtual int CreateBackend(net::NetLog* /* net_log */, 541 disk_cache::Backend** backend, 542 net::CompletionCallback* callback) { 543 *backend = new MockDiskCache(); 544 return net::OK; 545 } 546 }; 547 548 class MockHttpCache { 549 public: 550 MockHttpCache() 551 : http_cache_(new MockNetworkLayer(), NULL, new MockBackendFactory()) { 552 } 553 554 explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory) 555 : http_cache_(new MockNetworkLayer(), NULL, disk_cache_factory) { 556 } 557 558 net::HttpCache* http_cache() { return &http_cache_; } 559 560 MockNetworkLayer* network_layer() { 561 return static_cast<MockNetworkLayer*>(http_cache_.network_layer()); 562 } 563 MockDiskCache* disk_cache() { 564 TestCompletionCallback cb; 565 disk_cache::Backend* backend; 566 int rv = http_cache_.GetBackend(&backend, &cb); 567 rv = cb.GetResult(rv); 568 return (rv == net::OK) ? static_cast<MockDiskCache*>(backend) : NULL; 569 } 570 571 // Helper function for reading response info from the disk cache. 572 static bool ReadResponseInfo(disk_cache::Entry* disk_entry, 573 net::HttpResponseInfo* response_info, 574 bool* response_truncated) { 575 int size = disk_entry->GetDataSize(0); 576 577 TestCompletionCallback cb; 578 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size)); 579 int rv = disk_entry->ReadData(0, 0, buffer, size, &cb); 580 rv = cb.GetResult(rv); 581 EXPECT_EQ(size, rv); 582 583 return net::HttpCache::ParseResponseInfo(buffer->data(), size, 584 response_info, 585 response_truncated); 586 } 587 588 // Helper function for writing response info into the disk cache. 589 static bool WriteResponseInfo(disk_cache::Entry* disk_entry, 590 const net::HttpResponseInfo* response_info, 591 bool skip_transient_headers, 592 bool response_truncated) { 593 Pickle pickle; 594 response_info->Persist( 595 &pickle, skip_transient_headers, response_truncated); 596 597 TestCompletionCallback cb; 598 scoped_refptr<net::WrappedIOBuffer> data(new net::WrappedIOBuffer( 599 reinterpret_cast<const char*>(pickle.data()))); 600 int len = static_cast<int>(pickle.size()); 601 602 int rv = disk_entry->WriteData(0, 0, data, len, &cb, true); 603 rv = cb.GetResult(rv); 604 return (rv == len); 605 } 606 607 // Helper function to synchronously open a backend entry. 608 bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry) { 609 TestCompletionCallback cb; 610 int rv = disk_cache()->OpenEntry(key, entry, &cb); 611 return (cb.GetResult(rv) == net::OK); 612 } 613 614 // Helper function to synchronously create a backend entry. 615 bool CreateBackendEntry(const std::string& key, disk_cache::Entry** entry, 616 net::NetLog* /* net_log */) { 617 TestCompletionCallback cb; 618 int rv = disk_cache()->CreateEntry(key, entry, &cb); 619 return (cb.GetResult(rv) == net::OK); 620 } 621 622 private: 623 net::HttpCache http_cache_; 624 }; 625 626 // This version of the disk cache doesn't invoke CreateEntry callbacks. 627 class MockDiskCacheNoCB : public MockDiskCache { 628 virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, 629 net::CompletionCallback* callback) { 630 return net::ERR_IO_PENDING; 631 } 632 }; 633 634 class MockBackendNoCbFactory : public net::HttpCache::BackendFactory { 635 public: 636 virtual int CreateBackend(net::NetLog* /* net_log */, 637 disk_cache::Backend** backend, 638 net::CompletionCallback* callback) { 639 *backend = new MockDiskCacheNoCB(); 640 return net::OK; 641 } 642 }; 643 644 // This backend factory allows us to control the backend instantiation. 645 class MockBlockingBackendFactory : public net::HttpCache::BackendFactory { 646 public: 647 MockBlockingBackendFactory() 648 : backend_(NULL), callback_(NULL), block_(true), fail_(false) {} 649 650 virtual int CreateBackend(net::NetLog* /* net_log */, 651 disk_cache::Backend** backend, 652 net::CompletionCallback* callback) { 653 if (!block_) { 654 if (!fail_) 655 *backend = new MockDiskCache(); 656 return Result(); 657 } 658 659 backend_ = backend; 660 callback_ = callback; 661 return net::ERR_IO_PENDING; 662 } 663 664 // Completes the backend creation. Any blocked call will be notified via the 665 // provided callback. 666 void FinishCreation() { 667 block_ = false; 668 if (callback_) { 669 if (!fail_) 670 *backend_ = new MockDiskCache(); 671 net::CompletionCallback* cb = callback_; 672 callback_ = NULL; 673 cb->Run(Result()); // This object can be deleted here. 674 } 675 } 676 677 disk_cache::Backend** backend() { return backend_; } 678 void set_fail(bool fail) { fail_ = fail; } 679 680 net::CompletionCallback* callback() { return callback_; } 681 682 private: 683 int Result() { return fail_ ? net::ERR_FAILED : net::OK; } 684 685 disk_cache::Backend** backend_; 686 net::CompletionCallback* callback_; 687 bool block_; 688 bool fail_; 689 }; 690 691 class DeleteCacheCompletionCallback : public TestCompletionCallback { 692 public: 693 explicit DeleteCacheCompletionCallback(MockHttpCache* cache) 694 : cache_(cache) {} 695 696 virtual void RunWithParams(const Tuple1<int>& params) { 697 delete cache_; 698 TestCompletionCallback::RunWithParams(params); 699 } 700 701 private: 702 MockHttpCache* cache_; 703 }; 704 705 //----------------------------------------------------------------------------- 706 // helpers 707 708 void ReadAndVerifyTransaction(net::HttpTransaction* trans, 709 const MockTransaction& trans_info) { 710 std::string content; 711 int rv = ReadTransaction(trans, &content); 712 713 EXPECT_EQ(net::OK, rv); 714 std::string expected(trans_info.data); 715 EXPECT_EQ(expected, content); 716 } 717 718 void RunTransactionTestWithRequestAndLog(net::HttpCache* cache, 719 const MockTransaction& trans_info, 720 const MockHttpRequest& request, 721 net::HttpResponseInfo* response_info, 722 const net::BoundNetLog& net_log) { 723 TestCompletionCallback callback; 724 725 // write to the cache 726 727 scoped_ptr<net::HttpTransaction> trans; 728 int rv = cache->CreateTransaction(&trans); 729 EXPECT_EQ(net::OK, rv); 730 ASSERT_TRUE(trans.get()); 731 732 rv = trans->Start(&request, &callback, net_log); 733 if (rv == net::ERR_IO_PENDING) 734 rv = callback.WaitForResult(); 735 ASSERT_EQ(net::OK, rv); 736 737 const net::HttpResponseInfo* response = trans->GetResponseInfo(); 738 ASSERT_TRUE(response); 739 740 if (response_info) 741 *response_info = *response; 742 743 ReadAndVerifyTransaction(trans.get(), trans_info); 744 } 745 746 void RunTransactionTestWithRequest(net::HttpCache* cache, 747 const MockTransaction& trans_info, 748 const MockHttpRequest& request, 749 net::HttpResponseInfo* response_info) { 750 RunTransactionTestWithRequestAndLog(cache, trans_info, request, 751 response_info, net::BoundNetLog()); 752 } 753 754 void RunTransactionTestWithLog(net::HttpCache* cache, 755 const MockTransaction& trans_info, 756 const net::BoundNetLog& log) { 757 RunTransactionTestWithRequestAndLog( 758 cache, trans_info, MockHttpRequest(trans_info), NULL, log); 759 } 760 761 void RunTransactionTest(net::HttpCache* cache, 762 const MockTransaction& trans_info) { 763 RunTransactionTestWithLog(cache, trans_info, net::BoundNetLog()); 764 } 765 766 void RunTransactionTestWithResponseInfo(net::HttpCache* cache, 767 const MockTransaction& trans_info, 768 net::HttpResponseInfo* response) { 769 RunTransactionTestWithRequest( 770 cache, trans_info, MockHttpRequest(trans_info), response); 771 } 772 773 void RunTransactionTestWithResponse(net::HttpCache* cache, 774 const MockTransaction& trans_info, 775 std::string* response_headers) { 776 net::HttpResponseInfo response; 777 RunTransactionTestWithResponseInfo(cache, trans_info, &response); 778 response.headers->GetNormalizedHeaders(response_headers); 779 } 780 781 // This class provides a handler for kFastNoStoreGET_Transaction so that the 782 // no-store header can be included on demand. 783 class FastTransactionServer { 784 public: 785 FastTransactionServer() { 786 no_store = false; 787 } 788 ~FastTransactionServer() {} 789 790 void set_no_store(bool value) { no_store = value; } 791 792 static void FastNoStoreHandler(const net::HttpRequestInfo* request, 793 std::string* response_status, 794 std::string* response_headers, 795 std::string* response_data) { 796 if (no_store) 797 *response_headers = "Cache-Control: no-store\n"; 798 } 799 800 private: 801 static bool no_store; 802 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer); 803 }; 804 bool FastTransactionServer::no_store; 805 806 const MockTransaction kFastNoStoreGET_Transaction = { 807 "http://www.google.com/nostore", 808 "GET", 809 base::Time(), 810 "", 811 net::LOAD_VALIDATE_CACHE, 812 "HTTP/1.1 200 OK", 813 "Cache-Control: max-age=10000\n", 814 base::Time(), 815 "<html><body>Google Blah Blah</body></html>", 816 TEST_MODE_SYNC_NET_START, 817 &FastTransactionServer::FastNoStoreHandler, 818 0 819 }; 820 821 // This class provides a handler for kRangeGET_TransactionOK so that the range 822 // request can be served on demand. 823 class RangeTransactionServer { 824 public: 825 RangeTransactionServer() { 826 not_modified_ = false; 827 modified_ = false; 828 bad_200_ = false; 829 } 830 ~RangeTransactionServer() { 831 not_modified_ = false; 832 modified_ = false; 833 bad_200_ = false; 834 } 835 836 // Returns only 416 or 304 when set. 837 void set_not_modified(bool value) { not_modified_ = value; } 838 839 // Returns 206 when revalidating a range (instead of 304). 840 void set_modified(bool value) { modified_ = value; } 841 842 // Returns 200 instead of 206 (a malformed response overall). 843 void set_bad_200(bool value) { bad_200_ = value; } 844 845 static void RangeHandler(const net::HttpRequestInfo* request, 846 std::string* response_status, 847 std::string* response_headers, 848 std::string* response_data); 849 850 private: 851 static bool not_modified_; 852 static bool modified_; 853 static bool bad_200_; 854 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); 855 }; 856 bool RangeTransactionServer::not_modified_ = false; 857 bool RangeTransactionServer::modified_ = false; 858 bool RangeTransactionServer::bad_200_ = false; 859 860 // A dummy extra header that must be preserved on a given request. 861 #define EXTRA_HEADER "Extra: header" 862 static const char kExtraHeaderKey[] = "Extra"; 863 864 // Static. 865 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, 866 std::string* response_status, 867 std::string* response_headers, 868 std::string* response_data) { 869 if (request->extra_headers.IsEmpty()) { 870 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); 871 response_data->clear(); 872 return; 873 } 874 875 // We want to make sure we don't delete extra headers. 876 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); 877 878 if (not_modified_) { 879 response_status->assign("HTTP/1.1 304 Not Modified"); 880 response_data->clear(); 881 return; 882 } 883 884 std::vector<net::HttpByteRange> ranges; 885 std::string range_header; 886 if (!request->extra_headers.GetHeader( 887 net::HttpRequestHeaders::kRange, &range_header) || 888 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || 889 ranges.size() != 1) { 890 // This is not a byte range request. We return 200. 891 response_status->assign("HTTP/1.1 200 OK"); 892 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); 893 response_data->assign("Not a range"); 894 return; 895 } 896 897 // We can handle this range request. 898 net::HttpByteRange byte_range = ranges[0]; 899 if (byte_range.first_byte_position() > 79) { 900 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); 901 response_data->clear(); 902 return; 903 } 904 905 EXPECT_TRUE(byte_range.ComputeBounds(80)); 906 int start = static_cast<int>(byte_range.first_byte_position()); 907 int end = static_cast<int>(byte_range.last_byte_position()); 908 909 EXPECT_LT(end, 80); 910 911 std::string content_range = base::StringPrintf( 912 "Content-Range: bytes %d-%d/80\n", start, end); 913 response_headers->append(content_range); 914 915 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) { 916 std::string data; 917 if (end == start) { 918 EXPECT_EQ(0, end % 10); 919 data = "r"; 920 } else { 921 EXPECT_EQ(9, (end - start) % 10); 922 for (int block_start = start; block_start < end; block_start += 10) { 923 base::StringAppendF(&data, "rg: %02d-%02d ", 924 block_start, block_start + 9); 925 } 926 } 927 *response_data = data; 928 929 if (end - start != 9) { 930 // We also have to fix content-length. 931 int len = end - start + 1; 932 std::string content_length = base::StringPrintf("Content-Length: %d\n", 933 len); 934 response_headers->replace(response_headers->find("Content-Length:"), 935 content_length.size(), content_length); 936 } 937 } else { 938 response_status->assign("HTTP/1.1 304 Not Modified"); 939 response_data->clear(); 940 } 941 } 942 943 const MockTransaction kRangeGET_TransactionOK = { 944 "http://www.google.com/range", 945 "GET", 946 base::Time(), 947 "Range: bytes = 40-49\r\n" 948 EXTRA_HEADER, 949 net::LOAD_NORMAL, 950 "HTTP/1.1 206 Partial Content", 951 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 952 "ETag: \"foo\"\n" 953 "Accept-Ranges: bytes\n" 954 "Content-Length: 10\n", 955 base::Time(), 956 "rg: 40-49 ", 957 TEST_MODE_NORMAL, 958 &RangeTransactionServer::RangeHandler, 959 0 960 }; 961 962 // Verifies the response headers (|response|) match a partial content 963 // response for the range starting at |start| and ending at |end|. 964 void Verify206Response(std::string response, int start, int end) { 965 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), 966 response.size())); 967 scoped_refptr<net::HttpResponseHeaders> headers( 968 new net::HttpResponseHeaders(raw_headers)); 969 970 ASSERT_EQ(206, headers->response_code()); 971 972 int64 range_start, range_end, object_size; 973 ASSERT_TRUE( 974 headers->GetContentRange(&range_start, &range_end, &object_size)); 975 int64 content_length = headers->GetContentLength(); 976 977 int length = end - start + 1; 978 ASSERT_EQ(length, content_length); 979 ASSERT_EQ(start, range_start); 980 ASSERT_EQ(end, range_end); 981 } 982 983 // Creates a truncated entry that can be resumed using byte ranges. 984 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) { 985 // Create a disk cache entry that stores an incomplete resource. 986 disk_cache::Entry* entry; 987 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, 988 NULL)); 989 990 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 991 raw_headers.size()); 992 993 net::HttpResponseInfo response; 994 response.response_time = base::Time::Now(); 995 response.request_time = base::Time::Now(); 996 response.headers = new net::HttpResponseHeaders(raw_headers); 997 // Set the last argument for this to be an incomplete request. 998 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); 999 1000 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); 1001 int len = static_cast<int>(base::strlcpy(buf->data(), 1002 "rg: 00-09 rg: 10-19 ", 100)); 1003 TestCompletionCallback cb; 1004 int rv = entry->WriteData(1, 0, buf, len, &cb, true); 1005 EXPECT_EQ(len, cb.GetResult(rv)); 1006 entry->Close(); 1007 } 1008 1009 // Helper to represent a network HTTP response. 1010 struct Response { 1011 // Set this response into |trans|. 1012 void AssignTo(MockTransaction* trans) const { 1013 trans->status = status; 1014 trans->response_headers = headers; 1015 trans->data = body; 1016 } 1017 1018 std::string status_and_headers() const { 1019 return std::string(status) + "\n" + std::string(headers); 1020 } 1021 1022 const char* status; 1023 const char* headers; 1024 const char* body; 1025 }; 1026 1027 struct Context { 1028 Context() : result(net::ERR_IO_PENDING) {} 1029 1030 int result; 1031 TestCompletionCallback callback; 1032 scoped_ptr<net::HttpTransaction> trans; 1033 }; 1034 1035 } // namespace 1036 1037 1038 //----------------------------------------------------------------------------- 1039 // tests 1040 1041 TEST(HttpCache, CreateThenDestroy) { 1042 MockHttpCache cache; 1043 1044 scoped_ptr<net::HttpTransaction> trans; 1045 int rv = cache.http_cache()->CreateTransaction(&trans); 1046 EXPECT_EQ(net::OK, rv); 1047 ASSERT_TRUE(trans.get()); 1048 } 1049 1050 TEST(HttpCache, GetBackend) { 1051 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0)); 1052 1053 disk_cache::Backend* backend; 1054 TestCompletionCallback cb; 1055 // This will lazily initialize the backend. 1056 int rv = cache.http_cache()->GetBackend(&backend, &cb); 1057 EXPECT_EQ(net::OK, cb.GetResult(rv)); 1058 } 1059 1060 TEST(HttpCache, SimpleGET) { 1061 MockHttpCache cache; 1062 1063 // write to the cache 1064 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1065 1066 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1067 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1068 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1069 } 1070 1071 TEST(HttpCache, SimpleGETNoDiskCache) { 1072 MockHttpCache cache; 1073 1074 cache.disk_cache()->set_fail_requests(); 1075 1076 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded); 1077 log.SetLogLevel(net::NetLog::LOG_BASIC); 1078 1079 // Read from the network, and don't use the cache. 1080 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction, 1081 log.bound()); 1082 1083 // Check that the NetLog was filled as expected. 1084 // (We attempted to both Open and Create entries, but both failed). 1085 net::CapturingNetLog::EntryList entries; 1086 log.GetEntries(&entries); 1087 1088 EXPECT_EQ(6u, entries.size()); 1089 EXPECT_TRUE(net::LogContainsBeginEvent( 1090 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1091 EXPECT_TRUE(net::LogContainsEndEvent( 1092 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1093 EXPECT_TRUE(net::LogContainsBeginEvent( 1094 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 1095 EXPECT_TRUE(net::LogContainsEndEvent( 1096 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 1097 EXPECT_TRUE(net::LogContainsBeginEvent( 1098 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1099 EXPECT_TRUE(net::LogContainsEndEvent( 1100 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1101 1102 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1103 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1104 EXPECT_EQ(0, cache.disk_cache()->create_count()); 1105 } 1106 1107 TEST(HttpCache, SimpleGETNoDiskCache2) { 1108 // This will initialize a cache object with NULL backend. 1109 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 1110 factory->set_fail(true); 1111 factory->FinishCreation(); // We'll complete synchronously. 1112 MockHttpCache cache(factory); 1113 1114 // Read from the network, and don't use the cache. 1115 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1116 1117 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1118 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend()); 1119 } 1120 1121 TEST(HttpCache, SimpleGETWithDiskFailures) { 1122 MockHttpCache cache; 1123 1124 cache.disk_cache()->set_soft_failures(true); 1125 1126 // Read from the network, and fail to write to the cache. 1127 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1128 1129 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1130 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1131 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1132 1133 // This one should see an empty cache again. 1134 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1135 1136 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1137 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1138 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1139 } 1140 1141 // Tests that disk failures after the transaction has started don't cause the 1142 // request to fail. 1143 TEST(HttpCache, SimpleGETWithDiskFailures2) { 1144 MockHttpCache cache; 1145 1146 MockHttpRequest request(kSimpleGET_Transaction); 1147 1148 scoped_ptr<Context> c(new Context()); 1149 int rv = cache.http_cache()->CreateTransaction(&c->trans); 1150 EXPECT_EQ(net::OK, rv); 1151 1152 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1153 EXPECT_EQ(net::ERR_IO_PENDING, rv); 1154 rv = c->callback.WaitForResult(); 1155 1156 // Start failing request now. 1157 cache.disk_cache()->set_soft_failures(true); 1158 1159 // We have to open the entry again to propagate the failure flag. 1160 disk_cache::Entry* en; 1161 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en)); 1162 en->Close(); 1163 1164 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1165 c.reset(); 1166 1167 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1168 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1169 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1170 1171 // This one should see an empty cache again. 1172 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1173 1174 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1175 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1176 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1177 } 1178 1179 // Tests that we don't crash after failures to read from the cache. 1180 TEST(HttpCache, SimpleGETWithDiskFailures3) { 1181 MockHttpCache cache; 1182 1183 // Read from the network, and write to the cache. 1184 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1185 1186 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1187 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1188 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1189 1190 cache.disk_cache()->set_soft_failures(true); 1191 1192 // Now fail to read from the cache. 1193 scoped_ptr<Context> c(new Context()); 1194 int rv = cache.http_cache()->CreateTransaction(&c->trans); 1195 EXPECT_EQ(net::OK, rv); 1196 1197 MockHttpRequest request(kSimpleGET_Transaction); 1198 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1199 EXPECT_EQ(net::ERR_CACHE_READ_FAILURE, c->callback.GetResult(rv)); 1200 } 1201 1202 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) { 1203 MockHttpCache cache; 1204 1205 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded); 1206 1207 // This prevents a number of write events from being logged. 1208 log.SetLogLevel(net::NetLog::LOG_BASIC); 1209 1210 // write to the cache 1211 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction, 1212 log.bound()); 1213 1214 // Check that the NetLog was filled as expected. 1215 net::CapturingNetLog::EntryList entries; 1216 log.GetEntries(&entries); 1217 1218 EXPECT_EQ(8u, entries.size()); 1219 EXPECT_TRUE(net::LogContainsBeginEvent( 1220 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1221 EXPECT_TRUE(net::LogContainsEndEvent( 1222 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1223 EXPECT_TRUE(net::LogContainsBeginEvent( 1224 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 1225 EXPECT_TRUE(net::LogContainsEndEvent( 1226 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 1227 EXPECT_TRUE(net::LogContainsBeginEvent( 1228 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1229 EXPECT_TRUE(net::LogContainsEndEvent( 1230 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1231 EXPECT_TRUE(net::LogContainsBeginEvent( 1232 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1233 EXPECT_TRUE(net::LogContainsEndEvent( 1234 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1235 1236 // force this transaction to read from the cache 1237 MockTransaction transaction(kSimpleGET_Transaction); 1238 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 1239 1240 log.Clear(); 1241 1242 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound()); 1243 1244 // Check that the NetLog was filled as expected. 1245 log.GetEntries(&entries); 1246 1247 EXPECT_EQ(8u, entries.size()); 1248 EXPECT_TRUE(net::LogContainsBeginEvent( 1249 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1250 EXPECT_TRUE(net::LogContainsEndEvent( 1251 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1252 EXPECT_TRUE(net::LogContainsBeginEvent( 1253 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 1254 EXPECT_TRUE(net::LogContainsEndEvent( 1255 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY)); 1256 EXPECT_TRUE(net::LogContainsBeginEvent( 1257 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1258 EXPECT_TRUE(net::LogContainsEndEvent( 1259 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1260 EXPECT_TRUE(net::LogContainsBeginEvent( 1261 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO)); 1262 EXPECT_TRUE(net::LogContainsEndEvent( 1263 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO)); 1264 1265 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1266 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1267 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1268 } 1269 1270 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) { 1271 MockHttpCache cache; 1272 1273 // force this transaction to read from the cache 1274 MockTransaction transaction(kSimpleGET_Transaction); 1275 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 1276 1277 MockHttpRequest request(transaction); 1278 TestCompletionCallback callback; 1279 1280 scoped_ptr<net::HttpTransaction> trans; 1281 int rv = cache.http_cache()->CreateTransaction(&trans); 1282 EXPECT_EQ(net::OK, rv); 1283 ASSERT_TRUE(trans.get()); 1284 1285 rv = trans->Start(&request, &callback, net::BoundNetLog()); 1286 if (rv == net::ERR_IO_PENDING) 1287 rv = callback.WaitForResult(); 1288 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 1289 1290 trans.reset(); 1291 1292 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 1293 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1294 EXPECT_EQ(0, cache.disk_cache()->create_count()); 1295 } 1296 1297 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) { 1298 MockHttpCache cache; 1299 1300 // write to the cache 1301 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1302 1303 // force this transaction to read from the cache if valid 1304 MockTransaction transaction(kSimpleGET_Transaction); 1305 transaction.load_flags |= net::LOAD_PREFERRING_CACHE; 1306 1307 RunTransactionTest(cache.http_cache(), transaction); 1308 1309 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1310 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1311 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1312 } 1313 1314 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) { 1315 MockHttpCache cache; 1316 1317 // force this transaction to read from the cache if valid 1318 MockTransaction transaction(kSimpleGET_Transaction); 1319 transaction.load_flags |= net::LOAD_PREFERRING_CACHE; 1320 1321 RunTransactionTest(cache.http_cache(), transaction); 1322 1323 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1324 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1325 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1326 } 1327 1328 TEST(HttpCache, SimpleGET_LoadBypassCache) { 1329 MockHttpCache cache; 1330 1331 // Write to the cache. 1332 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1333 1334 // Force this transaction to write to the cache again. 1335 MockTransaction transaction(kSimpleGET_Transaction); 1336 transaction.load_flags |= net::LOAD_BYPASS_CACHE; 1337 1338 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded); 1339 1340 // This prevents a number of write events from being logged. 1341 log.SetLogLevel(net::NetLog::LOG_BASIC); 1342 1343 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound()); 1344 1345 // Check that the NetLog was filled as expected. 1346 net::CapturingNetLog::EntryList entries; 1347 log.GetEntries(&entries); 1348 1349 EXPECT_EQ(8u, entries.size()); 1350 EXPECT_TRUE(net::LogContainsBeginEvent( 1351 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1352 EXPECT_TRUE(net::LogContainsEndEvent( 1353 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND)); 1354 EXPECT_TRUE(net::LogContainsBeginEvent( 1355 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY)); 1356 EXPECT_TRUE(net::LogContainsEndEvent( 1357 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY)); 1358 EXPECT_TRUE(net::LogContainsBeginEvent( 1359 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1360 EXPECT_TRUE(net::LogContainsEndEvent( 1361 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY)); 1362 EXPECT_TRUE(net::LogContainsBeginEvent( 1363 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1364 EXPECT_TRUE(net::LogContainsEndEvent( 1365 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY)); 1366 1367 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1368 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1369 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1370 } 1371 1372 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) { 1373 MockHttpCache cache; 1374 1375 // write to the cache 1376 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1377 1378 // force this transaction to write to the cache again 1379 MockTransaction transaction(kSimpleGET_Transaction); 1380 transaction.request_headers = "pragma: no-cache"; 1381 1382 RunTransactionTest(cache.http_cache(), transaction); 1383 1384 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1385 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1386 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1387 } 1388 1389 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) { 1390 MockHttpCache cache; 1391 1392 // write to the cache 1393 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1394 1395 // force this transaction to write to the cache again 1396 MockTransaction transaction(kSimpleGET_Transaction); 1397 transaction.request_headers = "cache-control: no-cache"; 1398 1399 RunTransactionTest(cache.http_cache(), transaction); 1400 1401 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1402 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1403 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1404 } 1405 1406 TEST(HttpCache, SimpleGET_LoadValidateCache) { 1407 MockHttpCache cache; 1408 1409 // write to the cache 1410 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1411 1412 // read from the cache 1413 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1414 1415 // force this transaction to validate the cache 1416 MockTransaction transaction(kSimpleGET_Transaction); 1417 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 1418 1419 RunTransactionTest(cache.http_cache(), transaction); 1420 1421 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1422 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1423 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1424 } 1425 1426 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) { 1427 MockHttpCache cache; 1428 1429 // write to the cache 1430 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1431 1432 // read from the cache 1433 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1434 1435 // force this transaction to validate the cache 1436 MockTransaction transaction(kSimpleGET_Transaction); 1437 transaction.request_headers = "cache-control: max-age=0"; 1438 1439 RunTransactionTest(cache.http_cache(), transaction); 1440 1441 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1442 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1443 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1444 } 1445 1446 static void PreserveRequestHeaders_Handler( 1447 const net::HttpRequestInfo* request, 1448 std::string* response_status, 1449 std::string* response_headers, 1450 std::string* response_data) { 1451 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); 1452 } 1453 1454 // Tests that we don't remove extra headers for simple requests. 1455 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) { 1456 MockHttpCache cache; 1457 1458 MockTransaction transaction(kSimpleGET_Transaction); 1459 transaction.handler = PreserveRequestHeaders_Handler; 1460 transaction.request_headers = EXTRA_HEADER; 1461 transaction.response_headers = "Cache-Control: max-age=0\n"; 1462 AddMockTransaction(&transaction); 1463 1464 // Write, then revalidate the entry. 1465 RunTransactionTest(cache.http_cache(), transaction); 1466 RunTransactionTest(cache.http_cache(), transaction); 1467 1468 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1469 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1470 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1471 RemoveMockTransaction(&transaction); 1472 } 1473 1474 // Tests that we don't remove extra headers for conditionalized requests. 1475 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) { 1476 MockHttpCache cache; 1477 1478 // Write to the cache. 1479 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 1480 1481 MockTransaction transaction(kETagGET_Transaction); 1482 transaction.handler = PreserveRequestHeaders_Handler; 1483 transaction.request_headers = "If-None-Match: \"foopy\"\r\n" 1484 EXTRA_HEADER; 1485 AddMockTransaction(&transaction); 1486 1487 RunTransactionTest(cache.http_cache(), transaction); 1488 1489 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1490 EXPECT_EQ(1, cache.disk_cache()->open_count()); 1491 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1492 RemoveMockTransaction(&transaction); 1493 } 1494 1495 TEST(HttpCache, SimpleGET_ManyReaders) { 1496 MockHttpCache cache; 1497 1498 MockHttpRequest request(kSimpleGET_Transaction); 1499 1500 std::vector<Context*> context_list; 1501 const int kNumTransactions = 5; 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(&c->trans); 1508 EXPECT_EQ(net::OK, c->result); 1509 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState()); 1510 1511 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1512 } 1513 1514 // All requests are waiting for the active entry. 1515 for (int i = 0; i < kNumTransactions; ++i) { 1516 Context* c = context_list[i]; 1517 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); 1518 } 1519 1520 // Allow all requests to move from the Create queue to the active entry. 1521 MessageLoop::current()->RunAllPending(); 1522 1523 // The first request should be a writer at this point, and the subsequent 1524 // requests should be pending. 1525 1526 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1527 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1528 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1529 1530 // All requests depend on the writer, and the writer is between Start and 1531 // Read, i.e. idle. 1532 for (int i = 0; i < kNumTransactions; ++i) { 1533 Context* c = context_list[i]; 1534 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState()); 1535 } 1536 1537 for (int i = 0; i < kNumTransactions; ++i) { 1538 Context* c = context_list[i]; 1539 if (c->result == net::ERR_IO_PENDING) 1540 c->result = c->callback.WaitForResult(); 1541 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1542 } 1543 1544 // We should not have had to re-open the disk entry 1545 1546 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1547 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1548 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1549 1550 for (int i = 0; i < kNumTransactions; ++i) { 1551 Context* c = context_list[i]; 1552 delete c; 1553 } 1554 } 1555 1556 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. 1557 // If cancelling a request is racing with another request for the same resource 1558 // finishing, we have to make sure that we remove both transactions from the 1559 // entry. 1560 TEST(HttpCache, SimpleGET_RacingReaders) { 1561 MockHttpCache cache; 1562 1563 MockHttpRequest request(kSimpleGET_Transaction); 1564 MockHttpRequest reader_request(kSimpleGET_Transaction); 1565 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE; 1566 1567 std::vector<Context*> context_list; 1568 const int kNumTransactions = 5; 1569 1570 for (int i = 0; i < kNumTransactions; ++i) { 1571 context_list.push_back(new Context()); 1572 Context* c = context_list[i]; 1573 1574 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1575 EXPECT_EQ(net::OK, c->result); 1576 1577 MockHttpRequest* this_request = &request; 1578 if (i == 1 || i == 2) 1579 this_request = &reader_request; 1580 1581 c->result = c->trans->Start(this_request, &c->callback, net::BoundNetLog()); 1582 } 1583 1584 // Allow all requests to move from the Create queue to the active entry. 1585 MessageLoop::current()->RunAllPending(); 1586 1587 // The first request should be a writer at this point, and the subsequent 1588 // requests should be pending. 1589 1590 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1591 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1592 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1593 1594 Context* c = context_list[0]; 1595 ASSERT_EQ(net::ERR_IO_PENDING, c->result); 1596 c->result = c->callback.WaitForResult(); 1597 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1598 1599 // Now we have 2 active readers and two queued transactions. 1600 1601 EXPECT_EQ(net::LOAD_STATE_IDLE, 1602 context_list[2]->trans->GetLoadState()); 1603 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, 1604 context_list[3]->trans->GetLoadState()); 1605 1606 c = context_list[1]; 1607 ASSERT_EQ(net::ERR_IO_PENDING, c->result); 1608 c->result = c->callback.WaitForResult(); 1609 if (c->result == net::OK) 1610 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1611 1612 // At this point we have one reader, two pending transactions and a task on 1613 // the queue to move to the next transaction. Now we cancel the request that 1614 // is the current reader, and expect the queued task to be able to start the 1615 // next request. 1616 1617 c = context_list[2]; 1618 c->trans.reset(); 1619 1620 for (int i = 3; i < kNumTransactions; ++i) { 1621 Context* c = context_list[i]; 1622 if (c->result == net::ERR_IO_PENDING) 1623 c->result = c->callback.WaitForResult(); 1624 if (c->result == net::OK) 1625 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1626 } 1627 1628 // We should not have had to re-open the disk entry. 1629 1630 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1631 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1632 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1633 1634 for (int i = 0; i < kNumTransactions; ++i) { 1635 Context* c = context_list[i]; 1636 delete c; 1637 } 1638 } 1639 1640 // Tests that we can doom an entry with pending transactions and delete one of 1641 // the pending transactions before the first one completes. 1642 // See http://code.google.com/p/chromium/issues/detail?id=25588 1643 TEST(HttpCache, SimpleGET_DoomWithPending) { 1644 // We need simultaneous doomed / not_doomed entries so let's use a real cache. 1645 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024)); 1646 1647 MockHttpRequest request(kSimpleGET_Transaction); 1648 MockHttpRequest writer_request(kSimpleGET_Transaction); 1649 writer_request.load_flags = net::LOAD_BYPASS_CACHE; 1650 1651 ScopedVector<Context> context_list; 1652 const int kNumTransactions = 4; 1653 1654 for (int i = 0; i < kNumTransactions; ++i) { 1655 context_list.push_back(new Context()); 1656 Context* c = context_list[i]; 1657 1658 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1659 EXPECT_EQ(net::OK, c->result); 1660 1661 MockHttpRequest* this_request = &request; 1662 if (i == 3) 1663 this_request = &writer_request; 1664 1665 c->result = c->trans->Start(this_request, &c->callback, net::BoundNetLog()); 1666 } 1667 1668 // The first request should be a writer at this point, and the two subsequent 1669 // requests should be pending. The last request doomed the first entry. 1670 1671 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1672 1673 // Cancel the first queued transaction. 1674 delete context_list[1]; 1675 context_list.get()[1] = NULL; 1676 1677 for (int i = 0; i < kNumTransactions; ++i) { 1678 if (i == 1) 1679 continue; 1680 Context* c = context_list[i]; 1681 ASSERT_EQ(net::ERR_IO_PENDING, c->result); 1682 c->result = c->callback.WaitForResult(); 1683 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1684 } 1685 } 1686 1687 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731. 1688 // We may attempt to delete an entry synchronously with the act of adding a new 1689 // transaction to said entry. 1690 TEST(HttpCache, FastNoStoreGET_DoneWithPending) { 1691 MockHttpCache cache; 1692 1693 // The headers will be served right from the call to Start() the request. 1694 MockHttpRequest request(kFastNoStoreGET_Transaction); 1695 FastTransactionServer request_handler; 1696 AddMockTransaction(&kFastNoStoreGET_Transaction); 1697 1698 std::vector<Context*> context_list; 1699 const int kNumTransactions = 3; 1700 1701 for (int i = 0; i < kNumTransactions; ++i) { 1702 context_list.push_back(new Context()); 1703 Context* c = context_list[i]; 1704 1705 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1706 EXPECT_EQ(net::OK, c->result); 1707 1708 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1709 } 1710 1711 // Allow all requests to move from the Create queue to the active entry. 1712 MessageLoop::current()->RunAllPending(); 1713 1714 // The first request should be a writer at this point, and the subsequent 1715 // requests should be pending. 1716 1717 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1718 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1719 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1720 1721 // Now, make sure that the second request asks for the entry not to be stored. 1722 request_handler.set_no_store(true); 1723 1724 for (int i = 0; i < kNumTransactions; ++i) { 1725 Context* c = context_list[i]; 1726 if (c->result == net::ERR_IO_PENDING) 1727 c->result = c->callback.WaitForResult(); 1728 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); 1729 delete c; 1730 } 1731 1732 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 1733 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1734 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1735 1736 RemoveMockTransaction(&kFastNoStoreGET_Transaction); 1737 } 1738 1739 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) { 1740 MockHttpCache cache; 1741 1742 MockHttpRequest request(kSimpleGET_Transaction); 1743 1744 std::vector<Context*> context_list; 1745 const int kNumTransactions = 2; 1746 1747 for (int i = 0; i < kNumTransactions; ++i) { 1748 context_list.push_back(new Context()); 1749 Context* c = context_list[i]; 1750 1751 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1752 EXPECT_EQ(net::OK, c->result); 1753 1754 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1755 } 1756 1757 // Allow all requests to move from the Create queue to the active entry. 1758 MessageLoop::current()->RunAllPending(); 1759 1760 // The first request should be a writer at this point, and the subsequent 1761 // requests should be pending. 1762 1763 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1764 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1765 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1766 1767 for (int i = 0; i < kNumTransactions; ++i) { 1768 Context* c = context_list[i]; 1769 if (c->result == net::ERR_IO_PENDING) 1770 c->result = c->callback.WaitForResult(); 1771 // Destroy only the first transaction. 1772 if (i == 0) { 1773 delete c; 1774 context_list[i] = NULL; 1775 } 1776 } 1777 1778 // Complete the rest of the transactions. 1779 for (int i = 1; i < kNumTransactions; ++i) { 1780 Context* c = context_list[i]; 1781 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1782 } 1783 1784 // We should have had to re-open the disk entry. 1785 1786 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 1787 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1788 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1789 1790 for (int i = 1; i < kNumTransactions; ++i) { 1791 Context* c = context_list[i]; 1792 delete c; 1793 } 1794 } 1795 1796 // Tests that we can cancel requests that are queued waiting to open the disk 1797 // cache entry. 1798 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) { 1799 MockHttpCache cache; 1800 1801 MockHttpRequest request(kSimpleGET_Transaction); 1802 1803 std::vector<Context*> context_list; 1804 const int kNumTransactions = 5; 1805 1806 for (int i = 0; i < kNumTransactions; i++) { 1807 context_list.push_back(new Context()); 1808 Context* c = context_list[i]; 1809 1810 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1811 EXPECT_EQ(net::OK, c->result); 1812 1813 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1814 } 1815 1816 // The first request should be creating the disk cache entry and the others 1817 // should be pending. 1818 1819 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 1820 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1821 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1822 1823 // Cancel a request from the pending queue. 1824 delete context_list[3]; 1825 context_list[3] = NULL; 1826 1827 // Cancel the request that is creating the entry. This will force the pending 1828 // operations to restart. 1829 delete context_list[0]; 1830 context_list[0] = NULL; 1831 1832 // Complete the rest of the transactions. 1833 for (int i = 1; i < kNumTransactions; i++) { 1834 Context* c = context_list[i]; 1835 if (c) { 1836 c->result = c->callback.GetResult(c->result); 1837 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1838 } 1839 } 1840 1841 // We should have had to re-create the disk entry. 1842 1843 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 1844 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1845 EXPECT_EQ(2, cache.disk_cache()->create_count()); 1846 1847 for (int i = 1; i < kNumTransactions; ++i) { 1848 delete context_list[i]; 1849 } 1850 } 1851 1852 // Tests that we can cancel a single request to open a disk cache entry. 1853 TEST(HttpCache, SimpleGET_CancelCreate) { 1854 MockHttpCache cache; 1855 1856 MockHttpRequest request(kSimpleGET_Transaction); 1857 1858 Context* c = new Context(); 1859 1860 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1861 EXPECT_EQ(net::OK, c->result); 1862 1863 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1864 EXPECT_EQ(net::ERR_IO_PENDING, c->result); 1865 1866 // Release the reference that the mock disk cache keeps for this entry, so 1867 // that we test that the http cache handles the cancelation correctly. 1868 cache.disk_cache()->ReleaseAll(); 1869 delete c; 1870 1871 MessageLoop::current()->RunAllPending(); 1872 EXPECT_EQ(1, cache.disk_cache()->create_count()); 1873 } 1874 1875 // Tests that we delete/create entries even if multiple requests are queued. 1876 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) { 1877 MockHttpCache cache; 1878 1879 MockHttpRequest request(kSimpleGET_Transaction); 1880 request.load_flags = net::LOAD_BYPASS_CACHE; 1881 1882 std::vector<Context*> context_list; 1883 const int kNumTransactions = 5; 1884 1885 for (int i = 0; i < kNumTransactions; i++) { 1886 context_list.push_back(new Context()); 1887 Context* c = context_list[i]; 1888 1889 c->result = cache.http_cache()->CreateTransaction(&c->trans); 1890 EXPECT_EQ(net::OK, c->result); 1891 1892 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1893 } 1894 1895 // The first request should be deleting the disk cache entry and the others 1896 // should be pending. 1897 1898 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 1899 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1900 EXPECT_EQ(0, cache.disk_cache()->create_count()); 1901 1902 // Complete the transactions. 1903 for (int i = 0; i < kNumTransactions; i++) { 1904 Context* c = context_list[i]; 1905 c->result = c->callback.GetResult(c->result); 1906 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); 1907 } 1908 1909 // We should have had to re-create the disk entry multiple times. 1910 1911 EXPECT_EQ(5, cache.network_layer()->transaction_count()); 1912 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1913 EXPECT_EQ(5, cache.disk_cache()->create_count()); 1914 1915 for (int i = 0; i < kNumTransactions; ++i) { 1916 delete context_list[i]; 1917 } 1918 } 1919 1920 TEST(HttpCache, SimpleGET_AbandonedCacheRead) { 1921 MockHttpCache cache; 1922 1923 // write to the cache 1924 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 1925 1926 MockHttpRequest request(kSimpleGET_Transaction); 1927 TestCompletionCallback callback; 1928 1929 scoped_ptr<net::HttpTransaction> trans; 1930 int rv = cache.http_cache()->CreateTransaction(&trans); 1931 EXPECT_EQ(net::OK, rv); 1932 rv = trans->Start(&request, &callback, net::BoundNetLog()); 1933 if (rv == net::ERR_IO_PENDING) 1934 rv = callback.WaitForResult(); 1935 ASSERT_EQ(net::OK, rv); 1936 1937 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); 1938 rv = trans->Read(buf, 256, &callback); 1939 EXPECT_EQ(net::ERR_IO_PENDING, rv); 1940 1941 // Test that destroying the transaction while it is reading from the cache 1942 // works properly. 1943 trans.reset(); 1944 1945 // Make sure we pump any pending events, which should include a call to 1946 // HttpCache::Transaction::OnCacheReadCompleted. 1947 MessageLoop::current()->RunAllPending(); 1948 } 1949 1950 // Tests that we can delete the HttpCache and deal with queued transactions 1951 // ("waiting for the backend" as opposed to Active or Doomed entries). 1952 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) { 1953 scoped_ptr<MockHttpCache> cache(new MockHttpCache( 1954 new MockBackendNoCbFactory())); 1955 1956 MockHttpRequest request(kSimpleGET_Transaction); 1957 1958 std::vector<Context*> context_list; 1959 const int kNumTransactions = 5; 1960 1961 for (int i = 0; i < kNumTransactions; i++) { 1962 context_list.push_back(new Context()); 1963 Context* c = context_list[i]; 1964 1965 c->result = cache->http_cache()->CreateTransaction(&c->trans); 1966 EXPECT_EQ(net::OK, c->result); 1967 1968 c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 1969 } 1970 1971 // The first request should be creating the disk cache entry and the others 1972 // should be pending. 1973 1974 EXPECT_EQ(0, cache->network_layer()->transaction_count()); 1975 EXPECT_EQ(0, cache->disk_cache()->open_count()); 1976 EXPECT_EQ(0, cache->disk_cache()->create_count()); 1977 1978 cache.reset(); 1979 1980 // There is not much to do with the transactions at this point... they are 1981 // waiting for a callback that will not fire. 1982 for (int i = 0; i < kNumTransactions; ++i) { 1983 delete context_list[i]; 1984 } 1985 } 1986 1987 // Tests that we queue requests when initializing the backend. 1988 TEST(HttpCache, SimpleGET_WaitForBackend) { 1989 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 1990 MockHttpCache cache(factory); 1991 1992 MockHttpRequest request0(kSimpleGET_Transaction); 1993 MockHttpRequest request1(kTypicalGET_Transaction); 1994 MockHttpRequest request2(kETagGET_Transaction); 1995 1996 std::vector<Context*> context_list; 1997 const int kNumTransactions = 3; 1998 1999 for (int i = 0; i < kNumTransactions; i++) { 2000 context_list.push_back(new Context()); 2001 Context* c = context_list[i]; 2002 2003 c->result = cache.http_cache()->CreateTransaction(&c->trans); 2004 EXPECT_EQ(net::OK, c->result); 2005 } 2006 2007 context_list[0]->result = context_list[0]->trans->Start( 2008 &request0, &context_list[0]->callback, net::BoundNetLog()); 2009 context_list[1]->result = context_list[1]->trans->Start( 2010 &request1, &context_list[1]->callback, net::BoundNetLog()); 2011 context_list[2]->result = context_list[2]->trans->Start( 2012 &request2, &context_list[2]->callback, net::BoundNetLog()); 2013 2014 // Just to make sure that everything is still pending. 2015 MessageLoop::current()->RunAllPending(); 2016 2017 // The first request should be creating the disk cache. 2018 EXPECT_FALSE(context_list[0]->callback.have_result()); 2019 2020 factory->FinishCreation(); 2021 2022 MessageLoop::current()->RunAllPending(); 2023 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2024 EXPECT_EQ(3, cache.disk_cache()->create_count()); 2025 2026 for (int i = 0; i < kNumTransactions; ++i) { 2027 EXPECT_TRUE(context_list[i]->callback.have_result()); 2028 delete context_list[i]; 2029 } 2030 } 2031 2032 // Tests that we can cancel requests that are queued waiting for the backend 2033 // to be initialized. 2034 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) { 2035 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 2036 MockHttpCache cache(factory); 2037 2038 MockHttpRequest request0(kSimpleGET_Transaction); 2039 MockHttpRequest request1(kTypicalGET_Transaction); 2040 MockHttpRequest request2(kETagGET_Transaction); 2041 2042 std::vector<Context*> context_list; 2043 const int kNumTransactions = 3; 2044 2045 for (int i = 0; i < kNumTransactions; i++) { 2046 context_list.push_back(new Context()); 2047 Context* c = context_list[i]; 2048 2049 c->result = cache.http_cache()->CreateTransaction(&c->trans); 2050 EXPECT_EQ(net::OK, c->result); 2051 } 2052 2053 context_list[0]->result = context_list[0]->trans->Start( 2054 &request0, &context_list[0]->callback, net::BoundNetLog()); 2055 context_list[1]->result = context_list[1]->trans->Start( 2056 &request1, &context_list[1]->callback, net::BoundNetLog()); 2057 context_list[2]->result = context_list[2]->trans->Start( 2058 &request2, &context_list[2]->callback, net::BoundNetLog()); 2059 2060 // Just to make sure that everything is still pending. 2061 MessageLoop::current()->RunAllPending(); 2062 2063 // The first request should be creating the disk cache. 2064 EXPECT_FALSE(context_list[0]->callback.have_result()); 2065 2066 // Cancel a request from the pending queue. 2067 delete context_list[1]; 2068 context_list[1] = NULL; 2069 2070 // Cancel the request that is creating the entry. 2071 delete context_list[0]; 2072 context_list[0] = NULL; 2073 2074 // Complete the last transaction. 2075 factory->FinishCreation(); 2076 2077 context_list[2]->result = 2078 context_list[2]->callback.GetResult(context_list[2]->result); 2079 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction); 2080 2081 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2082 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2083 2084 delete context_list[2]; 2085 } 2086 2087 // Tests that we can delete the cache while creating the backend. 2088 TEST(HttpCache, DeleteCacheWaitingForBackend) { 2089 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 2090 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory)); 2091 2092 MockHttpRequest request(kSimpleGET_Transaction); 2093 2094 scoped_ptr<Context> c(new Context()); 2095 c->result = cache->http_cache()->CreateTransaction(&c->trans); 2096 EXPECT_EQ(net::OK, c->result); 2097 2098 c->trans->Start(&request, &c->callback, net::BoundNetLog()); 2099 2100 // Just to make sure that everything is still pending. 2101 MessageLoop::current()->RunAllPending(); 2102 2103 // The request should be creating the disk cache. 2104 EXPECT_FALSE(c->callback.have_result()); 2105 2106 // We cannot call FinishCreation because the factory itself will go away with 2107 // the cache, so grab the callback and attempt to use it. 2108 net::CompletionCallback* callback = factory->callback(); 2109 disk_cache::Backend** backend = factory->backend(); 2110 2111 cache.reset(); 2112 MessageLoop::current()->RunAllPending(); 2113 2114 *backend = NULL; 2115 callback->Run(net::ERR_ABORTED); 2116 } 2117 2118 // Tests that we can delete the cache while creating the backend, from within 2119 // one of the callbacks. 2120 TEST(HttpCache, DeleteCacheWaitingForBackend2) { 2121 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 2122 MockHttpCache* cache = new MockHttpCache(factory); 2123 2124 DeleteCacheCompletionCallback cb(cache); 2125 disk_cache::Backend* backend; 2126 int rv = cache->http_cache()->GetBackend(&backend, &cb); 2127 EXPECT_EQ(net::ERR_IO_PENDING, rv); 2128 2129 // Now let's queue a regular transaction 2130 MockHttpRequest request(kSimpleGET_Transaction); 2131 2132 scoped_ptr<Context> c(new Context()); 2133 c->result = cache->http_cache()->CreateTransaction(&c->trans); 2134 EXPECT_EQ(net::OK, c->result); 2135 2136 c->trans->Start(&request, &c->callback, net::BoundNetLog()); 2137 2138 // And another direct backend request. 2139 TestCompletionCallback cb2; 2140 rv = cache->http_cache()->GetBackend(&backend, &cb2); 2141 EXPECT_EQ(net::ERR_IO_PENDING, rv); 2142 2143 // Just to make sure that everything is still pending. 2144 MessageLoop::current()->RunAllPending(); 2145 2146 // The request should be queued. 2147 EXPECT_FALSE(c->callback.have_result()); 2148 2149 // Generate the callback. 2150 factory->FinishCreation(); 2151 rv = cb.WaitForResult(); 2152 2153 // The cache should be gone by now. 2154 MessageLoop::current()->RunAllPending(); 2155 EXPECT_EQ(net::OK, c->callback.GetResult(c->result)); 2156 EXPECT_FALSE(cb2.have_result()); 2157 } 2158 2159 TEST(HttpCache, TypicalGET_ConditionalRequest) { 2160 MockHttpCache cache; 2161 2162 // write to the cache 2163 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction); 2164 2165 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2166 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2167 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2168 2169 // get the same URL again, but this time we expect it to result 2170 // in a conditional request. 2171 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction); 2172 2173 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2174 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2175 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2176 } 2177 2178 static void ETagGet_ConditionalRequest_Handler( 2179 const net::HttpRequestInfo* request, 2180 std::string* response_status, 2181 std::string* response_headers, 2182 std::string* response_data) { 2183 EXPECT_TRUE( 2184 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch)); 2185 response_status->assign("HTTP/1.1 304 Not Modified"); 2186 response_headers->assign(kETagGET_Transaction.response_headers); 2187 response_data->clear(); 2188 } 2189 2190 TEST(HttpCache, ETagGET_ConditionalRequest_304) { 2191 MockHttpCache cache; 2192 2193 ScopedMockTransaction transaction(kETagGET_Transaction); 2194 2195 // write to the cache 2196 RunTransactionTest(cache.http_cache(), transaction); 2197 2198 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2199 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2200 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2201 2202 // get the same URL again, but this time we expect it to result 2203 // in a conditional request. 2204 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 2205 transaction.handler = ETagGet_ConditionalRequest_Handler; 2206 RunTransactionTest(cache.http_cache(), transaction); 2207 2208 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2209 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2210 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2211 } 2212 2213 static void ETagGet_ConditionalRequest_NoStore_Handler( 2214 const net::HttpRequestInfo* request, 2215 std::string* response_status, 2216 std::string* response_headers, 2217 std::string* response_data) { 2218 EXPECT_TRUE( 2219 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch)); 2220 response_status->assign("HTTP/1.1 304 Not Modified"); 2221 response_headers->assign("Cache-Control: no-store\n"); 2222 response_data->clear(); 2223 } 2224 2225 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) { 2226 MockHttpCache cache; 2227 2228 ScopedMockTransaction transaction(kETagGET_Transaction); 2229 2230 // Write to the cache. 2231 RunTransactionTest(cache.http_cache(), transaction); 2232 2233 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2234 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2235 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2236 2237 // Get the same URL again, but this time we expect it to result 2238 // in a conditional request. 2239 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 2240 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler; 2241 RunTransactionTest(cache.http_cache(), transaction); 2242 2243 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2244 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2245 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2246 2247 ScopedMockTransaction transaction2(kETagGET_Transaction); 2248 2249 // Write to the cache again. This should create a new entry. 2250 RunTransactionTest(cache.http_cache(), transaction2); 2251 2252 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2253 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2254 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2255 } 2256 2257 TEST(HttpCache, SimplePOST_SkipsCache) { 2258 MockHttpCache cache; 2259 2260 // Test that we skip the cache for POST requests that do not have an upload 2261 // identifier. 2262 2263 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction); 2264 2265 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2266 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2267 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2268 } 2269 2270 // Helper that does 4 requests using HttpCache: 2271 // 2272 // (1) loads |kUrl| -- expects |net_response_1| to be returned. 2273 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. 2274 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to 2275 // be returned. 2276 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be 2277 // returned. 2278 static void ConditionalizedRequestUpdatesCacheHelper( 2279 const Response& net_response_1, 2280 const Response& net_response_2, 2281 const Response& cached_response_2, 2282 const char* extra_request_headers) { 2283 MockHttpCache cache; 2284 2285 // The URL we will be requesting. 2286 const char* kUrl = "http://foobar.com/main.css"; 2287 2288 // Junk network response. 2289 static const Response kUnexpectedResponse = { 2290 "HTTP/1.1 500 Unexpected", 2291 "Server: unexpected_header", 2292 "unexpected body" 2293 }; 2294 2295 // We will control the network layer's responses for |kUrl| using 2296 // |mock_network_response|. 2297 MockTransaction mock_network_response = { 0 }; 2298 mock_network_response.url = kUrl; 2299 AddMockTransaction(&mock_network_response); 2300 2301 // Request |kUrl| for the first time. It should hit the network and 2302 // receive |kNetResponse1|, which it saves into the HTTP cache. 2303 2304 MockTransaction request = { 0 }; 2305 request.url = kUrl; 2306 request.method = "GET"; 2307 request.request_headers = ""; 2308 2309 net_response_1.AssignTo(&mock_network_response); // Network mock. 2310 net_response_1.AssignTo(&request); // Expected result. 2311 2312 std::string response_headers; 2313 RunTransactionTestWithResponse( 2314 cache.http_cache(), request, &response_headers); 2315 2316 EXPECT_EQ(net_response_1.status_and_headers(), response_headers); 2317 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2318 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2319 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2320 2321 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP 2322 // cache, so we don't hit the network. 2323 2324 request.load_flags = net::LOAD_ONLY_FROM_CACHE; 2325 2326 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock. 2327 net_response_1.AssignTo(&request); // Expected result. 2328 2329 RunTransactionTestWithResponse( 2330 cache.http_cache(), request, &response_headers); 2331 2332 EXPECT_EQ(net_response_1.status_and_headers(), response_headers); 2333 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2334 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2335 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2336 2337 // Request |kUrl| yet again, but this time give the request an 2338 // "If-Modified-Since" header. This will cause the request to re-hit the 2339 // network. However now the network response is going to be 2340 // different -- this simulates a change made to the CSS file. 2341 2342 request.request_headers = extra_request_headers; 2343 request.load_flags = net::LOAD_NORMAL; 2344 2345 net_response_2.AssignTo(&mock_network_response); // Network mock. 2346 net_response_2.AssignTo(&request); // Expected result. 2347 2348 RunTransactionTestWithResponse( 2349 cache.http_cache(), request, &response_headers); 2350 2351 EXPECT_EQ(net_response_2.status_and_headers(), response_headers); 2352 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2353 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2354 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2355 2356 // Finally, request |kUrl| again. This request should be serviced from 2357 // the cache. Moreover, the value in the cache should be |kNetResponse2| 2358 // and NOT |kNetResponse1|. The previous step should have replaced the 2359 // value in the cache with the modified response. 2360 2361 request.request_headers = ""; 2362 request.load_flags = net::LOAD_ONLY_FROM_CACHE; 2363 2364 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock. 2365 cached_response_2.AssignTo(&request); // Expected result. 2366 2367 RunTransactionTestWithResponse( 2368 cache.http_cache(), request, &response_headers); 2369 2370 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers); 2371 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2372 EXPECT_EQ(2, cache.disk_cache()->open_count()); 2373 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2374 2375 RemoveMockTransaction(&mock_network_response); 2376 } 2377 2378 // Check that when an "if-modified-since" header is attached 2379 // to the request, the result still updates the cached entry. 2380 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) { 2381 // First network response for |kUrl|. 2382 static const Response kNetResponse1 = { 2383 "HTTP/1.1 200 OK", 2384 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2385 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2386 "body1" 2387 }; 2388 2389 // Second network response for |kUrl|. 2390 static const Response kNetResponse2 = { 2391 "HTTP/1.1 200 OK", 2392 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2393 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2394 "body2" 2395 }; 2396 2397 const char* extra_headers = 2398 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"; 2399 2400 ConditionalizedRequestUpdatesCacheHelper( 2401 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers); 2402 } 2403 2404 // Check that when an "if-none-match" header is attached 2405 // to the request, the result updates the cached entry. 2406 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) { 2407 // First network response for |kUrl|. 2408 static const Response kNetResponse1 = { 2409 "HTTP/1.1 200 OK", 2410 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2411 "Etag: \"ETAG1\"\n" 2412 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire. 2413 "body1" 2414 }; 2415 2416 // Second network response for |kUrl|. 2417 static const Response kNetResponse2 = { 2418 "HTTP/1.1 200 OK", 2419 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2420 "Etag: \"ETAG2\"\n" 2421 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire. 2422 "body2" 2423 }; 2424 2425 const char* extra_headers = "If-None-Match: \"ETAG1\"\n"; 2426 2427 ConditionalizedRequestUpdatesCacheHelper( 2428 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers); 2429 } 2430 2431 // Check that when an "if-modified-since" header is attached 2432 // to a request, the 304 (not modified result) result updates the cached 2433 // headers, and the 304 response is returned rather than the cached response. 2434 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) { 2435 // First network response for |kUrl|. 2436 static const Response kNetResponse1 = { 2437 "HTTP/1.1 200 OK", 2438 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2439 "Server: server1\n" 2440 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2441 "body1" 2442 }; 2443 2444 // Second network response for |kUrl|. 2445 static const Response kNetResponse2 = { 2446 "HTTP/1.1 304 Not Modified", 2447 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2448 "Server: server2\n" 2449 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2450 "" 2451 }; 2452 2453 static const Response kCachedResponse2 = { 2454 "HTTP/1.1 200 OK", 2455 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2456 "Server: server2\n" 2457 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2458 "body1" 2459 }; 2460 2461 const char* extra_headers = 2462 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"; 2463 2464 ConditionalizedRequestUpdatesCacheHelper( 2465 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers); 2466 } 2467 2468 // Test that when doing an externally conditionalized if-modified-since 2469 // and there is no corresponding cache entry, a new cache entry is NOT 2470 // created (304 response). 2471 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) { 2472 MockHttpCache cache; 2473 2474 const char* kUrl = "http://foobar.com/main.css"; 2475 2476 static const Response kNetResponse = { 2477 "HTTP/1.1 304 Not Modified", 2478 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2479 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2480 "" 2481 }; 2482 2483 const char* kExtraRequestHeaders = 2484 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT"; 2485 2486 // We will control the network layer's responses for |kUrl| using 2487 // |mock_network_response|. 2488 MockTransaction mock_network_response = { 0 }; 2489 mock_network_response.url = kUrl; 2490 AddMockTransaction(&mock_network_response); 2491 2492 MockTransaction request = { 0 }; 2493 request.url = kUrl; 2494 request.method = "GET"; 2495 request.request_headers = kExtraRequestHeaders; 2496 2497 kNetResponse.AssignTo(&mock_network_response); // Network mock. 2498 kNetResponse.AssignTo(&request); // Expected result. 2499 2500 std::string response_headers; 2501 RunTransactionTestWithResponse( 2502 cache.http_cache(), request, &response_headers); 2503 2504 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers); 2505 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2506 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2507 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2508 2509 RemoveMockTransaction(&mock_network_response); 2510 } 2511 2512 // Test that when doing an externally conditionalized if-modified-since 2513 // and there is no corresponding cache entry, a new cache entry is NOT 2514 // created (200 response). 2515 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) { 2516 MockHttpCache cache; 2517 2518 const char* kUrl = "http://foobar.com/main.css"; 2519 2520 static const Response kNetResponse = { 2521 "HTTP/1.1 200 OK", 2522 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2523 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2524 "foobar!!!" 2525 }; 2526 2527 const char* kExtraRequestHeaders = 2528 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT"; 2529 2530 // We will control the network layer's responses for |kUrl| using 2531 // |mock_network_response|. 2532 MockTransaction mock_network_response = { 0 }; 2533 mock_network_response.url = kUrl; 2534 AddMockTransaction(&mock_network_response); 2535 2536 MockTransaction request = { 0 }; 2537 request.url = kUrl; 2538 request.method = "GET"; 2539 request.request_headers = kExtraRequestHeaders; 2540 2541 kNetResponse.AssignTo(&mock_network_response); // Network mock. 2542 kNetResponse.AssignTo(&request); // Expected result. 2543 2544 std::string response_headers; 2545 RunTransactionTestWithResponse( 2546 cache.http_cache(), request, &response_headers); 2547 2548 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers); 2549 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2550 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2551 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2552 2553 RemoveMockTransaction(&mock_network_response); 2554 } 2555 2556 // Test that when doing an externally conditionalized if-modified-since 2557 // if the date does not match the cache entry's last-modified date, 2558 // then we do NOT use the response (304) to update the cache. 2559 // (the if-modified-since date is 2 days AFTER the cache's modification date). 2560 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) { 2561 static const Response kNetResponse1 = { 2562 "HTTP/1.1 200 OK", 2563 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2564 "Server: server1\n" 2565 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2566 "body1" 2567 }; 2568 2569 // Second network response for |kUrl|. 2570 static const Response kNetResponse2 = { 2571 "HTTP/1.1 304 Not Modified", 2572 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2573 "Server: server2\n" 2574 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2575 "" 2576 }; 2577 2578 // This is two days in the future from the original response's last-modified 2579 // date! 2580 const char* kExtraRequestHeaders = 2581 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n"; 2582 2583 ConditionalizedRequestUpdatesCacheHelper( 2584 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2585 } 2586 2587 // Test that when doing an externally conditionalized if-none-match 2588 // if the etag does not match the cache entry's etag, then we do not use the 2589 // response (304) to update the cache. 2590 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) { 2591 static const Response kNetResponse1 = { 2592 "HTTP/1.1 200 OK", 2593 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2594 "Etag: \"Foo1\"\n" 2595 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2596 "body1" 2597 }; 2598 2599 // Second network response for |kUrl|. 2600 static const Response kNetResponse2 = { 2601 "HTTP/1.1 304 Not Modified", 2602 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2603 "Etag: \"Foo2\"\n" 2604 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2605 "" 2606 }; 2607 2608 // Different etag from original response. 2609 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\n"; 2610 2611 ConditionalizedRequestUpdatesCacheHelper( 2612 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2613 } 2614 2615 // Test that doing an externally conditionalized request with both if-none-match 2616 // and if-modified-since updates the cache. 2617 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) { 2618 static const Response kNetResponse1 = { 2619 "HTTP/1.1 200 OK", 2620 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2621 "Etag: \"Foo1\"\n" 2622 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2623 "body1" 2624 }; 2625 2626 // Second network response for |kUrl|. 2627 static const Response kNetResponse2 = { 2628 "HTTP/1.1 200 OK", 2629 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2630 "Etag: \"Foo2\"\n" 2631 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2632 "body2" 2633 }; 2634 2635 const char* kExtraRequestHeaders = 2636 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n" 2637 "If-None-Match: \"Foo1\"\r\n"; 2638 2639 ConditionalizedRequestUpdatesCacheHelper( 2640 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders); 2641 } 2642 2643 // Test that doing an externally conditionalized request with both if-none-match 2644 // and if-modified-since does not update the cache with only one match. 2645 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) { 2646 static const Response kNetResponse1 = { 2647 "HTTP/1.1 200 OK", 2648 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2649 "Etag: \"Foo1\"\n" 2650 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2651 "body1" 2652 }; 2653 2654 // Second network response for |kUrl|. 2655 static const Response kNetResponse2 = { 2656 "HTTP/1.1 200 OK", 2657 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2658 "Etag: \"Foo2\"\n" 2659 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2660 "body2" 2661 }; 2662 2663 // The etag doesn't match what we have stored. 2664 const char* kExtraRequestHeaders = 2665 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n" 2666 "If-None-Match: \"Foo2\"\n"; 2667 2668 ConditionalizedRequestUpdatesCacheHelper( 2669 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2670 } 2671 2672 // Test that doing an externally conditionalized request with both if-none-match 2673 // and if-modified-since does not update the cache with only one match. 2674 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) { 2675 static const Response kNetResponse1 = { 2676 "HTTP/1.1 200 OK", 2677 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2678 "Etag: \"Foo1\"\n" 2679 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2680 "body1" 2681 }; 2682 2683 // Second network response for |kUrl|. 2684 static const Response kNetResponse2 = { 2685 "HTTP/1.1 200 OK", 2686 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2687 "Etag: \"Foo2\"\n" 2688 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2689 "body2" 2690 }; 2691 2692 // The modification date doesn't match what we have stored. 2693 const char* kExtraRequestHeaders = 2694 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n" 2695 "If-None-Match: \"Foo1\"\n"; 2696 2697 ConditionalizedRequestUpdatesCacheHelper( 2698 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2699 } 2700 2701 // Test that doing an externally conditionalized request with two conflicting 2702 // headers does not update the cache. 2703 TEST(HttpCache, ConditionalizedRequestUpdatesCache11) { 2704 static const Response kNetResponse1 = { 2705 "HTTP/1.1 200 OK", 2706 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 2707 "Etag: \"Foo1\"\n" 2708 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 2709 "body1" 2710 }; 2711 2712 // Second network response for |kUrl|. 2713 static const Response kNetResponse2 = { 2714 "HTTP/1.1 200 OK", 2715 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 2716 "Etag: \"Foo2\"\n" 2717 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", 2718 "body2" 2719 }; 2720 2721 // Two dates, the second matches what we have stored. 2722 const char* kExtraRequestHeaders = 2723 "If-Modified-Since: Mon, 04 Feb 2008 22:38:21 GMT\n" 2724 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"; 2725 2726 ConditionalizedRequestUpdatesCacheHelper( 2727 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders); 2728 } 2729 2730 TEST(HttpCache, UrlContainingHash) { 2731 MockHttpCache cache; 2732 2733 // Do a typical GET request -- should write an entry into our cache. 2734 MockTransaction trans(kTypicalGET_Transaction); 2735 RunTransactionTest(cache.http_cache(), trans); 2736 2737 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2738 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2739 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2740 2741 // Request the same URL, but this time with a reference section (hash). 2742 // Since the cache key strips the hash sections, this should be a cache hit. 2743 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes"; 2744 trans.url = url_with_hash.c_str(); 2745 trans.load_flags = net::LOAD_ONLY_FROM_CACHE; 2746 2747 RunTransactionTest(cache.http_cache(), trans); 2748 2749 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2750 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2751 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2752 } 2753 2754 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) { 2755 MockHttpCache cache; 2756 2757 // Test that we skip the cache for POST requests. Eventually, we will want 2758 // to cache these, but we'll still have cases where skipping the cache makes 2759 // sense, so we want to make sure that it works properly. 2760 2761 MockTransaction transaction(kSimplePOST_Transaction); 2762 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 2763 2764 MockHttpRequest request(transaction); 2765 TestCompletionCallback callback; 2766 2767 scoped_ptr<net::HttpTransaction> trans; 2768 int rv = cache.http_cache()->CreateTransaction(&trans); 2769 EXPECT_EQ(net::OK, rv); 2770 ASSERT_TRUE(trans.get()); 2771 2772 rv = trans->Start(&request, &callback, net::BoundNetLog()); 2773 if (rv == net::ERR_IO_PENDING) 2774 rv = callback.WaitForResult(); 2775 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 2776 2777 trans.reset(); 2778 2779 EXPECT_EQ(0, cache.network_layer()->transaction_count()); 2780 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2781 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2782 } 2783 2784 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) { 2785 MockHttpCache cache; 2786 2787 // Test that we hit the cache for POST requests. 2788 2789 MockTransaction transaction(kSimplePOST_Transaction); 2790 2791 const int64 kUploadId = 1; // Just a dummy value. 2792 2793 MockHttpRequest request(transaction); 2794 request.upload_data = new net::UploadData(); 2795 request.upload_data->set_identifier(kUploadId); 2796 request.upload_data->AppendBytes("hello", 5); 2797 2798 // Populate the cache. 2799 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 2800 2801 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2802 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2803 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2804 2805 // Load from cache. 2806 request.load_flags |= net::LOAD_ONLY_FROM_CACHE; 2807 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL); 2808 2809 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2810 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2811 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2812 } 2813 2814 TEST(HttpCache, RangeGET_SkipsCache) { 2815 MockHttpCache cache; 2816 2817 // Test that we skip the cache for range GET requests. Eventually, we will 2818 // want to cache these, but we'll still have cases where skipping the cache 2819 // makes sense, so we want to make sure that it works properly. 2820 2821 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction); 2822 2823 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2824 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2825 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2826 2827 MockTransaction transaction(kSimpleGET_Transaction); 2828 transaction.request_headers = "If-None-Match: foo"; 2829 RunTransactionTest(cache.http_cache(), transaction); 2830 2831 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2832 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2833 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2834 2835 transaction.request_headers = 2836 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT"; 2837 RunTransactionTest(cache.http_cache(), transaction); 2838 2839 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2840 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2841 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2842 } 2843 2844 // Test that we skip the cache for range requests that include a validation 2845 // header. 2846 TEST(HttpCache, RangeGET_SkipsCache2) { 2847 MockHttpCache cache; 2848 2849 MockTransaction transaction(kRangeGET_Transaction); 2850 transaction.request_headers = "If-None-Match: foo\r\n" 2851 EXTRA_HEADER 2852 "\r\nRange: bytes = 40-49"; 2853 RunTransactionTest(cache.http_cache(), transaction); 2854 2855 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2856 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2857 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2858 2859 transaction.request_headers = 2860 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n" 2861 EXTRA_HEADER 2862 "\r\nRange: bytes = 40-49"; 2863 RunTransactionTest(cache.http_cache(), transaction); 2864 2865 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2866 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2867 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2868 2869 transaction.request_headers = "If-Range: bla\r\n" 2870 EXTRA_HEADER 2871 "\r\nRange: bytes = 40-49\n"; 2872 RunTransactionTest(cache.http_cache(), transaction); 2873 2874 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 2875 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2876 EXPECT_EQ(0, cache.disk_cache()->create_count()); 2877 } 2878 2879 // Tests that receiving 206 for a regular request is handled correctly. 2880 TEST(HttpCache, GET_Crazy206) { 2881 MockHttpCache cache; 2882 2883 // Write to the cache. 2884 MockTransaction transaction(kRangeGET_TransactionOK); 2885 AddMockTransaction(&transaction); 2886 transaction.request_headers = EXTRA_HEADER; 2887 transaction.handler = NULL; 2888 RunTransactionTest(cache.http_cache(), transaction); 2889 2890 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2891 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2892 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2893 2894 // This should read again from the net. 2895 RunTransactionTest(cache.http_cache(), transaction); 2896 2897 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2898 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2899 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2900 RemoveMockTransaction(&transaction); 2901 } 2902 2903 // Tests that we don't cache partial responses that can't be validated. 2904 TEST(HttpCache, RangeGET_NoStrongValidators) { 2905 MockHttpCache cache; 2906 std::string headers; 2907 2908 // Attempt to write to the cache (40-49). 2909 MockTransaction transaction(kRangeGET_TransactionOK); 2910 AddMockTransaction(&transaction); 2911 transaction.response_headers = "Content-Length: 10\n" 2912 "ETag: w/\"foo\"\n"; 2913 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 2914 2915 Verify206Response(headers, 40, 49); 2916 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2917 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2918 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2919 2920 // Now verify that there's no cached data. 2921 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 2922 &headers); 2923 2924 Verify206Response(headers, 40, 49); 2925 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2926 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2927 EXPECT_EQ(2, cache.disk_cache()->create_count()); 2928 2929 RemoveMockTransaction(&transaction); 2930 } 2931 2932 // Tests that we can cache range requests and fetch random blocks from the 2933 // cache and the network. 2934 TEST(HttpCache, RangeGET_OK) { 2935 MockHttpCache cache; 2936 AddMockTransaction(&kRangeGET_TransactionOK); 2937 std::string headers; 2938 2939 // Write to the cache (40-49). 2940 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 2941 &headers); 2942 2943 Verify206Response(headers, 40, 49); 2944 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2945 EXPECT_EQ(0, cache.disk_cache()->open_count()); 2946 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2947 2948 // Read from the cache (40-49). 2949 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 2950 &headers); 2951 2952 Verify206Response(headers, 40, 49); 2953 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 2954 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2955 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2956 2957 // Make sure we are done with the previous transaction. 2958 MessageLoop::current()->RunAllPending(); 2959 2960 // Write to the cache (30-39). 2961 MockTransaction transaction(kRangeGET_TransactionOK); 2962 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER; 2963 transaction.data = "rg: 30-39 "; 2964 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 2965 2966 Verify206Response(headers, 30, 39); 2967 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2968 EXPECT_EQ(2, cache.disk_cache()->open_count()); 2969 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2970 2971 // Make sure we are done with the previous transaction. 2972 MessageLoop::current()->RunAllPending(); 2973 2974 // Write and read from the cache (20-59). 2975 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; 2976 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; 2977 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 2978 2979 Verify206Response(headers, 20, 59); 2980 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 2981 EXPECT_EQ(3, cache.disk_cache()->open_count()); 2982 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2983 2984 RemoveMockTransaction(&kRangeGET_TransactionOK); 2985 } 2986 2987 // Tests that we can cache range requests and fetch random blocks from the 2988 // cache and the network, with synchronous responses. 2989 TEST(HttpCache, RangeGET_SyncOK) { 2990 MockHttpCache cache; 2991 2992 MockTransaction transaction(kRangeGET_TransactionOK); 2993 transaction.test_mode = TEST_MODE_SYNC_ALL; 2994 AddMockTransaction(&transaction); 2995 2996 // Write to the cache (40-49). 2997 std::string headers; 2998 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 2999 3000 Verify206Response(headers, 40, 49); 3001 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3002 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3003 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3004 3005 // Read from the cache (40-49). 3006 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3007 3008 Verify206Response(headers, 40, 49); 3009 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3010 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3011 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3012 3013 // Make sure we are done with the previous transaction. 3014 MessageLoop::current()->RunAllPending(); 3015 3016 // Write to the cache (30-39). 3017 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER; 3018 transaction.data = "rg: 30-39 "; 3019 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3020 3021 Verify206Response(headers, 30, 39); 3022 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3023 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3024 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3025 3026 // Make sure we are done with the previous transaction. 3027 MessageLoop::current()->RunAllPending(); 3028 3029 // Write and read from the cache (20-59). 3030 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; 3031 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; 3032 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3033 3034 Verify206Response(headers, 20, 59); 3035 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 3036 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3037 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3038 3039 RemoveMockTransaction(&transaction); 3040 } 3041 3042 // Tests that we don't revalidate an entry unless we are required to do so. 3043 TEST(HttpCache, RangeGET_Revalidate1) { 3044 MockHttpCache cache; 3045 std::string headers; 3046 3047 // Write to the cache (40-49). 3048 MockTransaction transaction(kRangeGET_TransactionOK); 3049 transaction.response_headers = 3050 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 3051 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire. 3052 "ETag: \"foo\"\n" 3053 "Accept-Ranges: bytes\n" 3054 "Content-Length: 10\n"; 3055 AddMockTransaction(&transaction); 3056 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3057 3058 Verify206Response(headers, 40, 49); 3059 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3060 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3061 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3062 3063 // Read from the cache (40-49). 3064 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3065 Verify206Response(headers, 40, 49); 3066 3067 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3068 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3069 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3070 3071 // Read again forcing the revalidation. 3072 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3073 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3074 3075 Verify206Response(headers, 40, 49); 3076 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3077 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3078 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3079 3080 RemoveMockTransaction(&transaction); 3081 } 3082 3083 // Checks that we revalidate an entry when the headers say so. 3084 TEST(HttpCache, RangeGET_Revalidate2) { 3085 MockHttpCache cache; 3086 std::string headers; 3087 3088 // Write to the cache (40-49). 3089 MockTransaction transaction(kRangeGET_TransactionOK); 3090 transaction.response_headers = 3091 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 3092 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired. 3093 "ETag: \"foo\"\n" 3094 "Accept-Ranges: bytes\n" 3095 "Content-Length: 10\n"; 3096 AddMockTransaction(&transaction); 3097 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3098 3099 Verify206Response(headers, 40, 49); 3100 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3101 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3102 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3103 3104 // Read from the cache (40-49). 3105 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3106 Verify206Response(headers, 40, 49); 3107 3108 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3109 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3110 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3111 3112 RemoveMockTransaction(&transaction); 3113 } 3114 3115 // Tests that we deal with 304s for range requests. 3116 TEST(HttpCache, RangeGET_304) { 3117 MockHttpCache cache; 3118 AddMockTransaction(&kRangeGET_TransactionOK); 3119 std::string headers; 3120 3121 // Write to the cache (40-49). 3122 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3123 &headers); 3124 3125 Verify206Response(headers, 40, 49); 3126 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3127 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3128 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3129 3130 // Read from the cache (40-49). 3131 RangeTransactionServer handler; 3132 handler.set_not_modified(true); 3133 MockTransaction transaction(kRangeGET_TransactionOK); 3134 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3135 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3136 3137 Verify206Response(headers, 40, 49); 3138 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3139 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3140 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3141 3142 RemoveMockTransaction(&kRangeGET_TransactionOK); 3143 } 3144 3145 // Tests that we deal with 206s when revalidating range requests. 3146 TEST(HttpCache, RangeGET_ModifiedResult) { 3147 MockHttpCache cache; 3148 AddMockTransaction(&kRangeGET_TransactionOK); 3149 std::string headers; 3150 3151 // Write to the cache (40-49). 3152 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3153 &headers); 3154 3155 Verify206Response(headers, 40, 49); 3156 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3157 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3158 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3159 3160 // Attempt to read from the cache (40-49). 3161 RangeTransactionServer handler; 3162 handler.set_modified(true); 3163 MockTransaction transaction(kRangeGET_TransactionOK); 3164 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3165 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3166 3167 Verify206Response(headers, 40, 49); 3168 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3169 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3170 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3171 3172 // And the entry should be gone. 3173 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3174 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3175 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3176 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3177 3178 RemoveMockTransaction(&kRangeGET_TransactionOK); 3179 } 3180 3181 // Tests that we can cache range requests when the start or end is unknown. 3182 // We start with one suffix request, followed by a request from a given point. 3183 TEST(HttpCache, UnknownRangeGET_1) { 3184 MockHttpCache cache; 3185 AddMockTransaction(&kRangeGET_TransactionOK); 3186 std::string headers; 3187 3188 // Write to the cache (70-79). 3189 MockTransaction transaction(kRangeGET_TransactionOK); 3190 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER; 3191 transaction.data = "rg: 70-79 "; 3192 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3193 3194 Verify206Response(headers, 70, 79); 3195 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3196 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3197 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3198 3199 // Make sure we are done with the previous transaction. 3200 MessageLoop::current()->RunAllPending(); 3201 3202 // Write and read from the cache (60-79). 3203 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER; 3204 transaction.data = "rg: 60-69 rg: 70-79 "; 3205 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3206 3207 Verify206Response(headers, 60, 79); 3208 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3209 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3210 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3211 3212 RemoveMockTransaction(&kRangeGET_TransactionOK); 3213 } 3214 3215 // Tests that we can cache range requests when the start or end is unknown. 3216 // We start with one request from a given point, followed by a suffix request. 3217 // We'll also verify that synchronous cache responses work as intended. 3218 TEST(HttpCache, UnknownRangeGET_2) { 3219 MockHttpCache cache; 3220 std::string headers; 3221 3222 MockTransaction transaction(kRangeGET_TransactionOK); 3223 transaction.test_mode = TEST_MODE_SYNC_CACHE_START | 3224 TEST_MODE_SYNC_CACHE_READ | 3225 TEST_MODE_SYNC_CACHE_WRITE; 3226 AddMockTransaction(&transaction); 3227 3228 // Write to the cache (70-79). 3229 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER; 3230 transaction.data = "rg: 70-79 "; 3231 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3232 3233 Verify206Response(headers, 70, 79); 3234 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3235 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3236 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3237 3238 // Make sure we are done with the previous transaction. 3239 MessageLoop::current()->RunAllPending(); 3240 3241 // Write and read from the cache (60-79). 3242 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER; 3243 transaction.data = "rg: 60-69 rg: 70-79 "; 3244 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3245 3246 Verify206Response(headers, 60, 79); 3247 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3248 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3249 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3250 3251 RemoveMockTransaction(&transaction); 3252 } 3253 3254 // Tests that receiving Not Modified when asking for an open range doesn't mess 3255 // up things. 3256 TEST(HttpCache, UnknownRangeGET_304) { 3257 MockHttpCache cache; 3258 std::string headers; 3259 3260 MockTransaction transaction(kRangeGET_TransactionOK); 3261 AddMockTransaction(&transaction); 3262 3263 RangeTransactionServer handler; 3264 handler.set_not_modified(true); 3265 3266 // Ask for the end of the file, without knowing the length. 3267 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER; 3268 transaction.data = ""; 3269 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3270 3271 // We just bypass the cache. 3272 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n")); 3273 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3274 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3275 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3276 3277 RunTransactionTest(cache.http_cache(), transaction); 3278 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3279 3280 RemoveMockTransaction(&transaction); 3281 } 3282 3283 // Tests that we can handle non-range requests when we have cached a range. 3284 TEST(HttpCache, GET_Previous206) { 3285 MockHttpCache cache; 3286 AddMockTransaction(&kRangeGET_TransactionOK); 3287 std::string headers; 3288 3289 // Write to the cache (40-49). 3290 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3291 &headers); 3292 3293 Verify206Response(headers, 40, 49); 3294 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3295 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3296 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3297 3298 // Write and read from the cache (0-79), when not asked for a range. 3299 MockTransaction transaction(kRangeGET_TransactionOK); 3300 transaction.request_headers = EXTRA_HEADER; 3301 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 3302 "rg: 50-59 rg: 60-69 rg: 70-79 "; 3303 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3304 3305 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3306 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3307 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3308 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3309 3310 RemoveMockTransaction(&kRangeGET_TransactionOK); 3311 } 3312 3313 // Tests that we can handle non-range requests when we have cached the first 3314 // part of the object and the server replies with 304 (Not Modified). 3315 TEST(HttpCache, GET_Previous206_NotModified) { 3316 MockHttpCache cache; 3317 3318 MockTransaction transaction(kRangeGET_TransactionOK); 3319 AddMockTransaction(&transaction); 3320 std::string headers; 3321 3322 // Write to the cache (0-9). 3323 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; 3324 transaction.data = "rg: 00-09 "; 3325 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3326 Verify206Response(headers, 0, 9); 3327 3328 // Write to the cache (70-79). 3329 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; 3330 transaction.data = "rg: 70-79 "; 3331 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3332 Verify206Response(headers, 70, 79); 3333 3334 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3335 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3336 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3337 3338 // Read from the cache (0-9), write and read from cache (10 - 79). 3339 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3340 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER; 3341 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 3342 "rg: 50-59 rg: 60-69 rg: 70-79 "; 3343 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3344 3345 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3346 EXPECT_EQ(4, cache.network_layer()->transaction_count()); 3347 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3348 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3349 3350 RemoveMockTransaction(&transaction); 3351 } 3352 3353 // Tests that we can handle a regular request to a sparse entry, that results in 3354 // new content provided by the server (206). 3355 TEST(HttpCache, GET_Previous206_NewContent) { 3356 MockHttpCache cache; 3357 AddMockTransaction(&kRangeGET_TransactionOK); 3358 std::string headers; 3359 3360 // Write to the cache (0-9). 3361 MockTransaction transaction(kRangeGET_TransactionOK); 3362 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER; 3363 transaction.data = "rg: 00-09 "; 3364 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3365 3366 Verify206Response(headers, 0, 9); 3367 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3368 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3369 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3370 3371 // Now we'll issue a request without any range that should result first in a 3372 // 206 (when revalidating), and then in a weird standard answer: the test 3373 // server will not modify the response so we'll get the default range... a 3374 // real server will answer with 200. 3375 MockTransaction transaction2(kRangeGET_TransactionOK); 3376 transaction2.request_headers = EXTRA_HEADER; 3377 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE; 3378 transaction2.data = "Not a range"; 3379 RangeTransactionServer handler; 3380 handler.set_modified(true); 3381 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 3382 3383 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3384 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 3385 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3386 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3387 3388 // Verify that the previous request deleted the entry. 3389 RunTransactionTest(cache.http_cache(), transaction); 3390 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3391 3392 RemoveMockTransaction(&transaction); 3393 } 3394 3395 // Tests that we can handle cached 206 responses that are not sparse. 3396 TEST(HttpCache, GET_Previous206_NotSparse) { 3397 MockHttpCache cache; 3398 3399 // Create a disk cache entry that stores 206 headers while not being sparse. 3400 disk_cache::Entry* entry; 3401 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry, 3402 NULL)); 3403 3404 std::string raw_headers(kRangeGET_TransactionOK.status); 3405 raw_headers.append("\n"); 3406 raw_headers.append(kRangeGET_TransactionOK.response_headers); 3407 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 3408 raw_headers.size()); 3409 3410 net::HttpResponseInfo response; 3411 response.headers = new net::HttpResponseHeaders(raw_headers); 3412 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 3413 3414 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); 3415 int len = static_cast<int>(base::strlcpy(buf->data(), 3416 kRangeGET_TransactionOK.data, 500)); 3417 TestCompletionCallback cb; 3418 int rv = entry->WriteData(1, 0, buf, len, &cb, true); 3419 EXPECT_EQ(len, cb.GetResult(rv)); 3420 entry->Close(); 3421 3422 // Now see that we don't use the stored entry. 3423 std::string headers; 3424 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction, 3425 &headers); 3426 3427 // We are expecting a 200. 3428 std::string expected_headers(kSimpleGET_Transaction.status); 3429 expected_headers.append("\n"); 3430 expected_headers.append(kSimpleGET_Transaction.response_headers); 3431 EXPECT_EQ(expected_headers, headers); 3432 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3433 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3434 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3435 } 3436 3437 // Tests that we can handle cached 206 responses that are not sparse. This time 3438 // we issue a range request and expect to receive a range. 3439 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) { 3440 MockHttpCache cache; 3441 AddMockTransaction(&kRangeGET_TransactionOK); 3442 3443 // Create a disk cache entry that stores 206 headers while not being sparse. 3444 disk_cache::Entry* entry; 3445 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, 3446 NULL)); 3447 3448 std::string raw_headers(kRangeGET_TransactionOK.status); 3449 raw_headers.append("\n"); 3450 raw_headers.append(kRangeGET_TransactionOK.response_headers); 3451 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 3452 raw_headers.size()); 3453 3454 net::HttpResponseInfo response; 3455 response.headers = new net::HttpResponseHeaders(raw_headers); 3456 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 3457 3458 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); 3459 int len = static_cast<int>(base::strlcpy(buf->data(), 3460 kRangeGET_TransactionOK.data, 500)); 3461 TestCompletionCallback cb; 3462 int rv = entry->WriteData(1, 0, buf, len, &cb, true); 3463 EXPECT_EQ(len, cb.GetResult(rv)); 3464 entry->Close(); 3465 3466 // Now see that we don't use the stored entry. 3467 std::string headers; 3468 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3469 &headers); 3470 3471 // We are expecting a 206. 3472 Verify206Response(headers, 40, 49); 3473 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3474 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3475 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3476 3477 RemoveMockTransaction(&kRangeGET_TransactionOK); 3478 } 3479 3480 // Tests that we can handle cached 206 responses that can't be validated. 3481 TEST(HttpCache, GET_Previous206_NotValidation) { 3482 MockHttpCache cache; 3483 3484 // Create a disk cache entry that stores 206 headers. 3485 disk_cache::Entry* entry; 3486 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry, 3487 NULL)); 3488 3489 // Make sure that the headers cannot be validated with the server. 3490 std::string raw_headers(kRangeGET_TransactionOK.status); 3491 raw_headers.append("\n"); 3492 raw_headers.append("Content-Length: 80\n"); 3493 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), 3494 raw_headers.size()); 3495 3496 net::HttpResponseInfo response; 3497 response.headers = new net::HttpResponseHeaders(raw_headers); 3498 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 3499 3500 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); 3501 int len = static_cast<int>(base::strlcpy(buf->data(), 3502 kRangeGET_TransactionOK.data, 500)); 3503 TestCompletionCallback cb; 3504 int rv = entry->WriteData(1, 0, buf, len, &cb, true); 3505 EXPECT_EQ(len, cb.GetResult(rv)); 3506 entry->Close(); 3507 3508 // Now see that we don't use the stored entry. 3509 std::string headers; 3510 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction, 3511 &headers); 3512 3513 // We are expecting a 200. 3514 std::string expected_headers(kSimpleGET_Transaction.status); 3515 expected_headers.append("\n"); 3516 expected_headers.append(kSimpleGET_Transaction.response_headers); 3517 EXPECT_EQ(expected_headers, headers); 3518 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3519 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3520 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3521 } 3522 3523 // Tests that we can handle range requests with cached 200 responses. 3524 TEST(HttpCache, RangeGET_Previous200) { 3525 MockHttpCache cache; 3526 3527 // Store the whole thing with status 200. 3528 MockTransaction transaction(kTypicalGET_Transaction); 3529 transaction.url = kRangeGET_TransactionOK.url; 3530 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 3531 "rg: 50-59 rg: 60-69 rg: 70-79 "; 3532 AddMockTransaction(&transaction); 3533 RunTransactionTest(cache.http_cache(), transaction); 3534 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3535 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3536 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3537 3538 RemoveMockTransaction(&transaction); 3539 AddMockTransaction(&kRangeGET_TransactionOK); 3540 3541 // Now see that we use the stored entry. 3542 std::string headers; 3543 MockTransaction transaction2(kRangeGET_TransactionOK); 3544 RangeTransactionServer handler; 3545 handler.set_not_modified(true); 3546 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 3547 3548 // We are expecting a 206. 3549 Verify206Response(headers, 40, 49); 3550 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3551 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3552 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3553 3554 // The last transaction has finished so make sure the entry is deactivated. 3555 MessageLoop::current()->RunAllPending(); 3556 3557 // Make a request for an invalid range. 3558 MockTransaction transaction3(kRangeGET_TransactionOK); 3559 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER; 3560 transaction3.data = ""; 3561 transaction3.load_flags = net::LOAD_PREFERRING_CACHE; 3562 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers); 3563 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3564 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 ")); 3565 EXPECT_NE(std::string::npos, headers.find("Content-Range: bytes 0-0/80")); 3566 EXPECT_NE(std::string::npos, headers.find("Content-Length: 0")); 3567 3568 // Make sure the entry is deactivated. 3569 MessageLoop::current()->RunAllPending(); 3570 3571 // Even though the request was invalid, we should have the entry. 3572 RunTransactionTest(cache.http_cache(), transaction2); 3573 EXPECT_EQ(3, cache.disk_cache()->open_count()); 3574 3575 // Make sure the entry is deactivated. 3576 MessageLoop::current()->RunAllPending(); 3577 3578 // Now we should receive a range from the server and drop the stored entry. 3579 handler.set_not_modified(false); 3580 transaction2.request_headers = kRangeGET_TransactionOK.request_headers; 3581 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 3582 Verify206Response(headers, 40, 49); 3583 EXPECT_EQ(5, cache.network_layer()->transaction_count()); 3584 EXPECT_EQ(4, cache.disk_cache()->open_count()); 3585 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3586 3587 RunTransactionTest(cache.http_cache(), transaction2); 3588 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3589 3590 RemoveMockTransaction(&kRangeGET_TransactionOK); 3591 } 3592 3593 // Tests that we can handle a 200 response when dealing with sparse entries. 3594 TEST(HttpCache, RangeRequestResultsIn200) { 3595 MockHttpCache cache; 3596 AddMockTransaction(&kRangeGET_TransactionOK); 3597 std::string headers; 3598 3599 // Write to the cache (70-79). 3600 MockTransaction transaction(kRangeGET_TransactionOK); 3601 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER; 3602 transaction.data = "rg: 70-79 "; 3603 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3604 3605 Verify206Response(headers, 70, 79); 3606 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3607 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3608 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3609 3610 // Now we'll issue a request that results in a plain 200 response, but to 3611 // the to the same URL that we used to store sparse data, and making sure 3612 // that we ask for a range. 3613 RemoveMockTransaction(&kRangeGET_TransactionOK); 3614 MockTransaction transaction2(kSimpleGET_Transaction); 3615 transaction2.url = kRangeGET_TransactionOK.url; 3616 transaction2.request_headers = kRangeGET_TransactionOK.request_headers; 3617 AddMockTransaction(&transaction2); 3618 3619 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); 3620 3621 std::string expected_headers(kSimpleGET_Transaction.status); 3622 expected_headers.append("\n"); 3623 expected_headers.append(kSimpleGET_Transaction.response_headers); 3624 EXPECT_EQ(expected_headers, headers); 3625 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3626 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3627 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3628 3629 RemoveMockTransaction(&transaction2); 3630 } 3631 3632 // Tests that a range request that falls outside of the size that we know about 3633 // only deletes the entry if the resource has indeed changed. 3634 TEST(HttpCache, RangeGET_MoreThanCurrentSize) { 3635 MockHttpCache cache; 3636 AddMockTransaction(&kRangeGET_TransactionOK); 3637 std::string headers; 3638 3639 // Write to the cache (40-49). 3640 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3641 &headers); 3642 3643 Verify206Response(headers, 40, 49); 3644 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3645 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3646 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3647 3648 // A weird request should not delete this entry. Ask for bytes 120-. 3649 MockTransaction transaction(kRangeGET_TransactionOK); 3650 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER; 3651 transaction.data = ""; 3652 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3653 3654 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 ")); 3655 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3656 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3657 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3658 3659 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3660 EXPECT_EQ(2, cache.disk_cache()->open_count()); 3661 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3662 3663 RemoveMockTransaction(&kRangeGET_TransactionOK); 3664 } 3665 3666 // Tests that we don't delete a sparse entry when we cancel a request. 3667 TEST(HttpCache, RangeGET_Cancel) { 3668 MockHttpCache cache; 3669 AddMockTransaction(&kRangeGET_TransactionOK); 3670 3671 MockHttpRequest request(kRangeGET_TransactionOK); 3672 3673 Context* c = new Context(); 3674 int rv = cache.http_cache()->CreateTransaction(&c->trans); 3675 EXPECT_EQ(net::OK, rv); 3676 3677 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 3678 if (rv == net::ERR_IO_PENDING) 3679 rv = c->callback.WaitForResult(); 3680 3681 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3682 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3683 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3684 3685 // Make sure that the entry has some data stored. 3686 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 3687 rv = c->trans->Read(buf, buf->size(), &c->callback); 3688 if (rv == net::ERR_IO_PENDING) 3689 rv = c->callback.WaitForResult(); 3690 EXPECT_EQ(buf->size(), rv); 3691 3692 // Destroy the transaction. 3693 delete c; 3694 3695 // Verify that the entry has not been deleted. 3696 disk_cache::Entry* entry; 3697 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 3698 entry->Close(); 3699 RemoveMockTransaction(&kRangeGET_TransactionOK); 3700 } 3701 3702 // Tests that we don't delete a sparse entry when we start a new request after 3703 // cancelling the previous one. 3704 TEST(HttpCache, RangeGET_Cancel2) { 3705 MockHttpCache cache; 3706 AddMockTransaction(&kRangeGET_TransactionOK); 3707 3708 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3709 MockHttpRequest request(kRangeGET_TransactionOK); 3710 request.load_flags |= net::LOAD_VALIDATE_CACHE; 3711 3712 Context* c = new Context(); 3713 int rv = cache.http_cache()->CreateTransaction(&c->trans); 3714 EXPECT_EQ(net::OK, rv); 3715 3716 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 3717 if (rv == net::ERR_IO_PENDING) 3718 rv = c->callback.WaitForResult(); 3719 3720 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3721 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3722 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3723 3724 // Make sure that we revalidate the entry and read from the cache (a single 3725 // read will return while waiting for the network). 3726 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5)); 3727 rv = c->trans->Read(buf, buf->size(), &c->callback); 3728 EXPECT_EQ(5, c->callback.GetResult(rv)); 3729 rv = c->trans->Read(buf, buf->size(), &c->callback); 3730 EXPECT_EQ(net::ERR_IO_PENDING, rv); 3731 3732 // Destroy the transaction before completing the read. 3733 delete c; 3734 3735 // We have the read and the delete (OnProcessPendingQueue) waiting on the 3736 // message loop. This means that a new transaction will just reuse the same 3737 // active entry (no open or create). 3738 3739 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3740 3741 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3742 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3743 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3744 RemoveMockTransaction(&kRangeGET_TransactionOK); 3745 } 3746 3747 // A slight variation of the previous test, this time we cancel two requests in 3748 // a row, making sure that the second is waiting for the entry to be ready. 3749 TEST(HttpCache, RangeGET_Cancel3) { 3750 MockHttpCache cache; 3751 AddMockTransaction(&kRangeGET_TransactionOK); 3752 3753 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3754 MockHttpRequest request(kRangeGET_TransactionOK); 3755 request.load_flags |= net::LOAD_VALIDATE_CACHE; 3756 3757 Context* c = new Context(); 3758 int rv = cache.http_cache()->CreateTransaction(&c->trans); 3759 EXPECT_EQ(net::OK, rv); 3760 3761 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 3762 EXPECT_EQ(net::ERR_IO_PENDING, rv); 3763 rv = c->callback.WaitForResult(); 3764 3765 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3766 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3767 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3768 3769 // Make sure that we revalidate the entry and read from the cache (a single 3770 // read will return while waiting for the network). 3771 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5)); 3772 rv = c->trans->Read(buf, buf->size(), &c->callback); 3773 EXPECT_EQ(5, c->callback.GetResult(rv)); 3774 rv = c->trans->Read(buf, buf->size(), &c->callback); 3775 EXPECT_EQ(net::ERR_IO_PENDING, rv); 3776 3777 // Destroy the transaction before completing the read. 3778 delete c; 3779 3780 // We have the read and the delete (OnProcessPendingQueue) waiting on the 3781 // message loop. This means that a new transaction will just reuse the same 3782 // active entry (no open or create). 3783 3784 c = new Context(); 3785 rv = cache.http_cache()->CreateTransaction(&c->trans); 3786 EXPECT_EQ(net::OK, rv); 3787 3788 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 3789 EXPECT_EQ(net::ERR_IO_PENDING, rv); 3790 3791 MockDiskEntry::IgnoreCallbacks(true); 3792 MessageLoop::current()->RunAllPending(); 3793 MockDiskEntry::IgnoreCallbacks(false); 3794 3795 // The new transaction is waiting for the query range callback. 3796 delete c; 3797 3798 // And we should not crash when the callback is delivered. 3799 MessageLoop::current()->RunAllPending(); 3800 3801 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3802 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3803 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3804 RemoveMockTransaction(&kRangeGET_TransactionOK); 3805 } 3806 3807 // Tests that an invalid range response results in no cached entry. 3808 TEST(HttpCache, RangeGET_InvalidResponse1) { 3809 MockHttpCache cache; 3810 std::string headers; 3811 3812 MockTransaction transaction(kRangeGET_TransactionOK); 3813 transaction.handler = NULL; 3814 transaction.response_headers = "Content-Range: bytes 40-49/45\n" 3815 "Content-Length: 10\n"; 3816 AddMockTransaction(&transaction); 3817 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3818 3819 std::string expected(transaction.status); 3820 expected.append("\n"); 3821 expected.append(transaction.response_headers); 3822 EXPECT_EQ(expected, headers); 3823 3824 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3825 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3826 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3827 3828 // Verify that we don't have a cached entry. 3829 disk_cache::Entry* entry; 3830 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 3831 3832 RemoveMockTransaction(&kRangeGET_TransactionOK); 3833 } 3834 3835 // Tests that we reject a range that doesn't match the content-length. 3836 TEST(HttpCache, RangeGET_InvalidResponse2) { 3837 MockHttpCache cache; 3838 std::string headers; 3839 3840 MockTransaction transaction(kRangeGET_TransactionOK); 3841 transaction.handler = NULL; 3842 transaction.response_headers = "Content-Range: bytes 40-49/80\n" 3843 "Content-Length: 20\n"; 3844 AddMockTransaction(&transaction); 3845 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3846 3847 std::string expected(transaction.status); 3848 expected.append("\n"); 3849 expected.append(transaction.response_headers); 3850 EXPECT_EQ(expected, headers); 3851 3852 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3853 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3854 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3855 3856 // Verify that we don't have a cached entry. 3857 disk_cache::Entry* entry; 3858 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 3859 3860 RemoveMockTransaction(&kRangeGET_TransactionOK); 3861 } 3862 3863 // Tests that if a server tells us conflicting information about a resource we 3864 // ignore the response. 3865 TEST(HttpCache, RangeGET_InvalidResponse3) { 3866 MockHttpCache cache; 3867 std::string headers; 3868 3869 MockTransaction transaction(kRangeGET_TransactionOK); 3870 transaction.handler = NULL; 3871 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER; 3872 std::string response_headers(transaction.response_headers); 3873 response_headers.append("Content-Range: bytes 50-59/160\n"); 3874 transaction.response_headers = response_headers.c_str(); 3875 AddMockTransaction(&transaction); 3876 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3877 3878 Verify206Response(headers, 50, 59); 3879 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3880 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3881 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3882 3883 RemoveMockTransaction(&transaction); 3884 AddMockTransaction(&kRangeGET_TransactionOK); 3885 3886 // This transaction will report a resource size of 80 bytes, and we think it's 3887 // 160 so we should ignore the response. 3888 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 3889 &headers); 3890 3891 Verify206Response(headers, 40, 49); 3892 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3893 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3894 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3895 3896 // Verify that we cached the first response but not the second one. 3897 disk_cache::Entry* en; 3898 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en)); 3899 3900 int64 cached_start = 0; 3901 TestCompletionCallback cb; 3902 int rv = en->GetAvailableRange(40, 20, &cached_start, &cb); 3903 EXPECT_EQ(10, cb.GetResult(rv)); 3904 EXPECT_EQ(50, cached_start); 3905 en->Close(); 3906 3907 RemoveMockTransaction(&kRangeGET_TransactionOK); 3908 } 3909 3910 // Tests that we handle large range values properly. 3911 TEST(HttpCache, RangeGET_LargeValues) { 3912 // We need a real sparse cache for this test. 3913 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024)); 3914 std::string headers; 3915 3916 MockTransaction transaction(kRangeGET_TransactionOK); 3917 transaction.handler = NULL; 3918 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n" 3919 EXTRA_HEADER; 3920 transaction.response_headers = 3921 "ETag: \"foo\"\n" 3922 "Content-Range: bytes 4294967288-4294967297/4294967299\n" 3923 "Content-Length: 10\n"; 3924 AddMockTransaction(&transaction); 3925 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3926 3927 std::string expected(transaction.status); 3928 expected.append("\n"); 3929 expected.append(transaction.response_headers); 3930 EXPECT_EQ(expected, headers); 3931 3932 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3933 3934 // Verify that we have a cached entry. 3935 disk_cache::Entry* en; 3936 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en)); 3937 en->Close(); 3938 3939 RemoveMockTransaction(&kRangeGET_TransactionOK); 3940 } 3941 3942 // Tests that we don't crash with a range request if the disk cache was not 3943 // initialized properly. 3944 TEST(HttpCache, RangeGET_NoDiskCache) { 3945 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); 3946 factory->set_fail(true); 3947 factory->FinishCreation(); // We'll complete synchronously. 3948 MockHttpCache cache(factory); 3949 3950 AddMockTransaction(&kRangeGET_TransactionOK); 3951 3952 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3953 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3954 3955 RemoveMockTransaction(&kRangeGET_TransactionOK); 3956 } 3957 3958 // Tests that we handle byte range requests that skip the cache. 3959 TEST(HttpCache, RangeHEAD) { 3960 MockHttpCache cache; 3961 AddMockTransaction(&kRangeGET_TransactionOK); 3962 3963 MockTransaction transaction(kRangeGET_TransactionOK); 3964 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER; 3965 transaction.method = "HEAD"; 3966 transaction.data = "rg: 70-79 "; 3967 3968 std::string headers; 3969 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3970 3971 Verify206Response(headers, 70, 79); 3972 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3973 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3974 EXPECT_EQ(0, cache.disk_cache()->create_count()); 3975 3976 RemoveMockTransaction(&kRangeGET_TransactionOK); 3977 } 3978 3979 // Tests that we don't crash when after reading from the cache we issue a 3980 // request for the next range and the server gives us a 200 synchronously. 3981 TEST(HttpCache, RangeGET_FastFlakyServer) { 3982 MockHttpCache cache; 3983 3984 MockTransaction transaction(kRangeGET_TransactionOK); 3985 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; 3986 transaction.test_mode = TEST_MODE_SYNC_NET_START; 3987 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 3988 AddMockTransaction(&transaction); 3989 3990 // Write to the cache. 3991 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 3992 3993 // And now read from the cache and the network. 3994 RangeTransactionServer handler; 3995 handler.set_bad_200(true); 3996 transaction.data = "Not a range"; 3997 RunTransactionTest(cache.http_cache(), transaction); 3998 3999 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 4000 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4001 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4002 4003 RemoveMockTransaction(&transaction); 4004 } 4005 4006 // Tests that when the server gives us less data than expected, we don't keep 4007 // asking for more data. 4008 TEST(HttpCache, RangeGET_FastFlakyServer2) { 4009 MockHttpCache cache; 4010 4011 // First, check with an empty cache (WRITE mode). 4012 MockTransaction transaction(kRangeGET_TransactionOK); 4013 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER; 4014 transaction.data = "rg: 40-"; // Less than expected. 4015 transaction.handler = NULL; 4016 std::string headers(transaction.response_headers); 4017 headers.append("Content-Range: bytes 40-49/80\n"); 4018 transaction.response_headers = headers.c_str(); 4019 4020 AddMockTransaction(&transaction); 4021 4022 // Write to the cache. 4023 RunTransactionTest(cache.http_cache(), transaction); 4024 4025 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4026 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4027 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4028 4029 // Now verify that even in READ_WRITE mode, we forward the bad response to 4030 // the caller. 4031 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER; 4032 transaction.data = "rg: 60-"; // Less than expected. 4033 headers = kRangeGET_TransactionOK.response_headers; 4034 headers.append("Content-Range: bytes 60-69/80\n"); 4035 transaction.response_headers = headers.c_str(); 4036 4037 RunTransactionTest(cache.http_cache(), transaction); 4038 4039 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4040 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4041 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4042 4043 RemoveMockTransaction(&transaction); 4044 } 4045 4046 #ifdef NDEBUG 4047 // This test hits a NOTREACHED so it is a release mode only test. 4048 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) { 4049 MockHttpCache cache; 4050 AddMockTransaction(&kRangeGET_TransactionOK); 4051 4052 // Write to the cache (40-49). 4053 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 4054 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4055 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4056 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4057 4058 // Force this transaction to read from the cache. 4059 MockTransaction transaction(kRangeGET_TransactionOK); 4060 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 4061 4062 MockHttpRequest request(transaction); 4063 TestCompletionCallback callback; 4064 4065 scoped_ptr<net::HttpTransaction> trans; 4066 int rv = cache.http_cache()->CreateTransaction(&trans); 4067 EXPECT_EQ(net::OK, rv); 4068 ASSERT_TRUE(trans.get()); 4069 4070 rv = trans->Start(&request, &callback, net::BoundNetLog()); 4071 if (rv == net::ERR_IO_PENDING) 4072 rv = callback.WaitForResult(); 4073 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 4074 4075 trans.reset(); 4076 4077 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4078 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4079 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4080 4081 RemoveMockTransaction(&kRangeGET_TransactionOK); 4082 } 4083 #endif 4084 4085 // Tests the handling of the "truncation" flag. 4086 TEST(HttpCache, WriteResponseInfo_Truncated) { 4087 MockHttpCache cache; 4088 disk_cache::Entry* entry; 4089 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry, 4090 NULL)); 4091 4092 std::string headers("HTTP/1.1 200 OK"); 4093 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size()); 4094 net::HttpResponseInfo response; 4095 response.headers = new net::HttpResponseHeaders(headers); 4096 4097 // Set the last argument for this to be an incomplete request. 4098 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); 4099 bool truncated = false; 4100 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4101 EXPECT_TRUE(truncated); 4102 4103 // And now test the opposite case. 4104 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false)); 4105 truncated = true; 4106 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4107 EXPECT_FALSE(truncated); 4108 entry->Close(); 4109 } 4110 4111 // Tests basic pickling/unpickling of HttpResponseInfo. 4112 TEST(HttpCache, PersistHttpResponseInfo) { 4113 // Set some fields (add more if needed.) 4114 net::HttpResponseInfo response1; 4115 response1.was_cached = false; 4116 response1.socket_address = net::HostPortPair("1.2.3.4", 80); 4117 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK"); 4118 4119 // Pickle. 4120 Pickle pickle; 4121 response1.Persist(&pickle, false, false); 4122 4123 // Unpickle. 4124 net::HttpResponseInfo response2; 4125 bool response_truncated; 4126 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated)); 4127 EXPECT_FALSE(response_truncated); 4128 4129 // Verify fields. 4130 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag. 4131 EXPECT_EQ("1.2.3.4", response2.socket_address.host()); 4132 EXPECT_EQ(80, response2.socket_address.port()); 4133 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 4134 } 4135 4136 // Tests that we delete an entry when the request is cancelled before starting 4137 // to read from the network. 4138 TEST(HttpCache, DoomOnDestruction) { 4139 MockHttpCache cache; 4140 4141 MockHttpRequest request(kSimpleGET_Transaction); 4142 4143 Context* c = new Context(); 4144 int rv = cache.http_cache()->CreateTransaction(&c->trans); 4145 EXPECT_EQ(net::OK, rv); 4146 4147 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 4148 if (rv == net::ERR_IO_PENDING) 4149 c->result = c->callback.WaitForResult(); 4150 4151 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4152 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4153 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4154 4155 // Destroy the transaction. We only have the headers so we should delete this 4156 // entry. 4157 delete c; 4158 4159 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4160 4161 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4162 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4163 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4164 } 4165 4166 // Tests that we delete an entry when the request is cancelled if the response 4167 // does not have content-length and strong validators. 4168 TEST(HttpCache, DoomOnDestruction2) { 4169 MockHttpCache cache; 4170 4171 MockHttpRequest request(kSimpleGET_Transaction); 4172 4173 Context* c = new Context(); 4174 int rv = cache.http_cache()->CreateTransaction(&c->trans); 4175 EXPECT_EQ(net::OK, rv); 4176 4177 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 4178 if (rv == net::ERR_IO_PENDING) 4179 rv = c->callback.WaitForResult(); 4180 4181 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4182 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4183 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4184 4185 // Make sure that the entry has some data stored. 4186 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4187 rv = c->trans->Read(buf, buf->size(), &c->callback); 4188 if (rv == net::ERR_IO_PENDING) 4189 rv = c->callback.WaitForResult(); 4190 EXPECT_EQ(buf->size(), rv); 4191 4192 // Destroy the transaction. 4193 delete c; 4194 4195 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4196 4197 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4198 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4199 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4200 } 4201 4202 // Tests that we delete an entry when the request is cancelled if the response 4203 // has an "Accept-Ranges: none" header. 4204 TEST(HttpCache, DoomOnDestruction3) { 4205 MockHttpCache cache; 4206 4207 MockTransaction transaction(kSimpleGET_Transaction); 4208 transaction.response_headers = 4209 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 4210 "Content-Length: 22\n" 4211 "Accept-Ranges: none\n" 4212 "Etag: foopy\n"; 4213 AddMockTransaction(&transaction); 4214 MockHttpRequest request(transaction); 4215 4216 Context* c = new Context(); 4217 int rv = cache.http_cache()->CreateTransaction(&c->trans); 4218 EXPECT_EQ(net::OK, rv); 4219 4220 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 4221 if (rv == net::ERR_IO_PENDING) 4222 rv = c->callback.WaitForResult(); 4223 4224 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4225 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4226 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4227 4228 // Make sure that the entry has some data stored. 4229 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4230 rv = c->trans->Read(buf, buf->size(), &c->callback); 4231 if (rv == net::ERR_IO_PENDING) 4232 rv = c->callback.WaitForResult(); 4233 EXPECT_EQ(buf->size(), rv); 4234 4235 // Destroy the transaction. 4236 delete c; 4237 4238 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4239 4240 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4241 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4242 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4243 4244 RemoveMockTransaction(&transaction); 4245 } 4246 4247 // Tests that we mark an entry as incomplete when the request is cancelled. 4248 TEST(HttpCache, Set_Truncated_Flag) { 4249 MockHttpCache cache; 4250 4251 MockTransaction transaction(kSimpleGET_Transaction); 4252 transaction.response_headers = 4253 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 4254 "Content-Length: 22\n" 4255 "Etag: foopy\n"; 4256 AddMockTransaction(&transaction); 4257 MockHttpRequest request(transaction); 4258 4259 scoped_ptr<Context> c(new Context()); 4260 int rv = cache.http_cache()->CreateTransaction(&c->trans); 4261 EXPECT_EQ(net::OK, rv); 4262 4263 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 4264 if (rv == net::ERR_IO_PENDING) 4265 rv = c->callback.WaitForResult(); 4266 4267 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4268 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4269 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4270 4271 // Make sure that the entry has some data stored. 4272 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10)); 4273 rv = c->trans->Read(buf, buf->size(), &c->callback); 4274 if (rv == net::ERR_IO_PENDING) 4275 rv = c->callback.WaitForResult(); 4276 EXPECT_EQ(buf->size(), rv); 4277 4278 // We want to cancel the request when the transaction is busy. 4279 rv = c->trans->Read(buf, buf->size(), &c->callback); 4280 EXPECT_EQ(net::ERR_IO_PENDING, rv); 4281 EXPECT_FALSE(c->callback.have_result()); 4282 4283 g_test_mode = TEST_MODE_SYNC_ALL; 4284 4285 // Destroy the transaction. 4286 c->trans.reset(); 4287 g_test_mode = 0; 4288 4289 // Make sure that we don't invoke the callback. We may have an issue if the 4290 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we 4291 // could end up with the transaction being deleted twice if we send any 4292 // notification from the transaction destructor (see http://crbug.com/31723). 4293 EXPECT_FALSE(c->callback.have_result()); 4294 4295 // Verify that the entry is marked as incomplete. 4296 disk_cache::Entry* entry; 4297 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry)); 4298 net::HttpResponseInfo response; 4299 bool truncated = false; 4300 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4301 EXPECT_TRUE(truncated); 4302 entry->Close(); 4303 4304 RemoveMockTransaction(&transaction); 4305 } 4306 4307 // Tests that we can continue with a request that was interrupted. 4308 TEST(HttpCache, GET_IncompleteResource) { 4309 MockHttpCache cache; 4310 AddMockTransaction(&kRangeGET_TransactionOK); 4311 4312 std::string raw_headers("HTTP/1.1 200 OK\n" 4313 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 4314 "ETag: \"foo\"\n" 4315 "Accept-Ranges: bytes\n" 4316 "Content-Length: 80\n"); 4317 CreateTruncatedEntry(raw_headers, &cache); 4318 4319 // Now make a regular request. 4320 std::string headers; 4321 MockTransaction transaction(kRangeGET_TransactionOK); 4322 transaction.request_headers = EXTRA_HEADER; 4323 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 4324 "rg: 50-59 rg: 60-69 rg: 70-79 "; 4325 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4326 4327 // We update the headers with the ones received while revalidating. 4328 std::string expected_headers( 4329 "HTTP/1.1 200 OK\n" 4330 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 4331 "Accept-Ranges: bytes\n" 4332 "ETag: \"foo\"\n" 4333 "Content-Length: 80\n"); 4334 4335 EXPECT_EQ(expected_headers, headers); 4336 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4337 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4338 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4339 4340 // Verify that the disk entry was updated. 4341 disk_cache::Entry* entry; 4342 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4343 EXPECT_EQ(80, entry->GetDataSize(1)); 4344 bool truncated = true; 4345 net::HttpResponseInfo response; 4346 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4347 EXPECT_FALSE(truncated); 4348 entry->Close(); 4349 4350 RemoveMockTransaction(&kRangeGET_TransactionOK); 4351 } 4352 4353 // Tests that we delete truncated entries if the server changes its mind midway. 4354 TEST(HttpCache, GET_IncompleteResource2) { 4355 MockHttpCache cache; 4356 AddMockTransaction(&kRangeGET_TransactionOK); 4357 4358 // Content-length will be intentionally bad. 4359 std::string raw_headers("HTTP/1.1 200 OK\n" 4360 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 4361 "ETag: \"foo\"\n" 4362 "Accept-Ranges: bytes\n" 4363 "Content-Length: 50\n"); 4364 CreateTruncatedEntry(raw_headers, &cache); 4365 4366 // Now make a regular request. We expect the code to fail the validation and 4367 // retry the request without using byte ranges. 4368 std::string headers; 4369 MockTransaction transaction(kRangeGET_TransactionOK); 4370 transaction.request_headers = EXTRA_HEADER; 4371 transaction.data = "Not a range"; 4372 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4373 4374 // The server will return 200 instead of a byte range. 4375 std::string expected_headers( 4376 "HTTP/1.1 200 OK\n" 4377 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); 4378 4379 EXPECT_EQ(expected_headers, headers); 4380 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4381 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4382 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4383 4384 // Verify that the disk entry was deleted. 4385 disk_cache::Entry* entry; 4386 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4387 RemoveMockTransaction(&kRangeGET_TransactionOK); 4388 } 4389 4390 // Tests that we always validate a truncated request. 4391 TEST(HttpCache, GET_IncompleteResource3) { 4392 MockHttpCache cache; 4393 AddMockTransaction(&kRangeGET_TransactionOK); 4394 4395 // This should not require validation for 10 hours. 4396 std::string raw_headers("HTTP/1.1 200 OK\n" 4397 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 4398 "ETag: \"foo\"\n" 4399 "Cache-Control: max-age= 36000\n" 4400 "Accept-Ranges: bytes\n" 4401 "Content-Length: 80\n"); 4402 CreateTruncatedEntry(raw_headers, &cache); 4403 4404 // Now make a regular request. 4405 std::string headers; 4406 MockTransaction transaction(kRangeGET_TransactionOK); 4407 transaction.request_headers = EXTRA_HEADER; 4408 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " 4409 "rg: 50-59 rg: 60-69 rg: 70-79 "; 4410 4411 scoped_ptr<Context> c(new Context); 4412 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans)); 4413 4414 MockHttpRequest request(transaction); 4415 int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 4416 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 4417 4418 // We should have checked with the server before finishing Start(). 4419 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4420 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4421 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4422 4423 RemoveMockTransaction(&kRangeGET_TransactionOK); 4424 } 4425 4426 // Tests that we cache a 200 response to the validation request. 4427 TEST(HttpCache, GET_IncompleteResource4) { 4428 MockHttpCache cache; 4429 AddMockTransaction(&kRangeGET_TransactionOK); 4430 4431 std::string raw_headers("HTTP/1.1 200 OK\n" 4432 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 4433 "ETag: \"foo\"\n" 4434 "Accept-Ranges: bytes\n" 4435 "Content-Length: 80\n"); 4436 CreateTruncatedEntry(raw_headers, &cache); 4437 4438 // Now make a regular request. 4439 std::string headers; 4440 MockTransaction transaction(kRangeGET_TransactionOK); 4441 transaction.request_headers = EXTRA_HEADER; 4442 transaction.data = "Not a range"; 4443 RangeTransactionServer handler; 4444 handler.set_bad_200(true); 4445 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4446 4447 EXPECT_EQ(1, 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 the disk entry was updated. 4452 disk_cache::Entry* entry; 4453 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4454 EXPECT_EQ(11, entry->GetDataSize(1)); 4455 bool truncated = true; 4456 net::HttpResponseInfo response; 4457 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4458 EXPECT_FALSE(truncated); 4459 entry->Close(); 4460 4461 RemoveMockTransaction(&kRangeGET_TransactionOK); 4462 } 4463 4464 // Tests that when we cancel a request that was interrupted, we mark it again 4465 // as truncated. 4466 TEST(HttpCache, GET_CancelIncompleteResource) { 4467 MockHttpCache cache; 4468 AddMockTransaction(&kRangeGET_TransactionOK); 4469 4470 std::string raw_headers("HTTP/1.1 200 OK\n" 4471 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 4472 "ETag: \"foo\"\n" 4473 "Accept-Ranges: bytes\n" 4474 "Content-Length: 80\n"); 4475 CreateTruncatedEntry(raw_headers, &cache); 4476 4477 // Now make a regular request. 4478 MockTransaction transaction(kRangeGET_TransactionOK); 4479 transaction.request_headers = EXTRA_HEADER; 4480 4481 MockHttpRequest request(transaction); 4482 Context* c = new Context(); 4483 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans)); 4484 4485 int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); 4486 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); 4487 4488 // Read 20 bytes from the cache, and 10 from the net. 4489 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); 4490 rv = c->trans->Read(buf, 20, &c->callback); 4491 EXPECT_EQ(20, c->callback.GetResult(rv)); 4492 rv = c->trans->Read(buf, 10, &c->callback); 4493 EXPECT_EQ(10, c->callback.GetResult(rv)); 4494 4495 // At this point, we are already reading so canceling the request should leave 4496 // a truncated one. 4497 delete c; 4498 4499 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4500 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4501 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4502 4503 // Verify that the disk entry was updated: now we have 30 bytes. 4504 disk_cache::Entry* entry; 4505 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 4506 EXPECT_EQ(30, entry->GetDataSize(1)); 4507 bool truncated = false; 4508 net::HttpResponseInfo response; 4509 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 4510 EXPECT_TRUE(truncated); 4511 entry->Close(); 4512 RemoveMockTransaction(&kRangeGET_TransactionOK); 4513 } 4514 4515 // Tests that we can handle range requests when we have a truncated entry. 4516 TEST(HttpCache, RangeGET_IncompleteResource) { 4517 MockHttpCache cache; 4518 AddMockTransaction(&kRangeGET_TransactionOK); 4519 4520 // Content-length will be intentionally bogus. 4521 std::string raw_headers("HTTP/1.1 200 OK\n" 4522 "Last-Modified: something\n" 4523 "ETag: \"foo\"\n" 4524 "Accept-Ranges: bytes\n" 4525 "Content-Length: 10\n"); 4526 CreateTruncatedEntry(raw_headers, &cache); 4527 4528 // Now make a range request. 4529 std::string headers; 4530 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, 4531 &headers); 4532 4533 Verify206Response(headers, 40, 49); 4534 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4535 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4536 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4537 4538 RemoveMockTransaction(&kRangeGET_TransactionOK); 4539 } 4540 4541 TEST(HttpCache, SyncRead) { 4542 MockHttpCache cache; 4543 4544 // This test ensures that a read that completes synchronously does not cause 4545 // any problems. 4546 4547 ScopedMockTransaction transaction(kSimpleGET_Transaction); 4548 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START | 4549 TEST_MODE_SYNC_CACHE_READ | 4550 TEST_MODE_SYNC_CACHE_WRITE); 4551 4552 MockHttpRequest r1(transaction), 4553 r2(transaction), 4554 r3(transaction); 4555 4556 TestTransactionConsumer c1(cache.http_cache()), 4557 c2(cache.http_cache()), 4558 c3(cache.http_cache()); 4559 4560 c1.Start(&r1, net::BoundNetLog()); 4561 4562 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE; 4563 c2.Start(&r2, net::BoundNetLog()); 4564 4565 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE; 4566 c3.Start(&r3, net::BoundNetLog()); 4567 4568 MessageLoop::current()->Run(); 4569 4570 EXPECT_TRUE(c1.is_done()); 4571 EXPECT_TRUE(c2.is_done()); 4572 EXPECT_TRUE(c3.is_done()); 4573 4574 EXPECT_EQ(net::OK, c1.error()); 4575 EXPECT_EQ(net::OK, c2.error()); 4576 EXPECT_EQ(net::OK, c3.error()); 4577 } 4578 4579 TEST(HttpCache, ValidationResultsIn200) { 4580 MockHttpCache cache; 4581 4582 // This test ensures that a conditional request, which results in a 200 4583 // instead of a 304, properly truncates the existing response data. 4584 4585 // write to the cache 4586 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 4587 4588 // force this transaction to validate the cache 4589 MockTransaction transaction(kETagGET_Transaction); 4590 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; 4591 RunTransactionTest(cache.http_cache(), transaction); 4592 4593 // read from the cache 4594 RunTransactionTest(cache.http_cache(), kETagGET_Transaction); 4595 } 4596 4597 TEST(HttpCache, CachedRedirect) { 4598 MockHttpCache cache; 4599 4600 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction); 4601 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently"; 4602 kTestTransaction.response_headers = "Location: http://www.bar.com/\n"; 4603 4604 MockHttpRequest request(kTestTransaction); 4605 TestCompletionCallback callback; 4606 4607 // write to the cache 4608 { 4609 scoped_ptr<net::HttpTransaction> trans; 4610 int rv = cache.http_cache()->CreateTransaction(&trans); 4611 EXPECT_EQ(net::OK, rv); 4612 ASSERT_TRUE(trans.get()); 4613 4614 rv = trans->Start(&request, &callback, net::BoundNetLog()); 4615 if (rv == net::ERR_IO_PENDING) 4616 rv = callback.WaitForResult(); 4617 ASSERT_EQ(net::OK, rv); 4618 4619 const net::HttpResponseInfo* info = trans->GetResponseInfo(); 4620 ASSERT_TRUE(info); 4621 4622 EXPECT_EQ(info->headers->response_code(), 301); 4623 4624 std::string location; 4625 info->headers->EnumerateHeader(NULL, "Location", &location); 4626 EXPECT_EQ(location, "http://www.bar.com/"); 4627 4628 // Destroy transaction when going out of scope. We have not actually 4629 // read the response body -- want to test that it is still getting cached. 4630 } 4631 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4632 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4633 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4634 4635 // read from the cache 4636 { 4637 scoped_ptr<net::HttpTransaction> trans; 4638 int rv = cache.http_cache()->CreateTransaction(&trans); 4639 EXPECT_EQ(net::OK, rv); 4640 ASSERT_TRUE(trans.get()); 4641 4642 rv = trans->Start(&request, &callback, net::BoundNetLog()); 4643 if (rv == net::ERR_IO_PENDING) 4644 rv = callback.WaitForResult(); 4645 ASSERT_EQ(net::OK, rv); 4646 4647 const net::HttpResponseInfo* info = trans->GetResponseInfo(); 4648 ASSERT_TRUE(info); 4649 4650 EXPECT_EQ(info->headers->response_code(), 301); 4651 4652 std::string location; 4653 info->headers->EnumerateHeader(NULL, "Location", &location); 4654 EXPECT_EQ(location, "http://www.bar.com/"); 4655 4656 // Destroy transaction when going out of scope. We have not actually 4657 // read the response body -- want to test that it is still getting cached. 4658 } 4659 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4660 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4661 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4662 } 4663 4664 TEST(HttpCache, CacheControlNoStore) { 4665 MockHttpCache cache; 4666 4667 ScopedMockTransaction transaction(kSimpleGET_Transaction); 4668 transaction.response_headers = "cache-control: no-store\n"; 4669 4670 // initial load 4671 RunTransactionTest(cache.http_cache(), transaction); 4672 4673 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4674 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4675 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4676 4677 // try loading again; it should result in a network fetch 4678 RunTransactionTest(cache.http_cache(), transaction); 4679 4680 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4681 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4682 EXPECT_EQ(2, cache.disk_cache()->create_count()); 4683 4684 disk_cache::Entry* entry; 4685 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry)); 4686 } 4687 4688 TEST(HttpCache, CacheControlNoStore2) { 4689 // this test is similar to the above test, except that the initial response 4690 // is cachable, but when it is validated, no-store is received causing the 4691 // cached document to be deleted. 4692 MockHttpCache cache; 4693 4694 ScopedMockTransaction transaction(kETagGET_Transaction); 4695 4696 // initial load 4697 RunTransactionTest(cache.http_cache(), transaction); 4698 4699 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4700 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4701 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4702 4703 // try loading again; it should result in a network fetch 4704 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 4705 transaction.response_headers = "cache-control: no-store\n"; 4706 RunTransactionTest(cache.http_cache(), transaction); 4707 4708 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4709 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4710 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4711 4712 disk_cache::Entry* entry; 4713 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry)); 4714 } 4715 4716 TEST(HttpCache, CacheControlNoStore3) { 4717 // this test is similar to the above test, except that the response is a 304 4718 // instead of a 200. this should never happen in practice, but it seems like 4719 // a good thing to verify that we still destroy the cache entry. 4720 MockHttpCache cache; 4721 4722 ScopedMockTransaction transaction(kETagGET_Transaction); 4723 4724 // initial load 4725 RunTransactionTest(cache.http_cache(), transaction); 4726 4727 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4728 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4729 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4730 4731 // try loading again; it should result in a network fetch 4732 transaction.load_flags = net::LOAD_VALIDATE_CACHE; 4733 transaction.response_headers = "cache-control: no-store\n"; 4734 transaction.status = "HTTP/1.1 304 Not Modified"; 4735 RunTransactionTest(cache.http_cache(), transaction); 4736 4737 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4738 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4739 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4740 4741 disk_cache::Entry* entry; 4742 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry)); 4743 } 4744 4745 // Ensure that we don't cache requests served over bad HTTPS. 4746 TEST(HttpCache, SimpleGET_SSLError) { 4747 MockHttpCache cache; 4748 4749 MockTransaction transaction = kSimpleGET_Transaction; 4750 transaction.cert_status = net::CERT_STATUS_REVOKED; 4751 ScopedMockTransaction scoped_transaction(transaction); 4752 4753 // write to the cache 4754 RunTransactionTest(cache.http_cache(), transaction); 4755 4756 // Test that it was not cached. 4757 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE; 4758 4759 MockHttpRequest request(transaction); 4760 TestCompletionCallback callback; 4761 4762 scoped_ptr<net::HttpTransaction> trans; 4763 int rv = cache.http_cache()->CreateTransaction(&trans); 4764 EXPECT_EQ(net::OK, rv); 4765 ASSERT_TRUE(trans.get()); 4766 4767 rv = trans->Start(&request, &callback, net::BoundNetLog()); 4768 if (rv == net::ERR_IO_PENDING) 4769 rv = callback.WaitForResult(); 4770 ASSERT_EQ(net::ERR_CACHE_MISS, rv); 4771 } 4772 4773 // Ensure that we don't crash by if left-behind transactions. 4774 TEST(HttpCache, OutlivedTransactions) { 4775 MockHttpCache* cache = new MockHttpCache; 4776 4777 scoped_ptr<net::HttpTransaction> trans; 4778 int rv = cache->http_cache()->CreateTransaction(&trans); 4779 EXPECT_EQ(net::OK, rv); 4780 4781 delete cache; 4782 trans.reset(); 4783 } 4784 4785 // Test that the disabled mode works. 4786 TEST(HttpCache, CacheDisabledMode) { 4787 MockHttpCache cache; 4788 4789 // write to the cache 4790 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 4791 4792 // go into disabled mode 4793 cache.http_cache()->set_mode(net::HttpCache::DISABLE); 4794 4795 // force this transaction to write to the cache again 4796 MockTransaction transaction(kSimpleGET_Transaction); 4797 4798 RunTransactionTest(cache.http_cache(), transaction); 4799 4800 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4801 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4802 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4803 } 4804 4805 // Other tests check that the response headers of the cached response 4806 // get updated on 304. Here we specifically check that the 4807 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time 4808 // fields also gets updated. 4809 // http://crbug.com/20594. 4810 TEST(HttpCache, UpdatesRequestResponseTimeOn304) { 4811 MockHttpCache cache; 4812 4813 const char* kUrl = "http://foobar"; 4814 const char* kData = "body"; 4815 4816 MockTransaction mock_network_response = { 0 }; 4817 mock_network_response.url = kUrl; 4818 4819 AddMockTransaction(&mock_network_response); 4820 4821 // Request |kUrl|, causing |kNetResponse1| to be written to the cache. 4822 4823 MockTransaction request = { 0 }; 4824 request.url = kUrl; 4825 request.method = "GET"; 4826 request.request_headers = ""; 4827 request.data = kData; 4828 4829 static const Response kNetResponse1 = { 4830 "HTTP/1.1 200 OK", 4831 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" 4832 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 4833 kData 4834 }; 4835 4836 kNetResponse1.AssignTo(&mock_network_response); 4837 4838 RunTransactionTest(cache.http_cache(), request); 4839 4840 // Request |kUrl| again, this time validating the cache and getting 4841 // a 304 back. 4842 4843 request.load_flags = net::LOAD_VALIDATE_CACHE; 4844 4845 static const Response kNetResponse2 = { 4846 "HTTP/1.1 304 Not Modified", 4847 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n", 4848 "" 4849 }; 4850 4851 kNetResponse2.AssignTo(&mock_network_response); 4852 4853 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234); 4854 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235); 4855 4856 mock_network_response.request_time = request_time; 4857 mock_network_response.response_time = response_time; 4858 4859 net::HttpResponseInfo response; 4860 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response); 4861 4862 // The request and response times should have been updated. 4863 EXPECT_EQ(request_time.ToInternalValue(), 4864 response.request_time.ToInternalValue()); 4865 EXPECT_EQ(response_time.ToInternalValue(), 4866 response.response_time.ToInternalValue()); 4867 4868 std::string headers; 4869 response.headers->GetNormalizedHeaders(&headers); 4870 4871 EXPECT_EQ("HTTP/1.1 200 OK\n" 4872 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" 4873 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", 4874 headers); 4875 4876 RemoveMockTransaction(&mock_network_response); 4877 } 4878 4879 // Tests that we can write metadata to an entry. 4880 TEST(HttpCache, WriteMetadata_OK) { 4881 MockHttpCache cache; 4882 4883 // Write to the cache 4884 net::HttpResponseInfo response; 4885 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 4886 &response); 4887 EXPECT_TRUE(response.metadata.get() == NULL); 4888 4889 // Trivial call. 4890 cache.http_cache()->WriteMetadata(GURL("foo"), Time::Now(), NULL, 0); 4891 4892 // Write meta data to the same entry. 4893 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50)); 4894 memset(buf->data(), 0, buf->size()); 4895 base::strlcpy(buf->data(), "Hi there", buf->size()); 4896 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), 4897 response.response_time, buf, buf->size()); 4898 4899 // Release the buffer before the operation takes place. 4900 buf = NULL; 4901 4902 // Makes sure we finish pending operations. 4903 MessageLoop::current()->RunAllPending(); 4904 4905 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 4906 &response); 4907 ASSERT_TRUE(response.metadata.get() != NULL); 4908 EXPECT_EQ(50, response.metadata->size()); 4909 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there")); 4910 4911 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4912 EXPECT_EQ(2, cache.disk_cache()->open_count()); 4913 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4914 } 4915 4916 // Tests that we only write metadata to an entry if the time stamp matches. 4917 TEST(HttpCache, WriteMetadata_Fail) { 4918 MockHttpCache cache; 4919 4920 // Write to the cache 4921 net::HttpResponseInfo response; 4922 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 4923 &response); 4924 EXPECT_TRUE(response.metadata.get() == NULL); 4925 4926 // Attempt to write meta data to the same entry. 4927 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50)); 4928 memset(buf->data(), 0, buf->size()); 4929 base::strlcpy(buf->data(), "Hi there", buf->size()); 4930 base::Time expected_time = response.response_time - 4931 base::TimeDelta::FromMilliseconds(20); 4932 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), 4933 expected_time, buf, buf->size()); 4934 4935 // Makes sure we finish pending operations. 4936 MessageLoop::current()->RunAllPending(); 4937 4938 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, 4939 &response); 4940 EXPECT_TRUE(response.metadata.get() == NULL); 4941 4942 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4943 EXPECT_EQ(2, cache.disk_cache()->open_count()); 4944 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4945 } 4946 4947 // Tests that we can read metadata after validating the entry and with READ mode 4948 // transactions. 4949 TEST(HttpCache, ReadMetadata) { 4950 MockHttpCache cache; 4951 4952 // Write to the cache 4953 net::HttpResponseInfo response; 4954 RunTransactionTestWithResponseInfo(cache.http_cache(), 4955 kTypicalGET_Transaction, &response); 4956 EXPECT_TRUE(response.metadata.get() == NULL); 4957 4958 // Write meta data to the same entry. 4959 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50)); 4960 memset(buf->data(), 0, buf->size()); 4961 base::strlcpy(buf->data(), "Hi there", buf->size()); 4962 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url), 4963 response.response_time, buf, buf->size()); 4964 4965 // Makes sure we finish pending operations. 4966 MessageLoop::current()->RunAllPending(); 4967 4968 // Start with a READ mode transaction. 4969 MockTransaction trans1(kTypicalGET_Transaction); 4970 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE; 4971 4972 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response); 4973 ASSERT_TRUE(response.metadata.get() != NULL); 4974 EXPECT_EQ(50, response.metadata->size()); 4975 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there")); 4976 4977 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4978 EXPECT_EQ(2, cache.disk_cache()->open_count()); 4979 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4980 MessageLoop::current()->RunAllPending(); 4981 4982 // Now make sure that the entry is re-validated with the server. 4983 trans1.load_flags = net::LOAD_VALIDATE_CACHE; 4984 trans1.status = "HTTP/1.1 304 Not Modified"; 4985 AddMockTransaction(&trans1); 4986 4987 response.metadata = NULL; 4988 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response); 4989 EXPECT_TRUE(response.metadata.get() != NULL); 4990 4991 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 4992 EXPECT_EQ(3, cache.disk_cache()->open_count()); 4993 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4994 MessageLoop::current()->RunAllPending(); 4995 RemoveMockTransaction(&trans1); 4996 4997 // Now return 200 when validating the entry so the metadata will be lost. 4998 MockTransaction trans2(kTypicalGET_Transaction); 4999 trans2.load_flags = net::LOAD_VALIDATE_CACHE; 5000 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response); 5001 EXPECT_TRUE(response.metadata.get() == NULL); 5002 5003 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 5004 EXPECT_EQ(4, cache.disk_cache()->open_count()); 5005 EXPECT_EQ(1, cache.disk_cache()->create_count()); 5006 } 5007