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