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"
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/test/simple_test_clock.h"
19 #include "net/base/cache_type.h"
20 #include "net/base/elements_upload_data_stream.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/load_flags.h"
23 #include "net/base/load_timing_info.h"
24 #include "net/base/load_timing_info_test_util.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/test_data_directory.h"
27 #include "net/base/upload_bytes_element_reader.h"
28 #include "net/cert/cert_status_flags.h"
29 #include "net/cert/x509_certificate.h"
30 #include "net/disk_cache/disk_cache.h"
31 #include "net/http/http_byte_range.h"
32 #include "net/http/http_cache_transaction.h"
33 #include "net/http/http_request_headers.h"
34 #include "net/http/http_request_info.h"
35 #include "net/http/http_response_headers.h"
36 #include "net/http/http_response_info.h"
37 #include "net/http/http_transaction.h"
38 #include "net/http/http_transaction_test_util.h"
39 #include "net/http/http_util.h"
40 #include "net/http/mock_http_cache.h"
41 #include "net/log/test_net_log.h"
42 #include "net/log/test_net_log_entry.h"
43 #include "net/log/test_net_log_util.h"
44 #include "net/socket/client_socket_handle.h"
45 #include "net/ssl/ssl_cert_request_info.h"
46 #include "net/ssl/ssl_connection_status_flags.h"
47 #include "net/test/cert_test_util.h"
48 #include "net/websockets/websocket_handshake_stream_base.h"
49 #include "testing/gtest/include/gtest/gtest.h"
57 // Tests the load timing values of a request that goes through a
58 // MockNetworkTransaction.
59 void TestLoadTimingNetworkRequest(const LoadTimingInfo
& load_timing_info
) {
60 EXPECT_FALSE(load_timing_info
.socket_reused
);
61 EXPECT_NE(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
63 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
64 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
66 ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
67 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
68 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
69 load_timing_info
.send_start
);
71 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
73 // Set by URLRequest / URLRequestHttpJob, at a higher level.
74 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
75 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
76 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
79 // Tests the load timing values of a request that receives a cached response.
80 void TestLoadTimingCachedResponse(const LoadTimingInfo
& load_timing_info
) {
81 EXPECT_FALSE(load_timing_info
.socket_reused
);
82 EXPECT_EQ(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
84 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
85 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
87 ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
89 // Only the send start / end times should be sent, and they should have the
91 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
92 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
94 // Set by URLRequest / URLRequestHttpJob, at a higher level.
95 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
96 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
97 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
100 class DeleteCacheCompletionCallback
: public TestCompletionCallbackBase
{
102 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
104 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
105 base::Unretained(this))) {
108 const CompletionCallback
& callback() const { return callback_
; }
111 void OnComplete(int result
) {
116 MockHttpCache
* cache_
;
117 CompletionCallback callback_
;
119 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
122 //-----------------------------------------------------------------------------
125 void ReadAndVerifyTransaction(HttpTransaction
* trans
,
126 const MockTransaction
& trans_info
) {
128 int rv
= ReadTransaction(trans
, &content
);
131 std::string
expected(trans_info
.data
);
132 EXPECT_EQ(expected
, content
);
135 void RunTransactionTestBase(HttpCache
* cache
,
136 const MockTransaction
& trans_info
,
137 const MockHttpRequest
& request
,
138 HttpResponseInfo
* response_info
,
139 const BoundNetLog
& net_log
,
140 LoadTimingInfo
* load_timing_info
,
142 int64_t* received_bytes
) {
143 TestCompletionCallback callback
;
145 // write to the cache
147 scoped_ptr
<HttpTransaction
> trans
;
148 int rv
= cache
->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
150 ASSERT_TRUE(trans
.get());
152 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
153 if (rv
== ERR_IO_PENDING
)
154 rv
= callback
.WaitForResult();
155 ASSERT_EQ(trans_info
.return_code
, rv
);
160 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
161 ASSERT_TRUE(response
);
164 *response_info
= *response
;
166 if (load_timing_info
) {
167 // If a fake network connection is used, need a NetLog to get a fake socket
169 EXPECT_TRUE(net_log
.net_log());
170 *load_timing_info
= LoadTimingInfo();
171 trans
->GetLoadTimingInfo(load_timing_info
);
174 ReadAndVerifyTransaction(trans
.get(), trans_info
);
177 *sent_bytes
= trans
->GetTotalSentBytes();
179 *received_bytes
= trans
->GetTotalReceivedBytes();
182 void RunTransactionTestWithRequest(HttpCache
* cache
,
183 const MockTransaction
& trans_info
,
184 const MockHttpRequest
& request
,
185 HttpResponseInfo
* response_info
) {
186 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
187 BoundNetLog(), nullptr, nullptr, nullptr);
190 void RunTransactionTestAndGetTiming(HttpCache
* cache
,
191 const MockTransaction
& trans_info
,
192 const BoundNetLog
& log
,
193 LoadTimingInfo
* load_timing_info
) {
194 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
195 nullptr, log
, load_timing_info
, nullptr, nullptr);
198 void RunTransactionTest(HttpCache
* cache
, const MockTransaction
& trans_info
) {
199 RunTransactionTestAndGetTiming(cache
, trans_info
, BoundNetLog(), nullptr);
202 void RunTransactionTestWithLog(HttpCache
* cache
,
203 const MockTransaction
& trans_info
,
204 const BoundNetLog
& log
) {
205 RunTransactionTestAndGetTiming(cache
, trans_info
, log
, nullptr);
208 void RunTransactionTestWithResponseInfo(HttpCache
* cache
,
209 const MockTransaction
& trans_info
,
210 HttpResponseInfo
* response
) {
211 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
215 void RunTransactionTestWithResponseInfoAndGetTiming(
217 const MockTransaction
& trans_info
,
218 HttpResponseInfo
* response
,
219 const BoundNetLog
& log
,
220 LoadTimingInfo
* load_timing_info
) {
221 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
222 response
, log
, load_timing_info
, nullptr, nullptr);
225 void RunTransactionTestWithResponse(HttpCache
* cache
,
226 const MockTransaction
& trans_info
,
227 std::string
* response_headers
) {
228 HttpResponseInfo response
;
229 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
230 response
.headers
->GetNormalizedHeaders(response_headers
);
233 void RunTransactionTestWithResponseAndGetTiming(
235 const MockTransaction
& trans_info
,
236 std::string
* response_headers
,
237 const BoundNetLog
& log
,
238 LoadTimingInfo
* load_timing_info
) {
239 HttpResponseInfo response
;
240 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
241 &response
, log
, load_timing_info
, nullptr, nullptr);
242 response
.headers
->GetNormalizedHeaders(response_headers
);
245 // This class provides a handler for kFastNoStoreGET_Transaction so that the
246 // no-store header can be included on demand.
247 class FastTransactionServer
{
249 FastTransactionServer() {
252 ~FastTransactionServer() {}
254 void set_no_store(bool value
) { no_store
= value
; }
256 static void FastNoStoreHandler(const HttpRequestInfo
* request
,
257 std::string
* response_status
,
258 std::string
* response_headers
,
259 std::string
* response_data
) {
261 *response_headers
= "Cache-Control: no-store\n";
265 static bool no_store
;
266 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
268 bool FastTransactionServer::no_store
;
270 const MockTransaction kFastNoStoreGET_Transaction
= {
271 "http://www.google.com/nostore",
277 "Cache-Control: max-age=10000\n",
279 "<html><body>Google Blah Blah</body></html>",
280 TEST_MODE_SYNC_NET_START
,
281 &FastTransactionServer::FastNoStoreHandler
,
287 // This class provides a handler for kRangeGET_TransactionOK so that the range
288 // request can be served on demand.
289 class RangeTransactionServer
{
291 RangeTransactionServer() {
292 not_modified_
= false;
296 ~RangeTransactionServer() {
297 not_modified_
= false;
302 // Returns only 416 or 304 when set.
303 void set_not_modified(bool value
) { not_modified_
= value
; }
305 // Returns 206 when revalidating a range (instead of 304).
306 void set_modified(bool value
) { modified_
= value
; }
308 // Returns 200 instead of 206 (a malformed response overall).
309 void set_bad_200(bool value
) { bad_200_
= value
; }
311 // Other than regular range related behavior (and the flags mentioned above),
312 // the server reacts to requests headers like so:
313 // X-Require-Mock-Auth -> return 401.
314 // X-Require-Mock-Auth-Alt -> return 401.
315 // X-Return-Default-Range -> assume 40-49 was requested.
316 // The -Alt variant doesn't cause the MockNetworkTransaction to
317 // report that it IsReadyToRestartForAuth().
318 static void RangeHandler(const HttpRequestInfo
* request
,
319 std::string
* response_status
,
320 std::string
* response_headers
,
321 std::string
* response_data
);
324 static bool not_modified_
;
325 static bool modified_
;
326 static bool bad_200_
;
327 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
329 bool RangeTransactionServer::not_modified_
= false;
330 bool RangeTransactionServer::modified_
= false;
331 bool RangeTransactionServer::bad_200_
= false;
333 // A dummy extra header that must be preserved on a given request.
335 // EXTRA_HEADER_LINE doesn't include a line terminator because it
336 // will be passed to AddHeaderFromString() which doesn't accept them.
337 #define EXTRA_HEADER_LINE "Extra: header"
339 // EXTRA_HEADER contains a line terminator, as expected by
340 // AddHeadersFromString() (_not_ AddHeaderFromString()).
341 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
343 static const char kExtraHeaderKey
[] = "Extra";
346 void RangeTransactionServer::RangeHandler(const HttpRequestInfo
* request
,
347 std::string
* response_status
,
348 std::string
* response_headers
,
349 std::string
* response_data
) {
350 if (request
->extra_headers
.IsEmpty()) {
351 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
352 response_data
->clear();
356 // We want to make sure we don't delete extra headers.
357 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
360 request
->extra_headers
.HasHeader("X-Require-Mock-Auth") ||
361 request
->extra_headers
.HasHeader("X-Require-Mock-Auth-Alt");
363 if (require_auth
&& !request
->extra_headers
.HasHeader("Authorization")) {
364 response_status
->assign("HTTP/1.1 401 Unauthorized");
365 response_data
->assign("WWW-Authenticate: Foo\n");
370 response_status
->assign("HTTP/1.1 304 Not Modified");
371 response_data
->clear();
375 std::vector
<HttpByteRange
> ranges
;
376 std::string range_header
;
377 if (!request
->extra_headers
.GetHeader(HttpRequestHeaders::kRange
,
379 !HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
380 ranges
.size() != 1) {
381 // This is not a byte range request. We return 200.
382 response_status
->assign("HTTP/1.1 200 OK");
383 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
384 response_data
->assign("Not a range");
388 // We can handle this range request.
389 HttpByteRange byte_range
= ranges
[0];
391 if (request
->extra_headers
.HasHeader("X-Return-Default-Range")) {
392 byte_range
.set_first_byte_position(40);
393 byte_range
.set_last_byte_position(49);
396 if (byte_range
.first_byte_position() > 79) {
397 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
398 response_data
->clear();
402 EXPECT_TRUE(byte_range
.ComputeBounds(80));
403 int start
= static_cast<int>(byte_range
.first_byte_position());
404 int end
= static_cast<int>(byte_range
.last_byte_position());
408 std::string content_range
= base::StringPrintf(
409 "Content-Range: bytes %d-%d/80\n", start
, end
);
410 response_headers
->append(content_range
);
412 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
415 EXPECT_EQ(0, end
% 10);
418 EXPECT_EQ(9, (end
- start
) % 10);
419 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
420 base::StringAppendF(&data
, "rg: %02d-%02d ",
421 block_start
, block_start
+ 9);
424 *response_data
= data
;
426 if (end
- start
!= 9) {
427 // We also have to fix content-length.
428 int len
= end
- start
+ 1;
429 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
431 response_headers
->replace(response_headers
->find("Content-Length:"),
432 content_length
.size(), content_length
);
435 response_status
->assign("HTTP/1.1 304 Not Modified");
436 response_data
->clear();
440 const MockTransaction kRangeGET_TransactionOK
= {
441 "http://www.google.com/range",
444 "Range: bytes = 40-49\r\n" EXTRA_HEADER
,
446 "HTTP/1.1 206 Partial Content",
447 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
449 "Accept-Ranges: bytes\n"
450 "Content-Length: 10\n",
454 &RangeTransactionServer::RangeHandler
,
460 const char kFullRangeData
[] =
461 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
462 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
464 // Verifies the response headers (|response|) match a partial content
465 // response for the range starting at |start| and ending at |end|.
466 void Verify206Response(std::string response
, int start
, int end
) {
467 std::string
raw_headers(
468 HttpUtil::AssembleRawHeaders(response
.data(), response
.size()));
469 scoped_refptr
<HttpResponseHeaders
> headers(
470 new HttpResponseHeaders(raw_headers
));
472 ASSERT_EQ(206, headers
->response_code());
474 int64 range_start
, range_end
, object_size
;
476 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
477 int64 content_length
= headers
->GetContentLength();
479 int length
= end
- start
+ 1;
480 ASSERT_EQ(length
, content_length
);
481 ASSERT_EQ(start
, range_start
);
482 ASSERT_EQ(end
, range_end
);
485 // Creates a truncated entry that can be resumed using byte ranges.
486 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
487 // Create a disk cache entry that stores an incomplete resource.
488 disk_cache::Entry
* entry
;
489 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
493 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
495 HttpResponseInfo response
;
496 response
.response_time
= base::Time::Now();
497 response
.request_time
= base::Time::Now();
498 response
.headers
= new HttpResponseHeaders(raw_headers
);
499 // Set the last argument for this to be an incomplete request.
500 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
502 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
503 int len
= static_cast<int>(base::strlcpy(buf
->data(),
504 "rg: 00-09 rg: 10-19 ", 100));
505 TestCompletionCallback cb
;
506 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
507 EXPECT_EQ(len
, cb
.GetResult(rv
));
511 // Verifies that there's an entry with this |key| with the truncated flag set to
512 // |flag_value|, and with an optional |data_size| (if not zero).
513 void VerifyTruncatedFlag(MockHttpCache
* cache
,
514 const std::string
& key
,
517 disk_cache::Entry
* entry
;
518 ASSERT_TRUE(cache
->OpenBackendEntry(key
, &entry
));
519 disk_cache::ScopedEntryPtr
closer(entry
);
521 HttpResponseInfo response
;
522 bool truncated
= !flag_value
;
523 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
524 EXPECT_EQ(flag_value
, truncated
);
526 EXPECT_EQ(data_size
, entry
->GetDataSize(1));
529 // Helper to represent a network HTTP response.
531 // Set this response into |trans|.
532 void AssignTo(MockTransaction
* trans
) const {
533 trans
->status
= status
;
534 trans
->response_headers
= headers
;
538 std::string
status_and_headers() const {
539 return std::string(status
) + "\n" + std::string(headers
);
548 Context() : result(ERR_IO_PENDING
) {}
551 TestCompletionCallback callback
;
552 scoped_ptr
<HttpTransaction
> trans
;
555 class FakeWebSocketHandshakeStreamCreateHelper
556 : public WebSocketHandshakeStreamBase::CreateHelper
{
558 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
559 WebSocketHandshakeStreamBase
* CreateBasicStream(
560 scoped_ptr
<ClientSocketHandle
> connect
,
561 bool using_proxy
) override
{
564 WebSocketHandshakeStreamBase
* CreateSpdyStream(
565 const base::WeakPtr
<SpdySession
>& session
,
566 bool use_relative_url
) override
{
571 // Returns true if |entry| is not one of the log types paid attention to in this
572 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
574 bool ShouldIgnoreLogEntry(const TestNetLogEntry
& entry
) {
575 switch (entry
.type
) {
576 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
577 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
578 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
579 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
580 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
581 case NetLog::TYPE_HTTP_CACHE_READ_INFO
:
588 // Modifies |entries| to only include log entries created by the cache layer and
589 // asserted on in these tests.
590 void FilterLogEntries(TestNetLogEntry::List
* entries
) {
591 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
592 &ShouldIgnoreLogEntry
),
596 bool LogContainsEventType(const BoundTestNetLog
& log
,
597 NetLog::EventType expected
) {
598 TestNetLogEntry::List entries
;
599 log
.GetEntries(&entries
);
600 for (size_t i
= 0; i
< entries
.size(); i
++) {
601 if (entries
[i
].type
== expected
)
610 //-----------------------------------------------------------------------------
613 TEST(HttpCache
, CreateThenDestroy
) {
616 scoped_ptr
<HttpTransaction
> trans
;
617 EXPECT_EQ(OK
, cache
.CreateTransaction(&trans
));
618 ASSERT_TRUE(trans
.get());
621 TEST(HttpCache
, GetBackend
) {
622 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(0));
624 disk_cache::Backend
* backend
;
625 TestCompletionCallback cb
;
626 // This will lazily initialize the backend.
627 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
628 EXPECT_EQ(OK
, cb
.GetResult(rv
));
631 TEST(HttpCache
, SimpleGET
) {
634 LoadTimingInfo load_timing_info
;
636 // Write to the cache.
637 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
638 log
.bound(), &load_timing_info
);
640 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
641 EXPECT_EQ(0, cache
.disk_cache()->open_count());
642 EXPECT_EQ(1, cache
.disk_cache()->create_count());
643 TestLoadTimingNetworkRequest(load_timing_info
);
646 TEST(HttpCache
, SimpleGETNoDiskCache
) {
649 cache
.disk_cache()->set_fail_requests();
652 LoadTimingInfo load_timing_info
;
654 // Read from the network, and don't use the cache.
655 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
656 log
.bound(), &load_timing_info
);
658 // Check that the NetLog was filled as expected.
659 // (We attempted to both Open and Create entries, but both failed).
660 TestNetLogEntry::List entries
;
661 log
.GetEntries(&entries
);
662 FilterLogEntries(&entries
);
664 EXPECT_EQ(6u, entries
.size());
666 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
668 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
670 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
672 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
674 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
676 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
678 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
679 EXPECT_EQ(0, cache
.disk_cache()->open_count());
680 EXPECT_EQ(0, cache
.disk_cache()->create_count());
681 TestLoadTimingNetworkRequest(load_timing_info
);
684 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
685 // This will initialize a cache object with NULL backend.
686 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
687 factory
->set_fail(true);
688 factory
->FinishCreation(); // We'll complete synchronously.
689 MockHttpCache
cache(factory
);
691 // Read from the network, and don't use the cache.
692 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
694 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
695 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
698 // Tests that IOBuffers are not referenced after IO completes.
699 TEST(HttpCache
, ReleaseBuffer
) {
702 // Write to the cache.
703 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
705 MockHttpRequest
request(kSimpleGET_Transaction
);
706 scoped_ptr
<HttpTransaction
> trans
;
707 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
709 const int kBufferSize
= 10;
710 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(kBufferSize
));
711 ReleaseBufferCompletionCallback
cb(buffer
.get());
713 int rv
= trans
->Start(&request
, cb
.callback(), BoundNetLog());
714 EXPECT_EQ(OK
, cb
.GetResult(rv
));
716 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
717 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
720 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
723 cache
.disk_cache()->set_soft_failures(true);
725 // Read from the network, and fail to write to the cache.
726 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
728 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
729 EXPECT_EQ(0, cache
.disk_cache()->open_count());
730 EXPECT_EQ(1, cache
.disk_cache()->create_count());
732 // This one should see an empty cache again.
733 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
735 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
736 EXPECT_EQ(0, cache
.disk_cache()->open_count());
737 EXPECT_EQ(2, cache
.disk_cache()->create_count());
740 // Tests that disk failures after the transaction has started don't cause the
742 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
745 MockHttpRequest
request(kSimpleGET_Transaction
);
747 scoped_ptr
<Context
> c(new Context());
748 int rv
= cache
.CreateTransaction(&c
->trans
);
751 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
752 EXPECT_EQ(ERR_IO_PENDING
, rv
);
753 rv
= c
->callback
.WaitForResult();
755 // Start failing request now.
756 cache
.disk_cache()->set_soft_failures(true);
758 // We have to open the entry again to propagate the failure flag.
759 disk_cache::Entry
* en
;
760 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
763 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
766 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
767 EXPECT_EQ(1, cache
.disk_cache()->open_count());
768 EXPECT_EQ(1, cache
.disk_cache()->create_count());
770 // This one should see an empty cache again.
771 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
773 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
774 EXPECT_EQ(1, cache
.disk_cache()->open_count());
775 EXPECT_EQ(2, cache
.disk_cache()->create_count());
778 // Tests that we handle failures to read from the cache.
779 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
782 // Read from the network, and write to the cache.
783 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
785 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
786 EXPECT_EQ(0, cache
.disk_cache()->open_count());
787 EXPECT_EQ(1, cache
.disk_cache()->create_count());
789 cache
.disk_cache()->set_soft_failures(true);
791 // Now fail to read from the cache.
792 scoped_ptr
<Context
> c(new Context());
793 int rv
= cache
.CreateTransaction(&c
->trans
);
796 MockHttpRequest
request(kSimpleGET_Transaction
);
797 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
798 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
800 // Now verify that the entry was removed from the cache.
801 cache
.disk_cache()->set_soft_failures(false);
803 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
804 EXPECT_EQ(1, cache
.disk_cache()->open_count());
805 EXPECT_EQ(2, cache
.disk_cache()->create_count());
807 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
809 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
810 EXPECT_EQ(1, cache
.disk_cache()->open_count());
811 EXPECT_EQ(3, cache
.disk_cache()->create_count());
814 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
818 LoadTimingInfo load_timing_info
;
820 // Write to the cache.
821 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
822 log
.bound(), &load_timing_info
);
824 // Check that the NetLog was filled as expected.
825 TestNetLogEntry::List entries
;
826 log
.GetEntries(&entries
);
827 FilterLogEntries(&entries
);
829 EXPECT_EQ(8u, entries
.size());
831 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
833 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
835 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
837 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
839 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
841 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
843 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
845 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
847 TestLoadTimingNetworkRequest(load_timing_info
);
849 // Force this transaction to read from the cache.
850 MockTransaction
transaction(kSimpleGET_Transaction
);
851 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
855 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
858 // Check that the NetLog was filled as expected.
859 log
.GetEntries(&entries
);
860 FilterLogEntries(&entries
);
862 EXPECT_EQ(8u, entries
.size());
864 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
866 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
868 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
870 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
872 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
874 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
876 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
878 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
880 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
881 EXPECT_EQ(1, cache
.disk_cache()->open_count());
882 EXPECT_EQ(1, cache
.disk_cache()->create_count());
883 TestLoadTimingCachedResponse(load_timing_info
);
886 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
889 // force this transaction to read from the cache
890 MockTransaction
transaction(kSimpleGET_Transaction
);
891 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
893 MockHttpRequest
request(transaction
);
894 TestCompletionCallback callback
;
896 scoped_ptr
<HttpTransaction
> trans
;
897 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
899 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
900 if (rv
== ERR_IO_PENDING
)
901 rv
= callback
.WaitForResult();
902 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
906 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
907 EXPECT_EQ(0, cache
.disk_cache()->open_count());
908 EXPECT_EQ(0, cache
.disk_cache()->create_count());
911 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
914 // write to the cache
915 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
917 // force this transaction to read from the cache if valid
918 MockTransaction
transaction(kSimpleGET_Transaction
);
919 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
921 RunTransactionTest(cache
.http_cache(), transaction
);
923 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
924 EXPECT_EQ(1, cache
.disk_cache()->open_count());
925 EXPECT_EQ(1, cache
.disk_cache()->create_count());
928 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
931 // force this transaction to read from the cache if valid
932 MockTransaction
transaction(kSimpleGET_Transaction
);
933 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
935 RunTransactionTest(cache
.http_cache(), transaction
);
937 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
938 EXPECT_EQ(0, cache
.disk_cache()->open_count());
939 EXPECT_EQ(1, cache
.disk_cache()->create_count());
942 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
943 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
946 // Write to the cache.
947 MockTransaction
transaction(kSimpleGET_Transaction
);
948 transaction
.request_headers
= "Foo: bar\r\n";
949 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
951 AddMockTransaction(&transaction
);
952 RunTransactionTest(cache
.http_cache(), transaction
);
954 // Read from the cache.
955 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
956 RunTransactionTest(cache
.http_cache(), transaction
);
958 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
959 EXPECT_EQ(1, cache
.disk_cache()->open_count());
960 EXPECT_EQ(1, cache
.disk_cache()->create_count());
961 RemoveMockTransaction(&transaction
);
964 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
965 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
968 // Write to the cache.
969 MockTransaction
transaction(kSimpleGET_Transaction
);
970 transaction
.request_headers
= "Foo: bar\r\n";
971 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
973 AddMockTransaction(&transaction
);
974 RunTransactionTest(cache
.http_cache(), transaction
);
976 // Attempt to read from the cache... this is a vary mismatch that must reach
977 // the network again.
978 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
979 transaction
.request_headers
= "Foo: none\r\n";
981 LoadTimingInfo load_timing_info
;
982 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
985 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
986 EXPECT_EQ(1, cache
.disk_cache()->open_count());
987 EXPECT_EQ(1, cache
.disk_cache()->create_count());
988 TestLoadTimingNetworkRequest(load_timing_info
);
989 RemoveMockTransaction(&transaction
);
992 // Tests that was_cached was set properly on a failure, even if the cached
993 // response wasn't returned.
994 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
998 MockTransaction
transaction(kSimpleGET_Transaction
);
999 transaction
.response_headers
= "Cache-Control: no-cache\n";
1001 AddMockTransaction(&transaction
);
1002 RunTransactionTest(cache
.http_cache(), transaction
);
1003 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1004 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1005 RemoveMockTransaction(&transaction
);
1007 // Network failure with error; should fail but have was_cached set.
1008 transaction
.return_code
= ERR_FAILED
;
1009 AddMockTransaction(&transaction
);
1011 MockHttpRequest
request(transaction
);
1012 TestCompletionCallback callback
;
1013 scoped_ptr
<HttpTransaction
> trans
;
1014 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
1016 ASSERT_TRUE(trans
.get());
1017 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1018 EXPECT_EQ(ERR_FAILED
, callback
.GetResult(rv
));
1020 const HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1021 ASSERT_TRUE(response_info
);
1022 EXPECT_TRUE(response_info
->was_cached
);
1023 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1025 RemoveMockTransaction(&transaction
);
1028 // Confirm if we have an empty cache, a read is marked as network verified.
1029 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1030 MockHttpCache cache
;
1032 // write to the cache
1033 HttpResponseInfo response_info
;
1034 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1037 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1038 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1039 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1040 EXPECT_TRUE(response_info
.network_accessed
);
1043 // Confirm if we have a fresh entry in cache, it isn't marked as
1044 // network verified.
1045 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1046 MockHttpCache cache
;
1049 MockTransaction
transaction(kSimpleGET_Transaction
);
1051 RunTransactionTest(cache
.http_cache(), transaction
);
1052 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1053 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1055 // Re-run transaction; make sure we don't mark the network as accessed.
1056 HttpResponseInfo response_info
;
1057 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1060 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1061 EXPECT_FALSE(response_info
.server_data_unavailable
);
1062 EXPECT_FALSE(response_info
.network_accessed
);
1065 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1066 MockHttpCache cache
;
1068 // Write to the cache.
1069 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1071 // Force this transaction to write to the cache again.
1072 MockTransaction
transaction(kSimpleGET_Transaction
);
1073 transaction
.load_flags
|= LOAD_BYPASS_CACHE
;
1075 BoundTestNetLog log
;
1076 LoadTimingInfo load_timing_info
;
1078 // Write to the cache.
1079 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1082 // Check that the NetLog was filled as expected.
1083 TestNetLogEntry::List entries
;
1084 log
.GetEntries(&entries
);
1085 FilterLogEntries(&entries
);
1087 EXPECT_EQ(8u, entries
.size());
1089 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1091 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1093 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1095 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1097 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1099 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1101 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1103 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1105 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1106 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1107 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1108 TestLoadTimingNetworkRequest(load_timing_info
);
1111 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1112 MockHttpCache cache
;
1114 // write to the cache
1115 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1117 // force this transaction to write to the cache again
1118 MockTransaction
transaction(kSimpleGET_Transaction
);
1119 transaction
.request_headers
= "pragma: no-cache\r\n";
1121 RunTransactionTest(cache
.http_cache(), transaction
);
1123 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1124 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1125 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1128 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1129 MockHttpCache cache
;
1131 // write to the cache
1132 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1134 // force this transaction to write to the cache again
1135 MockTransaction
transaction(kSimpleGET_Transaction
);
1136 transaction
.request_headers
= "cache-control: no-cache\r\n";
1138 RunTransactionTest(cache
.http_cache(), transaction
);
1140 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1141 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1142 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1145 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1146 MockHttpCache cache
;
1148 // Write to the cache.
1149 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1151 // Read from the cache.
1152 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1154 // Force this transaction to validate the cache.
1155 MockTransaction
transaction(kSimpleGET_Transaction
);
1156 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
1158 HttpResponseInfo response_info
;
1159 BoundTestNetLog log
;
1160 LoadTimingInfo load_timing_info
;
1161 RunTransactionTestWithResponseInfoAndGetTiming(
1162 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1165 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1166 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1167 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1168 EXPECT_TRUE(response_info
.network_accessed
);
1169 TestLoadTimingNetworkRequest(load_timing_info
);
1172 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1173 MockHttpCache cache
;
1175 // write to the cache
1176 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1178 // read from the cache
1179 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1181 // force this transaction to validate the cache
1182 MockTransaction
transaction(kSimpleGET_Transaction
);
1183 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1185 RunTransactionTest(cache
.http_cache(), transaction
);
1187 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1188 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1189 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1192 static void PreserveRequestHeaders_Handler(const HttpRequestInfo
* request
,
1193 std::string
* response_status
,
1194 std::string
* response_headers
,
1195 std::string
* response_data
) {
1196 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1199 // Tests that we don't remove extra headers for simple requests.
1200 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1201 MockHttpCache cache
;
1203 MockTransaction
transaction(kSimpleGET_Transaction
);
1204 transaction
.handler
= PreserveRequestHeaders_Handler
;
1205 transaction
.request_headers
= EXTRA_HEADER
;
1206 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1207 AddMockTransaction(&transaction
);
1209 // Write, then revalidate the entry.
1210 RunTransactionTest(cache
.http_cache(), transaction
);
1211 RunTransactionTest(cache
.http_cache(), transaction
);
1213 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1214 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1215 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1216 RemoveMockTransaction(&transaction
);
1219 // Tests that we don't remove extra headers for conditionalized requests.
1220 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1221 MockHttpCache cache
;
1223 // Write to the cache.
1224 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1226 MockTransaction
transaction(kETagGET_Transaction
);
1227 transaction
.handler
= PreserveRequestHeaders_Handler
;
1228 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1230 AddMockTransaction(&transaction
);
1232 RunTransactionTest(cache
.http_cache(), transaction
);
1234 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1235 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1236 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1237 RemoveMockTransaction(&transaction
);
1240 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1241 MockHttpCache cache
;
1243 MockHttpRequest
request(kSimpleGET_Transaction
);
1245 std::vector
<Context
*> context_list
;
1246 const int kNumTransactions
= 5;
1248 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1249 context_list
.push_back(new Context());
1250 Context
* c
= context_list
[i
];
1252 c
->result
= cache
.CreateTransaction(&c
->trans
);
1253 ASSERT_EQ(OK
, c
->result
);
1254 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1257 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1260 // All requests are waiting for the active entry.
1261 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1262 Context
* c
= context_list
[i
];
1263 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1266 // Allow all requests to move from the Create queue to the active entry.
1267 base::MessageLoop::current()->RunUntilIdle();
1269 // The first request should be a writer at this point, and the subsequent
1270 // requests should be pending.
1272 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1273 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1274 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1276 // All requests depend on the writer, and the writer is between Start and
1278 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1279 Context
* c
= context_list
[i
];
1280 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1283 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1284 Context
* c
= context_list
[i
];
1285 if (c
->result
== ERR_IO_PENDING
)
1286 c
->result
= c
->callback
.WaitForResult();
1287 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1290 // We should not have had to re-open the disk entry
1292 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1293 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1294 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1296 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1297 Context
* c
= context_list
[i
];
1302 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1303 // If cancelling a request is racing with another request for the same resource
1304 // finishing, we have to make sure that we remove both transactions from the
1306 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1307 MockHttpCache cache
;
1309 MockHttpRequest
request(kSimpleGET_Transaction
);
1310 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1311 reader_request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
1313 std::vector
<Context
*> context_list
;
1314 const int kNumTransactions
= 5;
1316 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1317 context_list
.push_back(new Context());
1318 Context
* c
= context_list
[i
];
1320 c
->result
= cache
.CreateTransaction(&c
->trans
);
1321 ASSERT_EQ(OK
, c
->result
);
1323 MockHttpRequest
* this_request
= &request
;
1324 if (i
== 1 || i
== 2)
1325 this_request
= &reader_request
;
1328 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1331 // Allow all requests to move from the Create queue to the active entry.
1332 base::MessageLoop::current()->RunUntilIdle();
1334 // The first request should be a writer at this point, and the subsequent
1335 // requests should be pending.
1337 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1338 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1339 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1341 Context
* c
= context_list
[0];
1342 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1343 c
->result
= c
->callback
.WaitForResult();
1344 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1346 // Now we have 2 active readers and two queued transactions.
1348 EXPECT_EQ(LOAD_STATE_IDLE
, context_list
[2]->trans
->GetLoadState());
1349 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
,
1350 context_list
[3]->trans
->GetLoadState());
1352 c
= context_list
[1];
1353 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1354 c
->result
= c
->callback
.WaitForResult();
1355 if (c
->result
== OK
)
1356 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1358 // At this point we have one reader, two pending transactions and a task on
1359 // the queue to move to the next transaction. Now we cancel the request that
1360 // is the current reader, and expect the queued task to be able to start the
1363 c
= context_list
[2];
1366 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1367 Context
* c
= context_list
[i
];
1368 if (c
->result
== ERR_IO_PENDING
)
1369 c
->result
= c
->callback
.WaitForResult();
1370 if (c
->result
== OK
)
1371 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1374 // We should not have had to re-open the disk entry.
1376 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1377 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1378 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1380 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1381 Context
* c
= context_list
[i
];
1386 // Tests that we can doom an entry with pending transactions and delete one of
1387 // the pending transactions before the first one completes.
1388 // See http://code.google.com/p/chromium/issues/detail?id=25588
1389 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1390 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1391 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
1393 MockHttpRequest
request(kSimpleGET_Transaction
);
1394 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1395 writer_request
.load_flags
= LOAD_BYPASS_CACHE
;
1397 ScopedVector
<Context
> context_list
;
1398 const int kNumTransactions
= 4;
1400 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1401 context_list
.push_back(new Context());
1402 Context
* c
= context_list
[i
];
1404 c
->result
= cache
.CreateTransaction(&c
->trans
);
1405 ASSERT_EQ(OK
, c
->result
);
1407 MockHttpRequest
* this_request
= &request
;
1409 this_request
= &writer_request
;
1412 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1415 // The first request should be a writer at this point, and the two subsequent
1416 // requests should be pending. The last request doomed the first entry.
1418 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1420 // Cancel the first queued transaction.
1421 delete context_list
[1];
1422 context_list
.get()[1] = NULL
;
1424 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1427 Context
* c
= context_list
[i
];
1428 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1429 c
->result
= c
->callback
.WaitForResult();
1430 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1434 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1435 // We may attempt to delete an entry synchronously with the act of adding a new
1436 // transaction to said entry.
1437 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1438 MockHttpCache cache
;
1440 // The headers will be served right from the call to Start() the request.
1441 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1442 FastTransactionServer request_handler
;
1443 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1445 std::vector
<Context
*> context_list
;
1446 const int kNumTransactions
= 3;
1448 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1449 context_list
.push_back(new Context());
1450 Context
* c
= context_list
[i
];
1452 c
->result
= cache
.CreateTransaction(&c
->trans
);
1453 ASSERT_EQ(OK
, c
->result
);
1456 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1459 // Allow all requests to move from the Create queue to the active entry.
1460 base::MessageLoop::current()->RunUntilIdle();
1462 // The first request should be a writer at this point, and the subsequent
1463 // requests should be pending.
1465 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1466 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1467 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1469 // Now, make sure that the second request asks for the entry not to be stored.
1470 request_handler
.set_no_store(true);
1472 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1473 Context
* c
= context_list
[i
];
1474 if (c
->result
== ERR_IO_PENDING
)
1475 c
->result
= c
->callback
.WaitForResult();
1476 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1480 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1481 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1482 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1484 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1487 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1488 MockHttpCache cache
;
1490 MockHttpRequest
request(kSimpleGET_Transaction
);
1492 std::vector
<Context
*> context_list
;
1493 const int kNumTransactions
= 2;
1495 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1496 context_list
.push_back(new Context());
1497 Context
* c
= context_list
[i
];
1499 c
->result
= cache
.CreateTransaction(&c
->trans
);
1500 ASSERT_EQ(OK
, c
->result
);
1503 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1506 // Allow all requests to move from the Create queue to the active entry.
1507 base::MessageLoop::current()->RunUntilIdle();
1509 // The first request should be a writer at this point, and the subsequent
1510 // requests should be pending.
1512 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1513 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1514 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1516 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1517 Context
* c
= context_list
[i
];
1518 if (c
->result
== ERR_IO_PENDING
)
1519 c
->result
= c
->callback
.WaitForResult();
1520 // Destroy only the first transaction.
1523 context_list
[i
] = NULL
;
1527 // Complete the rest of the transactions.
1528 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1529 Context
* c
= context_list
[i
];
1530 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1533 // We should have had to re-open the disk entry.
1535 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1536 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1537 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1539 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1540 Context
* c
= context_list
[i
];
1545 // Tests that we can cancel requests that are queued waiting to open the disk
1547 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1548 MockHttpCache cache
;
1550 MockHttpRequest
request(kSimpleGET_Transaction
);
1552 std::vector
<Context
*> context_list
;
1553 const int kNumTransactions
= 5;
1555 for (int i
= 0; i
< kNumTransactions
; i
++) {
1556 context_list
.push_back(new Context());
1557 Context
* c
= context_list
[i
];
1559 c
->result
= cache
.CreateTransaction(&c
->trans
);
1560 ASSERT_EQ(OK
, c
->result
);
1563 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1566 // The first request should be creating the disk cache entry and the others
1567 // should be pending.
1569 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1570 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1571 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1573 // Cancel a request from the pending queue.
1574 delete context_list
[3];
1575 context_list
[3] = NULL
;
1577 // Cancel the request that is creating the entry. This will force the pending
1578 // operations to restart.
1579 delete context_list
[0];
1580 context_list
[0] = NULL
;
1582 // Complete the rest of the transactions.
1583 for (int i
= 1; i
< kNumTransactions
; i
++) {
1584 Context
* c
= context_list
[i
];
1586 c
->result
= c
->callback
.GetResult(c
->result
);
1587 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1591 // We should have had to re-create the disk entry.
1593 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1594 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1595 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1597 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1598 delete context_list
[i
];
1602 // Tests that we can cancel a single request to open a disk cache entry.
1603 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1604 MockHttpCache cache
;
1606 MockHttpRequest
request(kSimpleGET_Transaction
);
1608 Context
* c
= new Context();
1610 c
->result
= cache
.CreateTransaction(&c
->trans
);
1611 ASSERT_EQ(OK
, c
->result
);
1613 c
->result
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1614 EXPECT_EQ(ERR_IO_PENDING
, c
->result
);
1616 // Release the reference that the mock disk cache keeps for this entry, so
1617 // that we test that the http cache handles the cancellation correctly.
1618 cache
.disk_cache()->ReleaseAll();
1621 base::MessageLoop::current()->RunUntilIdle();
1622 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1625 // Tests that we delete/create entries even if multiple requests are queued.
1626 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1627 MockHttpCache cache
;
1629 MockHttpRequest
request(kSimpleGET_Transaction
);
1630 request
.load_flags
= LOAD_BYPASS_CACHE
;
1632 std::vector
<Context
*> context_list
;
1633 const int kNumTransactions
= 5;
1635 for (int i
= 0; i
< kNumTransactions
; i
++) {
1636 context_list
.push_back(new Context());
1637 Context
* c
= context_list
[i
];
1639 c
->result
= cache
.CreateTransaction(&c
->trans
);
1640 ASSERT_EQ(OK
, c
->result
);
1643 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1646 // The first request should be deleting the disk cache entry and the others
1647 // should be pending.
1649 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1650 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1651 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1653 // Complete the transactions.
1654 for (int i
= 0; i
< kNumTransactions
; i
++) {
1655 Context
* c
= context_list
[i
];
1656 c
->result
= c
->callback
.GetResult(c
->result
);
1657 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1660 // We should have had to re-create the disk entry multiple times.
1662 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1663 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1664 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1666 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1667 delete context_list
[i
];
1671 // Tests that a (simulated) timeout allows transactions waiting on the cache
1672 // lock to continue.
1673 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1674 MockHttpCache cache
;
1675 cache
.BypassCacheLock();
1677 MockHttpRequest
request(kSimpleGET_Transaction
);
1679 ASSERT_EQ(OK
, cache
.CreateTransaction(&c1
.trans
));
1680 ASSERT_EQ(ERR_IO_PENDING
,
1681 c1
.trans
->Start(&request
, c1
.callback
.callback(), BoundNetLog()));
1682 ASSERT_EQ(OK
, cache
.CreateTransaction(&c2
.trans
));
1683 ASSERT_EQ(ERR_IO_PENDING
,
1684 c2
.trans
->Start(&request
, c2
.callback
.callback(), BoundNetLog()));
1686 // The second request is queued after the first one.
1688 c2
.callback
.WaitForResult();
1689 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1691 // Complete the first transaction.
1692 c1
.callback
.WaitForResult();
1693 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1696 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1697 MockHttpCache cache
;
1699 // write to the cache
1700 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1702 MockHttpRequest
request(kSimpleGET_Transaction
);
1703 TestCompletionCallback callback
;
1705 scoped_ptr
<HttpTransaction
> trans
;
1706 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
1707 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1708 if (rv
== ERR_IO_PENDING
)
1709 rv
= callback
.WaitForResult();
1712 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
1713 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1714 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1716 // Test that destroying the transaction while it is reading from the cache
1720 // Make sure we pump any pending events, which should include a call to
1721 // HttpCache::Transaction::OnCacheReadCompleted.
1722 base::MessageLoop::current()->RunUntilIdle();
1725 // Tests that we can delete the HttpCache and deal with queued transactions
1726 // ("waiting for the backend" as opposed to Active or Doomed entries).
1727 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1728 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1729 new MockBackendNoCbFactory()));
1731 MockHttpRequest
request(kSimpleGET_Transaction
);
1733 std::vector
<Context
*> context_list
;
1734 const int kNumTransactions
= 5;
1736 for (int i
= 0; i
< kNumTransactions
; i
++) {
1737 context_list
.push_back(new Context());
1738 Context
* c
= context_list
[i
];
1740 c
->result
= cache
->CreateTransaction(&c
->trans
);
1741 ASSERT_EQ(OK
, c
->result
);
1744 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1747 // The first request should be creating the disk cache entry and the others
1748 // should be pending.
1750 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1751 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1752 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1756 // There is not much to do with the transactions at this point... they are
1757 // waiting for a callback that will not fire.
1758 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1759 delete context_list
[i
];
1763 // Tests that we queue requests when initializing the backend.
1764 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1765 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1766 MockHttpCache
cache(factory
);
1768 MockHttpRequest
request0(kSimpleGET_Transaction
);
1769 MockHttpRequest
request1(kTypicalGET_Transaction
);
1770 MockHttpRequest
request2(kETagGET_Transaction
);
1772 std::vector
<Context
*> context_list
;
1773 const int kNumTransactions
= 3;
1775 for (int i
= 0; i
< kNumTransactions
; i
++) {
1776 context_list
.push_back(new Context());
1777 Context
* c
= context_list
[i
];
1779 c
->result
= cache
.CreateTransaction(&c
->trans
);
1780 ASSERT_EQ(OK
, c
->result
);
1783 context_list
[0]->result
= context_list
[0]->trans
->Start(
1784 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1785 context_list
[1]->result
= context_list
[1]->trans
->Start(
1786 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1787 context_list
[2]->result
= context_list
[2]->trans
->Start(
1788 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1790 // Just to make sure that everything is still pending.
1791 base::MessageLoop::current()->RunUntilIdle();
1793 // The first request should be creating the disk cache.
1794 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1796 factory
->FinishCreation();
1798 base::MessageLoop::current()->RunUntilIdle();
1799 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1800 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1802 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1803 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1804 delete context_list
[i
];
1808 // Tests that we can cancel requests that are queued waiting for the backend
1809 // to be initialized.
1810 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1811 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1812 MockHttpCache
cache(factory
);
1814 MockHttpRequest
request0(kSimpleGET_Transaction
);
1815 MockHttpRequest
request1(kTypicalGET_Transaction
);
1816 MockHttpRequest
request2(kETagGET_Transaction
);
1818 std::vector
<Context
*> context_list
;
1819 const int kNumTransactions
= 3;
1821 for (int i
= 0; i
< kNumTransactions
; i
++) {
1822 context_list
.push_back(new Context());
1823 Context
* c
= context_list
[i
];
1825 c
->result
= cache
.CreateTransaction(&c
->trans
);
1826 ASSERT_EQ(OK
, c
->result
);
1829 context_list
[0]->result
= context_list
[0]->trans
->Start(
1830 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1831 context_list
[1]->result
= context_list
[1]->trans
->Start(
1832 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1833 context_list
[2]->result
= context_list
[2]->trans
->Start(
1834 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1836 // Just to make sure that everything is still pending.
1837 base::MessageLoop::current()->RunUntilIdle();
1839 // The first request should be creating the disk cache.
1840 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1842 // Cancel a request from the pending queue.
1843 delete context_list
[1];
1844 context_list
[1] = NULL
;
1846 // Cancel the request that is creating the entry.
1847 delete context_list
[0];
1848 context_list
[0] = NULL
;
1850 // Complete the last transaction.
1851 factory
->FinishCreation();
1853 context_list
[2]->result
=
1854 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1855 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1857 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1858 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1860 delete context_list
[2];
1863 // Tests that we can delete the cache while creating the backend.
1864 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1865 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1866 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1868 MockHttpRequest
request(kSimpleGET_Transaction
);
1870 scoped_ptr
<Context
> c(new Context());
1871 c
->result
= cache
->CreateTransaction(&c
->trans
);
1872 ASSERT_EQ(OK
, c
->result
);
1874 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1876 // Just to make sure that everything is still pending.
1877 base::MessageLoop::current()->RunUntilIdle();
1879 // The request should be creating the disk cache.
1880 EXPECT_FALSE(c
->callback
.have_result());
1882 // We cannot call FinishCreation because the factory itself will go away with
1883 // the cache, so grab the callback and attempt to use it.
1884 CompletionCallback callback
= factory
->callback();
1885 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1888 base::MessageLoop::current()->RunUntilIdle();
1891 callback
.Run(ERR_ABORTED
);
1894 // Tests that we can delete the cache while creating the backend, from within
1895 // one of the callbacks.
1896 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1897 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1898 MockHttpCache
* cache
= new MockHttpCache(factory
);
1900 DeleteCacheCompletionCallback
cb(cache
);
1901 disk_cache::Backend
* backend
;
1902 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1903 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1905 // Now let's queue a regular transaction
1906 MockHttpRequest
request(kSimpleGET_Transaction
);
1908 scoped_ptr
<Context
> c(new Context());
1909 c
->result
= cache
->CreateTransaction(&c
->trans
);
1910 ASSERT_EQ(OK
, c
->result
);
1912 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1914 // And another direct backend request.
1915 TestCompletionCallback cb2
;
1916 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1917 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1919 // Just to make sure that everything is still pending.
1920 base::MessageLoop::current()->RunUntilIdle();
1922 // The request should be queued.
1923 EXPECT_FALSE(c
->callback
.have_result());
1925 // Generate the callback.
1926 factory
->FinishCreation();
1927 rv
= cb
.WaitForResult();
1929 // The cache should be gone by now.
1930 base::MessageLoop::current()->RunUntilIdle();
1931 EXPECT_EQ(OK
, c
->callback
.GetResult(c
->result
));
1932 EXPECT_FALSE(cb2
.have_result());
1935 // Fails only on bots. crbug.com/533640
1936 #if defined(OS_ANDROID)
1937 #define MAYBE_TypicalGET_ConditionalRequest \
1938 DISABLED_TypicalGET_ConditionalRequest
1940 #define MAYBE_TypicalGET_ConditionalRequest TypicalGET_ConditionalRequest
1942 TEST(HttpCache
, MAYBE_TypicalGET_ConditionalRequest
) {
1943 MockHttpCache cache
;
1945 // write to the cache
1946 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
1948 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1949 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1950 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1952 // Get the same URL again, but this time we expect it to result
1953 // in a conditional request.
1954 BoundTestNetLog log
;
1955 LoadTimingInfo load_timing_info
;
1956 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
1957 log
.bound(), &load_timing_info
);
1959 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1960 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1961 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1962 TestLoadTimingNetworkRequest(load_timing_info
);
1965 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo
* request
,
1966 std::string
* response_status
,
1967 std::string
* response_headers
,
1968 std::string
* response_data
) {
1970 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
1971 response_status
->assign("HTTP/1.1 304 Not Modified");
1972 response_headers
->assign(kETagGET_Transaction
.response_headers
);
1973 response_data
->clear();
1976 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
1977 MockHttpCache cache
;
1979 ScopedMockTransaction
transaction(kETagGET_Transaction
);
1981 // write to the cache
1982 RunTransactionTest(cache
.http_cache(), transaction
);
1984 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1985 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1986 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1988 // Get the same URL again, but this time we expect it to result
1989 // in a conditional request.
1990 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
1991 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
1992 BoundTestNetLog log
;
1993 LoadTimingInfo load_timing_info
;
1994 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1997 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1998 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1999 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2000 TestLoadTimingNetworkRequest(load_timing_info
);
2003 class RevalidationServer
{
2005 RevalidationServer() {
2006 s_etag_used_
= false;
2007 s_last_modified_used_
= false;
2010 bool EtagUsed() { return s_etag_used_
; }
2011 bool LastModifiedUsed() { return s_last_modified_used_
; }
2013 static void Handler(const HttpRequestInfo
* request
,
2014 std::string
* response_status
,
2015 std::string
* response_headers
,
2016 std::string
* response_data
);
2019 static bool s_etag_used_
;
2020 static bool s_last_modified_used_
;
2022 bool RevalidationServer::s_etag_used_
= false;
2023 bool RevalidationServer::s_last_modified_used_
= false;
2025 void RevalidationServer::Handler(const HttpRequestInfo
* request
,
2026 std::string
* response_status
,
2027 std::string
* response_headers
,
2028 std::string
* response_data
) {
2029 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
))
2030 s_etag_used_
= true;
2032 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfModifiedSince
)) {
2033 s_last_modified_used_
= true;
2036 if (s_etag_used_
|| s_last_modified_used_
) {
2037 response_status
->assign("HTTP/1.1 304 Not Modified");
2038 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2039 response_data
->clear();
2041 response_status
->assign(kTypicalGET_Transaction
.status
);
2042 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2043 response_data
->assign(kTypicalGET_Transaction
.data
);
2047 // Tests revalidation after a vary match.
2048 TEST(HttpCache
, GET_ValidateCache_VaryMatch
) {
2049 MockHttpCache cache
;
2051 // Write to the cache.
2052 MockTransaction
transaction(kTypicalGET_Transaction
);
2053 transaction
.request_headers
= "Foo: bar\r\n";
2054 transaction
.response_headers
=
2055 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2056 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2058 "Cache-Control: max-age=0\n"
2060 AddMockTransaction(&transaction
);
2061 RunTransactionTest(cache
.http_cache(), transaction
);
2063 // Read from the cache.
2064 RevalidationServer server
;
2065 transaction
.handler
= server
.Handler
;
2066 BoundTestNetLog log
;
2067 LoadTimingInfo load_timing_info
;
2068 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2071 EXPECT_TRUE(server
.EtagUsed());
2072 EXPECT_TRUE(server
.LastModifiedUsed());
2073 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2074 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2075 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2076 TestLoadTimingNetworkRequest(load_timing_info
);
2077 RemoveMockTransaction(&transaction
);
2080 // Tests revalidation after a vary mismatch if etag is present.
2081 TEST(HttpCache
, GET_ValidateCache_VaryMismatch
) {
2082 MockHttpCache cache
;
2084 // Write to the cache.
2085 MockTransaction
transaction(kTypicalGET_Transaction
);
2086 transaction
.request_headers
= "Foo: bar\r\n";
2087 transaction
.response_headers
=
2088 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2089 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2091 "Cache-Control: max-age=0\n"
2093 AddMockTransaction(&transaction
);
2094 RunTransactionTest(cache
.http_cache(), transaction
);
2096 // Read from the cache and revalidate the entry.
2097 RevalidationServer server
;
2098 transaction
.handler
= server
.Handler
;
2099 transaction
.request_headers
= "Foo: none\r\n";
2100 BoundTestNetLog log
;
2101 LoadTimingInfo load_timing_info
;
2102 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2105 EXPECT_TRUE(server
.EtagUsed());
2106 EXPECT_FALSE(server
.LastModifiedUsed());
2107 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2108 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2109 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2110 TestLoadTimingNetworkRequest(load_timing_info
);
2111 RemoveMockTransaction(&transaction
);
2114 // Tests lack of revalidation after a vary mismatch and no etag.
2115 TEST(HttpCache
, GET_DontValidateCache_VaryMismatch
) {
2116 MockHttpCache cache
;
2118 // Write to the cache.
2119 MockTransaction
transaction(kTypicalGET_Transaction
);
2120 transaction
.request_headers
= "Foo: bar\r\n";
2121 transaction
.response_headers
=
2122 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2123 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2124 "Cache-Control: max-age=0\n"
2126 AddMockTransaction(&transaction
);
2127 RunTransactionTest(cache
.http_cache(), transaction
);
2129 // Read from the cache and don't revalidate the entry.
2130 RevalidationServer server
;
2131 transaction
.handler
= server
.Handler
;
2132 transaction
.request_headers
= "Foo: none\r\n";
2133 BoundTestNetLog log
;
2134 LoadTimingInfo load_timing_info
;
2135 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2138 EXPECT_FALSE(server
.EtagUsed());
2139 EXPECT_FALSE(server
.LastModifiedUsed());
2140 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2141 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2142 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2143 TestLoadTimingNetworkRequest(load_timing_info
);
2144 RemoveMockTransaction(&transaction
);
2147 // Tests that a new vary header provided when revalidating an entry is saved.
2148 TEST(HttpCache
, GET_ValidateCache_VaryMatch_UpdateVary
) {
2149 MockHttpCache cache
;
2151 // Write to the cache.
2152 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2153 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2154 transaction
.response_headers
=
2156 "Cache-Control: max-age=0\n"
2158 RunTransactionTest(cache
.http_cache(), transaction
);
2160 // Validate the entry and change the vary field in the response.
2161 transaction
.request_headers
= "Foo: bar\r\n Name: none\r\n";
2162 transaction
.status
= "HTTP/1.1 304 Not Modified";
2163 transaction
.response_headers
=
2165 "Cache-Control: max-age=3600\n"
2167 RunTransactionTest(cache
.http_cache(), transaction
);
2169 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2170 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2171 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2173 // Make sure that the ActiveEntry is gone.
2174 base::RunLoop().RunUntilIdle();
2176 // Generate a vary mismatch.
2177 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2178 RunTransactionTest(cache
.http_cache(), transaction
);
2180 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2181 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2182 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2185 // Tests that new request headers causing a vary mismatch are paired with the
2186 // new response when the server says the old response can be used.
2187 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_UpdateRequestHeader
) {
2188 MockHttpCache cache
;
2190 // Write to the cache.
2191 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2192 transaction
.request_headers
= "Foo: bar\r\n";
2193 transaction
.response_headers
=
2195 "Cache-Control: max-age=3600\n"
2197 RunTransactionTest(cache
.http_cache(), transaction
);
2199 // Vary-mismatch validation receives 304.
2200 transaction
.request_headers
= "Foo: none\r\n";
2201 transaction
.status
= "HTTP/1.1 304 Not Modified";
2202 RunTransactionTest(cache
.http_cache(), transaction
);
2204 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2205 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2206 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2208 // Make sure that the ActiveEntry is gone.
2209 base::RunLoop().RunUntilIdle();
2211 // Generate a vary mismatch.
2212 transaction
.request_headers
= "Foo: bar\r\n";
2213 RunTransactionTest(cache
.http_cache(), transaction
);
2215 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2216 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2217 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2220 // Tests that a 304 without vary headers doesn't delete the previously stored
2221 // vary data after a vary match revalidation.
2222 TEST(HttpCache
, GET_ValidateCache_VaryMatch_DontDeleteVary
) {
2223 MockHttpCache cache
;
2225 // Write to the cache.
2226 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2227 transaction
.request_headers
= "Foo: bar\r\n";
2228 transaction
.response_headers
=
2230 "Cache-Control: max-age=0\n"
2232 RunTransactionTest(cache
.http_cache(), transaction
);
2234 // Validate the entry and remove the vary field in the response.
2235 transaction
.status
= "HTTP/1.1 304 Not Modified";
2236 transaction
.response_headers
=
2238 "Cache-Control: max-age=3600\n";
2239 RunTransactionTest(cache
.http_cache(), transaction
);
2241 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2242 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2243 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2245 // Make sure that the ActiveEntry is gone.
2246 base::RunLoop().RunUntilIdle();
2248 // Generate a vary mismatch.
2249 transaction
.request_headers
= "Foo: none\r\n";
2250 RunTransactionTest(cache
.http_cache(), transaction
);
2252 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2253 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2254 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2257 // Tests that a 304 without vary headers doesn't delete the previously stored
2258 // vary data after a vary mismatch.
2259 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_DontDeleteVary
) {
2260 MockHttpCache cache
;
2262 // Write to the cache.
2263 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2264 transaction
.request_headers
= "Foo: bar\r\n";
2265 transaction
.response_headers
=
2267 "Cache-Control: max-age=3600\n"
2269 RunTransactionTest(cache
.http_cache(), transaction
);
2271 // Vary-mismatch validation receives 304 and no vary header.
2272 transaction
.request_headers
= "Foo: none\r\n";
2273 transaction
.status
= "HTTP/1.1 304 Not Modified";
2274 transaction
.response_headers
=
2276 "Cache-Control: max-age=3600\n";
2277 RunTransactionTest(cache
.http_cache(), transaction
);
2279 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2280 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2281 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2283 // Make sure that the ActiveEntry is gone.
2284 base::RunLoop().RunUntilIdle();
2286 // Generate a vary mismatch.
2287 transaction
.request_headers
= "Foo: bar\r\n";
2288 RunTransactionTest(cache
.http_cache(), transaction
);
2290 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2291 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2292 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2295 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo
* request
,
2296 std::string
* response_status
,
2297 std::string
* response_headers
,
2298 std::string
* response_data
) {
2300 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2303 TEST(HttpCache
, ETagGET_Http10
) {
2304 MockHttpCache cache
;
2306 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2307 transaction
.status
= "HTTP/1.0 200 OK";
2309 // Write to the cache.
2310 RunTransactionTest(cache
.http_cache(), transaction
);
2312 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2313 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2314 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2316 // Get the same URL again, without generating a conditional request.
2317 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2318 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2319 RunTransactionTest(cache
.http_cache(), transaction
);
2321 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2322 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2323 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2326 TEST(HttpCache
, ETagGET_Http10_Range
) {
2327 MockHttpCache cache
;
2329 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2330 transaction
.status
= "HTTP/1.0 200 OK";
2332 // Write to the cache.
2333 RunTransactionTest(cache
.http_cache(), transaction
);
2335 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2336 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2337 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2339 // Get the same URL again, but use a byte range request.
2340 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2341 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2342 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2343 RunTransactionTest(cache
.http_cache(), transaction
);
2345 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2346 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2347 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2350 static void ETagGet_ConditionalRequest_NoStore_Handler(
2351 const HttpRequestInfo
* request
,
2352 std::string
* response_status
,
2353 std::string
* response_headers
,
2354 std::string
* response_data
) {
2356 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2357 response_status
->assign("HTTP/1.1 304 Not Modified");
2358 response_headers
->assign("Cache-Control: no-store\n");
2359 response_data
->clear();
2362 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2363 MockHttpCache cache
;
2365 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2367 // Write to the cache.
2368 RunTransactionTest(cache
.http_cache(), transaction
);
2370 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2371 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2372 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2374 // Get the same URL again, but this time we expect it to result
2375 // in a conditional request.
2376 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2377 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2378 RunTransactionTest(cache
.http_cache(), transaction
);
2380 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2381 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2382 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2384 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2386 // Write to the cache again. This should create a new entry.
2387 RunTransactionTest(cache
.http_cache(), transaction2
);
2389 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2390 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2391 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2394 // Helper that does 4 requests using HttpCache:
2396 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2397 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2398 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2400 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2402 static void ConditionalizedRequestUpdatesCacheHelper(
2403 const Response
& net_response_1
,
2404 const Response
& net_response_2
,
2405 const Response
& cached_response_2
,
2406 const char* extra_request_headers
) {
2407 MockHttpCache cache
;
2409 // The URL we will be requesting.
2410 const char kUrl
[] = "http://foobar.com/main.css";
2412 // Junk network response.
2413 static const Response kUnexpectedResponse
= {
2414 "HTTP/1.1 500 Unexpected",
2415 "Server: unexpected_header",
2419 // We will control the network layer's responses for |kUrl| using
2420 // |mock_network_response|.
2421 MockTransaction mock_network_response
= { 0 };
2422 mock_network_response
.url
= kUrl
;
2423 AddMockTransaction(&mock_network_response
);
2425 // Request |kUrl| for the first time. It should hit the network and
2426 // receive |kNetResponse1|, which it saves into the HTTP cache.
2428 MockTransaction request
= { 0 };
2430 request
.method
= "GET";
2431 request
.request_headers
= "";
2433 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2434 net_response_1
.AssignTo(&request
); // Expected result.
2436 std::string response_headers
;
2437 RunTransactionTestWithResponse(
2438 cache
.http_cache(), request
, &response_headers
);
2440 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2441 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2442 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2443 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2445 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2446 // cache, so we don't hit the network.
2448 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2450 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2451 net_response_1
.AssignTo(&request
); // Expected result.
2453 RunTransactionTestWithResponse(
2454 cache
.http_cache(), request
, &response_headers
);
2456 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2457 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2458 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2459 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2461 // Request |kUrl| yet again, but this time give the request an
2462 // "If-Modified-Since" header. This will cause the request to re-hit the
2463 // network. However now the network response is going to be
2464 // different -- this simulates a change made to the CSS file.
2466 request
.request_headers
= extra_request_headers
;
2467 request
.load_flags
= LOAD_NORMAL
;
2469 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2470 net_response_2
.AssignTo(&request
); // Expected result.
2472 RunTransactionTestWithResponse(
2473 cache
.http_cache(), request
, &response_headers
);
2475 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2476 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2477 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2478 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2480 // Finally, request |kUrl| again. This request should be serviced from
2481 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2482 // and NOT |kNetResponse1|. The previous step should have replaced the
2483 // value in the cache with the modified response.
2485 request
.request_headers
= "";
2486 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2488 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2489 cached_response_2
.AssignTo(&request
); // Expected result.
2491 RunTransactionTestWithResponse(
2492 cache
.http_cache(), request
, &response_headers
);
2494 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2495 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2496 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2497 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2499 RemoveMockTransaction(&mock_network_response
);
2502 // Check that when an "if-modified-since" header is attached
2503 // to the request, the result still updates the cached entry.
2504 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2505 // First network response for |kUrl|.
2506 static const Response kNetResponse1
= {
2508 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2509 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2513 // Second network response for |kUrl|.
2514 static const Response kNetResponse2
= {
2516 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2517 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2521 const char extra_headers
[] =
2522 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2524 ConditionalizedRequestUpdatesCacheHelper(
2525 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2528 // Check that when an "if-none-match" header is attached
2529 // to the request, the result updates the cached entry.
2530 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2531 // First network response for |kUrl|.
2532 static const Response kNetResponse1
= {
2534 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2536 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2540 // Second network response for |kUrl|.
2541 static const Response kNetResponse2
= {
2543 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2545 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2549 const char extra_headers
[] = "If-None-Match: \"ETAG1\"\r\n";
2551 ConditionalizedRequestUpdatesCacheHelper(
2552 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2555 // Check that when an "if-modified-since" header is attached
2556 // to a request, the 304 (not modified result) result updates the cached
2557 // headers, and the 304 response is returned rather than the cached response.
2558 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2559 // First network response for |kUrl|.
2560 static const Response kNetResponse1
= {
2562 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2564 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2568 // Second network response for |kUrl|.
2569 static const Response kNetResponse2
= {
2570 "HTTP/1.1 304 Not Modified",
2571 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2573 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2577 static const Response kCachedResponse2
= {
2579 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2581 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2585 const char extra_headers
[] =
2586 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2588 ConditionalizedRequestUpdatesCacheHelper(
2589 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2592 // Test that when doing an externally conditionalized if-modified-since
2593 // and there is no corresponding cache entry, a new cache entry is NOT
2594 // created (304 response).
2595 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2596 MockHttpCache cache
;
2598 const char kUrl
[] = "http://foobar.com/main.css";
2600 static const Response kNetResponse
= {
2601 "HTTP/1.1 304 Not Modified",
2602 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2603 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2607 const char kExtraRequestHeaders
[] =
2608 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2610 // We will control the network layer's responses for |kUrl| using
2611 // |mock_network_response|.
2612 MockTransaction mock_network_response
= { 0 };
2613 mock_network_response
.url
= kUrl
;
2614 AddMockTransaction(&mock_network_response
);
2616 MockTransaction request
= { 0 };
2618 request
.method
= "GET";
2619 request
.request_headers
= kExtraRequestHeaders
;
2621 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2622 kNetResponse
.AssignTo(&request
); // Expected result.
2624 std::string response_headers
;
2625 RunTransactionTestWithResponse(
2626 cache
.http_cache(), request
, &response_headers
);
2628 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2629 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2630 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2631 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2633 RemoveMockTransaction(&mock_network_response
);
2636 // Test that when doing an externally conditionalized if-modified-since
2637 // and there is no corresponding cache entry, a new cache entry is NOT
2638 // created (200 response).
2639 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2640 MockHttpCache cache
;
2642 const char kUrl
[] = "http://foobar.com/main.css";
2644 static const Response kNetResponse
= {
2646 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2647 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2651 const char kExtraRequestHeaders
[] =
2652 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2654 // We will control the network layer's responses for |kUrl| using
2655 // |mock_network_response|.
2656 MockTransaction mock_network_response
= { 0 };
2657 mock_network_response
.url
= kUrl
;
2658 AddMockTransaction(&mock_network_response
);
2660 MockTransaction request
= { 0 };
2662 request
.method
= "GET";
2663 request
.request_headers
= kExtraRequestHeaders
;
2665 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2666 kNetResponse
.AssignTo(&request
); // Expected result.
2668 std::string response_headers
;
2669 RunTransactionTestWithResponse(
2670 cache
.http_cache(), request
, &response_headers
);
2672 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2673 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2674 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2675 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2677 RemoveMockTransaction(&mock_network_response
);
2680 // Test that when doing an externally conditionalized if-modified-since
2681 // if the date does not match the cache entry's last-modified date,
2682 // then we do NOT use the response (304) to update the cache.
2683 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2684 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
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 // This is two days in the future from the original response's last-modified
2704 const char kExtraRequestHeaders
[] =
2705 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2707 ConditionalizedRequestUpdatesCacheHelper(
2708 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2711 // Test that when doing an externally conditionalized if-none-match
2712 // if the etag does not match the cache entry's etag, then we do not use the
2713 // response (304) to update the cache.
2714 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2715 static const Response kNetResponse1
= {
2717 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2719 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2723 // Second network response for |kUrl|.
2724 static const Response kNetResponse2
= {
2725 "HTTP/1.1 304 Not Modified",
2726 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2728 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2732 // Different etag from original response.
2733 const char kExtraRequestHeaders
[] = "If-None-Match: \"Foo2\"\r\n";
2735 ConditionalizedRequestUpdatesCacheHelper(
2736 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2739 // Test that doing an externally conditionalized request with both if-none-match
2740 // and if-modified-since updates the cache.
2741 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2742 static const Response kNetResponse1
= {
2744 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2746 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2750 // Second network response for |kUrl|.
2751 static const Response kNetResponse2
= {
2753 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2755 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2759 const char kExtraRequestHeaders
[] =
2760 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2761 "If-None-Match: \"Foo1\"\r\n";
2763 ConditionalizedRequestUpdatesCacheHelper(
2764 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2767 // Test that doing an externally conditionalized request with both if-none-match
2768 // and if-modified-since does not update the cache with only one match.
2769 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2770 static const Response kNetResponse1
= {
2772 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2774 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2778 // Second network response for |kUrl|.
2779 static const Response kNetResponse2
= {
2781 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2783 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2787 // The etag doesn't match what we have stored.
2788 const char kExtraRequestHeaders
[] =
2789 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2790 "If-None-Match: \"Foo2\"\r\n";
2792 ConditionalizedRequestUpdatesCacheHelper(
2793 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2796 // Test that doing an externally conditionalized request with both if-none-match
2797 // and if-modified-since does not update the cache with only one match.
2798 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2799 static const Response kNetResponse1
= {
2801 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2803 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2807 // Second network response for |kUrl|.
2808 static const Response kNetResponse2
= {
2810 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2812 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2816 // The modification date doesn't match what we have stored.
2817 const char kExtraRequestHeaders
[] =
2818 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2819 "If-None-Match: \"Foo1\"\r\n";
2821 ConditionalizedRequestUpdatesCacheHelper(
2822 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2825 TEST(HttpCache
, UrlContainingHash
) {
2826 MockHttpCache cache
;
2828 // Do a typical GET request -- should write an entry into our cache.
2829 MockTransaction
trans(kTypicalGET_Transaction
);
2830 RunTransactionTest(cache
.http_cache(), trans
);
2832 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2833 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2834 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2836 // Request the same URL, but this time with a reference section (hash).
2837 // Since the cache key strips the hash sections, this should be a cache hit.
2838 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2839 trans
.url
= url_with_hash
.c_str();
2840 trans
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2842 RunTransactionTest(cache
.http_cache(), trans
);
2844 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2845 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2846 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2849 // Tests that we skip the cache for POST requests that do not have an upload
2851 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2852 MockHttpCache cache
;
2854 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2856 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2857 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2858 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2861 // Tests POST handling with a disabled cache (no DCHECK).
2862 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2863 MockHttpCache cache
;
2864 cache
.http_cache()->set_mode(HttpCache::Mode::DISABLE
);
2866 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2868 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2869 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2870 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2873 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2874 MockHttpCache cache
;
2876 MockTransaction
transaction(kSimplePOST_Transaction
);
2877 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2879 MockHttpRequest
request(transaction
);
2880 TestCompletionCallback callback
;
2882 scoped_ptr
<HttpTransaction
> trans
;
2883 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
2884 ASSERT_TRUE(trans
.get());
2886 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
2887 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
2891 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2892 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2893 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2896 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2897 MockHttpCache cache
;
2899 // Test that we hit the cache for POST requests.
2901 MockTransaction
transaction(kSimplePOST_Transaction
);
2903 const int64 kUploadId
= 1; // Just a dummy value.
2905 ScopedVector
<UploadElementReader
> element_readers
;
2906 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2907 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2909 MockHttpRequest
request(transaction
);
2910 request
.upload_data_stream
= &upload_data_stream
;
2912 // Populate the cache.
2913 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2915 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2916 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2917 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2920 request
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2921 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2923 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2924 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2925 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2928 // Test that we don't hit the cache for POST requests if there is a byte range.
2929 TEST(HttpCache
, SimplePOST_WithRanges
) {
2930 MockHttpCache cache
;
2932 MockTransaction
transaction(kSimplePOST_Transaction
);
2933 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2935 const int64 kUploadId
= 1; // Just a dummy value.
2937 ScopedVector
<UploadElementReader
> element_readers
;
2938 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2939 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2942 MockHttpRequest
request(transaction
);
2943 request
.upload_data_stream
= &upload_data_stream
;
2945 // Attempt to populate the cache.
2946 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2948 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2949 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2950 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2953 // Tests that a POST is cached separately from a previously cached GET.
2954 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2955 MockHttpCache cache
;
2957 ScopedVector
<UploadElementReader
> element_readers
;
2958 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2959 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2961 MockTransaction
transaction(kSimplePOST_Transaction
);
2962 MockHttpRequest
req1(transaction
);
2963 req1
.upload_data_stream
= &upload_data_stream
;
2965 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2967 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2968 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2969 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2971 transaction
.method
= "GET";
2972 MockHttpRequest
req2(transaction
);
2974 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2976 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2977 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2978 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2981 // Tests that a successful POST invalidates a previously cached GET.
2982 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2983 MockHttpCache cache
;
2985 MockTransaction
transaction(kSimpleGET_Transaction
);
2986 AddMockTransaction(&transaction
);
2987 MockHttpRequest
req1(transaction
);
2989 // Attempt to populate the cache.
2990 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2992 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2993 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2994 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2996 ScopedVector
<UploadElementReader
> element_readers
;
2997 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2998 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3000 transaction
.method
= "POST";
3001 transaction
.status
= "HTTP/1.1 205 No Content";
3002 MockHttpRequest
req2(transaction
);
3003 req2
.upload_data_stream
= &upload_data_stream
;
3005 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3007 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3008 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3009 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3011 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3013 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3014 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3015 EXPECT_EQ(3, cache
.disk_cache()->create_count());
3016 RemoveMockTransaction(&transaction
);
3019 // Tests that a successful POST invalidates a previously cached GET, even when
3020 // there is no upload identifier.
3021 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
3022 MockHttpCache cache
;
3024 MockTransaction
transaction(kSimpleGET_Transaction
);
3025 AddMockTransaction(&transaction
);
3026 MockHttpRequest
req1(transaction
);
3028 // Attempt to populate the cache.
3029 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3031 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3032 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3033 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3035 ScopedVector
<UploadElementReader
> element_readers
;
3036 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3037 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3039 transaction
.method
= "POST";
3040 transaction
.status
= "HTTP/1.1 205 No Content";
3041 MockHttpRequest
req2(transaction
);
3042 req2
.upload_data_stream
= &upload_data_stream
;
3044 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3046 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3047 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3048 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3050 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3052 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3053 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3054 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3055 RemoveMockTransaction(&transaction
);
3058 // Tests that processing a POST before creating the backend doesn't crash.
3059 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
3060 // This will initialize a cache object with NULL backend.
3061 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
3062 factory
->set_fail(true);
3063 factory
->FinishCreation();
3064 MockHttpCache
cache(factory
);
3066 ScopedVector
<UploadElementReader
> element_readers
;
3067 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3068 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3070 MockTransaction
transaction(kSimplePOST_Transaction
);
3071 AddMockTransaction(&transaction
);
3072 MockHttpRequest
req(transaction
);
3073 req
.upload_data_stream
= &upload_data_stream
;
3075 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
3077 RemoveMockTransaction(&transaction
);
3080 // Tests that we don't invalidate entries as a result of a failed POST.
3081 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
3082 MockHttpCache cache
;
3084 MockTransaction
transaction(kSimpleGET_Transaction
);
3085 AddMockTransaction(&transaction
);
3086 MockHttpRequest
req1(transaction
);
3088 // Attempt to populate the cache.
3089 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3091 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3092 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3093 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3095 ScopedVector
<UploadElementReader
> element_readers
;
3096 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3097 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3099 transaction
.method
= "POST";
3100 transaction
.status
= "HTTP/1.1 100 Continue";
3101 MockHttpRequest
req2(transaction
);
3102 req2
.upload_data_stream
= &upload_data_stream
;
3104 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3106 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3107 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3108 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3110 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3112 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3113 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3114 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3115 RemoveMockTransaction(&transaction
);
3118 // Tests that a HEAD request is not cached by itself.
3119 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3120 MockHttpCache cache
;
3121 MockTransaction
transaction(kSimplePOST_Transaction
);
3122 AddMockTransaction(&transaction
);
3123 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3124 transaction
.method
= "HEAD";
3126 MockHttpRequest
request(transaction
);
3127 TestCompletionCallback callback
;
3129 scoped_ptr
<HttpTransaction
> trans
;
3130 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
3131 ASSERT_TRUE(trans
.get());
3133 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
3134 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
3138 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3139 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3140 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3141 RemoveMockTransaction(&transaction
);
3144 // Tests that a HEAD request is served from a cached GET.
3145 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3146 MockHttpCache cache
;
3147 MockTransaction
transaction(kSimpleGET_Transaction
);
3148 AddMockTransaction(&transaction
);
3150 // Populate the cache.
3151 RunTransactionTest(cache
.http_cache(), transaction
);
3153 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3154 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3155 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3158 transaction
.method
= "HEAD";
3159 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3160 transaction
.data
= "";
3161 RunTransactionTest(cache
.http_cache(), transaction
);
3163 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3164 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3165 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3166 RemoveMockTransaction(&transaction
);
3169 // Tests that a read-only request served from the cache preserves CL.
3170 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3171 MockHttpCache cache
;
3172 MockTransaction
transaction(kSimpleGET_Transaction
);
3173 AddMockTransaction(&transaction
);
3174 transaction
.response_headers
= "Content-Length: 42\n";
3176 // Populate the cache.
3177 RunTransactionTest(cache
.http_cache(), transaction
);
3180 transaction
.method
= "HEAD";
3181 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3182 transaction
.data
= "";
3183 std::string headers
;
3185 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3187 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3188 RemoveMockTransaction(&transaction
);
3191 // Tests that a read-write request served from the cache preserves CL.
3192 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3193 MockHttpCache cache
;
3194 MockTransaction
transaction(kETagGET_Transaction
);
3195 AddMockTransaction(&transaction
);
3196 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3197 server_headers
.append("Content-Length: 42\n");
3198 transaction
.response_headers
= server_headers
.data();
3200 // Populate the cache.
3201 RunTransactionTest(cache
.http_cache(), transaction
);
3204 transaction
.method
= "HEAD";
3205 transaction
.data
= "";
3206 std::string headers
;
3208 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3210 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3211 RemoveMockTransaction(&transaction
);
3214 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3215 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3216 MockHttpCache cache
;
3217 MockTransaction
transaction(kSimpleGET_Transaction
);
3218 AddMockTransaction(&transaction
);
3220 // Populate the cache.
3221 RunTransactionTest(cache
.http_cache(), transaction
);
3224 transaction
.method
= "HEAD";
3225 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3226 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3227 transaction
.return_code
= ERR_CACHE_MISS
;
3228 RunTransactionTest(cache
.http_cache(), transaction
);
3230 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3231 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3232 RemoveMockTransaction(&transaction
);
3235 // Tests that a HEAD request can be served from a partialy cached resource.
3236 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3237 MockHttpCache cache
;
3238 AddMockTransaction(&kRangeGET_TransactionOK
);
3240 // Write to the cache (40-49).
3241 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3242 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3244 MockTransaction
transaction(kSimpleGET_Transaction
);
3246 transaction
.url
= kRangeGET_TransactionOK
.url
;
3247 transaction
.method
= "HEAD";
3248 transaction
.data
= "";
3249 AddMockTransaction(&transaction
);
3250 std::string headers
;
3253 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3255 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3256 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3257 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3258 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3259 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3260 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3261 RemoveMockTransaction(&transaction
);
3264 // Tests that a HEAD request can be served from a truncated resource.
3265 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3266 MockHttpCache cache
;
3267 AddMockTransaction(&kRangeGET_TransactionOK
);
3269 std::string
raw_headers("HTTP/1.1 200 OK\n"
3270 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3272 "Accept-Ranges: bytes\n"
3273 "Content-Length: 80\n");
3274 CreateTruncatedEntry(raw_headers
, &cache
);
3275 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3277 MockTransaction
transaction(kSimpleGET_Transaction
);
3279 transaction
.url
= kRangeGET_TransactionOK
.url
;
3280 transaction
.method
= "HEAD";
3281 transaction
.data
= "";
3282 AddMockTransaction(&transaction
);
3283 std::string headers
;
3286 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3288 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3289 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3290 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3291 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3292 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3293 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3294 RemoveMockTransaction(&transaction
);
3297 // Tests that a HEAD request updates the cached response.
3298 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3299 MockHttpCache cache
;
3300 MockTransaction
transaction(kTypicalGET_Transaction
);
3301 AddMockTransaction(&transaction
);
3303 // Populate the cache.
3304 RunTransactionTest(cache
.http_cache(), transaction
);
3306 // Update the cache.
3307 transaction
.method
= "HEAD";
3308 transaction
.response_headers
= "Foo: bar\n";
3309 transaction
.data
= "";
3310 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3311 std::string headers
;
3312 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3313 RemoveMockTransaction(&transaction
);
3315 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3316 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3318 MockTransaction
transaction2(kTypicalGET_Transaction
);
3319 AddMockTransaction(&transaction2
);
3321 // Make sure we are done with the previous transaction.
3322 base::MessageLoop::current()->RunUntilIdle();
3324 // Load from the cache.
3325 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3326 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3328 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3329 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3330 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3331 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3332 RemoveMockTransaction(&transaction2
);
3335 // Tests that an externally conditionalized HEAD request updates the cache.
3336 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3337 MockHttpCache cache
;
3338 MockTransaction
transaction(kTypicalGET_Transaction
);
3339 AddMockTransaction(&transaction
);
3341 // Populate the cache.
3342 RunTransactionTest(cache
.http_cache(), transaction
);
3344 // Update the cache.
3345 transaction
.method
= "HEAD";
3346 transaction
.request_headers
=
3347 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3348 transaction
.response_headers
= "Foo: bar\n";
3349 transaction
.data
= "";
3350 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3351 std::string headers
;
3352 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3353 RemoveMockTransaction(&transaction
);
3355 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3356 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3358 MockTransaction
transaction2(kTypicalGET_Transaction
);
3359 AddMockTransaction(&transaction2
);
3361 // Make sure we are done with the previous transaction.
3362 base::MessageLoop::current()->RunUntilIdle();
3364 // Load from the cache.
3365 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3366 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3368 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3369 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3370 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3371 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3372 RemoveMockTransaction(&transaction2
);
3375 // Tests that a HEAD request invalidates an old cached entry.
3376 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3377 MockHttpCache cache
;
3378 MockTransaction
transaction(kTypicalGET_Transaction
);
3379 AddMockTransaction(&transaction
);
3381 // Populate the cache.
3382 RunTransactionTest(cache
.http_cache(), transaction
);
3384 // Update the cache.
3385 transaction
.method
= "HEAD";
3386 transaction
.data
= "";
3387 RunTransactionTest(cache
.http_cache(), transaction
);
3388 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3390 // Load from the cache.
3391 transaction
.method
= "GET";
3392 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3393 transaction
.return_code
= ERR_CACHE_MISS
;
3394 RunTransactionTest(cache
.http_cache(), transaction
);
3396 RemoveMockTransaction(&transaction
);
3399 // Tests that we do not cache the response of a PUT.
3400 TEST(HttpCache
, SimplePUT_Miss
) {
3401 MockHttpCache cache
;
3403 MockTransaction
transaction(kSimplePOST_Transaction
);
3404 transaction
.method
= "PUT";
3406 ScopedVector
<UploadElementReader
> element_readers
;
3407 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3408 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3410 MockHttpRequest
request(transaction
);
3411 request
.upload_data_stream
= &upload_data_stream
;
3413 // Attempt to populate the cache.
3414 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3416 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3417 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3418 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3421 // Tests that we invalidate entries as a result of a PUT.
3422 TEST(HttpCache
, SimplePUT_Invalidate
) {
3423 MockHttpCache cache
;
3425 MockTransaction
transaction(kSimpleGET_Transaction
);
3426 MockHttpRequest
req1(transaction
);
3428 // Attempt to populate the cache.
3429 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3431 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3432 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3433 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3435 ScopedVector
<UploadElementReader
> element_readers
;
3436 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3437 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3439 transaction
.method
= "PUT";
3440 MockHttpRequest
req2(transaction
);
3441 req2
.upload_data_stream
= &upload_data_stream
;
3443 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3445 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3446 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3447 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3449 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3451 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3452 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3453 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3456 // Tests that we invalidate entries as a result of a PUT.
3457 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3458 MockHttpCache cache
;
3460 MockTransaction
transaction(kSimpleGET_Transaction
);
3461 AddMockTransaction(&transaction
);
3462 MockHttpRequest
req1(transaction
);
3464 // Attempt to populate the cache.
3465 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3467 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3468 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3469 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3471 ScopedVector
<UploadElementReader
> element_readers
;
3472 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3473 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3475 transaction
.method
= "PUT";
3476 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3477 MockHttpRequest
req2(transaction
);
3478 req2
.upload_data_stream
= &upload_data_stream
;
3480 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3482 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3483 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3484 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3486 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3488 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3489 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3490 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3491 RemoveMockTransaction(&transaction
);
3494 // Tests that we don't invalidate entries as a result of a failed PUT.
3495 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3496 MockHttpCache cache
;
3498 MockTransaction
transaction(kSimpleGET_Transaction
);
3499 AddMockTransaction(&transaction
);
3500 MockHttpRequest
req1(transaction
);
3502 // Attempt to populate the cache.
3503 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3505 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3506 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3507 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3509 ScopedVector
<UploadElementReader
> element_readers
;
3510 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3511 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3513 transaction
.method
= "PUT";
3514 transaction
.status
= "HTTP/1.1 404 Not Found";
3515 MockHttpRequest
req2(transaction
);
3516 req2
.upload_data_stream
= &upload_data_stream
;
3518 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3520 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3521 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3522 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3524 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3526 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3527 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3528 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3529 RemoveMockTransaction(&transaction
);
3532 // Tests that we do not cache the response of a DELETE.
3533 TEST(HttpCache
, SimpleDELETE_Miss
) {
3534 MockHttpCache cache
;
3536 MockTransaction
transaction(kSimplePOST_Transaction
);
3537 transaction
.method
= "DELETE";
3539 ScopedVector
<UploadElementReader
> element_readers
;
3540 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3541 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3543 MockHttpRequest
request(transaction
);
3544 request
.upload_data_stream
= &upload_data_stream
;
3546 // Attempt to populate the cache.
3547 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3549 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3550 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3551 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3554 // Tests that we invalidate entries as a result of a DELETE.
3555 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3556 MockHttpCache cache
;
3558 MockTransaction
transaction(kSimpleGET_Transaction
);
3559 MockHttpRequest
req1(transaction
);
3561 // Attempt to populate the cache.
3562 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3564 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3565 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3566 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3568 ScopedVector
<UploadElementReader
> element_readers
;
3569 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3570 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3572 transaction
.method
= "DELETE";
3573 MockHttpRequest
req2(transaction
);
3574 req2
.upload_data_stream
= &upload_data_stream
;
3576 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
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 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3584 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3585 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3586 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3589 // Tests that we invalidate entries as a result of a DELETE.
3590 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3591 MockHttpCache cache
;
3593 MockTransaction
transaction(kSimpleGET_Transaction
);
3594 AddMockTransaction(&transaction
);
3596 // Attempt to populate the cache.
3597 RunTransactionTest(cache
.http_cache(), transaction
);
3599 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3600 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3601 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3603 transaction
.method
= "DELETE";
3604 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3606 RunTransactionTest(cache
.http_cache(), transaction
);
3608 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3609 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3610 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3612 transaction
.method
= "GET";
3613 RunTransactionTest(cache
.http_cache(), transaction
);
3615 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3616 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3617 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3618 RemoveMockTransaction(&transaction
);
3621 // Tests that we don't invalidate entries as a result of a failed DELETE.
3622 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3623 MockHttpCache cache
;
3625 MockTransaction
transaction(kSimpleGET_Transaction
);
3626 AddMockTransaction(&transaction
);
3628 // Attempt to populate the cache.
3629 RunTransactionTest(cache
.http_cache(), transaction
);
3631 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3632 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3633 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3635 transaction
.method
= "DELETE";
3636 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3638 RunTransactionTest(cache
.http_cache(), transaction
);
3640 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3641 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3642 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3644 transaction
.method
= "GET";
3645 transaction
.status
= "HTTP/1.1 200 OK";
3646 RunTransactionTest(cache
.http_cache(), transaction
);
3648 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3649 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3650 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3651 RemoveMockTransaction(&transaction
);
3654 // Tests that we don't invalidate entries after a failed network transaction.
3655 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3656 MockHttpCache cache
;
3658 // Populate the cache.
3659 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3660 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3662 // Fail the network request.
3663 MockTransaction
transaction(kSimpleGET_Transaction
);
3664 transaction
.return_code
= ERR_FAILED
;
3665 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
3667 AddMockTransaction(&transaction
);
3668 RunTransactionTest(cache
.http_cache(), transaction
);
3669 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3670 RemoveMockTransaction(&transaction
);
3672 transaction
.load_flags
= LOAD_ONLY_FROM_CACHE
;
3673 transaction
.return_code
= OK
;
3674 AddMockTransaction(&transaction
);
3675 RunTransactionTest(cache
.http_cache(), transaction
);
3677 // Make sure the transaction didn't reach the network.
3678 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3679 RemoveMockTransaction(&transaction
);
3682 TEST(HttpCache
, RangeGET_SkipsCache
) {
3683 MockHttpCache cache
;
3685 // Test that we skip the cache for range GET requests. Eventually, we will
3686 // want to cache these, but we'll still have cases where skipping the cache
3687 // makes sense, so we want to make sure that it works properly.
3689 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3691 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3692 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3693 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3695 MockTransaction
transaction(kSimpleGET_Transaction
);
3696 transaction
.request_headers
= "If-None-Match: foo\r\n";
3697 RunTransactionTest(cache
.http_cache(), transaction
);
3699 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3700 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3701 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3703 transaction
.request_headers
=
3704 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3705 RunTransactionTest(cache
.http_cache(), transaction
);
3707 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3708 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3709 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3712 // Test that we skip the cache for range requests that include a validation
3714 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3715 MockHttpCache cache
;
3717 MockTransaction
transaction(kRangeGET_Transaction
);
3718 transaction
.request_headers
= "If-None-Match: foo\r\n"
3720 "Range: bytes = 40-49\r\n";
3721 RunTransactionTest(cache
.http_cache(), transaction
);
3723 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3724 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3725 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3727 transaction
.request_headers
=
3728 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3730 "Range: bytes = 40-49\r\n";
3731 RunTransactionTest(cache
.http_cache(), transaction
);
3733 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3734 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3735 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3737 transaction
.request_headers
= "If-Range: bla\r\n"
3739 "Range: bytes = 40-49\r\n";
3740 RunTransactionTest(cache
.http_cache(), transaction
);
3742 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3743 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3744 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3747 TEST(HttpCache
, SimpleGET_DoesntLogHeaders
) {
3748 MockHttpCache cache
;
3750 BoundTestNetLog log
;
3751 RunTransactionTestWithLog(cache
.http_cache(), kSimpleGET_Transaction
,
3754 EXPECT_FALSE(LogContainsEventType(
3755 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3758 TEST(HttpCache
, RangeGET_LogsHeaders
) {
3759 MockHttpCache cache
;
3761 BoundTestNetLog log
;
3762 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_Transaction
,
3765 EXPECT_TRUE(LogContainsEventType(
3766 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3769 TEST(HttpCache
, ExternalValidation_LogsHeaders
) {
3770 MockHttpCache cache
;
3772 BoundTestNetLog log
;
3773 MockTransaction
transaction(kSimpleGET_Transaction
);
3774 transaction
.request_headers
= "If-None-Match: foo\r\n" EXTRA_HEADER
;
3775 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3777 EXPECT_TRUE(LogContainsEventType(
3778 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3781 TEST(HttpCache
, SpecialHeaders_LogsHeaders
) {
3782 MockHttpCache cache
;
3784 BoundTestNetLog log
;
3785 MockTransaction
transaction(kSimpleGET_Transaction
);
3786 transaction
.request_headers
= "cache-control: no-cache\r\n" EXTRA_HEADER
;
3787 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3789 EXPECT_TRUE(LogContainsEventType(
3790 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3793 // Tests that receiving 206 for a regular request is handled correctly.
3794 TEST(HttpCache
, GET_Crazy206
) {
3795 MockHttpCache cache
;
3797 // Write to the cache.
3798 MockTransaction
transaction(kRangeGET_TransactionOK
);
3799 AddMockTransaction(&transaction
);
3800 transaction
.request_headers
= EXTRA_HEADER
;
3801 transaction
.handler
= NULL
;
3802 RunTransactionTest(cache
.http_cache(), transaction
);
3804 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3805 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3806 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3808 // This should read again from the net.
3809 RunTransactionTest(cache
.http_cache(), transaction
);
3811 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3812 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3813 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3814 RemoveMockTransaction(&transaction
);
3817 // Tests that receiving 416 for a regular request is handled correctly.
3818 TEST(HttpCache
, GET_Crazy416
) {
3819 MockHttpCache cache
;
3821 // Write to the cache.
3822 MockTransaction
transaction(kSimpleGET_Transaction
);
3823 AddMockTransaction(&transaction
);
3824 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3825 RunTransactionTest(cache
.http_cache(), transaction
);
3827 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3828 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3829 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3831 RemoveMockTransaction(&transaction
);
3834 // Tests that we don't store partial responses that can't be validated.
3835 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3836 MockHttpCache cache
;
3837 std::string headers
;
3839 // Attempt to write to the cache (40-49).
3840 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3841 transaction
.response_headers
= "Content-Length: 10\n"
3842 "Cache-Control: max-age=3600\n"
3843 "ETag: w/\"foo\"\n";
3844 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3846 Verify206Response(headers
, 40, 49);
3847 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3848 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3849 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3851 // Now verify that there's no cached data.
3852 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3855 Verify206Response(headers
, 40, 49);
3856 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3857 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3858 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3861 // Tests failures to conditionalize byte range requests.
3862 TEST(HttpCache
, RangeGET_NoConditionalization
) {
3863 MockHttpCache cache
;
3864 cache
.FailConditionalizations();
3865 std::string headers
;
3867 // Write to the cache (40-49).
3868 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3869 transaction
.response_headers
= "Content-Length: 10\n"
3871 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3873 Verify206Response(headers
, 40, 49);
3874 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3875 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3876 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3878 // Now verify that the cached data is not used.
3879 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3882 Verify206Response(headers
, 40, 49);
3883 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3884 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3885 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3888 // Tests that restarting a partial request when the cached data cannot be
3889 // revalidated logs an event.
3890 TEST(HttpCache
, RangeGET_NoValidation_LogsRestart
) {
3891 MockHttpCache cache
;
3892 cache
.FailConditionalizations();
3894 // Write to the cache (40-49).
3895 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3896 transaction
.response_headers
= "Content-Length: 10\n"
3898 RunTransactionTest(cache
.http_cache(), transaction
);
3900 // Now verify that the cached data is not used.
3901 BoundTestNetLog log
;
3902 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_TransactionOK
,
3905 EXPECT_TRUE(LogContainsEventType(
3906 log
, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST
));
3909 // Tests that a failure to conditionalize a regular request (no range) with a
3910 // sparse entry results in a full response.
3911 TEST(HttpCache
, GET_NoConditionalization
) {
3912 MockHttpCache cache
;
3913 cache
.FailConditionalizations();
3914 std::string headers
;
3916 // Write to the cache (40-49).
3917 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3918 transaction
.response_headers
= "Content-Length: 10\n"
3920 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3922 Verify206Response(headers
, 40, 49);
3923 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3924 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3925 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3927 // Now verify that the cached data is not used.
3928 // Don't ask for a range. The cache will attempt to use the cached data but
3929 // should discard it as it cannot be validated. A regular request should go
3930 // to the server and a new entry should be created.
3931 transaction
.request_headers
= EXTRA_HEADER
;
3932 transaction
.data
= "Not a range";
3933 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3935 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
3936 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3937 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3938 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3940 // The last response was saved.
3941 RunTransactionTest(cache
.http_cache(), transaction
);
3942 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3943 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3944 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3947 // Verifies that conditionalization failures when asking for a range that would
3948 // require the cache to modify the range to ask, result in a network request
3949 // that matches the user's one.
3950 TEST(HttpCache
, RangeGET_NoConditionalization2
) {
3951 MockHttpCache cache
;
3952 cache
.FailConditionalizations();
3953 std::string headers
;
3955 // Write to the cache (40-49).
3956 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3957 transaction
.response_headers
= "Content-Length: 10\n"
3959 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3961 Verify206Response(headers
, 40, 49);
3962 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3963 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3964 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3966 // Now verify that the cached data is not used.
3967 // Ask for a range that extends before and after the cached data so that the
3968 // cache would normally mix data from three sources. After deleting the entry,
3969 // the response will come from a single network request.
3970 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3971 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3972 transaction
.response_headers
= kRangeGET_TransactionOK
.response_headers
;
3973 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3975 Verify206Response(headers
, 20, 59);
3976 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3977 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3978 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3980 // The last response was saved.
3981 RunTransactionTest(cache
.http_cache(), transaction
);
3982 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3983 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3984 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3987 // Tests that we cache partial responses that lack content-length.
3988 TEST(HttpCache
, RangeGET_NoContentLength
) {
3989 MockHttpCache cache
;
3990 std::string headers
;
3992 // Attempt to write to the cache (40-49).
3993 MockTransaction
transaction(kRangeGET_TransactionOK
);
3994 AddMockTransaction(&transaction
);
3995 transaction
.response_headers
= "ETag: \"foo\"\n"
3996 "Accept-Ranges: bytes\n"
3997 "Content-Range: bytes 40-49/80\n";
3998 transaction
.handler
= NULL
;
3999 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4001 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4002 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4003 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4005 // Now verify that there's no cached data.
4006 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
4007 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4010 Verify206Response(headers
, 40, 49);
4011 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4012 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4013 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4015 RemoveMockTransaction(&transaction
);
4018 // Fails only on bots. crbug.com/533640
4019 #if defined(OS_ANDROID)
4020 #define MAYBE_RangeGET_OK DISABLED_RangeGET_OK
4022 #define MAYBE_RangeGET_OK RangeGET_OK
4024 // Tests that we can cache range requests and fetch random blocks from the
4025 // cache and the network.
4026 TEST(HttpCache
, MAYBE_RangeGET_OK
) {
4027 MockHttpCache cache
;
4028 AddMockTransaction(&kRangeGET_TransactionOK
);
4029 std::string headers
;
4031 // Write to the cache (40-49).
4032 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4035 Verify206Response(headers
, 40, 49);
4036 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4037 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4038 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4040 // Read from the cache (40-49).
4041 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4044 Verify206Response(headers
, 40, 49);
4045 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4046 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4047 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4049 // Make sure we are done with the previous transaction.
4050 base::MessageLoop::current()->RunUntilIdle();
4052 // Write to the cache (30-39).
4053 MockTransaction
transaction(kRangeGET_TransactionOK
);
4054 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4055 transaction
.data
= "rg: 30-39 ";
4056 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4058 Verify206Response(headers
, 30, 39);
4059 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4060 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4061 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4063 // Make sure we are done with the previous transaction.
4064 base::MessageLoop::current()->RunUntilIdle();
4066 // Write and read from the cache (20-59).
4067 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4068 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4069 BoundTestNetLog log
;
4070 LoadTimingInfo load_timing_info
;
4071 RunTransactionTestWithResponseAndGetTiming(
4072 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4075 Verify206Response(headers
, 20, 59);
4076 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4077 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4078 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4079 TestLoadTimingNetworkRequest(load_timing_info
);
4081 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4084 // Fails only on bots. crbug.com/533640
4085 #if defined(OS_ANDROID)
4086 #define MAYBE_RangeGET_SyncOK DISABLED_RangeGET_SyncOK
4088 #define MAYBE_RangeGET_SyncOK RangeGET_SyncOK
4090 // Tests that we can cache range requests and fetch random blocks from the
4091 // cache and the network, with synchronous responses.
4092 TEST(HttpCache
, MAYBE_RangeGET_SyncOK
) {
4093 MockHttpCache cache
;
4095 MockTransaction
transaction(kRangeGET_TransactionOK
);
4096 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
4097 AddMockTransaction(&transaction
);
4099 // Write to the cache (40-49).
4100 std::string headers
;
4101 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4103 Verify206Response(headers
, 40, 49);
4104 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4105 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4106 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4108 // Read from the cache (40-49).
4109 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4111 Verify206Response(headers
, 40, 49);
4112 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4113 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4114 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4116 // Make sure we are done with the previous transaction.
4117 base::MessageLoop::current()->RunUntilIdle();
4119 // Write to the cache (30-39).
4120 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4121 transaction
.data
= "rg: 30-39 ";
4122 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4124 Verify206Response(headers
, 30, 39);
4125 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4126 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4127 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4129 // Make sure we are done with the previous transaction.
4130 base::MessageLoop::current()->RunUntilIdle();
4132 // Write and read from the cache (20-59).
4133 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4134 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4135 BoundTestNetLog log
;
4136 LoadTimingInfo load_timing_info
;
4137 RunTransactionTestWithResponseAndGetTiming(
4138 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4141 Verify206Response(headers
, 20, 59);
4142 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4143 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4144 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4145 TestLoadTimingNetworkRequest(load_timing_info
);
4147 RemoveMockTransaction(&transaction
);
4150 // Tests that if the previous transaction is cancelled while busy (doing sparse
4151 // IO), a new transaction (that reuses that same ActiveEntry) waits until the
4152 // entry is ready again.
4153 TEST(HttpCache
, Sparse_WaitForEntry
) {
4154 MockHttpCache cache
;
4156 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4158 // Create a sparse entry.
4159 RunTransactionTest(cache
.http_cache(), transaction
);
4161 // Simulate a previous transaction being cancelled.
4162 disk_cache::Entry
* entry
;
4163 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4164 entry
->CancelSparseIO();
4166 // Test with a range request.
4167 RunTransactionTest(cache
.http_cache(), transaction
);
4169 // Now test with a regular request.
4170 entry
->CancelSparseIO();
4171 transaction
.request_headers
= EXTRA_HEADER
;
4172 transaction
.data
= kFullRangeData
;
4173 RunTransactionTest(cache
.http_cache(), transaction
);
4178 // Tests that we don't revalidate an entry unless we are required to do so.
4179 TEST(HttpCache
, RangeGET_Revalidate1
) {
4180 MockHttpCache cache
;
4181 std::string headers
;
4183 // Write to the cache (40-49).
4184 MockTransaction
transaction(kRangeGET_TransactionOK
);
4185 transaction
.response_headers
=
4186 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4187 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4189 "Accept-Ranges: bytes\n"
4190 "Content-Length: 10\n";
4191 AddMockTransaction(&transaction
);
4192 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4194 Verify206Response(headers
, 40, 49);
4195 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4196 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4197 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4199 // Read from the cache (40-49).
4200 BoundTestNetLog log
;
4201 LoadTimingInfo load_timing_info
;
4202 RunTransactionTestWithResponseAndGetTiming(
4203 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4206 Verify206Response(headers
, 40, 49);
4207 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4208 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4209 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4210 TestLoadTimingCachedResponse(load_timing_info
);
4212 // Read again forcing the revalidation.
4213 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4214 RunTransactionTestWithResponseAndGetTiming(
4215 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4218 Verify206Response(headers
, 40, 49);
4219 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4220 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4221 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4222 TestLoadTimingNetworkRequest(load_timing_info
);
4224 RemoveMockTransaction(&transaction
);
4227 // Fails only on bots. crbug.com/533640
4228 #if defined(OS_ANDROID)
4229 #define MAYBE_RangeGET_Revalidate2 DISABLED_RangeGET_Revalidate2
4231 #define MAYBE_RangeGET_Revalidate2 RangeGET_Revalidate2
4233 // Checks that we revalidate an entry when the headers say so.
4234 TEST(HttpCache
, MAYBE_RangeGET_Revalidate2
) {
4235 MockHttpCache cache
;
4236 std::string headers
;
4238 // Write to the cache (40-49).
4239 MockTransaction
transaction(kRangeGET_TransactionOK
);
4240 transaction
.response_headers
=
4241 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4242 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4244 "Accept-Ranges: bytes\n"
4245 "Content-Length: 10\n";
4246 AddMockTransaction(&transaction
);
4247 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4249 Verify206Response(headers
, 40, 49);
4250 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4251 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4252 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4254 // Read from the cache (40-49).
4255 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4256 Verify206Response(headers
, 40, 49);
4258 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4259 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4262 RemoveMockTransaction(&transaction
);
4265 // Tests that we deal with 304s for range requests.
4266 TEST(HttpCache
, RangeGET_304
) {
4267 MockHttpCache cache
;
4268 AddMockTransaction(&kRangeGET_TransactionOK
);
4269 std::string headers
;
4271 // Write to the cache (40-49).
4272 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4275 Verify206Response(headers
, 40, 49);
4276 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4277 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4278 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4280 // Read from the cache (40-49).
4281 RangeTransactionServer handler
;
4282 handler
.set_not_modified(true);
4283 MockTransaction
transaction(kRangeGET_TransactionOK
);
4284 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4285 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4287 Verify206Response(headers
, 40, 49);
4288 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4289 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4290 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4292 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4295 // Tests that we deal with 206s when revalidating range requests.
4296 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4297 MockHttpCache cache
;
4298 AddMockTransaction(&kRangeGET_TransactionOK
);
4299 std::string headers
;
4301 // Write to the cache (40-49).
4302 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4305 Verify206Response(headers
, 40, 49);
4306 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4307 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4308 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4310 // Attempt to read from the cache (40-49).
4311 RangeTransactionServer handler
;
4312 handler
.set_modified(true);
4313 MockTransaction
transaction(kRangeGET_TransactionOK
);
4314 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4315 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4317 Verify206Response(headers
, 40, 49);
4318 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4319 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4320 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4322 // And the entry should be gone.
4323 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4324 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4325 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4326 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4328 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4331 // Tests that when a server returns 206 with a sub-range of the requested range,
4332 // and there is nothing stored in the cache, the returned response is passed to
4333 // the caller as is. In this context, a subrange means a response that starts
4334 // with the same byte that was requested, but that is not the whole range that
4336 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_NoCachedContent
) {
4337 MockHttpCache cache
;
4338 std::string headers
;
4340 // Request a large range (40-59). The server sends 40-49.
4341 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4342 transaction
.request_headers
= "Range: bytes = 40-59\r\n" EXTRA_HEADER
;
4343 transaction
.response_headers
=
4344 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4346 "Accept-Ranges: bytes\n"
4347 "Content-Length: 10\n"
4348 "Content-Range: bytes 40-49/80\n";
4349 transaction
.handler
= nullptr;
4350 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4352 Verify206Response(headers
, 40, 49);
4353 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4354 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4355 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4358 // Tests that when a server returns 206 with a sub-range of the requested range,
4359 // and there was an entry stored in the cache, the cache gets out of the way.
4360 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_CachedContent
) {
4361 MockHttpCache cache
;
4362 std::string headers
;
4364 // Write to the cache (70-79).
4365 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4366 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4367 transaction
.data
= "rg: 70-79 ";
4368 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4369 Verify206Response(headers
, 70, 79);
4371 // Request a large range (40-79). The cache will ask the server for 40-59.
4372 // The server returns 40-49. The cache should consider the server confused and
4373 // abort caching, restarting the request without caching.
4374 transaction
.request_headers
= "Range: bytes = 40-79\r\n" EXTRA_HEADER
;
4375 transaction
.response_headers
=
4376 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4378 "Accept-Ranges: bytes\n"
4379 "Content-Length: 10\n"
4380 "Content-Range: bytes 40-49/80\n";
4381 transaction
.handler
= nullptr;
4382 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4384 // Two new network requests were issued, one from the cache and another after
4385 // deleting the entry.
4386 Verify206Response(headers
, 40, 49);
4387 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4388 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4389 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4391 // The entry was deleted.
4392 RunTransactionTest(cache
.http_cache(), transaction
);
4393 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4394 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4395 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4398 // Tests that when a server returns 206 with a sub-range of the requested range,
4399 // and there was an entry stored in the cache, the cache gets out of the way,
4400 // when the caller is not using ranges.
4401 TEST(HttpCache
, GET_206ReturnsSubrangeRange_CachedContent
) {
4402 MockHttpCache cache
;
4403 std::string headers
;
4405 // Write to the cache (70-79).
4406 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4407 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4408 transaction
.data
= "rg: 70-79 ";
4409 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4410 Verify206Response(headers
, 70, 79);
4412 // Don't ask for a range. The cache will ask the server for 0-69.
4413 // The server returns 40-49. The cache should consider the server confused and
4414 // abort caching, restarting the request.
4415 // The second network request should not be a byte range request so the server
4416 // should return 200 + "Not a range"
4417 transaction
.request_headers
= "X-Return-Default-Range:\r\n" EXTRA_HEADER
;
4418 transaction
.data
= "Not a range";
4419 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4421 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4422 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4423 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4424 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4426 // The entry was deleted.
4427 RunTransactionTest(cache
.http_cache(), transaction
);
4428 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4429 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4430 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4433 // Tests that when a server returns 206 with a random range and there is
4434 // nothing stored in the cache, the returned response is passed to the caller
4435 // as is. In this context, a WrongRange means that the returned range may or may
4436 // not have any relationship with the requested range (may or may not be
4437 // contained). The important part is that the first byte doesn't match the first
4439 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_NoCachedContent
) {
4440 MockHttpCache cache
;
4441 std::string headers
;
4443 // Request a large range (30-59). The server sends (40-49).
4444 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4445 transaction
.request_headers
= "Range: bytes = 30-59\r\n" EXTRA_HEADER
;
4446 transaction
.response_headers
=
4447 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4449 "Accept-Ranges: bytes\n"
4450 "Content-Length: 10\n"
4451 "Content-Range: bytes 40-49/80\n";
4452 transaction
.handler
= nullptr;
4453 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4455 Verify206Response(headers
, 40, 49);
4456 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4457 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4458 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4460 // The entry was deleted.
4461 RunTransactionTest(cache
.http_cache(), transaction
);
4462 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4463 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4464 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4467 // Tests that when a server returns 206 with a random range and there is
4468 // an entry stored in the cache, the cache gets out of the way.
4469 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_CachedContent
) {
4470 MockHttpCache cache
;
4471 std::string headers
;
4473 // Write to the cache (70-79).
4474 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4475 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4476 transaction
.data
= "rg: 70-79 ";
4477 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4478 Verify206Response(headers
, 70, 79);
4480 // Request a large range (30-79). The cache will ask the server for 30-69.
4481 // The server returns 40-49. The cache should consider the server confused and
4482 // abort caching, returning the weird range to the caller.
4483 transaction
.request_headers
= "Range: bytes = 30-79\r\n" EXTRA_HEADER
;
4484 transaction
.response_headers
=
4485 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4487 "Accept-Ranges: bytes\n"
4488 "Content-Length: 10\n"
4489 "Content-Range: bytes 40-49/80\n";
4490 transaction
.handler
= nullptr;
4491 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4493 Verify206Response(headers
, 40, 49);
4494 EXPECT_EQ(3, 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 deleted.
4499 RunTransactionTest(cache
.http_cache(), transaction
);
4500 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4501 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4502 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4505 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4506 // the response matches the one provided by the server.
4507 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_NoCachedContent
) {
4508 MockHttpCache cache
;
4509 std::string headers
;
4511 // Request a large range (70-99). The server sends 70-79.
4512 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4513 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4514 transaction
.data
= "rg: 70-79 ";
4515 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4517 Verify206Response(headers
, 70, 79);
4518 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4519 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4520 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4522 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4523 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4526 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4527 // the cache automatically fixes the request.
4528 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_CachedContent
) {
4529 MockHttpCache cache
;
4530 std::string headers
;
4532 // Write to the cache (40-49).
4533 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4534 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4536 // Request a large range (70-99). The server sends 70-79.
4537 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4538 transaction
.data
= "rg: 70-79 ";
4539 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4541 Verify206Response(headers
, 70, 79);
4542 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4543 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4544 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4546 // The entry was not deleted (the range was automatically fixed).
4547 RunTransactionTest(cache
.http_cache(), transaction
);
4548 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4549 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4550 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4553 // Tests that when a caller asks for a not-satisfiable range, the server's
4554 // response is forwarded to the caller.
4555 TEST(HttpCache
, RangeGET_416_NoCachedContent
) {
4556 MockHttpCache cache
;
4557 std::string headers
;
4559 // Request a range beyond EOF (80-99).
4560 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4561 transaction
.request_headers
= "Range: bytes = 80-99\r\n" EXTRA_HEADER
;
4562 transaction
.data
= "";
4563 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
4564 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4566 EXPECT_EQ(0U, headers
.find(transaction
.status
));
4567 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4568 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4569 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4571 // The entry was deleted.
4572 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4573 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4576 // Tests that we cache 301s for range requests.
4577 TEST(HttpCache
, RangeGET_301
) {
4578 MockHttpCache cache
;
4579 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4580 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4581 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4582 transaction
.data
= "";
4583 transaction
.handler
= NULL
;
4585 // Write to the cache.
4586 RunTransactionTest(cache
.http_cache(), transaction
);
4587 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4588 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4589 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4591 // Read from the cache.
4592 RunTransactionTest(cache
.http_cache(), transaction
);
4593 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4594 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4595 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4598 // Tests that we can cache range requests when the start or end is unknown.
4599 // We start with one suffix request, followed by a request from a given point.
4600 TEST(HttpCache
, UnknownRangeGET_1
) {
4601 MockHttpCache cache
;
4602 AddMockTransaction(&kRangeGET_TransactionOK
);
4603 std::string headers
;
4605 // Write to the cache (70-79).
4606 MockTransaction
transaction(kRangeGET_TransactionOK
);
4607 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4608 transaction
.data
= "rg: 70-79 ";
4609 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4611 Verify206Response(headers
, 70, 79);
4612 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4613 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4614 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4616 // Make sure we are done with the previous transaction.
4617 base::MessageLoop::current()->RunUntilIdle();
4619 // Write and read from the cache (60-79).
4620 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4621 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4622 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4624 Verify206Response(headers
, 60, 79);
4625 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4626 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4627 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4629 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4632 // Tests that we can cache range requests when the start or end is unknown.
4633 // We start with one request from a given point, followed by a suffix request.
4634 // We'll also verify that synchronous cache responses work as intended.
4635 TEST(HttpCache
, UnknownRangeGET_2
) {
4636 MockHttpCache cache
;
4637 std::string headers
;
4639 MockTransaction
transaction(kRangeGET_TransactionOK
);
4640 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4641 TEST_MODE_SYNC_CACHE_READ
|
4642 TEST_MODE_SYNC_CACHE_WRITE
;
4643 AddMockTransaction(&transaction
);
4645 // Write to the cache (70-79).
4646 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4647 transaction
.data
= "rg: 70-79 ";
4648 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4650 Verify206Response(headers
, 70, 79);
4651 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4652 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4653 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4655 // Make sure we are done with the previous transaction.
4656 base::MessageLoop::current()->RunUntilIdle();
4658 // Write and read from the cache (60-79).
4659 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4660 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4661 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4663 Verify206Response(headers
, 60, 79);
4664 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4665 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4666 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4668 RemoveMockTransaction(&transaction
);
4671 // Tests that receiving Not Modified when asking for an open range doesn't mess
4673 TEST(HttpCache
, UnknownRangeGET_304
) {
4674 MockHttpCache cache
;
4675 std::string headers
;
4677 MockTransaction
transaction(kRangeGET_TransactionOK
);
4678 AddMockTransaction(&transaction
);
4680 RangeTransactionServer handler
;
4681 handler
.set_not_modified(true);
4683 // Ask for the end of the file, without knowing the length.
4684 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4685 transaction
.data
= "";
4686 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4688 // We just bypass the cache.
4689 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4690 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4691 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4692 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4694 RunTransactionTest(cache
.http_cache(), transaction
);
4695 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4697 RemoveMockTransaction(&transaction
);
4700 // Tests that we can handle non-range requests when we have cached a range.
4701 TEST(HttpCache
, GET_Previous206
) {
4702 MockHttpCache cache
;
4703 AddMockTransaction(&kRangeGET_TransactionOK
);
4704 std::string headers
;
4705 BoundTestNetLog log
;
4706 LoadTimingInfo load_timing_info
;
4708 // Write to the cache (40-49).
4709 RunTransactionTestWithResponseAndGetTiming(
4710 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4713 Verify206Response(headers
, 40, 49);
4714 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4715 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4716 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4717 TestLoadTimingNetworkRequest(load_timing_info
);
4719 // Write and read from the cache (0-79), when not asked for a range.
4720 MockTransaction
transaction(kRangeGET_TransactionOK
);
4721 transaction
.request_headers
= EXTRA_HEADER
;
4722 transaction
.data
= kFullRangeData
;
4723 RunTransactionTestWithResponseAndGetTiming(
4724 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4727 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4728 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4729 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4730 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4731 TestLoadTimingNetworkRequest(load_timing_info
);
4733 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4736 // Tests that we can handle non-range requests when we have cached the first
4737 // part of the object and the server replies with 304 (Not Modified).
4738 TEST(HttpCache
, GET_Previous206_NotModified
) {
4739 MockHttpCache cache
;
4741 MockTransaction
transaction(kRangeGET_TransactionOK
);
4742 AddMockTransaction(&transaction
);
4743 std::string headers
;
4744 BoundTestNetLog log
;
4745 LoadTimingInfo load_timing_info
;
4747 // Write to the cache (0-9).
4748 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4749 transaction
.data
= "rg: 00-09 ";
4750 RunTransactionTestWithResponseAndGetTiming(
4751 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4753 Verify206Response(headers
, 0, 9);
4754 TestLoadTimingNetworkRequest(load_timing_info
);
4756 // Write to the cache (70-79).
4757 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4758 transaction
.data
= "rg: 70-79 ";
4759 RunTransactionTestWithResponseAndGetTiming(
4760 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4762 Verify206Response(headers
, 70, 79);
4764 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4765 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4766 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4767 TestLoadTimingNetworkRequest(load_timing_info
);
4769 // Read from the cache (0-9), write and read from cache (10 - 79).
4770 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4771 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4772 transaction
.data
= kFullRangeData
;
4773 RunTransactionTestWithResponseAndGetTiming(
4774 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4777 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4778 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4779 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4780 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4781 TestLoadTimingNetworkRequest(load_timing_info
);
4783 RemoveMockTransaction(&transaction
);
4786 // Tests that we can handle a regular request to a sparse entry, that results in
4787 // new content provided by the server (206).
4788 TEST(HttpCache
, GET_Previous206_NewContent
) {
4789 MockHttpCache cache
;
4790 AddMockTransaction(&kRangeGET_TransactionOK
);
4791 std::string headers
;
4793 // Write to the cache (0-9).
4794 MockTransaction
transaction(kRangeGET_TransactionOK
);
4795 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4796 transaction
.data
= "rg: 00-09 ";
4797 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4799 Verify206Response(headers
, 0, 9);
4800 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4801 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4802 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4804 // Now we'll issue a request without any range that should result first in a
4805 // 206 (when revalidating), and then in a weird standard answer: the test
4806 // server will not modify the response so we'll get the default range... a
4807 // real server will answer with 200.
4808 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4809 transaction2
.request_headers
= EXTRA_HEADER
;
4810 transaction2
.load_flags
|= LOAD_VALIDATE_CACHE
;
4811 transaction2
.data
= "Not a range";
4812 RangeTransactionServer handler
;
4813 handler
.set_modified(true);
4814 BoundTestNetLog log
;
4815 LoadTimingInfo load_timing_info
;
4816 RunTransactionTestWithResponseAndGetTiming(
4817 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4820 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4821 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4822 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4823 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4824 TestLoadTimingNetworkRequest(load_timing_info
);
4826 // Verify that the previous request deleted the entry.
4827 RunTransactionTest(cache
.http_cache(), transaction
);
4828 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4830 RemoveMockTransaction(&transaction
);
4833 // Tests that we can handle cached 206 responses that are not sparse.
4834 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4835 MockHttpCache cache
;
4837 // Create a disk cache entry that stores 206 headers while not being sparse.
4838 disk_cache::Entry
* entry
;
4839 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.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 BoundTestNetLog log
;
4863 LoadTimingInfo load_timing_info
;
4864 RunTransactionTestWithResponseAndGetTiming(
4865 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4868 // We are expecting a 200.
4869 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4870 expected_headers
.append("\n");
4871 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4872 EXPECT_EQ(expected_headers
, headers
);
4873 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4874 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4875 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4876 TestLoadTimingNetworkRequest(load_timing_info
);
4879 // Tests that we can handle cached 206 responses that are not sparse. This time
4880 // we issue a range request and expect to receive a range.
4881 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4882 MockHttpCache cache
;
4883 AddMockTransaction(&kRangeGET_TransactionOK
);
4885 // Create a disk cache entry that stores 206 headers while not being sparse.
4886 disk_cache::Entry
* entry
;
4887 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4890 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4891 raw_headers
.append("\n");
4892 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4894 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4896 HttpResponseInfo response
;
4897 response
.headers
= new HttpResponseHeaders(raw_headers
);
4898 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4900 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4901 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4902 kRangeGET_TransactionOK
.data
, 500));
4903 TestCompletionCallback cb
;
4904 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4905 EXPECT_EQ(len
, cb
.GetResult(rv
));
4908 // Now see that we don't use the stored entry.
4909 std::string headers
;
4910 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4913 // We are expecting a 206.
4914 Verify206Response(headers
, 40, 49);
4915 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4916 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4917 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4919 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4922 // Tests that we can handle cached 206 responses that can't be validated.
4923 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4924 MockHttpCache cache
;
4926 // Create a disk cache entry that stores 206 headers.
4927 disk_cache::Entry
* entry
;
4928 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4931 // Make sure that the headers cannot be validated with the server.
4932 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4933 raw_headers
.append("\n");
4934 raw_headers
.append("Content-Length: 80\n");
4936 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4938 HttpResponseInfo response
;
4939 response
.headers
= new HttpResponseHeaders(raw_headers
);
4940 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4942 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4943 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4944 kRangeGET_TransactionOK
.data
, 500));
4945 TestCompletionCallback cb
;
4946 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4947 EXPECT_EQ(len
, cb
.GetResult(rv
));
4950 // Now see that we don't use the stored entry.
4951 std::string headers
;
4952 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4955 // We are expecting a 200.
4956 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4957 expected_headers
.append("\n");
4958 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4959 EXPECT_EQ(expected_headers
, headers
);
4960 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4961 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4962 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4965 // Fails only on bots. crbug.com/533640
4966 #if defined(OS_ANDROID)
4967 #define MAYBE_RangeGET_Previous200 DISABLED_RangeGET_Previous200
4969 #define MAYBE_RangeGET_Previous200 RangeGET_Previous200
4971 // Tests that we can handle range requests with cached 200 responses.
4972 TEST(HttpCache
, MAYBE_RangeGET_Previous200
) {
4973 MockHttpCache cache
;
4975 // Store the whole thing with status 200.
4976 MockTransaction
transaction(kTypicalGET_Transaction
);
4977 transaction
.url
= kRangeGET_TransactionOK
.url
;
4978 transaction
.data
= kFullRangeData
;
4979 AddMockTransaction(&transaction
);
4980 RunTransactionTest(cache
.http_cache(), transaction
);
4981 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4982 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4983 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4985 RemoveMockTransaction(&transaction
);
4986 AddMockTransaction(&kRangeGET_TransactionOK
);
4988 // Now see that we use the stored entry.
4989 std::string headers
;
4990 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4991 RangeTransactionServer handler
;
4992 handler
.set_not_modified(true);
4993 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4995 // We are expecting a 206.
4996 Verify206Response(headers
, 40, 49);
4997 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4998 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4999 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5001 // The last transaction has finished so make sure the entry is deactivated.
5002 base::MessageLoop::current()->RunUntilIdle();
5004 // Make a request for an invalid range.
5005 MockTransaction
transaction3(kRangeGET_TransactionOK
);
5006 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
5007 transaction3
.data
= transaction
.data
;
5008 transaction3
.load_flags
= LOAD_PREFERRING_CACHE
;
5009 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
5010 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5011 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
5012 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
5013 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
5015 // Make sure the entry is deactivated.
5016 base::MessageLoop::current()->RunUntilIdle();
5018 // Even though the request was invalid, we should have the entry.
5019 RunTransactionTest(cache
.http_cache(), transaction2
);
5020 EXPECT_EQ(3, cache
.disk_cache()->open_count());
5022 // Make sure the entry is deactivated.
5023 base::MessageLoop::current()->RunUntilIdle();
5025 // Now we should receive a range from the server and drop the stored entry.
5026 handler
.set_not_modified(false);
5027 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5028 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5029 Verify206Response(headers
, 40, 49);
5030 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
5031 EXPECT_EQ(4, cache
.disk_cache()->open_count());
5032 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5034 RunTransactionTest(cache
.http_cache(), transaction2
);
5035 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5037 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5040 // Tests that we can handle a 200 response when dealing with sparse entries.
5041 TEST(HttpCache
, RangeRequestResultsIn200
) {
5042 MockHttpCache cache
;
5043 AddMockTransaction(&kRangeGET_TransactionOK
);
5044 std::string headers
;
5046 // Write to the cache (70-79).
5047 MockTransaction
transaction(kRangeGET_TransactionOK
);
5048 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5049 transaction
.data
= "rg: 70-79 ";
5050 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5052 Verify206Response(headers
, 70, 79);
5053 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5054 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5055 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5057 // Now we'll issue a request that results in a plain 200 response, but to
5058 // the to the same URL that we used to store sparse data, and making sure
5059 // that we ask for a range.
5060 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5061 MockTransaction
transaction2(kSimpleGET_Transaction
);
5062 transaction2
.url
= kRangeGET_TransactionOK
.url
;
5063 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5064 AddMockTransaction(&transaction2
);
5066 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5068 std::string
expected_headers(kSimpleGET_Transaction
.status
);
5069 expected_headers
.append("\n");
5070 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
5071 EXPECT_EQ(expected_headers
, headers
);
5072 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5073 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5074 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5076 RemoveMockTransaction(&transaction2
);
5079 // Tests that a range request that falls outside of the size that we know about
5080 // only deletes the entry if the resource has indeed changed.
5081 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
5082 MockHttpCache cache
;
5083 AddMockTransaction(&kRangeGET_TransactionOK
);
5084 std::string headers
;
5086 // Write to the cache (40-49).
5087 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5090 Verify206Response(headers
, 40, 49);
5091 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5092 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5093 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5095 // A weird request should not delete this entry. Ask for bytes 120-.
5096 MockTransaction
transaction(kRangeGET_TransactionOK
);
5097 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
5098 transaction
.data
= "";
5099 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5101 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
5102 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5103 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5104 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5106 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5107 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5108 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5110 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5113 // Fails only on bots. crbug.com/533640
5114 #if defined(OS_ANDROID)
5115 #define MAYBE_RangeGET_Cancel DISABLED_RangeGET_Cancel
5117 #define MAYBE_RangeGET_Cancel RangeGET_Cancel
5119 // Tests that we don't delete a sparse entry when we cancel a request.
5120 TEST(HttpCache
, MAYBE_RangeGET_Cancel
) {
5121 MockHttpCache cache
;
5122 AddMockTransaction(&kRangeGET_TransactionOK
);
5124 MockHttpRequest
request(kRangeGET_TransactionOK
);
5126 Context
* c
= new Context();
5127 int rv
= cache
.CreateTransaction(&c
->trans
);
5130 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5131 if (rv
== ERR_IO_PENDING
)
5132 rv
= c
->callback
.WaitForResult();
5134 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5135 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5136 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5138 // Make sure that the entry has some data stored.
5139 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5140 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5141 if (rv
== ERR_IO_PENDING
)
5142 rv
= c
->callback
.WaitForResult();
5143 EXPECT_EQ(buf
->size(), rv
);
5145 // Destroy the transaction.
5148 // Verify that the entry has not been deleted.
5149 disk_cache::Entry
* entry
;
5150 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5152 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5155 // Fails only on bots. crbug.com/533640
5156 #if defined(OS_ANDROID)
5157 #define MAYBE_RangeGET_Cancel2 DISABLED_RangeGET_Cancel2
5159 #define MAYBE_RangeGET_Cancel2 RangeGET_Cancel2
5161 // Tests that we don't delete a sparse entry when we start a new request after
5162 // cancelling the previous one.
5163 TEST(HttpCache
, MAYBE_RangeGET_Cancel2
) {
5164 MockHttpCache cache
;
5165 AddMockTransaction(&kRangeGET_TransactionOK
);
5167 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5168 MockHttpRequest
request(kRangeGET_TransactionOK
);
5169 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5171 Context
* c
= new Context();
5172 int rv
= cache
.CreateTransaction(&c
->trans
);
5175 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5176 if (rv
== ERR_IO_PENDING
)
5177 rv
= c
->callback
.WaitForResult();
5179 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5180 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5181 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5183 // Make sure that we revalidate the entry and read from the cache (a single
5184 // read will return while waiting for the network).
5185 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5186 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5187 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5188 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5189 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5191 // Destroy the transaction before completing the read.
5194 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5195 // message loop. This means that a new transaction will just reuse the same
5196 // active entry (no open or create).
5198 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5200 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5201 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5202 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5203 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5206 // A slight variation of the previous test, this time we cancel two requests in
5207 // a row, making sure that the second is waiting for the entry to be ready.
5208 TEST(HttpCache
, RangeGET_Cancel3
) {
5209 MockHttpCache cache
;
5210 AddMockTransaction(&kRangeGET_TransactionOK
);
5212 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5213 MockHttpRequest
request(kRangeGET_TransactionOK
);
5214 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5216 Context
* c
= new Context();
5217 int rv
= cache
.CreateTransaction(&c
->trans
);
5220 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5221 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5222 rv
= c
->callback
.WaitForResult();
5224 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5225 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5226 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5228 // Make sure that we revalidate the entry and read from the cache (a single
5229 // read will return while waiting for the network).
5230 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5231 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5232 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5233 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5234 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5236 // Destroy the transaction before completing the read.
5239 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5240 // message loop. This means that a new transaction will just reuse the same
5241 // active entry (no open or create).
5244 rv
= cache
.CreateTransaction(&c
->trans
);
5247 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5248 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5250 MockDiskEntry::IgnoreCallbacks(true);
5251 base::MessageLoop::current()->RunUntilIdle();
5252 MockDiskEntry::IgnoreCallbacks(false);
5254 // The new transaction is waiting for the query range callback.
5257 // And we should not crash when the callback is delivered.
5258 base::MessageLoop::current()->RunUntilIdle();
5260 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5261 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5262 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5263 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5266 // Tests that an invalid range response results in no cached entry.
5267 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
5268 MockHttpCache cache
;
5269 std::string headers
;
5271 MockTransaction
transaction(kRangeGET_TransactionOK
);
5272 transaction
.handler
= NULL
;
5273 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
5274 "Content-Length: 10\n";
5275 AddMockTransaction(&transaction
);
5276 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5278 std::string
expected(transaction
.status
);
5279 expected
.append("\n");
5280 expected
.append(transaction
.response_headers
);
5281 EXPECT_EQ(expected
, headers
);
5283 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5284 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5285 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5287 // Verify that we don't have a cached entry.
5288 disk_cache::Entry
* entry
;
5289 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5291 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5294 // Tests that we reject a range that doesn't match the content-length.
5295 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
5296 MockHttpCache cache
;
5297 std::string headers
;
5299 MockTransaction
transaction(kRangeGET_TransactionOK
);
5300 transaction
.handler
= NULL
;
5301 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
5302 "Content-Length: 20\n";
5303 AddMockTransaction(&transaction
);
5304 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5306 std::string
expected(transaction
.status
);
5307 expected
.append("\n");
5308 expected
.append(transaction
.response_headers
);
5309 EXPECT_EQ(expected
, headers
);
5311 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5312 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5313 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5315 // Verify that we don't have a cached entry.
5316 disk_cache::Entry
* entry
;
5317 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5319 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5322 // Tests that if a server tells us conflicting information about a resource we
5324 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
5325 MockHttpCache cache
;
5326 std::string headers
;
5328 MockTransaction
transaction(kRangeGET_TransactionOK
);
5329 transaction
.handler
= NULL
;
5330 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
5331 std::string
response_headers(transaction
.response_headers
);
5332 response_headers
.append("Content-Range: bytes 50-59/160\n");
5333 transaction
.response_headers
= response_headers
.c_str();
5334 AddMockTransaction(&transaction
);
5335 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5337 Verify206Response(headers
, 50, 59);
5338 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5339 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5340 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5342 RemoveMockTransaction(&transaction
);
5343 AddMockTransaction(&kRangeGET_TransactionOK
);
5345 // This transaction will report a resource size of 80 bytes, and we think it's
5346 // 160 so we should ignore the response.
5347 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5350 Verify206Response(headers
, 40, 49);
5351 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5352 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5353 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5355 // Verify that the entry is gone.
5356 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5357 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5358 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5359 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5362 // Tests that we handle large range values properly.
5363 TEST(HttpCache
, RangeGET_LargeValues
) {
5364 // We need a real sparse cache for this test.
5365 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5366 std::string headers
;
5368 MockTransaction
transaction(kRangeGET_TransactionOK
);
5369 transaction
.handler
= NULL
;
5370 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
5372 transaction
.response_headers
=
5374 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5375 "Content-Length: 10\n";
5376 AddMockTransaction(&transaction
);
5377 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5379 std::string
expected(transaction
.status
);
5380 expected
.append("\n");
5381 expected
.append(transaction
.response_headers
);
5382 EXPECT_EQ(expected
, headers
);
5384 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5386 // Verify that we have a cached entry.
5387 disk_cache::Entry
* en
;
5388 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
5391 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5394 // Tests that we don't crash with a range request if the disk cache was not
5395 // initialized properly.
5396 TEST(HttpCache
, RangeGET_NoDiskCache
) {
5397 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
5398 factory
->set_fail(true);
5399 factory
->FinishCreation(); // We'll complete synchronously.
5400 MockHttpCache
cache(factory
);
5402 AddMockTransaction(&kRangeGET_TransactionOK
);
5404 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5405 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5407 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5410 // Tests that we handle byte range requests that skip the cache.
5411 TEST(HttpCache
, RangeHEAD
) {
5412 MockHttpCache cache
;
5413 AddMockTransaction(&kRangeGET_TransactionOK
);
5415 MockTransaction
transaction(kRangeGET_TransactionOK
);
5416 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5417 transaction
.method
= "HEAD";
5418 transaction
.data
= "rg: 70-79 ";
5420 std::string headers
;
5421 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5423 Verify206Response(headers
, 70, 79);
5424 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5425 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5426 EXPECT_EQ(0, cache
.disk_cache()->create_count());
5428 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5431 // Tests that we don't crash when after reading from the cache we issue a
5432 // request for the next range and the server gives us a 200 synchronously.
5433 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
5434 MockHttpCache cache
;
5436 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5437 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
5438 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
5439 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
5441 // Write to the cache.
5442 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5444 // And now read from the cache and the network.
5445 RangeTransactionServer handler
;
5446 handler
.set_bad_200(true);
5447 transaction
.data
= "Not a range";
5448 BoundTestNetLog log
;
5449 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
5451 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5453 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5454 EXPECT_TRUE(LogContainsEventType(
5455 log
, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST
));
5458 // Tests that when the server gives us less data than expected, we don't keep
5459 // asking for more data.
5460 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
5461 MockHttpCache cache
;
5463 // First, check with an empty cache (WRITE mode).
5464 MockTransaction
transaction(kRangeGET_TransactionOK
);
5465 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
5466 transaction
.data
= "rg: 40-"; // Less than expected.
5467 transaction
.handler
= NULL
;
5468 std::string
headers(transaction
.response_headers
);
5469 headers
.append("Content-Range: bytes 40-49/80\n");
5470 transaction
.response_headers
= headers
.c_str();
5472 AddMockTransaction(&transaction
);
5474 // Write to the cache.
5475 RunTransactionTest(cache
.http_cache(), transaction
);
5477 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5478 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5479 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5481 // Now verify that even in READ_WRITE mode, we forward the bad response to
5483 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5484 transaction
.data
= "rg: 60-"; // Less than expected.
5485 headers
= kRangeGET_TransactionOK
.response_headers
;
5486 headers
.append("Content-Range: bytes 60-69/80\n");
5487 transaction
.response_headers
= headers
.c_str();
5489 RunTransactionTest(cache
.http_cache(), transaction
);
5491 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5492 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5493 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5495 RemoveMockTransaction(&transaction
);
5498 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5499 // This test hits a NOTREACHED so it is a release mode only test.
5500 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5501 MockHttpCache cache
;
5502 AddMockTransaction(&kRangeGET_TransactionOK
);
5504 // Write to the cache (40-49).
5505 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5506 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5507 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5508 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5510 // Force this transaction to read from the cache.
5511 MockTransaction
transaction(kRangeGET_TransactionOK
);
5512 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
5514 MockHttpRequest
request(transaction
);
5515 TestCompletionCallback callback
;
5517 scoped_ptr
<HttpTransaction
> trans
;
5518 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
5520 ASSERT_TRUE(trans
.get());
5522 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
5523 if (rv
== ERR_IO_PENDING
)
5524 rv
= callback
.WaitForResult();
5525 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
5529 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5530 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5531 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5533 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5537 // Tests the handling of the "truncation" flag.
5538 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5539 MockHttpCache cache
;
5540 disk_cache::Entry
* entry
;
5541 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5544 std::string
headers("HTTP/1.1 200 OK");
5545 headers
= HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5546 HttpResponseInfo response
;
5547 response
.headers
= new HttpResponseHeaders(headers
);
5549 // Set the last argument for this to be an incomplete request.
5550 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5551 bool truncated
= false;
5552 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5553 EXPECT_TRUE(truncated
);
5555 // And now test the opposite case.
5556 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5558 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5559 EXPECT_FALSE(truncated
);
5563 // Tests basic pickling/unpickling of HttpResponseInfo.
5564 TEST(HttpCache
, PersistHttpResponseInfo
) {
5565 // Set some fields (add more if needed.)
5566 HttpResponseInfo response1
;
5567 response1
.was_cached
= false;
5568 response1
.socket_address
= HostPortPair("1.2.3.4", 80);
5569 response1
.headers
= new HttpResponseHeaders("HTTP/1.1 200 OK");
5572 base::Pickle pickle
;
5573 response1
.Persist(&pickle
, false, false);
5576 HttpResponseInfo response2
;
5577 bool response_truncated
;
5578 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5579 EXPECT_FALSE(response_truncated
);
5582 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5583 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5584 EXPECT_EQ(80, response2
.socket_address
.port());
5585 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5588 // Tests that we delete an entry when the request is cancelled before starting
5589 // to read from the network.
5590 TEST(HttpCache
, DoomOnDestruction
) {
5591 MockHttpCache cache
;
5593 MockHttpRequest
request(kSimpleGET_Transaction
);
5595 Context
* c
= new Context();
5596 int rv
= cache
.CreateTransaction(&c
->trans
);
5599 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5600 if (rv
== ERR_IO_PENDING
)
5601 c
->result
= c
->callback
.WaitForResult();
5603 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5605 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5607 // Destroy the transaction. We only have the headers so we should delete this
5611 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5613 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5614 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5615 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5618 // Tests that we delete an entry when the request is cancelled if the response
5619 // does not have content-length and strong validators.
5620 TEST(HttpCache
, DoomOnDestruction2
) {
5621 MockHttpCache cache
;
5623 MockHttpRequest
request(kSimpleGET_Transaction
);
5625 Context
* c
= new Context();
5626 int rv
= cache
.CreateTransaction(&c
->trans
);
5629 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5630 if (rv
== ERR_IO_PENDING
)
5631 rv
= c
->callback
.WaitForResult();
5633 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5634 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5635 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5637 // Make sure that the entry has some data stored.
5638 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5639 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5640 if (rv
== ERR_IO_PENDING
)
5641 rv
= c
->callback
.WaitForResult();
5642 EXPECT_EQ(buf
->size(), rv
);
5644 // Destroy the transaction.
5647 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5649 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5650 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5651 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5654 // Tests that we delete an entry when the request is cancelled if the response
5655 // has an "Accept-Ranges: none" header.
5656 TEST(HttpCache
, DoomOnDestruction3
) {
5657 MockHttpCache cache
;
5659 MockTransaction
transaction(kSimpleGET_Transaction
);
5660 transaction
.response_headers
=
5661 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5662 "Content-Length: 22\n"
5663 "Accept-Ranges: none\n"
5664 "Etag: \"foopy\"\n";
5665 AddMockTransaction(&transaction
);
5666 MockHttpRequest
request(transaction
);
5668 Context
* c
= new Context();
5669 int rv
= cache
.CreateTransaction(&c
->trans
);
5672 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5673 if (rv
== ERR_IO_PENDING
)
5674 rv
= c
->callback
.WaitForResult();
5676 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5677 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5678 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5680 // Make sure that the entry has some data stored.
5681 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5682 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5683 if (rv
== ERR_IO_PENDING
)
5684 rv
= c
->callback
.WaitForResult();
5685 EXPECT_EQ(buf
->size(), rv
);
5687 // Destroy the transaction.
5690 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5692 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5693 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5694 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5696 RemoveMockTransaction(&transaction
);
5699 // Tests that we mark an entry as incomplete when the request is cancelled.
5700 TEST(HttpCache
, SetTruncatedFlag
) {
5701 MockHttpCache cache
;
5703 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5704 transaction
.response_headers
=
5705 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5706 "Content-Length: 22\n"
5707 "Etag: \"foopy\"\n";
5708 MockHttpRequest
request(transaction
);
5710 scoped_ptr
<Context
> c(new Context());
5712 int rv
= cache
.CreateTransaction(&c
->trans
);
5715 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5716 if (rv
== ERR_IO_PENDING
)
5717 rv
= c
->callback
.WaitForResult();
5719 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5720 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5721 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5723 // Make sure that the entry has some data stored.
5724 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5725 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5726 if (rv
== ERR_IO_PENDING
)
5727 rv
= c
->callback
.WaitForResult();
5728 EXPECT_EQ(buf
->size(), rv
);
5730 // We want to cancel the request when the transaction is busy.
5731 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5732 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5733 EXPECT_FALSE(c
->callback
.have_result());
5735 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5737 // Destroy the transaction.
5739 MockHttpCache::SetTestMode(0);
5742 // Make sure that we don't invoke the callback. We may have an issue if the
5743 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5744 // could end up with the transaction being deleted twice if we send any
5745 // notification from the transaction destructor (see http://crbug.com/31723).
5746 EXPECT_FALSE(c
->callback
.have_result());
5748 // Verify that the entry is marked as incomplete.
5749 VerifyTruncatedFlag(&cache
, kSimpleGET_Transaction
.url
, true, 0);
5752 // Tests that we don't mark an entry as truncated when we read everything.
5753 TEST(HttpCache
, DontSetTruncatedFlag
) {
5754 MockHttpCache cache
;
5756 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5757 transaction
.response_headers
=
5758 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5759 "Content-Length: 22\n"
5760 "Etag: \"foopy\"\n";
5761 MockHttpRequest
request(transaction
);
5763 scoped_ptr
<Context
> c(new Context());
5764 int rv
= cache
.CreateTransaction(&c
->trans
);
5767 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5768 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5771 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(22));
5772 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5773 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5775 // Destroy the transaction.
5778 // Verify that the entry is not marked as truncated.
5779 VerifyTruncatedFlag(&cache
, kSimpleGET_Transaction
.url
, false, 0);
5782 // Tests that sparse entries don't set the truncate flag.
5783 TEST(HttpCache
, RangeGET_DontTruncate
) {
5784 MockHttpCache cache
;
5786 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5787 transaction
.request_headers
= "Range: bytes = 0-19\r\n" EXTRA_HEADER
;
5789 scoped_ptr
<MockHttpRequest
> request(new MockHttpRequest(transaction
));
5790 scoped_ptr
<HttpTransaction
> trans
;
5792 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
5795 TestCompletionCallback cb
;
5796 rv
= trans
->Start(request
.get(), cb
.callback(), BoundNetLog());
5797 EXPECT_EQ(0, cb
.GetResult(rv
));
5799 scoped_refptr
<IOBuffer
> buf(new IOBuffer(10));
5800 rv
= trans
->Read(buf
.get(), 10, cb
.callback());
5801 EXPECT_EQ(10, cb
.GetResult(rv
));
5803 // Should not trigger any DCHECK.
5805 VerifyTruncatedFlag(&cache
, kRangeGET_TransactionOK
.url
, false, 0);
5808 // Tests that sparse entries don't set the truncate flag (when the byte range
5810 TEST(HttpCache
, RangeGET_DontTruncate2
) {
5811 MockHttpCache cache
;
5813 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5814 transaction
.request_headers
= "Range: bytes = 30-49\r\n" EXTRA_HEADER
;
5816 scoped_ptr
<MockHttpRequest
> request(new MockHttpRequest(transaction
));
5817 scoped_ptr
<HttpTransaction
> trans
;
5819 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
5822 TestCompletionCallback cb
;
5823 rv
= trans
->Start(request
.get(), cb
.callback(), BoundNetLog());
5824 EXPECT_EQ(0, cb
.GetResult(rv
));
5826 scoped_refptr
<IOBuffer
> buf(new IOBuffer(10));
5827 rv
= trans
->Read(buf
.get(), 10, cb
.callback());
5828 EXPECT_EQ(10, cb
.GetResult(rv
));
5830 // Should not trigger any DCHECK.
5832 VerifyTruncatedFlag(&cache
, kRangeGET_TransactionOK
.url
, false, 0);
5835 // Tests that we can continue with a request that was interrupted.
5836 TEST(HttpCache
, GET_IncompleteResource
) {
5837 MockHttpCache cache
;
5838 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5840 std::string
raw_headers("HTTP/1.1 200 OK\n"
5841 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5843 "Accept-Ranges: bytes\n"
5844 "Content-Length: 80\n");
5845 CreateTruncatedEntry(raw_headers
, &cache
);
5847 // Now make a regular request.
5848 std::string headers
;
5849 transaction
.request_headers
= EXTRA_HEADER
;
5850 transaction
.data
= kFullRangeData
;
5851 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5853 // We update the headers with the ones received while revalidating.
5854 std::string
expected_headers(
5856 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5857 "Accept-Ranges: bytes\n"
5859 "Content-Length: 80\n");
5861 EXPECT_EQ(expected_headers
, headers
);
5862 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5863 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5864 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5866 // Verify that the disk entry was updated.
5867 VerifyTruncatedFlag(&cache
, kRangeGET_TransactionOK
.url
, false, 80);
5870 // Tests the handling of no-store when revalidating a truncated entry.
5871 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5872 MockHttpCache cache
;
5873 AddMockTransaction(&kRangeGET_TransactionOK
);
5875 std::string
raw_headers("HTTP/1.1 200 OK\n"
5876 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5878 "Accept-Ranges: bytes\n"
5879 "Content-Length: 80\n");
5880 CreateTruncatedEntry(raw_headers
, &cache
);
5881 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5883 // Now make a regular request.
5884 MockTransaction
transaction(kRangeGET_TransactionOK
);
5885 transaction
.request_headers
= EXTRA_HEADER
;
5886 std::string
response_headers(transaction
.response_headers
);
5887 response_headers
+= ("Cache-Control: no-store\n");
5888 transaction
.response_headers
= response_headers
.c_str();
5889 transaction
.data
= kFullRangeData
;
5890 AddMockTransaction(&transaction
);
5892 std::string headers
;
5893 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5895 // We update the headers with the ones received while revalidating.
5896 std::string
expected_headers(
5898 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5899 "Accept-Ranges: bytes\n"
5900 "Cache-Control: no-store\n"
5902 "Content-Length: 80\n");
5904 EXPECT_EQ(expected_headers
, headers
);
5905 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5906 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5907 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5909 // Verify that the disk entry was deleted.
5910 disk_cache::Entry
* entry
;
5911 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5912 RemoveMockTransaction(&transaction
);
5915 // Tests cancelling a request after the server sent no-store.
5916 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5917 MockHttpCache cache
;
5918 AddMockTransaction(&kRangeGET_TransactionOK
);
5920 std::string
raw_headers("HTTP/1.1 200 OK\n"
5921 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5923 "Accept-Ranges: bytes\n"
5924 "Content-Length: 80\n");
5925 CreateTruncatedEntry(raw_headers
, &cache
);
5926 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5928 // Now make a regular request.
5929 MockTransaction
transaction(kRangeGET_TransactionOK
);
5930 transaction
.request_headers
= EXTRA_HEADER
;
5931 std::string
response_headers(transaction
.response_headers
);
5932 response_headers
+= ("Cache-Control: no-store\n");
5933 transaction
.response_headers
= response_headers
.c_str();
5934 transaction
.data
= kFullRangeData
;
5935 AddMockTransaction(&transaction
);
5937 MockHttpRequest
request(transaction
);
5938 Context
* c
= new Context();
5940 int rv
= cache
.CreateTransaction(&c
->trans
);
5943 // Queue another request to this transaction. We have to start this request
5944 // before the first one gets the response from the server and dooms the entry,
5945 // otherwise it will just create a new entry without being queued to the first
5947 Context
* pending
= new Context();
5948 ASSERT_EQ(OK
, cache
.CreateTransaction(&pending
->trans
));
5950 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5951 EXPECT_EQ(ERR_IO_PENDING
,
5952 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5954 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5956 // Make sure that the entry has some data stored.
5957 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5958 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5959 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5961 // Cancel the requests.
5965 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5966 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5967 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5969 base::MessageLoop::current()->RunUntilIdle();
5970 RemoveMockTransaction(&transaction
);
5973 // Tests that we delete truncated entries if the server changes its mind midway.
5974 TEST(HttpCache
, GET_IncompleteResource2
) {
5975 MockHttpCache cache
;
5976 AddMockTransaction(&kRangeGET_TransactionOK
);
5978 // Content-length will be intentionally bad.
5979 std::string
raw_headers("HTTP/1.1 200 OK\n"
5980 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5982 "Accept-Ranges: bytes\n"
5983 "Content-Length: 50\n");
5984 CreateTruncatedEntry(raw_headers
, &cache
);
5986 // Now make a regular request. We expect the code to fail the validation and
5987 // retry the request without using byte ranges.
5988 std::string headers
;
5989 MockTransaction
transaction(kRangeGET_TransactionOK
);
5990 transaction
.request_headers
= EXTRA_HEADER
;
5991 transaction
.data
= "Not a range";
5992 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5994 // The server will return 200 instead of a byte range.
5995 std::string
expected_headers(
5997 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5999 EXPECT_EQ(expected_headers
, headers
);
6000 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6001 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6002 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6004 // Verify that the disk entry was deleted.
6005 disk_cache::Entry
* entry
;
6006 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6007 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6010 // Tests that we always validate a truncated request.
6011 TEST(HttpCache
, GET_IncompleteResource3
) {
6012 MockHttpCache cache
;
6013 AddMockTransaction(&kRangeGET_TransactionOK
);
6015 // This should not require validation for 10 hours.
6016 std::string
raw_headers("HTTP/1.1 200 OK\n"
6017 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6019 "Cache-Control: max-age= 36000\n"
6020 "Accept-Ranges: bytes\n"
6021 "Content-Length: 80\n");
6022 CreateTruncatedEntry(raw_headers
, &cache
);
6024 // Now make a regular request.
6025 std::string headers
;
6026 MockTransaction
transaction(kRangeGET_TransactionOK
);
6027 transaction
.request_headers
= EXTRA_HEADER
;
6028 transaction
.data
= kFullRangeData
;
6030 scoped_ptr
<Context
> c(new Context
);
6031 int rv
= cache
.CreateTransaction(&c
->trans
);
6034 MockHttpRequest
request(transaction
);
6035 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6036 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6038 // We should have checked with the server before finishing Start().
6039 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6040 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6041 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6043 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6046 // Tests that we handle 401s for truncated resources.
6047 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
6048 MockHttpCache cache
;
6049 AddMockTransaction(&kRangeGET_TransactionOK
);
6051 std::string
raw_headers("HTTP/1.1 200 OK\n"
6052 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6054 "Accept-Ranges: bytes\n"
6055 "Content-Length: 80\n");
6056 CreateTruncatedEntry(raw_headers
, &cache
);
6058 // Now make a regular request.
6059 MockTransaction
transaction(kRangeGET_TransactionOK
);
6060 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
6062 transaction
.data
= kFullRangeData
;
6063 RangeTransactionServer handler
;
6065 scoped_ptr
<Context
> c(new Context
);
6066 int rv
= cache
.CreateTransaction(&c
->trans
);
6069 MockHttpRequest
request(transaction
);
6070 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6071 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6073 const HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
6074 ASSERT_TRUE(response
);
6075 ASSERT_EQ(401, response
->headers
->response_code());
6076 rv
= c
->trans
->RestartWithAuth(AuthCredentials(), c
->callback
.callback());
6077 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6078 response
= c
->trans
->GetResponseInfo();
6079 ASSERT_TRUE(response
);
6080 ASSERT_EQ(200, response
->headers
->response_code());
6082 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
6083 c
.reset(); // The destructor could delete the entry.
6084 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6086 // Verify that the entry was not deleted.
6087 disk_cache::Entry
* entry
;
6088 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6091 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6094 // Test that the transaction won't retry failed partial requests
6095 // after it starts reading data. http://crbug.com/474835
6096 TEST(HttpCache
, TransactionRetryLimit
) {
6097 MockHttpCache cache
;
6099 // Cache 0-9, so that we have data to read before failing.
6100 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
6101 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
6102 transaction
.data
= "rg: 00-09 ";
6104 // Write to the cache.
6105 RunTransactionTest(cache
.http_cache(), transaction
);
6106 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6108 // And now read from the cache and the network. 10-19 will get a
6109 // 401, but will have already returned 0-9.
6110 // We do not set X-Require-Mock-Auth because that causes the mock
6111 // network transaction to become IsReadyToRestartForAuth().
6112 transaction
.request_headers
=
6113 "Range: bytes = 0-79\r\n"
6114 "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER
;
6116 scoped_ptr
<Context
> c(new Context
);
6117 int rv
= cache
.CreateTransaction(&c
->trans
);
6120 MockHttpRequest
request(transaction
);
6122 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6123 if (rv
== ERR_IO_PENDING
)
6124 rv
= c
->callback
.WaitForResult();
6125 std::string content
;
6126 rv
= ReadTransaction(c
->trans
.get(), &content
);
6127 EXPECT_EQ(ERR_CACHE_AUTH_FAILURE_AFTER_READ
, rv
);
6130 // Tests that we cache a 200 response to the validation request.
6131 TEST(HttpCache
, GET_IncompleteResource4
) {
6132 MockHttpCache cache
;
6133 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
6135 std::string
raw_headers("HTTP/1.1 200 OK\n"
6136 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6138 "Accept-Ranges: bytes\n"
6139 "Content-Length: 80\n");
6140 CreateTruncatedEntry(raw_headers
, &cache
);
6142 // Now make a regular request.
6143 std::string headers
;
6144 transaction
.request_headers
= EXTRA_HEADER
;
6145 transaction
.data
= "Not a range";
6146 RangeTransactionServer handler
;
6147 handler
.set_bad_200(true);
6148 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
6150 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6151 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6152 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6154 // Verify that the disk entry was updated.
6155 VerifyTruncatedFlag(&cache
, kRangeGET_TransactionOK
.url
, false, 11);
6158 // Tests that when we cancel a request that was interrupted, we mark it again
6160 TEST(HttpCache
, GET_CancelIncompleteResource
) {
6161 MockHttpCache cache
;
6162 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
6164 std::string
raw_headers("HTTP/1.1 200 OK\n"
6165 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6167 "Accept-Ranges: bytes\n"
6168 "Content-Length: 80\n");
6169 CreateTruncatedEntry(raw_headers
, &cache
);
6171 // Now make a regular request.
6172 transaction
.request_headers
= EXTRA_HEADER
;
6174 MockHttpRequest
request(transaction
);
6175 Context
* c
= new Context();
6176 int rv
= cache
.CreateTransaction(&c
->trans
);
6179 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6180 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6182 // Read 20 bytes from the cache, and 10 from the net.
6183 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
6184 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
6185 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
6186 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
6187 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
6189 // At this point, we are already reading so canceling the request should leave
6193 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6194 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6195 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6197 // Verify that the disk entry was updated: now we have 30 bytes.
6198 VerifyTruncatedFlag(&cache
, kRangeGET_TransactionOK
.url
, true, 30);
6201 // Tests that we can handle range requests when we have a truncated entry.
6202 TEST(HttpCache
, RangeGET_IncompleteResource
) {
6203 MockHttpCache cache
;
6204 AddMockTransaction(&kRangeGET_TransactionOK
);
6206 // Content-length will be intentionally bogus.
6207 std::string
raw_headers("HTTP/1.1 200 OK\n"
6208 "Last-Modified: something\n"
6210 "Accept-Ranges: bytes\n"
6211 "Content-Length: 10\n");
6212 CreateTruncatedEntry(raw_headers
, &cache
);
6214 // Now make a range request.
6215 std::string headers
;
6216 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
6219 Verify206Response(headers
, 40, 49);
6220 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6221 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6222 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6224 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6227 TEST(HttpCache
, SyncRead
) {
6228 MockHttpCache cache
;
6230 // This test ensures that a read that completes synchronously does not cause
6233 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6234 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
6235 TEST_MODE_SYNC_CACHE_READ
|
6236 TEST_MODE_SYNC_CACHE_WRITE
);
6238 MockHttpRequest
r1(transaction
),
6242 TestTransactionConsumer
c1(DEFAULT_PRIORITY
, cache
.http_cache()),
6243 c2(DEFAULT_PRIORITY
, cache
.http_cache()),
6244 c3(DEFAULT_PRIORITY
, cache
.http_cache());
6246 c1
.Start(&r1
, BoundNetLog());
6248 r2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6249 c2
.Start(&r2
, BoundNetLog());
6251 r3
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6252 c3
.Start(&r3
, BoundNetLog());
6254 base::MessageLoop::current()->Run();
6256 EXPECT_TRUE(c1
.is_done());
6257 EXPECT_TRUE(c2
.is_done());
6258 EXPECT_TRUE(c3
.is_done());
6260 EXPECT_EQ(OK
, c1
.error());
6261 EXPECT_EQ(OK
, c2
.error());
6262 EXPECT_EQ(OK
, c3
.error());
6265 TEST(HttpCache
, ValidationResultsIn200
) {
6266 MockHttpCache cache
;
6268 // This test ensures that a conditional request, which results in a 200
6269 // instead of a 304, properly truncates the existing response data.
6271 // write to the cache
6272 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6274 // force this transaction to validate the cache
6275 MockTransaction
transaction(kETagGET_Transaction
);
6276 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
6277 RunTransactionTest(cache
.http_cache(), transaction
);
6279 // read from the cache
6280 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6283 TEST(HttpCache
, CachedRedirect
) {
6284 MockHttpCache cache
;
6286 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
6287 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
6288 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
6290 MockHttpRequest
request(kTestTransaction
);
6291 TestCompletionCallback callback
;
6293 // Write to the cache.
6295 scoped_ptr
<HttpTransaction
> trans
;
6296 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6298 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6299 if (rv
== ERR_IO_PENDING
)
6300 rv
= callback
.WaitForResult();
6303 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6306 EXPECT_EQ(info
->headers
->response_code(), 301);
6308 std::string location
;
6309 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6310 EXPECT_EQ(location
, "http://www.bar.com/");
6312 // Mark the transaction as completed so it is cached.
6313 trans
->DoneReading();
6315 // Destroy transaction when going out of scope. We have not actually
6316 // read the response body -- want to test that it is still getting cached.
6318 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6319 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6320 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6322 // Active entries in the cache are not retired synchronously. Make
6323 // sure the next run hits the MockHttpCache and open_count is
6325 base::MessageLoop::current()->RunUntilIdle();
6327 // Read from the cache.
6329 scoped_ptr
<HttpTransaction
> trans
;
6330 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6332 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6333 if (rv
== ERR_IO_PENDING
)
6334 rv
= callback
.WaitForResult();
6337 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6340 EXPECT_EQ(info
->headers
->response_code(), 301);
6342 std::string location
;
6343 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6344 EXPECT_EQ(location
, "http://www.bar.com/");
6346 // Mark the transaction as completed so it is cached.
6347 trans
->DoneReading();
6349 // Destroy transaction when going out of scope. We have not actually
6350 // read the response body -- want to test that it is still getting cached.
6352 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6353 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6354 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6357 // Verify that no-cache resources are stored in cache, but are not fetched from
6358 // cache during normal loads.
6359 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
6360 MockHttpCache cache
;
6362 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6363 transaction
.response_headers
= "cache-control: no-cache\n";
6366 RunTransactionTest(cache
.http_cache(), transaction
);
6368 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6369 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6370 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6372 // Try loading again; it should result in a network fetch.
6373 RunTransactionTest(cache
.http_cache(), transaction
);
6375 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6376 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6377 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6379 disk_cache::Entry
* entry
;
6380 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6384 // Verify that no-cache resources are stored in cache and fetched from cache
6385 // when the LOAD_PREFERRING_CACHE flag is set.
6386 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
6387 MockHttpCache cache
;
6389 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6390 transaction
.response_headers
= "cache-control: no-cache\n";
6393 RunTransactionTest(cache
.http_cache(), transaction
);
6395 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6396 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6397 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6399 // Try loading again with LOAD_PREFERRING_CACHE.
6400 transaction
.load_flags
= LOAD_PREFERRING_CACHE
;
6401 RunTransactionTest(cache
.http_cache(), transaction
);
6403 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6404 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6405 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6407 disk_cache::Entry
* entry
;
6408 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6412 TEST(HttpCache
, CacheControlNoStore
) {
6413 MockHttpCache cache
;
6415 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6416 transaction
.response_headers
= "cache-control: no-store\n";
6419 RunTransactionTest(cache
.http_cache(), transaction
);
6421 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6422 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6423 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6425 // try loading again; it should result in a network fetch
6426 RunTransactionTest(cache
.http_cache(), transaction
);
6428 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6429 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6430 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6432 disk_cache::Entry
* entry
;
6433 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6436 TEST(HttpCache
, CacheControlNoStore2
) {
6437 // this test is similar to the above test, except that the initial response
6438 // is cachable, but when it is validated, no-store is received causing the
6439 // cached document to be deleted.
6440 MockHttpCache cache
;
6442 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6445 RunTransactionTest(cache
.http_cache(), transaction
);
6447 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6448 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6449 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6451 // try loading again; it should result in a network fetch
6452 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6453 transaction
.response_headers
= "cache-control: no-store\n";
6454 RunTransactionTest(cache
.http_cache(), transaction
);
6456 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6457 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6458 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6460 disk_cache::Entry
* entry
;
6461 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6464 TEST(HttpCache
, CacheControlNoStore3
) {
6465 // this test is similar to the above test, except that the response is a 304
6466 // instead of a 200. this should never happen in practice, but it seems like
6467 // a good thing to verify that we still destroy the cache entry.
6468 MockHttpCache cache
;
6470 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6473 RunTransactionTest(cache
.http_cache(), transaction
);
6475 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6476 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6477 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6479 // try loading again; it should result in a network fetch
6480 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6481 transaction
.response_headers
= "cache-control: no-store\n";
6482 transaction
.status
= "HTTP/1.1 304 Not Modified";
6483 RunTransactionTest(cache
.http_cache(), transaction
);
6485 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6486 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6487 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6489 disk_cache::Entry
* entry
;
6490 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6493 // Ensure that we don't cache requests served over bad HTTPS.
6494 TEST(HttpCache
, SimpleGET_SSLError
) {
6495 MockHttpCache cache
;
6497 MockTransaction transaction
= kSimpleGET_Transaction
;
6498 transaction
.cert_status
= CERT_STATUS_REVOKED
;
6499 ScopedMockTransaction
scoped_transaction(transaction
);
6501 // write to the cache
6502 RunTransactionTest(cache
.http_cache(), transaction
);
6504 // Test that it was not cached.
6505 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6507 MockHttpRequest
request(transaction
);
6508 TestCompletionCallback callback
;
6510 scoped_ptr
<HttpTransaction
> trans
;
6511 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6513 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6514 if (rv
== ERR_IO_PENDING
)
6515 rv
= callback
.WaitForResult();
6516 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
6519 // Ensure that we don't crash by if left-behind transactions.
6520 TEST(HttpCache
, OutlivedTransactions
) {
6521 MockHttpCache
* cache
= new MockHttpCache
;
6523 scoped_ptr
<HttpTransaction
> trans
;
6524 EXPECT_EQ(OK
, cache
->CreateTransaction(&trans
));
6530 // Test that the disabled mode works.
6531 TEST(HttpCache
, CacheDisabledMode
) {
6532 MockHttpCache cache
;
6534 // write to the cache
6535 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6537 // go into disabled mode
6538 cache
.http_cache()->set_mode(HttpCache::DISABLE
);
6540 // force this transaction to write to the cache again
6541 MockTransaction
transaction(kSimpleGET_Transaction
);
6543 RunTransactionTest(cache
.http_cache(), transaction
);
6545 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6546 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6547 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6550 // Other tests check that the response headers of the cached response
6551 // get updated on 304. Here we specifically check that the
6552 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6553 // fields also gets updated.
6554 // http://crbug.com/20594.
6555 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6556 MockHttpCache cache
;
6558 const char kUrl
[] = "http://foobar";
6559 const char kData
[] = "body";
6561 MockTransaction mock_network_response
= { 0 };
6562 mock_network_response
.url
= kUrl
;
6564 AddMockTransaction(&mock_network_response
);
6566 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6568 MockTransaction request
= { 0 };
6570 request
.method
= "GET";
6571 request
.request_headers
= "\r\n";
6572 request
.data
= kData
;
6574 static const Response kNetResponse1
= {
6576 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6577 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6581 kNetResponse1
.AssignTo(&mock_network_response
);
6583 RunTransactionTest(cache
.http_cache(), request
);
6585 // Request |kUrl| again, this time validating the cache and getting
6588 request
.load_flags
= LOAD_VALIDATE_CACHE
;
6590 static const Response kNetResponse2
= {
6591 "HTTP/1.1 304 Not Modified",
6592 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6596 kNetResponse2
.AssignTo(&mock_network_response
);
6598 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6599 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6601 mock_network_response
.request_time
= request_time
;
6602 mock_network_response
.response_time
= response_time
;
6604 HttpResponseInfo response
;
6605 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6607 // The request and response times should have been updated.
6608 EXPECT_EQ(request_time
.ToInternalValue(),
6609 response
.request_time
.ToInternalValue());
6610 EXPECT_EQ(response_time
.ToInternalValue(),
6611 response
.response_time
.ToInternalValue());
6613 std::string headers
;
6614 response
.headers
->GetNormalizedHeaders(&headers
);
6616 EXPECT_EQ("HTTP/1.1 200 OK\n"
6617 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6618 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6621 RemoveMockTransaction(&mock_network_response
);
6624 // Tests that we can write metadata to an entry.
6625 TEST(HttpCache
, WriteMetadata_OK
) {
6626 MockHttpCache cache
;
6628 // Write to the cache
6629 HttpResponseInfo response
;
6630 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6632 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6635 cache
.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY
, Time::Now(),
6638 // Write meta data to the same entry.
6639 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6640 memset(buf
->data(), 0, buf
->size());
6641 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6642 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6643 DEFAULT_PRIORITY
, response
.response_time
,
6644 buf
.get(), buf
->size());
6646 // Release the buffer before the operation takes place.
6649 // Makes sure we finish pending operations.
6650 base::MessageLoop::current()->RunUntilIdle();
6652 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6654 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6655 EXPECT_EQ(50, response
.metadata
->size());
6656 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6658 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6659 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6660 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6663 // Tests that we only write metadata to an entry if the time stamp matches.
6664 TEST(HttpCache
, WriteMetadata_Fail
) {
6665 MockHttpCache cache
;
6667 // Write to the cache
6668 HttpResponseInfo response
;
6669 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6671 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6673 // Attempt to write meta data to the same entry.
6674 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6675 memset(buf
->data(), 0, buf
->size());
6676 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6677 base::Time expected_time
= response
.response_time
-
6678 base::TimeDelta::FromMilliseconds(20);
6679 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6680 DEFAULT_PRIORITY
, expected_time
, buf
.get(),
6683 // Makes sure we finish pending operations.
6684 base::MessageLoop::current()->RunUntilIdle();
6686 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6688 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6690 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6691 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6692 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6695 // Tests that we can read metadata after validating the entry and with READ mode
6697 TEST(HttpCache
, ReadMetadata
) {
6698 MockHttpCache cache
;
6700 // Write to the cache
6701 HttpResponseInfo response
;
6702 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6703 kTypicalGET_Transaction
, &response
);
6704 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6706 // Write meta data to the same entry.
6707 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6708 memset(buf
->data(), 0, buf
->size());
6709 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6710 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6711 DEFAULT_PRIORITY
, response
.response_time
,
6712 buf
.get(), buf
->size());
6714 // Makes sure we finish pending operations.
6715 base::MessageLoop::current()->RunUntilIdle();
6717 // Start with a READ mode transaction.
6718 MockTransaction
trans1(kTypicalGET_Transaction
);
6719 trans1
.load_flags
= LOAD_ONLY_FROM_CACHE
;
6721 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6722 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6723 EXPECT_EQ(50, response
.metadata
->size());
6724 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6726 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6727 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6728 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6729 base::MessageLoop::current()->RunUntilIdle();
6731 // Now make sure that the entry is re-validated with the server.
6732 trans1
.load_flags
= LOAD_VALIDATE_CACHE
;
6733 trans1
.status
= "HTTP/1.1 304 Not Modified";
6734 AddMockTransaction(&trans1
);
6736 response
.metadata
= NULL
;
6737 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6738 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6740 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6741 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6742 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6743 base::MessageLoop::current()->RunUntilIdle();
6744 RemoveMockTransaction(&trans1
);
6746 // Now return 200 when validating the entry so the metadata will be lost.
6747 MockTransaction
trans2(kTypicalGET_Transaction
);
6748 trans2
.load_flags
= LOAD_VALIDATE_CACHE
;
6749 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6750 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6752 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6753 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6754 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6757 // Tests that we don't mark entries as truncated when a filter detects the end
6759 TEST(HttpCache
, FilterCompletion
) {
6760 MockHttpCache cache
;
6761 TestCompletionCallback callback
;
6764 scoped_ptr
<HttpTransaction
> trans
;
6765 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6767 MockHttpRequest
request(kSimpleGET_Transaction
);
6768 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6769 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6771 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6772 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6773 EXPECT_GT(callback
.GetResult(rv
), 0);
6775 // Now make sure that the entry is preserved.
6776 trans
->DoneReading();
6779 // Make sure that the ActiveEntry is gone.
6780 base::MessageLoop::current()->RunUntilIdle();
6782 // Read from the cache.
6783 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6785 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6786 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6787 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6790 // Tests that we don't mark entries as truncated and release the cache
6791 // entry when DoneReading() is called before any Read() calls, such as
6793 TEST(HttpCache
, DoneReading
) {
6794 MockHttpCache cache
;
6795 TestCompletionCallback callback
;
6797 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6798 transaction
.data
= "";
6800 scoped_ptr
<HttpTransaction
> trans
;
6801 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6803 MockHttpRequest
request(transaction
);
6804 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6805 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6807 trans
->DoneReading();
6808 // Leave the transaction around.
6810 // Make sure that the ActiveEntry is gone.
6811 base::MessageLoop::current()->RunUntilIdle();
6813 // Read from the cache. This should not deadlock.
6814 RunTransactionTest(cache
.http_cache(), transaction
);
6816 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6817 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6818 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6821 // Tests that we stop caching when told.
6822 TEST(HttpCache
, StopCachingDeletesEntry
) {
6823 MockHttpCache cache
;
6824 TestCompletionCallback callback
;
6825 MockHttpRequest
request(kSimpleGET_Transaction
);
6828 scoped_ptr
<HttpTransaction
> trans
;
6829 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6831 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6832 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6834 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6835 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6836 EXPECT_EQ(10, callback
.GetResult(rv
));
6838 trans
->StopCaching();
6840 // We should be able to keep reading.
6841 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6842 EXPECT_GT(callback
.GetResult(rv
), 0);
6843 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6844 EXPECT_EQ(0, callback
.GetResult(rv
));
6847 // Make sure that the ActiveEntry is gone.
6848 base::MessageLoop::current()->RunUntilIdle();
6850 // Verify that the entry is gone.
6851 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6853 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6854 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6855 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6858 // Tests that we stop caching when told, even if DoneReading is called
6859 // after StopCaching.
6860 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6861 MockHttpCache cache
;
6862 TestCompletionCallback callback
;
6863 MockHttpRequest
request(kSimpleGET_Transaction
);
6866 scoped_ptr
<HttpTransaction
> trans
;
6867 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6869 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6870 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6872 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6873 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6874 EXPECT_EQ(10, callback
.GetResult(rv
));
6876 trans
->StopCaching();
6878 // We should be able to keep reading.
6879 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6880 EXPECT_GT(callback
.GetResult(rv
), 0);
6881 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6882 EXPECT_EQ(0, callback
.GetResult(rv
));
6884 // We should be able to call DoneReading.
6885 trans
->DoneReading();
6888 // Make sure that the ActiveEntry is gone.
6889 base::MessageLoop::current()->RunUntilIdle();
6891 // Verify that the entry is gone.
6892 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6894 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6895 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6896 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6899 // Tests that we stop caching when told, when using auth.
6900 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6901 MockHttpCache cache
;
6902 TestCompletionCallback callback
;
6903 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6904 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6905 AddMockTransaction(&mock_transaction
);
6906 MockHttpRequest
request(mock_transaction
);
6909 scoped_ptr
<HttpTransaction
> trans
;
6910 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6912 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6913 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6915 trans
->StopCaching();
6917 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6918 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6919 EXPECT_EQ(callback
.GetResult(rv
), 10);
6921 RemoveMockTransaction(&mock_transaction
);
6923 // Make sure that the ActiveEntry is gone.
6924 base::MessageLoop::current()->RunUntilIdle();
6926 // Verify that the entry is gone.
6927 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6929 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6930 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6931 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6934 // Tests that when we are told to stop caching we don't throw away valid data.
6935 TEST(HttpCache
, StopCachingSavesEntry
) {
6936 MockHttpCache cache
;
6937 TestCompletionCallback callback
;
6938 MockHttpRequest
request(kSimpleGET_Transaction
);
6941 scoped_ptr
<HttpTransaction
> trans
;
6942 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6944 // Force a response that can be resumed.
6945 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
6946 AddMockTransaction(&mock_transaction
);
6947 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6948 "Content-Length: 42\n"
6951 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6952 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6954 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6955 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6956 EXPECT_EQ(callback
.GetResult(rv
), 10);
6958 trans
->StopCaching();
6960 // We should be able to keep reading.
6961 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6962 EXPECT_GT(callback
.GetResult(rv
), 0);
6963 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6964 EXPECT_EQ(callback
.GetResult(rv
), 0);
6967 // Verify that the entry is marked as incomplete.
6968 VerifyTruncatedFlag(&cache
, kSimpleGET_Transaction
.url
, true, 0);
6971 // Tests that we handle truncated enries when StopCaching is called.
6972 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6973 MockHttpCache cache
;
6974 TestCompletionCallback callback
;
6975 MockHttpRequest
request(kRangeGET_TransactionOK
);
6976 request
.extra_headers
.Clear();
6977 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6978 AddMockTransaction(&kRangeGET_TransactionOK
);
6980 std::string
raw_headers("HTTP/1.1 200 OK\n"
6981 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6983 "Accept-Ranges: bytes\n"
6984 "Content-Length: 80\n");
6985 CreateTruncatedEntry(raw_headers
, &cache
);
6988 // Now make a regular request.
6989 scoped_ptr
<HttpTransaction
> trans
;
6990 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6992 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6993 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6995 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6996 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6997 EXPECT_EQ(callback
.GetResult(rv
), 10);
6999 // This is actually going to do nothing.
7000 trans
->StopCaching();
7002 // We should be able to keep reading.
7003 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
7004 EXPECT_GT(callback
.GetResult(rv
), 0);
7005 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
7006 EXPECT_GT(callback
.GetResult(rv
), 0);
7007 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
7008 EXPECT_EQ(callback
.GetResult(rv
), 0);
7011 // Verify that the disk entry was updated.
7012 VerifyTruncatedFlag(&cache
, kRangeGET_TransactionOK
.url
, false, 80);
7013 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7016 // Tests that we detect truncated resources from the net when there is
7017 // a Content-Length header.
7018 TEST(HttpCache
, TruncatedByContentLength
) {
7019 MockHttpCache cache
;
7020 TestCompletionCallback callback
;
7022 MockTransaction
transaction(kSimpleGET_Transaction
);
7023 AddMockTransaction(&transaction
);
7024 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
7025 "Content-Length: 100\n";
7026 RunTransactionTest(cache
.http_cache(), transaction
);
7027 RemoveMockTransaction(&transaction
);
7029 // Read from the cache.
7030 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
7032 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7033 EXPECT_EQ(0, cache
.disk_cache()->open_count());
7034 EXPECT_EQ(2, cache
.disk_cache()->create_count());
7037 // Tests that we actually flag entries as truncated when we detect an error
7039 TEST(HttpCache
, TruncatedByContentLength2
) {
7040 MockHttpCache cache
;
7041 TestCompletionCallback callback
;
7043 MockTransaction
transaction(kSimpleGET_Transaction
);
7044 AddMockTransaction(&transaction
);
7045 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
7046 "Content-Length: 100\n"
7048 RunTransactionTest(cache
.http_cache(), transaction
);
7049 RemoveMockTransaction(&transaction
);
7051 // Verify that the entry is marked as incomplete.
7052 VerifyTruncatedFlag(&cache
, kSimpleGET_Transaction
.url
, true, 0);
7055 // Make sure that calling SetPriority on a cache transaction passes on
7056 // its priority updates to its underlying network transaction.
7057 TEST(HttpCache
, SetPriority
) {
7058 MockHttpCache cache
;
7060 scoped_ptr
<HttpTransaction
> trans
;
7061 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
7063 // Shouldn't crash, but doesn't do anything either.
7064 trans
->SetPriority(LOW
);
7066 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7067 EXPECT_EQ(DEFAULT_PRIORITY
,
7068 cache
.network_layer()->last_create_transaction_priority());
7070 HttpRequestInfo info
;
7071 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7072 TestCompletionCallback callback
;
7073 EXPECT_EQ(ERR_IO_PENDING
,
7074 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7076 EXPECT_TRUE(cache
.network_layer()->last_transaction());
7077 if (cache
.network_layer()->last_transaction()) {
7078 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
7079 EXPECT_EQ(LOW
, cache
.network_layer()->last_transaction()->priority());
7082 trans
->SetPriority(HIGHEST
);
7084 if (cache
.network_layer()->last_transaction()) {
7085 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
7086 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_transaction()->priority());
7089 EXPECT_EQ(OK
, callback
.WaitForResult());
7092 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7093 // transaction passes on its argument to the underlying network transaction.
7094 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
7095 MockHttpCache cache
;
7097 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
7098 scoped_ptr
<HttpTransaction
> trans
;
7099 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
7101 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7103 HttpRequestInfo info
;
7104 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7105 TestCompletionCallback callback
;
7106 EXPECT_EQ(ERR_IO_PENDING
,
7107 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7109 ASSERT_TRUE(cache
.network_layer()->last_transaction());
7110 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
7111 websocket_handshake_stream_create_helper());
7112 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
7113 EXPECT_EQ(&create_helper
,
7114 cache
.network_layer()->last_transaction()->
7115 websocket_handshake_stream_create_helper());
7116 EXPECT_EQ(OK
, callback
.WaitForResult());
7119 // Make sure that a cache transaction passes on its priority to
7120 // newly-created network transactions.
7121 TEST(HttpCache
, SetPriorityNewTransaction
) {
7122 MockHttpCache cache
;
7123 AddMockTransaction(&kRangeGET_TransactionOK
);
7125 std::string
raw_headers("HTTP/1.1 200 OK\n"
7126 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7128 "Accept-Ranges: bytes\n"
7129 "Content-Length: 80\n");
7130 CreateTruncatedEntry(raw_headers
, &cache
);
7132 // Now make a regular request.
7133 std::string headers
;
7134 MockTransaction
transaction(kRangeGET_TransactionOK
);
7135 transaction
.request_headers
= EXTRA_HEADER
;
7136 transaction
.data
= kFullRangeData
;
7138 scoped_ptr
<HttpTransaction
> trans
;
7139 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(MEDIUM
, &trans
));
7140 EXPECT_EQ(DEFAULT_PRIORITY
,
7141 cache
.network_layer()->last_create_transaction_priority());
7143 MockHttpRequest
info(transaction
);
7144 TestCompletionCallback callback
;
7145 EXPECT_EQ(ERR_IO_PENDING
,
7146 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7147 EXPECT_EQ(OK
, callback
.WaitForResult());
7149 EXPECT_EQ(MEDIUM
, cache
.network_layer()->last_create_transaction_priority());
7151 trans
->SetPriority(HIGHEST
);
7152 // Should trigger a new network transaction and pick up the new
7154 ReadAndVerifyTransaction(trans
.get(), transaction
);
7156 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_create_transaction_priority());
7158 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7163 void RunTransactionAndGetNetworkBytes(MockHttpCache
& cache
,
7164 const MockTransaction
& trans_info
,
7165 int64_t* sent_bytes
,
7166 int64_t* received_bytes
) {
7167 RunTransactionTestBase(cache
.http_cache(), trans_info
,
7168 MockHttpRequest(trans_info
), nullptr, BoundNetLog(),
7169 nullptr, sent_bytes
, received_bytes
);
7174 TEST(HttpCache
, NetworkBytesCacheMissAndThenHit
) {
7175 MockHttpCache cache
;
7177 MockTransaction
transaction(kSimpleGET_Transaction
);
7178 int64_t sent
, received
;
7179 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7180 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7181 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7183 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7185 EXPECT_EQ(0, received
);
7188 TEST(HttpCache
, NetworkBytesConditionalRequest304
) {
7189 MockHttpCache cache
;
7191 ScopedMockTransaction
transaction(kETagGET_Transaction
);
7192 int64_t sent
, received
;
7193 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7194 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7195 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7197 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
7198 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
7199 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7200 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7201 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7204 TEST(HttpCache
, NetworkBytesConditionalRequest200
) {
7205 MockHttpCache cache
;
7207 MockTransaction
transaction(kTypicalGET_Transaction
);
7208 transaction
.request_headers
= "Foo: bar\r\n";
7209 transaction
.response_headers
=
7210 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7211 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7213 "Cache-Control: max-age=0\n"
7215 AddMockTransaction(&transaction
);
7216 int64_t sent
, received
;
7217 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7218 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7219 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7221 RevalidationServer server
;
7222 transaction
.handler
= server
.Handler
;
7223 transaction
.request_headers
= "Foo: none\r\n";
7224 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7225 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7226 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7228 RemoveMockTransaction(&transaction
);
7231 TEST(HttpCache
, NetworkBytesRange
) {
7232 MockHttpCache cache
;
7233 AddMockTransaction(&kRangeGET_TransactionOK
);
7234 MockTransaction
transaction(kRangeGET_TransactionOK
);
7236 // Read bytes 40-49 from the network.
7237 int64_t sent
, received
;
7238 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7239 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7240 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7242 // Read bytes 40-49 from the cache.
7243 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7245 EXPECT_EQ(0, received
);
7246 base::MessageLoop::current()->RunUntilIdle();
7248 // Read bytes 30-39 from the network.
7249 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
7250 transaction
.data
= "rg: 30-39 ";
7251 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7252 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
, sent
);
7253 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
, received
);
7254 base::MessageLoop::current()->RunUntilIdle();
7256 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7257 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
7258 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7259 RunTransactionAndGetNetworkBytes(cache
, transaction
, &sent
, &received
);
7260 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes
* 2, sent
);
7261 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes
* 2, received
);
7263 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7266 class HttpCachePrefetchValidationTest
: public ::testing::Test
{
7268 static const int kMaxAgeSecs
= 100;
7269 static const int kRequireValidationSecs
= kMaxAgeSecs
+ 1;
7271 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction
) {
7272 DCHECK_LT(kMaxAgeSecs
, prefetch_reuse_mins() * kNumSecondsPerMinute
);
7274 clock_
= new base::SimpleTestClock();
7275 cache_
.http_cache()->SetClockForTesting(make_scoped_ptr(clock_
));
7276 cache_
.network_layer()->SetClock(clock_
);
7278 transaction_
.response_headers
= "Cache-Control: max-age=100\n";
7281 bool TransactionRequiredNetwork(int load_flags
) {
7282 int pre_transaction_count
= transaction_count();
7283 transaction_
.load_flags
= load_flags
;
7284 RunTransactionTest(cache_
.http_cache(), transaction_
);
7285 return pre_transaction_count
!= transaction_count();
7288 void AdvanceTime(int seconds
) {
7289 clock_
->Advance(base::TimeDelta::FromSeconds(seconds
));
7292 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins
; }
7294 // How many times this test has sent requests to the (fake) origin
7295 // server. Every test case needs to make at least one request to initialise
7297 int transaction_count() {
7298 return cache_
.network_layer()->transaction_count();
7301 MockHttpCache cache_
;
7302 ScopedMockTransaction transaction_
;
7303 std::string response_headers_
;
7304 base::SimpleTestClock
* clock_
;
7307 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationShortlyAfterPrefetch
) {
7308 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7309 AdvanceTime(kRequireValidationSecs
);
7310 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7313 TEST_F(HttpCachePrefetchValidationTest
, ValidateLongAfterPrefetch
) {
7314 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7315 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute
);
7316 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7319 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceOnly
) {
7320 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7321 AdvanceTime(kRequireValidationSecs
);
7322 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7323 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7326 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceReadOnly
) {
7327 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7328 AdvanceTime(kRequireValidationSecs
);
7329 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE
));
7330 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7333 TEST_F(HttpCachePrefetchValidationTest
, BypassCacheOverwritesPrefetch
) {
7334 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7335 AdvanceTime(kRequireValidationSecs
);
7336 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE
));
7337 AdvanceTime(kRequireValidationSecs
);
7338 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7341 TEST_F(HttpCachePrefetchValidationTest
,
7342 SkipValidationOnExistingEntryThatNeedsValidation
) {
7343 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7344 AdvanceTime(kRequireValidationSecs
);
7345 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7346 AdvanceTime(kRequireValidationSecs
);
7347 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7348 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7351 TEST_F(HttpCachePrefetchValidationTest
,
7352 SkipValidationOnExistingEntryThatDoesNotNeedValidation
) {
7353 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7354 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7355 AdvanceTime(kRequireValidationSecs
);
7356 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7357 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7360 TEST_F(HttpCachePrefetchValidationTest
, PrefetchMultipleTimes
) {
7361 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7362 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7363 AdvanceTime(kRequireValidationSecs
);
7364 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7367 TEST_F(HttpCachePrefetchValidationTest
, ValidateOnDelayedSecondPrefetch
) {
7368 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7369 AdvanceTime(kRequireValidationSecs
);
7370 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7371 AdvanceTime(kRequireValidationSecs
);
7372 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7375 static void CheckResourceFreshnessHeader(const HttpRequestInfo
* request
,
7376 std::string
* response_status
,
7377 std::string
* response_headers
,
7378 std::string
* response_data
) {
7380 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
7381 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
7384 // Verify that the Resource-Freshness header is sent on a revalidation if the
7385 // stale-while-revalidate directive was on the response.
7386 TEST(HttpCache
, ResourceFreshnessHeaderSent
) {
7387 MockHttpCache cache
;
7389 ScopedMockTransaction
stale_while_revalidate_transaction(
7390 kSimpleGET_Transaction
);
7391 stale_while_revalidate_transaction
.response_headers
=
7392 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7394 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
7396 // Write to the cache.
7397 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7399 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7401 // Send the request again and check that Resource-Freshness header is added.
7402 stale_while_revalidate_transaction
.handler
= CheckResourceFreshnessHeader
;
7404 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7406 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7409 static void CheckResourceFreshnessAbsent(const HttpRequestInfo
* request
,
7410 std::string
* response_status
,
7411 std::string
* response_headers
,
7412 std::string
* response_data
) {
7413 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7416 // Verify that the Resource-Freshness header is not sent when
7417 // stale-while-revalidate is 0.
7418 TEST(HttpCache
, ResourceFreshnessHeaderNotSent
) {
7419 MockHttpCache cache
;
7421 ScopedMockTransaction
stale_while_revalidate_transaction(
7422 kSimpleGET_Transaction
);
7423 stale_while_revalidate_transaction
.response_headers
=
7424 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7426 "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
7428 // Write to the cache.
7429 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7431 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7433 // Send the request again and check that Resource-Freshness header is absent.
7434 stale_while_revalidate_transaction
.handler
= CheckResourceFreshnessAbsent
;
7436 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7438 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7441 TEST(HttpCache
, StaleContentNotUsedWhenLoadFlagNotSet
) {
7442 MockHttpCache cache
;
7444 ScopedMockTransaction
stale_while_revalidate_transaction(
7445 kSimpleGET_Transaction
);
7447 stale_while_revalidate_transaction
.response_headers
=
7448 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7450 "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
7452 // Write to the cache.
7453 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7455 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7457 // Send the request again and check that it is sent to the network again.
7458 HttpResponseInfo response_info
;
7459 RunTransactionTestWithResponseInfo(
7460 cache
.http_cache(), stale_while_revalidate_transaction
, &response_info
);
7462 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7463 EXPECT_FALSE(response_info
.async_revalidation_required
);
7466 TEST(HttpCache
, StaleContentUsedWhenLoadFlagSetAndUsable
) {
7467 MockHttpCache cache
;
7469 ScopedMockTransaction
stale_while_revalidate_transaction(
7470 kSimpleGET_Transaction
);
7471 stale_while_revalidate_transaction
.load_flags
|=
7472 LOAD_SUPPORT_ASYNC_REVALIDATION
;
7473 stale_while_revalidate_transaction
.response_headers
=
7474 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7476 "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
7478 // Write to the cache.
7479 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7481 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7483 // Send the request again and check that it is not sent to the network again.
7484 HttpResponseInfo response_info
;
7485 RunTransactionTestWithResponseInfo(
7486 cache
.http_cache(), stale_while_revalidate_transaction
, &response_info
);
7488 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7489 EXPECT_TRUE(response_info
.async_revalidation_required
);
7492 TEST(HttpCache
, StaleContentNotUsedWhenUnusable
) {
7493 MockHttpCache cache
;
7495 ScopedMockTransaction
stale_while_revalidate_transaction(
7496 kSimpleGET_Transaction
);
7497 stale_while_revalidate_transaction
.load_flags
|=
7498 LOAD_SUPPORT_ASYNC_REVALIDATION
;
7499 stale_while_revalidate_transaction
.response_headers
=
7500 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7502 "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
7504 // Write to the cache.
7505 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
7507 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7509 // Send the request again and check that it is sent to the network again.
7510 HttpResponseInfo response_info
;
7511 RunTransactionTestWithResponseInfo(
7512 cache
.http_cache(), stale_while_revalidate_transaction
, &response_info
);
7514 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7515 EXPECT_FALSE(response_info
.async_revalidation_required
);
7518 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7519 // take place on a sparse entry.
7520 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7521 MockHttpCache cache
;
7523 // Create a transaction for bytes 0-9.
7524 MockHttpRequest
request(kRangeGET_TransactionOK
);
7525 MockTransaction
transaction(kRangeGET_TransactionOK
);
7526 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7527 transaction
.data
= "rg: 00-09 ";
7528 AddMockTransaction(&transaction
);
7530 TestCompletionCallback callback
;
7531 scoped_ptr
<HttpTransaction
> trans
;
7532 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
7534 ASSERT_TRUE(trans
.get());
7536 // Start our transaction.
7537 trans
->Start(&request
, callback
.callback(), BoundNetLog());
7539 // A second transaction on a different part of the file (the default
7540 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7541 // the already pending transaction.
7542 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7544 // Let the first transaction complete.
7545 callback
.WaitForResult();
7547 RemoveMockTransaction(&transaction
);
7550 // Makes sure that a request stops using the cache when the response headers
7551 // with "Cache-Control: no-store" arrives. That means that another request for
7552 // the same URL can be processed before the response body of the original
7554 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7555 MockHttpCache cache
;
7556 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7557 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7558 MockHttpRequest
request(mock_transaction
);
7560 scoped_ptr
<Context
> first(new Context
);
7561 first
->result
= cache
.CreateTransaction(&first
->trans
);
7562 ASSERT_EQ(OK
, first
->result
);
7563 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7565 first
->trans
->Start(&request
, first
->callback
.callback(), BoundNetLog());
7566 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7568 base::MessageLoop::current()->RunUntilIdle();
7569 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7570 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7571 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7572 "Cache-Control", "no-store"));
7573 // Here we have read the response header but not read the response body yet.
7575 // Let us create the second (read) transaction.
7576 scoped_ptr
<Context
> second(new Context
);
7577 second
->result
= cache
.CreateTransaction(&second
->trans
);
7578 ASSERT_EQ(OK
, second
->result
);
7579 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7580 second
->result
= second
->trans
->Start(&request
, second
->callback
.callback(),
7583 // Here the second transaction proceeds without reading the first body.
7584 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7585 base::MessageLoop::current()->RunUntilIdle();
7586 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7587 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7588 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7589 "Cache-Control", "no-store"));
7590 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);
7593 // Tests that serving a response entirely from cache replays the previous
7595 TEST(HttpCache
, CachePreservesSSLInfo
) {
7596 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
= 0xc02f;
7598 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
7600 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2
, &status
);
7602 scoped_refptr
<X509Certificate
> cert
=
7603 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7605 MockHttpCache cache
;
7607 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
7608 transaction
.cert
= cert
;
7609 transaction
.ssl_connection_status
= status
;
7611 // Fetch the resource.
7612 HttpResponseInfo response_info
;
7613 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7616 // The request should have hit the network and a cache entry created.
7617 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7618 EXPECT_EQ(0, cache
.disk_cache()->open_count());
7619 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7621 // The expected SSL state was reported.
7622 EXPECT_EQ(transaction
.ssl_connection_status
,
7623 response_info
.ssl_info
.connection_status
);
7624 EXPECT_TRUE(cert
->Equals(response_info
.ssl_info
.cert
.get()));
7626 // Fetch the resource again.
7627 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7630 // The request should have been reused without hitting the network.
7631 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7632 EXPECT_EQ(1, cache
.disk_cache()->open_count());
7633 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7635 // The SSL state was preserved.
7636 EXPECT_EQ(status
, response_info
.ssl_info
.connection_status
);
7637 EXPECT_TRUE(cert
->Equals(response_info
.ssl_info
.cert
.get()));
7640 // Tests that SSLInfo gets updated when revalidating a cached response.
7641 TEST(HttpCache
, RevalidationUpdatesSSLInfo
) {
7642 static const uint16_t kTLS_RSA_WITH_RC4_128_MD5
= 0x0004;
7643 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
= 0xc02f;
7646 SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5
, &status1
);
7647 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1
, &status1
);
7649 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
7651 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2
, &status2
);
7653 scoped_refptr
<X509Certificate
> cert1
=
7654 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
7655 scoped_refptr
<X509Certificate
> cert2
=
7656 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7658 MockHttpCache cache
;
7660 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
7661 transaction
.cert
= cert1
;
7662 transaction
.ssl_connection_status
= status1
;
7664 // Fetch the resource.
7665 HttpResponseInfo response_info
;
7666 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7669 // The request should have hit the network and a cache entry created.
7670 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
7671 EXPECT_EQ(0, cache
.disk_cache()->open_count());
7672 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7673 EXPECT_FALSE(response_info
.was_cached
);
7675 // The expected SSL state was reported.
7676 EXPECT_EQ(status1
, response_info
.ssl_info
.connection_status
);
7677 EXPECT_TRUE(cert1
->Equals(response_info
.ssl_info
.cert
.get()));
7679 // The server deploys a more modern configuration but reports 304 on the
7680 // revalidation attempt.
7681 transaction
.status
= "HTTP/1.1 304 Not Modified";
7682 transaction
.cert
= cert2
;
7683 transaction
.ssl_connection_status
= status2
;
7685 // Fetch the resource again, forcing a revalidation.
7686 transaction
.request_headers
= "Cache-Control: max-age=0\r\n";
7687 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
7690 // The request should have been successfully revalidated.
7691 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7692 EXPECT_EQ(1, cache
.disk_cache()->open_count());
7693 EXPECT_EQ(1, cache
.disk_cache()->create_count());
7694 EXPECT_TRUE(response_info
.was_cached
);
7696 // The new SSL state is reported.
7697 EXPECT_EQ(status2
, response_info
.ssl_info
.connection_status
);
7698 EXPECT_TRUE(cert2
->Equals(response_info
.ssl_info
.cert
.get()));