1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/http_cache.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/test/simple_test_clock.h"
17 #include "net/base/cache_type.h"
18 #include "net/base/elements_upload_data_stream.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/load_flags.h"
21 #include "net/base/load_timing_info.h"
22 #include "net/base/load_timing_info_test_util.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/upload_bytes_element_reader.h"
25 #include "net/cert/cert_status_flags.h"
26 #include "net/disk_cache/disk_cache.h"
27 #include "net/http/http_byte_range.h"
28 #include "net/http/http_cache_transaction.h"
29 #include "net/http/http_request_headers.h"
30 #include "net/http/http_request_info.h"
31 #include "net/http/http_response_headers.h"
32 #include "net/http/http_response_info.h"
33 #include "net/http/http_transaction.h"
34 #include "net/http/http_transaction_test_util.h"
35 #include "net/http/http_util.h"
36 #include "net/http/mock_http_cache.h"
37 #include "net/log/test_net_log.h"
38 #include "net/log/test_net_log_entry.h"
39 #include "net/log/test_net_log_util.h"
40 #include "net/socket/client_socket_handle.h"
41 #include "net/ssl/ssl_cert_request_info.h"
42 #include "net/websockets/websocket_handshake_stream_base.h"
43 #include "testing/gtest/include/gtest/gtest.h"
51 // Tests the load timing values of a request that goes through a
52 // MockNetworkTransaction.
53 void TestLoadTimingNetworkRequest(const LoadTimingInfo
& load_timing_info
) {
54 EXPECT_FALSE(load_timing_info
.socket_reused
);
55 EXPECT_NE(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
57 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
58 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
60 ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
61 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
62 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
63 load_timing_info
.send_start
);
65 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
67 // Set by URLRequest / URLRequestHttpJob, at a higher level.
68 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
69 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
70 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
73 // Tests the load timing values of a request that receives a cached response.
74 void TestLoadTimingCachedResponse(const LoadTimingInfo
& load_timing_info
) {
75 EXPECT_FALSE(load_timing_info
.socket_reused
);
76 EXPECT_EQ(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
78 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
79 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
81 ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
83 // Only the send start / end times should be sent, and they should have the
85 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
86 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
88 // Set by URLRequest / URLRequestHttpJob, at a higher level.
89 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
90 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
91 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
94 class DeleteCacheCompletionCallback
: public TestCompletionCallbackBase
{
96 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
98 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
99 base::Unretained(this))) {
102 const CompletionCallback
& callback() const { return callback_
; }
105 void OnComplete(int result
) {
110 MockHttpCache
* cache_
;
111 CompletionCallback callback_
;
113 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
116 //-----------------------------------------------------------------------------
119 void ReadAndVerifyTransaction(HttpTransaction
* trans
,
120 const MockTransaction
& trans_info
) {
122 int rv
= ReadTransaction(trans
, &content
);
125 std::string
expected(trans_info
.data
);
126 EXPECT_EQ(expected
, content
);
129 void RunTransactionTestBase(HttpCache
* cache
,
130 const MockTransaction
& trans_info
,
131 const MockHttpRequest
& request
,
132 HttpResponseInfo
* response_info
,
133 const BoundNetLog
& net_log
,
134 LoadTimingInfo
* load_timing_info
,
135 int64
* received_bytes
) {
136 TestCompletionCallback callback
;
138 // write to the cache
140 scoped_ptr
<HttpTransaction
> trans
;
141 int rv
= cache
->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
143 ASSERT_TRUE(trans
.get());
145 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
146 if (rv
== ERR_IO_PENDING
)
147 rv
= callback
.WaitForResult();
148 ASSERT_EQ(trans_info
.return_code
, rv
);
153 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
154 ASSERT_TRUE(response
);
157 *response_info
= *response
;
159 if (load_timing_info
) {
160 // If a fake network connection is used, need a NetLog to get a fake socket
162 EXPECT_TRUE(net_log
.net_log());
163 *load_timing_info
= LoadTimingInfo();
164 trans
->GetLoadTimingInfo(load_timing_info
);
167 ReadAndVerifyTransaction(trans
.get(), trans_info
);
170 *received_bytes
= trans
->GetTotalReceivedBytes();
173 void RunTransactionTestWithRequest(HttpCache
* cache
,
174 const MockTransaction
& trans_info
,
175 const MockHttpRequest
& request
,
176 HttpResponseInfo
* response_info
) {
177 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
178 BoundNetLog(), NULL
, NULL
);
181 void RunTransactionTestAndGetTiming(HttpCache
* cache
,
182 const MockTransaction
& trans_info
,
183 const BoundNetLog
& log
,
184 LoadTimingInfo
* load_timing_info
) {
185 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
186 NULL
, log
, load_timing_info
, NULL
);
189 void RunTransactionTest(HttpCache
* cache
, const MockTransaction
& trans_info
) {
190 RunTransactionTestAndGetTiming(cache
, trans_info
, BoundNetLog(), NULL
);
193 void RunTransactionTestWithLog(HttpCache
* cache
,
194 const MockTransaction
& trans_info
,
195 const BoundNetLog
& log
) {
196 RunTransactionTestAndGetTiming(cache
, trans_info
, log
, NULL
);
199 void RunTransactionTestWithResponseInfo(HttpCache
* cache
,
200 const MockTransaction
& trans_info
,
201 HttpResponseInfo
* response
) {
202 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
206 void RunTransactionTestWithResponseInfoAndGetTiming(
208 const MockTransaction
& trans_info
,
209 HttpResponseInfo
* response
,
210 const BoundNetLog
& log
,
211 LoadTimingInfo
* load_timing_info
) {
212 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
213 response
, log
, load_timing_info
, NULL
);
216 void RunTransactionTestWithResponse(HttpCache
* cache
,
217 const MockTransaction
& trans_info
,
218 std::string
* response_headers
) {
219 HttpResponseInfo response
;
220 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
221 response
.headers
->GetNormalizedHeaders(response_headers
);
224 void RunTransactionTestWithResponseAndGetTiming(
226 const MockTransaction
& trans_info
,
227 std::string
* response_headers
,
228 const BoundNetLog
& log
,
229 LoadTimingInfo
* load_timing_info
) {
230 HttpResponseInfo response
;
231 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
232 &response
, log
, load_timing_info
, NULL
);
233 response
.headers
->GetNormalizedHeaders(response_headers
);
236 // This class provides a handler for kFastNoStoreGET_Transaction so that the
237 // no-store header can be included on demand.
238 class FastTransactionServer
{
240 FastTransactionServer() {
243 ~FastTransactionServer() {}
245 void set_no_store(bool value
) { no_store
= value
; }
247 static void FastNoStoreHandler(const HttpRequestInfo
* request
,
248 std::string
* response_status
,
249 std::string
* response_headers
,
250 std::string
* response_data
) {
252 *response_headers
= "Cache-Control: no-store\n";
256 static bool no_store
;
257 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
259 bool FastTransactionServer::no_store
;
261 const MockTransaction kFastNoStoreGET_Transaction
= {
262 "http://www.google.com/nostore",
268 "Cache-Control: max-age=10000\n",
270 "<html><body>Google Blah Blah</body></html>",
271 TEST_MODE_SYNC_NET_START
,
272 &FastTransactionServer::FastNoStoreHandler
,
276 // This class provides a handler for kRangeGET_TransactionOK so that the range
277 // request can be served on demand.
278 class RangeTransactionServer
{
280 RangeTransactionServer() {
281 not_modified_
= false;
285 ~RangeTransactionServer() {
286 not_modified_
= false;
291 // Returns only 416 or 304 when set.
292 void set_not_modified(bool value
) { not_modified_
= value
; }
294 // Returns 206 when revalidating a range (instead of 304).
295 void set_modified(bool value
) { modified_
= value
; }
297 // Returns 200 instead of 206 (a malformed response overall).
298 void set_bad_200(bool value
) { bad_200_
= value
; }
300 // Other than regular range related behavior (and the flags mentioned above),
301 // the server reacts to requests headers like so:
302 // X-Require-Mock-Auth -> return 401.
303 // X-Return-Default-Range -> assume 40-49 was requested.
304 static void RangeHandler(const HttpRequestInfo
* request
,
305 std::string
* response_status
,
306 std::string
* response_headers
,
307 std::string
* response_data
);
310 static bool not_modified_
;
311 static bool modified_
;
312 static bool bad_200_
;
313 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
315 bool RangeTransactionServer::not_modified_
= false;
316 bool RangeTransactionServer::modified_
= false;
317 bool RangeTransactionServer::bad_200_
= false;
319 // A dummy extra header that must be preserved on a given request.
321 // EXTRA_HEADER_LINE doesn't include a line terminator because it
322 // will be passed to AddHeaderFromString() which doesn't accept them.
323 #define EXTRA_HEADER_LINE "Extra: header"
325 // EXTRA_HEADER contains a line terminator, as expected by
326 // AddHeadersFromString() (_not_ AddHeaderFromString()).
327 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
329 static const char kExtraHeaderKey
[] = "Extra";
332 void RangeTransactionServer::RangeHandler(const HttpRequestInfo
* request
,
333 std::string
* response_status
,
334 std::string
* response_headers
,
335 std::string
* response_data
) {
336 if (request
->extra_headers
.IsEmpty()) {
337 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
338 response_data
->clear();
342 // We want to make sure we don't delete extra headers.
343 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
345 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
346 !request
->extra_headers
.HasHeader("Authorization")) {
347 response_status
->assign("HTTP/1.1 401 Unauthorized");
348 response_data
->assign("WWW-Authenticate: Foo\n");
353 response_status
->assign("HTTP/1.1 304 Not Modified");
354 response_data
->clear();
358 std::vector
<HttpByteRange
> ranges
;
359 std::string range_header
;
360 if (!request
->extra_headers
.GetHeader(HttpRequestHeaders::kRange
,
362 !HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
363 ranges
.size() != 1) {
364 // This is not a byte range request. We return 200.
365 response_status
->assign("HTTP/1.1 200 OK");
366 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
367 response_data
->assign("Not a range");
371 // We can handle this range request.
372 HttpByteRange byte_range
= ranges
[0];
374 if (request
->extra_headers
.HasHeader("X-Return-Default-Range")) {
375 byte_range
.set_first_byte_position(40);
376 byte_range
.set_last_byte_position(49);
379 if (byte_range
.first_byte_position() > 79) {
380 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
381 response_data
->clear();
385 EXPECT_TRUE(byte_range
.ComputeBounds(80));
386 int start
= static_cast<int>(byte_range
.first_byte_position());
387 int end
= static_cast<int>(byte_range
.last_byte_position());
391 std::string content_range
= base::StringPrintf(
392 "Content-Range: bytes %d-%d/80\n", start
, end
);
393 response_headers
->append(content_range
);
395 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
398 EXPECT_EQ(0, end
% 10);
401 EXPECT_EQ(9, (end
- start
) % 10);
402 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
403 base::StringAppendF(&data
, "rg: %02d-%02d ",
404 block_start
, block_start
+ 9);
407 *response_data
= data
;
409 if (end
- start
!= 9) {
410 // We also have to fix content-length.
411 int len
= end
- start
+ 1;
412 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
414 response_headers
->replace(response_headers
->find("Content-Length:"),
415 content_length
.size(), content_length
);
418 response_status
->assign("HTTP/1.1 304 Not Modified");
419 response_data
->clear();
423 const MockTransaction kRangeGET_TransactionOK
= {
424 "http://www.google.com/range",
427 "Range: bytes = 40-49\r\n" EXTRA_HEADER
,
429 "HTTP/1.1 206 Partial Content",
430 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
432 "Accept-Ranges: bytes\n"
433 "Content-Length: 10\n",
437 &RangeTransactionServer::RangeHandler
,
441 const char kFullRangeData
[] =
442 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
443 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
445 // Verifies the response headers (|response|) match a partial content
446 // response for the range starting at |start| and ending at |end|.
447 void Verify206Response(std::string response
, int start
, int end
) {
448 std::string
raw_headers(
449 HttpUtil::AssembleRawHeaders(response
.data(), response
.size()));
450 scoped_refptr
<HttpResponseHeaders
> headers(
451 new HttpResponseHeaders(raw_headers
));
453 ASSERT_EQ(206, headers
->response_code());
455 int64 range_start
, range_end
, object_size
;
457 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
458 int64 content_length
= headers
->GetContentLength();
460 int length
= end
- start
+ 1;
461 ASSERT_EQ(length
, content_length
);
462 ASSERT_EQ(start
, range_start
);
463 ASSERT_EQ(end
, range_end
);
466 // Creates a truncated entry that can be resumed using byte ranges.
467 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
468 // Create a disk cache entry that stores an incomplete resource.
469 disk_cache::Entry
* entry
;
470 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
474 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
476 HttpResponseInfo response
;
477 response
.response_time
= base::Time::Now();
478 response
.request_time
= base::Time::Now();
479 response
.headers
= new HttpResponseHeaders(raw_headers
);
480 // Set the last argument for this to be an incomplete request.
481 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
483 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
484 int len
= static_cast<int>(base::strlcpy(buf
->data(),
485 "rg: 00-09 rg: 10-19 ", 100));
486 TestCompletionCallback cb
;
487 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
488 EXPECT_EQ(len
, cb
.GetResult(rv
));
492 // Helper to represent a network HTTP response.
494 // Set this response into |trans|.
495 void AssignTo(MockTransaction
* trans
) const {
496 trans
->status
= status
;
497 trans
->response_headers
= headers
;
501 std::string
status_and_headers() const {
502 return std::string(status
) + "\n" + std::string(headers
);
511 Context() : result(ERR_IO_PENDING
) {}
514 TestCompletionCallback callback
;
515 scoped_ptr
<HttpTransaction
> trans
;
518 class FakeWebSocketHandshakeStreamCreateHelper
519 : public WebSocketHandshakeStreamBase::CreateHelper
{
521 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
522 WebSocketHandshakeStreamBase
* CreateBasicStream(
523 scoped_ptr
<ClientSocketHandle
> connect
,
524 bool using_proxy
) override
{
527 WebSocketHandshakeStreamBase
* CreateSpdyStream(
528 const base::WeakPtr
<SpdySession
>& session
,
529 bool use_relative_url
) override
{
534 // Returns true if |entry| is not one of the log types paid attention to in this
535 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
537 bool ShouldIgnoreLogEntry(const TestNetLogEntry
& entry
) {
538 switch (entry
.type
) {
539 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
540 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
541 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
542 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
543 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
544 case NetLog::TYPE_HTTP_CACHE_READ_INFO
:
551 // Modifies |entries| to only include log entries created by the cache layer and
552 // asserted on in these tests.
553 void FilterLogEntries(TestNetLogEntry::List
* entries
) {
554 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
555 &ShouldIgnoreLogEntry
),
559 bool LogContainsEventType(const BoundTestNetLog
& log
,
560 NetLog::EventType expected
) {
561 TestNetLogEntry::List entries
;
562 log
.GetEntries(&entries
);
563 for (size_t i
= 0; i
< entries
.size(); i
++) {
564 if (entries
[i
].type
== expected
)
573 //-----------------------------------------------------------------------------
576 TEST(HttpCache
, CreateThenDestroy
) {
579 scoped_ptr
<HttpTransaction
> trans
;
580 EXPECT_EQ(OK
, cache
.CreateTransaction(&trans
));
581 ASSERT_TRUE(trans
.get());
584 TEST(HttpCache
, GetBackend
) {
585 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(0));
587 disk_cache::Backend
* backend
;
588 TestCompletionCallback cb
;
589 // This will lazily initialize the backend.
590 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
591 EXPECT_EQ(OK
, cb
.GetResult(rv
));
594 TEST(HttpCache
, SimpleGET
) {
597 LoadTimingInfo load_timing_info
;
599 // Write to the cache.
600 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
601 log
.bound(), &load_timing_info
);
603 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
605 EXPECT_EQ(1, cache
.disk_cache()->create_count());
606 TestLoadTimingNetworkRequest(load_timing_info
);
609 TEST(HttpCache
, SimpleGETNoDiskCache
) {
612 cache
.disk_cache()->set_fail_requests();
615 LoadTimingInfo load_timing_info
;
617 // Read from the network, and don't use the cache.
618 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
619 log
.bound(), &load_timing_info
);
621 // Check that the NetLog was filled as expected.
622 // (We attempted to both Open and Create entries, but both failed).
623 TestNetLogEntry::List entries
;
624 log
.GetEntries(&entries
);
625 FilterLogEntries(&entries
);
627 EXPECT_EQ(6u, entries
.size());
629 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
631 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
633 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
635 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
637 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
639 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
641 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
642 EXPECT_EQ(0, cache
.disk_cache()->open_count());
643 EXPECT_EQ(0, cache
.disk_cache()->create_count());
644 TestLoadTimingNetworkRequest(load_timing_info
);
647 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
648 // This will initialize a cache object with NULL backend.
649 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
650 factory
->set_fail(true);
651 factory
->FinishCreation(); // We'll complete synchronously.
652 MockHttpCache
cache(factory
);
654 // Read from the network, and don't use the cache.
655 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
657 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
658 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
661 // Tests that IOBuffers are not referenced after IO completes.
662 TEST(HttpCache
, ReleaseBuffer
) {
665 // Write to the cache.
666 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
668 MockHttpRequest
request(kSimpleGET_Transaction
);
669 scoped_ptr
<HttpTransaction
> trans
;
670 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
672 const int kBufferSize
= 10;
673 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(kBufferSize
));
674 ReleaseBufferCompletionCallback
cb(buffer
.get());
676 int rv
= trans
->Start(&request
, cb
.callback(), BoundNetLog());
677 EXPECT_EQ(OK
, cb
.GetResult(rv
));
679 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
680 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
683 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
686 cache
.disk_cache()->set_soft_failures(true);
688 // Read from the network, and fail to write to the cache.
689 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
691 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
692 EXPECT_EQ(0, cache
.disk_cache()->open_count());
693 EXPECT_EQ(1, cache
.disk_cache()->create_count());
695 // This one should see an empty cache again.
696 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
698 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
699 EXPECT_EQ(0, cache
.disk_cache()->open_count());
700 EXPECT_EQ(2, cache
.disk_cache()->create_count());
703 // Tests that disk failures after the transaction has started don't cause the
705 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
708 MockHttpRequest
request(kSimpleGET_Transaction
);
710 scoped_ptr
<Context
> c(new Context());
711 int rv
= cache
.CreateTransaction(&c
->trans
);
714 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
715 EXPECT_EQ(ERR_IO_PENDING
, rv
);
716 rv
= c
->callback
.WaitForResult();
718 // Start failing request now.
719 cache
.disk_cache()->set_soft_failures(true);
721 // We have to open the entry again to propagate the failure flag.
722 disk_cache::Entry
* en
;
723 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
726 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
729 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
730 EXPECT_EQ(1, cache
.disk_cache()->open_count());
731 EXPECT_EQ(1, cache
.disk_cache()->create_count());
733 // This one should see an empty cache again.
734 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
736 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
737 EXPECT_EQ(1, cache
.disk_cache()->open_count());
738 EXPECT_EQ(2, cache
.disk_cache()->create_count());
741 // Tests that we handle failures to read from the cache.
742 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
745 // Read from the network, and write to the cache.
746 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
748 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
749 EXPECT_EQ(0, cache
.disk_cache()->open_count());
750 EXPECT_EQ(1, cache
.disk_cache()->create_count());
752 cache
.disk_cache()->set_soft_failures(true);
754 // Now fail to read from the cache.
755 scoped_ptr
<Context
> c(new Context());
756 int rv
= cache
.CreateTransaction(&c
->trans
);
759 MockHttpRequest
request(kSimpleGET_Transaction
);
760 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
761 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
763 // Now verify that the entry was removed from the cache.
764 cache
.disk_cache()->set_soft_failures(false);
766 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
767 EXPECT_EQ(1, cache
.disk_cache()->open_count());
768 EXPECT_EQ(2, cache
.disk_cache()->create_count());
770 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
772 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
773 EXPECT_EQ(1, cache
.disk_cache()->open_count());
774 EXPECT_EQ(3, cache
.disk_cache()->create_count());
777 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
781 LoadTimingInfo load_timing_info
;
783 // Write to the cache.
784 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
785 log
.bound(), &load_timing_info
);
787 // Check that the NetLog was filled as expected.
788 TestNetLogEntry::List entries
;
789 log
.GetEntries(&entries
);
790 FilterLogEntries(&entries
);
792 EXPECT_EQ(8u, entries
.size());
794 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
796 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
798 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
800 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
802 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
804 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
806 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
808 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
810 TestLoadTimingNetworkRequest(load_timing_info
);
812 // Force this transaction to read from the cache.
813 MockTransaction
transaction(kSimpleGET_Transaction
);
814 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
818 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
821 // Check that the NetLog was filled as expected.
822 log
.GetEntries(&entries
);
823 FilterLogEntries(&entries
);
825 EXPECT_EQ(8u, entries
.size());
827 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
829 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
831 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
833 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
835 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
837 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
839 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
841 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
843 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
844 EXPECT_EQ(1, cache
.disk_cache()->open_count());
845 EXPECT_EQ(1, cache
.disk_cache()->create_count());
846 TestLoadTimingCachedResponse(load_timing_info
);
849 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
852 // force this transaction to read from the cache
853 MockTransaction
transaction(kSimpleGET_Transaction
);
854 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
856 MockHttpRequest
request(transaction
);
857 TestCompletionCallback callback
;
859 scoped_ptr
<HttpTransaction
> trans
;
860 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
862 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
863 if (rv
== ERR_IO_PENDING
)
864 rv
= callback
.WaitForResult();
865 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
869 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
870 EXPECT_EQ(0, cache
.disk_cache()->open_count());
871 EXPECT_EQ(0, cache
.disk_cache()->create_count());
874 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
877 // write to the cache
878 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
880 // force this transaction to read from the cache if valid
881 MockTransaction
transaction(kSimpleGET_Transaction
);
882 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
884 RunTransactionTest(cache
.http_cache(), transaction
);
886 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
887 EXPECT_EQ(1, cache
.disk_cache()->open_count());
888 EXPECT_EQ(1, cache
.disk_cache()->create_count());
891 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
894 // force this transaction to read from the cache if valid
895 MockTransaction
transaction(kSimpleGET_Transaction
);
896 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
898 RunTransactionTest(cache
.http_cache(), transaction
);
900 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
901 EXPECT_EQ(0, cache
.disk_cache()->open_count());
902 EXPECT_EQ(1, cache
.disk_cache()->create_count());
905 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
906 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
909 // Write to the cache.
910 MockTransaction
transaction(kSimpleGET_Transaction
);
911 transaction
.request_headers
= "Foo: bar\r\n";
912 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
914 AddMockTransaction(&transaction
);
915 RunTransactionTest(cache
.http_cache(), transaction
);
917 // Read from the cache.
918 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
919 RunTransactionTest(cache
.http_cache(), transaction
);
921 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
922 EXPECT_EQ(1, cache
.disk_cache()->open_count());
923 EXPECT_EQ(1, cache
.disk_cache()->create_count());
924 RemoveMockTransaction(&transaction
);
927 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
928 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
931 // Write to the cache.
932 MockTransaction
transaction(kSimpleGET_Transaction
);
933 transaction
.request_headers
= "Foo: bar\r\n";
934 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
936 AddMockTransaction(&transaction
);
937 RunTransactionTest(cache
.http_cache(), transaction
);
939 // Attempt to read from the cache... this is a vary mismatch that must reach
940 // the network again.
941 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
942 transaction
.request_headers
= "Foo: none\r\n";
944 LoadTimingInfo load_timing_info
;
945 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
948 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
949 EXPECT_EQ(1, cache
.disk_cache()->open_count());
950 EXPECT_EQ(1, cache
.disk_cache()->create_count());
951 TestLoadTimingNetworkRequest(load_timing_info
);
952 RemoveMockTransaction(&transaction
);
955 // Tests that was_cached was set properly on a failure, even if the cached
956 // response wasn't returned.
957 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
961 MockTransaction
transaction(kSimpleGET_Transaction
);
962 transaction
.response_headers
= "Cache-Control: no-cache\n";
964 AddMockTransaction(&transaction
);
965 RunTransactionTest(cache
.http_cache(), transaction
);
966 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
967 EXPECT_EQ(1, cache
.disk_cache()->create_count());
968 RemoveMockTransaction(&transaction
);
970 // Network failure with error; should fail but have was_cached set.
971 transaction
.return_code
= ERR_FAILED
;
972 AddMockTransaction(&transaction
);
974 MockHttpRequest
request(transaction
);
975 TestCompletionCallback callback
;
976 scoped_ptr
<HttpTransaction
> trans
;
977 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
979 ASSERT_TRUE(trans
.get());
980 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
981 EXPECT_EQ(ERR_FAILED
, callback
.GetResult(rv
));
983 const HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
984 ASSERT_TRUE(response_info
);
985 EXPECT_TRUE(response_info
->was_cached
);
986 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
988 RemoveMockTransaction(&transaction
);
991 // Confirm if we have an empty cache, a read is marked as network verified.
992 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
995 // write to the cache
996 HttpResponseInfo response_info
;
997 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1000 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1001 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1002 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1003 EXPECT_TRUE(response_info
.network_accessed
);
1006 // Confirm if we have a fresh entry in cache, it isn't marked as
1007 // network verified.
1008 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1009 MockHttpCache cache
;
1012 MockTransaction
transaction(kSimpleGET_Transaction
);
1014 RunTransactionTest(cache
.http_cache(), transaction
);
1015 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1016 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1018 // Re-run transaction; make sure we don't mark the network as accessed.
1019 HttpResponseInfo response_info
;
1020 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1023 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1024 EXPECT_FALSE(response_info
.server_data_unavailable
);
1025 EXPECT_FALSE(response_info
.network_accessed
);
1028 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1029 MockHttpCache cache
;
1031 // Write to the cache.
1032 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1034 // Force this transaction to write to the cache again.
1035 MockTransaction
transaction(kSimpleGET_Transaction
);
1036 transaction
.load_flags
|= LOAD_BYPASS_CACHE
;
1038 BoundTestNetLog log
;
1039 LoadTimingInfo load_timing_info
;
1041 // Write to the cache.
1042 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1045 // Check that the NetLog was filled as expected.
1046 TestNetLogEntry::List entries
;
1047 log
.GetEntries(&entries
);
1048 FilterLogEntries(&entries
);
1050 EXPECT_EQ(8u, entries
.size());
1052 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1054 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1056 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1058 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1060 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1062 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1064 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1066 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1068 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1069 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1070 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1071 TestLoadTimingNetworkRequest(load_timing_info
);
1074 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1075 MockHttpCache cache
;
1077 // write to the cache
1078 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1080 // force this transaction to write to the cache again
1081 MockTransaction
transaction(kSimpleGET_Transaction
);
1082 transaction
.request_headers
= "pragma: no-cache\r\n";
1084 RunTransactionTest(cache
.http_cache(), transaction
);
1086 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1087 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1088 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1091 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1092 MockHttpCache cache
;
1094 // write to the cache
1095 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1097 // force this transaction to write to the cache again
1098 MockTransaction
transaction(kSimpleGET_Transaction
);
1099 transaction
.request_headers
= "cache-control: no-cache\r\n";
1101 RunTransactionTest(cache
.http_cache(), transaction
);
1103 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1104 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1105 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1108 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1109 MockHttpCache cache
;
1111 // Write to the cache.
1112 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1114 // Read from the cache.
1115 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1117 // Force this transaction to validate the cache.
1118 MockTransaction
transaction(kSimpleGET_Transaction
);
1119 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
1121 HttpResponseInfo response_info
;
1122 BoundTestNetLog log
;
1123 LoadTimingInfo load_timing_info
;
1124 RunTransactionTestWithResponseInfoAndGetTiming(
1125 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1128 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1129 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1130 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1131 EXPECT_TRUE(response_info
.network_accessed
);
1132 TestLoadTimingNetworkRequest(load_timing_info
);
1135 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1136 MockHttpCache cache
;
1138 // write to the cache
1139 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1141 // read from the cache
1142 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1144 // force this transaction to validate the cache
1145 MockTransaction
transaction(kSimpleGET_Transaction
);
1146 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1148 RunTransactionTest(cache
.http_cache(), transaction
);
1150 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1151 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1152 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1155 static void PreserveRequestHeaders_Handler(const HttpRequestInfo
* request
,
1156 std::string
* response_status
,
1157 std::string
* response_headers
,
1158 std::string
* response_data
) {
1159 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1162 // Tests that we don't remove extra headers for simple requests.
1163 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1164 MockHttpCache cache
;
1166 MockTransaction
transaction(kSimpleGET_Transaction
);
1167 transaction
.handler
= PreserveRequestHeaders_Handler
;
1168 transaction
.request_headers
= EXTRA_HEADER
;
1169 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1170 AddMockTransaction(&transaction
);
1172 // Write, then revalidate the entry.
1173 RunTransactionTest(cache
.http_cache(), transaction
);
1174 RunTransactionTest(cache
.http_cache(), transaction
);
1176 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1177 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1178 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1179 RemoveMockTransaction(&transaction
);
1182 // Tests that we don't remove extra headers for conditionalized requests.
1183 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1184 MockHttpCache cache
;
1186 // Write to the cache.
1187 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1189 MockTransaction
transaction(kETagGET_Transaction
);
1190 transaction
.handler
= PreserveRequestHeaders_Handler
;
1191 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1193 AddMockTransaction(&transaction
);
1195 RunTransactionTest(cache
.http_cache(), transaction
);
1197 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1198 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1199 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1200 RemoveMockTransaction(&transaction
);
1203 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1204 MockHttpCache cache
;
1206 MockHttpRequest
request(kSimpleGET_Transaction
);
1208 std::vector
<Context
*> context_list
;
1209 const int kNumTransactions
= 5;
1211 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1212 context_list
.push_back(new Context());
1213 Context
* c
= context_list
[i
];
1215 c
->result
= cache
.CreateTransaction(&c
->trans
);
1216 ASSERT_EQ(OK
, c
->result
);
1217 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1220 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1223 // All requests are waiting for the active entry.
1224 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1225 Context
* c
= context_list
[i
];
1226 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1229 // Allow all requests to move from the Create queue to the active entry.
1230 base::MessageLoop::current()->RunUntilIdle();
1232 // The first request should be a writer at this point, and the subsequent
1233 // requests should be pending.
1235 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1236 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1237 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1239 // All requests depend on the writer, and the writer is between Start and
1241 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1242 Context
* c
= context_list
[i
];
1243 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1246 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1247 Context
* c
= context_list
[i
];
1248 if (c
->result
== ERR_IO_PENDING
)
1249 c
->result
= c
->callback
.WaitForResult();
1250 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1253 // We should not have had to re-open the disk entry
1255 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1256 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1257 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1259 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1260 Context
* c
= context_list
[i
];
1265 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1266 // If cancelling a request is racing with another request for the same resource
1267 // finishing, we have to make sure that we remove both transactions from the
1269 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1270 MockHttpCache cache
;
1272 MockHttpRequest
request(kSimpleGET_Transaction
);
1273 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1274 reader_request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
1276 std::vector
<Context
*> context_list
;
1277 const int kNumTransactions
= 5;
1279 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1280 context_list
.push_back(new Context());
1281 Context
* c
= context_list
[i
];
1283 c
->result
= cache
.CreateTransaction(&c
->trans
);
1284 ASSERT_EQ(OK
, c
->result
);
1286 MockHttpRequest
* this_request
= &request
;
1287 if (i
== 1 || i
== 2)
1288 this_request
= &reader_request
;
1291 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1294 // Allow all requests to move from the Create queue to the active entry.
1295 base::MessageLoop::current()->RunUntilIdle();
1297 // The first request should be a writer at this point, and the subsequent
1298 // requests should be pending.
1300 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1301 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1302 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1304 Context
* c
= context_list
[0];
1305 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1306 c
->result
= c
->callback
.WaitForResult();
1307 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1309 // Now we have 2 active readers and two queued transactions.
1311 EXPECT_EQ(LOAD_STATE_IDLE
, context_list
[2]->trans
->GetLoadState());
1312 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
,
1313 context_list
[3]->trans
->GetLoadState());
1315 c
= context_list
[1];
1316 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1317 c
->result
= c
->callback
.WaitForResult();
1318 if (c
->result
== OK
)
1319 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1321 // At this point we have one reader, two pending transactions and a task on
1322 // the queue to move to the next transaction. Now we cancel the request that
1323 // is the current reader, and expect the queued task to be able to start the
1326 c
= context_list
[2];
1329 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1330 Context
* c
= context_list
[i
];
1331 if (c
->result
== ERR_IO_PENDING
)
1332 c
->result
= c
->callback
.WaitForResult();
1333 if (c
->result
== OK
)
1334 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1337 // We should not have had to re-open the disk entry.
1339 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1340 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1341 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1343 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1344 Context
* c
= context_list
[i
];
1349 // Tests that we can doom an entry with pending transactions and delete one of
1350 // the pending transactions before the first one completes.
1351 // See http://code.google.com/p/chromium/issues/detail?id=25588
1352 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1353 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1354 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
1356 MockHttpRequest
request(kSimpleGET_Transaction
);
1357 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1358 writer_request
.load_flags
= LOAD_BYPASS_CACHE
;
1360 ScopedVector
<Context
> context_list
;
1361 const int kNumTransactions
= 4;
1363 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1364 context_list
.push_back(new Context());
1365 Context
* c
= context_list
[i
];
1367 c
->result
= cache
.CreateTransaction(&c
->trans
);
1368 ASSERT_EQ(OK
, c
->result
);
1370 MockHttpRequest
* this_request
= &request
;
1372 this_request
= &writer_request
;
1375 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1378 // The first request should be a writer at this point, and the two subsequent
1379 // requests should be pending. The last request doomed the first entry.
1381 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1383 // Cancel the first queued transaction.
1384 delete context_list
[1];
1385 context_list
.get()[1] = NULL
;
1387 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1390 Context
* c
= context_list
[i
];
1391 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1392 c
->result
= c
->callback
.WaitForResult();
1393 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1397 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1398 // We may attempt to delete an entry synchronously with the act of adding a new
1399 // transaction to said entry.
1400 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1401 MockHttpCache cache
;
1403 // The headers will be served right from the call to Start() the request.
1404 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1405 FastTransactionServer request_handler
;
1406 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1408 std::vector
<Context
*> context_list
;
1409 const int kNumTransactions
= 3;
1411 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1412 context_list
.push_back(new Context());
1413 Context
* c
= context_list
[i
];
1415 c
->result
= cache
.CreateTransaction(&c
->trans
);
1416 ASSERT_EQ(OK
, c
->result
);
1419 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1422 // Allow all requests to move from the Create queue to the active entry.
1423 base::MessageLoop::current()->RunUntilIdle();
1425 // The first request should be a writer at this point, and the subsequent
1426 // requests should be pending.
1428 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1429 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1430 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1432 // Now, make sure that the second request asks for the entry not to be stored.
1433 request_handler
.set_no_store(true);
1435 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1436 Context
* c
= context_list
[i
];
1437 if (c
->result
== ERR_IO_PENDING
)
1438 c
->result
= c
->callback
.WaitForResult();
1439 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1443 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1444 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1445 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1447 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1450 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1451 MockHttpCache cache
;
1453 MockHttpRequest
request(kSimpleGET_Transaction
);
1455 std::vector
<Context
*> context_list
;
1456 const int kNumTransactions
= 2;
1458 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1459 context_list
.push_back(new Context());
1460 Context
* c
= context_list
[i
];
1462 c
->result
= cache
.CreateTransaction(&c
->trans
);
1463 ASSERT_EQ(OK
, c
->result
);
1466 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1469 // Allow all requests to move from the Create queue to the active entry.
1470 base::MessageLoop::current()->RunUntilIdle();
1472 // The first request should be a writer at this point, and the subsequent
1473 // requests should be pending.
1475 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1476 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1477 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1479 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1480 Context
* c
= context_list
[i
];
1481 if (c
->result
== ERR_IO_PENDING
)
1482 c
->result
= c
->callback
.WaitForResult();
1483 // Destroy only the first transaction.
1486 context_list
[i
] = NULL
;
1490 // Complete the rest of the transactions.
1491 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1492 Context
* c
= context_list
[i
];
1493 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1496 // We should have had to re-open the disk entry.
1498 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1499 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1500 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1502 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1503 Context
* c
= context_list
[i
];
1508 // Tests that we can cancel requests that are queued waiting to open the disk
1510 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1511 MockHttpCache cache
;
1513 MockHttpRequest
request(kSimpleGET_Transaction
);
1515 std::vector
<Context
*> context_list
;
1516 const int kNumTransactions
= 5;
1518 for (int i
= 0; i
< kNumTransactions
; i
++) {
1519 context_list
.push_back(new Context());
1520 Context
* c
= context_list
[i
];
1522 c
->result
= cache
.CreateTransaction(&c
->trans
);
1523 ASSERT_EQ(OK
, c
->result
);
1526 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1529 // The first request should be creating the disk cache entry and the others
1530 // should be pending.
1532 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1533 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1534 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1536 // Cancel a request from the pending queue.
1537 delete context_list
[3];
1538 context_list
[3] = NULL
;
1540 // Cancel the request that is creating the entry. This will force the pending
1541 // operations to restart.
1542 delete context_list
[0];
1543 context_list
[0] = NULL
;
1545 // Complete the rest of the transactions.
1546 for (int i
= 1; i
< kNumTransactions
; i
++) {
1547 Context
* c
= context_list
[i
];
1549 c
->result
= c
->callback
.GetResult(c
->result
);
1550 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1554 // We should have had to re-create the disk entry.
1556 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1557 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1558 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1560 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1561 delete context_list
[i
];
1565 // Tests that we can cancel a single request to open a disk cache entry.
1566 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1567 MockHttpCache cache
;
1569 MockHttpRequest
request(kSimpleGET_Transaction
);
1571 Context
* c
= new Context();
1573 c
->result
= cache
.CreateTransaction(&c
->trans
);
1574 ASSERT_EQ(OK
, c
->result
);
1576 c
->result
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1577 EXPECT_EQ(ERR_IO_PENDING
, c
->result
);
1579 // Release the reference that the mock disk cache keeps for this entry, so
1580 // that we test that the http cache handles the cancellation correctly.
1581 cache
.disk_cache()->ReleaseAll();
1584 base::MessageLoop::current()->RunUntilIdle();
1585 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1588 // Tests that we delete/create entries even if multiple requests are queued.
1589 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1590 MockHttpCache cache
;
1592 MockHttpRequest
request(kSimpleGET_Transaction
);
1593 request
.load_flags
= LOAD_BYPASS_CACHE
;
1595 std::vector
<Context
*> context_list
;
1596 const int kNumTransactions
= 5;
1598 for (int i
= 0; i
< kNumTransactions
; i
++) {
1599 context_list
.push_back(new Context());
1600 Context
* c
= context_list
[i
];
1602 c
->result
= cache
.CreateTransaction(&c
->trans
);
1603 ASSERT_EQ(OK
, c
->result
);
1606 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1609 // The first request should be deleting the disk cache entry and the others
1610 // should be pending.
1612 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1613 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1614 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1616 // Complete the transactions.
1617 for (int i
= 0; i
< kNumTransactions
; i
++) {
1618 Context
* c
= context_list
[i
];
1619 c
->result
= c
->callback
.GetResult(c
->result
);
1620 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1623 // We should have had to re-create the disk entry multiple times.
1625 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1626 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1627 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1629 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1630 delete context_list
[i
];
1634 // Tests that a (simulated) timeout allows transactions waiting on the cache
1635 // lock to continue.
1636 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1637 MockHttpCache cache
;
1638 cache
.BypassCacheLock();
1640 MockHttpRequest
request(kSimpleGET_Transaction
);
1642 ASSERT_EQ(OK
, cache
.CreateTransaction(&c1
.trans
));
1643 ASSERT_EQ(ERR_IO_PENDING
,
1644 c1
.trans
->Start(&request
, c1
.callback
.callback(), BoundNetLog()));
1645 ASSERT_EQ(OK
, cache
.CreateTransaction(&c2
.trans
));
1646 ASSERT_EQ(ERR_IO_PENDING
,
1647 c2
.trans
->Start(&request
, c2
.callback
.callback(), BoundNetLog()));
1649 // The second request is queued after the first one.
1651 c2
.callback
.WaitForResult();
1652 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1654 // Complete the first transaction.
1655 c1
.callback
.WaitForResult();
1656 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1659 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1660 MockHttpCache cache
;
1662 // write to the cache
1663 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1665 MockHttpRequest
request(kSimpleGET_Transaction
);
1666 TestCompletionCallback callback
;
1668 scoped_ptr
<HttpTransaction
> trans
;
1669 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
1670 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1671 if (rv
== ERR_IO_PENDING
)
1672 rv
= callback
.WaitForResult();
1675 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
1676 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1677 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1679 // Test that destroying the transaction while it is reading from the cache
1683 // Make sure we pump any pending events, which should include a call to
1684 // HttpCache::Transaction::OnCacheReadCompleted.
1685 base::MessageLoop::current()->RunUntilIdle();
1688 // Tests that we can delete the HttpCache and deal with queued transactions
1689 // ("waiting for the backend" as opposed to Active or Doomed entries).
1690 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1691 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1692 new MockBackendNoCbFactory()));
1694 MockHttpRequest
request(kSimpleGET_Transaction
);
1696 std::vector
<Context
*> context_list
;
1697 const int kNumTransactions
= 5;
1699 for (int i
= 0; i
< kNumTransactions
; i
++) {
1700 context_list
.push_back(new Context());
1701 Context
* c
= context_list
[i
];
1703 c
->result
= cache
->CreateTransaction(&c
->trans
);
1704 ASSERT_EQ(OK
, c
->result
);
1707 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1710 // The first request should be creating the disk cache entry and the others
1711 // should be pending.
1713 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1714 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1715 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1719 // There is not much to do with the transactions at this point... they are
1720 // waiting for a callback that will not fire.
1721 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1722 delete context_list
[i
];
1726 // Tests that we queue requests when initializing the backend.
1727 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1728 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1729 MockHttpCache
cache(factory
);
1731 MockHttpRequest
request0(kSimpleGET_Transaction
);
1732 MockHttpRequest
request1(kTypicalGET_Transaction
);
1733 MockHttpRequest
request2(kETagGET_Transaction
);
1735 std::vector
<Context
*> context_list
;
1736 const int kNumTransactions
= 3;
1738 for (int i
= 0; i
< kNumTransactions
; i
++) {
1739 context_list
.push_back(new Context());
1740 Context
* c
= context_list
[i
];
1742 c
->result
= cache
.CreateTransaction(&c
->trans
);
1743 ASSERT_EQ(OK
, c
->result
);
1746 context_list
[0]->result
= context_list
[0]->trans
->Start(
1747 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1748 context_list
[1]->result
= context_list
[1]->trans
->Start(
1749 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1750 context_list
[2]->result
= context_list
[2]->trans
->Start(
1751 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1753 // Just to make sure that everything is still pending.
1754 base::MessageLoop::current()->RunUntilIdle();
1756 // The first request should be creating the disk cache.
1757 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1759 factory
->FinishCreation();
1761 base::MessageLoop::current()->RunUntilIdle();
1762 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1763 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1765 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1766 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1767 delete context_list
[i
];
1771 // Tests that we can cancel requests that are queued waiting for the backend
1772 // to be initialized.
1773 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1774 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1775 MockHttpCache
cache(factory
);
1777 MockHttpRequest
request0(kSimpleGET_Transaction
);
1778 MockHttpRequest
request1(kTypicalGET_Transaction
);
1779 MockHttpRequest
request2(kETagGET_Transaction
);
1781 std::vector
<Context
*> context_list
;
1782 const int kNumTransactions
= 3;
1784 for (int i
= 0; i
< kNumTransactions
; i
++) {
1785 context_list
.push_back(new Context());
1786 Context
* c
= context_list
[i
];
1788 c
->result
= cache
.CreateTransaction(&c
->trans
);
1789 ASSERT_EQ(OK
, c
->result
);
1792 context_list
[0]->result
= context_list
[0]->trans
->Start(
1793 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1794 context_list
[1]->result
= context_list
[1]->trans
->Start(
1795 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1796 context_list
[2]->result
= context_list
[2]->trans
->Start(
1797 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1799 // Just to make sure that everything is still pending.
1800 base::MessageLoop::current()->RunUntilIdle();
1802 // The first request should be creating the disk cache.
1803 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1805 // Cancel a request from the pending queue.
1806 delete context_list
[1];
1807 context_list
[1] = NULL
;
1809 // Cancel the request that is creating the entry.
1810 delete context_list
[0];
1811 context_list
[0] = NULL
;
1813 // Complete the last transaction.
1814 factory
->FinishCreation();
1816 context_list
[2]->result
=
1817 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1818 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1820 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1821 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1823 delete context_list
[2];
1826 // Tests that we can delete the cache while creating the backend.
1827 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1828 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1829 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1831 MockHttpRequest
request(kSimpleGET_Transaction
);
1833 scoped_ptr
<Context
> c(new Context());
1834 c
->result
= cache
->CreateTransaction(&c
->trans
);
1835 ASSERT_EQ(OK
, c
->result
);
1837 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1839 // Just to make sure that everything is still pending.
1840 base::MessageLoop::current()->RunUntilIdle();
1842 // The request should be creating the disk cache.
1843 EXPECT_FALSE(c
->callback
.have_result());
1845 // We cannot call FinishCreation because the factory itself will go away with
1846 // the cache, so grab the callback and attempt to use it.
1847 CompletionCallback callback
= factory
->callback();
1848 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1851 base::MessageLoop::current()->RunUntilIdle();
1854 callback
.Run(ERR_ABORTED
);
1857 // Tests that we can delete the cache while creating the backend, from within
1858 // one of the callbacks.
1859 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1860 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1861 MockHttpCache
* cache
= new MockHttpCache(factory
);
1863 DeleteCacheCompletionCallback
cb(cache
);
1864 disk_cache::Backend
* backend
;
1865 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1866 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1868 // Now let's queue a regular transaction
1869 MockHttpRequest
request(kSimpleGET_Transaction
);
1871 scoped_ptr
<Context
> c(new Context());
1872 c
->result
= cache
->CreateTransaction(&c
->trans
);
1873 ASSERT_EQ(OK
, c
->result
);
1875 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1877 // And another direct backend request.
1878 TestCompletionCallback cb2
;
1879 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1880 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1882 // Just to make sure that everything is still pending.
1883 base::MessageLoop::current()->RunUntilIdle();
1885 // The request should be queued.
1886 EXPECT_FALSE(c
->callback
.have_result());
1888 // Generate the callback.
1889 factory
->FinishCreation();
1890 rv
= cb
.WaitForResult();
1892 // The cache should be gone by now.
1893 base::MessageLoop::current()->RunUntilIdle();
1894 EXPECT_EQ(OK
, c
->callback
.GetResult(c
->result
));
1895 EXPECT_FALSE(cb2
.have_result());
1898 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
1899 MockHttpCache cache
;
1901 // write to the cache
1902 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
1904 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1905 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1906 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1908 // Get the same URL again, but this time we expect it to result
1909 // in a conditional request.
1910 BoundTestNetLog log
;
1911 LoadTimingInfo load_timing_info
;
1912 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
1913 log
.bound(), &load_timing_info
);
1915 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1916 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1917 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1918 TestLoadTimingNetworkRequest(load_timing_info
);
1921 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo
* request
,
1922 std::string
* response_status
,
1923 std::string
* response_headers
,
1924 std::string
* response_data
) {
1926 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
1927 response_status
->assign("HTTP/1.1 304 Not Modified");
1928 response_headers
->assign(kETagGET_Transaction
.response_headers
);
1929 response_data
->clear();
1932 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
1933 MockHttpCache cache
;
1935 ScopedMockTransaction
transaction(kETagGET_Transaction
);
1937 // write to the cache
1938 RunTransactionTest(cache
.http_cache(), transaction
);
1940 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1941 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1942 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1944 // Get the same URL again, but this time we expect it to result
1945 // in a conditional request.
1946 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
1947 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
1948 BoundTestNetLog log
;
1949 LoadTimingInfo load_timing_info
;
1950 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1953 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1954 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1955 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1956 TestLoadTimingNetworkRequest(load_timing_info
);
1959 class RevalidationServer
{
1961 RevalidationServer() {
1962 s_etag_used_
= false;
1963 s_last_modified_used_
= false;
1966 bool EtagUsed() { return s_etag_used_
; }
1967 bool LastModifiedUsed() { return s_last_modified_used_
; }
1969 static void Handler(const HttpRequestInfo
* request
,
1970 std::string
* response_status
,
1971 std::string
* response_headers
,
1972 std::string
* response_data
);
1975 static bool s_etag_used_
;
1976 static bool s_last_modified_used_
;
1978 bool RevalidationServer::s_etag_used_
= false;
1979 bool RevalidationServer::s_last_modified_used_
= false;
1981 void RevalidationServer::Handler(const HttpRequestInfo
* request
,
1982 std::string
* response_status
,
1983 std::string
* response_headers
,
1984 std::string
* response_data
) {
1985 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
))
1986 s_etag_used_
= true;
1988 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfModifiedSince
)) {
1989 s_last_modified_used_
= true;
1992 if (s_etag_used_
|| s_last_modified_used_
) {
1993 response_status
->assign("HTTP/1.1 304 Not Modified");
1994 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
1995 response_data
->clear();
1997 response_status
->assign(kTypicalGET_Transaction
.status
);
1998 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
1999 response_data
->assign(kTypicalGET_Transaction
.data
);
2003 // Tests revalidation after a vary match.
2004 TEST(HttpCache
, GET_ValidateCache_VaryMatch
) {
2005 MockHttpCache cache
;
2007 // Write to the cache.
2008 MockTransaction
transaction(kTypicalGET_Transaction
);
2009 transaction
.request_headers
= "Foo: bar\r\n";
2010 transaction
.response_headers
=
2011 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2012 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2014 "Cache-Control: max-age=0\n"
2016 AddMockTransaction(&transaction
);
2017 RunTransactionTest(cache
.http_cache(), transaction
);
2019 // Read from the cache.
2020 RevalidationServer server
;
2021 transaction
.handler
= server
.Handler
;
2022 BoundTestNetLog log
;
2023 LoadTimingInfo load_timing_info
;
2024 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2027 EXPECT_TRUE(server
.EtagUsed());
2028 EXPECT_TRUE(server
.LastModifiedUsed());
2029 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2030 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2031 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2032 TestLoadTimingNetworkRequest(load_timing_info
);
2033 RemoveMockTransaction(&transaction
);
2036 // Tests revalidation after a vary mismatch if etag is present.
2037 TEST(HttpCache
, GET_ValidateCache_VaryMismatch
) {
2038 MockHttpCache cache
;
2040 // Write to the cache.
2041 MockTransaction
transaction(kTypicalGET_Transaction
);
2042 transaction
.request_headers
= "Foo: bar\r\n";
2043 transaction
.response_headers
=
2044 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2045 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2047 "Cache-Control: max-age=0\n"
2049 AddMockTransaction(&transaction
);
2050 RunTransactionTest(cache
.http_cache(), transaction
);
2052 // Read from the cache and revalidate the entry.
2053 RevalidationServer server
;
2054 transaction
.handler
= server
.Handler
;
2055 transaction
.request_headers
= "Foo: none\r\n";
2056 BoundTestNetLog log
;
2057 LoadTimingInfo load_timing_info
;
2058 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2061 EXPECT_TRUE(server
.EtagUsed());
2062 EXPECT_FALSE(server
.LastModifiedUsed());
2063 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2064 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2065 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2066 TestLoadTimingNetworkRequest(load_timing_info
);
2067 RemoveMockTransaction(&transaction
);
2070 // Tests lack of revalidation after a vary mismatch and no etag.
2071 TEST(HttpCache
, GET_DontValidateCache_VaryMismatch
) {
2072 MockHttpCache cache
;
2074 // Write to the cache.
2075 MockTransaction
transaction(kTypicalGET_Transaction
);
2076 transaction
.request_headers
= "Foo: bar\r\n";
2077 transaction
.response_headers
=
2078 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2079 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2080 "Cache-Control: max-age=0\n"
2082 AddMockTransaction(&transaction
);
2083 RunTransactionTest(cache
.http_cache(), transaction
);
2085 // Read from the cache and don't revalidate the entry.
2086 RevalidationServer server
;
2087 transaction
.handler
= server
.Handler
;
2088 transaction
.request_headers
= "Foo: none\r\n";
2089 BoundTestNetLog log
;
2090 LoadTimingInfo load_timing_info
;
2091 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2094 EXPECT_FALSE(server
.EtagUsed());
2095 EXPECT_FALSE(server
.LastModifiedUsed());
2096 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2097 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2098 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2099 TestLoadTimingNetworkRequest(load_timing_info
);
2100 RemoveMockTransaction(&transaction
);
2103 // Tests that a new vary header provided when revalidating an entry is saved.
2104 TEST(HttpCache
, GET_ValidateCache_VaryMatch_UpdateVary
) {
2105 MockHttpCache cache
;
2107 // Write to the cache.
2108 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2109 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2110 transaction
.response_headers
=
2112 "Cache-Control: max-age=0\n"
2114 RunTransactionTest(cache
.http_cache(), transaction
);
2116 // Validate the entry and change the vary field in the response.
2117 transaction
.request_headers
= "Foo: bar\r\n Name: none\r\n";
2118 transaction
.status
= "HTTP/1.1 304 Not Modified";
2119 transaction
.response_headers
=
2121 "Cache-Control: max-age=3600\n"
2123 RunTransactionTest(cache
.http_cache(), transaction
);
2125 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2126 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2127 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2129 // Make sure that the ActiveEntry is gone.
2130 base::RunLoop().RunUntilIdle();
2132 // Generate a vary mismatch.
2133 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2134 RunTransactionTest(cache
.http_cache(), transaction
);
2136 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2137 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2138 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2141 // Tests that new request headers causing a vary mismatch are paired with the
2142 // new response when the server says the old response can be used.
2143 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_UpdateRequestHeader
) {
2144 MockHttpCache cache
;
2146 // Write to the cache.
2147 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2148 transaction
.request_headers
= "Foo: bar\r\n";
2149 transaction
.response_headers
=
2151 "Cache-Control: max-age=3600\n"
2153 RunTransactionTest(cache
.http_cache(), transaction
);
2155 // Vary-mismatch validation receives 304.
2156 transaction
.request_headers
= "Foo: none\r\n";
2157 transaction
.status
= "HTTP/1.1 304 Not Modified";
2158 RunTransactionTest(cache
.http_cache(), transaction
);
2160 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2161 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2162 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2164 // Make sure that the ActiveEntry is gone.
2165 base::RunLoop().RunUntilIdle();
2167 // Generate a vary mismatch.
2168 transaction
.request_headers
= "Foo: bar\r\n";
2169 RunTransactionTest(cache
.http_cache(), transaction
);
2171 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2172 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2173 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2176 // Tests that a 304 without vary headers doesn't delete the previously stored
2177 // vary data after a vary match revalidation.
2178 TEST(HttpCache
, GET_ValidateCache_VaryMatch_DontDeleteVary
) {
2179 MockHttpCache cache
;
2181 // Write to the cache.
2182 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2183 transaction
.request_headers
= "Foo: bar\r\n";
2184 transaction
.response_headers
=
2186 "Cache-Control: max-age=0\n"
2188 RunTransactionTest(cache
.http_cache(), transaction
);
2190 // Validate the entry and remove the vary field in the response.
2191 transaction
.status
= "HTTP/1.1 304 Not Modified";
2192 transaction
.response_headers
=
2194 "Cache-Control: max-age=3600\n";
2195 RunTransactionTest(cache
.http_cache(), transaction
);
2197 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2198 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2199 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2201 // Make sure that the ActiveEntry is gone.
2202 base::RunLoop().RunUntilIdle();
2204 // Generate a vary mismatch.
2205 transaction
.request_headers
= "Foo: none\r\n";
2206 RunTransactionTest(cache
.http_cache(), transaction
);
2208 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2209 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2210 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2213 // Tests that a 304 without vary headers doesn't delete the previously stored
2214 // vary data after a vary mismatch.
2215 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_DontDeleteVary
) {
2216 MockHttpCache cache
;
2218 // Write to the cache.
2219 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2220 transaction
.request_headers
= "Foo: bar\r\n";
2221 transaction
.response_headers
=
2223 "Cache-Control: max-age=3600\n"
2225 RunTransactionTest(cache
.http_cache(), transaction
);
2227 // Vary-mismatch validation receives 304 and no vary header.
2228 transaction
.request_headers
= "Foo: none\r\n";
2229 transaction
.status
= "HTTP/1.1 304 Not Modified";
2230 transaction
.response_headers
=
2232 "Cache-Control: max-age=3600\n";
2233 RunTransactionTest(cache
.http_cache(), transaction
);
2235 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2236 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2237 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2239 // Make sure that the ActiveEntry is gone.
2240 base::RunLoop().RunUntilIdle();
2242 // Generate a vary mismatch.
2243 transaction
.request_headers
= "Foo: bar\r\n";
2244 RunTransactionTest(cache
.http_cache(), transaction
);
2246 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2247 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2248 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2251 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo
* request
,
2252 std::string
* response_status
,
2253 std::string
* response_headers
,
2254 std::string
* response_data
) {
2256 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2259 TEST(HttpCache
, ETagGET_Http10
) {
2260 MockHttpCache cache
;
2262 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2263 transaction
.status
= "HTTP/1.0 200 OK";
2265 // Write to the cache.
2266 RunTransactionTest(cache
.http_cache(), transaction
);
2268 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2269 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2270 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2272 // Get the same URL again, without generating a conditional request.
2273 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2274 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2275 RunTransactionTest(cache
.http_cache(), transaction
);
2277 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2278 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2279 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2282 TEST(HttpCache
, ETagGET_Http10_Range
) {
2283 MockHttpCache cache
;
2285 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2286 transaction
.status
= "HTTP/1.0 200 OK";
2288 // Write to the cache.
2289 RunTransactionTest(cache
.http_cache(), transaction
);
2291 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2292 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2293 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2295 // Get the same URL again, but use a byte range request.
2296 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2297 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2298 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2299 RunTransactionTest(cache
.http_cache(), transaction
);
2301 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2302 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2303 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2306 static void ETagGet_ConditionalRequest_NoStore_Handler(
2307 const HttpRequestInfo
* request
,
2308 std::string
* response_status
,
2309 std::string
* response_headers
,
2310 std::string
* response_data
) {
2312 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2313 response_status
->assign("HTTP/1.1 304 Not Modified");
2314 response_headers
->assign("Cache-Control: no-store\n");
2315 response_data
->clear();
2318 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2319 MockHttpCache cache
;
2321 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2323 // Write to the cache.
2324 RunTransactionTest(cache
.http_cache(), transaction
);
2326 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2327 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2328 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2330 // Get the same URL again, but this time we expect it to result
2331 // in a conditional request.
2332 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2333 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2334 RunTransactionTest(cache
.http_cache(), transaction
);
2336 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2337 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2338 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2340 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2342 // Write to the cache again. This should create a new entry.
2343 RunTransactionTest(cache
.http_cache(), transaction2
);
2345 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2346 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2347 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2350 // Helper that does 4 requests using HttpCache:
2352 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2353 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2354 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2356 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2358 static void ConditionalizedRequestUpdatesCacheHelper(
2359 const Response
& net_response_1
,
2360 const Response
& net_response_2
,
2361 const Response
& cached_response_2
,
2362 const char* extra_request_headers
) {
2363 MockHttpCache cache
;
2365 // The URL we will be requesting.
2366 const char kUrl
[] = "http://foobar.com/main.css";
2368 // Junk network response.
2369 static const Response kUnexpectedResponse
= {
2370 "HTTP/1.1 500 Unexpected",
2371 "Server: unexpected_header",
2375 // We will control the network layer's responses for |kUrl| using
2376 // |mock_network_response|.
2377 MockTransaction mock_network_response
= { 0 };
2378 mock_network_response
.url
= kUrl
;
2379 AddMockTransaction(&mock_network_response
);
2381 // Request |kUrl| for the first time. It should hit the network and
2382 // receive |kNetResponse1|, which it saves into the HTTP cache.
2384 MockTransaction request
= { 0 };
2386 request
.method
= "GET";
2387 request
.request_headers
= "";
2389 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2390 net_response_1
.AssignTo(&request
); // Expected result.
2392 std::string response_headers
;
2393 RunTransactionTestWithResponse(
2394 cache
.http_cache(), request
, &response_headers
);
2396 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2397 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2398 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2399 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2401 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2402 // cache, so we don't hit the network.
2404 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2406 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2407 net_response_1
.AssignTo(&request
); // Expected result.
2409 RunTransactionTestWithResponse(
2410 cache
.http_cache(), request
, &response_headers
);
2412 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2413 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2414 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2415 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2417 // Request |kUrl| yet again, but this time give the request an
2418 // "If-Modified-Since" header. This will cause the request to re-hit the
2419 // network. However now the network response is going to be
2420 // different -- this simulates a change made to the CSS file.
2422 request
.request_headers
= extra_request_headers
;
2423 request
.load_flags
= LOAD_NORMAL
;
2425 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2426 net_response_2
.AssignTo(&request
); // Expected result.
2428 RunTransactionTestWithResponse(
2429 cache
.http_cache(), request
, &response_headers
);
2431 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2432 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2433 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2434 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2436 // Finally, request |kUrl| again. This request should be serviced from
2437 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2438 // and NOT |kNetResponse1|. The previous step should have replaced the
2439 // value in the cache with the modified response.
2441 request
.request_headers
= "";
2442 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2444 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2445 cached_response_2
.AssignTo(&request
); // Expected result.
2447 RunTransactionTestWithResponse(
2448 cache
.http_cache(), request
, &response_headers
);
2450 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2451 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2452 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2453 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2455 RemoveMockTransaction(&mock_network_response
);
2458 // Check that when an "if-modified-since" header is attached
2459 // to the request, the result still updates the cached entry.
2460 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2461 // First network response for |kUrl|.
2462 static const Response kNetResponse1
= {
2464 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2465 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2469 // Second network response for |kUrl|.
2470 static const Response kNetResponse2
= {
2472 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2473 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2477 const char extra_headers
[] =
2478 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2480 ConditionalizedRequestUpdatesCacheHelper(
2481 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2484 // Check that when an "if-none-match" header is attached
2485 // to the request, the result updates the cached entry.
2486 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2487 // First network response for |kUrl|.
2488 static const Response kNetResponse1
= {
2490 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2492 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2496 // Second network response for |kUrl|.
2497 static const Response kNetResponse2
= {
2499 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2501 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2505 const char extra_headers
[] = "If-None-Match: \"ETAG1\"\r\n";
2507 ConditionalizedRequestUpdatesCacheHelper(
2508 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2511 // Check that when an "if-modified-since" header is attached
2512 // to a request, the 304 (not modified result) result updates the cached
2513 // headers, and the 304 response is returned rather than the cached response.
2514 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2515 // First network response for |kUrl|.
2516 static const Response kNetResponse1
= {
2518 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2520 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2524 // Second network response for |kUrl|.
2525 static const Response kNetResponse2
= {
2526 "HTTP/1.1 304 Not Modified",
2527 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2529 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2533 static const Response kCachedResponse2
= {
2535 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2537 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2541 const char extra_headers
[] =
2542 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2544 ConditionalizedRequestUpdatesCacheHelper(
2545 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2548 // Test that when doing an externally conditionalized if-modified-since
2549 // and there is no corresponding cache entry, a new cache entry is NOT
2550 // created (304 response).
2551 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2552 MockHttpCache cache
;
2554 const char kUrl
[] = "http://foobar.com/main.css";
2556 static const Response kNetResponse
= {
2557 "HTTP/1.1 304 Not Modified",
2558 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2559 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2563 const char kExtraRequestHeaders
[] =
2564 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2566 // We will control the network layer's responses for |kUrl| using
2567 // |mock_network_response|.
2568 MockTransaction mock_network_response
= { 0 };
2569 mock_network_response
.url
= kUrl
;
2570 AddMockTransaction(&mock_network_response
);
2572 MockTransaction request
= { 0 };
2574 request
.method
= "GET";
2575 request
.request_headers
= kExtraRequestHeaders
;
2577 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2578 kNetResponse
.AssignTo(&request
); // Expected result.
2580 std::string response_headers
;
2581 RunTransactionTestWithResponse(
2582 cache
.http_cache(), request
, &response_headers
);
2584 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2585 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2586 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2587 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2589 RemoveMockTransaction(&mock_network_response
);
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 (200 response).
2595 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2596 MockHttpCache cache
;
2598 const char kUrl
[] = "http://foobar.com/main.css";
2600 static const Response kNetResponse
= {
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 // if the date does not match the cache entry's last-modified date,
2638 // then we do NOT use the response (304) to update the cache.
2639 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2640 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2641 static const Response kNetResponse1
= {
2643 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2645 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2649 // Second network response for |kUrl|.
2650 static const Response kNetResponse2
= {
2651 "HTTP/1.1 304 Not Modified",
2652 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2654 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2658 // This is two days in the future from the original response's last-modified
2660 const char kExtraRequestHeaders
[] =
2661 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2663 ConditionalizedRequestUpdatesCacheHelper(
2664 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2667 // Test that when doing an externally conditionalized if-none-match
2668 // if the etag does not match the cache entry's etag, then we do not use the
2669 // response (304) to update the cache.
2670 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2671 static const Response kNetResponse1
= {
2673 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2675 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2679 // Second network response for |kUrl|.
2680 static const Response kNetResponse2
= {
2681 "HTTP/1.1 304 Not Modified",
2682 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2684 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2688 // Different etag from original response.
2689 const char kExtraRequestHeaders
[] = "If-None-Match: \"Foo2\"\r\n";
2691 ConditionalizedRequestUpdatesCacheHelper(
2692 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2695 // Test that doing an externally conditionalized request with both if-none-match
2696 // and if-modified-since updates the cache.
2697 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2698 static const Response kNetResponse1
= {
2700 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2702 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2706 // Second network response for |kUrl|.
2707 static const Response kNetResponse2
= {
2709 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2711 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2715 const char kExtraRequestHeaders
[] =
2716 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2717 "If-None-Match: \"Foo1\"\r\n";
2719 ConditionalizedRequestUpdatesCacheHelper(
2720 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2723 // Test that doing an externally conditionalized request with both if-none-match
2724 // and if-modified-since does not update the cache with only one match.
2725 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2726 static const Response kNetResponse1
= {
2728 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2730 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2734 // Second network response for |kUrl|.
2735 static const Response kNetResponse2
= {
2737 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2739 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2743 // The etag doesn't match what we have stored.
2744 const char kExtraRequestHeaders
[] =
2745 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2746 "If-None-Match: \"Foo2\"\r\n";
2748 ConditionalizedRequestUpdatesCacheHelper(
2749 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2752 // Test that doing an externally conditionalized request with both if-none-match
2753 // and if-modified-since does not update the cache with only one match.
2754 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2755 static const Response kNetResponse1
= {
2757 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2759 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2763 // Second network response for |kUrl|.
2764 static const Response kNetResponse2
= {
2766 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2768 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2772 // The modification date doesn't match what we have stored.
2773 const char kExtraRequestHeaders
[] =
2774 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2775 "If-None-Match: \"Foo1\"\r\n";
2777 ConditionalizedRequestUpdatesCacheHelper(
2778 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2781 TEST(HttpCache
, UrlContainingHash
) {
2782 MockHttpCache cache
;
2784 // Do a typical GET request -- should write an entry into our cache.
2785 MockTransaction
trans(kTypicalGET_Transaction
);
2786 RunTransactionTest(cache
.http_cache(), trans
);
2788 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2789 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2790 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2792 // Request the same URL, but this time with a reference section (hash).
2793 // Since the cache key strips the hash sections, this should be a cache hit.
2794 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2795 trans
.url
= url_with_hash
.c_str();
2796 trans
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2798 RunTransactionTest(cache
.http_cache(), trans
);
2800 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2801 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2802 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2805 // Tests that we skip the cache for POST requests that do not have an upload
2807 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2808 MockHttpCache cache
;
2810 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2812 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2813 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2814 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2817 // Tests POST handling with a disabled cache (no DCHECK).
2818 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2819 MockHttpCache cache
;
2820 cache
.http_cache()->set_mode(HttpCache::Mode::DISABLE
);
2822 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2824 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2825 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2826 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2829 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2830 MockHttpCache cache
;
2832 MockTransaction
transaction(kSimplePOST_Transaction
);
2833 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2835 MockHttpRequest
request(transaction
);
2836 TestCompletionCallback callback
;
2838 scoped_ptr
<HttpTransaction
> trans
;
2839 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
2840 ASSERT_TRUE(trans
.get());
2842 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
2843 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
2847 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2848 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2849 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2852 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2853 MockHttpCache cache
;
2855 // Test that we hit the cache for POST requests.
2857 MockTransaction
transaction(kSimplePOST_Transaction
);
2859 const int64 kUploadId
= 1; // Just a dummy value.
2861 ScopedVector
<UploadElementReader
> element_readers
;
2862 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2863 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2865 MockHttpRequest
request(transaction
);
2866 request
.upload_data_stream
= &upload_data_stream
;
2868 // Populate the cache.
2869 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2871 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2872 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2873 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2876 request
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2877 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2879 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2880 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2881 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2884 // Test that we don't hit the cache for POST requests if there is a byte range.
2885 TEST(HttpCache
, SimplePOST_WithRanges
) {
2886 MockHttpCache cache
;
2888 MockTransaction
transaction(kSimplePOST_Transaction
);
2889 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2891 const int64 kUploadId
= 1; // Just a dummy value.
2893 ScopedVector
<UploadElementReader
> element_readers
;
2894 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2895 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2898 MockHttpRequest
request(transaction
);
2899 request
.upload_data_stream
= &upload_data_stream
;
2901 // Attempt to populate the cache.
2902 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2904 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2905 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2906 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2909 // Tests that a POST is cached separately from a previously cached GET.
2910 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2911 MockHttpCache cache
;
2913 ScopedVector
<UploadElementReader
> element_readers
;
2914 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2915 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2917 MockTransaction
transaction(kSimplePOST_Transaction
);
2918 MockHttpRequest
req1(transaction
);
2919 req1
.upload_data_stream
= &upload_data_stream
;
2921 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2923 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2924 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2925 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2927 transaction
.method
= "GET";
2928 MockHttpRequest
req2(transaction
);
2930 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2932 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2933 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2934 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2937 // Tests that a successful POST invalidates a previously cached GET.
2938 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2939 MockHttpCache cache
;
2941 MockTransaction
transaction(kSimpleGET_Transaction
);
2942 AddMockTransaction(&transaction
);
2943 MockHttpRequest
req1(transaction
);
2945 // Attempt to populate the cache.
2946 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2948 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2949 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2950 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2952 ScopedVector
<UploadElementReader
> element_readers
;
2953 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2954 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2956 transaction
.method
= "POST";
2957 transaction
.status
= "HTTP/1.1 205 No Content";
2958 MockHttpRequest
req2(transaction
);
2959 req2
.upload_data_stream
= &upload_data_stream
;
2961 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2963 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2964 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2965 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2967 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2969 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2970 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2971 EXPECT_EQ(3, cache
.disk_cache()->create_count());
2972 RemoveMockTransaction(&transaction
);
2975 // Tests that a successful POST invalidates a previously cached GET, even when
2976 // there is no upload identifier.
2977 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
2978 MockHttpCache cache
;
2980 MockTransaction
transaction(kSimpleGET_Transaction
);
2981 AddMockTransaction(&transaction
);
2982 MockHttpRequest
req1(transaction
);
2984 // Attempt to populate the cache.
2985 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2987 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2988 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2989 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2991 ScopedVector
<UploadElementReader
> element_readers
;
2992 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2993 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2995 transaction
.method
= "POST";
2996 transaction
.status
= "HTTP/1.1 205 No Content";
2997 MockHttpRequest
req2(transaction
);
2998 req2
.upload_data_stream
= &upload_data_stream
;
3000 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3002 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3003 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3004 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3006 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3008 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3009 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3010 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3011 RemoveMockTransaction(&transaction
);
3014 // Tests that processing a POST before creating the backend doesn't crash.
3015 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
3016 // This will initialize a cache object with NULL backend.
3017 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
3018 factory
->set_fail(true);
3019 factory
->FinishCreation();
3020 MockHttpCache
cache(factory
);
3022 ScopedVector
<UploadElementReader
> element_readers
;
3023 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3024 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3026 MockTransaction
transaction(kSimplePOST_Transaction
);
3027 AddMockTransaction(&transaction
);
3028 MockHttpRequest
req(transaction
);
3029 req
.upload_data_stream
= &upload_data_stream
;
3031 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
3033 RemoveMockTransaction(&transaction
);
3036 // Tests that we don't invalidate entries as a result of a failed POST.
3037 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
3038 MockHttpCache cache
;
3040 MockTransaction
transaction(kSimpleGET_Transaction
);
3041 AddMockTransaction(&transaction
);
3042 MockHttpRequest
req1(transaction
);
3044 // Attempt to populate the cache.
3045 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3047 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3048 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3049 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3051 ScopedVector
<UploadElementReader
> element_readers
;
3052 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3053 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3055 transaction
.method
= "POST";
3056 transaction
.status
= "HTTP/1.1 100 Continue";
3057 MockHttpRequest
req2(transaction
);
3058 req2
.upload_data_stream
= &upload_data_stream
;
3060 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3062 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3063 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3064 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3066 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3068 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3069 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3070 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3071 RemoveMockTransaction(&transaction
);
3074 // Tests that a HEAD request is not cached by itself.
3075 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3076 MockHttpCache cache
;
3077 MockTransaction
transaction(kSimplePOST_Transaction
);
3078 AddMockTransaction(&transaction
);
3079 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3080 transaction
.method
= "HEAD";
3082 MockHttpRequest
request(transaction
);
3083 TestCompletionCallback callback
;
3085 scoped_ptr
<HttpTransaction
> trans
;
3086 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
3087 ASSERT_TRUE(trans
.get());
3089 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
3090 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
3094 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3095 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3096 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3097 RemoveMockTransaction(&transaction
);
3100 // Tests that a HEAD request is served from a cached GET.
3101 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3102 MockHttpCache cache
;
3103 MockTransaction
transaction(kSimpleGET_Transaction
);
3104 AddMockTransaction(&transaction
);
3106 // Populate the cache.
3107 RunTransactionTest(cache
.http_cache(), transaction
);
3109 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3110 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3111 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3114 transaction
.method
= "HEAD";
3115 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3116 transaction
.data
= "";
3117 RunTransactionTest(cache
.http_cache(), transaction
);
3119 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3120 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3121 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3122 RemoveMockTransaction(&transaction
);
3125 // Tests that a read-only request served from the cache preserves CL.
3126 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3127 MockHttpCache cache
;
3128 MockTransaction
transaction(kSimpleGET_Transaction
);
3129 AddMockTransaction(&transaction
);
3130 transaction
.response_headers
= "Content-Length: 42\n";
3132 // Populate the cache.
3133 RunTransactionTest(cache
.http_cache(), transaction
);
3136 transaction
.method
= "HEAD";
3137 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3138 transaction
.data
= "";
3139 std::string headers
;
3141 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3143 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3144 RemoveMockTransaction(&transaction
);
3147 // Tests that a read-write request served from the cache preserves CL.
3148 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3149 MockHttpCache cache
;
3150 MockTransaction
transaction(kETagGET_Transaction
);
3151 AddMockTransaction(&transaction
);
3152 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3153 server_headers
.append("Content-Length: 42\n");
3154 transaction
.response_headers
= server_headers
.data();
3156 // Populate the cache.
3157 RunTransactionTest(cache
.http_cache(), transaction
);
3160 transaction
.method
= "HEAD";
3161 transaction
.data
= "";
3162 std::string headers
;
3164 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3166 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3167 RemoveMockTransaction(&transaction
);
3170 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3171 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3172 MockHttpCache cache
;
3173 MockTransaction
transaction(kSimpleGET_Transaction
);
3174 AddMockTransaction(&transaction
);
3176 // Populate the cache.
3177 RunTransactionTest(cache
.http_cache(), transaction
);
3180 transaction
.method
= "HEAD";
3181 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3182 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3183 transaction
.return_code
= ERR_CACHE_MISS
;
3184 RunTransactionTest(cache
.http_cache(), transaction
);
3186 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3187 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3188 RemoveMockTransaction(&transaction
);
3191 // Tests that a HEAD request can be served from a partialy cached resource.
3192 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3193 MockHttpCache cache
;
3194 AddMockTransaction(&kRangeGET_TransactionOK
);
3196 // Write to the cache (40-49).
3197 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3198 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3200 MockTransaction
transaction(kSimpleGET_Transaction
);
3202 transaction
.url
= kRangeGET_TransactionOK
.url
;
3203 transaction
.method
= "HEAD";
3204 transaction
.data
= "";
3205 AddMockTransaction(&transaction
);
3206 std::string headers
;
3209 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3211 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3212 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3213 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3214 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3215 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3216 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3217 RemoveMockTransaction(&transaction
);
3220 // Tests that a HEAD request can be served from a truncated resource.
3221 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3222 MockHttpCache cache
;
3223 AddMockTransaction(&kRangeGET_TransactionOK
);
3225 std::string
raw_headers("HTTP/1.1 200 OK\n"
3226 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3228 "Accept-Ranges: bytes\n"
3229 "Content-Length: 80\n");
3230 CreateTruncatedEntry(raw_headers
, &cache
);
3231 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3233 MockTransaction
transaction(kSimpleGET_Transaction
);
3235 transaction
.url
= kRangeGET_TransactionOK
.url
;
3236 transaction
.method
= "HEAD";
3237 transaction
.data
= "";
3238 AddMockTransaction(&transaction
);
3239 std::string headers
;
3242 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3244 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3245 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3246 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3247 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3248 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3249 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3250 RemoveMockTransaction(&transaction
);
3253 // Tests that a HEAD request updates the cached response.
3254 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3255 MockHttpCache cache
;
3256 MockTransaction
transaction(kTypicalGET_Transaction
);
3257 AddMockTransaction(&transaction
);
3259 // Populate the cache.
3260 RunTransactionTest(cache
.http_cache(), transaction
);
3262 // Update the cache.
3263 transaction
.method
= "HEAD";
3264 transaction
.response_headers
= "Foo: bar\n";
3265 transaction
.data
= "";
3266 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3267 std::string headers
;
3268 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3269 RemoveMockTransaction(&transaction
);
3271 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3272 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3274 MockTransaction
transaction2(kTypicalGET_Transaction
);
3275 AddMockTransaction(&transaction2
);
3277 // Make sure we are done with the previous transaction.
3278 base::MessageLoop::current()->RunUntilIdle();
3280 // Load from the cache.
3281 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3282 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3284 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3285 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3286 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3287 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3288 RemoveMockTransaction(&transaction2
);
3291 // Tests that an externally conditionalized HEAD request updates the cache.
3292 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3293 MockHttpCache cache
;
3294 MockTransaction
transaction(kTypicalGET_Transaction
);
3295 AddMockTransaction(&transaction
);
3297 // Populate the cache.
3298 RunTransactionTest(cache
.http_cache(), transaction
);
3300 // Update the cache.
3301 transaction
.method
= "HEAD";
3302 transaction
.request_headers
=
3303 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3304 transaction
.response_headers
= "Foo: bar\n";
3305 transaction
.data
= "";
3306 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3307 std::string headers
;
3308 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3309 RemoveMockTransaction(&transaction
);
3311 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3312 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3314 MockTransaction
transaction2(kTypicalGET_Transaction
);
3315 AddMockTransaction(&transaction2
);
3317 // Make sure we are done with the previous transaction.
3318 base::MessageLoop::current()->RunUntilIdle();
3320 // Load from the cache.
3321 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3322 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3324 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3325 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3326 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3327 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3328 RemoveMockTransaction(&transaction2
);
3331 // Tests that a HEAD request invalidates an old cached entry.
3332 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3333 MockHttpCache cache
;
3334 MockTransaction
transaction(kTypicalGET_Transaction
);
3335 AddMockTransaction(&transaction
);
3337 // Populate the cache.
3338 RunTransactionTest(cache
.http_cache(), transaction
);
3340 // Update the cache.
3341 transaction
.method
= "HEAD";
3342 transaction
.data
= "";
3343 RunTransactionTest(cache
.http_cache(), transaction
);
3344 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3346 // Load from the cache.
3347 transaction
.method
= "GET";
3348 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3349 transaction
.return_code
= ERR_CACHE_MISS
;
3350 RunTransactionTest(cache
.http_cache(), transaction
);
3352 RemoveMockTransaction(&transaction
);
3355 // Tests that we do not cache the response of a PUT.
3356 TEST(HttpCache
, SimplePUT_Miss
) {
3357 MockHttpCache cache
;
3359 MockTransaction
transaction(kSimplePOST_Transaction
);
3360 transaction
.method
= "PUT";
3362 ScopedVector
<UploadElementReader
> element_readers
;
3363 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3364 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3366 MockHttpRequest
request(transaction
);
3367 request
.upload_data_stream
= &upload_data_stream
;
3369 // Attempt to populate the cache.
3370 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3372 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3373 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3374 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3377 // Tests that we invalidate entries as a result of a PUT.
3378 TEST(HttpCache
, SimplePUT_Invalidate
) {
3379 MockHttpCache cache
;
3381 MockTransaction
transaction(kSimpleGET_Transaction
);
3382 MockHttpRequest
req1(transaction
);
3384 // Attempt to populate the cache.
3385 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3387 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3388 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3389 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3391 ScopedVector
<UploadElementReader
> element_readers
;
3392 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3393 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3395 transaction
.method
= "PUT";
3396 MockHttpRequest
req2(transaction
);
3397 req2
.upload_data_stream
= &upload_data_stream
;
3399 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3401 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3402 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3403 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3405 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3407 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3408 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3409 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3412 // Tests that we invalidate entries as a result of a PUT.
3413 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3414 MockHttpCache cache
;
3416 MockTransaction
transaction(kSimpleGET_Transaction
);
3417 AddMockTransaction(&transaction
);
3418 MockHttpRequest
req1(transaction
);
3420 // Attempt to populate the cache.
3421 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3423 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3424 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3425 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3427 ScopedVector
<UploadElementReader
> element_readers
;
3428 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3429 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3431 transaction
.method
= "PUT";
3432 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3433 MockHttpRequest
req2(transaction
);
3434 req2
.upload_data_stream
= &upload_data_stream
;
3436 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3438 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3439 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3440 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3442 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3444 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3445 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3446 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3447 RemoveMockTransaction(&transaction
);
3450 // Tests that we don't invalidate entries as a result of a failed PUT.
3451 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3452 MockHttpCache cache
;
3454 MockTransaction
transaction(kSimpleGET_Transaction
);
3455 AddMockTransaction(&transaction
);
3456 MockHttpRequest
req1(transaction
);
3458 // Attempt to populate the cache.
3459 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3461 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3462 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3463 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3465 ScopedVector
<UploadElementReader
> element_readers
;
3466 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3467 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3469 transaction
.method
= "PUT";
3470 transaction
.status
= "HTTP/1.1 404 Not Found";
3471 MockHttpRequest
req2(transaction
);
3472 req2
.upload_data_stream
= &upload_data_stream
;
3474 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3476 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3477 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3478 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3480 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3482 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3483 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3484 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3485 RemoveMockTransaction(&transaction
);
3488 // Tests that we do not cache the response of a DELETE.
3489 TEST(HttpCache
, SimpleDELETE_Miss
) {
3490 MockHttpCache cache
;
3492 MockTransaction
transaction(kSimplePOST_Transaction
);
3493 transaction
.method
= "DELETE";
3495 ScopedVector
<UploadElementReader
> element_readers
;
3496 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3497 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3499 MockHttpRequest
request(transaction
);
3500 request
.upload_data_stream
= &upload_data_stream
;
3502 // Attempt to populate the cache.
3503 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3505 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3506 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3507 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3510 // Tests that we invalidate entries as a result of a DELETE.
3511 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3512 MockHttpCache cache
;
3514 MockTransaction
transaction(kSimpleGET_Transaction
);
3515 MockHttpRequest
req1(transaction
);
3517 // Attempt to populate the cache.
3518 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3520 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3521 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3522 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3524 ScopedVector
<UploadElementReader
> element_readers
;
3525 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3526 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3528 transaction
.method
= "DELETE";
3529 MockHttpRequest
req2(transaction
);
3530 req2
.upload_data_stream
= &upload_data_stream
;
3532 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3534 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3535 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3536 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3538 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3540 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3541 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3542 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3545 // Tests that we invalidate entries as a result of a DELETE.
3546 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3547 MockHttpCache cache
;
3549 MockTransaction
transaction(kSimpleGET_Transaction
);
3550 AddMockTransaction(&transaction
);
3552 // Attempt to populate the cache.
3553 RunTransactionTest(cache
.http_cache(), transaction
);
3555 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3556 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3557 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3559 transaction
.method
= "DELETE";
3560 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3562 RunTransactionTest(cache
.http_cache(), transaction
);
3564 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3565 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3566 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3568 transaction
.method
= "GET";
3569 RunTransactionTest(cache
.http_cache(), transaction
);
3571 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3572 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3573 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3574 RemoveMockTransaction(&transaction
);
3577 // Tests that we don't invalidate entries as a result of a failed DELETE.
3578 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3579 MockHttpCache cache
;
3581 MockTransaction
transaction(kSimpleGET_Transaction
);
3582 AddMockTransaction(&transaction
);
3584 // Attempt to populate the cache.
3585 RunTransactionTest(cache
.http_cache(), transaction
);
3587 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3588 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3589 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3591 transaction
.method
= "DELETE";
3592 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3594 RunTransactionTest(cache
.http_cache(), transaction
);
3596 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3597 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3598 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3600 transaction
.method
= "GET";
3601 transaction
.status
= "HTTP/1.1 200 OK";
3602 RunTransactionTest(cache
.http_cache(), transaction
);
3604 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3605 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3606 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3607 RemoveMockTransaction(&transaction
);
3610 // Tests that we don't invalidate entries after a failed network transaction.
3611 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3612 MockHttpCache cache
;
3614 // Populate the cache.
3615 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3616 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3618 // Fail the network request.
3619 MockTransaction
transaction(kSimpleGET_Transaction
);
3620 transaction
.return_code
= ERR_FAILED
;
3621 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
3623 AddMockTransaction(&transaction
);
3624 RunTransactionTest(cache
.http_cache(), transaction
);
3625 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3626 RemoveMockTransaction(&transaction
);
3628 transaction
.load_flags
= LOAD_ONLY_FROM_CACHE
;
3629 transaction
.return_code
= OK
;
3630 AddMockTransaction(&transaction
);
3631 RunTransactionTest(cache
.http_cache(), transaction
);
3633 // Make sure the transaction didn't reach the network.
3634 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3635 RemoveMockTransaction(&transaction
);
3638 TEST(HttpCache
, RangeGET_SkipsCache
) {
3639 MockHttpCache cache
;
3641 // Test that we skip the cache for range GET requests. Eventually, we will
3642 // want to cache these, but we'll still have cases where skipping the cache
3643 // makes sense, so we want to make sure that it works properly.
3645 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3647 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3648 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3649 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3651 MockTransaction
transaction(kSimpleGET_Transaction
);
3652 transaction
.request_headers
= "If-None-Match: foo\r\n";
3653 RunTransactionTest(cache
.http_cache(), transaction
);
3655 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3656 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3657 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3659 transaction
.request_headers
=
3660 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3661 RunTransactionTest(cache
.http_cache(), transaction
);
3663 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3664 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3665 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3668 // Test that we skip the cache for range requests that include a validation
3670 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3671 MockHttpCache cache
;
3673 MockTransaction
transaction(kRangeGET_Transaction
);
3674 transaction
.request_headers
= "If-None-Match: foo\r\n"
3676 "Range: bytes = 40-49\r\n";
3677 RunTransactionTest(cache
.http_cache(), transaction
);
3679 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3680 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3681 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3683 transaction
.request_headers
=
3684 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3686 "Range: bytes = 40-49\r\n";
3687 RunTransactionTest(cache
.http_cache(), transaction
);
3689 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3690 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3691 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3693 transaction
.request_headers
= "If-Range: bla\r\n"
3695 "Range: bytes = 40-49\r\n";
3696 RunTransactionTest(cache
.http_cache(), transaction
);
3698 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3699 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3700 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3703 TEST(HttpCache
, SimpleGET_DoesntLogHeaders
) {
3704 MockHttpCache cache
;
3706 BoundTestNetLog log
;
3707 RunTransactionTestWithLog(cache
.http_cache(), kSimpleGET_Transaction
,
3710 EXPECT_FALSE(LogContainsEventType(
3711 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3714 TEST(HttpCache
, RangeGET_LogsHeaders
) {
3715 MockHttpCache cache
;
3717 BoundTestNetLog log
;
3718 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_Transaction
,
3721 EXPECT_TRUE(LogContainsEventType(
3722 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3725 TEST(HttpCache
, ExternalValidation_LogsHeaders
) {
3726 MockHttpCache cache
;
3728 BoundTestNetLog log
;
3729 MockTransaction
transaction(kSimpleGET_Transaction
);
3730 transaction
.request_headers
= "If-None-Match: foo\r\n" EXTRA_HEADER
;
3731 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3733 EXPECT_TRUE(LogContainsEventType(
3734 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3737 TEST(HttpCache
, SpecialHeaders_LogsHeaders
) {
3738 MockHttpCache cache
;
3740 BoundTestNetLog log
;
3741 MockTransaction
transaction(kSimpleGET_Transaction
);
3742 transaction
.request_headers
= "cache-control: no-cache\r\n" EXTRA_HEADER
;
3743 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3745 EXPECT_TRUE(LogContainsEventType(
3746 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3749 // Tests that receiving 206 for a regular request is handled correctly.
3750 TEST(HttpCache
, GET_Crazy206
) {
3751 MockHttpCache cache
;
3753 // Write to the cache.
3754 MockTransaction
transaction(kRangeGET_TransactionOK
);
3755 AddMockTransaction(&transaction
);
3756 transaction
.request_headers
= EXTRA_HEADER
;
3757 transaction
.handler
= NULL
;
3758 RunTransactionTest(cache
.http_cache(), transaction
);
3760 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3761 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3762 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3764 // This should read again from the net.
3765 RunTransactionTest(cache
.http_cache(), transaction
);
3767 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3768 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3769 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3770 RemoveMockTransaction(&transaction
);
3773 // Tests that receiving 416 for a regular request is handled correctly.
3774 TEST(HttpCache
, GET_Crazy416
) {
3775 MockHttpCache cache
;
3777 // Write to the cache.
3778 MockTransaction
transaction(kSimpleGET_Transaction
);
3779 AddMockTransaction(&transaction
);
3780 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3781 RunTransactionTest(cache
.http_cache(), transaction
);
3783 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3784 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3785 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3787 RemoveMockTransaction(&transaction
);
3790 // Tests that we don't store partial responses that can't be validated.
3791 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3792 MockHttpCache cache
;
3793 std::string headers
;
3795 // Attempt to write to the cache (40-49).
3796 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3797 transaction
.response_headers
= "Content-Length: 10\n"
3798 "Cache-Control: max-age=3600\n"
3799 "ETag: w/\"foo\"\n";
3800 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3802 Verify206Response(headers
, 40, 49);
3803 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3804 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3805 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3807 // Now verify that there's no cached data.
3808 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3811 Verify206Response(headers
, 40, 49);
3812 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3813 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3814 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3817 // Tests failures to conditionalize byte range requests.
3818 TEST(HttpCache
, RangeGET_NoConditionalization
) {
3819 MockHttpCache cache
;
3820 cache
.FailConditionalizations();
3821 std::string headers
;
3823 // Write to the cache (40-49).
3824 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3825 transaction
.response_headers
= "Content-Length: 10\n"
3827 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3829 Verify206Response(headers
, 40, 49);
3830 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3831 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3832 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3834 // Now verify that the cached data is not used.
3835 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3838 Verify206Response(headers
, 40, 49);
3839 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3840 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3841 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3844 // Tests that restarting a partial request when the cached data cannot be
3845 // revalidated logs an event.
3846 TEST(HttpCache
, RangeGET_NoValidation_LogsRestart
) {
3847 MockHttpCache cache
;
3848 cache
.FailConditionalizations();
3850 // Write to the cache (40-49).
3851 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3852 transaction
.response_headers
= "Content-Length: 10\n"
3854 RunTransactionTest(cache
.http_cache(), transaction
);
3856 // Now verify that the cached data is not used.
3857 BoundTestNetLog log
;
3858 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_TransactionOK
,
3861 EXPECT_TRUE(LogContainsEventType(
3862 log
, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST
));
3865 // Tests that a failure to conditionalize a regular request (no range) with a
3866 // sparse entry results in a full response.
3867 TEST(HttpCache
, GET_NoConditionalization
) {
3868 MockHttpCache cache
;
3869 cache
.FailConditionalizations();
3870 std::string headers
;
3872 // Write to the cache (40-49).
3873 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3874 transaction
.response_headers
= "Content-Length: 10\n"
3876 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3878 Verify206Response(headers
, 40, 49);
3879 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3880 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3881 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3883 // Now verify that the cached data is not used.
3884 // Don't ask for a range. The cache will attempt to use the cached data but
3885 // should discard it as it cannot be validated. A regular request should go
3886 // to the server and a new entry should be created.
3887 transaction
.request_headers
= EXTRA_HEADER
;
3888 transaction
.data
= "Not a range";
3889 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3891 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
3892 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3893 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3894 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3896 // The last response was saved.
3897 RunTransactionTest(cache
.http_cache(), transaction
);
3898 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3899 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3900 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3903 // Verifies that conditionalization failures when asking for a range that would
3904 // require the cache to modify the range to ask, result in a network request
3905 // that matches the user's one.
3906 TEST(HttpCache
, RangeGET_NoConditionalization2
) {
3907 MockHttpCache cache
;
3908 cache
.FailConditionalizations();
3909 std::string headers
;
3911 // Write to the cache (40-49).
3912 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3913 transaction
.response_headers
= "Content-Length: 10\n"
3915 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3917 Verify206Response(headers
, 40, 49);
3918 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3919 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3920 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3922 // Now verify that the cached data is not used.
3923 // Ask for a range that extends before and after the cached data so that the
3924 // cache would normally mix data from three sources. After deleting the entry,
3925 // the response will come from a single network request.
3926 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3927 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3928 transaction
.response_headers
= kRangeGET_TransactionOK
.response_headers
;
3929 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3931 Verify206Response(headers
, 20, 59);
3932 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3933 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3934 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3936 // The last response was saved.
3937 RunTransactionTest(cache
.http_cache(), transaction
);
3938 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3939 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3940 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3943 // Tests that we cache partial responses that lack content-length.
3944 TEST(HttpCache
, RangeGET_NoContentLength
) {
3945 MockHttpCache cache
;
3946 std::string headers
;
3948 // Attempt to write to the cache (40-49).
3949 MockTransaction
transaction(kRangeGET_TransactionOK
);
3950 AddMockTransaction(&transaction
);
3951 transaction
.response_headers
= "ETag: \"foo\"\n"
3952 "Accept-Ranges: bytes\n"
3953 "Content-Range: bytes 40-49/80\n";
3954 transaction
.handler
= NULL
;
3955 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3957 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3958 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3959 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3961 // Now verify that there's no cached data.
3962 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
3963 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3966 Verify206Response(headers
, 40, 49);
3967 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3968 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3969 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3971 RemoveMockTransaction(&transaction
);
3974 // Tests that we can cache range requests and fetch random blocks from the
3975 // cache and the network.
3976 TEST(HttpCache
, RangeGET_OK
) {
3977 MockHttpCache cache
;
3978 AddMockTransaction(&kRangeGET_TransactionOK
);
3979 std::string headers
;
3981 // Write to the cache (40-49).
3982 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3985 Verify206Response(headers
, 40, 49);
3986 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3987 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3988 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3990 // Read from the cache (40-49).
3991 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3994 Verify206Response(headers
, 40, 49);
3995 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3996 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3997 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3999 // Make sure we are done with the previous transaction.
4000 base::MessageLoop::current()->RunUntilIdle();
4002 // Write to the cache (30-39).
4003 MockTransaction
transaction(kRangeGET_TransactionOK
);
4004 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4005 transaction
.data
= "rg: 30-39 ";
4006 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4008 Verify206Response(headers
, 30, 39);
4009 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4010 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4011 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4013 // Make sure we are done with the previous transaction.
4014 base::MessageLoop::current()->RunUntilIdle();
4016 // Write and read from the cache (20-59).
4017 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4018 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4019 BoundTestNetLog log
;
4020 LoadTimingInfo load_timing_info
;
4021 RunTransactionTestWithResponseAndGetTiming(
4022 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4025 Verify206Response(headers
, 20, 59);
4026 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4027 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4028 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4029 TestLoadTimingNetworkRequest(load_timing_info
);
4031 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4034 // Tests that we can cache range requests and fetch random blocks from the
4035 // cache and the network, with synchronous responses.
4036 TEST(HttpCache
, RangeGET_SyncOK
) {
4037 MockHttpCache cache
;
4039 MockTransaction
transaction(kRangeGET_TransactionOK
);
4040 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
4041 AddMockTransaction(&transaction
);
4043 // Write to the cache (40-49).
4044 std::string headers
;
4045 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4047 Verify206Response(headers
, 40, 49);
4048 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4049 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4050 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4052 // Read from the cache (40-49).
4053 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4055 Verify206Response(headers
, 40, 49);
4056 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4057 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4058 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4060 // Make sure we are done with the previous transaction.
4061 base::MessageLoop::current()->RunUntilIdle();
4063 // Write to the cache (30-39).
4064 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4065 transaction
.data
= "rg: 30-39 ";
4066 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4068 Verify206Response(headers
, 30, 39);
4069 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4070 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4071 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4073 // Make sure we are done with the previous transaction.
4074 base::MessageLoop::current()->RunUntilIdle();
4076 // Write and read from the cache (20-59).
4077 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4078 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4079 BoundTestNetLog log
;
4080 LoadTimingInfo load_timing_info
;
4081 RunTransactionTestWithResponseAndGetTiming(
4082 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4085 Verify206Response(headers
, 20, 59);
4086 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4087 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4088 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4089 TestLoadTimingNetworkRequest(load_timing_info
);
4091 RemoveMockTransaction(&transaction
);
4094 // Tests that we don't revalidate an entry unless we are required to do so.
4095 TEST(HttpCache
, RangeGET_Revalidate1
) {
4096 MockHttpCache cache
;
4097 std::string headers
;
4099 // Write to the cache (40-49).
4100 MockTransaction
transaction(kRangeGET_TransactionOK
);
4101 transaction
.response_headers
=
4102 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4103 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4105 "Accept-Ranges: bytes\n"
4106 "Content-Length: 10\n";
4107 AddMockTransaction(&transaction
);
4108 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4110 Verify206Response(headers
, 40, 49);
4111 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4112 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4113 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4115 // Read from the cache (40-49).
4116 BoundTestNetLog log
;
4117 LoadTimingInfo load_timing_info
;
4118 RunTransactionTestWithResponseAndGetTiming(
4119 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4122 Verify206Response(headers
, 40, 49);
4123 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4124 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4125 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4126 TestLoadTimingCachedResponse(load_timing_info
);
4128 // Read again forcing the revalidation.
4129 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4130 RunTransactionTestWithResponseAndGetTiming(
4131 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4134 Verify206Response(headers
, 40, 49);
4135 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4136 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4137 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4138 TestLoadTimingNetworkRequest(load_timing_info
);
4140 RemoveMockTransaction(&transaction
);
4143 // Checks that we revalidate an entry when the headers say so.
4144 TEST(HttpCache
, RangeGET_Revalidate2
) {
4145 MockHttpCache cache
;
4146 std::string headers
;
4148 // Write to the cache (40-49).
4149 MockTransaction
transaction(kRangeGET_TransactionOK
);
4150 transaction
.response_headers
=
4151 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4152 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4154 "Accept-Ranges: bytes\n"
4155 "Content-Length: 10\n";
4156 AddMockTransaction(&transaction
);
4157 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4159 Verify206Response(headers
, 40, 49);
4160 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4161 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4162 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4164 // Read from the cache (40-49).
4165 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4166 Verify206Response(headers
, 40, 49);
4168 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4169 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4170 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4172 RemoveMockTransaction(&transaction
);
4175 // Tests that we deal with 304s for range requests.
4176 TEST(HttpCache
, RangeGET_304
) {
4177 MockHttpCache cache
;
4178 AddMockTransaction(&kRangeGET_TransactionOK
);
4179 std::string headers
;
4181 // Write to the cache (40-49).
4182 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4185 Verify206Response(headers
, 40, 49);
4186 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4187 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4188 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4190 // Read from the cache (40-49).
4191 RangeTransactionServer handler
;
4192 handler
.set_not_modified(true);
4193 MockTransaction
transaction(kRangeGET_TransactionOK
);
4194 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4195 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4197 Verify206Response(headers
, 40, 49);
4198 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4199 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4200 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4202 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4205 // Tests that we deal with 206s when revalidating range requests.
4206 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4207 MockHttpCache cache
;
4208 AddMockTransaction(&kRangeGET_TransactionOK
);
4209 std::string headers
;
4211 // Write to the cache (40-49).
4212 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4215 Verify206Response(headers
, 40, 49);
4216 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4217 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4218 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4220 // Attempt to read from the cache (40-49).
4221 RangeTransactionServer handler
;
4222 handler
.set_modified(true);
4223 MockTransaction
transaction(kRangeGET_TransactionOK
);
4224 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4225 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4227 Verify206Response(headers
, 40, 49);
4228 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4229 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4230 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4232 // And the entry should be gone.
4233 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4234 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4235 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4236 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4238 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4241 // Tests that when a server returns 206 with a sub-range of the requested range,
4242 // and there is nothing stored in the cache, the returned response is passed to
4243 // the caller as is. In this context, a subrange means a response that starts
4244 // with the same byte that was requested, but that is not the whole range that
4246 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_NoCachedContent
) {
4247 MockHttpCache cache
;
4248 std::string headers
;
4250 // Request a large range (40-59). The server sends 40-49.
4251 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4252 transaction
.request_headers
= "Range: bytes = 40-59\r\n" EXTRA_HEADER
;
4253 transaction
.response_headers
=
4254 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4256 "Accept-Ranges: bytes\n"
4257 "Content-Length: 10\n"
4258 "Content-Range: bytes 40-49/80\n";
4259 transaction
.handler
= nullptr;
4260 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4262 Verify206Response(headers
, 40, 49);
4263 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4264 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4265 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4268 // Tests that when a server returns 206 with a sub-range of the requested range,
4269 // and there was an entry stored in the cache, the cache gets out of the way.
4270 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_CachedContent
) {
4271 MockHttpCache cache
;
4272 std::string headers
;
4274 // Write to the cache (70-79).
4275 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4276 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4277 transaction
.data
= "rg: 70-79 ";
4278 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4279 Verify206Response(headers
, 70, 79);
4281 // Request a large range (40-79). The cache will ask the server for 40-59.
4282 // The server returns 40-49. The cache should consider the server confused and
4283 // abort caching, restarting the request without caching.
4284 transaction
.request_headers
= "Range: bytes = 40-79\r\n" EXTRA_HEADER
;
4285 transaction
.response_headers
=
4286 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4288 "Accept-Ranges: bytes\n"
4289 "Content-Length: 10\n"
4290 "Content-Range: bytes 40-49/80\n";
4291 transaction
.handler
= nullptr;
4292 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4294 // Two new network requests were issued, one from the cache and another after
4295 // deleting the entry.
4296 Verify206Response(headers
, 40, 49);
4297 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4298 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4299 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4301 // The entry was deleted.
4302 RunTransactionTest(cache
.http_cache(), transaction
);
4303 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4304 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4305 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4308 // Tests that when a server returns 206 with a sub-range of the requested range,
4309 // and there was an entry stored in the cache, the cache gets out of the way,
4310 // when the caller is not using ranges.
4311 TEST(HttpCache
, GET_206ReturnsSubrangeRange_CachedContent
) {
4312 MockHttpCache cache
;
4313 std::string headers
;
4315 // Write to the cache (70-79).
4316 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4317 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4318 transaction
.data
= "rg: 70-79 ";
4319 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4320 Verify206Response(headers
, 70, 79);
4322 // Don't ask for a range. The cache will ask the server for 0-69.
4323 // The server returns 40-49. The cache should consider the server confused and
4324 // abort caching, restarting the request.
4325 // The second network request should not be a byte range request so the server
4326 // should return 200 + "Not a range"
4327 transaction
.request_headers
= "X-Return-Default-Range:\r\n" EXTRA_HEADER
;
4328 transaction
.data
= "Not a range";
4329 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4331 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4332 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4333 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4334 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4336 // The entry was deleted.
4337 RunTransactionTest(cache
.http_cache(), transaction
);
4338 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4339 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4340 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4343 // Tests that when a server returns 206 with a random range and there is
4344 // nothing stored in the cache, the returned response is passed to the caller
4345 // as is. In this context, a WrongRange means that the returned range may or may
4346 // not have any relationship with the requested range (may or may not be
4347 // contained). The important part is that the first byte doesn't match the first
4349 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_NoCachedContent
) {
4350 MockHttpCache cache
;
4351 std::string headers
;
4353 // Request a large range (30-59). The server sends (40-49).
4354 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4355 transaction
.request_headers
= "Range: bytes = 30-59\r\n" EXTRA_HEADER
;
4356 transaction
.response_headers
=
4357 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4359 "Accept-Ranges: bytes\n"
4360 "Content-Length: 10\n"
4361 "Content-Range: bytes 40-49/80\n";
4362 transaction
.handler
= nullptr;
4363 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4365 Verify206Response(headers
, 40, 49);
4366 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4367 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4368 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4370 // The entry was deleted.
4371 RunTransactionTest(cache
.http_cache(), transaction
);
4372 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4373 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4374 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4377 // Tests that when a server returns 206 with a random range and there is
4378 // an entry stored in the cache, the cache gets out of the way.
4379 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_CachedContent
) {
4380 MockHttpCache cache
;
4381 std::string headers
;
4383 // Write to the cache (70-79).
4384 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4385 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4386 transaction
.data
= "rg: 70-79 ";
4387 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4388 Verify206Response(headers
, 70, 79);
4390 // Request a large range (30-79). The cache will ask the server for 30-69.
4391 // The server returns 40-49. The cache should consider the server confused and
4392 // abort caching, returning the weird range to the caller.
4393 transaction
.request_headers
= "Range: bytes = 30-79\r\n" EXTRA_HEADER
;
4394 transaction
.response_headers
=
4395 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4397 "Accept-Ranges: bytes\n"
4398 "Content-Length: 10\n"
4399 "Content-Range: bytes 40-49/80\n";
4400 transaction
.handler
= nullptr;
4401 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4403 Verify206Response(headers
, 40, 49);
4404 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4405 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4406 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4408 // The entry was deleted.
4409 RunTransactionTest(cache
.http_cache(), transaction
);
4410 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4411 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4412 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4415 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4416 // the response matches the one provided by the server.
4417 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_NoCachedContent
) {
4418 MockHttpCache cache
;
4419 std::string headers
;
4421 // Request a large range (70-99). The server sends 70-79.
4422 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4423 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4424 transaction
.data
= "rg: 70-79 ";
4425 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4427 Verify206Response(headers
, 70, 79);
4428 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4429 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4430 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4432 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4433 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4436 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4437 // the cache automatically fixes the request.
4438 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_CachedContent
) {
4439 MockHttpCache cache
;
4440 std::string headers
;
4442 // Write to the cache (40-49).
4443 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4444 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4446 // Request a large range (70-99). The server sends 70-79.
4447 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4448 transaction
.data
= "rg: 70-79 ";
4449 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4451 Verify206Response(headers
, 70, 79);
4452 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4453 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4454 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4456 // The entry was not deleted (the range was automatically fixed).
4457 RunTransactionTest(cache
.http_cache(), transaction
);
4458 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4459 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4460 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4463 // Tests that when a caller asks for a not-satisfiable range, the server's
4464 // response is forwarded to the caller.
4465 TEST(HttpCache
, RangeGET_416_NoCachedContent
) {
4466 MockHttpCache cache
;
4467 std::string headers
;
4469 // Request a range beyond EOF (80-99).
4470 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4471 transaction
.request_headers
= "Range: bytes = 80-99\r\n" EXTRA_HEADER
;
4472 transaction
.data
= "";
4473 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
4474 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4476 EXPECT_EQ(0U, headers
.find(transaction
.status
));
4477 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4478 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4479 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4481 // The entry was deleted.
4482 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4483 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4486 // Tests that we cache 301s for range requests.
4487 TEST(HttpCache
, RangeGET_301
) {
4488 MockHttpCache cache
;
4489 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4490 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4491 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4492 transaction
.data
= "";
4493 transaction
.handler
= NULL
;
4495 // Write to the cache.
4496 RunTransactionTest(cache
.http_cache(), transaction
);
4497 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4498 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4499 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4501 // Read from the cache.
4502 RunTransactionTest(cache
.http_cache(), transaction
);
4503 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4504 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4505 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4508 // Tests that we can cache range requests when the start or end is unknown.
4509 // We start with one suffix request, followed by a request from a given point.
4510 TEST(HttpCache
, UnknownRangeGET_1
) {
4511 MockHttpCache cache
;
4512 AddMockTransaction(&kRangeGET_TransactionOK
);
4513 std::string headers
;
4515 // Write to the cache (70-79).
4516 MockTransaction
transaction(kRangeGET_TransactionOK
);
4517 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4518 transaction
.data
= "rg: 70-79 ";
4519 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4521 Verify206Response(headers
, 70, 79);
4522 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4523 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4524 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4526 // Make sure we are done with the previous transaction.
4527 base::MessageLoop::current()->RunUntilIdle();
4529 // Write and read from the cache (60-79).
4530 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4531 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4532 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4534 Verify206Response(headers
, 60, 79);
4535 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4536 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4537 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4539 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4542 // Tests that we can cache range requests when the start or end is unknown.
4543 // We start with one request from a given point, followed by a suffix request.
4544 // We'll also verify that synchronous cache responses work as intended.
4545 TEST(HttpCache
, UnknownRangeGET_2
) {
4546 MockHttpCache cache
;
4547 std::string headers
;
4549 MockTransaction
transaction(kRangeGET_TransactionOK
);
4550 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4551 TEST_MODE_SYNC_CACHE_READ
|
4552 TEST_MODE_SYNC_CACHE_WRITE
;
4553 AddMockTransaction(&transaction
);
4555 // Write to the cache (70-79).
4556 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4557 transaction
.data
= "rg: 70-79 ";
4558 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4560 Verify206Response(headers
, 70, 79);
4561 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4562 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4563 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4565 // Make sure we are done with the previous transaction.
4566 base::MessageLoop::current()->RunUntilIdle();
4568 // Write and read from the cache (60-79).
4569 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4570 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4571 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4573 Verify206Response(headers
, 60, 79);
4574 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4575 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4576 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4578 RemoveMockTransaction(&transaction
);
4581 // Tests that receiving Not Modified when asking for an open range doesn't mess
4583 TEST(HttpCache
, UnknownRangeGET_304
) {
4584 MockHttpCache cache
;
4585 std::string headers
;
4587 MockTransaction
transaction(kRangeGET_TransactionOK
);
4588 AddMockTransaction(&transaction
);
4590 RangeTransactionServer handler
;
4591 handler
.set_not_modified(true);
4593 // Ask for the end of the file, without knowing the length.
4594 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4595 transaction
.data
= "";
4596 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4598 // We just bypass the cache.
4599 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4600 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4601 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4602 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4604 RunTransactionTest(cache
.http_cache(), transaction
);
4605 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4607 RemoveMockTransaction(&transaction
);
4610 // Tests that we can handle non-range requests when we have cached a range.
4611 TEST(HttpCache
, GET_Previous206
) {
4612 MockHttpCache cache
;
4613 AddMockTransaction(&kRangeGET_TransactionOK
);
4614 std::string headers
;
4615 BoundTestNetLog log
;
4616 LoadTimingInfo load_timing_info
;
4618 // Write to the cache (40-49).
4619 RunTransactionTestWithResponseAndGetTiming(
4620 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4623 Verify206Response(headers
, 40, 49);
4624 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4625 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4626 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4627 TestLoadTimingNetworkRequest(load_timing_info
);
4629 // Write and read from the cache (0-79), when not asked for a range.
4630 MockTransaction
transaction(kRangeGET_TransactionOK
);
4631 transaction
.request_headers
= EXTRA_HEADER
;
4632 transaction
.data
= kFullRangeData
;
4633 RunTransactionTestWithResponseAndGetTiming(
4634 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4637 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4638 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4639 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4640 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4641 TestLoadTimingNetworkRequest(load_timing_info
);
4643 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4646 // Tests that we can handle non-range requests when we have cached the first
4647 // part of the object and the server replies with 304 (Not Modified).
4648 TEST(HttpCache
, GET_Previous206_NotModified
) {
4649 MockHttpCache cache
;
4651 MockTransaction
transaction(kRangeGET_TransactionOK
);
4652 AddMockTransaction(&transaction
);
4653 std::string headers
;
4654 BoundTestNetLog log
;
4655 LoadTimingInfo load_timing_info
;
4657 // Write to the cache (0-9).
4658 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4659 transaction
.data
= "rg: 00-09 ";
4660 RunTransactionTestWithResponseAndGetTiming(
4661 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4663 Verify206Response(headers
, 0, 9);
4664 TestLoadTimingNetworkRequest(load_timing_info
);
4666 // Write to the cache (70-79).
4667 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4668 transaction
.data
= "rg: 70-79 ";
4669 RunTransactionTestWithResponseAndGetTiming(
4670 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4672 Verify206Response(headers
, 70, 79);
4674 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4675 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4676 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4677 TestLoadTimingNetworkRequest(load_timing_info
);
4679 // Read from the cache (0-9), write and read from cache (10 - 79).
4680 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4681 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4682 transaction
.data
= kFullRangeData
;
4683 RunTransactionTestWithResponseAndGetTiming(
4684 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4687 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4688 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4689 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4690 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4691 TestLoadTimingNetworkRequest(load_timing_info
);
4693 RemoveMockTransaction(&transaction
);
4696 // Tests that we can handle a regular request to a sparse entry, that results in
4697 // new content provided by the server (206).
4698 TEST(HttpCache
, GET_Previous206_NewContent
) {
4699 MockHttpCache cache
;
4700 AddMockTransaction(&kRangeGET_TransactionOK
);
4701 std::string headers
;
4703 // Write to the cache (0-9).
4704 MockTransaction
transaction(kRangeGET_TransactionOK
);
4705 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4706 transaction
.data
= "rg: 00-09 ";
4707 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4709 Verify206Response(headers
, 0, 9);
4710 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4711 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4712 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4714 // Now we'll issue a request without any range that should result first in a
4715 // 206 (when revalidating), and then in a weird standard answer: the test
4716 // server will not modify the response so we'll get the default range... a
4717 // real server will answer with 200.
4718 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4719 transaction2
.request_headers
= EXTRA_HEADER
;
4720 transaction2
.load_flags
|= LOAD_VALIDATE_CACHE
;
4721 transaction2
.data
= "Not a range";
4722 RangeTransactionServer handler
;
4723 handler
.set_modified(true);
4724 BoundTestNetLog log
;
4725 LoadTimingInfo load_timing_info
;
4726 RunTransactionTestWithResponseAndGetTiming(
4727 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4730 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4731 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4732 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4733 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4734 TestLoadTimingNetworkRequest(load_timing_info
);
4736 // Verify that the previous request deleted the entry.
4737 RunTransactionTest(cache
.http_cache(), transaction
);
4738 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4740 RemoveMockTransaction(&transaction
);
4743 // Tests that we can handle cached 206 responses that are not sparse.
4744 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4745 MockHttpCache cache
;
4747 // Create a disk cache entry that stores 206 headers while not being sparse.
4748 disk_cache::Entry
* entry
;
4749 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4752 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4753 raw_headers
.append("\n");
4754 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4756 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4758 HttpResponseInfo response
;
4759 response
.headers
= new HttpResponseHeaders(raw_headers
);
4760 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4762 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4763 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4764 kRangeGET_TransactionOK
.data
, 500));
4765 TestCompletionCallback cb
;
4766 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4767 EXPECT_EQ(len
, cb
.GetResult(rv
));
4770 // Now see that we don't use the stored entry.
4771 std::string headers
;
4772 BoundTestNetLog log
;
4773 LoadTimingInfo load_timing_info
;
4774 RunTransactionTestWithResponseAndGetTiming(
4775 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4778 // We are expecting a 200.
4779 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4780 expected_headers
.append("\n");
4781 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4782 EXPECT_EQ(expected_headers
, headers
);
4783 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4784 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4785 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4786 TestLoadTimingNetworkRequest(load_timing_info
);
4789 // Tests that we can handle cached 206 responses that are not sparse. This time
4790 // we issue a range request and expect to receive a range.
4791 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4792 MockHttpCache cache
;
4793 AddMockTransaction(&kRangeGET_TransactionOK
);
4795 // Create a disk cache entry that stores 206 headers while not being sparse.
4796 disk_cache::Entry
* entry
;
4797 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4800 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4801 raw_headers
.append("\n");
4802 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4804 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4806 HttpResponseInfo response
;
4807 response
.headers
= new HttpResponseHeaders(raw_headers
);
4808 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4810 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4811 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4812 kRangeGET_TransactionOK
.data
, 500));
4813 TestCompletionCallback cb
;
4814 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4815 EXPECT_EQ(len
, cb
.GetResult(rv
));
4818 // Now see that we don't use the stored entry.
4819 std::string headers
;
4820 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4823 // We are expecting a 206.
4824 Verify206Response(headers
, 40, 49);
4825 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4826 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4827 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4829 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4832 // Tests that we can handle cached 206 responses that can't be validated.
4833 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4834 MockHttpCache cache
;
4836 // Create a disk cache entry that stores 206 headers.
4837 disk_cache::Entry
* entry
;
4838 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4841 // Make sure that the headers cannot be validated with the server.
4842 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4843 raw_headers
.append("\n");
4844 raw_headers
.append("Content-Length: 80\n");
4846 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4848 HttpResponseInfo response
;
4849 response
.headers
= new HttpResponseHeaders(raw_headers
);
4850 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4852 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4853 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4854 kRangeGET_TransactionOK
.data
, 500));
4855 TestCompletionCallback cb
;
4856 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4857 EXPECT_EQ(len
, cb
.GetResult(rv
));
4860 // Now see that we don't use the stored entry.
4861 std::string headers
;
4862 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4865 // We are expecting a 200.
4866 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4867 expected_headers
.append("\n");
4868 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4869 EXPECT_EQ(expected_headers
, headers
);
4870 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4871 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4872 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4875 // Tests that we can handle range requests with cached 200 responses.
4876 TEST(HttpCache
, RangeGET_Previous200
) {
4877 MockHttpCache cache
;
4879 // Store the whole thing with status 200.
4880 MockTransaction
transaction(kTypicalGET_Transaction
);
4881 transaction
.url
= kRangeGET_TransactionOK
.url
;
4882 transaction
.data
= kFullRangeData
;
4883 AddMockTransaction(&transaction
);
4884 RunTransactionTest(cache
.http_cache(), transaction
);
4885 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4886 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4887 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4889 RemoveMockTransaction(&transaction
);
4890 AddMockTransaction(&kRangeGET_TransactionOK
);
4892 // Now see that we use the stored entry.
4893 std::string headers
;
4894 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4895 RangeTransactionServer handler
;
4896 handler
.set_not_modified(true);
4897 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4899 // We are expecting a 206.
4900 Verify206Response(headers
, 40, 49);
4901 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4902 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4903 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4905 // The last transaction has finished so make sure the entry is deactivated.
4906 base::MessageLoop::current()->RunUntilIdle();
4908 // Make a request for an invalid range.
4909 MockTransaction
transaction3(kRangeGET_TransactionOK
);
4910 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
4911 transaction3
.data
= transaction
.data
;
4912 transaction3
.load_flags
= LOAD_PREFERRING_CACHE
;
4913 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
4914 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4915 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
4916 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
4917 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
4919 // Make sure the entry is deactivated.
4920 base::MessageLoop::current()->RunUntilIdle();
4922 // Even though the request was invalid, we should have the entry.
4923 RunTransactionTest(cache
.http_cache(), transaction2
);
4924 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4926 // Make sure the entry is deactivated.
4927 base::MessageLoop::current()->RunUntilIdle();
4929 // Now we should receive a range from the server and drop the stored entry.
4930 handler
.set_not_modified(false);
4931 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4932 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4933 Verify206Response(headers
, 40, 49);
4934 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4935 EXPECT_EQ(4, cache
.disk_cache()->open_count());
4936 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4938 RunTransactionTest(cache
.http_cache(), transaction2
);
4939 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4941 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4944 // Tests that we can handle a 200 response when dealing with sparse entries.
4945 TEST(HttpCache
, RangeRequestResultsIn200
) {
4946 MockHttpCache cache
;
4947 AddMockTransaction(&kRangeGET_TransactionOK
);
4948 std::string headers
;
4950 // Write to the cache (70-79).
4951 MockTransaction
transaction(kRangeGET_TransactionOK
);
4952 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4953 transaction
.data
= "rg: 70-79 ";
4954 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4956 Verify206Response(headers
, 70, 79);
4957 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4958 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4959 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4961 // Now we'll issue a request that results in a plain 200 response, but to
4962 // the to the same URL that we used to store sparse data, and making sure
4963 // that we ask for a range.
4964 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4965 MockTransaction
transaction2(kSimpleGET_Transaction
);
4966 transaction2
.url
= kRangeGET_TransactionOK
.url
;
4967 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4968 AddMockTransaction(&transaction2
);
4970 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4972 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4973 expected_headers
.append("\n");
4974 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4975 EXPECT_EQ(expected_headers
, headers
);
4976 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4977 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4978 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4980 RemoveMockTransaction(&transaction2
);
4983 // Tests that a range request that falls outside of the size that we know about
4984 // only deletes the entry if the resource has indeed changed.
4985 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
4986 MockHttpCache cache
;
4987 AddMockTransaction(&kRangeGET_TransactionOK
);
4988 std::string headers
;
4990 // Write to the cache (40-49).
4991 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4994 Verify206Response(headers
, 40, 49);
4995 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4996 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4997 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4999 // A weird request should not delete this entry. Ask for bytes 120-.
5000 MockTransaction
transaction(kRangeGET_TransactionOK
);
5001 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
5002 transaction
.data
= "";
5003 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5005 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
5006 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5007 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5008 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5010 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5011 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5012 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5014 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5017 // Tests that we don't delete a sparse entry when we cancel a request.
5018 TEST(HttpCache
, RangeGET_Cancel
) {
5019 MockHttpCache cache
;
5020 AddMockTransaction(&kRangeGET_TransactionOK
);
5022 MockHttpRequest
request(kRangeGET_TransactionOK
);
5024 Context
* c
= new Context();
5025 int rv
= cache
.CreateTransaction(&c
->trans
);
5028 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5029 if (rv
== ERR_IO_PENDING
)
5030 rv
= c
->callback
.WaitForResult();
5032 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5033 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5034 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5036 // Make sure that the entry has some data stored.
5037 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5038 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5039 if (rv
== ERR_IO_PENDING
)
5040 rv
= c
->callback
.WaitForResult();
5041 EXPECT_EQ(buf
->size(), rv
);
5043 // Destroy the transaction.
5046 // Verify that the entry has not been deleted.
5047 disk_cache::Entry
* entry
;
5048 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5050 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5053 // Tests that we don't delete a sparse entry when we start a new request after
5054 // cancelling the previous one.
5055 TEST(HttpCache
, RangeGET_Cancel2
) {
5056 MockHttpCache cache
;
5057 AddMockTransaction(&kRangeGET_TransactionOK
);
5059 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5060 MockHttpRequest
request(kRangeGET_TransactionOK
);
5061 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5063 Context
* c
= new Context();
5064 int rv
= cache
.CreateTransaction(&c
->trans
);
5067 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5068 if (rv
== ERR_IO_PENDING
)
5069 rv
= c
->callback
.WaitForResult();
5071 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5072 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5073 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5075 // Make sure that we revalidate the entry and read from the cache (a single
5076 // read will return while waiting for the network).
5077 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5078 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5079 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5080 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5081 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5083 // Destroy the transaction before completing the read.
5086 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5087 // message loop. This means that a new transaction will just reuse the same
5088 // active entry (no open or create).
5090 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5092 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5093 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5094 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5095 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5098 // A slight variation of the previous test, this time we cancel two requests in
5099 // a row, making sure that the second is waiting for the entry to be ready.
5100 TEST(HttpCache
, RangeGET_Cancel3
) {
5101 MockHttpCache cache
;
5102 AddMockTransaction(&kRangeGET_TransactionOK
);
5104 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5105 MockHttpRequest
request(kRangeGET_TransactionOK
);
5106 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5108 Context
* c
= new Context();
5109 int rv
= cache
.CreateTransaction(&c
->trans
);
5112 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5113 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5114 rv
= c
->callback
.WaitForResult();
5116 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5117 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5118 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5120 // Make sure that we revalidate the entry and read from the cache (a single
5121 // read will return while waiting for the network).
5122 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5123 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5124 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5125 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5126 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5128 // Destroy the transaction before completing the read.
5131 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5132 // message loop. This means that a new transaction will just reuse the same
5133 // active entry (no open or create).
5136 rv
= cache
.CreateTransaction(&c
->trans
);
5139 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5140 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5142 MockDiskEntry::IgnoreCallbacks(true);
5143 base::MessageLoop::current()->RunUntilIdle();
5144 MockDiskEntry::IgnoreCallbacks(false);
5146 // The new transaction is waiting for the query range callback.
5149 // And we should not crash when the callback is delivered.
5150 base::MessageLoop::current()->RunUntilIdle();
5152 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5153 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5154 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5155 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5158 // Tests that an invalid range response results in no cached entry.
5159 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
5160 MockHttpCache cache
;
5161 std::string headers
;
5163 MockTransaction
transaction(kRangeGET_TransactionOK
);
5164 transaction
.handler
= NULL
;
5165 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
5166 "Content-Length: 10\n";
5167 AddMockTransaction(&transaction
);
5168 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5170 std::string
expected(transaction
.status
);
5171 expected
.append("\n");
5172 expected
.append(transaction
.response_headers
);
5173 EXPECT_EQ(expected
, headers
);
5175 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5176 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5177 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5179 // Verify that we don't have a cached entry.
5180 disk_cache::Entry
* entry
;
5181 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5183 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5186 // Tests that we reject a range that doesn't match the content-length.
5187 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
5188 MockHttpCache cache
;
5189 std::string headers
;
5191 MockTransaction
transaction(kRangeGET_TransactionOK
);
5192 transaction
.handler
= NULL
;
5193 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
5194 "Content-Length: 20\n";
5195 AddMockTransaction(&transaction
);
5196 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5198 std::string
expected(transaction
.status
);
5199 expected
.append("\n");
5200 expected
.append(transaction
.response_headers
);
5201 EXPECT_EQ(expected
, headers
);
5203 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5204 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5205 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5207 // Verify that we don't have a cached entry.
5208 disk_cache::Entry
* entry
;
5209 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5211 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5214 // Tests that if a server tells us conflicting information about a resource we
5216 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
5217 MockHttpCache cache
;
5218 std::string headers
;
5220 MockTransaction
transaction(kRangeGET_TransactionOK
);
5221 transaction
.handler
= NULL
;
5222 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
5223 std::string
response_headers(transaction
.response_headers
);
5224 response_headers
.append("Content-Range: bytes 50-59/160\n");
5225 transaction
.response_headers
= response_headers
.c_str();
5226 AddMockTransaction(&transaction
);
5227 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5229 Verify206Response(headers
, 50, 59);
5230 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5231 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5232 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5234 RemoveMockTransaction(&transaction
);
5235 AddMockTransaction(&kRangeGET_TransactionOK
);
5237 // This transaction will report a resource size of 80 bytes, and we think it's
5238 // 160 so we should ignore the response.
5239 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5242 Verify206Response(headers
, 40, 49);
5243 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5244 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5247 // Verify that the entry is gone.
5248 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5249 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5250 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5251 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5254 // Tests that we handle large range values properly.
5255 TEST(HttpCache
, RangeGET_LargeValues
) {
5256 // We need a real sparse cache for this test.
5257 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5258 std::string headers
;
5260 MockTransaction
transaction(kRangeGET_TransactionOK
);
5261 transaction
.handler
= NULL
;
5262 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
5264 transaction
.response_headers
=
5266 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5267 "Content-Length: 10\n";
5268 AddMockTransaction(&transaction
);
5269 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5271 std::string
expected(transaction
.status
);
5272 expected
.append("\n");
5273 expected
.append(transaction
.response_headers
);
5274 EXPECT_EQ(expected
, headers
);
5276 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5278 // Verify that we have a cached entry.
5279 disk_cache::Entry
* en
;
5280 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
5283 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5286 // Tests that we don't crash with a range request if the disk cache was not
5287 // initialized properly.
5288 TEST(HttpCache
, RangeGET_NoDiskCache
) {
5289 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
5290 factory
->set_fail(true);
5291 factory
->FinishCreation(); // We'll complete synchronously.
5292 MockHttpCache
cache(factory
);
5294 AddMockTransaction(&kRangeGET_TransactionOK
);
5296 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5297 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5299 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5302 // Tests that we handle byte range requests that skip the cache.
5303 TEST(HttpCache
, RangeHEAD
) {
5304 MockHttpCache cache
;
5305 AddMockTransaction(&kRangeGET_TransactionOK
);
5307 MockTransaction
transaction(kRangeGET_TransactionOK
);
5308 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5309 transaction
.method
= "HEAD";
5310 transaction
.data
= "rg: 70-79 ";
5312 std::string headers
;
5313 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5315 Verify206Response(headers
, 70, 79);
5316 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5317 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5318 EXPECT_EQ(0, cache
.disk_cache()->create_count());
5320 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5323 // Tests that we don't crash when after reading from the cache we issue a
5324 // request for the next range and the server gives us a 200 synchronously.
5325 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
5326 MockHttpCache cache
;
5328 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5329 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
5330 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
5331 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
5333 // Write to the cache.
5334 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5336 // And now read from the cache and the network.
5337 RangeTransactionServer handler
;
5338 handler
.set_bad_200(true);
5339 transaction
.data
= "Not a range";
5340 BoundTestNetLog log
;
5341 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
5343 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
5344 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5345 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5346 EXPECT_TRUE(LogContainsEventType(
5347 log
, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST
));
5350 // Tests that when the server gives us less data than expected, we don't keep
5351 // asking for more data.
5352 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
5353 MockHttpCache cache
;
5355 // First, check with an empty cache (WRITE mode).
5356 MockTransaction
transaction(kRangeGET_TransactionOK
);
5357 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
5358 transaction
.data
= "rg: 40-"; // Less than expected.
5359 transaction
.handler
= NULL
;
5360 std::string
headers(transaction
.response_headers
);
5361 headers
.append("Content-Range: bytes 40-49/80\n");
5362 transaction
.response_headers
= headers
.c_str();
5364 AddMockTransaction(&transaction
);
5366 // Write to the cache.
5367 RunTransactionTest(cache
.http_cache(), transaction
);
5369 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5370 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5371 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5373 // Now verify that even in READ_WRITE mode, we forward the bad response to
5375 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5376 transaction
.data
= "rg: 60-"; // Less than expected.
5377 headers
= kRangeGET_TransactionOK
.response_headers
;
5378 headers
.append("Content-Range: bytes 60-69/80\n");
5379 transaction
.response_headers
= headers
.c_str();
5381 RunTransactionTest(cache
.http_cache(), transaction
);
5383 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5384 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5385 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5387 RemoveMockTransaction(&transaction
);
5390 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5391 // This test hits a NOTREACHED so it is a release mode only test.
5392 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5393 MockHttpCache cache
;
5394 AddMockTransaction(&kRangeGET_TransactionOK
);
5396 // Write to the cache (40-49).
5397 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5398 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5399 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5400 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5402 // Force this transaction to read from the cache.
5403 MockTransaction
transaction(kRangeGET_TransactionOK
);
5404 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
5406 MockHttpRequest
request(transaction
);
5407 TestCompletionCallback callback
;
5409 scoped_ptr
<HttpTransaction
> trans
;
5410 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
5412 ASSERT_TRUE(trans
.get());
5414 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
5415 if (rv
== ERR_IO_PENDING
)
5416 rv
= callback
.WaitForResult();
5417 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
5421 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5422 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5423 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5425 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5429 // Tests the handling of the "truncation" flag.
5430 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5431 MockHttpCache cache
;
5432 disk_cache::Entry
* entry
;
5433 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5436 std::string
headers("HTTP/1.1 200 OK");
5437 headers
= HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5438 HttpResponseInfo response
;
5439 response
.headers
= new HttpResponseHeaders(headers
);
5441 // Set the last argument for this to be an incomplete request.
5442 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5443 bool truncated
= false;
5444 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5445 EXPECT_TRUE(truncated
);
5447 // And now test the opposite case.
5448 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5450 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5451 EXPECT_FALSE(truncated
);
5455 // Tests basic pickling/unpickling of HttpResponseInfo.
5456 TEST(HttpCache
, PersistHttpResponseInfo
) {
5457 // Set some fields (add more if needed.)
5458 HttpResponseInfo response1
;
5459 response1
.was_cached
= false;
5460 response1
.socket_address
= HostPortPair("1.2.3.4", 80);
5461 response1
.headers
= new HttpResponseHeaders("HTTP/1.1 200 OK");
5465 response1
.Persist(&pickle
, false, false);
5468 HttpResponseInfo response2
;
5469 bool response_truncated
;
5470 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5471 EXPECT_FALSE(response_truncated
);
5474 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5475 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5476 EXPECT_EQ(80, response2
.socket_address
.port());
5477 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5480 // Tests that we delete an entry when the request is cancelled before starting
5481 // to read from the network.
5482 TEST(HttpCache
, DoomOnDestruction
) {
5483 MockHttpCache cache
;
5485 MockHttpRequest
request(kSimpleGET_Transaction
);
5487 Context
* c
= new Context();
5488 int rv
= cache
.CreateTransaction(&c
->trans
);
5491 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5492 if (rv
== ERR_IO_PENDING
)
5493 c
->result
= c
->callback
.WaitForResult();
5495 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5496 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5497 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5499 // Destroy the transaction. We only have the headers so we should delete this
5503 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5505 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5506 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5507 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5510 // Tests that we delete an entry when the request is cancelled if the response
5511 // does not have content-length and strong validators.
5512 TEST(HttpCache
, DoomOnDestruction2
) {
5513 MockHttpCache cache
;
5515 MockHttpRequest
request(kSimpleGET_Transaction
);
5517 Context
* c
= new Context();
5518 int rv
= cache
.CreateTransaction(&c
->trans
);
5521 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5522 if (rv
== ERR_IO_PENDING
)
5523 rv
= c
->callback
.WaitForResult();
5525 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5526 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5527 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5529 // Make sure that the entry has some data stored.
5530 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5531 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5532 if (rv
== ERR_IO_PENDING
)
5533 rv
= c
->callback
.WaitForResult();
5534 EXPECT_EQ(buf
->size(), rv
);
5536 // Destroy the transaction.
5539 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5541 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5542 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5543 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5546 // Tests that we delete an entry when the request is cancelled if the response
5547 // has an "Accept-Ranges: none" header.
5548 TEST(HttpCache
, DoomOnDestruction3
) {
5549 MockHttpCache cache
;
5551 MockTransaction
transaction(kSimpleGET_Transaction
);
5552 transaction
.response_headers
=
5553 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5554 "Content-Length: 22\n"
5555 "Accept-Ranges: none\n"
5556 "Etag: \"foopy\"\n";
5557 AddMockTransaction(&transaction
);
5558 MockHttpRequest
request(transaction
);
5560 Context
* c
= new Context();
5561 int rv
= cache
.CreateTransaction(&c
->trans
);
5564 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5565 if (rv
== ERR_IO_PENDING
)
5566 rv
= c
->callback
.WaitForResult();
5568 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5569 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5570 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5572 // Make sure that the entry has some data stored.
5573 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5574 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5575 if (rv
== ERR_IO_PENDING
)
5576 rv
= c
->callback
.WaitForResult();
5577 EXPECT_EQ(buf
->size(), rv
);
5579 // Destroy the transaction.
5582 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5584 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5585 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5586 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5588 RemoveMockTransaction(&transaction
);
5591 // Tests that we mark an entry as incomplete when the request is cancelled.
5592 TEST(HttpCache
, SetTruncatedFlag
) {
5593 MockHttpCache cache
;
5595 MockTransaction
transaction(kSimpleGET_Transaction
);
5596 transaction
.response_headers
=
5597 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5598 "Content-Length: 22\n"
5599 "Etag: \"foopy\"\n";
5600 AddMockTransaction(&transaction
);
5601 MockHttpRequest
request(transaction
);
5603 scoped_ptr
<Context
> c(new Context());
5605 int rv
= cache
.CreateTransaction(&c
->trans
);
5608 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5609 if (rv
== ERR_IO_PENDING
)
5610 rv
= c
->callback
.WaitForResult();
5612 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5613 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5614 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5616 // Make sure that the entry has some data stored.
5617 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5618 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5619 if (rv
== ERR_IO_PENDING
)
5620 rv
= c
->callback
.WaitForResult();
5621 EXPECT_EQ(buf
->size(), rv
);
5623 // We want to cancel the request when the transaction is busy.
5624 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5625 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5626 EXPECT_FALSE(c
->callback
.have_result());
5628 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5630 // Destroy the transaction.
5632 MockHttpCache::SetTestMode(0);
5635 // Make sure that we don't invoke the callback. We may have an issue if the
5636 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5637 // could end up with the transaction being deleted twice if we send any
5638 // notification from the transaction destructor (see http://crbug.com/31723).
5639 EXPECT_FALSE(c
->callback
.have_result());
5641 // Verify that the entry is marked as incomplete.
5642 disk_cache::Entry
* entry
;
5643 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5644 HttpResponseInfo response
;
5645 bool truncated
= false;
5646 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5647 EXPECT_TRUE(truncated
);
5650 RemoveMockTransaction(&transaction
);
5653 // Tests that we don't mark an entry as truncated when we read everything.
5654 TEST(HttpCache
, DontSetTruncatedFlag
) {
5655 MockHttpCache cache
;
5657 MockTransaction
transaction(kSimpleGET_Transaction
);
5658 transaction
.response_headers
=
5659 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5660 "Content-Length: 22\n"
5661 "Etag: \"foopy\"\n";
5662 AddMockTransaction(&transaction
);
5663 MockHttpRequest
request(transaction
);
5665 scoped_ptr
<Context
> c(new Context());
5666 int rv
= cache
.CreateTransaction(&c
->trans
);
5669 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5670 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5673 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(22));
5674 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5675 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5677 // Destroy the transaction.
5680 // Verify that the entry is not marked as truncated.
5681 disk_cache::Entry
* entry
;
5682 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5683 HttpResponseInfo response
;
5684 bool truncated
= true;
5685 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5686 EXPECT_FALSE(truncated
);
5689 RemoveMockTransaction(&transaction
);
5692 // Tests that we can continue with a request that was interrupted.
5693 TEST(HttpCache
, GET_IncompleteResource
) {
5694 MockHttpCache cache
;
5695 AddMockTransaction(&kRangeGET_TransactionOK
);
5697 std::string
raw_headers("HTTP/1.1 200 OK\n"
5698 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5700 "Accept-Ranges: bytes\n"
5701 "Content-Length: 80\n");
5702 CreateTruncatedEntry(raw_headers
, &cache
);
5704 // Now make a regular request.
5705 std::string headers
;
5706 MockTransaction
transaction(kRangeGET_TransactionOK
);
5707 transaction
.request_headers
= EXTRA_HEADER
;
5708 transaction
.data
= kFullRangeData
;
5709 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5711 // We update the headers with the ones received while revalidating.
5712 std::string
expected_headers(
5714 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5715 "Accept-Ranges: bytes\n"
5717 "Content-Length: 80\n");
5719 EXPECT_EQ(expected_headers
, headers
);
5720 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5721 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5722 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5724 // Verify that the disk entry was updated.
5725 disk_cache::Entry
* entry
;
5726 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5727 EXPECT_EQ(80, entry
->GetDataSize(1));
5728 bool truncated
= true;
5729 HttpResponseInfo response
;
5730 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5731 EXPECT_FALSE(truncated
);
5734 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5737 // Tests the handling of no-store when revalidating a truncated entry.
5738 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5739 MockHttpCache cache
;
5740 AddMockTransaction(&kRangeGET_TransactionOK
);
5742 std::string
raw_headers("HTTP/1.1 200 OK\n"
5743 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5745 "Accept-Ranges: bytes\n"
5746 "Content-Length: 80\n");
5747 CreateTruncatedEntry(raw_headers
, &cache
);
5748 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5750 // Now make a regular request.
5751 MockTransaction
transaction(kRangeGET_TransactionOK
);
5752 transaction
.request_headers
= EXTRA_HEADER
;
5753 std::string
response_headers(transaction
.response_headers
);
5754 response_headers
+= ("Cache-Control: no-store\n");
5755 transaction
.response_headers
= response_headers
.c_str();
5756 transaction
.data
= kFullRangeData
;
5757 AddMockTransaction(&transaction
);
5759 std::string headers
;
5760 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5762 // We update the headers with the ones received while revalidating.
5763 std::string
expected_headers(
5765 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5766 "Accept-Ranges: bytes\n"
5767 "Cache-Control: no-store\n"
5769 "Content-Length: 80\n");
5771 EXPECT_EQ(expected_headers
, headers
);
5772 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5773 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5774 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5776 // Verify that the disk entry was deleted.
5777 disk_cache::Entry
* entry
;
5778 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5779 RemoveMockTransaction(&transaction
);
5782 // Tests cancelling a request after the server sent no-store.
5783 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5784 MockHttpCache cache
;
5785 AddMockTransaction(&kRangeGET_TransactionOK
);
5787 std::string
raw_headers("HTTP/1.1 200 OK\n"
5788 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5790 "Accept-Ranges: bytes\n"
5791 "Content-Length: 80\n");
5792 CreateTruncatedEntry(raw_headers
, &cache
);
5793 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5795 // Now make a regular request.
5796 MockTransaction
transaction(kRangeGET_TransactionOK
);
5797 transaction
.request_headers
= EXTRA_HEADER
;
5798 std::string
response_headers(transaction
.response_headers
);
5799 response_headers
+= ("Cache-Control: no-store\n");
5800 transaction
.response_headers
= response_headers
.c_str();
5801 transaction
.data
= kFullRangeData
;
5802 AddMockTransaction(&transaction
);
5804 MockHttpRequest
request(transaction
);
5805 Context
* c
= new Context();
5807 int rv
= cache
.CreateTransaction(&c
->trans
);
5810 // Queue another request to this transaction. We have to start this request
5811 // before the first one gets the response from the server and dooms the entry,
5812 // otherwise it will just create a new entry without being queued to the first
5814 Context
* pending
= new Context();
5815 ASSERT_EQ(OK
, cache
.CreateTransaction(&pending
->trans
));
5817 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5818 EXPECT_EQ(ERR_IO_PENDING
,
5819 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5821 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5823 // Make sure that the entry has some data stored.
5824 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5825 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5826 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5828 // Cancel the requests.
5832 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5833 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5834 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5836 base::MessageLoop::current()->RunUntilIdle();
5837 RemoveMockTransaction(&transaction
);
5840 // Tests that we delete truncated entries if the server changes its mind midway.
5841 TEST(HttpCache
, GET_IncompleteResource2
) {
5842 MockHttpCache cache
;
5843 AddMockTransaction(&kRangeGET_TransactionOK
);
5845 // Content-length will be intentionally bad.
5846 std::string
raw_headers("HTTP/1.1 200 OK\n"
5847 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5849 "Accept-Ranges: bytes\n"
5850 "Content-Length: 50\n");
5851 CreateTruncatedEntry(raw_headers
, &cache
);
5853 // Now make a regular request. We expect the code to fail the validation and
5854 // retry the request without using byte ranges.
5855 std::string headers
;
5856 MockTransaction
transaction(kRangeGET_TransactionOK
);
5857 transaction
.request_headers
= EXTRA_HEADER
;
5858 transaction
.data
= "Not a range";
5859 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5861 // The server will return 200 instead of a byte range.
5862 std::string
expected_headers(
5864 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5866 EXPECT_EQ(expected_headers
, headers
);
5867 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5868 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5869 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5871 // Verify that the disk entry was deleted.
5872 disk_cache::Entry
* entry
;
5873 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5874 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5877 // Tests that we always validate a truncated request.
5878 TEST(HttpCache
, GET_IncompleteResource3
) {
5879 MockHttpCache cache
;
5880 AddMockTransaction(&kRangeGET_TransactionOK
);
5882 // This should not require validation for 10 hours.
5883 std::string
raw_headers("HTTP/1.1 200 OK\n"
5884 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5886 "Cache-Control: max-age= 36000\n"
5887 "Accept-Ranges: bytes\n"
5888 "Content-Length: 80\n");
5889 CreateTruncatedEntry(raw_headers
, &cache
);
5891 // Now make a regular request.
5892 std::string headers
;
5893 MockTransaction
transaction(kRangeGET_TransactionOK
);
5894 transaction
.request_headers
= EXTRA_HEADER
;
5895 transaction
.data
= kFullRangeData
;
5897 scoped_ptr
<Context
> c(new Context
);
5898 int rv
= cache
.CreateTransaction(&c
->trans
);
5901 MockHttpRequest
request(transaction
);
5902 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5903 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5905 // We should have checked with the server before finishing Start().
5906 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5907 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5908 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5910 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5913 // Tests that we handle 401s for truncated resources.
5914 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
5915 MockHttpCache cache
;
5916 AddMockTransaction(&kRangeGET_TransactionOK
);
5918 std::string
raw_headers("HTTP/1.1 200 OK\n"
5919 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5921 "Accept-Ranges: bytes\n"
5922 "Content-Length: 80\n");
5923 CreateTruncatedEntry(raw_headers
, &cache
);
5925 // Now make a regular request.
5926 MockTransaction
transaction(kRangeGET_TransactionOK
);
5927 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
5929 transaction
.data
= kFullRangeData
;
5930 RangeTransactionServer handler
;
5932 scoped_ptr
<Context
> c(new Context
);
5933 int rv
= cache
.CreateTransaction(&c
->trans
);
5936 MockHttpRequest
request(transaction
);
5937 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5938 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5940 const HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
5941 ASSERT_TRUE(response
);
5942 ASSERT_EQ(401, response
->headers
->response_code());
5943 rv
= c
->trans
->RestartWithAuth(AuthCredentials(), c
->callback
.callback());
5944 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5945 response
= c
->trans
->GetResponseInfo();
5946 ASSERT_TRUE(response
);
5947 ASSERT_EQ(200, response
->headers
->response_code());
5949 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
5950 c
.reset(); // The destructor could delete the entry.
5951 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5953 // Verify that the entry was not deleted.
5954 disk_cache::Entry
* entry
;
5955 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5958 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5961 // Tests that we cache a 200 response to the validation request.
5962 TEST(HttpCache
, GET_IncompleteResource4
) {
5963 MockHttpCache cache
;
5964 AddMockTransaction(&kRangeGET_TransactionOK
);
5966 std::string
raw_headers("HTTP/1.1 200 OK\n"
5967 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5969 "Accept-Ranges: bytes\n"
5970 "Content-Length: 80\n");
5971 CreateTruncatedEntry(raw_headers
, &cache
);
5973 // Now make a regular request.
5974 std::string headers
;
5975 MockTransaction
transaction(kRangeGET_TransactionOK
);
5976 transaction
.request_headers
= EXTRA_HEADER
;
5977 transaction
.data
= "Not a range";
5978 RangeTransactionServer handler
;
5979 handler
.set_bad_200(true);
5980 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5982 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5983 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5984 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5986 // Verify that the disk entry was updated.
5987 disk_cache::Entry
* entry
;
5988 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5989 EXPECT_EQ(11, entry
->GetDataSize(1));
5990 bool truncated
= true;
5991 HttpResponseInfo response
;
5992 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5993 EXPECT_FALSE(truncated
);
5996 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5999 // Tests that when we cancel a request that was interrupted, we mark it again
6001 TEST(HttpCache
, GET_CancelIncompleteResource
) {
6002 MockHttpCache cache
;
6003 AddMockTransaction(&kRangeGET_TransactionOK
);
6005 std::string
raw_headers("HTTP/1.1 200 OK\n"
6006 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6008 "Accept-Ranges: bytes\n"
6009 "Content-Length: 80\n");
6010 CreateTruncatedEntry(raw_headers
, &cache
);
6012 // Now make a regular request.
6013 MockTransaction
transaction(kRangeGET_TransactionOK
);
6014 transaction
.request_headers
= EXTRA_HEADER
;
6016 MockHttpRequest
request(transaction
);
6017 Context
* c
= new Context();
6018 int rv
= cache
.CreateTransaction(&c
->trans
);
6021 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6022 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6024 // Read 20 bytes from the cache, and 10 from the net.
6025 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
6026 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
6027 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
6028 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
6029 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
6031 // At this point, we are already reading so canceling the request should leave
6035 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6036 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6037 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6039 // Verify that the disk entry was updated: now we have 30 bytes.
6040 disk_cache::Entry
* entry
;
6041 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6042 EXPECT_EQ(30, entry
->GetDataSize(1));
6043 bool truncated
= false;
6044 HttpResponseInfo response
;
6045 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6046 EXPECT_TRUE(truncated
);
6048 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6051 // Tests that we can handle range requests when we have a truncated entry.
6052 TEST(HttpCache
, RangeGET_IncompleteResource
) {
6053 MockHttpCache cache
;
6054 AddMockTransaction(&kRangeGET_TransactionOK
);
6056 // Content-length will be intentionally bogus.
6057 std::string
raw_headers("HTTP/1.1 200 OK\n"
6058 "Last-Modified: something\n"
6060 "Accept-Ranges: bytes\n"
6061 "Content-Length: 10\n");
6062 CreateTruncatedEntry(raw_headers
, &cache
);
6064 // Now make a range request.
6065 std::string headers
;
6066 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
6069 Verify206Response(headers
, 40, 49);
6070 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6071 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6072 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6074 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6077 TEST(HttpCache
, SyncRead
) {
6078 MockHttpCache cache
;
6080 // This test ensures that a read that completes synchronously does not cause
6083 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6084 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
6085 TEST_MODE_SYNC_CACHE_READ
|
6086 TEST_MODE_SYNC_CACHE_WRITE
);
6088 MockHttpRequest
r1(transaction
),
6092 TestTransactionConsumer
c1(DEFAULT_PRIORITY
, cache
.http_cache()),
6093 c2(DEFAULT_PRIORITY
, cache
.http_cache()),
6094 c3(DEFAULT_PRIORITY
, cache
.http_cache());
6096 c1
.Start(&r1
, BoundNetLog());
6098 r2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6099 c2
.Start(&r2
, BoundNetLog());
6101 r3
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6102 c3
.Start(&r3
, BoundNetLog());
6104 base::MessageLoop::current()->Run();
6106 EXPECT_TRUE(c1
.is_done());
6107 EXPECT_TRUE(c2
.is_done());
6108 EXPECT_TRUE(c3
.is_done());
6110 EXPECT_EQ(OK
, c1
.error());
6111 EXPECT_EQ(OK
, c2
.error());
6112 EXPECT_EQ(OK
, c3
.error());
6115 TEST(HttpCache
, ValidationResultsIn200
) {
6116 MockHttpCache cache
;
6118 // This test ensures that a conditional request, which results in a 200
6119 // instead of a 304, properly truncates the existing response data.
6121 // write to the cache
6122 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6124 // force this transaction to validate the cache
6125 MockTransaction
transaction(kETagGET_Transaction
);
6126 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
6127 RunTransactionTest(cache
.http_cache(), transaction
);
6129 // read from the cache
6130 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6133 TEST(HttpCache
, CachedRedirect
) {
6134 MockHttpCache cache
;
6136 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
6137 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
6138 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
6140 MockHttpRequest
request(kTestTransaction
);
6141 TestCompletionCallback callback
;
6143 // Write to the cache.
6145 scoped_ptr
<HttpTransaction
> trans
;
6146 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6148 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6149 if (rv
== ERR_IO_PENDING
)
6150 rv
= callback
.WaitForResult();
6153 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6156 EXPECT_EQ(info
->headers
->response_code(), 301);
6158 std::string location
;
6159 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6160 EXPECT_EQ(location
, "http://www.bar.com/");
6162 // Mark the transaction as completed so it is cached.
6163 trans
->DoneReading();
6165 // Destroy transaction when going out of scope. We have not actually
6166 // read the response body -- want to test that it is still getting cached.
6168 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6169 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6170 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6172 // Active entries in the cache are not retired synchronously. Make
6173 // sure the next run hits the MockHttpCache and open_count is
6175 base::MessageLoop::current()->RunUntilIdle();
6177 // Read from the cache.
6179 scoped_ptr
<HttpTransaction
> trans
;
6180 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6182 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6183 if (rv
== ERR_IO_PENDING
)
6184 rv
= callback
.WaitForResult();
6187 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6190 EXPECT_EQ(info
->headers
->response_code(), 301);
6192 std::string location
;
6193 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6194 EXPECT_EQ(location
, "http://www.bar.com/");
6196 // Mark the transaction as completed so it is cached.
6197 trans
->DoneReading();
6199 // Destroy transaction when going out of scope. We have not actually
6200 // read the response body -- want to test that it is still getting cached.
6202 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6203 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6204 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6207 // Verify that no-cache resources are stored in cache, but are not fetched from
6208 // cache during normal loads.
6209 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
6210 MockHttpCache cache
;
6212 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6213 transaction
.response_headers
= "cache-control: no-cache\n";
6216 RunTransactionTest(cache
.http_cache(), transaction
);
6218 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6219 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6220 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6222 // Try loading again; it should result in a network fetch.
6223 RunTransactionTest(cache
.http_cache(), transaction
);
6225 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6226 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6227 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6229 disk_cache::Entry
* entry
;
6230 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6234 // Verify that no-cache resources are stored in cache and fetched from cache
6235 // when the LOAD_PREFERRING_CACHE flag is set.
6236 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
6237 MockHttpCache cache
;
6239 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6240 transaction
.response_headers
= "cache-control: no-cache\n";
6243 RunTransactionTest(cache
.http_cache(), transaction
);
6245 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6246 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6247 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6249 // Try loading again with LOAD_PREFERRING_CACHE.
6250 transaction
.load_flags
= LOAD_PREFERRING_CACHE
;
6251 RunTransactionTest(cache
.http_cache(), transaction
);
6253 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6254 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6255 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6257 disk_cache::Entry
* entry
;
6258 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6262 TEST(HttpCache
, CacheControlNoStore
) {
6263 MockHttpCache cache
;
6265 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6266 transaction
.response_headers
= "cache-control: no-store\n";
6269 RunTransactionTest(cache
.http_cache(), transaction
);
6271 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6272 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6273 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6275 // try loading again; it should result in a network fetch
6276 RunTransactionTest(cache
.http_cache(), transaction
);
6278 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6279 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6280 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6282 disk_cache::Entry
* entry
;
6283 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6286 TEST(HttpCache
, CacheControlNoStore2
) {
6287 // this test is similar to the above test, except that the initial response
6288 // is cachable, but when it is validated, no-store is received causing the
6289 // cached document to be deleted.
6290 MockHttpCache cache
;
6292 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6295 RunTransactionTest(cache
.http_cache(), transaction
);
6297 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6298 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6299 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6301 // try loading again; it should result in a network fetch
6302 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6303 transaction
.response_headers
= "cache-control: no-store\n";
6304 RunTransactionTest(cache
.http_cache(), transaction
);
6306 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6307 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6308 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6310 disk_cache::Entry
* entry
;
6311 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6314 TEST(HttpCache
, CacheControlNoStore3
) {
6315 // this test is similar to the above test, except that the response is a 304
6316 // instead of a 200. this should never happen in practice, but it seems like
6317 // a good thing to verify that we still destroy the cache entry.
6318 MockHttpCache cache
;
6320 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6323 RunTransactionTest(cache
.http_cache(), transaction
);
6325 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6326 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6327 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6329 // try loading again; it should result in a network fetch
6330 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6331 transaction
.response_headers
= "cache-control: no-store\n";
6332 transaction
.status
= "HTTP/1.1 304 Not Modified";
6333 RunTransactionTest(cache
.http_cache(), transaction
);
6335 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6336 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6337 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6339 disk_cache::Entry
* entry
;
6340 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6343 // Ensure that we don't cache requests served over bad HTTPS.
6344 TEST(HttpCache
, SimpleGET_SSLError
) {
6345 MockHttpCache cache
;
6347 MockTransaction transaction
= kSimpleGET_Transaction
;
6348 transaction
.cert_status
= CERT_STATUS_REVOKED
;
6349 ScopedMockTransaction
scoped_transaction(transaction
);
6351 // write to the cache
6352 RunTransactionTest(cache
.http_cache(), transaction
);
6354 // Test that it was not cached.
6355 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6357 MockHttpRequest
request(transaction
);
6358 TestCompletionCallback callback
;
6360 scoped_ptr
<HttpTransaction
> trans
;
6361 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6363 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6364 if (rv
== ERR_IO_PENDING
)
6365 rv
= callback
.WaitForResult();
6366 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
6369 // Ensure that we don't crash by if left-behind transactions.
6370 TEST(HttpCache
, OutlivedTransactions
) {
6371 MockHttpCache
* cache
= new MockHttpCache
;
6373 scoped_ptr
<HttpTransaction
> trans
;
6374 EXPECT_EQ(OK
, cache
->CreateTransaction(&trans
));
6380 // Test that the disabled mode works.
6381 TEST(HttpCache
, CacheDisabledMode
) {
6382 MockHttpCache cache
;
6384 // write to the cache
6385 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6387 // go into disabled mode
6388 cache
.http_cache()->set_mode(HttpCache::DISABLE
);
6390 // force this transaction to write to the cache again
6391 MockTransaction
transaction(kSimpleGET_Transaction
);
6393 RunTransactionTest(cache
.http_cache(), transaction
);
6395 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6396 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6397 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6400 // Other tests check that the response headers of the cached response
6401 // get updated on 304. Here we specifically check that the
6402 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6403 // fields also gets updated.
6404 // http://crbug.com/20594.
6405 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6406 MockHttpCache cache
;
6408 const char kUrl
[] = "http://foobar";
6409 const char kData
[] = "body";
6411 MockTransaction mock_network_response
= { 0 };
6412 mock_network_response
.url
= kUrl
;
6414 AddMockTransaction(&mock_network_response
);
6416 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6418 MockTransaction request
= { 0 };
6420 request
.method
= "GET";
6421 request
.request_headers
= "\r\n";
6422 request
.data
= kData
;
6424 static const Response kNetResponse1
= {
6426 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6427 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6431 kNetResponse1
.AssignTo(&mock_network_response
);
6433 RunTransactionTest(cache
.http_cache(), request
);
6435 // Request |kUrl| again, this time validating the cache and getting
6438 request
.load_flags
= LOAD_VALIDATE_CACHE
;
6440 static const Response kNetResponse2
= {
6441 "HTTP/1.1 304 Not Modified",
6442 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6446 kNetResponse2
.AssignTo(&mock_network_response
);
6448 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6449 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6451 mock_network_response
.request_time
= request_time
;
6452 mock_network_response
.response_time
= response_time
;
6454 HttpResponseInfo response
;
6455 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6457 // The request and response times should have been updated.
6458 EXPECT_EQ(request_time
.ToInternalValue(),
6459 response
.request_time
.ToInternalValue());
6460 EXPECT_EQ(response_time
.ToInternalValue(),
6461 response
.response_time
.ToInternalValue());
6463 std::string headers
;
6464 response
.headers
->GetNormalizedHeaders(&headers
);
6466 EXPECT_EQ("HTTP/1.1 200 OK\n"
6467 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6468 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6471 RemoveMockTransaction(&mock_network_response
);
6474 // Tests that we can write metadata to an entry.
6475 TEST(HttpCache
, WriteMetadata_OK
) {
6476 MockHttpCache cache
;
6478 // Write to the cache
6479 HttpResponseInfo response
;
6480 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6482 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6485 cache
.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY
, Time::Now(),
6488 // Write meta data to the same entry.
6489 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6490 memset(buf
->data(), 0, buf
->size());
6491 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6492 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6493 DEFAULT_PRIORITY
, response
.response_time
,
6494 buf
.get(), buf
->size());
6496 // Release the buffer before the operation takes place.
6499 // Makes sure we finish pending operations.
6500 base::MessageLoop::current()->RunUntilIdle();
6502 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6504 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6505 EXPECT_EQ(50, response
.metadata
->size());
6506 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6508 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6509 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6510 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6513 // Tests that we only write metadata to an entry if the time stamp matches.
6514 TEST(HttpCache
, WriteMetadata_Fail
) {
6515 MockHttpCache cache
;
6517 // Write to the cache
6518 HttpResponseInfo response
;
6519 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6521 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6523 // Attempt to write meta data to the same entry.
6524 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6525 memset(buf
->data(), 0, buf
->size());
6526 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6527 base::Time expected_time
= response
.response_time
-
6528 base::TimeDelta::FromMilliseconds(20);
6529 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6530 DEFAULT_PRIORITY
, expected_time
, buf
.get(),
6533 // Makes sure we finish pending operations.
6534 base::MessageLoop::current()->RunUntilIdle();
6536 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6538 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6540 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6541 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6542 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6545 // Tests that we can read metadata after validating the entry and with READ mode
6547 TEST(HttpCache
, ReadMetadata
) {
6548 MockHttpCache cache
;
6550 // Write to the cache
6551 HttpResponseInfo response
;
6552 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6553 kTypicalGET_Transaction
, &response
);
6554 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6556 // Write meta data to the same entry.
6557 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6558 memset(buf
->data(), 0, buf
->size());
6559 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6560 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6561 DEFAULT_PRIORITY
, response
.response_time
,
6562 buf
.get(), buf
->size());
6564 // Makes sure we finish pending operations.
6565 base::MessageLoop::current()->RunUntilIdle();
6567 // Start with a READ mode transaction.
6568 MockTransaction
trans1(kTypicalGET_Transaction
);
6569 trans1
.load_flags
= LOAD_ONLY_FROM_CACHE
;
6571 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6572 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6573 EXPECT_EQ(50, response
.metadata
->size());
6574 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6576 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6577 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6578 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6579 base::MessageLoop::current()->RunUntilIdle();
6581 // Now make sure that the entry is re-validated with the server.
6582 trans1
.load_flags
= LOAD_VALIDATE_CACHE
;
6583 trans1
.status
= "HTTP/1.1 304 Not Modified";
6584 AddMockTransaction(&trans1
);
6586 response
.metadata
= NULL
;
6587 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6588 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6590 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6591 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6592 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6593 base::MessageLoop::current()->RunUntilIdle();
6594 RemoveMockTransaction(&trans1
);
6596 // Now return 200 when validating the entry so the metadata will be lost.
6597 MockTransaction
trans2(kTypicalGET_Transaction
);
6598 trans2
.load_flags
= LOAD_VALIDATE_CACHE
;
6599 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6600 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6602 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6603 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6604 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6607 // Tests that we don't mark entries as truncated when a filter detects the end
6609 TEST(HttpCache
, FilterCompletion
) {
6610 MockHttpCache cache
;
6611 TestCompletionCallback callback
;
6614 scoped_ptr
<HttpTransaction
> trans
;
6615 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6617 MockHttpRequest
request(kSimpleGET_Transaction
);
6618 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6619 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6621 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6622 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6623 EXPECT_GT(callback
.GetResult(rv
), 0);
6625 // Now make sure that the entry is preserved.
6626 trans
->DoneReading();
6629 // Make sure that the ActiveEntry is gone.
6630 base::MessageLoop::current()->RunUntilIdle();
6632 // Read from the cache.
6633 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6635 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6636 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6637 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6640 // Tests that we don't mark entries as truncated and release the cache
6641 // entry when DoneReading() is called before any Read() calls, such as
6643 TEST(HttpCache
, DoneReading
) {
6644 MockHttpCache cache
;
6645 TestCompletionCallback callback
;
6647 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6648 transaction
.data
= "";
6650 scoped_ptr
<HttpTransaction
> trans
;
6651 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6653 MockHttpRequest
request(transaction
);
6654 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6655 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6657 trans
->DoneReading();
6658 // Leave the transaction around.
6660 // Make sure that the ActiveEntry is gone.
6661 base::MessageLoop::current()->RunUntilIdle();
6663 // Read from the cache. This should not deadlock.
6664 RunTransactionTest(cache
.http_cache(), transaction
);
6666 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6667 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6668 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6671 // Tests that we stop caching when told.
6672 TEST(HttpCache
, StopCachingDeletesEntry
) {
6673 MockHttpCache cache
;
6674 TestCompletionCallback callback
;
6675 MockHttpRequest
request(kSimpleGET_Transaction
);
6678 scoped_ptr
<HttpTransaction
> trans
;
6679 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6681 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6682 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6684 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6685 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6686 EXPECT_EQ(10, callback
.GetResult(rv
));
6688 trans
->StopCaching();
6690 // We should be able to keep reading.
6691 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6692 EXPECT_GT(callback
.GetResult(rv
), 0);
6693 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6694 EXPECT_EQ(0, callback
.GetResult(rv
));
6697 // Make sure that the ActiveEntry is gone.
6698 base::MessageLoop::current()->RunUntilIdle();
6700 // Verify that the entry is gone.
6701 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6703 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6704 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6705 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6708 // Tests that we stop caching when told, even if DoneReading is called
6709 // after StopCaching.
6710 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6711 MockHttpCache cache
;
6712 TestCompletionCallback callback
;
6713 MockHttpRequest
request(kSimpleGET_Transaction
);
6716 scoped_ptr
<HttpTransaction
> trans
;
6717 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6719 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6720 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6722 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6723 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6724 EXPECT_EQ(10, callback
.GetResult(rv
));
6726 trans
->StopCaching();
6728 // We should be able to keep reading.
6729 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6730 EXPECT_GT(callback
.GetResult(rv
), 0);
6731 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6732 EXPECT_EQ(0, callback
.GetResult(rv
));
6734 // We should be able to call DoneReading.
6735 trans
->DoneReading();
6738 // Make sure that the ActiveEntry is gone.
6739 base::MessageLoop::current()->RunUntilIdle();
6741 // Verify that the entry is gone.
6742 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6744 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6745 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6746 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6749 // Tests that we stop caching when told, when using auth.
6750 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6751 MockHttpCache cache
;
6752 TestCompletionCallback callback
;
6753 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6754 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6755 AddMockTransaction(&mock_transaction
);
6756 MockHttpRequest
request(mock_transaction
);
6759 scoped_ptr
<HttpTransaction
> trans
;
6760 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6762 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6763 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6765 trans
->StopCaching();
6767 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6768 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6769 EXPECT_EQ(callback
.GetResult(rv
), 10);
6771 RemoveMockTransaction(&mock_transaction
);
6773 // Make sure that the ActiveEntry is gone.
6774 base::MessageLoop::current()->RunUntilIdle();
6776 // Verify that the entry is gone.
6777 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6779 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6780 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6781 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6784 // Tests that when we are told to stop caching we don't throw away valid data.
6785 TEST(HttpCache
, StopCachingSavesEntry
) {
6786 MockHttpCache cache
;
6787 TestCompletionCallback callback
;
6788 MockHttpRequest
request(kSimpleGET_Transaction
);
6791 scoped_ptr
<HttpTransaction
> trans
;
6792 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6794 // Force a response that can be resumed.
6795 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6796 AddMockTransaction(&mock_transaction
);
6797 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6798 "Content-Length: 42\n"
6801 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6802 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6804 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6805 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6806 EXPECT_EQ(callback
.GetResult(rv
), 10);
6808 trans
->StopCaching();
6810 // We should be able to keep reading.
6811 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6812 EXPECT_GT(callback
.GetResult(rv
), 0);
6813 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6814 EXPECT_EQ(callback
.GetResult(rv
), 0);
6816 RemoveMockTransaction(&mock_transaction
);
6819 // Verify that the entry is marked as incomplete.
6820 disk_cache::Entry
* entry
;
6821 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6822 HttpResponseInfo response
;
6823 bool truncated
= false;
6824 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6825 EXPECT_TRUE(truncated
);
6829 // Tests that we handle truncated enries when StopCaching is called.
6830 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6831 MockHttpCache cache
;
6832 TestCompletionCallback callback
;
6833 MockHttpRequest
request(kRangeGET_TransactionOK
);
6834 request
.extra_headers
.Clear();
6835 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6836 AddMockTransaction(&kRangeGET_TransactionOK
);
6838 std::string
raw_headers("HTTP/1.1 200 OK\n"
6839 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6841 "Accept-Ranges: bytes\n"
6842 "Content-Length: 80\n");
6843 CreateTruncatedEntry(raw_headers
, &cache
);
6846 // Now make a regular request.
6847 scoped_ptr
<HttpTransaction
> trans
;
6848 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6850 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6851 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6853 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6854 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6855 EXPECT_EQ(callback
.GetResult(rv
), 10);
6857 // This is actually going to do nothing.
6858 trans
->StopCaching();
6860 // We should be able to keep reading.
6861 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6862 EXPECT_GT(callback
.GetResult(rv
), 0);
6863 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6864 EXPECT_GT(callback
.GetResult(rv
), 0);
6865 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6866 EXPECT_EQ(callback
.GetResult(rv
), 0);
6869 // Verify that the disk entry was updated.
6870 disk_cache::Entry
* entry
;
6871 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6872 EXPECT_EQ(80, entry
->GetDataSize(1));
6873 bool truncated
= true;
6874 HttpResponseInfo response
;
6875 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6876 EXPECT_FALSE(truncated
);
6879 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6882 // Tests that we detect truncated resources from the net when there is
6883 // a Content-Length header.
6884 TEST(HttpCache
, TruncatedByContentLength
) {
6885 MockHttpCache cache
;
6886 TestCompletionCallback callback
;
6888 MockTransaction
transaction(kSimpleGET_Transaction
);
6889 AddMockTransaction(&transaction
);
6890 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6891 "Content-Length: 100\n";
6892 RunTransactionTest(cache
.http_cache(), transaction
);
6893 RemoveMockTransaction(&transaction
);
6895 // Read from the cache.
6896 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6898 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6899 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6900 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6903 // Tests that we actually flag entries as truncated when we detect an error
6905 TEST(HttpCache
, TruncatedByContentLength2
) {
6906 MockHttpCache cache
;
6907 TestCompletionCallback callback
;
6909 MockTransaction
transaction(kSimpleGET_Transaction
);
6910 AddMockTransaction(&transaction
);
6911 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6912 "Content-Length: 100\n"
6914 RunTransactionTest(cache
.http_cache(), transaction
);
6915 RemoveMockTransaction(&transaction
);
6917 // Verify that the entry is marked as incomplete.
6918 disk_cache::Entry
* entry
;
6919 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6920 HttpResponseInfo response
;
6921 bool truncated
= false;
6922 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6923 EXPECT_TRUE(truncated
);
6927 // Make sure that calling SetPriority on a cache transaction passes on
6928 // its priority updates to its underlying network transaction.
6929 TEST(HttpCache
, SetPriority
) {
6930 MockHttpCache cache
;
6932 scoped_ptr
<HttpTransaction
> trans
;
6933 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
6935 // Shouldn't crash, but doesn't do anything either.
6936 trans
->SetPriority(LOW
);
6938 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6939 EXPECT_EQ(DEFAULT_PRIORITY
,
6940 cache
.network_layer()->last_create_transaction_priority());
6942 HttpRequestInfo info
;
6943 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6944 TestCompletionCallback callback
;
6945 EXPECT_EQ(ERR_IO_PENDING
,
6946 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
6948 EXPECT_TRUE(cache
.network_layer()->last_transaction());
6949 if (cache
.network_layer()->last_transaction()) {
6950 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
6951 EXPECT_EQ(LOW
, cache
.network_layer()->last_transaction()->priority());
6954 trans
->SetPriority(HIGHEST
);
6956 if (cache
.network_layer()->last_transaction()) {
6957 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
6958 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_transaction()->priority());
6961 EXPECT_EQ(OK
, callback
.WaitForResult());
6964 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6965 // transaction passes on its argument to the underlying network transaction.
6966 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
6967 MockHttpCache cache
;
6969 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
6970 scoped_ptr
<HttpTransaction
> trans
;
6971 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
6973 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6975 HttpRequestInfo info
;
6976 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6977 TestCompletionCallback callback
;
6978 EXPECT_EQ(ERR_IO_PENDING
,
6979 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
6981 ASSERT_TRUE(cache
.network_layer()->last_transaction());
6982 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
6983 websocket_handshake_stream_create_helper());
6984 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
6985 EXPECT_EQ(&create_helper
,
6986 cache
.network_layer()->last_transaction()->
6987 websocket_handshake_stream_create_helper());
6988 EXPECT_EQ(OK
, callback
.WaitForResult());
6991 // Make sure that a cache transaction passes on its priority to
6992 // newly-created network transactions.
6993 TEST(HttpCache
, SetPriorityNewTransaction
) {
6994 MockHttpCache cache
;
6995 AddMockTransaction(&kRangeGET_TransactionOK
);
6997 std::string
raw_headers("HTTP/1.1 200 OK\n"
6998 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7000 "Accept-Ranges: bytes\n"
7001 "Content-Length: 80\n");
7002 CreateTruncatedEntry(raw_headers
, &cache
);
7004 // Now make a regular request.
7005 std::string headers
;
7006 MockTransaction
transaction(kRangeGET_TransactionOK
);
7007 transaction
.request_headers
= EXTRA_HEADER
;
7008 transaction
.data
= kFullRangeData
;
7010 scoped_ptr
<HttpTransaction
> trans
;
7011 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(MEDIUM
, &trans
));
7012 EXPECT_EQ(DEFAULT_PRIORITY
,
7013 cache
.network_layer()->last_create_transaction_priority());
7015 MockHttpRequest
info(transaction
);
7016 TestCompletionCallback callback
;
7017 EXPECT_EQ(ERR_IO_PENDING
,
7018 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7019 EXPECT_EQ(OK
, callback
.WaitForResult());
7021 EXPECT_EQ(MEDIUM
, cache
.network_layer()->last_create_transaction_priority());
7023 trans
->SetPriority(HIGHEST
);
7024 // Should trigger a new network transaction and pick up the new
7026 ReadAndVerifyTransaction(trans
.get(), transaction
);
7028 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_create_transaction_priority());
7030 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7033 int64
RunTransactionAndGetReceivedBytes(
7034 MockHttpCache
& cache
,
7035 const MockTransaction
& trans_info
) {
7036 int64 received_bytes
= -1;
7037 RunTransactionTestBase(cache
.http_cache(), trans_info
,
7038 MockHttpRequest(trans_info
), NULL
, BoundNetLog(), NULL
,
7040 return received_bytes
;
7043 int64
TransactionSize(const MockTransaction
& transaction
) {
7044 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
7045 strlen(transaction
.data
);
7048 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
7049 MockHttpCache cache
;
7051 MockTransaction
transaction(kSimpleGET_Transaction
);
7052 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7053 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7055 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7056 EXPECT_EQ(0, received_bytes
);
7059 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
7060 MockHttpCache cache
;
7062 ScopedMockTransaction
transaction(kETagGET_Transaction
);
7063 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7064 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7066 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
7067 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
7068 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7069 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7072 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
7073 MockHttpCache cache
;
7075 MockTransaction
transaction(kTypicalGET_Transaction
);
7076 transaction
.request_headers
= "Foo: bar\r\n";
7077 transaction
.response_headers
=
7078 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7079 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7081 "Cache-Control: max-age=0\n"
7083 AddMockTransaction(&transaction
);
7084 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7085 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7087 RevalidationServer server
;
7088 transaction
.handler
= server
.Handler
;
7089 transaction
.request_headers
= "Foo: none\r\n";
7090 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7091 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7093 RemoveMockTransaction(&transaction
);
7096 TEST(HttpCache
, ReceivedBytesRange
) {
7097 MockHttpCache cache
;
7098 AddMockTransaction(&kRangeGET_TransactionOK
);
7099 MockTransaction
transaction(kRangeGET_TransactionOK
);
7101 // Read bytes 40-49 from the network.
7102 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7103 int64 range_response_size
= TransactionSize(transaction
);
7104 EXPECT_EQ(range_response_size
, received_bytes
);
7106 // Read bytes 40-49 from the cache.
7107 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7108 EXPECT_EQ(0, received_bytes
);
7109 base::MessageLoop::current()->RunUntilIdle();
7111 // Read bytes 30-39 from the network.
7112 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
7113 transaction
.data
= "rg: 30-39 ";
7114 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7115 EXPECT_EQ(range_response_size
, received_bytes
);
7116 base::MessageLoop::current()->RunUntilIdle();
7118 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7119 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
7120 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7121 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7122 EXPECT_EQ(range_response_size
* 2, received_bytes
);
7124 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7127 class HttpCachePrefetchValidationTest
: public ::testing::Test
{
7129 static const int kMaxAgeSecs
= 100;
7130 static const int kRequireValidationSecs
= kMaxAgeSecs
+ 1;
7132 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction
) {
7133 DCHECK_LT(kMaxAgeSecs
, prefetch_reuse_mins() * kNumSecondsPerMinute
);
7135 clock_
= new base::SimpleTestClock();
7136 cache_
.http_cache()->SetClockForTesting(make_scoped_ptr(clock_
));
7137 cache_
.network_layer()->SetClock(clock_
);
7139 transaction_
.response_headers
= "Cache-Control: max-age=100\n";
7142 bool TransactionRequiredNetwork(int load_flags
) {
7143 int pre_transaction_count
= transaction_count();
7144 transaction_
.load_flags
= load_flags
;
7145 RunTransactionTest(cache_
.http_cache(), transaction_
);
7146 return pre_transaction_count
!= transaction_count();
7149 void AdvanceTime(int seconds
) {
7150 clock_
->Advance(base::TimeDelta::FromSeconds(seconds
));
7153 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins
; }
7155 // How many times this test has sent requests to the (fake) origin
7156 // server. Every test case needs to make at least one request to initialise
7158 int transaction_count() {
7159 return cache_
.network_layer()->transaction_count();
7162 MockHttpCache cache_
;
7163 ScopedMockTransaction transaction_
;
7164 std::string response_headers_
;
7165 base::SimpleTestClock
* clock_
;
7168 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationShortlyAfterPrefetch
) {
7169 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7170 AdvanceTime(kRequireValidationSecs
);
7171 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7174 TEST_F(HttpCachePrefetchValidationTest
, ValidateLongAfterPrefetch
) {
7175 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7176 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute
);
7177 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7180 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceOnly
) {
7181 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7182 AdvanceTime(kRequireValidationSecs
);
7183 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7184 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7187 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceReadOnly
) {
7188 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7189 AdvanceTime(kRequireValidationSecs
);
7190 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE
));
7191 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7194 TEST_F(HttpCachePrefetchValidationTest
, BypassCacheOverwritesPrefetch
) {
7195 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7196 AdvanceTime(kRequireValidationSecs
);
7197 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE
));
7198 AdvanceTime(kRequireValidationSecs
);
7199 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7202 TEST_F(HttpCachePrefetchValidationTest
,
7203 SkipValidationOnExistingEntryThatNeedsValidation
) {
7204 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7205 AdvanceTime(kRequireValidationSecs
);
7206 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7207 AdvanceTime(kRequireValidationSecs
);
7208 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7209 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7212 TEST_F(HttpCachePrefetchValidationTest
,
7213 SkipValidationOnExistingEntryThatDoesNotNeedValidation
) {
7214 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7215 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7216 AdvanceTime(kRequireValidationSecs
);
7217 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7218 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7221 TEST_F(HttpCachePrefetchValidationTest
, PrefetchMultipleTimes
) {
7222 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7223 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7224 AdvanceTime(kRequireValidationSecs
);
7225 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7228 TEST_F(HttpCachePrefetchValidationTest
, ValidateOnDelayedSecondPrefetch
) {
7229 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7230 AdvanceTime(kRequireValidationSecs
);
7231 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7232 AdvanceTime(kRequireValidationSecs
);
7233 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7236 // Framework for tests of stale-while-revalidate related functionality. With
7237 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
7238 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
7239 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
7240 // synchronous revalidation.
7241 class HttpCacheStaleWhileRevalidateTest
: public ::testing::Test
{
7243 HttpCacheStaleWhileRevalidateTest()
7244 : transaction_(kSimpleGET_Transaction
),
7246 stale_while_revalidate_(7200),
7247 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
7248 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(true);
7251 // RunTransactionTest() with the arguments from this fixture.
7252 void RunFixtureTransactionTest() {
7253 std::string response_headers
= base::StringPrintf(
7256 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
7259 stale_while_revalidate_
);
7260 transaction_
.response_headers
= response_headers
.c_str();
7261 RunTransactionTest(cache_
.http_cache(), transaction_
);
7262 transaction_
.response_headers
= "";
7265 // How many times this test has sent requests to the (fake) origin
7266 // server. Every test case needs to make at least one request to initialise
7268 int transaction_count() {
7269 return cache_
.network_layer()->transaction_count();
7272 // How many times an existing cache entry was opened during the test case.
7273 int open_count() { return cache_
.disk_cache()->open_count(); }
7275 MockHttpCache cache_
;
7276 ScopedMockTransaction transaction_
;
7278 int stale_while_revalidate_
;
7279 std::string validator_
;
7282 static void CheckResourceFreshnessHeader(const HttpRequestInfo
* request
,
7283 std::string
* response_status
,
7284 std::string
* response_headers
,
7285 std::string
* response_data
) {
7287 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
7288 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
7291 // Verify that the Resource-Freshness header is sent on a revalidation if the
7292 // stale-while-revalidate directive was on the response.
7293 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderSent
) {
7294 age_
= 10801; // Outside the stale-while-revalidate window.
7296 // Write to the cache.
7297 RunFixtureTransactionTest();
7299 EXPECT_EQ(1, transaction_count());
7301 // Send the request again and check that Resource-Freshness header is added.
7302 transaction_
.handler
= CheckResourceFreshnessHeader
;
7304 RunFixtureTransactionTest();
7306 EXPECT_EQ(2, transaction_count());
7309 static void CheckResourceFreshnessAbsent(const HttpRequestInfo
* request
,
7310 std::string
* response_status
,
7311 std::string
* response_headers
,
7312 std::string
* response_data
) {
7313 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7316 // Verify that the Resource-Freshness header is not sent when
7317 // stale-while-revalidate is 0.
7318 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderNotSent
) {
7320 stale_while_revalidate_
= 0;
7322 // Write to the cache.
7323 RunFixtureTransactionTest();
7325 EXPECT_EQ(1, transaction_count());
7327 // Send the request again and check that Resource-Freshness header is absent.
7328 transaction_
.handler
= CheckResourceFreshnessAbsent
;
7330 RunFixtureTransactionTest();
7332 EXPECT_EQ(2, transaction_count());
7335 // Verify that when stale-while-revalidate applies the response is read from
7337 TEST_F(HttpCacheStaleWhileRevalidateTest
, ReadFromCache
) {
7338 // Write to the cache.
7339 RunFixtureTransactionTest();
7341 EXPECT_EQ(0, open_count());
7342 EXPECT_EQ(1, transaction_count());
7344 // Read back from the cache.
7345 RunFixtureTransactionTest();
7347 EXPECT_EQ(1, open_count());
7348 EXPECT_EQ(1, transaction_count());
7351 // Verify that when stale-while-revalidate applies an asynchronous request is
7353 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestSent
) {
7354 // Write to the cache.
7355 RunFixtureTransactionTest();
7357 EXPECT_EQ(1, transaction_count());
7359 // Read back from the cache.
7360 RunFixtureTransactionTest();
7362 EXPECT_EQ(1, transaction_count());
7364 // Let the async request execute.
7365 base::RunLoop().RunUntilIdle();
7366 EXPECT_EQ(2, transaction_count());
7369 // Verify that tearing down the HttpCache with an async revalidation in progress
7370 // does not break anything (this test is most likely to find problems when run
7371 // with a memory checker such as AddressSanitizer).
7372 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncTearDown
) {
7373 // Write to the cache.
7374 RunFixtureTransactionTest();
7376 // Read back from the cache.
7377 RunFixtureTransactionTest();
7380 static void CheckIfModifiedSinceHeader(const HttpRequestInfo
* request
,
7381 std::string
* response_status
,
7382 std::string
* response_headers
,
7383 std::string
* response_data
) {
7385 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-Modified-Since", &value
));
7386 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value
);
7389 // Verify that the async revalidation contains an If-Modified-Since header.
7390 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfModifiedSince
) {
7391 // Write to the cache.
7392 RunFixtureTransactionTest();
7394 transaction_
.handler
= CheckIfModifiedSinceHeader
;
7396 // Read back from the cache.
7397 RunFixtureTransactionTest();
7400 static void CheckIfNoneMatchHeader(const HttpRequestInfo
* request
,
7401 std::string
* response_status
,
7402 std::string
* response_headers
,
7403 std::string
* response_data
) {
7405 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-None-Match", &value
));
7406 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value
);
7409 // If the response had ETag rather than Last-Modified, then that is used to
7410 // conditionalise the response.
7411 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfNoneMatch
) {
7412 validator_
= "Etag: \"40a1-1320-4f6adefa22a40\"";
7414 // Write to the cache.
7415 RunFixtureTransactionTest();
7417 transaction_
.handler
= CheckIfNoneMatchHeader
;
7419 // Read back from the cache.
7420 RunFixtureTransactionTest();
7423 static void CheckResourceFreshnessHeaderPresent(const HttpRequestInfo
* request
,
7424 std::string
* response_status
,
7425 std::string
* response_headers
,
7426 std::string
* response_data
) {
7427 EXPECT_TRUE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7430 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestHasResourceFreshness
) {
7431 // Write to the cache.
7432 RunFixtureTransactionTest();
7434 transaction_
.handler
= CheckResourceFreshnessHeaderPresent
;
7436 // Read back from the cache.
7437 RunFixtureTransactionTest();
7440 // Verify that when age > max-age + stale-while-revalidate stale results are
7442 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedIfTooStale
) {
7445 // Write to the cache.
7446 RunFixtureTransactionTest();
7448 EXPECT_EQ(0, open_count());
7449 EXPECT_EQ(1, transaction_count());
7451 // Reading back reads from the network.
7452 RunFixtureTransactionTest();
7454 EXPECT_EQ(1, open_count());
7455 EXPECT_EQ(2, transaction_count());
7458 // HEAD requests should be able to take advantage of stale-while-revalidate.
7459 TEST_F(HttpCacheStaleWhileRevalidateTest
, WorksForHeadMethod
) {
7460 // Write to the cache. This has to be a GET request; HEAD requests don't
7461 // create new cache entries.
7462 RunFixtureTransactionTest();
7464 EXPECT_EQ(0, open_count());
7465 EXPECT_EQ(1, transaction_count());
7467 // Read back from the cache, and trigger an asynchronous HEAD request.
7468 transaction_
.method
= "HEAD";
7469 transaction_
.data
= "";
7471 RunFixtureTransactionTest();
7473 EXPECT_EQ(1, open_count());
7474 EXPECT_EQ(1, transaction_count());
7476 // Let the network request proceed.
7477 base::RunLoop().RunUntilIdle();
7479 EXPECT_EQ(2, transaction_count());
7482 // POST requests should not use stale-while-revalidate.
7483 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedToPost
) {
7484 transaction_
= ScopedMockTransaction(kSimplePOST_Transaction
);
7486 // Write to the cache.
7487 RunFixtureTransactionTest();
7489 EXPECT_EQ(0, open_count());
7490 EXPECT_EQ(1, transaction_count());
7492 // Reading back reads from the network.
7493 RunFixtureTransactionTest();
7495 EXPECT_EQ(0, open_count());
7496 EXPECT_EQ(2, transaction_count());
7499 static void CheckUrlMatches(const HttpRequestInfo
* request
,
7500 std::string
* response_status
,
7501 std::string
* response_headers
,
7502 std::string
* response_data
) {
7503 EXPECT_EQ("http://www.google.com/", request
->url
.spec());
7506 // Async revalidation is issued to the original URL.
7507 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestUrlMatches
) {
7508 transaction_
.url
= "http://www.google.com/";
7509 // Write to the cache.
7510 RunFixtureTransactionTest();
7512 // Read back from the cache.
7513 RunFixtureTransactionTest();
7515 EXPECT_EQ(1, transaction_count());
7517 transaction_
.handler
= CheckUrlMatches
;
7519 // Let the async request execute and perform the check.
7520 base::RunLoop().RunUntilIdle();
7521 EXPECT_EQ(2, transaction_count());
7524 class SyncLoadFlagTest
: public HttpCacheStaleWhileRevalidateTest
,
7525 public ::testing::WithParamInterface
<int> {};
7527 // Flags which should always cause the request to be synchronous.
7528 TEST_P(SyncLoadFlagTest
, MustBeSynchronous
) {
7529 transaction_
.load_flags
|= GetParam();
7530 // Write to the cache.
7531 RunFixtureTransactionTest();
7533 EXPECT_EQ(1, transaction_count());
7535 // Reading back reads from the network.
7536 RunFixtureTransactionTest();
7538 EXPECT_EQ(2, transaction_count());
7541 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate
,
7543 ::testing::Values(LOAD_VALIDATE_CACHE
,
7545 LOAD_DISABLE_CACHE
));
7547 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7548 PreferringCacheDoesNotTriggerAsyncRequest
) {
7549 transaction_
.load_flags
|= LOAD_PREFERRING_CACHE
;
7550 // Write to the cache.
7551 RunFixtureTransactionTest();
7553 EXPECT_EQ(1, transaction_count());
7555 // Reading back reads from the cache.
7556 RunFixtureTransactionTest();
7558 EXPECT_EQ(1, transaction_count());
7560 // If there was an async transaction created, it would run now.
7561 base::RunLoop().RunUntilIdle();
7563 // There was no async transaction.
7564 EXPECT_EQ(1, transaction_count());
7567 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotUsedWhenDisabled
) {
7568 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7569 // Write to the cache.
7570 RunFixtureTransactionTest();
7572 EXPECT_EQ(1, transaction_count());
7574 // A synchronous revalidation is performed.
7575 RunFixtureTransactionTest();
7577 EXPECT_EQ(2, transaction_count());
7580 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7581 OnlyFromCacheDoesNotTriggerAsyncRequest
) {
7582 transaction_
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
7583 transaction_
.return_code
= ERR_CACHE_MISS
;
7585 // Writing to the cache should fail, because we are avoiding the network.
7586 RunFixtureTransactionTest();
7588 EXPECT_EQ(0, transaction_count());
7590 base::RunLoop().RunUntilIdle();
7593 EXPECT_EQ(0, transaction_count());
7596 // A certificate error during an asynchronous fetch should cause the next fetch
7597 // to proceed synchronously.
7598 // TODO(ricea): In future, only certificate errors which require user
7599 // interaction should fail the asynchronous revalidation, and they should cause
7600 // the next revalidation to be synchronous rather than requiring a total
7601 // refetch. This test will need to be updated appropriately.
7602 TEST_F(HttpCacheStaleWhileRevalidateTest
, CertificateErrorCausesRefetch
) {
7603 // Write to the cache.
7604 RunFixtureTransactionTest();
7606 EXPECT_EQ(1, transaction_count());
7608 // Now read back. RunTransactionTestBase() expects to receive the network
7609 // error back from the HttpCache::Transaction, but since the cache request
7610 // will return OK we need to duplicate some of its implementation here.
7611 transaction_
.return_code
= ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
7612 TestCompletionCallback callback
;
7613 scoped_ptr
<HttpTransaction
> trans
;
7614 int rv
= cache_
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
7616 ASSERT_TRUE(trans
.get());
7618 MockHttpRequest
request(transaction_
);
7619 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
7620 ASSERT_EQ(ERR_IO_PENDING
, rv
);
7621 ASSERT_EQ(OK
, callback
.WaitForResult());
7622 ReadAndVerifyTransaction(trans
.get(), transaction_
);
7624 EXPECT_EQ(1, transaction_count());
7626 // Allow the asynchronous fetch to run.
7627 base::RunLoop().RunUntilIdle();
7629 EXPECT_EQ(2, transaction_count());
7631 // Now run the transaction again. It should run synchronously.
7632 transaction_
.return_code
= OK
;
7633 RunFixtureTransactionTest();
7635 EXPECT_EQ(3, transaction_count());
7638 // Ensure that the response cached by the asynchronous request is not truncated,
7639 // even if the server is slow.
7640 TEST_F(HttpCacheStaleWhileRevalidateTest
, EntireResponseCached
) {
7641 transaction_
.test_mode
= TEST_MODE_SLOW_READ
;
7642 // Write to the cache.
7643 RunFixtureTransactionTest();
7645 // Read back from the cache.
7646 RunFixtureTransactionTest();
7648 // Let the async request execute.
7649 base::RunLoop().RunUntilIdle();
7651 // The cache entry should still be complete.
7652 transaction_
.load_flags
= LOAD_ONLY_FROM_CACHE
;
7653 RunFixtureTransactionTest();
7656 // Verify that there are no race conditions in the completely synchronous case.
7657 TEST_F(HttpCacheStaleWhileRevalidateTest
, SynchronousCaseWorks
) {
7658 transaction_
.test_mode
= TEST_MODE_SYNC_ALL
;
7659 // Write to the cache.
7660 RunFixtureTransactionTest();
7662 EXPECT_EQ(1, transaction_count());
7664 // Read back from the cache.
7665 RunFixtureTransactionTest();
7667 EXPECT_EQ(1, transaction_count());
7669 // Let the async request execute.
7670 base::RunLoop().RunUntilIdle();
7671 EXPECT_EQ(2, transaction_count());
7674 static void CheckLoadFlagsAsyncRevalidation(const HttpRequestInfo
* request
,
7675 std::string
* response_status
,
7676 std::string
* response_headers
,
7677 std::string
* response_data
) {
7678 EXPECT_EQ(LOAD_ASYNC_REVALIDATION
, request
->load_flags
);
7681 // Check that the load flags on the async request are the same as the load flags
7682 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7683 TEST_F(HttpCacheStaleWhileRevalidateTest
, LoadFlagsAsyncRevalidation
) {
7684 transaction_
.load_flags
= LOAD_NORMAL
;
7685 // Write to the cache.
7686 RunFixtureTransactionTest();
7688 EXPECT_EQ(1, transaction_count());
7690 // Read back from the cache.
7691 RunFixtureTransactionTest();
7693 EXPECT_EQ(1, transaction_count());
7695 transaction_
.handler
= CheckLoadFlagsAsyncRevalidation
;
7696 // Let the async request execute.
7697 base::RunLoop().RunUntilIdle();
7698 EXPECT_EQ(2, transaction_count());
7701 static void SimpleMockAuthHandler(const HttpRequestInfo
* request
,
7702 std::string
* response_status
,
7703 std::string
* response_headers
,
7704 std::string
* response_data
) {
7705 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
7706 !request
->extra_headers
.HasHeader("Authorization")) {
7707 response_status
->assign("HTTP/1.1 401 Unauthorized");
7708 response_headers
->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7711 response_status
->assign("HTTP/1.1 200 OK");
7714 TEST_F(HttpCacheStaleWhileRevalidateTest
, RestartForAuth
) {
7715 // Write to the cache.
7716 RunFixtureTransactionTest();
7718 EXPECT_EQ(1, transaction_count());
7720 // Now make the transaction require auth.
7721 transaction_
.request_headers
= "X-Require-Mock-Auth: dummy\r\n\r\n";
7722 transaction_
.handler
= SimpleMockAuthHandler
;
7724 // Read back from the cache.
7725 RunFixtureTransactionTest();
7727 EXPECT_EQ(1, transaction_count());
7729 // Let the async request execute.
7730 base::RunLoop().RunUntilIdle();
7732 EXPECT_EQ(2, transaction_count());
7735 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7736 // take place on a sparse entry.
7737 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7738 MockHttpCache cache
;
7740 // Create a transaction for bytes 0-9.
7741 MockHttpRequest
request(kRangeGET_TransactionOK
);
7742 MockTransaction
transaction(kRangeGET_TransactionOK
);
7743 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7744 transaction
.data
= "rg: 00-09 ";
7745 AddMockTransaction(&transaction
);
7747 TestCompletionCallback callback
;
7748 scoped_ptr
<HttpTransaction
> trans
;
7749 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
7751 ASSERT_TRUE(trans
.get());
7753 // Start our transaction.
7754 trans
->Start(&request
, callback
.callback(), BoundNetLog());
7756 // A second transaction on a different part of the file (the default
7757 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7758 // the already pending transaction.
7759 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7761 // Let the first transaction complete.
7762 callback
.WaitForResult();
7764 RemoveMockTransaction(&transaction
);
7767 // Makes sure that a request stops using the cache when the response headers
7768 // with "Cache-Control: no-store" arrives. That means that another request for
7769 // the same URL can be processed before the response body of the original
7771 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7772 MockHttpCache cache
;
7773 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7774 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7775 MockHttpRequest
request(mock_transaction
);
7777 scoped_ptr
<Context
> first(new Context
);
7778 first
->result
= cache
.CreateTransaction(&first
->trans
);
7779 ASSERT_EQ(OK
, first
->result
);
7780 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7782 first
->trans
->Start(&request
, first
->callback
.callback(), BoundNetLog());
7783 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7785 base::MessageLoop::current()->RunUntilIdle();
7786 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7787 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7788 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7789 "Cache-Control", "no-store"));
7790 // Here we have read the response header but not read the response body yet.
7792 // Let us create the second (read) transaction.
7793 scoped_ptr
<Context
> second(new Context
);
7794 second
->result
= cache
.CreateTransaction(&second
->trans
);
7795 ASSERT_EQ(OK
, second
->result
);
7796 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7797 second
->result
= second
->trans
->Start(&request
, second
->callback
.callback(),
7800 // Here the second transaction proceeds without reading the first body.
7801 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7802 base::MessageLoop::current()->RunUntilIdle();
7803 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7804 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7805 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7806 "Cache-Control", "no-store"));
7807 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);