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.
5 #include "net/http/http_cache.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/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/test/simple_test_clock.h"
17 #include "net/base/cache_type.h"
18 #include "net/base/elements_upload_data_stream.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/load_flags.h"
21 #include "net/base/load_timing_info.h"
22 #include "net/base/load_timing_info_test_util.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/test_data_directory.h"
25 #include "net/base/upload_bytes_element_reader.h"
26 #include "net/cert/cert_status_flags.h"
27 #include "net/cert/x509_certificate.h"
28 #include "net/disk_cache/disk_cache.h"
29 #include "net/http/http_byte_range.h"
30 #include "net/http/http_cache_transaction.h"
31 #include "net/http/http_request_headers.h"
32 #include "net/http/http_request_info.h"
33 #include "net/http/http_response_headers.h"
34 #include "net/http/http_response_info.h"
35 #include "net/http/http_transaction.h"
36 #include "net/http/http_transaction_test_util.h"
37 #include "net/http/http_util.h"
38 #include "net/http/mock_http_cache.h"
39 #include "net/log/test_net_log.h"
40 #include "net/log/test_net_log_entry.h"
41 #include "net/log/test_net_log_util.h"
42 #include "net/socket/client_socket_handle.h"
43 #include "net/ssl/ssl_cert_request_info.h"
44 #include "net/ssl/ssl_connection_status_flags.h"
45 #include "net/test/cert_test_util.h"
46 #include "net/websockets/websocket_handshake_stream_base.h"
47 #include "testing/gtest/include/gtest/gtest.h"
55 // Tests the load timing values of a request that goes through a
56 // MockNetworkTransaction.
57 void TestLoadTimingNetworkRequest(const LoadTimingInfo
& load_timing_info
) {
58 EXPECT_FALSE(load_timing_info
.socket_reused
);
59 EXPECT_NE(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
61 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
62 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
64 ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
65 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
66 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
67 load_timing_info
.send_start
);
69 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
71 // Set by URLRequest / URLRequestHttpJob, at a higher level.
72 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
73 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
74 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
77 // Tests the load timing values of a request that receives a cached response.
78 void TestLoadTimingCachedResponse(const LoadTimingInfo
& load_timing_info
) {
79 EXPECT_FALSE(load_timing_info
.socket_reused
);
80 EXPECT_EQ(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
82 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
83 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
85 ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
87 // Only the send start / end times should be sent, and they should have the
89 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
90 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
92 // Set by URLRequest / URLRequestHttpJob, at a higher level.
93 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
94 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
95 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
98 class DeleteCacheCompletionCallback
: public TestCompletionCallbackBase
{
100 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
102 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
103 base::Unretained(this))) {
106 const CompletionCallback
& callback() const { return callback_
; }
109 void OnComplete(int result
) {
114 MockHttpCache
* cache_
;
115 CompletionCallback callback_
;
117 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
120 //-----------------------------------------------------------------------------
123 void ReadAndVerifyTransaction(HttpTransaction
* trans
,
124 const MockTransaction
& trans_info
) {
126 int rv
= ReadTransaction(trans
, &content
);
129 std::string
expected(trans_info
.data
);
130 EXPECT_EQ(expected
, content
);
133 void RunTransactionTestBase(HttpCache
* cache
,
134 const MockTransaction
& trans_info
,
135 const MockHttpRequest
& request
,
136 HttpResponseInfo
* response_info
,
137 const BoundNetLog
& net_log
,
138 LoadTimingInfo
* load_timing_info
,
139 int64
* received_bytes
) {
140 TestCompletionCallback callback
;
142 // write to the cache
144 scoped_ptr
<HttpTransaction
> trans
;
145 int rv
= cache
->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
147 ASSERT_TRUE(trans
.get());
149 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
150 if (rv
== ERR_IO_PENDING
)
151 rv
= callback
.WaitForResult();
152 ASSERT_EQ(trans_info
.return_code
, rv
);
157 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
158 ASSERT_TRUE(response
);
161 *response_info
= *response
;
163 if (load_timing_info
) {
164 // If a fake network connection is used, need a NetLog to get a fake socket
166 EXPECT_TRUE(net_log
.net_log());
167 *load_timing_info
= LoadTimingInfo();
168 trans
->GetLoadTimingInfo(load_timing_info
);
171 ReadAndVerifyTransaction(trans
.get(), trans_info
);
174 *received_bytes
= trans
->GetTotalReceivedBytes();
177 void RunTransactionTestWithRequest(HttpCache
* cache
,
178 const MockTransaction
& trans_info
,
179 const MockHttpRequest
& request
,
180 HttpResponseInfo
* response_info
) {
181 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
182 BoundNetLog(), NULL
, NULL
);
185 void RunTransactionTestAndGetTiming(HttpCache
* cache
,
186 const MockTransaction
& trans_info
,
187 const BoundNetLog
& log
,
188 LoadTimingInfo
* load_timing_info
) {
189 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
190 NULL
, log
, load_timing_info
, NULL
);
193 void RunTransactionTest(HttpCache
* cache
, const MockTransaction
& trans_info
) {
194 RunTransactionTestAndGetTiming(cache
, trans_info
, BoundNetLog(), NULL
);
197 void RunTransactionTestWithLog(HttpCache
* cache
,
198 const MockTransaction
& trans_info
,
199 const BoundNetLog
& log
) {
200 RunTransactionTestAndGetTiming(cache
, trans_info
, log
, NULL
);
203 void RunTransactionTestWithResponseInfo(HttpCache
* cache
,
204 const MockTransaction
& trans_info
,
205 HttpResponseInfo
* response
) {
206 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
210 void RunTransactionTestWithResponseInfoAndGetTiming(
212 const MockTransaction
& trans_info
,
213 HttpResponseInfo
* response
,
214 const BoundNetLog
& log
,
215 LoadTimingInfo
* load_timing_info
) {
216 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
217 response
, log
, load_timing_info
, NULL
);
220 void RunTransactionTestWithResponse(HttpCache
* cache
,
221 const MockTransaction
& trans_info
,
222 std::string
* response_headers
) {
223 HttpResponseInfo response
;
224 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
225 response
.headers
->GetNormalizedHeaders(response_headers
);
228 void RunTransactionTestWithResponseAndGetTiming(
230 const MockTransaction
& trans_info
,
231 std::string
* response_headers
,
232 const BoundNetLog
& log
,
233 LoadTimingInfo
* load_timing_info
) {
234 HttpResponseInfo response
;
235 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
236 &response
, log
, load_timing_info
, NULL
);
237 response
.headers
->GetNormalizedHeaders(response_headers
);
240 // This class provides a handler for kFastNoStoreGET_Transaction so that the
241 // no-store header can be included on demand.
242 class FastTransactionServer
{
244 FastTransactionServer() {
247 ~FastTransactionServer() {}
249 void set_no_store(bool value
) { no_store
= value
; }
251 static void FastNoStoreHandler(const HttpRequestInfo
* request
,
252 std::string
* response_status
,
253 std::string
* response_headers
,
254 std::string
* response_data
) {
256 *response_headers
= "Cache-Control: no-store\n";
260 static bool no_store
;
261 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
263 bool FastTransactionServer::no_store
;
265 const MockTransaction kFastNoStoreGET_Transaction
= {
266 "http://www.google.com/nostore",
272 "Cache-Control: max-age=10000\n",
274 "<html><body>Google Blah Blah</body></html>",
275 TEST_MODE_SYNC_NET_START
,
276 &FastTransactionServer::FastNoStoreHandler
,
282 // This class provides a handler for kRangeGET_TransactionOK so that the range
283 // request can be served on demand.
284 class RangeTransactionServer
{
286 RangeTransactionServer() {
287 not_modified_
= false;
291 ~RangeTransactionServer() {
292 not_modified_
= false;
297 // Returns only 416 or 304 when set.
298 void set_not_modified(bool value
) { not_modified_
= value
; }
300 // Returns 206 when revalidating a range (instead of 304).
301 void set_modified(bool value
) { modified_
= value
; }
303 // Returns 200 instead of 206 (a malformed response overall).
304 void set_bad_200(bool value
) { bad_200_
= value
; }
306 // Other than regular range related behavior (and the flags mentioned above),
307 // the server reacts to requests headers like so:
308 // X-Require-Mock-Auth -> return 401.
309 // X-Require-Mock-Auth-Alt -> return 401.
310 // X-Return-Default-Range -> assume 40-49 was requested.
311 // The -Alt variant doesn't cause the MockNetworkTransaction to
312 // report that it IsReadyToRestartForAuth().
313 static void RangeHandler(const HttpRequestInfo
* request
,
314 std::string
* response_status
,
315 std::string
* response_headers
,
316 std::string
* response_data
);
319 static bool not_modified_
;
320 static bool modified_
;
321 static bool bad_200_
;
322 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
324 bool RangeTransactionServer::not_modified_
= false;
325 bool RangeTransactionServer::modified_
= false;
326 bool RangeTransactionServer::bad_200_
= false;
328 // A dummy extra header that must be preserved on a given request.
330 // EXTRA_HEADER_LINE doesn't include a line terminator because it
331 // will be passed to AddHeaderFromString() which doesn't accept them.
332 #define EXTRA_HEADER_LINE "Extra: header"
334 // EXTRA_HEADER contains a line terminator, as expected by
335 // AddHeadersFromString() (_not_ AddHeaderFromString()).
336 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
338 static const char kExtraHeaderKey
[] = "Extra";
341 void RangeTransactionServer::RangeHandler(const HttpRequestInfo
* request
,
342 std::string
* response_status
,
343 std::string
* response_headers
,
344 std::string
* response_data
) {
345 if (request
->extra_headers
.IsEmpty()) {
346 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
347 response_data
->clear();
351 // We want to make sure we don't delete extra headers.
352 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
355 request
->extra_headers
.HasHeader("X-Require-Mock-Auth") ||
356 request
->extra_headers
.HasHeader("X-Require-Mock-Auth-Alt");
358 if (require_auth
&& !request
->extra_headers
.HasHeader("Authorization")) {
359 response_status
->assign("HTTP/1.1 401 Unauthorized");
360 response_data
->assign("WWW-Authenticate: Foo\n");
365 response_status
->assign("HTTP/1.1 304 Not Modified");
366 response_data
->clear();
370 std::vector
<HttpByteRange
> ranges
;
371 std::string range_header
;
372 if (!request
->extra_headers
.GetHeader(HttpRequestHeaders::kRange
,
374 !HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
375 ranges
.size() != 1) {
376 // This is not a byte range request. We return 200.
377 response_status
->assign("HTTP/1.1 200 OK");
378 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
379 response_data
->assign("Not a range");
383 // We can handle this range request.
384 HttpByteRange byte_range
= ranges
[0];
386 if (request
->extra_headers
.HasHeader("X-Return-Default-Range")) {
387 byte_range
.set_first_byte_position(40);
388 byte_range
.set_last_byte_position(49);
391 if (byte_range
.first_byte_position() > 79) {
392 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
393 response_data
->clear();
397 EXPECT_TRUE(byte_range
.ComputeBounds(80));
398 int start
= static_cast<int>(byte_range
.first_byte_position());
399 int end
= static_cast<int>(byte_range
.last_byte_position());
403 std::string content_range
= base::StringPrintf(
404 "Content-Range: bytes %d-%d/80\n", start
, end
);
405 response_headers
->append(content_range
);
407 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
410 EXPECT_EQ(0, end
% 10);
413 EXPECT_EQ(9, (end
- start
) % 10);
414 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
415 base::StringAppendF(&data
, "rg: %02d-%02d ",
416 block_start
, block_start
+ 9);
419 *response_data
= data
;
421 if (end
- start
!= 9) {
422 // We also have to fix content-length.
423 int len
= end
- start
+ 1;
424 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
426 response_headers
->replace(response_headers
->find("Content-Length:"),
427 content_length
.size(), content_length
);
430 response_status
->assign("HTTP/1.1 304 Not Modified");
431 response_data
->clear();
435 const MockTransaction kRangeGET_TransactionOK
= {
436 "http://www.google.com/range",
439 "Range: bytes = 40-49\r\n" EXTRA_HEADER
,
441 "HTTP/1.1 206 Partial Content",
442 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
444 "Accept-Ranges: bytes\n"
445 "Content-Length: 10\n",
449 &RangeTransactionServer::RangeHandler
,
455 const char kFullRangeData
[] =
456 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
457 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
459 // Verifies the response headers (|response|) match a partial content
460 // response for the range starting at |start| and ending at |end|.
461 void Verify206Response(std::string response
, int start
, int end
) {
462 std::string
raw_headers(
463 HttpUtil::AssembleRawHeaders(response
.data(), response
.size()));
464 scoped_refptr
<HttpResponseHeaders
> headers(
465 new HttpResponseHeaders(raw_headers
));
467 ASSERT_EQ(206, headers
->response_code());
469 int64 range_start
, range_end
, object_size
;
471 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
472 int64 content_length
= headers
->GetContentLength();
474 int length
= end
- start
+ 1;
475 ASSERT_EQ(length
, content_length
);
476 ASSERT_EQ(start
, range_start
);
477 ASSERT_EQ(end
, range_end
);
480 // Creates a truncated entry that can be resumed using byte ranges.
481 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
482 // Create a disk cache entry that stores an incomplete resource.
483 disk_cache::Entry
* entry
;
484 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
488 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
490 HttpResponseInfo response
;
491 response
.response_time
= base::Time::Now();
492 response
.request_time
= base::Time::Now();
493 response
.headers
= new HttpResponseHeaders(raw_headers
);
494 // Set the last argument for this to be an incomplete request.
495 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
497 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
498 int len
= static_cast<int>(base::strlcpy(buf
->data(),
499 "rg: 00-09 rg: 10-19 ", 100));
500 TestCompletionCallback cb
;
501 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
502 EXPECT_EQ(len
, cb
.GetResult(rv
));
506 // Helper to represent a network HTTP response.
508 // Set this response into |trans|.
509 void AssignTo(MockTransaction
* trans
) const {
510 trans
->status
= status
;
511 trans
->response_headers
= headers
;
515 std::string
status_and_headers() const {
516 return std::string(status
) + "\n" + std::string(headers
);
525 Context() : result(ERR_IO_PENDING
) {}
528 TestCompletionCallback callback
;
529 scoped_ptr
<HttpTransaction
> trans
;
532 class FakeWebSocketHandshakeStreamCreateHelper
533 : public WebSocketHandshakeStreamBase::CreateHelper
{
535 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
536 WebSocketHandshakeStreamBase
* CreateBasicStream(
537 scoped_ptr
<ClientSocketHandle
> connect
,
538 bool using_proxy
) override
{
541 WebSocketHandshakeStreamBase
* CreateSpdyStream(
542 const base::WeakPtr
<SpdySession
>& session
,
543 bool use_relative_url
) override
{
548 // Returns true if |entry| is not one of the log types paid attention to in this
549 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
551 bool ShouldIgnoreLogEntry(const TestNetLogEntry
& entry
) {
552 switch (entry
.type
) {
553 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
554 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
555 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
556 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
557 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
558 case NetLog::TYPE_HTTP_CACHE_READ_INFO
:
565 // Modifies |entries| to only include log entries created by the cache layer and
566 // asserted on in these tests.
567 void FilterLogEntries(TestNetLogEntry::List
* entries
) {
568 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
569 &ShouldIgnoreLogEntry
),
573 bool LogContainsEventType(const BoundTestNetLog
& log
,
574 NetLog::EventType expected
) {
575 TestNetLogEntry::List entries
;
576 log
.GetEntries(&entries
);
577 for (size_t i
= 0; i
< entries
.size(); i
++) {
578 if (entries
[i
].type
== expected
)
587 //-----------------------------------------------------------------------------
590 TEST(HttpCache
, CreateThenDestroy
) {
593 scoped_ptr
<HttpTransaction
> trans
;
594 EXPECT_EQ(OK
, cache
.CreateTransaction(&trans
));
595 ASSERT_TRUE(trans
.get());
598 TEST(HttpCache
, GetBackend
) {
599 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(0));
601 disk_cache::Backend
* backend
;
602 TestCompletionCallback cb
;
603 // This will lazily initialize the backend.
604 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
605 EXPECT_EQ(OK
, cb
.GetResult(rv
));
608 TEST(HttpCache
, SimpleGET
) {
611 LoadTimingInfo load_timing_info
;
613 // Write to the cache.
614 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
615 log
.bound(), &load_timing_info
);
617 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
618 EXPECT_EQ(0, cache
.disk_cache()->open_count());
619 EXPECT_EQ(1, cache
.disk_cache()->create_count());
620 TestLoadTimingNetworkRequest(load_timing_info
);
623 TEST(HttpCache
, SimpleGETNoDiskCache
) {
626 cache
.disk_cache()->set_fail_requests();
629 LoadTimingInfo load_timing_info
;
631 // Read from the network, and don't use the cache.
632 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
633 log
.bound(), &load_timing_info
);
635 // Check that the NetLog was filled as expected.
636 // (We attempted to both Open and Create entries, but both failed).
637 TestNetLogEntry::List entries
;
638 log
.GetEntries(&entries
);
639 FilterLogEntries(&entries
);
641 EXPECT_EQ(6u, entries
.size());
643 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
645 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
647 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
649 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
651 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
653 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
655 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
656 EXPECT_EQ(0, cache
.disk_cache()->open_count());
657 EXPECT_EQ(0, cache
.disk_cache()->create_count());
658 TestLoadTimingNetworkRequest(load_timing_info
);
661 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
662 // This will initialize a cache object with NULL backend.
663 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
664 factory
->set_fail(true);
665 factory
->FinishCreation(); // We'll complete synchronously.
666 MockHttpCache
cache(factory
);
668 // Read from the network, and don't use the cache.
669 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
671 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
672 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
675 // Tests that IOBuffers are not referenced after IO completes.
676 TEST(HttpCache
, ReleaseBuffer
) {
679 // Write to the cache.
680 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
682 MockHttpRequest
request(kSimpleGET_Transaction
);
683 scoped_ptr
<HttpTransaction
> trans
;
684 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
686 const int kBufferSize
= 10;
687 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(kBufferSize
));
688 ReleaseBufferCompletionCallback
cb(buffer
.get());
690 int rv
= trans
->Start(&request
, cb
.callback(), BoundNetLog());
691 EXPECT_EQ(OK
, cb
.GetResult(rv
));
693 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
694 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
697 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
700 cache
.disk_cache()->set_soft_failures(true);
702 // Read from the network, and fail to write to the cache.
703 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
705 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
706 EXPECT_EQ(0, cache
.disk_cache()->open_count());
707 EXPECT_EQ(1, cache
.disk_cache()->create_count());
709 // This one should see an empty cache again.
710 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
712 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
713 EXPECT_EQ(0, cache
.disk_cache()->open_count());
714 EXPECT_EQ(2, cache
.disk_cache()->create_count());
717 // Tests that disk failures after the transaction has started don't cause the
719 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
722 MockHttpRequest
request(kSimpleGET_Transaction
);
724 scoped_ptr
<Context
> c(new Context());
725 int rv
= cache
.CreateTransaction(&c
->trans
);
728 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
729 EXPECT_EQ(ERR_IO_PENDING
, rv
);
730 rv
= c
->callback
.WaitForResult();
732 // Start failing request now.
733 cache
.disk_cache()->set_soft_failures(true);
735 // We have to open the entry again to propagate the failure flag.
736 disk_cache::Entry
* en
;
737 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
740 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
743 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
744 EXPECT_EQ(1, cache
.disk_cache()->open_count());
745 EXPECT_EQ(1, cache
.disk_cache()->create_count());
747 // This one should see an empty cache again.
748 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
750 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
751 EXPECT_EQ(1, cache
.disk_cache()->open_count());
752 EXPECT_EQ(2, cache
.disk_cache()->create_count());
755 // Tests that we handle failures to read from the cache.
756 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
759 // Read from the network, and write to the cache.
760 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
762 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
763 EXPECT_EQ(0, cache
.disk_cache()->open_count());
764 EXPECT_EQ(1, cache
.disk_cache()->create_count());
766 cache
.disk_cache()->set_soft_failures(true);
768 // Now fail to read from the cache.
769 scoped_ptr
<Context
> c(new Context());
770 int rv
= cache
.CreateTransaction(&c
->trans
);
773 MockHttpRequest
request(kSimpleGET_Transaction
);
774 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
775 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
777 // Now verify that the entry was removed from the cache.
778 cache
.disk_cache()->set_soft_failures(false);
780 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
781 EXPECT_EQ(1, cache
.disk_cache()->open_count());
782 EXPECT_EQ(2, cache
.disk_cache()->create_count());
784 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
786 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
787 EXPECT_EQ(1, cache
.disk_cache()->open_count());
788 EXPECT_EQ(3, cache
.disk_cache()->create_count());
791 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
795 LoadTimingInfo load_timing_info
;
797 // Write to the cache.
798 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
799 log
.bound(), &load_timing_info
);
801 // Check that the NetLog was filled as expected.
802 TestNetLogEntry::List entries
;
803 log
.GetEntries(&entries
);
804 FilterLogEntries(&entries
);
806 EXPECT_EQ(8u, entries
.size());
808 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
810 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
812 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
814 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
816 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
818 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
820 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
822 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
824 TestLoadTimingNetworkRequest(load_timing_info
);
826 // Force this transaction to read from the cache.
827 MockTransaction
transaction(kSimpleGET_Transaction
);
828 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
832 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
835 // Check that the NetLog was filled as expected.
836 log
.GetEntries(&entries
);
837 FilterLogEntries(&entries
);
839 EXPECT_EQ(8u, entries
.size());
841 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
843 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
845 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
847 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
849 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
851 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
853 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
855 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
857 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
858 EXPECT_EQ(1, cache
.disk_cache()->open_count());
859 EXPECT_EQ(1, cache
.disk_cache()->create_count());
860 TestLoadTimingCachedResponse(load_timing_info
);
863 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
866 // force this transaction to read from the cache
867 MockTransaction
transaction(kSimpleGET_Transaction
);
868 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
870 MockHttpRequest
request(transaction
);
871 TestCompletionCallback callback
;
873 scoped_ptr
<HttpTransaction
> trans
;
874 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
876 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
877 if (rv
== ERR_IO_PENDING
)
878 rv
= callback
.WaitForResult();
879 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
883 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
884 EXPECT_EQ(0, cache
.disk_cache()->open_count());
885 EXPECT_EQ(0, cache
.disk_cache()->create_count());
888 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
891 // write to the cache
892 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
894 // force this transaction to read from the cache if valid
895 MockTransaction
transaction(kSimpleGET_Transaction
);
896 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
898 RunTransactionTest(cache
.http_cache(), transaction
);
900 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
901 EXPECT_EQ(1, cache
.disk_cache()->open_count());
902 EXPECT_EQ(1, cache
.disk_cache()->create_count());
905 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
908 // force this transaction to read from the cache if valid
909 MockTransaction
transaction(kSimpleGET_Transaction
);
910 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
912 RunTransactionTest(cache
.http_cache(), transaction
);
914 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
915 EXPECT_EQ(0, cache
.disk_cache()->open_count());
916 EXPECT_EQ(1, cache
.disk_cache()->create_count());
919 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
920 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
923 // Write to the cache.
924 MockTransaction
transaction(kSimpleGET_Transaction
);
925 transaction
.request_headers
= "Foo: bar\r\n";
926 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
928 AddMockTransaction(&transaction
);
929 RunTransactionTest(cache
.http_cache(), transaction
);
931 // Read from the cache.
932 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
933 RunTransactionTest(cache
.http_cache(), transaction
);
935 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
936 EXPECT_EQ(1, cache
.disk_cache()->open_count());
937 EXPECT_EQ(1, cache
.disk_cache()->create_count());
938 RemoveMockTransaction(&transaction
);
941 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
942 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
945 // Write to the cache.
946 MockTransaction
transaction(kSimpleGET_Transaction
);
947 transaction
.request_headers
= "Foo: bar\r\n";
948 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
950 AddMockTransaction(&transaction
);
951 RunTransactionTest(cache
.http_cache(), transaction
);
953 // Attempt to read from the cache... this is a vary mismatch that must reach
954 // the network again.
955 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
956 transaction
.request_headers
= "Foo: none\r\n";
958 LoadTimingInfo load_timing_info
;
959 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
962 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
963 EXPECT_EQ(1, cache
.disk_cache()->open_count());
964 EXPECT_EQ(1, cache
.disk_cache()->create_count());
965 TestLoadTimingNetworkRequest(load_timing_info
);
966 RemoveMockTransaction(&transaction
);
969 // Tests that was_cached was set properly on a failure, even if the cached
970 // response wasn't returned.
971 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
975 MockTransaction
transaction(kSimpleGET_Transaction
);
976 transaction
.response_headers
= "Cache-Control: no-cache\n";
978 AddMockTransaction(&transaction
);
979 RunTransactionTest(cache
.http_cache(), transaction
);
980 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
981 EXPECT_EQ(1, cache
.disk_cache()->create_count());
982 RemoveMockTransaction(&transaction
);
984 // Network failure with error; should fail but have was_cached set.
985 transaction
.return_code
= ERR_FAILED
;
986 AddMockTransaction(&transaction
);
988 MockHttpRequest
request(transaction
);
989 TestCompletionCallback callback
;
990 scoped_ptr
<HttpTransaction
> trans
;
991 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
993 ASSERT_TRUE(trans
.get());
994 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
995 EXPECT_EQ(ERR_FAILED
, callback
.GetResult(rv
));
997 const HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
998 ASSERT_TRUE(response_info
);
999 EXPECT_TRUE(response_info
->was_cached
);
1000 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1002 RemoveMockTransaction(&transaction
);
1005 // Confirm if we have an empty cache, a read is marked as network verified.
1006 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1007 MockHttpCache cache
;
1009 // write to the cache
1010 HttpResponseInfo response_info
;
1011 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1014 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1015 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1016 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1017 EXPECT_TRUE(response_info
.network_accessed
);
1020 // Confirm if we have a fresh entry in cache, it isn't marked as
1021 // network verified.
1022 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1023 MockHttpCache cache
;
1026 MockTransaction
transaction(kSimpleGET_Transaction
);
1028 RunTransactionTest(cache
.http_cache(), transaction
);
1029 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1030 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1032 // Re-run transaction; make sure we don't mark the network as accessed.
1033 HttpResponseInfo response_info
;
1034 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1037 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1038 EXPECT_FALSE(response_info
.server_data_unavailable
);
1039 EXPECT_FALSE(response_info
.network_accessed
);
1042 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1043 MockHttpCache cache
;
1045 // Write to the cache.
1046 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1048 // Force this transaction to write to the cache again.
1049 MockTransaction
transaction(kSimpleGET_Transaction
);
1050 transaction
.load_flags
|= LOAD_BYPASS_CACHE
;
1052 BoundTestNetLog log
;
1053 LoadTimingInfo load_timing_info
;
1055 // Write to the cache.
1056 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1059 // Check that the NetLog was filled as expected.
1060 TestNetLogEntry::List entries
;
1061 log
.GetEntries(&entries
);
1062 FilterLogEntries(&entries
);
1064 EXPECT_EQ(8u, entries
.size());
1066 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1068 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1070 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1072 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1074 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1076 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1078 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1080 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1082 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1083 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1084 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1085 TestLoadTimingNetworkRequest(load_timing_info
);
1088 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1089 MockHttpCache cache
;
1091 // write to the cache
1092 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1094 // force this transaction to write to the cache again
1095 MockTransaction
transaction(kSimpleGET_Transaction
);
1096 transaction
.request_headers
= "pragma: no-cache\r\n";
1098 RunTransactionTest(cache
.http_cache(), transaction
);
1100 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1101 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1102 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1105 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1106 MockHttpCache cache
;
1108 // write to the cache
1109 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1111 // force this transaction to write to the cache again
1112 MockTransaction
transaction(kSimpleGET_Transaction
);
1113 transaction
.request_headers
= "cache-control: no-cache\r\n";
1115 RunTransactionTest(cache
.http_cache(), transaction
);
1117 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1118 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1119 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1122 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1123 MockHttpCache cache
;
1125 // Write to the cache.
1126 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1128 // Read from the cache.
1129 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1131 // Force this transaction to validate the cache.
1132 MockTransaction
transaction(kSimpleGET_Transaction
);
1133 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
1135 HttpResponseInfo response_info
;
1136 BoundTestNetLog log
;
1137 LoadTimingInfo load_timing_info
;
1138 RunTransactionTestWithResponseInfoAndGetTiming(
1139 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1142 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1143 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1144 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1145 EXPECT_TRUE(response_info
.network_accessed
);
1146 TestLoadTimingNetworkRequest(load_timing_info
);
1149 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1150 MockHttpCache cache
;
1152 // write to the cache
1153 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1155 // read from the cache
1156 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1158 // force this transaction to validate the cache
1159 MockTransaction
transaction(kSimpleGET_Transaction
);
1160 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1162 RunTransactionTest(cache
.http_cache(), transaction
);
1164 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1165 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1166 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1169 static void PreserveRequestHeaders_Handler(const HttpRequestInfo
* request
,
1170 std::string
* response_status
,
1171 std::string
* response_headers
,
1172 std::string
* response_data
) {
1173 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1176 // Tests that we don't remove extra headers for simple requests.
1177 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1178 MockHttpCache cache
;
1180 MockTransaction
transaction(kSimpleGET_Transaction
);
1181 transaction
.handler
= PreserveRequestHeaders_Handler
;
1182 transaction
.request_headers
= EXTRA_HEADER
;
1183 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1184 AddMockTransaction(&transaction
);
1186 // Write, then revalidate the entry.
1187 RunTransactionTest(cache
.http_cache(), transaction
);
1188 RunTransactionTest(cache
.http_cache(), transaction
);
1190 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1191 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1192 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1193 RemoveMockTransaction(&transaction
);
1196 // Tests that we don't remove extra headers for conditionalized requests.
1197 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1198 MockHttpCache cache
;
1200 // Write to the cache.
1201 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1203 MockTransaction
transaction(kETagGET_Transaction
);
1204 transaction
.handler
= PreserveRequestHeaders_Handler
;
1205 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1207 AddMockTransaction(&transaction
);
1209 RunTransactionTest(cache
.http_cache(), transaction
);
1211 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1212 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1213 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1214 RemoveMockTransaction(&transaction
);
1217 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1218 MockHttpCache cache
;
1220 MockHttpRequest
request(kSimpleGET_Transaction
);
1222 std::vector
<Context
*> context_list
;
1223 const int kNumTransactions
= 5;
1225 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1226 context_list
.push_back(new Context());
1227 Context
* c
= context_list
[i
];
1229 c
->result
= cache
.CreateTransaction(&c
->trans
);
1230 ASSERT_EQ(OK
, c
->result
);
1231 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1234 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1237 // All requests are waiting for the active entry.
1238 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1239 Context
* c
= context_list
[i
];
1240 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1243 // Allow all requests to move from the Create queue to the active entry.
1244 base::MessageLoop::current()->RunUntilIdle();
1246 // The first request should be a writer at this point, and the subsequent
1247 // requests should be pending.
1249 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1250 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1251 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1253 // All requests depend on the writer, and the writer is between Start and
1255 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1256 Context
* c
= context_list
[i
];
1257 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1260 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1261 Context
* c
= context_list
[i
];
1262 if (c
->result
== ERR_IO_PENDING
)
1263 c
->result
= c
->callback
.WaitForResult();
1264 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1267 // We should not have had to re-open the disk entry
1269 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1270 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1271 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1273 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1274 Context
* c
= context_list
[i
];
1279 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1280 // If cancelling a request is racing with another request for the same resource
1281 // finishing, we have to make sure that we remove both transactions from the
1283 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1284 MockHttpCache cache
;
1286 MockHttpRequest
request(kSimpleGET_Transaction
);
1287 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1288 reader_request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
1290 std::vector
<Context
*> context_list
;
1291 const int kNumTransactions
= 5;
1293 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1294 context_list
.push_back(new Context());
1295 Context
* c
= context_list
[i
];
1297 c
->result
= cache
.CreateTransaction(&c
->trans
);
1298 ASSERT_EQ(OK
, c
->result
);
1300 MockHttpRequest
* this_request
= &request
;
1301 if (i
== 1 || i
== 2)
1302 this_request
= &reader_request
;
1305 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1308 // Allow all requests to move from the Create queue to the active entry.
1309 base::MessageLoop::current()->RunUntilIdle();
1311 // The first request should be a writer at this point, and the subsequent
1312 // requests should be pending.
1314 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1315 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1316 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1318 Context
* c
= context_list
[0];
1319 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1320 c
->result
= c
->callback
.WaitForResult();
1321 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1323 // Now we have 2 active readers and two queued transactions.
1325 EXPECT_EQ(LOAD_STATE_IDLE
, context_list
[2]->trans
->GetLoadState());
1326 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
,
1327 context_list
[3]->trans
->GetLoadState());
1329 c
= context_list
[1];
1330 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1331 c
->result
= c
->callback
.WaitForResult();
1332 if (c
->result
== OK
)
1333 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1335 // At this point we have one reader, two pending transactions and a task on
1336 // the queue to move to the next transaction. Now we cancel the request that
1337 // is the current reader, and expect the queued task to be able to start the
1340 c
= context_list
[2];
1343 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1344 Context
* c
= context_list
[i
];
1345 if (c
->result
== ERR_IO_PENDING
)
1346 c
->result
= c
->callback
.WaitForResult();
1347 if (c
->result
== OK
)
1348 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1351 // We should not have had to re-open the disk entry.
1353 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1354 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1355 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1357 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1358 Context
* c
= context_list
[i
];
1363 // Tests that we can doom an entry with pending transactions and delete one of
1364 // the pending transactions before the first one completes.
1365 // See http://code.google.com/p/chromium/issues/detail?id=25588
1366 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1367 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1368 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
1370 MockHttpRequest
request(kSimpleGET_Transaction
);
1371 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1372 writer_request
.load_flags
= LOAD_BYPASS_CACHE
;
1374 ScopedVector
<Context
> context_list
;
1375 const int kNumTransactions
= 4;
1377 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1378 context_list
.push_back(new Context());
1379 Context
* c
= context_list
[i
];
1381 c
->result
= cache
.CreateTransaction(&c
->trans
);
1382 ASSERT_EQ(OK
, c
->result
);
1384 MockHttpRequest
* this_request
= &request
;
1386 this_request
= &writer_request
;
1389 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1392 // The first request should be a writer at this point, and the two subsequent
1393 // requests should be pending. The last request doomed the first entry.
1395 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1397 // Cancel the first queued transaction.
1398 delete context_list
[1];
1399 context_list
.get()[1] = NULL
;
1401 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1404 Context
* c
= context_list
[i
];
1405 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1406 c
->result
= c
->callback
.WaitForResult();
1407 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1411 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1412 // We may attempt to delete an entry synchronously with the act of adding a new
1413 // transaction to said entry.
1414 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1415 MockHttpCache cache
;
1417 // The headers will be served right from the call to Start() the request.
1418 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1419 FastTransactionServer request_handler
;
1420 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1422 std::vector
<Context
*> context_list
;
1423 const int kNumTransactions
= 3;
1425 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1426 context_list
.push_back(new Context());
1427 Context
* c
= context_list
[i
];
1429 c
->result
= cache
.CreateTransaction(&c
->trans
);
1430 ASSERT_EQ(OK
, c
->result
);
1433 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1436 // Allow all requests to move from the Create queue to the active entry.
1437 base::MessageLoop::current()->RunUntilIdle();
1439 // The first request should be a writer at this point, and the subsequent
1440 // requests should be pending.
1442 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1443 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1444 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1446 // Now, make sure that the second request asks for the entry not to be stored.
1447 request_handler
.set_no_store(true);
1449 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1450 Context
* c
= context_list
[i
];
1451 if (c
->result
== ERR_IO_PENDING
)
1452 c
->result
= c
->callback
.WaitForResult();
1453 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1457 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1458 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1459 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1461 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1464 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1465 MockHttpCache cache
;
1467 MockHttpRequest
request(kSimpleGET_Transaction
);
1469 std::vector
<Context
*> context_list
;
1470 const int kNumTransactions
= 2;
1472 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1473 context_list
.push_back(new Context());
1474 Context
* c
= context_list
[i
];
1476 c
->result
= cache
.CreateTransaction(&c
->trans
);
1477 ASSERT_EQ(OK
, c
->result
);
1480 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1483 // Allow all requests to move from the Create queue to the active entry.
1484 base::MessageLoop::current()->RunUntilIdle();
1486 // The first request should be a writer at this point, and the subsequent
1487 // requests should be pending.
1489 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1490 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1491 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1493 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1494 Context
* c
= context_list
[i
];
1495 if (c
->result
== ERR_IO_PENDING
)
1496 c
->result
= c
->callback
.WaitForResult();
1497 // Destroy only the first transaction.
1500 context_list
[i
] = NULL
;
1504 // Complete the rest of the transactions.
1505 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1506 Context
* c
= context_list
[i
];
1507 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1510 // We should have had to re-open the disk entry.
1512 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1513 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1514 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1516 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1517 Context
* c
= context_list
[i
];
1522 // Tests that we can cancel requests that are queued waiting to open the disk
1524 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1525 MockHttpCache cache
;
1527 MockHttpRequest
request(kSimpleGET_Transaction
);
1529 std::vector
<Context
*> context_list
;
1530 const int kNumTransactions
= 5;
1532 for (int i
= 0; i
< kNumTransactions
; i
++) {
1533 context_list
.push_back(new Context());
1534 Context
* c
= context_list
[i
];
1536 c
->result
= cache
.CreateTransaction(&c
->trans
);
1537 ASSERT_EQ(OK
, c
->result
);
1540 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1543 // The first request should be creating the disk cache entry and the others
1544 // should be pending.
1546 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1547 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1548 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1550 // Cancel a request from the pending queue.
1551 delete context_list
[3];
1552 context_list
[3] = NULL
;
1554 // Cancel the request that is creating the entry. This will force the pending
1555 // operations to restart.
1556 delete context_list
[0];
1557 context_list
[0] = NULL
;
1559 // Complete the rest of the transactions.
1560 for (int i
= 1; i
< kNumTransactions
; i
++) {
1561 Context
* c
= context_list
[i
];
1563 c
->result
= c
->callback
.GetResult(c
->result
);
1564 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1568 // We should have had to re-create the disk entry.
1570 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1571 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1572 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1574 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1575 delete context_list
[i
];
1579 // Tests that we can cancel a single request to open a disk cache entry.
1580 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1581 MockHttpCache cache
;
1583 MockHttpRequest
request(kSimpleGET_Transaction
);
1585 Context
* c
= new Context();
1587 c
->result
= cache
.CreateTransaction(&c
->trans
);
1588 ASSERT_EQ(OK
, c
->result
);
1590 c
->result
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1591 EXPECT_EQ(ERR_IO_PENDING
, c
->result
);
1593 // Release the reference that the mock disk cache keeps for this entry, so
1594 // that we test that the http cache handles the cancellation correctly.
1595 cache
.disk_cache()->ReleaseAll();
1598 base::MessageLoop::current()->RunUntilIdle();
1599 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1602 // Tests that we delete/create entries even if multiple requests are queued.
1603 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1604 MockHttpCache cache
;
1606 MockHttpRequest
request(kSimpleGET_Transaction
);
1607 request
.load_flags
= LOAD_BYPASS_CACHE
;
1609 std::vector
<Context
*> context_list
;
1610 const int kNumTransactions
= 5;
1612 for (int i
= 0; i
< kNumTransactions
; i
++) {
1613 context_list
.push_back(new Context());
1614 Context
* c
= context_list
[i
];
1616 c
->result
= cache
.CreateTransaction(&c
->trans
);
1617 ASSERT_EQ(OK
, c
->result
);
1620 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1623 // The first request should be deleting the disk cache entry and the others
1624 // should be pending.
1626 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1627 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1628 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1630 // Complete the transactions.
1631 for (int i
= 0; i
< kNumTransactions
; i
++) {
1632 Context
* c
= context_list
[i
];
1633 c
->result
= c
->callback
.GetResult(c
->result
);
1634 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1637 // We should have had to re-create the disk entry multiple times.
1639 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1640 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1641 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1643 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1644 delete context_list
[i
];
1648 // Tests that a (simulated) timeout allows transactions waiting on the cache
1649 // lock to continue.
1650 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1651 MockHttpCache cache
;
1652 cache
.BypassCacheLock();
1654 MockHttpRequest
request(kSimpleGET_Transaction
);
1656 ASSERT_EQ(OK
, cache
.CreateTransaction(&c1
.trans
));
1657 ASSERT_EQ(ERR_IO_PENDING
,
1658 c1
.trans
->Start(&request
, c1
.callback
.callback(), BoundNetLog()));
1659 ASSERT_EQ(OK
, cache
.CreateTransaction(&c2
.trans
));
1660 ASSERT_EQ(ERR_IO_PENDING
,
1661 c2
.trans
->Start(&request
, c2
.callback
.callback(), BoundNetLog()));
1663 // The second request is queued after the first one.
1665 c2
.callback
.WaitForResult();
1666 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1668 // Complete the first transaction.
1669 c1
.callback
.WaitForResult();
1670 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1673 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1674 MockHttpCache cache
;
1676 // write to the cache
1677 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1679 MockHttpRequest
request(kSimpleGET_Transaction
);
1680 TestCompletionCallback callback
;
1682 scoped_ptr
<HttpTransaction
> trans
;
1683 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
1684 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1685 if (rv
== ERR_IO_PENDING
)
1686 rv
= callback
.WaitForResult();
1689 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
1690 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1691 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1693 // Test that destroying the transaction while it is reading from the cache
1697 // Make sure we pump any pending events, which should include a call to
1698 // HttpCache::Transaction::OnCacheReadCompleted.
1699 base::MessageLoop::current()->RunUntilIdle();
1702 // Tests that we can delete the HttpCache and deal with queued transactions
1703 // ("waiting for the backend" as opposed to Active or Doomed entries).
1704 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1705 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1706 new MockBackendNoCbFactory()));
1708 MockHttpRequest
request(kSimpleGET_Transaction
);
1710 std::vector
<Context
*> context_list
;
1711 const int kNumTransactions
= 5;
1713 for (int i
= 0; i
< kNumTransactions
; i
++) {
1714 context_list
.push_back(new Context());
1715 Context
* c
= context_list
[i
];
1717 c
->result
= cache
->CreateTransaction(&c
->trans
);
1718 ASSERT_EQ(OK
, c
->result
);
1721 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1724 // The first request should be creating the disk cache entry and the others
1725 // should be pending.
1727 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1728 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1729 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1733 // There is not much to do with the transactions at this point... they are
1734 // waiting for a callback that will not fire.
1735 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1736 delete context_list
[i
];
1740 // Tests that we queue requests when initializing the backend.
1741 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1742 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1743 MockHttpCache
cache(factory
);
1745 MockHttpRequest
request0(kSimpleGET_Transaction
);
1746 MockHttpRequest
request1(kTypicalGET_Transaction
);
1747 MockHttpRequest
request2(kETagGET_Transaction
);
1749 std::vector
<Context
*> context_list
;
1750 const int kNumTransactions
= 3;
1752 for (int i
= 0; i
< kNumTransactions
; i
++) {
1753 context_list
.push_back(new Context());
1754 Context
* c
= context_list
[i
];
1756 c
->result
= cache
.CreateTransaction(&c
->trans
);
1757 ASSERT_EQ(OK
, c
->result
);
1760 context_list
[0]->result
= context_list
[0]->trans
->Start(
1761 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1762 context_list
[1]->result
= context_list
[1]->trans
->Start(
1763 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1764 context_list
[2]->result
= context_list
[2]->trans
->Start(
1765 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1767 // Just to make sure that everything is still pending.
1768 base::MessageLoop::current()->RunUntilIdle();
1770 // The first request should be creating the disk cache.
1771 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1773 factory
->FinishCreation();
1775 base::MessageLoop::current()->RunUntilIdle();
1776 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1777 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1779 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1780 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1781 delete context_list
[i
];
1785 // Tests that we can cancel requests that are queued waiting for the backend
1786 // to be initialized.
1787 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1788 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1789 MockHttpCache
cache(factory
);
1791 MockHttpRequest
request0(kSimpleGET_Transaction
);
1792 MockHttpRequest
request1(kTypicalGET_Transaction
);
1793 MockHttpRequest
request2(kETagGET_Transaction
);
1795 std::vector
<Context
*> context_list
;
1796 const int kNumTransactions
= 3;
1798 for (int i
= 0; i
< kNumTransactions
; i
++) {
1799 context_list
.push_back(new Context());
1800 Context
* c
= context_list
[i
];
1802 c
->result
= cache
.CreateTransaction(&c
->trans
);
1803 ASSERT_EQ(OK
, c
->result
);
1806 context_list
[0]->result
= context_list
[0]->trans
->Start(
1807 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1808 context_list
[1]->result
= context_list
[1]->trans
->Start(
1809 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1810 context_list
[2]->result
= context_list
[2]->trans
->Start(
1811 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1813 // Just to make sure that everything is still pending.
1814 base::MessageLoop::current()->RunUntilIdle();
1816 // The first request should be creating the disk cache.
1817 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1819 // Cancel a request from the pending queue.
1820 delete context_list
[1];
1821 context_list
[1] = NULL
;
1823 // Cancel the request that is creating the entry.
1824 delete context_list
[0];
1825 context_list
[0] = NULL
;
1827 // Complete the last transaction.
1828 factory
->FinishCreation();
1830 context_list
[2]->result
=
1831 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1832 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1834 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1835 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1837 delete context_list
[2];
1840 // Tests that we can delete the cache while creating the backend.
1841 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1842 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1843 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1845 MockHttpRequest
request(kSimpleGET_Transaction
);
1847 scoped_ptr
<Context
> c(new Context());
1848 c
->result
= cache
->CreateTransaction(&c
->trans
);
1849 ASSERT_EQ(OK
, c
->result
);
1851 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1853 // Just to make sure that everything is still pending.
1854 base::MessageLoop::current()->RunUntilIdle();
1856 // The request should be creating the disk cache.
1857 EXPECT_FALSE(c
->callback
.have_result());
1859 // We cannot call FinishCreation because the factory itself will go away with
1860 // the cache, so grab the callback and attempt to use it.
1861 CompletionCallback callback
= factory
->callback();
1862 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1865 base::MessageLoop::current()->RunUntilIdle();
1868 callback
.Run(ERR_ABORTED
);
1871 // Tests that we can delete the cache while creating the backend, from within
1872 // one of the callbacks.
1873 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1874 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1875 MockHttpCache
* cache
= new MockHttpCache(factory
);
1877 DeleteCacheCompletionCallback
cb(cache
);
1878 disk_cache::Backend
* backend
;
1879 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1880 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1882 // Now let's queue a regular transaction
1883 MockHttpRequest
request(kSimpleGET_Transaction
);
1885 scoped_ptr
<Context
> c(new Context());
1886 c
->result
= cache
->CreateTransaction(&c
->trans
);
1887 ASSERT_EQ(OK
, c
->result
);
1889 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1891 // And another direct backend request.
1892 TestCompletionCallback cb2
;
1893 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1894 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1896 // Just to make sure that everything is still pending.
1897 base::MessageLoop::current()->RunUntilIdle();
1899 // The request should be queued.
1900 EXPECT_FALSE(c
->callback
.have_result());
1902 // Generate the callback.
1903 factory
->FinishCreation();
1904 rv
= cb
.WaitForResult();
1906 // The cache should be gone by now.
1907 base::MessageLoop::current()->RunUntilIdle();
1908 EXPECT_EQ(OK
, c
->callback
.GetResult(c
->result
));
1909 EXPECT_FALSE(cb2
.have_result());
1912 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
1913 MockHttpCache cache
;
1915 // write to the cache
1916 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
1918 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1919 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1920 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1922 // Get the same URL again, but this time we expect it to result
1923 // in a conditional request.
1924 BoundTestNetLog log
;
1925 LoadTimingInfo load_timing_info
;
1926 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
1927 log
.bound(), &load_timing_info
);
1929 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1930 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1931 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1932 TestLoadTimingNetworkRequest(load_timing_info
);
1935 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo
* request
,
1936 std::string
* response_status
,
1937 std::string
* response_headers
,
1938 std::string
* response_data
) {
1940 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
1941 response_status
->assign("HTTP/1.1 304 Not Modified");
1942 response_headers
->assign(kETagGET_Transaction
.response_headers
);
1943 response_data
->clear();
1946 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
1947 MockHttpCache cache
;
1949 ScopedMockTransaction
transaction(kETagGET_Transaction
);
1951 // write to the cache
1952 RunTransactionTest(cache
.http_cache(), transaction
);
1954 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1955 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1956 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1958 // Get the same URL again, but this time we expect it to result
1959 // in a conditional request.
1960 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
1961 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
1962 BoundTestNetLog log
;
1963 LoadTimingInfo load_timing_info
;
1964 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1967 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1968 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1969 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1970 TestLoadTimingNetworkRequest(load_timing_info
);
1973 class RevalidationServer
{
1975 RevalidationServer() {
1976 s_etag_used_
= false;
1977 s_last_modified_used_
= false;
1980 bool EtagUsed() { return s_etag_used_
; }
1981 bool LastModifiedUsed() { return s_last_modified_used_
; }
1983 static void Handler(const HttpRequestInfo
* request
,
1984 std::string
* response_status
,
1985 std::string
* response_headers
,
1986 std::string
* response_data
);
1989 static bool s_etag_used_
;
1990 static bool s_last_modified_used_
;
1992 bool RevalidationServer::s_etag_used_
= false;
1993 bool RevalidationServer::s_last_modified_used_
= false;
1995 void RevalidationServer::Handler(const HttpRequestInfo
* request
,
1996 std::string
* response_status
,
1997 std::string
* response_headers
,
1998 std::string
* response_data
) {
1999 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
))
2000 s_etag_used_
= true;
2002 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfModifiedSince
)) {
2003 s_last_modified_used_
= true;
2006 if (s_etag_used_
|| s_last_modified_used_
) {
2007 response_status
->assign("HTTP/1.1 304 Not Modified");
2008 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2009 response_data
->clear();
2011 response_status
->assign(kTypicalGET_Transaction
.status
);
2012 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2013 response_data
->assign(kTypicalGET_Transaction
.data
);
2017 // Tests revalidation after a vary match.
2018 TEST(HttpCache
, GET_ValidateCache_VaryMatch
) {
2019 MockHttpCache cache
;
2021 // Write to the cache.
2022 MockTransaction
transaction(kTypicalGET_Transaction
);
2023 transaction
.request_headers
= "Foo: bar\r\n";
2024 transaction
.response_headers
=
2025 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2026 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2028 "Cache-Control: max-age=0\n"
2030 AddMockTransaction(&transaction
);
2031 RunTransactionTest(cache
.http_cache(), transaction
);
2033 // Read from the cache.
2034 RevalidationServer server
;
2035 transaction
.handler
= server
.Handler
;
2036 BoundTestNetLog log
;
2037 LoadTimingInfo load_timing_info
;
2038 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2041 EXPECT_TRUE(server
.EtagUsed());
2042 EXPECT_TRUE(server
.LastModifiedUsed());
2043 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2044 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2045 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2046 TestLoadTimingNetworkRequest(load_timing_info
);
2047 RemoveMockTransaction(&transaction
);
2050 // Tests revalidation after a vary mismatch if etag is present.
2051 TEST(HttpCache
, GET_ValidateCache_VaryMismatch
) {
2052 MockHttpCache cache
;
2054 // Write to the cache.
2055 MockTransaction
transaction(kTypicalGET_Transaction
);
2056 transaction
.request_headers
= "Foo: bar\r\n";
2057 transaction
.response_headers
=
2058 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2059 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2061 "Cache-Control: max-age=0\n"
2063 AddMockTransaction(&transaction
);
2064 RunTransactionTest(cache
.http_cache(), transaction
);
2066 // Read from the cache and revalidate the entry.
2067 RevalidationServer server
;
2068 transaction
.handler
= server
.Handler
;
2069 transaction
.request_headers
= "Foo: none\r\n";
2070 BoundTestNetLog log
;
2071 LoadTimingInfo load_timing_info
;
2072 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2075 EXPECT_TRUE(server
.EtagUsed());
2076 EXPECT_FALSE(server
.LastModifiedUsed());
2077 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2078 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2079 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2080 TestLoadTimingNetworkRequest(load_timing_info
);
2081 RemoveMockTransaction(&transaction
);
2084 // Tests lack of revalidation after a vary mismatch and no etag.
2085 TEST(HttpCache
, GET_DontValidateCache_VaryMismatch
) {
2086 MockHttpCache cache
;
2088 // Write to the cache.
2089 MockTransaction
transaction(kTypicalGET_Transaction
);
2090 transaction
.request_headers
= "Foo: bar\r\n";
2091 transaction
.response_headers
=
2092 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2093 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2094 "Cache-Control: max-age=0\n"
2096 AddMockTransaction(&transaction
);
2097 RunTransactionTest(cache
.http_cache(), transaction
);
2099 // Read from the cache and don't revalidate the entry.
2100 RevalidationServer server
;
2101 transaction
.handler
= server
.Handler
;
2102 transaction
.request_headers
= "Foo: none\r\n";
2103 BoundTestNetLog log
;
2104 LoadTimingInfo load_timing_info
;
2105 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2108 EXPECT_FALSE(server
.EtagUsed());
2109 EXPECT_FALSE(server
.LastModifiedUsed());
2110 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2111 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2112 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2113 TestLoadTimingNetworkRequest(load_timing_info
);
2114 RemoveMockTransaction(&transaction
);
2117 // Tests that a new vary header provided when revalidating an entry is saved.
2118 TEST(HttpCache
, GET_ValidateCache_VaryMatch_UpdateVary
) {
2119 MockHttpCache cache
;
2121 // Write to the cache.
2122 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2123 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2124 transaction
.response_headers
=
2126 "Cache-Control: max-age=0\n"
2128 RunTransactionTest(cache
.http_cache(), transaction
);
2130 // Validate the entry and change the vary field in the response.
2131 transaction
.request_headers
= "Foo: bar\r\n Name: none\r\n";
2132 transaction
.status
= "HTTP/1.1 304 Not Modified";
2133 transaction
.response_headers
=
2135 "Cache-Control: max-age=3600\n"
2137 RunTransactionTest(cache
.http_cache(), transaction
);
2139 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2140 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2141 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2143 // Make sure that the ActiveEntry is gone.
2144 base::RunLoop().RunUntilIdle();
2146 // Generate a vary mismatch.
2147 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2148 RunTransactionTest(cache
.http_cache(), transaction
);
2150 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2151 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2152 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2155 // Tests that new request headers causing a vary mismatch are paired with the
2156 // new response when the server says the old response can be used.
2157 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_UpdateRequestHeader
) {
2158 MockHttpCache cache
;
2160 // Write to the cache.
2161 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2162 transaction
.request_headers
= "Foo: bar\r\n";
2163 transaction
.response_headers
=
2165 "Cache-Control: max-age=3600\n"
2167 RunTransactionTest(cache
.http_cache(), transaction
);
2169 // Vary-mismatch validation receives 304.
2170 transaction
.request_headers
= "Foo: none\r\n";
2171 transaction
.status
= "HTTP/1.1 304 Not Modified";
2172 RunTransactionTest(cache
.http_cache(), transaction
);
2174 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2175 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2176 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2178 // Make sure that the ActiveEntry is gone.
2179 base::RunLoop().RunUntilIdle();
2181 // Generate a vary mismatch.
2182 transaction
.request_headers
= "Foo: bar\r\n";
2183 RunTransactionTest(cache
.http_cache(), transaction
);
2185 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2186 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2187 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2190 // Tests that a 304 without vary headers doesn't delete the previously stored
2191 // vary data after a vary match revalidation.
2192 TEST(HttpCache
, GET_ValidateCache_VaryMatch_DontDeleteVary
) {
2193 MockHttpCache cache
;
2195 // Write to the cache.
2196 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2197 transaction
.request_headers
= "Foo: bar\r\n";
2198 transaction
.response_headers
=
2200 "Cache-Control: max-age=0\n"
2202 RunTransactionTest(cache
.http_cache(), transaction
);
2204 // Validate the entry and remove the vary field in the response.
2205 transaction
.status
= "HTTP/1.1 304 Not Modified";
2206 transaction
.response_headers
=
2208 "Cache-Control: max-age=3600\n";
2209 RunTransactionTest(cache
.http_cache(), transaction
);
2211 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2212 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2213 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2215 // Make sure that the ActiveEntry is gone.
2216 base::RunLoop().RunUntilIdle();
2218 // Generate a vary mismatch.
2219 transaction
.request_headers
= "Foo: none\r\n";
2220 RunTransactionTest(cache
.http_cache(), transaction
);
2222 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2223 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2224 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2227 // Tests that a 304 without vary headers doesn't delete the previously stored
2228 // vary data after a vary mismatch.
2229 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_DontDeleteVary
) {
2230 MockHttpCache cache
;
2232 // Write to the cache.
2233 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2234 transaction
.request_headers
= "Foo: bar\r\n";
2235 transaction
.response_headers
=
2237 "Cache-Control: max-age=3600\n"
2239 RunTransactionTest(cache
.http_cache(), transaction
);
2241 // Vary-mismatch validation receives 304 and no vary header.
2242 transaction
.request_headers
= "Foo: none\r\n";
2243 transaction
.status
= "HTTP/1.1 304 Not Modified";
2244 transaction
.response_headers
=
2246 "Cache-Control: max-age=3600\n";
2247 RunTransactionTest(cache
.http_cache(), transaction
);
2249 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2250 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2251 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2253 // Make sure that the ActiveEntry is gone.
2254 base::RunLoop().RunUntilIdle();
2256 // Generate a vary mismatch.
2257 transaction
.request_headers
= "Foo: bar\r\n";
2258 RunTransactionTest(cache
.http_cache(), transaction
);
2260 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2261 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2262 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2265 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo
* request
,
2266 std::string
* response_status
,
2267 std::string
* response_headers
,
2268 std::string
* response_data
) {
2270 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2273 TEST(HttpCache
, ETagGET_Http10
) {
2274 MockHttpCache cache
;
2276 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2277 transaction
.status
= "HTTP/1.0 200 OK";
2279 // Write to the cache.
2280 RunTransactionTest(cache
.http_cache(), transaction
);
2282 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2283 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2284 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2286 // Get the same URL again, without generating a conditional request.
2287 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2288 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2289 RunTransactionTest(cache
.http_cache(), transaction
);
2291 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2292 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2293 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2296 TEST(HttpCache
, ETagGET_Http10_Range
) {
2297 MockHttpCache cache
;
2299 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2300 transaction
.status
= "HTTP/1.0 200 OK";
2302 // Write to the cache.
2303 RunTransactionTest(cache
.http_cache(), transaction
);
2305 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2306 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2307 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2309 // Get the same URL again, but use a byte range request.
2310 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2311 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2312 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2313 RunTransactionTest(cache
.http_cache(), transaction
);
2315 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2316 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2317 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2320 static void ETagGet_ConditionalRequest_NoStore_Handler(
2321 const HttpRequestInfo
* request
,
2322 std::string
* response_status
,
2323 std::string
* response_headers
,
2324 std::string
* response_data
) {
2326 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2327 response_status
->assign("HTTP/1.1 304 Not Modified");
2328 response_headers
->assign("Cache-Control: no-store\n");
2329 response_data
->clear();
2332 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2333 MockHttpCache cache
;
2335 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2337 // Write to the cache.
2338 RunTransactionTest(cache
.http_cache(), transaction
);
2340 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2341 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2342 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2344 // Get the same URL again, but this time we expect it to result
2345 // in a conditional request.
2346 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2347 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2348 RunTransactionTest(cache
.http_cache(), transaction
);
2350 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2351 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2352 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2354 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2356 // Write to the cache again. This should create a new entry.
2357 RunTransactionTest(cache
.http_cache(), transaction2
);
2359 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2360 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2361 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2364 // Helper that does 4 requests using HttpCache:
2366 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2367 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2368 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2370 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2372 static void ConditionalizedRequestUpdatesCacheHelper(
2373 const Response
& net_response_1
,
2374 const Response
& net_response_2
,
2375 const Response
& cached_response_2
,
2376 const char* extra_request_headers
) {
2377 MockHttpCache cache
;
2379 // The URL we will be requesting.
2380 const char kUrl
[] = "http://foobar.com/main.css";
2382 // Junk network response.
2383 static const Response kUnexpectedResponse
= {
2384 "HTTP/1.1 500 Unexpected",
2385 "Server: unexpected_header",
2389 // We will control the network layer's responses for |kUrl| using
2390 // |mock_network_response|.
2391 MockTransaction mock_network_response
= { 0 };
2392 mock_network_response
.url
= kUrl
;
2393 AddMockTransaction(&mock_network_response
);
2395 // Request |kUrl| for the first time. It should hit the network and
2396 // receive |kNetResponse1|, which it saves into the HTTP cache.
2398 MockTransaction request
= { 0 };
2400 request
.method
= "GET";
2401 request
.request_headers
= "";
2403 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2404 net_response_1
.AssignTo(&request
); // Expected result.
2406 std::string response_headers
;
2407 RunTransactionTestWithResponse(
2408 cache
.http_cache(), request
, &response_headers
);
2410 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2411 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2412 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2413 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2415 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2416 // cache, so we don't hit the network.
2418 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2420 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2421 net_response_1
.AssignTo(&request
); // Expected result.
2423 RunTransactionTestWithResponse(
2424 cache
.http_cache(), request
, &response_headers
);
2426 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2427 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2428 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2429 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2431 // Request |kUrl| yet again, but this time give the request an
2432 // "If-Modified-Since" header. This will cause the request to re-hit the
2433 // network. However now the network response is going to be
2434 // different -- this simulates a change made to the CSS file.
2436 request
.request_headers
= extra_request_headers
;
2437 request
.load_flags
= LOAD_NORMAL
;
2439 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2440 net_response_2
.AssignTo(&request
); // Expected result.
2442 RunTransactionTestWithResponse(
2443 cache
.http_cache(), request
, &response_headers
);
2445 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2446 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2447 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2448 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2450 // Finally, request |kUrl| again. This request should be serviced from
2451 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2452 // and NOT |kNetResponse1|. The previous step should have replaced the
2453 // value in the cache with the modified response.
2455 request
.request_headers
= "";
2456 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2458 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2459 cached_response_2
.AssignTo(&request
); // Expected result.
2461 RunTransactionTestWithResponse(
2462 cache
.http_cache(), request
, &response_headers
);
2464 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2465 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2466 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2467 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2469 RemoveMockTransaction(&mock_network_response
);
2472 // Check that when an "if-modified-since" header is attached
2473 // to the request, the result still updates the cached entry.
2474 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2475 // First network response for |kUrl|.
2476 static const Response kNetResponse1
= {
2478 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2479 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2483 // Second network response for |kUrl|.
2484 static const Response kNetResponse2
= {
2486 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2487 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2491 const char extra_headers
[] =
2492 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2494 ConditionalizedRequestUpdatesCacheHelper(
2495 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2498 // Check that when an "if-none-match" header is attached
2499 // to the request, the result updates the cached entry.
2500 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2501 // First network response for |kUrl|.
2502 static const Response kNetResponse1
= {
2504 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2506 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2510 // Second network response for |kUrl|.
2511 static const Response kNetResponse2
= {
2513 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2515 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2519 const char extra_headers
[] = "If-None-Match: \"ETAG1\"\r\n";
2521 ConditionalizedRequestUpdatesCacheHelper(
2522 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2525 // Check that when an "if-modified-since" header is attached
2526 // to a request, the 304 (not modified result) result updates the cached
2527 // headers, and the 304 response is returned rather than the cached response.
2528 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2529 // First network response for |kUrl|.
2530 static const Response kNetResponse1
= {
2532 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2534 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2538 // Second network response for |kUrl|.
2539 static const Response kNetResponse2
= {
2540 "HTTP/1.1 304 Not Modified",
2541 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2543 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2547 static const Response kCachedResponse2
= {
2549 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2551 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2555 const char extra_headers
[] =
2556 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2558 ConditionalizedRequestUpdatesCacheHelper(
2559 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2562 // Test that when doing an externally conditionalized if-modified-since
2563 // and there is no corresponding cache entry, a new cache entry is NOT
2564 // created (304 response).
2565 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2566 MockHttpCache cache
;
2568 const char kUrl
[] = "http://foobar.com/main.css";
2570 static const Response kNetResponse
= {
2571 "HTTP/1.1 304 Not Modified",
2572 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2573 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2577 const char kExtraRequestHeaders
[] =
2578 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2580 // We will control the network layer's responses for |kUrl| using
2581 // |mock_network_response|.
2582 MockTransaction mock_network_response
= { 0 };
2583 mock_network_response
.url
= kUrl
;
2584 AddMockTransaction(&mock_network_response
);
2586 MockTransaction request
= { 0 };
2588 request
.method
= "GET";
2589 request
.request_headers
= kExtraRequestHeaders
;
2591 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2592 kNetResponse
.AssignTo(&request
); // Expected result.
2594 std::string response_headers
;
2595 RunTransactionTestWithResponse(
2596 cache
.http_cache(), request
, &response_headers
);
2598 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2599 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2600 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2601 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2603 RemoveMockTransaction(&mock_network_response
);
2606 // Test that when doing an externally conditionalized if-modified-since
2607 // and there is no corresponding cache entry, a new cache entry is NOT
2608 // created (200 response).
2609 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2610 MockHttpCache cache
;
2612 const char kUrl
[] = "http://foobar.com/main.css";
2614 static const Response kNetResponse
= {
2616 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2617 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2621 const char kExtraRequestHeaders
[] =
2622 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2624 // We will control the network layer's responses for |kUrl| using
2625 // |mock_network_response|.
2626 MockTransaction mock_network_response
= { 0 };
2627 mock_network_response
.url
= kUrl
;
2628 AddMockTransaction(&mock_network_response
);
2630 MockTransaction request
= { 0 };
2632 request
.method
= "GET";
2633 request
.request_headers
= kExtraRequestHeaders
;
2635 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2636 kNetResponse
.AssignTo(&request
); // Expected result.
2638 std::string response_headers
;
2639 RunTransactionTestWithResponse(
2640 cache
.http_cache(), request
, &response_headers
);
2642 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2643 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2644 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2645 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2647 RemoveMockTransaction(&mock_network_response
);
2650 // Test that when doing an externally conditionalized if-modified-since
2651 // if the date does not match the cache entry's last-modified date,
2652 // then we do NOT use the response (304) to update the cache.
2653 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2654 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2655 static const Response kNetResponse1
= {
2657 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2659 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2663 // Second network response for |kUrl|.
2664 static const Response kNetResponse2
= {
2665 "HTTP/1.1 304 Not Modified",
2666 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2668 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2672 // This is two days in the future from the original response's last-modified
2674 const char kExtraRequestHeaders
[] =
2675 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2677 ConditionalizedRequestUpdatesCacheHelper(
2678 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2681 // Test that when doing an externally conditionalized if-none-match
2682 // if the etag does not match the cache entry's etag, then we do not use the
2683 // response (304) to update the cache.
2684 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2685 static const Response kNetResponse1
= {
2687 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2689 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2693 // Second network response for |kUrl|.
2694 static const Response kNetResponse2
= {
2695 "HTTP/1.1 304 Not Modified",
2696 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2698 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2702 // Different etag from original response.
2703 const char kExtraRequestHeaders
[] = "If-None-Match: \"Foo2\"\r\n";
2705 ConditionalizedRequestUpdatesCacheHelper(
2706 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2709 // Test that doing an externally conditionalized request with both if-none-match
2710 // and if-modified-since updates the cache.
2711 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2712 static const Response kNetResponse1
= {
2714 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2716 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2720 // Second network response for |kUrl|.
2721 static const Response kNetResponse2
= {
2723 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2725 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2729 const char kExtraRequestHeaders
[] =
2730 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2731 "If-None-Match: \"Foo1\"\r\n";
2733 ConditionalizedRequestUpdatesCacheHelper(
2734 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2737 // Test that doing an externally conditionalized request with both if-none-match
2738 // and if-modified-since does not update the cache with only one match.
2739 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2740 static const Response kNetResponse1
= {
2742 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2744 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2748 // Second network response for |kUrl|.
2749 static const Response kNetResponse2
= {
2751 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2753 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2757 // The etag doesn't match what we have stored.
2758 const char kExtraRequestHeaders
[] =
2759 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2760 "If-None-Match: \"Foo2\"\r\n";
2762 ConditionalizedRequestUpdatesCacheHelper(
2763 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2766 // Test that doing an externally conditionalized request with both if-none-match
2767 // and if-modified-since does not update the cache with only one match.
2768 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2769 static const Response kNetResponse1
= {
2771 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2773 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2777 // Second network response for |kUrl|.
2778 static const Response kNetResponse2
= {
2780 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2782 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2786 // The modification date doesn't match what we have stored.
2787 const char kExtraRequestHeaders
[] =
2788 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2789 "If-None-Match: \"Foo1\"\r\n";
2791 ConditionalizedRequestUpdatesCacheHelper(
2792 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2795 TEST(HttpCache
, UrlContainingHash
) {
2796 MockHttpCache cache
;
2798 // Do a typical GET request -- should write an entry into our cache.
2799 MockTransaction
trans(kTypicalGET_Transaction
);
2800 RunTransactionTest(cache
.http_cache(), trans
);
2802 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2803 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2804 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2806 // Request the same URL, but this time with a reference section (hash).
2807 // Since the cache key strips the hash sections, this should be a cache hit.
2808 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2809 trans
.url
= url_with_hash
.c_str();
2810 trans
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2812 RunTransactionTest(cache
.http_cache(), trans
);
2814 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2815 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2816 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2819 // Tests that we skip the cache for POST requests that do not have an upload
2821 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2822 MockHttpCache cache
;
2824 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2826 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2827 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2828 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2831 // Tests POST handling with a disabled cache (no DCHECK).
2832 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2833 MockHttpCache cache
;
2834 cache
.http_cache()->set_mode(HttpCache::Mode::DISABLE
);
2836 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2838 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2839 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2840 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2843 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2844 MockHttpCache cache
;
2846 MockTransaction
transaction(kSimplePOST_Transaction
);
2847 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2849 MockHttpRequest
request(transaction
);
2850 TestCompletionCallback callback
;
2852 scoped_ptr
<HttpTransaction
> trans
;
2853 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
2854 ASSERT_TRUE(trans
.get());
2856 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
2857 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
2861 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2862 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2863 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2866 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2867 MockHttpCache cache
;
2869 // Test that we hit the cache for POST requests.
2871 MockTransaction
transaction(kSimplePOST_Transaction
);
2873 const int64 kUploadId
= 1; // Just a dummy value.
2875 ScopedVector
<UploadElementReader
> element_readers
;
2876 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2877 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2879 MockHttpRequest
request(transaction
);
2880 request
.upload_data_stream
= &upload_data_stream
;
2882 // Populate the cache.
2883 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2885 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2886 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2887 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2890 request
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2891 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2893 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2894 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2895 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2898 // Test that we don't hit the cache for POST requests if there is a byte range.
2899 TEST(HttpCache
, SimplePOST_WithRanges
) {
2900 MockHttpCache cache
;
2902 MockTransaction
transaction(kSimplePOST_Transaction
);
2903 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2905 const int64 kUploadId
= 1; // Just a dummy value.
2907 ScopedVector
<UploadElementReader
> element_readers
;
2908 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2909 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2912 MockHttpRequest
request(transaction
);
2913 request
.upload_data_stream
= &upload_data_stream
;
2915 // Attempt to populate the cache.
2916 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2918 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2919 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2920 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2923 // Tests that a POST is cached separately from a previously cached GET.
2924 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2925 MockHttpCache cache
;
2927 ScopedVector
<UploadElementReader
> element_readers
;
2928 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2929 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2931 MockTransaction
transaction(kSimplePOST_Transaction
);
2932 MockHttpRequest
req1(transaction
);
2933 req1
.upload_data_stream
= &upload_data_stream
;
2935 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2937 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2938 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2939 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2941 transaction
.method
= "GET";
2942 MockHttpRequest
req2(transaction
);
2944 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2946 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2947 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2948 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2951 // Tests that a successful POST invalidates a previously cached GET.
2952 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2953 MockHttpCache cache
;
2955 MockTransaction
transaction(kSimpleGET_Transaction
);
2956 AddMockTransaction(&transaction
);
2957 MockHttpRequest
req1(transaction
);
2959 // Attempt to populate the cache.
2960 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2962 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2963 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2964 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2966 ScopedVector
<UploadElementReader
> element_readers
;
2967 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2968 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2970 transaction
.method
= "POST";
2971 transaction
.status
= "HTTP/1.1 205 No Content";
2972 MockHttpRequest
req2(transaction
);
2973 req2
.upload_data_stream
= &upload_data_stream
;
2975 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2977 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2978 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2979 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2981 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2983 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2984 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2985 EXPECT_EQ(3, cache
.disk_cache()->create_count());
2986 RemoveMockTransaction(&transaction
);
2989 // Tests that a successful POST invalidates a previously cached GET, even when
2990 // there is no upload identifier.
2991 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
2992 MockHttpCache cache
;
2994 MockTransaction
transaction(kSimpleGET_Transaction
);
2995 AddMockTransaction(&transaction
);
2996 MockHttpRequest
req1(transaction
);
2998 // Attempt to populate the cache.
2999 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3001 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3002 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3003 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3005 ScopedVector
<UploadElementReader
> element_readers
;
3006 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3007 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3009 transaction
.method
= "POST";
3010 transaction
.status
= "HTTP/1.1 205 No Content";
3011 MockHttpRequest
req2(transaction
);
3012 req2
.upload_data_stream
= &upload_data_stream
;
3014 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3016 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3017 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3018 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3020 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3022 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3023 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3024 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3025 RemoveMockTransaction(&transaction
);
3028 // Tests that processing a POST before creating the backend doesn't crash.
3029 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
3030 // This will initialize a cache object with NULL backend.
3031 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
3032 factory
->set_fail(true);
3033 factory
->FinishCreation();
3034 MockHttpCache
cache(factory
);
3036 ScopedVector
<UploadElementReader
> element_readers
;
3037 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3038 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3040 MockTransaction
transaction(kSimplePOST_Transaction
);
3041 AddMockTransaction(&transaction
);
3042 MockHttpRequest
req(transaction
);
3043 req
.upload_data_stream
= &upload_data_stream
;
3045 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
3047 RemoveMockTransaction(&transaction
);
3050 // Tests that we don't invalidate entries as a result of a failed POST.
3051 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
3052 MockHttpCache cache
;
3054 MockTransaction
transaction(kSimpleGET_Transaction
);
3055 AddMockTransaction(&transaction
);
3056 MockHttpRequest
req1(transaction
);
3058 // Attempt to populate the cache.
3059 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3061 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3062 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3063 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3065 ScopedVector
<UploadElementReader
> element_readers
;
3066 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3067 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3069 transaction
.method
= "POST";
3070 transaction
.status
= "HTTP/1.1 100 Continue";
3071 MockHttpRequest
req2(transaction
);
3072 req2
.upload_data_stream
= &upload_data_stream
;
3074 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3076 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3077 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3078 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3080 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3082 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3083 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3084 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3085 RemoveMockTransaction(&transaction
);
3088 // Tests that a HEAD request is not cached by itself.
3089 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3090 MockHttpCache cache
;
3091 MockTransaction
transaction(kSimplePOST_Transaction
);
3092 AddMockTransaction(&transaction
);
3093 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3094 transaction
.method
= "HEAD";
3096 MockHttpRequest
request(transaction
);
3097 TestCompletionCallback callback
;
3099 scoped_ptr
<HttpTransaction
> trans
;
3100 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
3101 ASSERT_TRUE(trans
.get());
3103 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
3104 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
3108 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3109 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3110 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3111 RemoveMockTransaction(&transaction
);
3114 // Tests that a HEAD request is served from a cached GET.
3115 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3116 MockHttpCache cache
;
3117 MockTransaction
transaction(kSimpleGET_Transaction
);
3118 AddMockTransaction(&transaction
);
3120 // Populate the cache.
3121 RunTransactionTest(cache
.http_cache(), transaction
);
3123 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3124 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3125 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3128 transaction
.method
= "HEAD";
3129 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3130 transaction
.data
= "";
3131 RunTransactionTest(cache
.http_cache(), transaction
);
3133 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3134 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3135 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3136 RemoveMockTransaction(&transaction
);
3139 // Tests that a read-only request served from the cache preserves CL.
3140 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3141 MockHttpCache cache
;
3142 MockTransaction
transaction(kSimpleGET_Transaction
);
3143 AddMockTransaction(&transaction
);
3144 transaction
.response_headers
= "Content-Length: 42\n";
3146 // Populate the cache.
3147 RunTransactionTest(cache
.http_cache(), transaction
);
3150 transaction
.method
= "HEAD";
3151 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3152 transaction
.data
= "";
3153 std::string headers
;
3155 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3157 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3158 RemoveMockTransaction(&transaction
);
3161 // Tests that a read-write request served from the cache preserves CL.
3162 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3163 MockHttpCache cache
;
3164 MockTransaction
transaction(kETagGET_Transaction
);
3165 AddMockTransaction(&transaction
);
3166 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3167 server_headers
.append("Content-Length: 42\n");
3168 transaction
.response_headers
= server_headers
.data();
3170 // Populate the cache.
3171 RunTransactionTest(cache
.http_cache(), transaction
);
3174 transaction
.method
= "HEAD";
3175 transaction
.data
= "";
3176 std::string headers
;
3178 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3180 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3181 RemoveMockTransaction(&transaction
);
3184 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3185 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3186 MockHttpCache cache
;
3187 MockTransaction
transaction(kSimpleGET_Transaction
);
3188 AddMockTransaction(&transaction
);
3190 // Populate the cache.
3191 RunTransactionTest(cache
.http_cache(), transaction
);
3194 transaction
.method
= "HEAD";
3195 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3196 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3197 transaction
.return_code
= ERR_CACHE_MISS
;
3198 RunTransactionTest(cache
.http_cache(), transaction
);
3200 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3201 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3202 RemoveMockTransaction(&transaction
);
3205 // Tests that a HEAD request can be served from a partialy cached resource.
3206 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3207 MockHttpCache cache
;
3208 AddMockTransaction(&kRangeGET_TransactionOK
);
3210 // Write to the cache (40-49).
3211 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3212 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3214 MockTransaction
transaction(kSimpleGET_Transaction
);
3216 transaction
.url
= kRangeGET_TransactionOK
.url
;
3217 transaction
.method
= "HEAD";
3218 transaction
.data
= "";
3219 AddMockTransaction(&transaction
);
3220 std::string headers
;
3223 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3225 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3226 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3227 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3228 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3229 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3230 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3231 RemoveMockTransaction(&transaction
);
3234 // Tests that a HEAD request can be served from a truncated resource.
3235 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3236 MockHttpCache cache
;
3237 AddMockTransaction(&kRangeGET_TransactionOK
);
3239 std::string
raw_headers("HTTP/1.1 200 OK\n"
3240 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3242 "Accept-Ranges: bytes\n"
3243 "Content-Length: 80\n");
3244 CreateTruncatedEntry(raw_headers
, &cache
);
3245 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3247 MockTransaction
transaction(kSimpleGET_Transaction
);
3249 transaction
.url
= kRangeGET_TransactionOK
.url
;
3250 transaction
.method
= "HEAD";
3251 transaction
.data
= "";
3252 AddMockTransaction(&transaction
);
3253 std::string headers
;
3256 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3258 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3259 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3260 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3261 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3262 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3263 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3264 RemoveMockTransaction(&transaction
);
3267 // Tests that a HEAD request updates the cached response.
3268 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3269 MockHttpCache cache
;
3270 MockTransaction
transaction(kTypicalGET_Transaction
);
3271 AddMockTransaction(&transaction
);
3273 // Populate the cache.
3274 RunTransactionTest(cache
.http_cache(), transaction
);
3276 // Update the cache.
3277 transaction
.method
= "HEAD";
3278 transaction
.response_headers
= "Foo: bar\n";
3279 transaction
.data
= "";
3280 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3281 std::string headers
;
3282 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3283 RemoveMockTransaction(&transaction
);
3285 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3286 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3288 MockTransaction
transaction2(kTypicalGET_Transaction
);
3289 AddMockTransaction(&transaction2
);
3291 // Make sure we are done with the previous transaction.
3292 base::MessageLoop::current()->RunUntilIdle();
3294 // Load from the cache.
3295 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3296 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3298 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3299 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3300 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3301 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3302 RemoveMockTransaction(&transaction2
);
3305 // Tests that an externally conditionalized HEAD request updates the cache.
3306 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3307 MockHttpCache cache
;
3308 MockTransaction
transaction(kTypicalGET_Transaction
);
3309 AddMockTransaction(&transaction
);
3311 // Populate the cache.
3312 RunTransactionTest(cache
.http_cache(), transaction
);
3314 // Update the cache.
3315 transaction
.method
= "HEAD";
3316 transaction
.request_headers
=
3317 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3318 transaction
.response_headers
= "Foo: bar\n";
3319 transaction
.data
= "";
3320 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3321 std::string headers
;
3322 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3323 RemoveMockTransaction(&transaction
);
3325 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3326 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3328 MockTransaction
transaction2(kTypicalGET_Transaction
);
3329 AddMockTransaction(&transaction2
);
3331 // Make sure we are done with the previous transaction.
3332 base::MessageLoop::current()->RunUntilIdle();
3334 // Load from the cache.
3335 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3336 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3338 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3339 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3340 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3341 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3342 RemoveMockTransaction(&transaction2
);
3345 // Tests that a HEAD request invalidates an old cached entry.
3346 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3347 MockHttpCache cache
;
3348 MockTransaction
transaction(kTypicalGET_Transaction
);
3349 AddMockTransaction(&transaction
);
3351 // Populate the cache.
3352 RunTransactionTest(cache
.http_cache(), transaction
);
3354 // Update the cache.
3355 transaction
.method
= "HEAD";
3356 transaction
.data
= "";
3357 RunTransactionTest(cache
.http_cache(), transaction
);
3358 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3360 // Load from the cache.
3361 transaction
.method
= "GET";
3362 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3363 transaction
.return_code
= ERR_CACHE_MISS
;
3364 RunTransactionTest(cache
.http_cache(), transaction
);
3366 RemoveMockTransaction(&transaction
);
3369 // Tests that we do not cache the response of a PUT.
3370 TEST(HttpCache
, SimplePUT_Miss
) {
3371 MockHttpCache cache
;
3373 MockTransaction
transaction(kSimplePOST_Transaction
);
3374 transaction
.method
= "PUT";
3376 ScopedVector
<UploadElementReader
> element_readers
;
3377 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3378 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3380 MockHttpRequest
request(transaction
);
3381 request
.upload_data_stream
= &upload_data_stream
;
3383 // Attempt to populate the cache.
3384 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3386 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3387 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3388 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3391 // Tests that we invalidate entries as a result of a PUT.
3392 TEST(HttpCache
, SimplePUT_Invalidate
) {
3393 MockHttpCache cache
;
3395 MockTransaction
transaction(kSimpleGET_Transaction
);
3396 MockHttpRequest
req1(transaction
);
3398 // Attempt to populate the cache.
3399 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3401 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3402 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3403 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3405 ScopedVector
<UploadElementReader
> element_readers
;
3406 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3407 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3409 transaction
.method
= "PUT";
3410 MockHttpRequest
req2(transaction
);
3411 req2
.upload_data_stream
= &upload_data_stream
;
3413 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3415 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3416 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3417 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3419 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3421 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3422 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3423 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3426 // Tests that we invalidate entries as a result of a PUT.
3427 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3428 MockHttpCache cache
;
3430 MockTransaction
transaction(kSimpleGET_Transaction
);
3431 AddMockTransaction(&transaction
);
3432 MockHttpRequest
req1(transaction
);
3434 // Attempt to populate the cache.
3435 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3437 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3438 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3439 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3441 ScopedVector
<UploadElementReader
> element_readers
;
3442 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3443 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3445 transaction
.method
= "PUT";
3446 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3447 MockHttpRequest
req2(transaction
);
3448 req2
.upload_data_stream
= &upload_data_stream
;
3450 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3452 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3453 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3454 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3456 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3458 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3459 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3460 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3461 RemoveMockTransaction(&transaction
);
3464 // Tests that we don't invalidate entries as a result of a failed PUT.
3465 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3466 MockHttpCache cache
;
3468 MockTransaction
transaction(kSimpleGET_Transaction
);
3469 AddMockTransaction(&transaction
);
3470 MockHttpRequest
req1(transaction
);
3472 // Attempt to populate the cache.
3473 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3475 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3476 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3477 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3479 ScopedVector
<UploadElementReader
> element_readers
;
3480 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3481 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3483 transaction
.method
= "PUT";
3484 transaction
.status
= "HTTP/1.1 404 Not Found";
3485 MockHttpRequest
req2(transaction
);
3486 req2
.upload_data_stream
= &upload_data_stream
;
3488 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3490 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3491 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3492 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3494 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3496 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3497 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3498 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3499 RemoveMockTransaction(&transaction
);
3502 // Tests that we do not cache the response of a DELETE.
3503 TEST(HttpCache
, SimpleDELETE_Miss
) {
3504 MockHttpCache cache
;
3506 MockTransaction
transaction(kSimplePOST_Transaction
);
3507 transaction
.method
= "DELETE";
3509 ScopedVector
<UploadElementReader
> element_readers
;
3510 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3511 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3513 MockHttpRequest
request(transaction
);
3514 request
.upload_data_stream
= &upload_data_stream
;
3516 // Attempt to populate the cache.
3517 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3519 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3520 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3521 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3524 // Tests that we invalidate entries as a result of a DELETE.
3525 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3526 MockHttpCache cache
;
3528 MockTransaction
transaction(kSimpleGET_Transaction
);
3529 MockHttpRequest
req1(transaction
);
3531 // Attempt to populate the cache.
3532 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3534 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3535 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3536 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3538 ScopedVector
<UploadElementReader
> element_readers
;
3539 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3540 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3542 transaction
.method
= "DELETE";
3543 MockHttpRequest
req2(transaction
);
3544 req2
.upload_data_stream
= &upload_data_stream
;
3546 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3548 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3549 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3550 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3552 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3554 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3555 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3556 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3559 // Tests that we invalidate entries as a result of a DELETE.
3560 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3561 MockHttpCache cache
;
3563 MockTransaction
transaction(kSimpleGET_Transaction
);
3564 AddMockTransaction(&transaction
);
3566 // Attempt to populate the cache.
3567 RunTransactionTest(cache
.http_cache(), transaction
);
3569 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3570 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3571 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3573 transaction
.method
= "DELETE";
3574 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3576 RunTransactionTest(cache
.http_cache(), transaction
);
3578 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3579 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3580 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3582 transaction
.method
= "GET";
3583 RunTransactionTest(cache
.http_cache(), transaction
);
3585 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3586 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3587 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3588 RemoveMockTransaction(&transaction
);
3591 // Tests that we don't invalidate entries as a result of a failed DELETE.
3592 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3593 MockHttpCache cache
;
3595 MockTransaction
transaction(kSimpleGET_Transaction
);
3596 AddMockTransaction(&transaction
);
3598 // Attempt to populate the cache.
3599 RunTransactionTest(cache
.http_cache(), transaction
);
3601 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3602 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3603 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3605 transaction
.method
= "DELETE";
3606 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3608 RunTransactionTest(cache
.http_cache(), transaction
);
3610 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3611 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3612 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3614 transaction
.method
= "GET";
3615 transaction
.status
= "HTTP/1.1 200 OK";
3616 RunTransactionTest(cache
.http_cache(), transaction
);
3618 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3619 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3620 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3621 RemoveMockTransaction(&transaction
);
3624 // Tests that we don't invalidate entries after a failed network transaction.
3625 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3626 MockHttpCache cache
;
3628 // Populate the cache.
3629 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3630 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3632 // Fail the network request.
3633 MockTransaction
transaction(kSimpleGET_Transaction
);
3634 transaction
.return_code
= ERR_FAILED
;
3635 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
3637 AddMockTransaction(&transaction
);
3638 RunTransactionTest(cache
.http_cache(), transaction
);
3639 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3640 RemoveMockTransaction(&transaction
);
3642 transaction
.load_flags
= LOAD_ONLY_FROM_CACHE
;
3643 transaction
.return_code
= OK
;
3644 AddMockTransaction(&transaction
);
3645 RunTransactionTest(cache
.http_cache(), transaction
);
3647 // Make sure the transaction didn't reach the network.
3648 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3649 RemoveMockTransaction(&transaction
);
3652 TEST(HttpCache
, RangeGET_SkipsCache
) {
3653 MockHttpCache cache
;
3655 // Test that we skip the cache for range GET requests. Eventually, we will
3656 // want to cache these, but we'll still have cases where skipping the cache
3657 // makes sense, so we want to make sure that it works properly.
3659 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3661 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3662 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3663 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3665 MockTransaction
transaction(kSimpleGET_Transaction
);
3666 transaction
.request_headers
= "If-None-Match: foo\r\n";
3667 RunTransactionTest(cache
.http_cache(), transaction
);
3669 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3670 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3671 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3673 transaction
.request_headers
=
3674 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3675 RunTransactionTest(cache
.http_cache(), transaction
);
3677 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3678 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3679 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3682 // Test that we skip the cache for range requests that include a validation
3684 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3685 MockHttpCache cache
;
3687 MockTransaction
transaction(kRangeGET_Transaction
);
3688 transaction
.request_headers
= "If-None-Match: foo\r\n"
3690 "Range: bytes = 40-49\r\n";
3691 RunTransactionTest(cache
.http_cache(), transaction
);
3693 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3694 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3695 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3697 transaction
.request_headers
=
3698 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3700 "Range: bytes = 40-49\r\n";
3701 RunTransactionTest(cache
.http_cache(), transaction
);
3703 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3704 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3705 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3707 transaction
.request_headers
= "If-Range: bla\r\n"
3709 "Range: bytes = 40-49\r\n";
3710 RunTransactionTest(cache
.http_cache(), transaction
);
3712 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3713 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3714 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3717 TEST(HttpCache
, SimpleGET_DoesntLogHeaders
) {
3718 MockHttpCache cache
;
3720 BoundTestNetLog log
;
3721 RunTransactionTestWithLog(cache
.http_cache(), kSimpleGET_Transaction
,
3724 EXPECT_FALSE(LogContainsEventType(
3725 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3728 TEST(HttpCache
, RangeGET_LogsHeaders
) {
3729 MockHttpCache cache
;
3731 BoundTestNetLog log
;
3732 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_Transaction
,
3735 EXPECT_TRUE(LogContainsEventType(
3736 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3739 TEST(HttpCache
, ExternalValidation_LogsHeaders
) {
3740 MockHttpCache cache
;
3742 BoundTestNetLog log
;
3743 MockTransaction
transaction(kSimpleGET_Transaction
);
3744 transaction
.request_headers
= "If-None-Match: foo\r\n" EXTRA_HEADER
;
3745 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3747 EXPECT_TRUE(LogContainsEventType(
3748 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3751 TEST(HttpCache
, SpecialHeaders_LogsHeaders
) {
3752 MockHttpCache cache
;
3754 BoundTestNetLog log
;
3755 MockTransaction
transaction(kSimpleGET_Transaction
);
3756 transaction
.request_headers
= "cache-control: no-cache\r\n" EXTRA_HEADER
;
3757 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3759 EXPECT_TRUE(LogContainsEventType(
3760 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3763 // Tests that receiving 206 for a regular request is handled correctly.
3764 TEST(HttpCache
, GET_Crazy206
) {
3765 MockHttpCache cache
;
3767 // Write to the cache.
3768 MockTransaction
transaction(kRangeGET_TransactionOK
);
3769 AddMockTransaction(&transaction
);
3770 transaction
.request_headers
= EXTRA_HEADER
;
3771 transaction
.handler
= NULL
;
3772 RunTransactionTest(cache
.http_cache(), transaction
);
3774 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3775 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3776 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3778 // This should read again from the net.
3779 RunTransactionTest(cache
.http_cache(), transaction
);
3781 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3782 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3783 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3784 RemoveMockTransaction(&transaction
);
3787 // Tests that receiving 416 for a regular request is handled correctly.
3788 TEST(HttpCache
, GET_Crazy416
) {
3789 MockHttpCache cache
;
3791 // Write to the cache.
3792 MockTransaction
transaction(kSimpleGET_Transaction
);
3793 AddMockTransaction(&transaction
);
3794 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3795 RunTransactionTest(cache
.http_cache(), transaction
);
3797 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3798 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3799 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3801 RemoveMockTransaction(&transaction
);
3804 // Tests that we don't store partial responses that can't be validated.
3805 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3806 MockHttpCache cache
;
3807 std::string headers
;
3809 // Attempt to write to the cache (40-49).
3810 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3811 transaction
.response_headers
= "Content-Length: 10\n"
3812 "Cache-Control: max-age=3600\n"
3813 "ETag: w/\"foo\"\n";
3814 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3816 Verify206Response(headers
, 40, 49);
3817 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3818 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3819 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3821 // Now verify that there's no cached data.
3822 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3825 Verify206Response(headers
, 40, 49);
3826 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3827 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3828 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3831 // Tests failures to conditionalize byte range requests.
3832 TEST(HttpCache
, RangeGET_NoConditionalization
) {
3833 MockHttpCache cache
;
3834 cache
.FailConditionalizations();
3835 std::string headers
;
3837 // Write to the cache (40-49).
3838 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3839 transaction
.response_headers
= "Content-Length: 10\n"
3841 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3843 Verify206Response(headers
, 40, 49);
3844 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3845 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3846 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3848 // Now verify that the cached data is not used.
3849 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3852 Verify206Response(headers
, 40, 49);
3853 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3854 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3855 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3858 // Tests that restarting a partial request when the cached data cannot be
3859 // revalidated logs an event.
3860 TEST(HttpCache
, RangeGET_NoValidation_LogsRestart
) {
3861 MockHttpCache cache
;
3862 cache
.FailConditionalizations();
3864 // Write to the cache (40-49).
3865 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3866 transaction
.response_headers
= "Content-Length: 10\n"
3868 RunTransactionTest(cache
.http_cache(), transaction
);
3870 // Now verify that the cached data is not used.
3871 BoundTestNetLog log
;
3872 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_TransactionOK
,
3875 EXPECT_TRUE(LogContainsEventType(
3876 log
, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST
));
3879 // Tests that a failure to conditionalize a regular request (no range) with a
3880 // sparse entry results in a full response.
3881 TEST(HttpCache
, GET_NoConditionalization
) {
3882 MockHttpCache cache
;
3883 cache
.FailConditionalizations();
3884 std::string headers
;
3886 // Write to the cache (40-49).
3887 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3888 transaction
.response_headers
= "Content-Length: 10\n"
3890 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
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());
3897 // Now verify that the cached data is not used.
3898 // Don't ask for a range. The cache will attempt to use the cached data but
3899 // should discard it as it cannot be validated. A regular request should go
3900 // to the server and a new entry should be created.
3901 transaction
.request_headers
= EXTRA_HEADER
;
3902 transaction
.data
= "Not a range";
3903 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3905 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
3906 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3907 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3908 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3910 // The last response was saved.
3911 RunTransactionTest(cache
.http_cache(), transaction
);
3912 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3913 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3914 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3917 // Verifies that conditionalization failures when asking for a range that would
3918 // require the cache to modify the range to ask, result in a network request
3919 // that matches the user's one.
3920 TEST(HttpCache
, RangeGET_NoConditionalization2
) {
3921 MockHttpCache cache
;
3922 cache
.FailConditionalizations();
3923 std::string headers
;
3925 // Write to the cache (40-49).
3926 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3927 transaction
.response_headers
= "Content-Length: 10\n"
3929 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3931 Verify206Response(headers
, 40, 49);
3932 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3933 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3934 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3936 // Now verify that the cached data is not used.
3937 // Ask for a range that extends before and after the cached data so that the
3938 // cache would normally mix data from three sources. After deleting the entry,
3939 // the response will come from a single network request.
3940 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3941 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3942 transaction
.response_headers
= kRangeGET_TransactionOK
.response_headers
;
3943 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3945 Verify206Response(headers
, 20, 59);
3946 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3947 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3948 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3950 // The last response was saved.
3951 RunTransactionTest(cache
.http_cache(), transaction
);
3952 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3953 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3954 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3957 // Tests that we cache partial responses that lack content-length.
3958 TEST(HttpCache
, RangeGET_NoContentLength
) {
3959 MockHttpCache cache
;
3960 std::string headers
;
3962 // Attempt to write to the cache (40-49).
3963 MockTransaction
transaction(kRangeGET_TransactionOK
);
3964 AddMockTransaction(&transaction
);
3965 transaction
.response_headers
= "ETag: \"foo\"\n"
3966 "Accept-Ranges: bytes\n"
3967 "Content-Range: bytes 40-49/80\n";
3968 transaction
.handler
= NULL
;
3969 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3971 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3972 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3973 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3975 // Now verify that there's no cached data.
3976 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
3977 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3980 Verify206Response(headers
, 40, 49);
3981 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3982 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3983 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3985 RemoveMockTransaction(&transaction
);
3988 // Tests that we can cache range requests and fetch random blocks from the
3989 // cache and the network.
3990 TEST(HttpCache
, RangeGET_OK
) {
3991 MockHttpCache cache
;
3992 AddMockTransaction(&kRangeGET_TransactionOK
);
3993 std::string headers
;
3995 // Write to the cache (40-49).
3996 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3999 Verify206Response(headers
, 40, 49);
4000 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4001 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4002 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4004 // Read from the cache (40-49).
4005 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4008 Verify206Response(headers
, 40, 49);
4009 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4010 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4011 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4013 // Make sure we are done with the previous transaction.
4014 base::MessageLoop::current()->RunUntilIdle();
4016 // Write to the cache (30-39).
4017 MockTransaction
transaction(kRangeGET_TransactionOK
);
4018 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4019 transaction
.data
= "rg: 30-39 ";
4020 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4022 Verify206Response(headers
, 30, 39);
4023 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4024 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4025 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4027 // Make sure we are done with the previous transaction.
4028 base::MessageLoop::current()->RunUntilIdle();
4030 // Write and read from the cache (20-59).
4031 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4032 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4033 BoundTestNetLog log
;
4034 LoadTimingInfo load_timing_info
;
4035 RunTransactionTestWithResponseAndGetTiming(
4036 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4039 Verify206Response(headers
, 20, 59);
4040 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4041 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4042 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4043 TestLoadTimingNetworkRequest(load_timing_info
);
4045 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4048 // Tests that we can cache range requests and fetch random blocks from the
4049 // cache and the network, with synchronous responses.
4050 TEST(HttpCache
, RangeGET_SyncOK
) {
4051 MockHttpCache cache
;
4053 MockTransaction
transaction(kRangeGET_TransactionOK
);
4054 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
4055 AddMockTransaction(&transaction
);
4057 // Write to the cache (40-49).
4058 std::string headers
;
4059 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4061 Verify206Response(headers
, 40, 49);
4062 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4063 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4064 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4066 // Read from the cache (40-49).
4067 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4069 Verify206Response(headers
, 40, 49);
4070 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4071 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4072 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4074 // Make sure we are done with the previous transaction.
4075 base::MessageLoop::current()->RunUntilIdle();
4077 // Write to the cache (30-39).
4078 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4079 transaction
.data
= "rg: 30-39 ";
4080 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4082 Verify206Response(headers
, 30, 39);
4083 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4084 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4085 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4087 // Make sure we are done with the previous transaction.
4088 base::MessageLoop::current()->RunUntilIdle();
4090 // Write and read from the cache (20-59).
4091 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4092 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4093 BoundTestNetLog log
;
4094 LoadTimingInfo load_timing_info
;
4095 RunTransactionTestWithResponseAndGetTiming(
4096 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4099 Verify206Response(headers
, 20, 59);
4100 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4101 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4102 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4103 TestLoadTimingNetworkRequest(load_timing_info
);
4105 RemoveMockTransaction(&transaction
);
4108 // Tests that if the previous transaction is cancelled while busy (doing sparse
4109 // IO), a new transaction (that reuses that same ActiveEntry) waits until the
4110 // entry is ready again.
4111 TEST(HttpCache
, Sparse_WaitForEntry
) {
4112 MockHttpCache cache
;
4114 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4116 // Create a sparse entry.
4117 RunTransactionTest(cache
.http_cache(), transaction
);
4119 // Simulate a previous transaction being cancelled.
4120 disk_cache::Entry
* entry
;
4121 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4122 entry
->CancelSparseIO();
4124 // Test with a range request.
4125 RunTransactionTest(cache
.http_cache(), transaction
);
4127 // Now test with a regular request.
4128 entry
->CancelSparseIO();
4129 transaction
.request_headers
= EXTRA_HEADER
;
4130 transaction
.data
= kFullRangeData
;
4131 RunTransactionTest(cache
.http_cache(), transaction
);
4136 // Tests that we don't revalidate an entry unless we are required to do so.
4137 TEST(HttpCache
, RangeGET_Revalidate1
) {
4138 MockHttpCache cache
;
4139 std::string headers
;
4141 // Write to the cache (40-49).
4142 MockTransaction
transaction(kRangeGET_TransactionOK
);
4143 transaction
.response_headers
=
4144 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4145 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4147 "Accept-Ranges: bytes\n"
4148 "Content-Length: 10\n";
4149 AddMockTransaction(&transaction
);
4150 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4152 Verify206Response(headers
, 40, 49);
4153 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4154 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4155 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4157 // Read from the cache (40-49).
4158 BoundTestNetLog log
;
4159 LoadTimingInfo load_timing_info
;
4160 RunTransactionTestWithResponseAndGetTiming(
4161 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4164 Verify206Response(headers
, 40, 49);
4165 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4166 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4167 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4168 TestLoadTimingCachedResponse(load_timing_info
);
4170 // Read again forcing the revalidation.
4171 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4172 RunTransactionTestWithResponseAndGetTiming(
4173 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4176 Verify206Response(headers
, 40, 49);
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 TestLoadTimingNetworkRequest(load_timing_info
);
4182 RemoveMockTransaction(&transaction
);
4185 // Checks that we revalidate an entry when the headers say so.
4186 TEST(HttpCache
, RangeGET_Revalidate2
) {
4187 MockHttpCache cache
;
4188 std::string headers
;
4190 // Write to the cache (40-49).
4191 MockTransaction
transaction(kRangeGET_TransactionOK
);
4192 transaction
.response_headers
=
4193 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4194 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4196 "Accept-Ranges: bytes\n"
4197 "Content-Length: 10\n";
4198 AddMockTransaction(&transaction
);
4199 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4201 Verify206Response(headers
, 40, 49);
4202 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4203 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4204 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4206 // Read from the cache (40-49).
4207 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4208 Verify206Response(headers
, 40, 49);
4210 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4211 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4212 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4214 RemoveMockTransaction(&transaction
);
4217 // Tests that we deal with 304s for range requests.
4218 TEST(HttpCache
, RangeGET_304
) {
4219 MockHttpCache cache
;
4220 AddMockTransaction(&kRangeGET_TransactionOK
);
4221 std::string headers
;
4223 // Write to the cache (40-49).
4224 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4227 Verify206Response(headers
, 40, 49);
4228 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4229 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4230 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4232 // Read from the cache (40-49).
4233 RangeTransactionServer handler
;
4234 handler
.set_not_modified(true);
4235 MockTransaction
transaction(kRangeGET_TransactionOK
);
4236 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4237 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4239 Verify206Response(headers
, 40, 49);
4240 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4241 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4242 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4244 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4247 // Tests that we deal with 206s when revalidating range requests.
4248 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4249 MockHttpCache cache
;
4250 AddMockTransaction(&kRangeGET_TransactionOK
);
4251 std::string headers
;
4253 // Write to the cache (40-49).
4254 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4257 Verify206Response(headers
, 40, 49);
4258 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4259 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4262 // Attempt to read from the cache (40-49).
4263 RangeTransactionServer handler
;
4264 handler
.set_modified(true);
4265 MockTransaction
transaction(kRangeGET_TransactionOK
);
4266 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4267 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4269 Verify206Response(headers
, 40, 49);
4270 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4271 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4272 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4274 // And the entry should be gone.
4275 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4276 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4277 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4278 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4280 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4283 // Tests that when a server returns 206 with a sub-range of the requested range,
4284 // and there is nothing stored in the cache, the returned response is passed to
4285 // the caller as is. In this context, a subrange means a response that starts
4286 // with the same byte that was requested, but that is not the whole range that
4288 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_NoCachedContent
) {
4289 MockHttpCache cache
;
4290 std::string headers
;
4292 // Request a large range (40-59). The server sends 40-49.
4293 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4294 transaction
.request_headers
= "Range: bytes = 40-59\r\n" EXTRA_HEADER
;
4295 transaction
.response_headers
=
4296 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4298 "Accept-Ranges: bytes\n"
4299 "Content-Length: 10\n"
4300 "Content-Range: bytes 40-49/80\n";
4301 transaction
.handler
= nullptr;
4302 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4304 Verify206Response(headers
, 40, 49);
4305 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4306 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4307 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4310 // Tests that when a server returns 206 with a sub-range of the requested range,
4311 // and there was an entry stored in the cache, the cache gets out of the way.
4312 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_CachedContent
) {
4313 MockHttpCache cache
;
4314 std::string headers
;
4316 // Write to the cache (70-79).
4317 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4318 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4319 transaction
.data
= "rg: 70-79 ";
4320 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4321 Verify206Response(headers
, 70, 79);
4323 // Request a large range (40-79). The cache will ask the server for 40-59.
4324 // The server returns 40-49. The cache should consider the server confused and
4325 // abort caching, restarting the request without caching.
4326 transaction
.request_headers
= "Range: bytes = 40-79\r\n" EXTRA_HEADER
;
4327 transaction
.response_headers
=
4328 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4330 "Accept-Ranges: bytes\n"
4331 "Content-Length: 10\n"
4332 "Content-Range: bytes 40-49/80\n";
4333 transaction
.handler
= nullptr;
4334 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4336 // Two new network requests were issued, one from the cache and another after
4337 // deleting the entry.
4338 Verify206Response(headers
, 40, 49);
4339 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4340 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4341 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4343 // The entry was deleted.
4344 RunTransactionTest(cache
.http_cache(), transaction
);
4345 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4346 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4347 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4350 // Tests that when a server returns 206 with a sub-range of the requested range,
4351 // and there was an entry stored in the cache, the cache gets out of the way,
4352 // when the caller is not using ranges.
4353 TEST(HttpCache
, GET_206ReturnsSubrangeRange_CachedContent
) {
4354 MockHttpCache cache
;
4355 std::string headers
;
4357 // Write to the cache (70-79).
4358 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4359 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4360 transaction
.data
= "rg: 70-79 ";
4361 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4362 Verify206Response(headers
, 70, 79);
4364 // Don't ask for a range. The cache will ask the server for 0-69.
4365 // The server returns 40-49. The cache should consider the server confused and
4366 // abort caching, restarting the request.
4367 // The second network request should not be a byte range request so the server
4368 // should return 200 + "Not a range"
4369 transaction
.request_headers
= "X-Return-Default-Range:\r\n" EXTRA_HEADER
;
4370 transaction
.data
= "Not a range";
4371 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4373 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4374 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4375 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4376 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4378 // The entry was deleted.
4379 RunTransactionTest(cache
.http_cache(), transaction
);
4380 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4381 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4382 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4385 // Tests that when a server returns 206 with a random range and there is
4386 // nothing stored in the cache, the returned response is passed to the caller
4387 // as is. In this context, a WrongRange means that the returned range may or may
4388 // not have any relationship with the requested range (may or may not be
4389 // contained). The important part is that the first byte doesn't match the first
4391 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_NoCachedContent
) {
4392 MockHttpCache cache
;
4393 std::string headers
;
4395 // Request a large range (30-59). The server sends (40-49).
4396 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4397 transaction
.request_headers
= "Range: bytes = 30-59\r\n" EXTRA_HEADER
;
4398 transaction
.response_headers
=
4399 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4401 "Accept-Ranges: bytes\n"
4402 "Content-Length: 10\n"
4403 "Content-Range: bytes 40-49/80\n";
4404 transaction
.handler
= nullptr;
4405 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4407 Verify206Response(headers
, 40, 49);
4408 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4409 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4410 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4412 // The entry was deleted.
4413 RunTransactionTest(cache
.http_cache(), transaction
);
4414 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4415 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4416 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4419 // Tests that when a server returns 206 with a random range and there is
4420 // an entry stored in the cache, the cache gets out of the way.
4421 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_CachedContent
) {
4422 MockHttpCache cache
;
4423 std::string headers
;
4425 // Write to the cache (70-79).
4426 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4427 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4428 transaction
.data
= "rg: 70-79 ";
4429 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4430 Verify206Response(headers
, 70, 79);
4432 // Request a large range (30-79). The cache will ask the server for 30-69.
4433 // The server returns 40-49. The cache should consider the server confused and
4434 // abort caching, returning the weird range to the caller.
4435 transaction
.request_headers
= "Range: bytes = 30-79\r\n" EXTRA_HEADER
;
4436 transaction
.response_headers
=
4437 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4439 "Accept-Ranges: bytes\n"
4440 "Content-Length: 10\n"
4441 "Content-Range: bytes 40-49/80\n";
4442 transaction
.handler
= nullptr;
4443 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4445 Verify206Response(headers
, 40, 49);
4446 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4447 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4448 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4450 // The entry was deleted.
4451 RunTransactionTest(cache
.http_cache(), transaction
);
4452 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4453 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4454 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4457 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4458 // the response matches the one provided by the server.
4459 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_NoCachedContent
) {
4460 MockHttpCache cache
;
4461 std::string headers
;
4463 // Request a large range (70-99). The server sends 70-79.
4464 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4465 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4466 transaction
.data
= "rg: 70-79 ";
4467 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4469 Verify206Response(headers
, 70, 79);
4470 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4471 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4472 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4474 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4475 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4478 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4479 // the cache automatically fixes the request.
4480 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_CachedContent
) {
4481 MockHttpCache cache
;
4482 std::string headers
;
4484 // Write to the cache (40-49).
4485 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4486 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4488 // Request a large range (70-99). The server sends 70-79.
4489 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4490 transaction
.data
= "rg: 70-79 ";
4491 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4493 Verify206Response(headers
, 70, 79);
4494 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4495 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4496 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4498 // The entry was not deleted (the range was automatically fixed).
4499 RunTransactionTest(cache
.http_cache(), transaction
);
4500 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4501 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4502 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4505 // Tests that when a caller asks for a not-satisfiable range, the server's
4506 // response is forwarded to the caller.
4507 TEST(HttpCache
, RangeGET_416_NoCachedContent
) {
4508 MockHttpCache cache
;
4509 std::string headers
;
4511 // Request a range beyond EOF (80-99).
4512 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4513 transaction
.request_headers
= "Range: bytes = 80-99\r\n" EXTRA_HEADER
;
4514 transaction
.data
= "";
4515 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
4516 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4518 EXPECT_EQ(0U, headers
.find(transaction
.status
));
4519 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4520 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4521 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4523 // The entry was deleted.
4524 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4525 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4528 // Tests that we cache 301s for range requests.
4529 TEST(HttpCache
, RangeGET_301
) {
4530 MockHttpCache cache
;
4531 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4532 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4533 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4534 transaction
.data
= "";
4535 transaction
.handler
= NULL
;
4537 // Write to the cache.
4538 RunTransactionTest(cache
.http_cache(), transaction
);
4539 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4540 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4541 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4543 // Read from the cache.
4544 RunTransactionTest(cache
.http_cache(), transaction
);
4545 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4546 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4547 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4550 // Tests that we can cache range requests when the start or end is unknown.
4551 // We start with one suffix request, followed by a request from a given point.
4552 TEST(HttpCache
, UnknownRangeGET_1
) {
4553 MockHttpCache cache
;
4554 AddMockTransaction(&kRangeGET_TransactionOK
);
4555 std::string headers
;
4557 // Write to the cache (70-79).
4558 MockTransaction
transaction(kRangeGET_TransactionOK
);
4559 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4560 transaction
.data
= "rg: 70-79 ";
4561 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4563 Verify206Response(headers
, 70, 79);
4564 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4565 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4566 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4568 // Make sure we are done with the previous transaction.
4569 base::MessageLoop::current()->RunUntilIdle();
4571 // Write and read from the cache (60-79).
4572 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4573 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4574 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4576 Verify206Response(headers
, 60, 79);
4577 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4578 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4579 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4581 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4584 // Tests that we can cache range requests when the start or end is unknown.
4585 // We start with one request from a given point, followed by a suffix request.
4586 // We'll also verify that synchronous cache responses work as intended.
4587 TEST(HttpCache
, UnknownRangeGET_2
) {
4588 MockHttpCache cache
;
4589 std::string headers
;
4591 MockTransaction
transaction(kRangeGET_TransactionOK
);
4592 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4593 TEST_MODE_SYNC_CACHE_READ
|
4594 TEST_MODE_SYNC_CACHE_WRITE
;
4595 AddMockTransaction(&transaction
);
4597 // Write to the cache (70-79).
4598 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4599 transaction
.data
= "rg: 70-79 ";
4600 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4602 Verify206Response(headers
, 70, 79);
4603 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4605 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4607 // Make sure we are done with the previous transaction.
4608 base::MessageLoop::current()->RunUntilIdle();
4610 // Write and read from the cache (60-79).
4611 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4612 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4613 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4615 Verify206Response(headers
, 60, 79);
4616 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4617 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4618 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4620 RemoveMockTransaction(&transaction
);
4623 // Tests that receiving Not Modified when asking for an open range doesn't mess
4625 TEST(HttpCache
, UnknownRangeGET_304
) {
4626 MockHttpCache cache
;
4627 std::string headers
;
4629 MockTransaction
transaction(kRangeGET_TransactionOK
);
4630 AddMockTransaction(&transaction
);
4632 RangeTransactionServer handler
;
4633 handler
.set_not_modified(true);
4635 // Ask for the end of the file, without knowing the length.
4636 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4637 transaction
.data
= "";
4638 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4640 // We just bypass the cache.
4641 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4642 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4643 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4644 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4646 RunTransactionTest(cache
.http_cache(), transaction
);
4647 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4649 RemoveMockTransaction(&transaction
);
4652 // Tests that we can handle non-range requests when we have cached a range.
4653 TEST(HttpCache
, GET_Previous206
) {
4654 MockHttpCache cache
;
4655 AddMockTransaction(&kRangeGET_TransactionOK
);
4656 std::string headers
;
4657 BoundTestNetLog log
;
4658 LoadTimingInfo load_timing_info
;
4660 // Write to the cache (40-49).
4661 RunTransactionTestWithResponseAndGetTiming(
4662 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4665 Verify206Response(headers
, 40, 49);
4666 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4667 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4668 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4669 TestLoadTimingNetworkRequest(load_timing_info
);
4671 // Write and read from the cache (0-79), when not asked for a range.
4672 MockTransaction
transaction(kRangeGET_TransactionOK
);
4673 transaction
.request_headers
= EXTRA_HEADER
;
4674 transaction
.data
= kFullRangeData
;
4675 RunTransactionTestWithResponseAndGetTiming(
4676 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4679 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4680 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4681 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4682 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4683 TestLoadTimingNetworkRequest(load_timing_info
);
4685 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4688 // Tests that we can handle non-range requests when we have cached the first
4689 // part of the object and the server replies with 304 (Not Modified).
4690 TEST(HttpCache
, GET_Previous206_NotModified
) {
4691 MockHttpCache cache
;
4693 MockTransaction
transaction(kRangeGET_TransactionOK
);
4694 AddMockTransaction(&transaction
);
4695 std::string headers
;
4696 BoundTestNetLog log
;
4697 LoadTimingInfo load_timing_info
;
4699 // Write to the cache (0-9).
4700 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4701 transaction
.data
= "rg: 00-09 ";
4702 RunTransactionTestWithResponseAndGetTiming(
4703 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4705 Verify206Response(headers
, 0, 9);
4706 TestLoadTimingNetworkRequest(load_timing_info
);
4708 // Write to the cache (70-79).
4709 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4710 transaction
.data
= "rg: 70-79 ";
4711 RunTransactionTestWithResponseAndGetTiming(
4712 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4714 Verify206Response(headers
, 70, 79);
4716 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4717 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4718 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4719 TestLoadTimingNetworkRequest(load_timing_info
);
4721 // Read from the cache (0-9), write and read from cache (10 - 79).
4722 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4723 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4724 transaction
.data
= kFullRangeData
;
4725 RunTransactionTestWithResponseAndGetTiming(
4726 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4729 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4730 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4731 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4732 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4733 TestLoadTimingNetworkRequest(load_timing_info
);
4735 RemoveMockTransaction(&transaction
);
4738 // Tests that we can handle a regular request to a sparse entry, that results in
4739 // new content provided by the server (206).
4740 TEST(HttpCache
, GET_Previous206_NewContent
) {
4741 MockHttpCache cache
;
4742 AddMockTransaction(&kRangeGET_TransactionOK
);
4743 std::string headers
;
4745 // Write to the cache (0-9).
4746 MockTransaction
transaction(kRangeGET_TransactionOK
);
4747 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4748 transaction
.data
= "rg: 00-09 ";
4749 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4751 Verify206Response(headers
, 0, 9);
4752 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4753 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4754 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4756 // Now we'll issue a request without any range that should result first in a
4757 // 206 (when revalidating), and then in a weird standard answer: the test
4758 // server will not modify the response so we'll get the default range... a
4759 // real server will answer with 200.
4760 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4761 transaction2
.request_headers
= EXTRA_HEADER
;
4762 transaction2
.load_flags
|= LOAD_VALIDATE_CACHE
;
4763 transaction2
.data
= "Not a range";
4764 RangeTransactionServer handler
;
4765 handler
.set_modified(true);
4766 BoundTestNetLog log
;
4767 LoadTimingInfo load_timing_info
;
4768 RunTransactionTestWithResponseAndGetTiming(
4769 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4772 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4773 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4774 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4775 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4776 TestLoadTimingNetworkRequest(load_timing_info
);
4778 // Verify that the previous request deleted the entry.
4779 RunTransactionTest(cache
.http_cache(), transaction
);
4780 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4782 RemoveMockTransaction(&transaction
);
4785 // Tests that we can handle cached 206 responses that are not sparse.
4786 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4787 MockHttpCache cache
;
4789 // Create a disk cache entry that stores 206 headers while not being sparse.
4790 disk_cache::Entry
* entry
;
4791 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4794 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4795 raw_headers
.append("\n");
4796 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4798 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4800 HttpResponseInfo response
;
4801 response
.headers
= new HttpResponseHeaders(raw_headers
);
4802 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4804 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4805 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4806 kRangeGET_TransactionOK
.data
, 500));
4807 TestCompletionCallback cb
;
4808 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4809 EXPECT_EQ(len
, cb
.GetResult(rv
));
4812 // Now see that we don't use the stored entry.
4813 std::string headers
;
4814 BoundTestNetLog log
;
4815 LoadTimingInfo load_timing_info
;
4816 RunTransactionTestWithResponseAndGetTiming(
4817 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4820 // We are expecting a 200.
4821 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4822 expected_headers
.append("\n");
4823 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4824 EXPECT_EQ(expected_headers
, headers
);
4825 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4826 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4827 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4828 TestLoadTimingNetworkRequest(load_timing_info
);
4831 // Tests that we can handle cached 206 responses that are not sparse. This time
4832 // we issue a range request and expect to receive a range.
4833 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4834 MockHttpCache cache
;
4835 AddMockTransaction(&kRangeGET_TransactionOK
);
4837 // Create a disk cache entry that stores 206 headers while not being sparse.
4838 disk_cache::Entry
* entry
;
4839 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4842 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4843 raw_headers
.append("\n");
4844 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4846 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4848 HttpResponseInfo response
;
4849 response
.headers
= new HttpResponseHeaders(raw_headers
);
4850 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4852 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4853 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4854 kRangeGET_TransactionOK
.data
, 500));
4855 TestCompletionCallback cb
;
4856 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4857 EXPECT_EQ(len
, cb
.GetResult(rv
));
4860 // Now see that we don't use the stored entry.
4861 std::string headers
;
4862 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4865 // We are expecting a 206.
4866 Verify206Response(headers
, 40, 49);
4867 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4868 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4869 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4871 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4874 // Tests that we can handle cached 206 responses that can't be validated.
4875 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4876 MockHttpCache cache
;
4878 // Create a disk cache entry that stores 206 headers.
4879 disk_cache::Entry
* entry
;
4880 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4883 // Make sure that the headers cannot be validated with the server.
4884 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4885 raw_headers
.append("\n");
4886 raw_headers
.append("Content-Length: 80\n");
4888 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4890 HttpResponseInfo response
;
4891 response
.headers
= new HttpResponseHeaders(raw_headers
);
4892 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4894 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4895 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4896 kRangeGET_TransactionOK
.data
, 500));
4897 TestCompletionCallback cb
;
4898 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4899 EXPECT_EQ(len
, cb
.GetResult(rv
));
4902 // Now see that we don't use the stored entry.
4903 std::string headers
;
4904 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4907 // We are expecting a 200.
4908 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4909 expected_headers
.append("\n");
4910 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4911 EXPECT_EQ(expected_headers
, headers
);
4912 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4913 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4914 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4917 // Tests that we can handle range requests with cached 200 responses.
4918 TEST(HttpCache
, RangeGET_Previous200
) {
4919 MockHttpCache cache
;
4921 // Store the whole thing with status 200.
4922 MockTransaction
transaction(kTypicalGET_Transaction
);
4923 transaction
.url
= kRangeGET_TransactionOK
.url
;
4924 transaction
.data
= kFullRangeData
;
4925 AddMockTransaction(&transaction
);
4926 RunTransactionTest(cache
.http_cache(), transaction
);
4927 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4928 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4929 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4931 RemoveMockTransaction(&transaction
);
4932 AddMockTransaction(&kRangeGET_TransactionOK
);
4934 // Now see that we use the stored entry.
4935 std::string headers
;
4936 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4937 RangeTransactionServer handler
;
4938 handler
.set_not_modified(true);
4939 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4941 // We are expecting a 206.
4942 Verify206Response(headers
, 40, 49);
4943 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4944 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4945 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4947 // The last transaction has finished so make sure the entry is deactivated.
4948 base::MessageLoop::current()->RunUntilIdle();
4950 // Make a request for an invalid range.
4951 MockTransaction
transaction3(kRangeGET_TransactionOK
);
4952 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
4953 transaction3
.data
= transaction
.data
;
4954 transaction3
.load_flags
= LOAD_PREFERRING_CACHE
;
4955 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
4956 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4957 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
4958 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
4959 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
4961 // Make sure the entry is deactivated.
4962 base::MessageLoop::current()->RunUntilIdle();
4964 // Even though the request was invalid, we should have the entry.
4965 RunTransactionTest(cache
.http_cache(), transaction2
);
4966 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4968 // Make sure the entry is deactivated.
4969 base::MessageLoop::current()->RunUntilIdle();
4971 // Now we should receive a range from the server and drop the stored entry.
4972 handler
.set_not_modified(false);
4973 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4974 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4975 Verify206Response(headers
, 40, 49);
4976 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4977 EXPECT_EQ(4, cache
.disk_cache()->open_count());
4978 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4980 RunTransactionTest(cache
.http_cache(), transaction2
);
4981 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4983 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4986 // Tests that we can handle a 200 response when dealing with sparse entries.
4987 TEST(HttpCache
, RangeRequestResultsIn200
) {
4988 MockHttpCache cache
;
4989 AddMockTransaction(&kRangeGET_TransactionOK
);
4990 std::string headers
;
4992 // Write to the cache (70-79).
4993 MockTransaction
transaction(kRangeGET_TransactionOK
);
4994 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4995 transaction
.data
= "rg: 70-79 ";
4996 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4998 Verify206Response(headers
, 70, 79);
4999 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5000 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5001 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5003 // Now we'll issue a request that results in a plain 200 response, but to
5004 // the to the same URL that we used to store sparse data, and making sure
5005 // that we ask for a range.
5006 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5007 MockTransaction
transaction2(kSimpleGET_Transaction
);
5008 transaction2
.url
= kRangeGET_TransactionOK
.url
;
5009 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5010 AddMockTransaction(&transaction2
);
5012 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5014 std::string
expected_headers(kSimpleGET_Transaction
.status
);
5015 expected_headers
.append("\n");
5016 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
5017 EXPECT_EQ(expected_headers
, headers
);
5018 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5019 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5020 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5022 RemoveMockTransaction(&transaction2
);
5025 // Tests that a range request that falls outside of the size that we know about
5026 // only deletes the entry if the resource has indeed changed.
5027 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
5028 MockHttpCache cache
;
5029 AddMockTransaction(&kRangeGET_TransactionOK
);
5030 std::string headers
;
5032 // Write to the cache (40-49).
5033 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5036 Verify206Response(headers
, 40, 49);
5037 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5038 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5039 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5041 // A weird request should not delete this entry. Ask for bytes 120-.
5042 MockTransaction
transaction(kRangeGET_TransactionOK
);
5043 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
5044 transaction
.data
= "";
5045 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5047 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
5048 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5049 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5050 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5052 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5053 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5054 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5056 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5059 // Tests that we don't delete a sparse entry when we cancel a request.
5060 TEST(HttpCache
, RangeGET_Cancel
) {
5061 MockHttpCache cache
;
5062 AddMockTransaction(&kRangeGET_TransactionOK
);
5064 MockHttpRequest
request(kRangeGET_TransactionOK
);
5066 Context
* c
= new Context();
5067 int rv
= cache
.CreateTransaction(&c
->trans
);
5070 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5071 if (rv
== ERR_IO_PENDING
)
5072 rv
= c
->callback
.WaitForResult();
5074 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5075 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5076 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5078 // Make sure that the entry has some data stored.
5079 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5080 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5081 if (rv
== ERR_IO_PENDING
)
5082 rv
= c
->callback
.WaitForResult();
5083 EXPECT_EQ(buf
->size(), rv
);
5085 // Destroy the transaction.
5088 // Verify that the entry has not been deleted.
5089 disk_cache::Entry
* entry
;
5090 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5092 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5095 // Tests that we don't delete a sparse entry when we start a new request after
5096 // cancelling the previous one.
5097 TEST(HttpCache
, RangeGET_Cancel2
) {
5098 MockHttpCache cache
;
5099 AddMockTransaction(&kRangeGET_TransactionOK
);
5101 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5102 MockHttpRequest
request(kRangeGET_TransactionOK
);
5103 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5105 Context
* c
= new Context();
5106 int rv
= cache
.CreateTransaction(&c
->trans
);
5109 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5110 if (rv
== ERR_IO_PENDING
)
5111 rv
= c
->callback
.WaitForResult();
5113 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5114 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5115 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5117 // Make sure that we revalidate the entry and read from the cache (a single
5118 // read will return while waiting for the network).
5119 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5120 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5121 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5122 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5123 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5125 // Destroy the transaction before completing the read.
5128 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5129 // message loop. This means that a new transaction will just reuse the same
5130 // active entry (no open or create).
5132 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5134 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5135 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5136 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5137 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5140 // A slight variation of the previous test, this time we cancel two requests in
5141 // a row, making sure that the second is waiting for the entry to be ready.
5142 TEST(HttpCache
, RangeGET_Cancel3
) {
5143 MockHttpCache cache
;
5144 AddMockTransaction(&kRangeGET_TransactionOK
);
5146 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5147 MockHttpRequest
request(kRangeGET_TransactionOK
);
5148 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5150 Context
* c
= new Context();
5151 int rv
= cache
.CreateTransaction(&c
->trans
);
5154 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5155 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5156 rv
= c
->callback
.WaitForResult();
5158 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5159 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5160 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5162 // Make sure that we revalidate the entry and read from the cache (a single
5163 // read will return while waiting for the network).
5164 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5165 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5166 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5167 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5168 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5170 // Destroy the transaction before completing the read.
5173 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5174 // message loop. This means that a new transaction will just reuse the same
5175 // active entry (no open or create).
5178 rv
= cache
.CreateTransaction(&c
->trans
);
5181 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5182 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5184 MockDiskEntry::IgnoreCallbacks(true);
5185 base::MessageLoop::current()->RunUntilIdle();
5186 MockDiskEntry::IgnoreCallbacks(false);
5188 // The new transaction is waiting for the query range callback.
5191 // And we should not crash when the callback is delivered.
5192 base::MessageLoop::current()->RunUntilIdle();
5194 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5195 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5196 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5197 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5200 // Tests that an invalid range response results in no cached entry.
5201 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
5202 MockHttpCache cache
;
5203 std::string headers
;
5205 MockTransaction
transaction(kRangeGET_TransactionOK
);
5206 transaction
.handler
= NULL
;
5207 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
5208 "Content-Length: 10\n";
5209 AddMockTransaction(&transaction
);
5210 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5212 std::string
expected(transaction
.status
);
5213 expected
.append("\n");
5214 expected
.append(transaction
.response_headers
);
5215 EXPECT_EQ(expected
, headers
);
5217 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5218 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5219 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5221 // Verify that we don't have a cached entry.
5222 disk_cache::Entry
* entry
;
5223 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5225 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5228 // Tests that we reject a range that doesn't match the content-length.
5229 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
5230 MockHttpCache cache
;
5231 std::string headers
;
5233 MockTransaction
transaction(kRangeGET_TransactionOK
);
5234 transaction
.handler
= NULL
;
5235 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
5236 "Content-Length: 20\n";
5237 AddMockTransaction(&transaction
);
5238 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5240 std::string
expected(transaction
.status
);
5241 expected
.append("\n");
5242 expected
.append(transaction
.response_headers
);
5243 EXPECT_EQ(expected
, headers
);
5245 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5246 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5247 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5249 // Verify that we don't have a cached entry.
5250 disk_cache::Entry
* entry
;
5251 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5253 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5256 // Tests that if a server tells us conflicting information about a resource we
5258 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
5259 MockHttpCache cache
;
5260 std::string headers
;
5262 MockTransaction
transaction(kRangeGET_TransactionOK
);
5263 transaction
.handler
= NULL
;
5264 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
5265 std::string
response_headers(transaction
.response_headers
);
5266 response_headers
.append("Content-Range: bytes 50-59/160\n");
5267 transaction
.response_headers
= response_headers
.c_str();
5268 AddMockTransaction(&transaction
);
5269 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5271 Verify206Response(headers
, 50, 59);
5272 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5273 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5274 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5276 RemoveMockTransaction(&transaction
);
5277 AddMockTransaction(&kRangeGET_TransactionOK
);
5279 // This transaction will report a resource size of 80 bytes, and we think it's
5280 // 160 so we should ignore the response.
5281 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5284 Verify206Response(headers
, 40, 49);
5285 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5286 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5287 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5289 // Verify that the entry is gone.
5290 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5291 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5292 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5293 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5296 // Tests that we handle large range values properly.
5297 TEST(HttpCache
, RangeGET_LargeValues
) {
5298 // We need a real sparse cache for this test.
5299 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5300 std::string headers
;
5302 MockTransaction
transaction(kRangeGET_TransactionOK
);
5303 transaction
.handler
= NULL
;
5304 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
5306 transaction
.response_headers
=
5308 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5309 "Content-Length: 10\n";
5310 AddMockTransaction(&transaction
);
5311 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5313 std::string
expected(transaction
.status
);
5314 expected
.append("\n");
5315 expected
.append(transaction
.response_headers
);
5316 EXPECT_EQ(expected
, headers
);
5318 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5320 // Verify that we have a cached entry.
5321 disk_cache::Entry
* en
;
5322 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
5325 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5328 // Tests that we don't crash with a range request if the disk cache was not
5329 // initialized properly.
5330 TEST(HttpCache
, RangeGET_NoDiskCache
) {
5331 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
5332 factory
->set_fail(true);
5333 factory
->FinishCreation(); // We'll complete synchronously.
5334 MockHttpCache
cache(factory
);
5336 AddMockTransaction(&kRangeGET_TransactionOK
);
5338 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5339 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5341 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5344 // Tests that we handle byte range requests that skip the cache.
5345 TEST(HttpCache
, RangeHEAD
) {
5346 MockHttpCache cache
;
5347 AddMockTransaction(&kRangeGET_TransactionOK
);
5349 MockTransaction
transaction(kRangeGET_TransactionOK
);
5350 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5351 transaction
.method
= "HEAD";
5352 transaction
.data
= "rg: 70-79 ";
5354 std::string headers
;
5355 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5357 Verify206Response(headers
, 70, 79);
5358 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5359 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5360 EXPECT_EQ(0, cache
.disk_cache()->create_count());
5362 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5365 // Tests that we don't crash when after reading from the cache we issue a
5366 // request for the next range and the server gives us a 200 synchronously.
5367 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
5368 MockHttpCache cache
;
5370 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5371 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
5372 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
5373 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
5375 // Write to the cache.
5376 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5378 // And now read from the cache and the network.
5379 RangeTransactionServer handler
;
5380 handler
.set_bad_200(true);
5381 transaction
.data
= "Not a range";
5382 BoundTestNetLog log
;
5383 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
5385 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
5386 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5387 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5388 EXPECT_TRUE(LogContainsEventType(
5389 log
, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST
));
5392 // Tests that when the server gives us less data than expected, we don't keep
5393 // asking for more data.
5394 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
5395 MockHttpCache cache
;
5397 // First, check with an empty cache (WRITE mode).
5398 MockTransaction
transaction(kRangeGET_TransactionOK
);
5399 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
5400 transaction
.data
= "rg: 40-"; // Less than expected.
5401 transaction
.handler
= NULL
;
5402 std::string
headers(transaction
.response_headers
);
5403 headers
.append("Content-Range: bytes 40-49/80\n");
5404 transaction
.response_headers
= headers
.c_str();
5406 AddMockTransaction(&transaction
);
5408 // Write to the cache.
5409 RunTransactionTest(cache
.http_cache(), transaction
);
5411 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5412 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5413 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5415 // Now verify that even in READ_WRITE mode, we forward the bad response to
5417 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5418 transaction
.data
= "rg: 60-"; // Less than expected.
5419 headers
= kRangeGET_TransactionOK
.response_headers
;
5420 headers
.append("Content-Range: bytes 60-69/80\n");
5421 transaction
.response_headers
= headers
.c_str();
5423 RunTransactionTest(cache
.http_cache(), transaction
);
5425 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5426 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5427 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5429 RemoveMockTransaction(&transaction
);
5432 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5433 // This test hits a NOTREACHED so it is a release mode only test.
5434 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5435 MockHttpCache cache
;
5436 AddMockTransaction(&kRangeGET_TransactionOK
);
5438 // Write to the cache (40-49).
5439 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5440 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5441 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5442 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5444 // Force this transaction to read from the cache.
5445 MockTransaction
transaction(kRangeGET_TransactionOK
);
5446 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
5448 MockHttpRequest
request(transaction
);
5449 TestCompletionCallback callback
;
5451 scoped_ptr
<HttpTransaction
> trans
;
5452 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
5454 ASSERT_TRUE(trans
.get());
5456 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
5457 if (rv
== ERR_IO_PENDING
)
5458 rv
= callback
.WaitForResult();
5459 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
5463 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5464 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5465 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5467 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5471 // Tests the handling of the "truncation" flag.
5472 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5473 MockHttpCache cache
;
5474 disk_cache::Entry
* entry
;
5475 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5478 std::string
headers("HTTP/1.1 200 OK");
5479 headers
= HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5480 HttpResponseInfo response
;
5481 response
.headers
= new HttpResponseHeaders(headers
);
5483 // Set the last argument for this to be an incomplete request.
5484 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5485 bool truncated
= false;
5486 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5487 EXPECT_TRUE(truncated
);
5489 // And now test the opposite case.
5490 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5492 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5493 EXPECT_FALSE(truncated
);
5497 // Tests basic pickling/unpickling of HttpResponseInfo.
5498 TEST(HttpCache
, PersistHttpResponseInfo
) {
5499 // Set some fields (add more if needed.)
5500 HttpResponseInfo response1
;
5501 response1
.was_cached
= false;
5502 response1
.socket_address
= HostPortPair("1.2.3.4", 80);
5503 response1
.headers
= new HttpResponseHeaders("HTTP/1.1 200 OK");
5506 base::Pickle pickle
;
5507 response1
.Persist(&pickle
, false, false);
5510 HttpResponseInfo response2
;
5511 bool response_truncated
;
5512 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5513 EXPECT_FALSE(response_truncated
);
5516 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5517 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5518 EXPECT_EQ(80, response2
.socket_address
.port());
5519 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5522 // Tests that we delete an entry when the request is cancelled before starting
5523 // to read from the network.
5524 TEST(HttpCache
, DoomOnDestruction
) {
5525 MockHttpCache cache
;
5527 MockHttpRequest
request(kSimpleGET_Transaction
);
5529 Context
* c
= new Context();
5530 int rv
= cache
.CreateTransaction(&c
->trans
);
5533 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5534 if (rv
== ERR_IO_PENDING
)
5535 c
->result
= c
->callback
.WaitForResult();
5537 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5538 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5539 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5541 // Destroy the transaction. We only have the headers so we should delete this
5545 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5547 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5548 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5549 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5552 // Tests that we delete an entry when the request is cancelled if the response
5553 // does not have content-length and strong validators.
5554 TEST(HttpCache
, DoomOnDestruction2
) {
5555 MockHttpCache cache
;
5557 MockHttpRequest
request(kSimpleGET_Transaction
);
5559 Context
* c
= new Context();
5560 int rv
= cache
.CreateTransaction(&c
->trans
);
5563 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5564 if (rv
== ERR_IO_PENDING
)
5565 rv
= c
->callback
.WaitForResult();
5567 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5568 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5569 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5571 // Make sure that the entry has some data stored.
5572 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5573 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5574 if (rv
== ERR_IO_PENDING
)
5575 rv
= c
->callback
.WaitForResult();
5576 EXPECT_EQ(buf
->size(), rv
);
5578 // Destroy the transaction.
5581 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5583 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5584 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5585 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5588 // Tests that we delete an entry when the request is cancelled if the response
5589 // has an "Accept-Ranges: none" header.
5590 TEST(HttpCache
, DoomOnDestruction3
) {
5591 MockHttpCache cache
;
5593 MockTransaction
transaction(kSimpleGET_Transaction
);
5594 transaction
.response_headers
=
5595 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5596 "Content-Length: 22\n"
5597 "Accept-Ranges: none\n"
5598 "Etag: \"foopy\"\n";
5599 AddMockTransaction(&transaction
);
5600 MockHttpRequest
request(transaction
);
5602 Context
* c
= new Context();
5603 int rv
= cache
.CreateTransaction(&c
->trans
);
5606 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5607 if (rv
== ERR_IO_PENDING
)
5608 rv
= c
->callback
.WaitForResult();
5610 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5611 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5612 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5614 // Make sure that the entry has some data stored.
5615 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5616 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5617 if (rv
== ERR_IO_PENDING
)
5618 rv
= c
->callback
.WaitForResult();
5619 EXPECT_EQ(buf
->size(), rv
);
5621 // Destroy the transaction.
5624 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5626 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5627 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5628 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5630 RemoveMockTransaction(&transaction
);
5633 // Tests that we mark an entry as incomplete when the request is cancelled.
5634 TEST(HttpCache
, SetTruncatedFlag
) {
5635 MockHttpCache cache
;
5637 MockTransaction
transaction(kSimpleGET_Transaction
);
5638 transaction
.response_headers
=
5639 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5640 "Content-Length: 22\n"
5641 "Etag: \"foopy\"\n";
5642 AddMockTransaction(&transaction
);
5643 MockHttpRequest
request(transaction
);
5645 scoped_ptr
<Context
> c(new Context());
5647 int rv
= cache
.CreateTransaction(&c
->trans
);
5650 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5651 if (rv
== ERR_IO_PENDING
)
5652 rv
= c
->callback
.WaitForResult();
5654 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5655 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5656 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5658 // Make sure that the entry has some data stored.
5659 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5660 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5661 if (rv
== ERR_IO_PENDING
)
5662 rv
= c
->callback
.WaitForResult();
5663 EXPECT_EQ(buf
->size(), rv
);
5665 // We want to cancel the request when the transaction is busy.
5666 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5667 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5668 EXPECT_FALSE(c
->callback
.have_result());
5670 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5672 // Destroy the transaction.
5674 MockHttpCache::SetTestMode(0);
5677 // Make sure that we don't invoke the callback. We may have an issue if the
5678 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5679 // could end up with the transaction being deleted twice if we send any
5680 // notification from the transaction destructor (see http://crbug.com/31723).
5681 EXPECT_FALSE(c
->callback
.have_result());
5683 // Verify that the entry is marked as incomplete.
5684 disk_cache::Entry
* entry
;
5685 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5686 HttpResponseInfo response
;
5687 bool truncated
= false;
5688 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5689 EXPECT_TRUE(truncated
);
5692 RemoveMockTransaction(&transaction
);
5695 // Tests that we don't mark an entry as truncated when we read everything.
5696 TEST(HttpCache
, DontSetTruncatedFlag
) {
5697 MockHttpCache cache
;
5699 MockTransaction
transaction(kSimpleGET_Transaction
);
5700 transaction
.response_headers
=
5701 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5702 "Content-Length: 22\n"
5703 "Etag: \"foopy\"\n";
5704 AddMockTransaction(&transaction
);
5705 MockHttpRequest
request(transaction
);
5707 scoped_ptr
<Context
> c(new Context());
5708 int rv
= cache
.CreateTransaction(&c
->trans
);
5711 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5712 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5715 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(22));
5716 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5717 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5719 // Destroy the transaction.
5722 // Verify that the entry is not marked as truncated.
5723 disk_cache::Entry
* entry
;
5724 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5725 HttpResponseInfo response
;
5726 bool truncated
= true;
5727 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5728 EXPECT_FALSE(truncated
);
5731 RemoveMockTransaction(&transaction
);
5734 // Tests that we can continue with a request that was interrupted.
5735 TEST(HttpCache
, GET_IncompleteResource
) {
5736 MockHttpCache cache
;
5737 AddMockTransaction(&kRangeGET_TransactionOK
);
5739 std::string
raw_headers("HTTP/1.1 200 OK\n"
5740 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5742 "Accept-Ranges: bytes\n"
5743 "Content-Length: 80\n");
5744 CreateTruncatedEntry(raw_headers
, &cache
);
5746 // Now make a regular request.
5747 std::string headers
;
5748 MockTransaction
transaction(kRangeGET_TransactionOK
);
5749 transaction
.request_headers
= EXTRA_HEADER
;
5750 transaction
.data
= kFullRangeData
;
5751 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5753 // We update the headers with the ones received while revalidating.
5754 std::string
expected_headers(
5756 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5757 "Accept-Ranges: bytes\n"
5759 "Content-Length: 80\n");
5761 EXPECT_EQ(expected_headers
, headers
);
5762 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5763 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5764 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5766 // Verify that the disk entry was updated.
5767 disk_cache::Entry
* entry
;
5768 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5769 EXPECT_EQ(80, entry
->GetDataSize(1));
5770 bool truncated
= true;
5771 HttpResponseInfo response
;
5772 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5773 EXPECT_FALSE(truncated
);
5776 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5779 // Tests the handling of no-store when revalidating a truncated entry.
5780 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5781 MockHttpCache cache
;
5782 AddMockTransaction(&kRangeGET_TransactionOK
);
5784 std::string
raw_headers("HTTP/1.1 200 OK\n"
5785 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5787 "Accept-Ranges: bytes\n"
5788 "Content-Length: 80\n");
5789 CreateTruncatedEntry(raw_headers
, &cache
);
5790 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5792 // Now make a regular request.
5793 MockTransaction
transaction(kRangeGET_TransactionOK
);
5794 transaction
.request_headers
= EXTRA_HEADER
;
5795 std::string
response_headers(transaction
.response_headers
);
5796 response_headers
+= ("Cache-Control: no-store\n");
5797 transaction
.response_headers
= response_headers
.c_str();
5798 transaction
.data
= kFullRangeData
;
5799 AddMockTransaction(&transaction
);
5801 std::string headers
;
5802 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5804 // We update the headers with the ones received while revalidating.
5805 std::string
expected_headers(
5807 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5808 "Accept-Ranges: bytes\n"
5809 "Cache-Control: no-store\n"
5811 "Content-Length: 80\n");
5813 EXPECT_EQ(expected_headers
, headers
);
5814 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5815 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5816 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5818 // Verify that the disk entry was deleted.
5819 disk_cache::Entry
* entry
;
5820 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5821 RemoveMockTransaction(&transaction
);
5824 // Tests cancelling a request after the server sent no-store.
5825 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5826 MockHttpCache cache
;
5827 AddMockTransaction(&kRangeGET_TransactionOK
);
5829 std::string
raw_headers("HTTP/1.1 200 OK\n"
5830 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5832 "Accept-Ranges: bytes\n"
5833 "Content-Length: 80\n");
5834 CreateTruncatedEntry(raw_headers
, &cache
);
5835 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5837 // Now make a regular request.
5838 MockTransaction
transaction(kRangeGET_TransactionOK
);
5839 transaction
.request_headers
= EXTRA_HEADER
;
5840 std::string
response_headers(transaction
.response_headers
);
5841 response_headers
+= ("Cache-Control: no-store\n");
5842 transaction
.response_headers
= response_headers
.c_str();
5843 transaction
.data
= kFullRangeData
;
5844 AddMockTransaction(&transaction
);
5846 MockHttpRequest
request(transaction
);
5847 Context
* c
= new Context();
5849 int rv
= cache
.CreateTransaction(&c
->trans
);
5852 // Queue another request to this transaction. We have to start this request
5853 // before the first one gets the response from the server and dooms the entry,
5854 // otherwise it will just create a new entry without being queued to the first
5856 Context
* pending
= new Context();
5857 ASSERT_EQ(OK
, cache
.CreateTransaction(&pending
->trans
));
5859 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5860 EXPECT_EQ(ERR_IO_PENDING
,
5861 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5863 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5865 // Make sure that the entry has some data stored.
5866 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5867 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5868 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5870 // Cancel the requests.
5874 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5875 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5876 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5878 base::MessageLoop::current()->RunUntilIdle();
5879 RemoveMockTransaction(&transaction
);
5882 // Tests that we delete truncated entries if the server changes its mind midway.
5883 TEST(HttpCache
, GET_IncompleteResource2
) {
5884 MockHttpCache cache
;
5885 AddMockTransaction(&kRangeGET_TransactionOK
);
5887 // Content-length will be intentionally bad.
5888 std::string
raw_headers("HTTP/1.1 200 OK\n"
5889 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5891 "Accept-Ranges: bytes\n"
5892 "Content-Length: 50\n");
5893 CreateTruncatedEntry(raw_headers
, &cache
);
5895 // Now make a regular request. We expect the code to fail the validation and
5896 // retry the request without using byte ranges.
5897 std::string headers
;
5898 MockTransaction
transaction(kRangeGET_TransactionOK
);
5899 transaction
.request_headers
= EXTRA_HEADER
;
5900 transaction
.data
= "Not a range";
5901 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5903 // The server will return 200 instead of a byte range.
5904 std::string
expected_headers(
5906 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5908 EXPECT_EQ(expected_headers
, headers
);
5909 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5910 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5911 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5913 // Verify that the disk entry was deleted.
5914 disk_cache::Entry
* entry
;
5915 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5916 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5919 // Tests that we always validate a truncated request.
5920 TEST(HttpCache
, GET_IncompleteResource3
) {
5921 MockHttpCache cache
;
5922 AddMockTransaction(&kRangeGET_TransactionOK
);
5924 // This should not require validation for 10 hours.
5925 std::string
raw_headers("HTTP/1.1 200 OK\n"
5926 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5928 "Cache-Control: max-age= 36000\n"
5929 "Accept-Ranges: bytes\n"
5930 "Content-Length: 80\n");
5931 CreateTruncatedEntry(raw_headers
, &cache
);
5933 // Now make a regular request.
5934 std::string headers
;
5935 MockTransaction
transaction(kRangeGET_TransactionOK
);
5936 transaction
.request_headers
= EXTRA_HEADER
;
5937 transaction
.data
= kFullRangeData
;
5939 scoped_ptr
<Context
> c(new Context
);
5940 int rv
= cache
.CreateTransaction(&c
->trans
);
5943 MockHttpRequest
request(transaction
);
5944 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5945 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5947 // We should have checked with the server before finishing Start().
5948 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5949 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5950 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5952 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5955 // Tests that we handle 401s for truncated resources.
5956 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
5957 MockHttpCache cache
;
5958 AddMockTransaction(&kRangeGET_TransactionOK
);
5960 std::string
raw_headers("HTTP/1.1 200 OK\n"
5961 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5963 "Accept-Ranges: bytes\n"
5964 "Content-Length: 80\n");
5965 CreateTruncatedEntry(raw_headers
, &cache
);
5967 // Now make a regular request.
5968 MockTransaction
transaction(kRangeGET_TransactionOK
);
5969 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
5971 transaction
.data
= kFullRangeData
;
5972 RangeTransactionServer handler
;
5974 scoped_ptr
<Context
> c(new Context
);
5975 int rv
= cache
.CreateTransaction(&c
->trans
);
5978 MockHttpRequest
request(transaction
);
5979 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5980 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5982 const HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
5983 ASSERT_TRUE(response
);
5984 ASSERT_EQ(401, response
->headers
->response_code());
5985 rv
= c
->trans
->RestartWithAuth(AuthCredentials(), c
->callback
.callback());
5986 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5987 response
= c
->trans
->GetResponseInfo();
5988 ASSERT_TRUE(response
);
5989 ASSERT_EQ(200, response
->headers
->response_code());
5991 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
5992 c
.reset(); // The destructor could delete the entry.
5993 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5995 // Verify that the entry was not deleted.
5996 disk_cache::Entry
* entry
;
5997 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6000 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6003 // Test that the transaction won't retry failed partial requests
6004 // after it starts reading data. http://crbug.com/474835
6005 TEST(HttpCache
, TransactionRetryLimit
) {
6006 MockHttpCache cache
;
6008 // Cache 0-9, so that we have data to read before failing.
6009 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
6010 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
6011 transaction
.data
= "rg: 00-09 ";
6013 // Write to the cache.
6014 RunTransactionTest(cache
.http_cache(), transaction
);
6015 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6017 // And now read from the cache and the network. 10-19 will get a
6018 // 401, but will have already returned 0-9.
6019 // We do not set X-Require-Mock-Auth because that causes the mock
6020 // network transaction to become IsReadyToRestartForAuth().
6021 transaction
.request_headers
=
6022 "Range: bytes = 0-79\r\n"
6023 "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER
;
6025 scoped_ptr
<Context
> c(new Context
);
6026 int rv
= cache
.CreateTransaction(&c
->trans
);
6029 MockHttpRequest
request(transaction
);
6031 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6032 if (rv
== ERR_IO_PENDING
)
6033 rv
= c
->callback
.WaitForResult();
6034 std::string content
;
6035 rv
= ReadTransaction(c
->trans
.get(), &content
);
6036 EXPECT_EQ(ERR_CACHE_AUTH_FAILURE_AFTER_READ
, rv
);
6039 // Tests that we cache a 200 response to the validation request.
6040 TEST(HttpCache
, GET_IncompleteResource4
) {
6041 MockHttpCache cache
;
6042 AddMockTransaction(&kRangeGET_TransactionOK
);
6044 std::string
raw_headers("HTTP/1.1 200 OK\n"
6045 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6047 "Accept-Ranges: bytes\n"
6048 "Content-Length: 80\n");
6049 CreateTruncatedEntry(raw_headers
, &cache
);
6051 // Now make a regular request.
6052 std::string headers
;
6053 MockTransaction
transaction(kRangeGET_TransactionOK
);
6054 transaction
.request_headers
= EXTRA_HEADER
;
6055 transaction
.data
= "Not a range";
6056 RangeTransactionServer handler
;
6057 handler
.set_bad_200(true);
6058 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
6060 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6061 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6062 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6064 // Verify that the disk entry was updated.
6065 disk_cache::Entry
* entry
;
6066 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6067 EXPECT_EQ(11, entry
->GetDataSize(1));
6068 bool truncated
= true;
6069 HttpResponseInfo response
;
6070 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6071 EXPECT_FALSE(truncated
);
6074 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6077 // Tests that when we cancel a request that was interrupted, we mark it again
6079 TEST(HttpCache
, GET_CancelIncompleteResource
) {
6080 MockHttpCache cache
;
6081 AddMockTransaction(&kRangeGET_TransactionOK
);
6083 std::string
raw_headers("HTTP/1.1 200 OK\n"
6084 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6086 "Accept-Ranges: bytes\n"
6087 "Content-Length: 80\n");
6088 CreateTruncatedEntry(raw_headers
, &cache
);
6090 // Now make a regular request.
6091 MockTransaction
transaction(kRangeGET_TransactionOK
);
6092 transaction
.request_headers
= EXTRA_HEADER
;
6094 MockHttpRequest
request(transaction
);
6095 Context
* c
= new Context();
6096 int rv
= cache
.CreateTransaction(&c
->trans
);
6099 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6100 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6102 // Read 20 bytes from the cache, and 10 from the net.
6103 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
6104 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
6105 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
6106 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
6107 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
6109 // At this point, we are already reading so canceling the request should leave
6113 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6114 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6115 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6117 // Verify that the disk entry was updated: now we have 30 bytes.
6118 disk_cache::Entry
* entry
;
6119 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6120 EXPECT_EQ(30, entry
->GetDataSize(1));
6121 bool truncated
= false;
6122 HttpResponseInfo response
;
6123 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6124 EXPECT_TRUE(truncated
);
6126 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6129 // Tests that we can handle range requests when we have a truncated entry.
6130 TEST(HttpCache
, RangeGET_IncompleteResource
) {
6131 MockHttpCache cache
;
6132 AddMockTransaction(&kRangeGET_TransactionOK
);
6134 // Content-length will be intentionally bogus.
6135 std::string
raw_headers("HTTP/1.1 200 OK\n"
6136 "Last-Modified: something\n"
6138 "Accept-Ranges: bytes\n"
6139 "Content-Length: 10\n");
6140 CreateTruncatedEntry(raw_headers
, &cache
);
6142 // Now make a range request.
6143 std::string headers
;
6144 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
6147 Verify206Response(headers
, 40, 49);
6148 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6149 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6150 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6152 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6155 TEST(HttpCache
, SyncRead
) {
6156 MockHttpCache cache
;
6158 // This test ensures that a read that completes synchronously does not cause
6161 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6162 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
6163 TEST_MODE_SYNC_CACHE_READ
|
6164 TEST_MODE_SYNC_CACHE_WRITE
);
6166 MockHttpRequest
r1(transaction
),
6170 TestTransactionConsumer
c1(DEFAULT_PRIORITY
, cache
.http_cache()),
6171 c2(DEFAULT_PRIORITY
, cache
.http_cache()),
6172 c3(DEFAULT_PRIORITY
, cache
.http_cache());
6174 c1
.Start(&r1
, BoundNetLog());
6176 r2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6177 c2
.Start(&r2
, BoundNetLog());
6179 r3
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6180 c3
.Start(&r3
, BoundNetLog());
6182 base::MessageLoop::current()->Run();
6184 EXPECT_TRUE(c1
.is_done());
6185 EXPECT_TRUE(c2
.is_done());
6186 EXPECT_TRUE(c3
.is_done());
6188 EXPECT_EQ(OK
, c1
.error());
6189 EXPECT_EQ(OK
, c2
.error());
6190 EXPECT_EQ(OK
, c3
.error());
6193 TEST(HttpCache
, ValidationResultsIn200
) {
6194 MockHttpCache cache
;
6196 // This test ensures that a conditional request, which results in a 200
6197 // instead of a 304, properly truncates the existing response data.
6199 // write to the cache
6200 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6202 // force this transaction to validate the cache
6203 MockTransaction
transaction(kETagGET_Transaction
);
6204 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
6205 RunTransactionTest(cache
.http_cache(), transaction
);
6207 // read from the cache
6208 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6211 TEST(HttpCache
, CachedRedirect
) {
6212 MockHttpCache cache
;
6214 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
6215 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
6216 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
6218 MockHttpRequest
request(kTestTransaction
);
6219 TestCompletionCallback callback
;
6221 // Write to the cache.
6223 scoped_ptr
<HttpTransaction
> trans
;
6224 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6226 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6227 if (rv
== ERR_IO_PENDING
)
6228 rv
= callback
.WaitForResult();
6231 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6234 EXPECT_EQ(info
->headers
->response_code(), 301);
6236 std::string location
;
6237 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6238 EXPECT_EQ(location
, "http://www.bar.com/");
6240 // Mark the transaction as completed so it is cached.
6241 trans
->DoneReading();
6243 // Destroy transaction when going out of scope. We have not actually
6244 // read the response body -- want to test that it is still getting cached.
6246 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6247 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6248 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6250 // Active entries in the cache are not retired synchronously. Make
6251 // sure the next run hits the MockHttpCache and open_count is
6253 base::MessageLoop::current()->RunUntilIdle();
6255 // Read from the cache.
6257 scoped_ptr
<HttpTransaction
> trans
;
6258 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6260 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6261 if (rv
== ERR_IO_PENDING
)
6262 rv
= callback
.WaitForResult();
6265 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6268 EXPECT_EQ(info
->headers
->response_code(), 301);
6270 std::string location
;
6271 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6272 EXPECT_EQ(location
, "http://www.bar.com/");
6274 // Mark the transaction as completed so it is cached.
6275 trans
->DoneReading();
6277 // Destroy transaction when going out of scope. We have not actually
6278 // read the response body -- want to test that it is still getting cached.
6280 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6281 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6282 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6285 // Verify that no-cache resources are stored in cache, but are not fetched from
6286 // cache during normal loads.
6287 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
6288 MockHttpCache cache
;
6290 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6291 transaction
.response_headers
= "cache-control: no-cache\n";
6294 RunTransactionTest(cache
.http_cache(), transaction
);
6296 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6297 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6298 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6300 // Try loading again; it should result in a network fetch.
6301 RunTransactionTest(cache
.http_cache(), transaction
);
6303 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6304 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6305 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6307 disk_cache::Entry
* entry
;
6308 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6312 // Verify that no-cache resources are stored in cache and fetched from cache
6313 // when the LOAD_PREFERRING_CACHE flag is set.
6314 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
6315 MockHttpCache cache
;
6317 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6318 transaction
.response_headers
= "cache-control: no-cache\n";
6321 RunTransactionTest(cache
.http_cache(), transaction
);
6323 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6324 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6325 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6327 // Try loading again with LOAD_PREFERRING_CACHE.
6328 transaction
.load_flags
= LOAD_PREFERRING_CACHE
;
6329 RunTransactionTest(cache
.http_cache(), transaction
);
6331 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6332 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6333 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6335 disk_cache::Entry
* entry
;
6336 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6340 TEST(HttpCache
, CacheControlNoStore
) {
6341 MockHttpCache cache
;
6343 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6344 transaction
.response_headers
= "cache-control: no-store\n";
6347 RunTransactionTest(cache
.http_cache(), transaction
);
6349 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6350 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6351 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6353 // try loading again; it should result in a network fetch
6354 RunTransactionTest(cache
.http_cache(), transaction
);
6356 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6357 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6358 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6360 disk_cache::Entry
* entry
;
6361 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6364 TEST(HttpCache
, CacheControlNoStore2
) {
6365 // this test is similar to the above test, except that the initial response
6366 // is cachable, but when it is validated, no-store is received causing the
6367 // cached document to be deleted.
6368 MockHttpCache cache
;
6370 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6373 RunTransactionTest(cache
.http_cache(), transaction
);
6375 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6376 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6377 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6379 // try loading again; it should result in a network fetch
6380 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6381 transaction
.response_headers
= "cache-control: no-store\n";
6382 RunTransactionTest(cache
.http_cache(), transaction
);
6384 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6385 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6386 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6388 disk_cache::Entry
* entry
;
6389 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6392 TEST(HttpCache
, CacheControlNoStore3
) {
6393 // this test is similar to the above test, except that the response is a 304
6394 // instead of a 200. this should never happen in practice, but it seems like
6395 // a good thing to verify that we still destroy the cache entry.
6396 MockHttpCache cache
;
6398 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6401 RunTransactionTest(cache
.http_cache(), transaction
);
6403 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6404 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6405 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6407 // try loading again; it should result in a network fetch
6408 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6409 transaction
.response_headers
= "cache-control: no-store\n";
6410 transaction
.status
= "HTTP/1.1 304 Not Modified";
6411 RunTransactionTest(cache
.http_cache(), transaction
);
6413 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6414 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6415 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6417 disk_cache::Entry
* entry
;
6418 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6421 // Ensure that we don't cache requests served over bad HTTPS.
6422 TEST(HttpCache
, SimpleGET_SSLError
) {
6423 MockHttpCache cache
;
6425 MockTransaction transaction
= kSimpleGET_Transaction
;
6426 transaction
.cert_status
= CERT_STATUS_REVOKED
;
6427 ScopedMockTransaction
scoped_transaction(transaction
);
6429 // write to the cache
6430 RunTransactionTest(cache
.http_cache(), transaction
);
6432 // Test that it was not cached.
6433 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6435 MockHttpRequest
request(transaction
);
6436 TestCompletionCallback callback
;
6438 scoped_ptr
<HttpTransaction
> trans
;
6439 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6441 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6442 if (rv
== ERR_IO_PENDING
)
6443 rv
= callback
.WaitForResult();
6444 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
6447 // Ensure that we don't crash by if left-behind transactions.
6448 TEST(HttpCache
, OutlivedTransactions
) {
6449 MockHttpCache
* cache
= new MockHttpCache
;
6451 scoped_ptr
<HttpTransaction
> trans
;
6452 EXPECT_EQ(OK
, cache
->CreateTransaction(&trans
));
6458 // Test that the disabled mode works.
6459 TEST(HttpCache
, CacheDisabledMode
) {
6460 MockHttpCache cache
;
6462 // write to the cache
6463 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6465 // go into disabled mode
6466 cache
.http_cache()->set_mode(HttpCache::DISABLE
);
6468 // force this transaction to write to the cache again
6469 MockTransaction
transaction(kSimpleGET_Transaction
);
6471 RunTransactionTest(cache
.http_cache(), transaction
);
6473 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6474 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6475 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6478 // Other tests check that the response headers of the cached response
6479 // get updated on 304. Here we specifically check that the
6480 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6481 // fields also gets updated.
6482 // http://crbug.com/20594.
6483 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6484 MockHttpCache cache
;
6486 const char kUrl
[] = "http://foobar";
6487 const char kData
[] = "body";
6489 MockTransaction mock_network_response
= { 0 };
6490 mock_network_response
.url
= kUrl
;
6492 AddMockTransaction(&mock_network_response
);
6494 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6496 MockTransaction request
= { 0 };
6498 request
.method
= "GET";
6499 request
.request_headers
= "\r\n";
6500 request
.data
= kData
;
6502 static const Response kNetResponse1
= {
6504 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6505 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6509 kNetResponse1
.AssignTo(&mock_network_response
);
6511 RunTransactionTest(cache
.http_cache(), request
);
6513 // Request |kUrl| again, this time validating the cache and getting
6516 request
.load_flags
= LOAD_VALIDATE_CACHE
;
6518 static const Response kNetResponse2
= {
6519 "HTTP/1.1 304 Not Modified",
6520 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6524 kNetResponse2
.AssignTo(&mock_network_response
);
6526 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6527 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6529 mock_network_response
.request_time
= request_time
;
6530 mock_network_response
.response_time
= response_time
;
6532 HttpResponseInfo response
;
6533 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6535 // The request and response times should have been updated.
6536 EXPECT_EQ(request_time
.ToInternalValue(),
6537 response
.request_time
.ToInternalValue());
6538 EXPECT_EQ(response_time
.ToInternalValue(),
6539 response
.response_time
.ToInternalValue());
6541 std::string headers
;
6542 response
.headers
->GetNormalizedHeaders(&headers
);
6544 EXPECT_EQ("HTTP/1.1 200 OK\n"
6545 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6546 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6549 RemoveMockTransaction(&mock_network_response
);
6552 // Tests that we can write metadata to an entry.
6553 TEST(HttpCache
, WriteMetadata_OK
) {
6554 MockHttpCache cache
;
6556 // Write to the cache
6557 HttpResponseInfo response
;
6558 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6560 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6563 cache
.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY
, Time::Now(),
6566 // Write meta data to the same entry.
6567 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6568 memset(buf
->data(), 0, buf
->size());
6569 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6570 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6571 DEFAULT_PRIORITY
, response
.response_time
,
6572 buf
.get(), buf
->size());
6574 // Release the buffer before the operation takes place.
6577 // Makes sure we finish pending operations.
6578 base::MessageLoop::current()->RunUntilIdle();
6580 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6582 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6583 EXPECT_EQ(50, response
.metadata
->size());
6584 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6586 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6587 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6588 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6591 // Tests that we only write metadata to an entry if the time stamp matches.
6592 TEST(HttpCache
, WriteMetadata_Fail
) {
6593 MockHttpCache cache
;
6595 // Write to the cache
6596 HttpResponseInfo response
;
6597 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6599 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6601 // Attempt to write meta data to the same entry.
6602 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6603 memset(buf
->data(), 0, buf
->size());
6604 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6605 base::Time expected_time
= response
.response_time
-
6606 base::TimeDelta::FromMilliseconds(20);
6607 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6608 DEFAULT_PRIORITY
, expected_time
, buf
.get(),
6611 // Makes sure we finish pending operations.
6612 base::MessageLoop::current()->RunUntilIdle();
6614 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6616 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6618 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6619 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6620 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6623 // Tests that we can read metadata after validating the entry and with READ mode
6625 TEST(HttpCache
, ReadMetadata
) {
6626 MockHttpCache cache
;
6628 // Write to the cache
6629 HttpResponseInfo response
;
6630 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6631 kTypicalGET_Transaction
, &response
);
6632 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6634 // Write meta data to the same entry.
6635 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6636 memset(buf
->data(), 0, buf
->size());
6637 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6638 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6639 DEFAULT_PRIORITY
, response
.response_time
,
6640 buf
.get(), buf
->size());
6642 // Makes sure we finish pending operations.
6643 base::MessageLoop::current()->RunUntilIdle();
6645 // Start with a READ mode transaction.
6646 MockTransaction
trans1(kTypicalGET_Transaction
);
6647 trans1
.load_flags
= LOAD_ONLY_FROM_CACHE
;
6649 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6650 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6651 EXPECT_EQ(50, response
.metadata
->size());
6652 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6654 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6655 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6656 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6657 base::MessageLoop::current()->RunUntilIdle();
6659 // Now make sure that the entry is re-validated with the server.
6660 trans1
.load_flags
= LOAD_VALIDATE_CACHE
;
6661 trans1
.status
= "HTTP/1.1 304 Not Modified";
6662 AddMockTransaction(&trans1
);
6664 response
.metadata
= NULL
;
6665 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6666 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6668 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6669 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6670 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6671 base::MessageLoop::current()->RunUntilIdle();
6672 RemoveMockTransaction(&trans1
);
6674 // Now return 200 when validating the entry so the metadata will be lost.
6675 MockTransaction
trans2(kTypicalGET_Transaction
);
6676 trans2
.load_flags
= LOAD_VALIDATE_CACHE
;
6677 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6678 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6680 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6681 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6682 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6685 // Tests that we don't mark entries as truncated when a filter detects the end
6687 TEST(HttpCache
, FilterCompletion
) {
6688 MockHttpCache cache
;
6689 TestCompletionCallback callback
;
6692 scoped_ptr
<HttpTransaction
> trans
;
6693 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6695 MockHttpRequest
request(kSimpleGET_Transaction
);
6696 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6697 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6699 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6700 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6701 EXPECT_GT(callback
.GetResult(rv
), 0);
6703 // Now make sure that the entry is preserved.
6704 trans
->DoneReading();
6707 // Make sure that the ActiveEntry is gone.
6708 base::MessageLoop::current()->RunUntilIdle();
6710 // Read from the cache.
6711 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6713 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6714 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6715 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6718 // Tests that we don't mark entries as truncated and release the cache
6719 // entry when DoneReading() is called before any Read() calls, such as
6721 TEST(HttpCache
, DoneReading
) {
6722 MockHttpCache cache
;
6723 TestCompletionCallback callback
;
6725 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6726 transaction
.data
= "";
6728 scoped_ptr
<HttpTransaction
> trans
;
6729 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6731 MockHttpRequest
request(transaction
);
6732 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6733 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6735 trans
->DoneReading();
6736 // Leave the transaction around.
6738 // Make sure that the ActiveEntry is gone.
6739 base::MessageLoop::current()->RunUntilIdle();
6741 // Read from the cache. This should not deadlock.
6742 RunTransactionTest(cache
.http_cache(), transaction
);
6744 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6745 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6746 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6749 // Tests that we stop caching when told.
6750 TEST(HttpCache
, StopCachingDeletesEntry
) {
6751 MockHttpCache cache
;
6752 TestCompletionCallback callback
;
6753 MockHttpRequest
request(kSimpleGET_Transaction
);
6756 scoped_ptr
<HttpTransaction
> trans
;
6757 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6759 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6760 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6762 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6763 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6764 EXPECT_EQ(10, callback
.GetResult(rv
));
6766 trans
->StopCaching();
6768 // We should be able to keep reading.
6769 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6770 EXPECT_GT(callback
.GetResult(rv
), 0);
6771 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6772 EXPECT_EQ(0, callback
.GetResult(rv
));
6775 // Make sure that the ActiveEntry is gone.
6776 base::MessageLoop::current()->RunUntilIdle();
6778 // Verify that the entry is gone.
6779 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6781 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6782 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6783 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6786 // Tests that we stop caching when told, even if DoneReading is called
6787 // after StopCaching.
6788 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6789 MockHttpCache cache
;
6790 TestCompletionCallback callback
;
6791 MockHttpRequest
request(kSimpleGET_Transaction
);
6794 scoped_ptr
<HttpTransaction
> trans
;
6795 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6797 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6798 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6800 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6801 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6802 EXPECT_EQ(10, callback
.GetResult(rv
));
6804 trans
->StopCaching();
6806 // We should be able to keep reading.
6807 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6808 EXPECT_GT(callback
.GetResult(rv
), 0);
6809 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6810 EXPECT_EQ(0, callback
.GetResult(rv
));
6812 // We should be able to call DoneReading.
6813 trans
->DoneReading();
6816 // Make sure that the ActiveEntry is gone.
6817 base::MessageLoop::current()->RunUntilIdle();
6819 // Verify that the entry is gone.
6820 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6822 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6823 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6824 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6827 // Tests that we stop caching when told, when using auth.
6828 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6829 MockHttpCache cache
;
6830 TestCompletionCallback callback
;
6831 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6832 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6833 AddMockTransaction(&mock_transaction
);
6834 MockHttpRequest
request(mock_transaction
);
6837 scoped_ptr
<HttpTransaction
> trans
;
6838 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6840 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6841 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6843 trans
->StopCaching();
6845 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6846 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6847 EXPECT_EQ(callback
.GetResult(rv
), 10);
6849 RemoveMockTransaction(&mock_transaction
);
6851 // Make sure that the ActiveEntry is gone.
6852 base::MessageLoop::current()->RunUntilIdle();
6854 // Verify that the entry is gone.
6855 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6857 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6858 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6859 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6862 // Tests that when we are told to stop caching we don't throw away valid data.
6863 TEST(HttpCache
, StopCachingSavesEntry
) {
6864 MockHttpCache cache
;
6865 TestCompletionCallback callback
;
6866 MockHttpRequest
request(kSimpleGET_Transaction
);
6869 scoped_ptr
<HttpTransaction
> trans
;
6870 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6872 // Force a response that can be resumed.
6873 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6874 AddMockTransaction(&mock_transaction
);
6875 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6876 "Content-Length: 42\n"
6879 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6880 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6882 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6883 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6884 EXPECT_EQ(callback
.GetResult(rv
), 10);
6886 trans
->StopCaching();
6888 // We should be able to keep reading.
6889 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6890 EXPECT_GT(callback
.GetResult(rv
), 0);
6891 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6892 EXPECT_EQ(callback
.GetResult(rv
), 0);
6894 RemoveMockTransaction(&mock_transaction
);
6897 // Verify that the entry is marked as incomplete.
6898 disk_cache::Entry
* entry
;
6899 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6900 HttpResponseInfo response
;
6901 bool truncated
= false;
6902 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6903 EXPECT_TRUE(truncated
);
6907 // Tests that we handle truncated enries when StopCaching is called.
6908 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6909 MockHttpCache cache
;
6910 TestCompletionCallback callback
;
6911 MockHttpRequest
request(kRangeGET_TransactionOK
);
6912 request
.extra_headers
.Clear();
6913 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6914 AddMockTransaction(&kRangeGET_TransactionOK
);
6916 std::string
raw_headers("HTTP/1.1 200 OK\n"
6917 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6919 "Accept-Ranges: bytes\n"
6920 "Content-Length: 80\n");
6921 CreateTruncatedEntry(raw_headers
, &cache
);
6924 // Now make a regular request.
6925 scoped_ptr
<HttpTransaction
> trans
;
6926 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6928 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6929 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6931 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6932 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6933 EXPECT_EQ(callback
.GetResult(rv
), 10);
6935 // This is actually going to do nothing.
6936 trans
->StopCaching();
6938 // We should be able to keep reading.
6939 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6940 EXPECT_GT(callback
.GetResult(rv
), 0);
6941 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6942 EXPECT_GT(callback
.GetResult(rv
), 0);
6943 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6944 EXPECT_EQ(callback
.GetResult(rv
), 0);
6947 // Verify that the disk entry was updated.
6948 disk_cache::Entry
* entry
;
6949 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6950 EXPECT_EQ(80, entry
->GetDataSize(1));
6951 bool truncated
= true;
6952 HttpResponseInfo response
;
6953 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6954 EXPECT_FALSE(truncated
);
6957 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6960 // Tests that we detect truncated resources from the net when there is
6961 // a Content-Length header.
6962 TEST(HttpCache
, TruncatedByContentLength
) {
6963 MockHttpCache cache
;
6964 TestCompletionCallback callback
;
6966 MockTransaction
transaction(kSimpleGET_Transaction
);
6967 AddMockTransaction(&transaction
);
6968 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6969 "Content-Length: 100\n";
6970 RunTransactionTest(cache
.http_cache(), transaction
);
6971 RemoveMockTransaction(&transaction
);
6973 // Read from the cache.
6974 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6976 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6977 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6978 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6981 // Tests that we actually flag entries as truncated when we detect an error
6983 TEST(HttpCache
, TruncatedByContentLength2
) {
6984 MockHttpCache cache
;
6985 TestCompletionCallback callback
;
6987 MockTransaction
transaction(kSimpleGET_Transaction
);
6988 AddMockTransaction(&transaction
);
6989 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6990 "Content-Length: 100\n"
6992 RunTransactionTest(cache
.http_cache(), transaction
);
6993 RemoveMockTransaction(&transaction
);
6995 // Verify that the entry is marked as incomplete.
6996 disk_cache::Entry
* entry
;
6997 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6998 HttpResponseInfo response
;
6999 bool truncated
= false;
7000 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
7001 EXPECT_TRUE(truncated
);
7005 // Make sure that calling SetPriority on a cache transaction passes on
7006 // its priority updates to its underlying network transaction.
7007 TEST(HttpCache
, SetPriority
) {
7008 MockHttpCache cache
;
7010 scoped_ptr
<HttpTransaction
> trans
;
7011 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
7013 // Shouldn't crash, but doesn't do anything either.
7014 trans
->SetPriority(LOW
);
7016 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7017 EXPECT_EQ(DEFAULT_PRIORITY
,
7018 cache
.network_layer()->last_create_transaction_priority());
7020 HttpRequestInfo info
;
7021 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7022 TestCompletionCallback callback
;
7023 EXPECT_EQ(ERR_IO_PENDING
,
7024 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7026 EXPECT_TRUE(cache
.network_layer()->last_transaction());
7027 if (cache
.network_layer()->last_transaction()) {
7028 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
7029 EXPECT_EQ(LOW
, cache
.network_layer()->last_transaction()->priority());
7032 trans
->SetPriority(HIGHEST
);
7034 if (cache
.network_layer()->last_transaction()) {
7035 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
7036 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_transaction()->priority());
7039 EXPECT_EQ(OK
, callback
.WaitForResult());
7042 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7043 // transaction passes on its argument to the underlying network transaction.
7044 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
7045 MockHttpCache cache
;
7047 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
7048 scoped_ptr
<HttpTransaction
> trans
;
7049 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
7051 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7053 HttpRequestInfo info
;
7054 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7055 TestCompletionCallback callback
;
7056 EXPECT_EQ(ERR_IO_PENDING
,
7057 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7059 ASSERT_TRUE(cache
.network_layer()->last_transaction());
7060 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
7061 websocket_handshake_stream_create_helper());
7062 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
7063 EXPECT_EQ(&create_helper
,
7064 cache
.network_layer()->last_transaction()->
7065 websocket_handshake_stream_create_helper());
7066 EXPECT_EQ(OK
, callback
.WaitForResult());
7069 // Make sure that a cache transaction passes on its priority to
7070 // newly-created network transactions.
7071 TEST(HttpCache
, SetPriorityNewTransaction
) {
7072 MockHttpCache cache
;
7073 AddMockTransaction(&kRangeGET_TransactionOK
);
7075 std::string
raw_headers("HTTP/1.1 200 OK\n"
7076 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7078 "Accept-Ranges: bytes\n"
7079 "Content-Length: 80\n");
7080 CreateTruncatedEntry(raw_headers
, &cache
);
7082 // Now make a regular request.
7083 std::string headers
;
7084 MockTransaction
transaction(kRangeGET_TransactionOK
);
7085 transaction
.request_headers
= EXTRA_HEADER
;
7086 transaction
.data
= kFullRangeData
;
7088 scoped_ptr
<HttpTransaction
> trans
;
7089 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(MEDIUM
, &trans
));
7090 EXPECT_EQ(DEFAULT_PRIORITY
,
7091 cache
.network_layer()->last_create_transaction_priority());
7093 MockHttpRequest
info(transaction
);
7094 TestCompletionCallback callback
;
7095 EXPECT_EQ(ERR_IO_PENDING
,
7096 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7097 EXPECT_EQ(OK
, callback
.WaitForResult());
7099 EXPECT_EQ(MEDIUM
, cache
.network_layer()->last_create_transaction_priority());
7101 trans
->SetPriority(HIGHEST
);
7102 // Should trigger a new network transaction and pick up the new
7104 ReadAndVerifyTransaction(trans
.get(), transaction
);
7106 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_create_transaction_priority());
7108 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7111 int64
RunTransactionAndGetReceivedBytes(
7112 MockHttpCache
& cache
,
7113 const MockTransaction
& trans_info
) {
7114 int64 received_bytes
= -1;
7115 RunTransactionTestBase(cache
.http_cache(), trans_info
,
7116 MockHttpRequest(trans_info
), NULL
, BoundNetLog(), NULL
,
7118 return received_bytes
;
7121 int64
TransactionSize(const MockTransaction
& transaction
) {
7122 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
7123 strlen(transaction
.data
);
7126 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
7127 MockHttpCache cache
;
7129 MockTransaction
transaction(kSimpleGET_Transaction
);
7130 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7131 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7133 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7134 EXPECT_EQ(0, received_bytes
);
7137 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
7138 MockHttpCache cache
;
7140 ScopedMockTransaction
transaction(kETagGET_Transaction
);
7141 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7142 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7144 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
7145 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
7146 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7147 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7150 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
7151 MockHttpCache cache
;
7153 MockTransaction
transaction(kTypicalGET_Transaction
);
7154 transaction
.request_headers
= "Foo: bar\r\n";
7155 transaction
.response_headers
=
7156 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7157 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7159 "Cache-Control: max-age=0\n"
7161 AddMockTransaction(&transaction
);
7162 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7163 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7165 RevalidationServer server
;
7166 transaction
.handler
= server
.Handler
;
7167 transaction
.request_headers
= "Foo: none\r\n";
7168 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7169 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7171 RemoveMockTransaction(&transaction
);
7174 TEST(HttpCache
, ReceivedBytesRange
) {
7175 MockHttpCache cache
;
7176 AddMockTransaction(&kRangeGET_TransactionOK
);
7177 MockTransaction
transaction(kRangeGET_TransactionOK
);
7179 // Read bytes 40-49 from the network.
7180 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7181 int64 range_response_size
= TransactionSize(transaction
);
7182 EXPECT_EQ(range_response_size
, received_bytes
);
7184 // Read bytes 40-49 from the cache.
7185 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7186 EXPECT_EQ(0, received_bytes
);
7187 base::MessageLoop::current()->RunUntilIdle();
7189 // Read bytes 30-39 from the network.
7190 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
7191 transaction
.data
= "rg: 30-39 ";
7192 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7193 EXPECT_EQ(range_response_size
, received_bytes
);
7194 base::MessageLoop::current()->RunUntilIdle();
7196 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7197 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
7198 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7199 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7200 EXPECT_EQ(range_response_size
* 2, received_bytes
);
7202 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7205 class HttpCachePrefetchValidationTest
: public ::testing::Test
{
7207 static const int kMaxAgeSecs
= 100;
7208 static const int kRequireValidationSecs
= kMaxAgeSecs
+ 1;
7210 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction
) {
7211 DCHECK_LT(kMaxAgeSecs
, prefetch_reuse_mins() * kNumSecondsPerMinute
);
7213 clock_
= new base::SimpleTestClock();
7214 cache_
.http_cache()->SetClockForTesting(make_scoped_ptr(clock_
));
7215 cache_
.network_layer()->SetClock(clock_
);
7217 transaction_
.response_headers
= "Cache-Control: max-age=100\n";
7220 bool TransactionRequiredNetwork(int load_flags
) {
7221 int pre_transaction_count
= transaction_count();
7222 transaction_
.load_flags
= load_flags
;
7223 RunTransactionTest(cache_
.http_cache(), transaction_
);
7224 return pre_transaction_count
!= transaction_count();
7227 void AdvanceTime(int seconds
) {
7228 clock_
->Advance(base::TimeDelta::FromSeconds(seconds
));
7231 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins
; }
7233 // How many times this test has sent requests to the (fake) origin
7234 // server. Every test case needs to make at least one request to initialise
7236 int transaction_count() {
7237 return cache_
.network_layer()->transaction_count();
7240 MockHttpCache cache_
;
7241 ScopedMockTransaction transaction_
;
7242 std::string response_headers_
;
7243 base::SimpleTestClock
* clock_
;
7246 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationShortlyAfterPrefetch
) {
7247 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7248 AdvanceTime(kRequireValidationSecs
);
7249 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7252 TEST_F(HttpCachePrefetchValidationTest
, ValidateLongAfterPrefetch
) {
7253 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7254 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute
);
7255 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7258 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceOnly
) {
7259 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7260 AdvanceTime(kRequireValidationSecs
);
7261 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7262 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7265 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceReadOnly
) {
7266 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7267 AdvanceTime(kRequireValidationSecs
);
7268 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE
));
7269 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7272 TEST_F(HttpCachePrefetchValidationTest
, BypassCacheOverwritesPrefetch
) {
7273 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7274 AdvanceTime(kRequireValidationSecs
);
7275 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE
));
7276 AdvanceTime(kRequireValidationSecs
);
7277 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7280 TEST_F(HttpCachePrefetchValidationTest
,
7281 SkipValidationOnExistingEntryThatNeedsValidation
) {
7282 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7283 AdvanceTime(kRequireValidationSecs
);
7284 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7285 AdvanceTime(kRequireValidationSecs
);
7286 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7287 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7290 TEST_F(HttpCachePrefetchValidationTest
,
7291 SkipValidationOnExistingEntryThatDoesNotNeedValidation
) {
7292 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7293 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7294 AdvanceTime(kRequireValidationSecs
);
7295 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7296 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7299 TEST_F(HttpCachePrefetchValidationTest
, PrefetchMultipleTimes
) {
7300 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7301 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7302 AdvanceTime(kRequireValidationSecs
);
7303 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7306 TEST_F(HttpCachePrefetchValidationTest
, ValidateOnDelayedSecondPrefetch
) {
7307 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7308 AdvanceTime(kRequireValidationSecs
);
7309 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7310 AdvanceTime(kRequireValidationSecs
);
7311 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7314 static void CheckResourceFreshnessHeader(const HttpRequestInfo
* request
,
7315 std::string
* response_status
,
7316 std::string
* response_headers
,
7317 std::string
* response_data
) {
7319 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
7320 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
7323 // Verify that the Resource-Freshness header is sent on a revalidation if the
7324 // stale-while-revalidate directive was on the response.
7325 TEST(HttpCache
, ResourceFreshnessHeaderSent
) {
7326 MockHttpCache cache
;
7328 ScopedMockTransaction
stale_while_revalidate_transaction(
7329 kSimpleGET_Transaction
);
7330 stale_while_revalidate_transaction
.response_headers
=
7331 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7333 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
7335 // Write to the cache.
7336 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7338 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7340 // Send the request again and check that Resource-Freshness header is added.
7341 stale_while_revalidate_transaction
.handler
= CheckResourceFreshnessHeader
;
7343 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7345 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7348 static void CheckResourceFreshnessAbsent(const HttpRequestInfo
* request
,
7349 std::string
* response_status
,
7350 std::string
* response_headers
,
7351 std::string
* response_data
) {
7352 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7355 // Verify that the Resource-Freshness header is not sent when
7356 // stale-while-revalidate is 0.
7357 TEST(HttpCache
, ResourceFreshnessHeaderNotSent
) {
7358 MockHttpCache cache
;
7360 ScopedMockTransaction
stale_while_revalidate_transaction(
7361 kSimpleGET_Transaction
);
7362 stale_while_revalidate_transaction
.response_headers
=
7363 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7365 "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
7367 // Write to the cache.
7368 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7370 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7372 // Send the request again and check that Resource-Freshness header is absent.
7373 stale_while_revalidate_transaction
.handler
= CheckResourceFreshnessAbsent
;
7375 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7377 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7380 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7381 // take place on a sparse entry.
7382 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7383 MockHttpCache cache
;
7385 // Create a transaction for bytes 0-9.
7386 MockHttpRequest
request(kRangeGET_TransactionOK
);
7387 MockTransaction
transaction(kRangeGET_TransactionOK
);
7388 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7389 transaction
.data
= "rg: 00-09 ";
7390 AddMockTransaction(&transaction
);
7392 TestCompletionCallback callback
;
7393 scoped_ptr
<HttpTransaction
> trans
;
7394 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
7396 ASSERT_TRUE(trans
.get());
7398 // Start our transaction.
7399 trans
->Start(&request
, callback
.callback(), BoundNetLog());
7401 // A second transaction on a different part of the file (the default
7402 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7403 // the already pending transaction.
7404 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7406 // Let the first transaction complete.
7407 callback
.WaitForResult();
7409 RemoveMockTransaction(&transaction
);
7412 // Makes sure that a request stops using the cache when the response headers
7413 // with "Cache-Control: no-store" arrives. That means that another request for
7414 // the same URL can be processed before the response body of the original
7416 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7417 MockHttpCache cache
;
7418 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7419 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7420 MockHttpRequest
request(mock_transaction
);
7422 scoped_ptr
<Context
> first(new Context
);
7423 first
->result
= cache
.CreateTransaction(&first
->trans
);
7424 ASSERT_EQ(OK
, first
->result
);
7425 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7427 first
->trans
->Start(&request
, first
->callback
.callback(), BoundNetLog());
7428 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7430 base::MessageLoop::current()->RunUntilIdle();
7431 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7432 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7433 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7434 "Cache-Control", "no-store"));
7435 // Here we have read the response header but not read the response body yet.
7437 // Let us create the second (read) transaction.
7438 scoped_ptr
<Context
> second(new Context
);
7439 second
->result
= cache
.CreateTransaction(&second
->trans
);
7440 ASSERT_EQ(OK
, second
->result
);
7441 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7442 second
->result
= second
->trans
->Start(&request
, second
->callback
.callback(),
7445 // Here the second transaction proceeds without reading the first body.
7446 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7447 base::MessageLoop::current()->RunUntilIdle();
7448 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7449 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7450 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7451 "Cache-Control", "no-store"));
7452 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);
7455 // Tests that serving a response entirely from cache replays the previous
7457 TEST(HttpCache
, CachePreservesSSLInfo
) {
7458 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
= 0xc02f;
7460 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
7462 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2
, &status
);
7464 scoped_refptr
<X509Certificate
> cert
=
7465 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7467 MockHttpCache cache
;
7469 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
7470 transaction
.cert
= cert
;
7471 transaction
.ssl_connection_status
= status
;
7473 // Fetch the resource.
7474 HttpResponseInfo response_info
;
7475 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7478 // The request should have hit the network and a cache entry created.
7479 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7480 EXPECT_EQ(0, cache
.disk_cache()->open_count());
7481 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7483 // The expected SSL state was reported.
7484 EXPECT_EQ(transaction
.ssl_connection_status
,
7485 response_info
.ssl_info
.connection_status
);
7486 EXPECT_TRUE(cert
->Equals(response_info
.ssl_info
.cert
.get()));
7488 // Fetch the resource again.
7489 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7492 // The request should have been reused without hitting the network.
7493 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7494 EXPECT_EQ(1, cache
.disk_cache()->open_count());
7495 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7497 // The SSL state was preserved.
7498 EXPECT_EQ(status
, response_info
.ssl_info
.connection_status
);
7499 EXPECT_TRUE(cert
->Equals(response_info
.ssl_info
.cert
.get()));
7502 // Tests that SSLInfo gets updated when revalidating a cached response.
7503 TEST(HttpCache
, RevalidationUpdatesSSLInfo
) {
7504 static const uint16_t kTLS_RSA_WITH_RC4_128_MD5
= 0x0004;
7505 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
= 0xc02f;
7508 SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5
, &status1
);
7509 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1
, &status1
);
7511 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
7513 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2
, &status2
);
7515 scoped_refptr
<X509Certificate
> cert1
=
7516 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
7517 scoped_refptr
<X509Certificate
> cert2
=
7518 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7520 MockHttpCache cache
;
7522 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
7523 transaction
.cert
= cert1
;
7524 transaction
.ssl_connection_status
= status1
;
7526 // Fetch the resource.
7527 HttpResponseInfo response_info
;
7528 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7531 // The request should have hit the network and a cache entry created.
7532 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7533 EXPECT_EQ(0, cache
.disk_cache()->open_count());
7534 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7535 EXPECT_FALSE(response_info
.was_cached
);
7537 // The expected SSL state was reported.
7538 EXPECT_EQ(status1
, response_info
.ssl_info
.connection_status
);
7539 EXPECT_TRUE(cert1
->Equals(response_info
.ssl_info
.cert
.get()));
7541 // The server deploys a more modern configuration but reports 304 on the
7542 // revalidation attempt.
7543 transaction
.status
= "HTTP/1.1 304 Not Modified";
7544 transaction
.cert
= cert2
;
7545 transaction
.ssl_connection_status
= status2
;
7547 // Fetch the resource again, forcing a revalidation.
7548 transaction
.request_headers
= "Cache-Control: max-age=0\r\n";
7549 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7552 // The request should have been successfully revalidated.
7553 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7554 EXPECT_EQ(1, cache
.disk_cache()->open_count());
7555 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7556 EXPECT_TRUE(response_info
.was_cached
);
7558 // The new SSL state is reported.
7559 EXPECT_EQ(status2
, response_info
.ssl_info
.connection_status
);
7560 EXPECT_TRUE(cert2
->Equals(response_info
.ssl_info
.cert
.get()));