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