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/net_log_unittest.h"
38 #include "net/socket/client_socket_handle.h"
39 #include "net/ssl/ssl_cert_request_info.h"
40 #include "net/websockets/websocket_handshake_stream_base.h"
41 #include "testing/gtest/include/gtest/gtest.h"
49 // Tests the load timing values of a request that goes through a
50 // MockNetworkTransaction.
51 void TestLoadTimingNetworkRequest(const LoadTimingInfo
& load_timing_info
) {
52 EXPECT_FALSE(load_timing_info
.socket_reused
);
53 EXPECT_NE(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
55 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
56 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
58 ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
59 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
60 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
61 load_timing_info
.send_start
);
63 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
65 // Set by URLRequest / URLRequestHttpJob, at a higher level.
66 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
67 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
68 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
71 // Tests the load timing values of a request that receives a cached response.
72 void TestLoadTimingCachedResponse(const LoadTimingInfo
& load_timing_info
) {
73 EXPECT_FALSE(load_timing_info
.socket_reused
);
74 EXPECT_EQ(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
76 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
77 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
79 ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
81 // Only the send start / end times should be sent, and they should have the
83 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
84 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
86 // Set by URLRequest / URLRequestHttpJob, at a higher level.
87 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
88 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
89 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
92 class DeleteCacheCompletionCallback
: public TestCompletionCallbackBase
{
94 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
96 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
97 base::Unretained(this))) {
100 const CompletionCallback
& callback() const { return callback_
; }
103 void OnComplete(int result
) {
108 MockHttpCache
* cache_
;
109 CompletionCallback callback_
;
111 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
114 //-----------------------------------------------------------------------------
117 void ReadAndVerifyTransaction(HttpTransaction
* trans
,
118 const MockTransaction
& trans_info
) {
120 int rv
= ReadTransaction(trans
, &content
);
123 std::string
expected(trans_info
.data
);
124 EXPECT_EQ(expected
, content
);
127 void RunTransactionTestBase(HttpCache
* cache
,
128 const MockTransaction
& trans_info
,
129 const MockHttpRequest
& request
,
130 HttpResponseInfo
* response_info
,
131 const BoundNetLog
& net_log
,
132 LoadTimingInfo
* load_timing_info
,
133 int64
* received_bytes
) {
134 TestCompletionCallback callback
;
136 // write to the cache
138 scoped_ptr
<HttpTransaction
> trans
;
139 int rv
= cache
->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
141 ASSERT_TRUE(trans
.get());
143 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
144 if (rv
== ERR_IO_PENDING
)
145 rv
= callback
.WaitForResult();
146 ASSERT_EQ(trans_info
.return_code
, rv
);
151 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
152 ASSERT_TRUE(response
);
155 *response_info
= *response
;
157 if (load_timing_info
) {
158 // If a fake network connection is used, need a NetLog to get a fake socket
160 EXPECT_TRUE(net_log
.net_log());
161 *load_timing_info
= LoadTimingInfo();
162 trans
->GetLoadTimingInfo(load_timing_info
);
165 ReadAndVerifyTransaction(trans
.get(), trans_info
);
168 *received_bytes
= trans
->GetTotalReceivedBytes();
171 void RunTransactionTestWithRequest(HttpCache
* cache
,
172 const MockTransaction
& trans_info
,
173 const MockHttpRequest
& request
,
174 HttpResponseInfo
* response_info
) {
175 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
176 BoundNetLog(), NULL
, NULL
);
179 void RunTransactionTestAndGetTiming(HttpCache
* cache
,
180 const MockTransaction
& trans_info
,
181 const BoundNetLog
& log
,
182 LoadTimingInfo
* load_timing_info
) {
183 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
184 NULL
, log
, load_timing_info
, NULL
);
187 void RunTransactionTest(HttpCache
* cache
, const MockTransaction
& trans_info
) {
188 RunTransactionTestAndGetTiming(cache
, trans_info
, BoundNetLog(), NULL
);
191 void RunTransactionTestWithLog(HttpCache
* cache
,
192 const MockTransaction
& trans_info
,
193 const BoundNetLog
& log
) {
194 RunTransactionTestAndGetTiming(cache
, trans_info
, log
, NULL
);
197 void RunTransactionTestWithResponseInfo(HttpCache
* cache
,
198 const MockTransaction
& trans_info
,
199 HttpResponseInfo
* response
) {
200 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
204 void RunTransactionTestWithResponseInfoAndGetTiming(
206 const MockTransaction
& trans_info
,
207 HttpResponseInfo
* response
,
208 const BoundNetLog
& log
,
209 LoadTimingInfo
* load_timing_info
) {
210 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
211 response
, log
, load_timing_info
, NULL
);
214 void RunTransactionTestWithResponse(HttpCache
* cache
,
215 const MockTransaction
& trans_info
,
216 std::string
* response_headers
) {
217 HttpResponseInfo response
;
218 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
219 response
.headers
->GetNormalizedHeaders(response_headers
);
222 void RunTransactionTestWithResponseAndGetTiming(
224 const MockTransaction
& trans_info
,
225 std::string
* response_headers
,
226 const BoundNetLog
& log
,
227 LoadTimingInfo
* load_timing_info
) {
228 HttpResponseInfo response
;
229 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
230 &response
, log
, load_timing_info
, NULL
);
231 response
.headers
->GetNormalizedHeaders(response_headers
);
234 // This class provides a handler for kFastNoStoreGET_Transaction so that the
235 // no-store header can be included on demand.
236 class FastTransactionServer
{
238 FastTransactionServer() {
241 ~FastTransactionServer() {}
243 void set_no_store(bool value
) { no_store
= value
; }
245 static void FastNoStoreHandler(const HttpRequestInfo
* request
,
246 std::string
* response_status
,
247 std::string
* response_headers
,
248 std::string
* response_data
) {
250 *response_headers
= "Cache-Control: no-store\n";
254 static bool no_store
;
255 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
257 bool FastTransactionServer::no_store
;
259 const MockTransaction kFastNoStoreGET_Transaction
= {
260 "http://www.google.com/nostore",
266 "Cache-Control: max-age=10000\n",
268 "<html><body>Google Blah Blah</body></html>",
269 TEST_MODE_SYNC_NET_START
,
270 &FastTransactionServer::FastNoStoreHandler
,
274 // This class provides a handler for kRangeGET_TransactionOK so that the range
275 // request can be served on demand.
276 class RangeTransactionServer
{
278 RangeTransactionServer() {
279 not_modified_
= false;
283 ~RangeTransactionServer() {
284 not_modified_
= false;
289 // Returns only 416 or 304 when set.
290 void set_not_modified(bool value
) { not_modified_
= value
; }
292 // Returns 206 when revalidating a range (instead of 304).
293 void set_modified(bool value
) { modified_
= value
; }
295 // Returns 200 instead of 206 (a malformed response overall).
296 void set_bad_200(bool value
) { bad_200_
= value
; }
298 // Other than regular range related behavior (and the flags mentioned above),
299 // the server reacts to requests headers like so:
300 // X-Require-Mock-Auth -> return 401.
301 // X-Return-Default-Range -> assume 40-49 was requested.
302 static void RangeHandler(const HttpRequestInfo
* request
,
303 std::string
* response_status
,
304 std::string
* response_headers
,
305 std::string
* response_data
);
308 static bool not_modified_
;
309 static bool modified_
;
310 static bool bad_200_
;
311 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
313 bool RangeTransactionServer::not_modified_
= false;
314 bool RangeTransactionServer::modified_
= false;
315 bool RangeTransactionServer::bad_200_
= false;
317 // A dummy extra header that must be preserved on a given request.
319 // EXTRA_HEADER_LINE doesn't include a line terminator because it
320 // will be passed to AddHeaderFromString() which doesn't accept them.
321 #define EXTRA_HEADER_LINE "Extra: header"
323 // EXTRA_HEADER contains a line terminator, as expected by
324 // AddHeadersFromString() (_not_ AddHeaderFromString()).
325 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
327 static const char kExtraHeaderKey
[] = "Extra";
330 void RangeTransactionServer::RangeHandler(const HttpRequestInfo
* request
,
331 std::string
* response_status
,
332 std::string
* response_headers
,
333 std::string
* response_data
) {
334 if (request
->extra_headers
.IsEmpty()) {
335 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
336 response_data
->clear();
340 // We want to make sure we don't delete extra headers.
341 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
343 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
344 !request
->extra_headers
.HasHeader("Authorization")) {
345 response_status
->assign("HTTP/1.1 401 Unauthorized");
346 response_data
->assign("WWW-Authenticate: Foo\n");
351 response_status
->assign("HTTP/1.1 304 Not Modified");
352 response_data
->clear();
356 std::vector
<HttpByteRange
> ranges
;
357 std::string range_header
;
358 if (!request
->extra_headers
.GetHeader(HttpRequestHeaders::kRange
,
360 !HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
361 ranges
.size() != 1) {
362 // This is not a byte range request. We return 200.
363 response_status
->assign("HTTP/1.1 200 OK");
364 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
365 response_data
->assign("Not a range");
369 // We can handle this range request.
370 HttpByteRange byte_range
= ranges
[0];
372 if (request
->extra_headers
.HasHeader("X-Return-Default-Range")) {
373 byte_range
.set_first_byte_position(40);
374 byte_range
.set_last_byte_position(49);
377 if (byte_range
.first_byte_position() > 79) {
378 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
379 response_data
->clear();
383 EXPECT_TRUE(byte_range
.ComputeBounds(80));
384 int start
= static_cast<int>(byte_range
.first_byte_position());
385 int end
= static_cast<int>(byte_range
.last_byte_position());
389 std::string content_range
= base::StringPrintf(
390 "Content-Range: bytes %d-%d/80\n", start
, end
);
391 response_headers
->append(content_range
);
393 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
396 EXPECT_EQ(0, end
% 10);
399 EXPECT_EQ(9, (end
- start
) % 10);
400 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
401 base::StringAppendF(&data
, "rg: %02d-%02d ",
402 block_start
, block_start
+ 9);
405 *response_data
= data
;
407 if (end
- start
!= 9) {
408 // We also have to fix content-length.
409 int len
= end
- start
+ 1;
410 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
412 response_headers
->replace(response_headers
->find("Content-Length:"),
413 content_length
.size(), content_length
);
416 response_status
->assign("HTTP/1.1 304 Not Modified");
417 response_data
->clear();
421 const MockTransaction kRangeGET_TransactionOK
= {
422 "http://www.google.com/range",
425 "Range: bytes = 40-49\r\n" EXTRA_HEADER
,
427 "HTTP/1.1 206 Partial Content",
428 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
430 "Accept-Ranges: bytes\n"
431 "Content-Length: 10\n",
435 &RangeTransactionServer::RangeHandler
,
439 const char kFullRangeData
[] =
440 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
441 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
443 // Verifies the response headers (|response|) match a partial content
444 // response for the range starting at |start| and ending at |end|.
445 void Verify206Response(std::string response
, int start
, int end
) {
446 std::string
raw_headers(
447 HttpUtil::AssembleRawHeaders(response
.data(), response
.size()));
448 scoped_refptr
<HttpResponseHeaders
> headers(
449 new HttpResponseHeaders(raw_headers
));
451 ASSERT_EQ(206, headers
->response_code());
453 int64 range_start
, range_end
, object_size
;
455 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
456 int64 content_length
= headers
->GetContentLength();
458 int length
= end
- start
+ 1;
459 ASSERT_EQ(length
, content_length
);
460 ASSERT_EQ(start
, range_start
);
461 ASSERT_EQ(end
, range_end
);
464 // Creates a truncated entry that can be resumed using byte ranges.
465 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
466 // Create a disk cache entry that stores an incomplete resource.
467 disk_cache::Entry
* entry
;
468 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
472 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
474 HttpResponseInfo response
;
475 response
.response_time
= base::Time::Now();
476 response
.request_time
= base::Time::Now();
477 response
.headers
= new HttpResponseHeaders(raw_headers
);
478 // Set the last argument for this to be an incomplete request.
479 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
481 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
482 int len
= static_cast<int>(base::strlcpy(buf
->data(),
483 "rg: 00-09 rg: 10-19 ", 100));
484 TestCompletionCallback cb
;
485 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
486 EXPECT_EQ(len
, cb
.GetResult(rv
));
490 // Helper to represent a network HTTP response.
492 // Set this response into |trans|.
493 void AssignTo(MockTransaction
* trans
) const {
494 trans
->status
= status
;
495 trans
->response_headers
= headers
;
499 std::string
status_and_headers() const {
500 return std::string(status
) + "\n" + std::string(headers
);
509 Context() : result(ERR_IO_PENDING
) {}
512 TestCompletionCallback callback
;
513 scoped_ptr
<HttpTransaction
> trans
;
516 class FakeWebSocketHandshakeStreamCreateHelper
517 : public WebSocketHandshakeStreamBase::CreateHelper
{
519 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
520 WebSocketHandshakeStreamBase
* CreateBasicStream(
521 scoped_ptr
<ClientSocketHandle
> connect
,
522 bool using_proxy
) override
{
525 WebSocketHandshakeStreamBase
* CreateSpdyStream(
526 const base::WeakPtr
<SpdySession
>& session
,
527 bool use_relative_url
) override
{
532 // Returns true if |entry| is not one of the log types paid attention to in this
533 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
535 bool ShouldIgnoreLogEntry(const TestNetLog::CapturedEntry
& entry
) {
536 switch (entry
.type
) {
537 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
538 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
539 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
540 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
541 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
542 case NetLog::TYPE_HTTP_CACHE_READ_INFO
:
549 // Modifies |entries| to only include log entries created by the cache layer and
550 // asserted on in these tests.
551 void FilterLogEntries(TestNetLog::CapturedEntryList
* entries
) {
552 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
553 &ShouldIgnoreLogEntry
),
557 bool LogContainsEventType(const BoundTestNetLog
& log
,
558 NetLog::EventType expected
) {
559 TestNetLog::CapturedEntryList entries
;
560 log
.GetEntries(&entries
);
561 for (size_t i
= 0; i
< entries
.size(); i
++) {
562 if (entries
[i
].type
== expected
)
571 //-----------------------------------------------------------------------------
574 TEST(HttpCache
, CreateThenDestroy
) {
577 scoped_ptr
<HttpTransaction
> trans
;
578 EXPECT_EQ(OK
, cache
.CreateTransaction(&trans
));
579 ASSERT_TRUE(trans
.get());
582 TEST(HttpCache
, GetBackend
) {
583 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(0));
585 disk_cache::Backend
* backend
;
586 TestCompletionCallback cb
;
587 // This will lazily initialize the backend.
588 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
589 EXPECT_EQ(OK
, cb
.GetResult(rv
));
592 TEST(HttpCache
, SimpleGET
) {
595 LoadTimingInfo load_timing_info
;
597 // Write to the cache.
598 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
599 log
.bound(), &load_timing_info
);
601 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
602 EXPECT_EQ(0, cache
.disk_cache()->open_count());
603 EXPECT_EQ(1, cache
.disk_cache()->create_count());
604 TestLoadTimingNetworkRequest(load_timing_info
);
607 TEST(HttpCache
, SimpleGETNoDiskCache
) {
610 cache
.disk_cache()->set_fail_requests();
613 LoadTimingInfo load_timing_info
;
615 // Read from the network, and don't use the cache.
616 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
617 log
.bound(), &load_timing_info
);
619 // Check that the NetLog was filled as expected.
620 // (We attempted to both Open and Create entries, but both failed).
621 TestNetLog::CapturedEntryList entries
;
622 log
.GetEntries(&entries
);
623 FilterLogEntries(&entries
);
625 EXPECT_EQ(6u, entries
.size());
627 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
629 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
631 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
633 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
635 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
637 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
639 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
640 EXPECT_EQ(0, cache
.disk_cache()->open_count());
641 EXPECT_EQ(0, cache
.disk_cache()->create_count());
642 TestLoadTimingNetworkRequest(load_timing_info
);
645 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
646 // This will initialize a cache object with NULL backend.
647 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
648 factory
->set_fail(true);
649 factory
->FinishCreation(); // We'll complete synchronously.
650 MockHttpCache
cache(factory
);
652 // Read from the network, and don't use the cache.
653 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
655 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
656 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
659 // Tests that IOBuffers are not referenced after IO completes.
660 TEST(HttpCache
, ReleaseBuffer
) {
663 // Write to the cache.
664 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
666 MockHttpRequest
request(kSimpleGET_Transaction
);
667 scoped_ptr
<HttpTransaction
> trans
;
668 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
670 const int kBufferSize
= 10;
671 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(kBufferSize
));
672 ReleaseBufferCompletionCallback
cb(buffer
.get());
674 int rv
= trans
->Start(&request
, cb
.callback(), BoundNetLog());
675 EXPECT_EQ(OK
, cb
.GetResult(rv
));
677 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
678 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
681 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
684 cache
.disk_cache()->set_soft_failures(true);
686 // Read from the network, and fail to write to the cache.
687 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
689 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
690 EXPECT_EQ(0, cache
.disk_cache()->open_count());
691 EXPECT_EQ(1, cache
.disk_cache()->create_count());
693 // This one should see an empty cache again.
694 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
696 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
697 EXPECT_EQ(0, cache
.disk_cache()->open_count());
698 EXPECT_EQ(2, cache
.disk_cache()->create_count());
701 // Tests that disk failures after the transaction has started don't cause the
703 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
706 MockHttpRequest
request(kSimpleGET_Transaction
);
708 scoped_ptr
<Context
> c(new Context());
709 int rv
= cache
.CreateTransaction(&c
->trans
);
712 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
713 EXPECT_EQ(ERR_IO_PENDING
, rv
);
714 rv
= c
->callback
.WaitForResult();
716 // Start failing request now.
717 cache
.disk_cache()->set_soft_failures(true);
719 // We have to open the entry again to propagate the failure flag.
720 disk_cache::Entry
* en
;
721 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
724 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
727 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
728 EXPECT_EQ(1, cache
.disk_cache()->open_count());
729 EXPECT_EQ(1, cache
.disk_cache()->create_count());
731 // This one should see an empty cache again.
732 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
734 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
735 EXPECT_EQ(1, cache
.disk_cache()->open_count());
736 EXPECT_EQ(2, cache
.disk_cache()->create_count());
739 // Tests that we handle failures to read from the cache.
740 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
743 // Read from the network, and write to the cache.
744 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
746 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
747 EXPECT_EQ(0, cache
.disk_cache()->open_count());
748 EXPECT_EQ(1, cache
.disk_cache()->create_count());
750 cache
.disk_cache()->set_soft_failures(true);
752 // Now fail to read from the cache.
753 scoped_ptr
<Context
> c(new Context());
754 int rv
= cache
.CreateTransaction(&c
->trans
);
757 MockHttpRequest
request(kSimpleGET_Transaction
);
758 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
759 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
761 // Now verify that the entry was removed from the cache.
762 cache
.disk_cache()->set_soft_failures(false);
764 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
765 EXPECT_EQ(1, cache
.disk_cache()->open_count());
766 EXPECT_EQ(2, cache
.disk_cache()->create_count());
768 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
770 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
771 EXPECT_EQ(1, cache
.disk_cache()->open_count());
772 EXPECT_EQ(3, cache
.disk_cache()->create_count());
775 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
779 LoadTimingInfo load_timing_info
;
781 // Write to the cache.
782 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
783 log
.bound(), &load_timing_info
);
785 // Check that the NetLog was filled as expected.
786 TestNetLog::CapturedEntryList entries
;
787 log
.GetEntries(&entries
);
788 FilterLogEntries(&entries
);
790 EXPECT_EQ(8u, entries
.size());
792 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
794 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
796 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
798 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
800 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
802 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
804 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
806 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
808 TestLoadTimingNetworkRequest(load_timing_info
);
810 // Force this transaction to read from the cache.
811 MockTransaction
transaction(kSimpleGET_Transaction
);
812 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
816 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
819 // Check that the NetLog was filled as expected.
820 log
.GetEntries(&entries
);
821 FilterLogEntries(&entries
);
823 EXPECT_EQ(8u, entries
.size());
825 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
827 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
829 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
831 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
833 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
835 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
837 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
839 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO
));
841 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
842 EXPECT_EQ(1, cache
.disk_cache()->open_count());
843 EXPECT_EQ(1, cache
.disk_cache()->create_count());
844 TestLoadTimingCachedResponse(load_timing_info
);
847 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
850 // force this transaction to read from the cache
851 MockTransaction
transaction(kSimpleGET_Transaction
);
852 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
854 MockHttpRequest
request(transaction
);
855 TestCompletionCallback callback
;
857 scoped_ptr
<HttpTransaction
> trans
;
858 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
860 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
861 if (rv
== ERR_IO_PENDING
)
862 rv
= callback
.WaitForResult();
863 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
867 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
868 EXPECT_EQ(0, cache
.disk_cache()->open_count());
869 EXPECT_EQ(0, cache
.disk_cache()->create_count());
872 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
875 // write to the cache
876 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
878 // force this transaction to read from the cache if valid
879 MockTransaction
transaction(kSimpleGET_Transaction
);
880 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
882 RunTransactionTest(cache
.http_cache(), transaction
);
884 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
885 EXPECT_EQ(1, cache
.disk_cache()->open_count());
886 EXPECT_EQ(1, cache
.disk_cache()->create_count());
889 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
892 // force this transaction to read from the cache if valid
893 MockTransaction
transaction(kSimpleGET_Transaction
);
894 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
896 RunTransactionTest(cache
.http_cache(), transaction
);
898 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
899 EXPECT_EQ(0, cache
.disk_cache()->open_count());
900 EXPECT_EQ(1, cache
.disk_cache()->create_count());
903 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
904 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
907 // Write to the cache.
908 MockTransaction
transaction(kSimpleGET_Transaction
);
909 transaction
.request_headers
= "Foo: bar\r\n";
910 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
912 AddMockTransaction(&transaction
);
913 RunTransactionTest(cache
.http_cache(), transaction
);
915 // Read from the cache.
916 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
917 RunTransactionTest(cache
.http_cache(), transaction
);
919 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
920 EXPECT_EQ(1, cache
.disk_cache()->open_count());
921 EXPECT_EQ(1, cache
.disk_cache()->create_count());
922 RemoveMockTransaction(&transaction
);
925 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
926 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
929 // Write to the cache.
930 MockTransaction
transaction(kSimpleGET_Transaction
);
931 transaction
.request_headers
= "Foo: bar\r\n";
932 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
934 AddMockTransaction(&transaction
);
935 RunTransactionTest(cache
.http_cache(), transaction
);
937 // Attempt to read from the cache... this is a vary mismatch that must reach
938 // the network again.
939 transaction
.load_flags
|= LOAD_PREFERRING_CACHE
;
940 transaction
.request_headers
= "Foo: none\r\n";
942 LoadTimingInfo load_timing_info
;
943 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
946 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
947 EXPECT_EQ(1, cache
.disk_cache()->open_count());
948 EXPECT_EQ(1, cache
.disk_cache()->create_count());
949 TestLoadTimingNetworkRequest(load_timing_info
);
950 RemoveMockTransaction(&transaction
);
953 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
955 TEST(HttpCache
, SimpleGET_CacheOverride_Network
) {
959 MockTransaction
transaction(kSimpleGET_Transaction
);
960 transaction
.load_flags
|= LOAD_FROM_CACHE_IF_OFFLINE
;
961 transaction
.response_headers
= "Cache-Control: no-cache\n";
963 AddMockTransaction(&transaction
);
964 RunTransactionTest(cache
.http_cache(), transaction
);
965 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
966 EXPECT_EQ(1, cache
.disk_cache()->create_count());
967 RemoveMockTransaction(&transaction
);
969 // Re-run transaction; make sure the result came from the network,
971 transaction
.data
= "Changed data.";
972 AddMockTransaction(&transaction
);
973 HttpResponseInfo response_info
;
974 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
977 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
978 EXPECT_FALSE(response_info
.server_data_unavailable
);
979 EXPECT_TRUE(response_info
.network_accessed
);
981 RemoveMockTransaction(&transaction
);
984 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
986 TEST(HttpCache
, SimpleGET_CacheOverride_Offline
) {
990 MockTransaction
transaction(kSimpleGET_Transaction
);
991 transaction
.load_flags
|= LOAD_FROM_CACHE_IF_OFFLINE
;
992 transaction
.response_headers
= "Cache-Control: no-cache\n";
994 AddMockTransaction(&transaction
);
995 RunTransactionTest(cache
.http_cache(), transaction
);
996 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
997 EXPECT_EQ(1, cache
.disk_cache()->create_count());
998 RemoveMockTransaction(&transaction
);
1000 // Network failure with offline error; should return cache entry above +
1001 // flag signalling stale data.
1002 transaction
.return_code
= ERR_NAME_NOT_RESOLVED
;
1003 AddMockTransaction(&transaction
);
1005 MockHttpRequest
request(transaction
);
1006 TestCompletionCallback callback
;
1007 scoped_ptr
<HttpTransaction
> trans
;
1008 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
1009 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1010 EXPECT_EQ(OK
, callback
.GetResult(rv
));
1012 const HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1013 ASSERT_TRUE(response_info
);
1014 EXPECT_TRUE(response_info
->server_data_unavailable
);
1015 EXPECT_TRUE(response_info
->was_cached
);
1016 EXPECT_FALSE(response_info
->network_accessed
);
1017 ReadAndVerifyTransaction(trans
.get(), transaction
);
1018 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1020 RemoveMockTransaction(&transaction
);
1023 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1024 // non-offline failure.
1025 TEST(HttpCache
, SimpleGET_CacheOverride_NonOffline
) {
1026 MockHttpCache cache
;
1029 MockTransaction
transaction(kSimpleGET_Transaction
);
1030 transaction
.load_flags
|= LOAD_FROM_CACHE_IF_OFFLINE
;
1031 transaction
.response_headers
= "Cache-Control: no-cache\n";
1033 AddMockTransaction(&transaction
);
1034 RunTransactionTest(cache
.http_cache(), transaction
);
1035 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1036 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1037 RemoveMockTransaction(&transaction
);
1039 // Network failure with non-offline error; should fail with that error.
1040 transaction
.return_code
= ERR_PROXY_CONNECTION_FAILED
;
1041 AddMockTransaction(&transaction
);
1043 HttpResponseInfo response_info2
;
1044 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1047 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1048 EXPECT_FALSE(response_info2
.server_data_unavailable
);
1050 RemoveMockTransaction(&transaction
);
1053 // Tests that was_cached was set properly on a failure, even if the cached
1054 // response wasn't returned.
1055 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
1056 MockHttpCache cache
;
1059 MockTransaction
transaction(kSimpleGET_Transaction
);
1060 transaction
.response_headers
= "Cache-Control: no-cache\n";
1062 AddMockTransaction(&transaction
);
1063 RunTransactionTest(cache
.http_cache(), transaction
);
1064 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1065 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1066 RemoveMockTransaction(&transaction
);
1068 // Network failure with error; should fail but have was_cached set.
1069 transaction
.return_code
= ERR_FAILED
;
1070 AddMockTransaction(&transaction
);
1072 MockHttpRequest
request(transaction
);
1073 TestCompletionCallback callback
;
1074 scoped_ptr
<HttpTransaction
> trans
;
1075 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
1077 ASSERT_TRUE(trans
.get());
1078 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1079 EXPECT_EQ(ERR_FAILED
, callback
.GetResult(rv
));
1081 const HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1082 ASSERT_TRUE(response_info
);
1083 EXPECT_TRUE(response_info
->was_cached
);
1084 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1086 RemoveMockTransaction(&transaction
);
1089 // Confirm if we have an empty cache, a read is marked as network verified.
1090 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1091 MockHttpCache cache
;
1093 // write to the cache
1094 HttpResponseInfo response_info
;
1095 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1098 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1099 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1100 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1101 EXPECT_TRUE(response_info
.network_accessed
);
1104 // Confirm if we have a fresh entry in cache, it isn't marked as
1105 // network verified.
1106 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1107 MockHttpCache cache
;
1110 MockTransaction
transaction(kSimpleGET_Transaction
);
1112 RunTransactionTest(cache
.http_cache(), transaction
);
1113 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1114 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1116 // Re-run transaction; make sure we don't mark the network as accessed.
1117 HttpResponseInfo response_info
;
1118 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1121 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1122 EXPECT_FALSE(response_info
.server_data_unavailable
);
1123 EXPECT_FALSE(response_info
.network_accessed
);
1126 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1127 MockHttpCache cache
;
1129 // Write to the cache.
1130 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1132 // Force this transaction to write to the cache again.
1133 MockTransaction
transaction(kSimpleGET_Transaction
);
1134 transaction
.load_flags
|= LOAD_BYPASS_CACHE
;
1136 BoundTestNetLog log
;
1137 LoadTimingInfo load_timing_info
;
1139 // Write to the cache.
1140 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1143 // Check that the NetLog was filled as expected.
1144 TestNetLog::CapturedEntryList entries
;
1145 log
.GetEntries(&entries
);
1146 FilterLogEntries(&entries
);
1148 EXPECT_EQ(8u, entries
.size());
1150 LogContainsBeginEvent(entries
, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1152 LogContainsEndEvent(entries
, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1154 LogContainsBeginEvent(entries
, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1156 LogContainsEndEvent(entries
, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1158 LogContainsBeginEvent(entries
, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1160 LogContainsEndEvent(entries
, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1162 LogContainsBeginEvent(entries
, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1164 LogContainsEndEvent(entries
, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1166 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1167 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1168 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1169 TestLoadTimingNetworkRequest(load_timing_info
);
1172 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1173 MockHttpCache cache
;
1175 // write to the cache
1176 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1178 // force this transaction to write to the cache again
1179 MockTransaction
transaction(kSimpleGET_Transaction
);
1180 transaction
.request_headers
= "pragma: no-cache\r\n";
1182 RunTransactionTest(cache
.http_cache(), transaction
);
1184 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1185 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1186 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1189 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1190 MockHttpCache cache
;
1192 // write to the cache
1193 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1195 // force this transaction to write to the cache again
1196 MockTransaction
transaction(kSimpleGET_Transaction
);
1197 transaction
.request_headers
= "cache-control: no-cache\r\n";
1199 RunTransactionTest(cache
.http_cache(), transaction
);
1201 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1202 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1203 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1206 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1207 MockHttpCache cache
;
1209 // Write to the cache.
1210 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1212 // Read from the cache.
1213 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1215 // Force this transaction to validate the cache.
1216 MockTransaction
transaction(kSimpleGET_Transaction
);
1217 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
1219 HttpResponseInfo response_info
;
1220 BoundTestNetLog log
;
1221 LoadTimingInfo load_timing_info
;
1222 RunTransactionTestWithResponseInfoAndGetTiming(
1223 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1226 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1227 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1228 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1229 EXPECT_TRUE(response_info
.network_accessed
);
1230 TestLoadTimingNetworkRequest(load_timing_info
);
1233 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1234 MockHttpCache cache
;
1236 // write to the cache
1237 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1239 // read from the cache
1240 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1242 // force this transaction to validate the cache
1243 MockTransaction
transaction(kSimpleGET_Transaction
);
1244 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1246 RunTransactionTest(cache
.http_cache(), transaction
);
1248 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1249 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1250 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1253 static void PreserveRequestHeaders_Handler(const HttpRequestInfo
* request
,
1254 std::string
* response_status
,
1255 std::string
* response_headers
,
1256 std::string
* response_data
) {
1257 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1260 // Tests that we don't remove extra headers for simple requests.
1261 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1262 MockHttpCache cache
;
1264 MockTransaction
transaction(kSimpleGET_Transaction
);
1265 transaction
.handler
= PreserveRequestHeaders_Handler
;
1266 transaction
.request_headers
= EXTRA_HEADER
;
1267 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1268 AddMockTransaction(&transaction
);
1270 // Write, then revalidate the entry.
1271 RunTransactionTest(cache
.http_cache(), transaction
);
1272 RunTransactionTest(cache
.http_cache(), transaction
);
1274 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1275 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1276 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1277 RemoveMockTransaction(&transaction
);
1280 // Tests that we don't remove extra headers for conditionalized requests.
1281 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1282 MockHttpCache cache
;
1284 // Write to the cache.
1285 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1287 MockTransaction
transaction(kETagGET_Transaction
);
1288 transaction
.handler
= PreserveRequestHeaders_Handler
;
1289 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1291 AddMockTransaction(&transaction
);
1293 RunTransactionTest(cache
.http_cache(), transaction
);
1295 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1296 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1297 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1298 RemoveMockTransaction(&transaction
);
1301 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1302 MockHttpCache cache
;
1304 MockHttpRequest
request(kSimpleGET_Transaction
);
1306 std::vector
<Context
*> context_list
;
1307 const int kNumTransactions
= 5;
1309 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1310 context_list
.push_back(new Context());
1311 Context
* c
= context_list
[i
];
1313 c
->result
= cache
.CreateTransaction(&c
->trans
);
1314 ASSERT_EQ(OK
, c
->result
);
1315 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1318 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1321 // All requests are waiting for the active entry.
1322 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1323 Context
* c
= context_list
[i
];
1324 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1327 // Allow all requests to move from the Create queue to the active entry.
1328 base::MessageLoop::current()->RunUntilIdle();
1330 // The first request should be a writer at this point, and the subsequent
1331 // requests should be pending.
1333 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1334 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1335 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1337 // All requests depend on the writer, and the writer is between Start and
1339 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1340 Context
* c
= context_list
[i
];
1341 EXPECT_EQ(LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1344 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1345 Context
* c
= context_list
[i
];
1346 if (c
->result
== ERR_IO_PENDING
)
1347 c
->result
= c
->callback
.WaitForResult();
1348 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1351 // We should not have had to re-open the disk entry
1353 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1354 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1355 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1357 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1358 Context
* c
= context_list
[i
];
1363 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1364 // If cancelling a request is racing with another request for the same resource
1365 // finishing, we have to make sure that we remove both transactions from the
1367 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1368 MockHttpCache cache
;
1370 MockHttpRequest
request(kSimpleGET_Transaction
);
1371 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1372 reader_request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
1374 std::vector
<Context
*> context_list
;
1375 const int kNumTransactions
= 5;
1377 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1378 context_list
.push_back(new Context());
1379 Context
* c
= context_list
[i
];
1381 c
->result
= cache
.CreateTransaction(&c
->trans
);
1382 ASSERT_EQ(OK
, c
->result
);
1384 MockHttpRequest
* this_request
= &request
;
1385 if (i
== 1 || i
== 2)
1386 this_request
= &reader_request
;
1389 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1392 // Allow all requests to move from the Create queue to the active entry.
1393 base::MessageLoop::current()->RunUntilIdle();
1395 // The first request should be a writer at this point, and the subsequent
1396 // requests should be pending.
1398 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1399 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1400 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1402 Context
* c
= context_list
[0];
1403 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1404 c
->result
= c
->callback
.WaitForResult();
1405 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1407 // Now we have 2 active readers and two queued transactions.
1409 EXPECT_EQ(LOAD_STATE_IDLE
, context_list
[2]->trans
->GetLoadState());
1410 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
,
1411 context_list
[3]->trans
->GetLoadState());
1413 c
= context_list
[1];
1414 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1415 c
->result
= c
->callback
.WaitForResult();
1416 if (c
->result
== OK
)
1417 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1419 // At this point we have one reader, two pending transactions and a task on
1420 // the queue to move to the next transaction. Now we cancel the request that
1421 // is the current reader, and expect the queued task to be able to start the
1424 c
= context_list
[2];
1427 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1428 Context
* c
= context_list
[i
];
1429 if (c
->result
== ERR_IO_PENDING
)
1430 c
->result
= c
->callback
.WaitForResult();
1431 if (c
->result
== OK
)
1432 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1435 // We should not have had to re-open the disk entry.
1437 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1438 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1439 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1441 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1442 Context
* c
= context_list
[i
];
1447 // Tests that we can doom an entry with pending transactions and delete one of
1448 // the pending transactions before the first one completes.
1449 // See http://code.google.com/p/chromium/issues/detail?id=25588
1450 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1451 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1452 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
1454 MockHttpRequest
request(kSimpleGET_Transaction
);
1455 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1456 writer_request
.load_flags
= LOAD_BYPASS_CACHE
;
1458 ScopedVector
<Context
> context_list
;
1459 const int kNumTransactions
= 4;
1461 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1462 context_list
.push_back(new Context());
1463 Context
* c
= context_list
[i
];
1465 c
->result
= cache
.CreateTransaction(&c
->trans
);
1466 ASSERT_EQ(OK
, c
->result
);
1468 MockHttpRequest
* this_request
= &request
;
1470 this_request
= &writer_request
;
1473 c
->trans
->Start(this_request
, c
->callback
.callback(), BoundNetLog());
1476 // The first request should be a writer at this point, and the two subsequent
1477 // requests should be pending. The last request doomed the first entry.
1479 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1481 // Cancel the first queued transaction.
1482 delete context_list
[1];
1483 context_list
.get()[1] = NULL
;
1485 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1488 Context
* c
= context_list
[i
];
1489 ASSERT_EQ(ERR_IO_PENDING
, c
->result
);
1490 c
->result
= c
->callback
.WaitForResult();
1491 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1495 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1496 // We may attempt to delete an entry synchronously with the act of adding a new
1497 // transaction to said entry.
1498 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1499 MockHttpCache cache
;
1501 // The headers will be served right from the call to Start() the request.
1502 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1503 FastTransactionServer request_handler
;
1504 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1506 std::vector
<Context
*> context_list
;
1507 const int kNumTransactions
= 3;
1509 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1510 context_list
.push_back(new Context());
1511 Context
* c
= context_list
[i
];
1513 c
->result
= cache
.CreateTransaction(&c
->trans
);
1514 ASSERT_EQ(OK
, c
->result
);
1517 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1520 // Allow all requests to move from the Create queue to the active entry.
1521 base::MessageLoop::current()->RunUntilIdle();
1523 // The first request should be a writer at this point, and the subsequent
1524 // requests should be pending.
1526 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1527 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1528 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1530 // Now, make sure that the second request asks for the entry not to be stored.
1531 request_handler
.set_no_store(true);
1533 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1534 Context
* c
= context_list
[i
];
1535 if (c
->result
== ERR_IO_PENDING
)
1536 c
->result
= c
->callback
.WaitForResult();
1537 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1541 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1542 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1543 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1545 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1548 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1549 MockHttpCache cache
;
1551 MockHttpRequest
request(kSimpleGET_Transaction
);
1553 std::vector
<Context
*> context_list
;
1554 const int kNumTransactions
= 2;
1556 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1557 context_list
.push_back(new Context());
1558 Context
* c
= context_list
[i
];
1560 c
->result
= cache
.CreateTransaction(&c
->trans
);
1561 ASSERT_EQ(OK
, c
->result
);
1564 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1567 // Allow all requests to move from the Create queue to the active entry.
1568 base::MessageLoop::current()->RunUntilIdle();
1570 // The first request should be a writer at this point, and the subsequent
1571 // requests should be pending.
1573 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1574 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1575 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1577 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1578 Context
* c
= context_list
[i
];
1579 if (c
->result
== ERR_IO_PENDING
)
1580 c
->result
= c
->callback
.WaitForResult();
1581 // Destroy only the first transaction.
1584 context_list
[i
] = NULL
;
1588 // Complete the rest of the transactions.
1589 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1590 Context
* c
= context_list
[i
];
1591 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1594 // We should have had to re-open the disk entry.
1596 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1597 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1598 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1600 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1601 Context
* c
= context_list
[i
];
1606 // Tests that we can cancel requests that are queued waiting to open the disk
1608 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1609 MockHttpCache cache
;
1611 MockHttpRequest
request(kSimpleGET_Transaction
);
1613 std::vector
<Context
*> context_list
;
1614 const int kNumTransactions
= 5;
1616 for (int i
= 0; i
< kNumTransactions
; i
++) {
1617 context_list
.push_back(new Context());
1618 Context
* c
= context_list
[i
];
1620 c
->result
= cache
.CreateTransaction(&c
->trans
);
1621 ASSERT_EQ(OK
, c
->result
);
1624 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1627 // The first request should be creating the disk cache entry and the others
1628 // should be pending.
1630 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1631 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1632 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1634 // Cancel a request from the pending queue.
1635 delete context_list
[3];
1636 context_list
[3] = NULL
;
1638 // Cancel the request that is creating the entry. This will force the pending
1639 // operations to restart.
1640 delete context_list
[0];
1641 context_list
[0] = NULL
;
1643 // Complete the rest of the transactions.
1644 for (int i
= 1; i
< kNumTransactions
; i
++) {
1645 Context
* c
= context_list
[i
];
1647 c
->result
= c
->callback
.GetResult(c
->result
);
1648 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1652 // We should have had to re-create the disk entry.
1654 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1655 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1656 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1658 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1659 delete context_list
[i
];
1663 // Tests that we can cancel a single request to open a disk cache entry.
1664 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1665 MockHttpCache cache
;
1667 MockHttpRequest
request(kSimpleGET_Transaction
);
1669 Context
* c
= new Context();
1671 c
->result
= cache
.CreateTransaction(&c
->trans
);
1672 ASSERT_EQ(OK
, c
->result
);
1674 c
->result
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1675 EXPECT_EQ(ERR_IO_PENDING
, c
->result
);
1677 // Release the reference that the mock disk cache keeps for this entry, so
1678 // that we test that the http cache handles the cancellation correctly.
1679 cache
.disk_cache()->ReleaseAll();
1682 base::MessageLoop::current()->RunUntilIdle();
1683 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1686 // Tests that we delete/create entries even if multiple requests are queued.
1687 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1688 MockHttpCache cache
;
1690 MockHttpRequest
request(kSimpleGET_Transaction
);
1691 request
.load_flags
= LOAD_BYPASS_CACHE
;
1693 std::vector
<Context
*> context_list
;
1694 const int kNumTransactions
= 5;
1696 for (int i
= 0; i
< kNumTransactions
; i
++) {
1697 context_list
.push_back(new Context());
1698 Context
* c
= context_list
[i
];
1700 c
->result
= cache
.CreateTransaction(&c
->trans
);
1701 ASSERT_EQ(OK
, c
->result
);
1704 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1707 // The first request should be deleting the disk cache entry and the others
1708 // should be pending.
1710 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1711 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1712 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1714 // Complete the transactions.
1715 for (int i
= 0; i
< kNumTransactions
; i
++) {
1716 Context
* c
= context_list
[i
];
1717 c
->result
= c
->callback
.GetResult(c
->result
);
1718 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1721 // We should have had to re-create the disk entry multiple times.
1723 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1724 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1725 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1727 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1728 delete context_list
[i
];
1732 // Tests that a (simulated) timeout allows transactions waiting on the cache
1733 // lock to continue.
1734 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1735 MockHttpCache cache
;
1736 cache
.BypassCacheLock();
1738 MockHttpRequest
request(kSimpleGET_Transaction
);
1740 ASSERT_EQ(OK
, cache
.CreateTransaction(&c1
.trans
));
1741 ASSERT_EQ(ERR_IO_PENDING
,
1742 c1
.trans
->Start(&request
, c1
.callback
.callback(), BoundNetLog()));
1743 ASSERT_EQ(OK
, cache
.CreateTransaction(&c2
.trans
));
1744 ASSERT_EQ(ERR_IO_PENDING
,
1745 c2
.trans
->Start(&request
, c2
.callback
.callback(), BoundNetLog()));
1747 // The second request is queued after the first one.
1749 c2
.callback
.WaitForResult();
1750 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1752 // Complete the first transaction.
1753 c1
.callback
.WaitForResult();
1754 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1757 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1758 MockHttpCache cache
;
1760 // write to the cache
1761 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1763 MockHttpRequest
request(kSimpleGET_Transaction
);
1764 TestCompletionCallback callback
;
1766 scoped_ptr
<HttpTransaction
> trans
;
1767 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
1768 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
1769 if (rv
== ERR_IO_PENDING
)
1770 rv
= callback
.WaitForResult();
1773 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
1774 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1775 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1777 // Test that destroying the transaction while it is reading from the cache
1781 // Make sure we pump any pending events, which should include a call to
1782 // HttpCache::Transaction::OnCacheReadCompleted.
1783 base::MessageLoop::current()->RunUntilIdle();
1786 // Tests that we can delete the HttpCache and deal with queued transactions
1787 // ("waiting for the backend" as opposed to Active or Doomed entries).
1788 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1789 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1790 new MockBackendNoCbFactory()));
1792 MockHttpRequest
request(kSimpleGET_Transaction
);
1794 std::vector
<Context
*> context_list
;
1795 const int kNumTransactions
= 5;
1797 for (int i
= 0; i
< kNumTransactions
; i
++) {
1798 context_list
.push_back(new Context());
1799 Context
* c
= context_list
[i
];
1801 c
->result
= cache
->CreateTransaction(&c
->trans
);
1802 ASSERT_EQ(OK
, c
->result
);
1805 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1808 // The first request should be creating the disk cache entry and the others
1809 // should be pending.
1811 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1812 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1813 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1817 // There is not much to do with the transactions at this point... they are
1818 // waiting for a callback that will not fire.
1819 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1820 delete context_list
[i
];
1824 // Tests that we queue requests when initializing the backend.
1825 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1826 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1827 MockHttpCache
cache(factory
);
1829 MockHttpRequest
request0(kSimpleGET_Transaction
);
1830 MockHttpRequest
request1(kTypicalGET_Transaction
);
1831 MockHttpRequest
request2(kETagGET_Transaction
);
1833 std::vector
<Context
*> context_list
;
1834 const int kNumTransactions
= 3;
1836 for (int i
= 0; i
< kNumTransactions
; i
++) {
1837 context_list
.push_back(new Context());
1838 Context
* c
= context_list
[i
];
1840 c
->result
= cache
.CreateTransaction(&c
->trans
);
1841 ASSERT_EQ(OK
, c
->result
);
1844 context_list
[0]->result
= context_list
[0]->trans
->Start(
1845 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1846 context_list
[1]->result
= context_list
[1]->trans
->Start(
1847 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1848 context_list
[2]->result
= context_list
[2]->trans
->Start(
1849 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1851 // Just to make sure that everything is still pending.
1852 base::MessageLoop::current()->RunUntilIdle();
1854 // The first request should be creating the disk cache.
1855 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1857 factory
->FinishCreation();
1859 base::MessageLoop::current()->RunUntilIdle();
1860 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1861 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1863 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1864 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1865 delete context_list
[i
];
1869 // Tests that we can cancel requests that are queued waiting for the backend
1870 // to be initialized.
1871 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1872 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1873 MockHttpCache
cache(factory
);
1875 MockHttpRequest
request0(kSimpleGET_Transaction
);
1876 MockHttpRequest
request1(kTypicalGET_Transaction
);
1877 MockHttpRequest
request2(kETagGET_Transaction
);
1879 std::vector
<Context
*> context_list
;
1880 const int kNumTransactions
= 3;
1882 for (int i
= 0; i
< kNumTransactions
; i
++) {
1883 context_list
.push_back(new Context());
1884 Context
* c
= context_list
[i
];
1886 c
->result
= cache
.CreateTransaction(&c
->trans
);
1887 ASSERT_EQ(OK
, c
->result
);
1890 context_list
[0]->result
= context_list
[0]->trans
->Start(
1891 &request0
, context_list
[0]->callback
.callback(), BoundNetLog());
1892 context_list
[1]->result
= context_list
[1]->trans
->Start(
1893 &request1
, context_list
[1]->callback
.callback(), BoundNetLog());
1894 context_list
[2]->result
= context_list
[2]->trans
->Start(
1895 &request2
, context_list
[2]->callback
.callback(), BoundNetLog());
1897 // Just to make sure that everything is still pending.
1898 base::MessageLoop::current()->RunUntilIdle();
1900 // The first request should be creating the disk cache.
1901 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1903 // Cancel a request from the pending queue.
1904 delete context_list
[1];
1905 context_list
[1] = NULL
;
1907 // Cancel the request that is creating the entry.
1908 delete context_list
[0];
1909 context_list
[0] = NULL
;
1911 // Complete the last transaction.
1912 factory
->FinishCreation();
1914 context_list
[2]->result
=
1915 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1916 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1918 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1919 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1921 delete context_list
[2];
1924 // Tests that we can delete the cache while creating the backend.
1925 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1926 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1927 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1929 MockHttpRequest
request(kSimpleGET_Transaction
);
1931 scoped_ptr
<Context
> c(new Context());
1932 c
->result
= cache
->CreateTransaction(&c
->trans
);
1933 ASSERT_EQ(OK
, c
->result
);
1935 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1937 // Just to make sure that everything is still pending.
1938 base::MessageLoop::current()->RunUntilIdle();
1940 // The request should be creating the disk cache.
1941 EXPECT_FALSE(c
->callback
.have_result());
1943 // We cannot call FinishCreation because the factory itself will go away with
1944 // the cache, so grab the callback and attempt to use it.
1945 CompletionCallback callback
= factory
->callback();
1946 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1949 base::MessageLoop::current()->RunUntilIdle();
1952 callback
.Run(ERR_ABORTED
);
1955 // Tests that we can delete the cache while creating the backend, from within
1956 // one of the callbacks.
1957 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1958 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1959 MockHttpCache
* cache
= new MockHttpCache(factory
);
1961 DeleteCacheCompletionCallback
cb(cache
);
1962 disk_cache::Backend
* backend
;
1963 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1964 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1966 // Now let's queue a regular transaction
1967 MockHttpRequest
request(kSimpleGET_Transaction
);
1969 scoped_ptr
<Context
> c(new Context());
1970 c
->result
= cache
->CreateTransaction(&c
->trans
);
1971 ASSERT_EQ(OK
, c
->result
);
1973 c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
1975 // And another direct backend request.
1976 TestCompletionCallback cb2
;
1977 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1978 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1980 // Just to make sure that everything is still pending.
1981 base::MessageLoop::current()->RunUntilIdle();
1983 // The request should be queued.
1984 EXPECT_FALSE(c
->callback
.have_result());
1986 // Generate the callback.
1987 factory
->FinishCreation();
1988 rv
= cb
.WaitForResult();
1990 // The cache should be gone by now.
1991 base::MessageLoop::current()->RunUntilIdle();
1992 EXPECT_EQ(OK
, c
->callback
.GetResult(c
->result
));
1993 EXPECT_FALSE(cb2
.have_result());
1996 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
1997 MockHttpCache cache
;
1999 // write to the cache
2000 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
2002 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2003 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2004 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2006 // Get the same URL again, but this time we expect it to result
2007 // in a conditional request.
2008 BoundTestNetLog log
;
2009 LoadTimingInfo load_timing_info
;
2010 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
2011 log
.bound(), &load_timing_info
);
2013 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2014 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2015 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2016 TestLoadTimingNetworkRequest(load_timing_info
);
2019 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo
* request
,
2020 std::string
* response_status
,
2021 std::string
* response_headers
,
2022 std::string
* response_data
) {
2024 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2025 response_status
->assign("HTTP/1.1 304 Not Modified");
2026 response_headers
->assign(kETagGET_Transaction
.response_headers
);
2027 response_data
->clear();
2030 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
2031 MockHttpCache cache
;
2033 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2035 // write to the cache
2036 RunTransactionTest(cache
.http_cache(), transaction
);
2038 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2039 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2040 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2042 // Get the same URL again, but this time we expect it to result
2043 // in a conditional request.
2044 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2045 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
2046 BoundTestNetLog log
;
2047 LoadTimingInfo load_timing_info
;
2048 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2051 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2052 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2053 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2054 TestLoadTimingNetworkRequest(load_timing_info
);
2057 class RevalidationServer
{
2059 RevalidationServer() {
2060 s_etag_used_
= false;
2061 s_last_modified_used_
= false;
2064 bool EtagUsed() { return s_etag_used_
; }
2065 bool LastModifiedUsed() { return s_last_modified_used_
; }
2067 static void Handler(const HttpRequestInfo
* request
,
2068 std::string
* response_status
,
2069 std::string
* response_headers
,
2070 std::string
* response_data
);
2073 static bool s_etag_used_
;
2074 static bool s_last_modified_used_
;
2076 bool RevalidationServer::s_etag_used_
= false;
2077 bool RevalidationServer::s_last_modified_used_
= false;
2079 void RevalidationServer::Handler(const HttpRequestInfo
* request
,
2080 std::string
* response_status
,
2081 std::string
* response_headers
,
2082 std::string
* response_data
) {
2083 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
))
2084 s_etag_used_
= true;
2086 if (request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfModifiedSince
)) {
2087 s_last_modified_used_
= true;
2090 if (s_etag_used_
|| s_last_modified_used_
) {
2091 response_status
->assign("HTTP/1.1 304 Not Modified");
2092 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2093 response_data
->clear();
2095 response_status
->assign(kTypicalGET_Transaction
.status
);
2096 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2097 response_data
->assign(kTypicalGET_Transaction
.data
);
2101 // Tests revalidation after a vary match.
2102 TEST(HttpCache
, GET_ValidateCache_VaryMatch
) {
2103 MockHttpCache cache
;
2105 // Write to the cache.
2106 MockTransaction
transaction(kTypicalGET_Transaction
);
2107 transaction
.request_headers
= "Foo: bar\r\n";
2108 transaction
.response_headers
=
2109 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2110 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2112 "Cache-Control: max-age=0\n"
2114 AddMockTransaction(&transaction
);
2115 RunTransactionTest(cache
.http_cache(), transaction
);
2117 // Read from the cache.
2118 RevalidationServer server
;
2119 transaction
.handler
= server
.Handler
;
2120 BoundTestNetLog log
;
2121 LoadTimingInfo load_timing_info
;
2122 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2125 EXPECT_TRUE(server
.EtagUsed());
2126 EXPECT_TRUE(server
.LastModifiedUsed());
2127 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2128 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2129 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2130 TestLoadTimingNetworkRequest(load_timing_info
);
2131 RemoveMockTransaction(&transaction
);
2134 // Tests revalidation after a vary mismatch if etag is present.
2135 TEST(HttpCache
, GET_ValidateCache_VaryMismatch
) {
2136 MockHttpCache cache
;
2138 // Write to the cache.
2139 MockTransaction
transaction(kTypicalGET_Transaction
);
2140 transaction
.request_headers
= "Foo: bar\r\n";
2141 transaction
.response_headers
=
2142 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2143 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2145 "Cache-Control: max-age=0\n"
2147 AddMockTransaction(&transaction
);
2148 RunTransactionTest(cache
.http_cache(), transaction
);
2150 // Read from the cache and revalidate the entry.
2151 RevalidationServer server
;
2152 transaction
.handler
= server
.Handler
;
2153 transaction
.request_headers
= "Foo: none\r\n";
2154 BoundTestNetLog log
;
2155 LoadTimingInfo load_timing_info
;
2156 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2159 EXPECT_TRUE(server
.EtagUsed());
2160 EXPECT_FALSE(server
.LastModifiedUsed());
2161 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2162 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2163 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2164 TestLoadTimingNetworkRequest(load_timing_info
);
2165 RemoveMockTransaction(&transaction
);
2168 // Tests lack of revalidation after a vary mismatch and no etag.
2169 TEST(HttpCache
, GET_DontValidateCache_VaryMismatch
) {
2170 MockHttpCache cache
;
2172 // Write to the cache.
2173 MockTransaction
transaction(kTypicalGET_Transaction
);
2174 transaction
.request_headers
= "Foo: bar\r\n";
2175 transaction
.response_headers
=
2176 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2177 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2178 "Cache-Control: max-age=0\n"
2180 AddMockTransaction(&transaction
);
2181 RunTransactionTest(cache
.http_cache(), transaction
);
2183 // Read from the cache and don't revalidate the entry.
2184 RevalidationServer server
;
2185 transaction
.handler
= server
.Handler
;
2186 transaction
.request_headers
= "Foo: none\r\n";
2187 BoundTestNetLog log
;
2188 LoadTimingInfo load_timing_info
;
2189 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2192 EXPECT_FALSE(server
.EtagUsed());
2193 EXPECT_FALSE(server
.LastModifiedUsed());
2194 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2195 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2196 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2197 TestLoadTimingNetworkRequest(load_timing_info
);
2198 RemoveMockTransaction(&transaction
);
2201 // Tests that a new vary header provided when revalidating an entry is saved.
2202 TEST(HttpCache
, GET_ValidateCache_VaryMatch_UpdateVary
) {
2203 MockHttpCache cache
;
2205 // Write to the cache.
2206 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2207 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2208 transaction
.response_headers
=
2210 "Cache-Control: max-age=0\n"
2212 RunTransactionTest(cache
.http_cache(), transaction
);
2214 // Validate the entry and change the vary field in the response.
2215 transaction
.request_headers
= "Foo: bar\r\n Name: none\r\n";
2216 transaction
.status
= "HTTP/1.1 304 Not Modified";
2217 transaction
.response_headers
=
2219 "Cache-Control: max-age=3600\n"
2221 RunTransactionTest(cache
.http_cache(), transaction
);
2223 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2224 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2225 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2227 // Make sure that the ActiveEntry is gone.
2228 base::RunLoop().RunUntilIdle();
2230 // Generate a vary mismatch.
2231 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2232 RunTransactionTest(cache
.http_cache(), transaction
);
2234 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2235 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2236 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2239 // Tests that new request headers causing a vary mismatch are paired with the
2240 // new response when the server says the old response can be used.
2241 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_UpdateRequestHeader
) {
2242 MockHttpCache cache
;
2244 // Write to the cache.
2245 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2246 transaction
.request_headers
= "Foo: bar\r\n";
2247 transaction
.response_headers
=
2249 "Cache-Control: max-age=3600\n"
2251 RunTransactionTest(cache
.http_cache(), transaction
);
2253 // Vary-mismatch validation receives 304.
2254 transaction
.request_headers
= "Foo: none\r\n";
2255 transaction
.status
= "HTTP/1.1 304 Not Modified";
2256 RunTransactionTest(cache
.http_cache(), transaction
);
2258 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2259 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2260 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2262 // Make sure that the ActiveEntry is gone.
2263 base::RunLoop().RunUntilIdle();
2265 // Generate a vary mismatch.
2266 transaction
.request_headers
= "Foo: bar\r\n";
2267 RunTransactionTest(cache
.http_cache(), transaction
);
2269 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2270 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2271 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2274 // Tests that a 304 without vary headers doesn't delete the previously stored
2275 // vary data after a vary match revalidation.
2276 TEST(HttpCache
, GET_ValidateCache_VaryMatch_DontDeleteVary
) {
2277 MockHttpCache cache
;
2279 // Write to the cache.
2280 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2281 transaction
.request_headers
= "Foo: bar\r\n";
2282 transaction
.response_headers
=
2284 "Cache-Control: max-age=0\n"
2286 RunTransactionTest(cache
.http_cache(), transaction
);
2288 // Validate the entry and remove the vary field in the response.
2289 transaction
.status
= "HTTP/1.1 304 Not Modified";
2290 transaction
.response_headers
=
2292 "Cache-Control: max-age=3600\n";
2293 RunTransactionTest(cache
.http_cache(), transaction
);
2295 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2296 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2297 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2299 // Make sure that the ActiveEntry is gone.
2300 base::RunLoop().RunUntilIdle();
2302 // Generate a vary mismatch.
2303 transaction
.request_headers
= "Foo: none\r\n";
2304 RunTransactionTest(cache
.http_cache(), transaction
);
2306 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2307 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2308 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2311 // Tests that a 304 without vary headers doesn't delete the previously stored
2312 // vary data after a vary mismatch.
2313 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_DontDeleteVary
) {
2314 MockHttpCache cache
;
2316 // Write to the cache.
2317 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2318 transaction
.request_headers
= "Foo: bar\r\n";
2319 transaction
.response_headers
=
2321 "Cache-Control: max-age=3600\n"
2323 RunTransactionTest(cache
.http_cache(), transaction
);
2325 // Vary-mismatch validation receives 304 and no vary header.
2326 transaction
.request_headers
= "Foo: none\r\n";
2327 transaction
.status
= "HTTP/1.1 304 Not Modified";
2328 transaction
.response_headers
=
2330 "Cache-Control: max-age=3600\n";
2331 RunTransactionTest(cache
.http_cache(), transaction
);
2333 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2334 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2335 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2337 // Make sure that the ActiveEntry is gone.
2338 base::RunLoop().RunUntilIdle();
2340 // Generate a vary mismatch.
2341 transaction
.request_headers
= "Foo: bar\r\n";
2342 RunTransactionTest(cache
.http_cache(), transaction
);
2344 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2345 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2346 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2349 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo
* request
,
2350 std::string
* response_status
,
2351 std::string
* response_headers
,
2352 std::string
* response_data
) {
2354 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2357 TEST(HttpCache
, ETagGET_Http10
) {
2358 MockHttpCache cache
;
2360 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2361 transaction
.status
= "HTTP/1.0 200 OK";
2363 // Write to the cache.
2364 RunTransactionTest(cache
.http_cache(), transaction
);
2366 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2367 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2368 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2370 // Get the same URL again, without generating a conditional request.
2371 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2372 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2373 RunTransactionTest(cache
.http_cache(), transaction
);
2375 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2376 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2377 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2380 TEST(HttpCache
, ETagGET_Http10_Range
) {
2381 MockHttpCache cache
;
2383 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2384 transaction
.status
= "HTTP/1.0 200 OK";
2386 // Write to the cache.
2387 RunTransactionTest(cache
.http_cache(), transaction
);
2389 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2390 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2391 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2393 // Get the same URL again, but use a byte range request.
2394 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2395 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2396 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2397 RunTransactionTest(cache
.http_cache(), transaction
);
2399 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2400 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2401 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2404 static void ETagGet_ConditionalRequest_NoStore_Handler(
2405 const HttpRequestInfo
* request
,
2406 std::string
* response_status
,
2407 std::string
* response_headers
,
2408 std::string
* response_data
) {
2410 request
->extra_headers
.HasHeader(HttpRequestHeaders::kIfNoneMatch
));
2411 response_status
->assign("HTTP/1.1 304 Not Modified");
2412 response_headers
->assign("Cache-Control: no-store\n");
2413 response_data
->clear();
2416 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2417 MockHttpCache cache
;
2419 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2421 // Write to the cache.
2422 RunTransactionTest(cache
.http_cache(), transaction
);
2424 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2425 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2426 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2428 // Get the same URL again, but this time we expect it to result
2429 // in a conditional request.
2430 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
2431 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2432 RunTransactionTest(cache
.http_cache(), transaction
);
2434 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2435 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2436 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2438 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2440 // Write to the cache again. This should create a new entry.
2441 RunTransactionTest(cache
.http_cache(), transaction2
);
2443 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2444 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2445 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2448 // Helper that does 4 requests using HttpCache:
2450 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2451 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2452 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2454 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2456 static void ConditionalizedRequestUpdatesCacheHelper(
2457 const Response
& net_response_1
,
2458 const Response
& net_response_2
,
2459 const Response
& cached_response_2
,
2460 const char* extra_request_headers
) {
2461 MockHttpCache cache
;
2463 // The URL we will be requesting.
2464 const char kUrl
[] = "http://foobar.com/main.css";
2466 // Junk network response.
2467 static const Response kUnexpectedResponse
= {
2468 "HTTP/1.1 500 Unexpected",
2469 "Server: unexpected_header",
2473 // We will control the network layer's responses for |kUrl| using
2474 // |mock_network_response|.
2475 MockTransaction mock_network_response
= { 0 };
2476 mock_network_response
.url
= kUrl
;
2477 AddMockTransaction(&mock_network_response
);
2479 // Request |kUrl| for the first time. It should hit the network and
2480 // receive |kNetResponse1|, which it saves into the HTTP cache.
2482 MockTransaction request
= { 0 };
2484 request
.method
= "GET";
2485 request
.request_headers
= "";
2487 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2488 net_response_1
.AssignTo(&request
); // Expected result.
2490 std::string response_headers
;
2491 RunTransactionTestWithResponse(
2492 cache
.http_cache(), request
, &response_headers
);
2494 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2495 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2496 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2497 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2499 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2500 // cache, so we don't hit the network.
2502 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2504 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2505 net_response_1
.AssignTo(&request
); // Expected result.
2507 RunTransactionTestWithResponse(
2508 cache
.http_cache(), request
, &response_headers
);
2510 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2511 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2512 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2513 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2515 // Request |kUrl| yet again, but this time give the request an
2516 // "If-Modified-Since" header. This will cause the request to re-hit the
2517 // network. However now the network response is going to be
2518 // different -- this simulates a change made to the CSS file.
2520 request
.request_headers
= extra_request_headers
;
2521 request
.load_flags
= LOAD_NORMAL
;
2523 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2524 net_response_2
.AssignTo(&request
); // Expected result.
2526 RunTransactionTestWithResponse(
2527 cache
.http_cache(), request
, &response_headers
);
2529 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2530 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2531 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2532 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2534 // Finally, request |kUrl| again. This request should be serviced from
2535 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2536 // and NOT |kNetResponse1|. The previous step should have replaced the
2537 // value in the cache with the modified response.
2539 request
.request_headers
= "";
2540 request
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2542 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2543 cached_response_2
.AssignTo(&request
); // Expected result.
2545 RunTransactionTestWithResponse(
2546 cache
.http_cache(), request
, &response_headers
);
2548 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2549 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2550 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2551 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2553 RemoveMockTransaction(&mock_network_response
);
2556 // Check that when an "if-modified-since" header is attached
2557 // to the request, the result still updates the cached entry.
2558 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2559 // First network response for |kUrl|.
2560 static const Response kNetResponse1
= {
2562 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2563 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2567 // Second network response for |kUrl|.
2568 static const Response kNetResponse2
= {
2570 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2571 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2575 const char extra_headers
[] =
2576 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2578 ConditionalizedRequestUpdatesCacheHelper(
2579 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2582 // Check that when an "if-none-match" header is attached
2583 // to the request, the result updates the cached entry.
2584 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2585 // First network response for |kUrl|.
2586 static const Response kNetResponse1
= {
2588 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2590 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2594 // Second network response for |kUrl|.
2595 static const Response kNetResponse2
= {
2597 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2599 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2603 const char extra_headers
[] = "If-None-Match: \"ETAG1\"\r\n";
2605 ConditionalizedRequestUpdatesCacheHelper(
2606 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2609 // Check that when an "if-modified-since" header is attached
2610 // to a request, the 304 (not modified result) result updates the cached
2611 // headers, and the 304 response is returned rather than the cached response.
2612 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2613 // First network response for |kUrl|.
2614 static const Response kNetResponse1
= {
2616 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2618 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2622 // Second network response for |kUrl|.
2623 static const Response kNetResponse2
= {
2624 "HTTP/1.1 304 Not Modified",
2625 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2627 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2631 static const Response kCachedResponse2
= {
2633 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2635 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2639 const char extra_headers
[] =
2640 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2642 ConditionalizedRequestUpdatesCacheHelper(
2643 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2646 // Test that when doing an externally conditionalized if-modified-since
2647 // and there is no corresponding cache entry, a new cache entry is NOT
2648 // created (304 response).
2649 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2650 MockHttpCache cache
;
2652 const char kUrl
[] = "http://foobar.com/main.css";
2654 static const Response kNetResponse
= {
2655 "HTTP/1.1 304 Not Modified",
2656 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2657 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2661 const char kExtraRequestHeaders
[] =
2662 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2664 // We will control the network layer's responses for |kUrl| using
2665 // |mock_network_response|.
2666 MockTransaction mock_network_response
= { 0 };
2667 mock_network_response
.url
= kUrl
;
2668 AddMockTransaction(&mock_network_response
);
2670 MockTransaction request
= { 0 };
2672 request
.method
= "GET";
2673 request
.request_headers
= kExtraRequestHeaders
;
2675 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2676 kNetResponse
.AssignTo(&request
); // Expected result.
2678 std::string response_headers
;
2679 RunTransactionTestWithResponse(
2680 cache
.http_cache(), request
, &response_headers
);
2682 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2683 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2684 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2685 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2687 RemoveMockTransaction(&mock_network_response
);
2690 // Test that when doing an externally conditionalized if-modified-since
2691 // and there is no corresponding cache entry, a new cache entry is NOT
2692 // created (200 response).
2693 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2694 MockHttpCache cache
;
2696 const char kUrl
[] = "http://foobar.com/main.css";
2698 static const Response kNetResponse
= {
2700 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2701 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2705 const char kExtraRequestHeaders
[] =
2706 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2708 // We will control the network layer's responses for |kUrl| using
2709 // |mock_network_response|.
2710 MockTransaction mock_network_response
= { 0 };
2711 mock_network_response
.url
= kUrl
;
2712 AddMockTransaction(&mock_network_response
);
2714 MockTransaction request
= { 0 };
2716 request
.method
= "GET";
2717 request
.request_headers
= kExtraRequestHeaders
;
2719 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2720 kNetResponse
.AssignTo(&request
); // Expected result.
2722 std::string response_headers
;
2723 RunTransactionTestWithResponse(
2724 cache
.http_cache(), request
, &response_headers
);
2726 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2727 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2728 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2729 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2731 RemoveMockTransaction(&mock_network_response
);
2734 // Test that when doing an externally conditionalized if-modified-since
2735 // if the date does not match the cache entry's last-modified date,
2736 // then we do NOT use the response (304) to update the cache.
2737 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2738 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2739 static const Response kNetResponse1
= {
2741 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2743 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2747 // Second network response for |kUrl|.
2748 static const Response kNetResponse2
= {
2749 "HTTP/1.1 304 Not Modified",
2750 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2752 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2756 // This is two days in the future from the original response's last-modified
2758 const char kExtraRequestHeaders
[] =
2759 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2761 ConditionalizedRequestUpdatesCacheHelper(
2762 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2765 // Test that when doing an externally conditionalized if-none-match
2766 // if the etag does not match the cache entry's etag, then we do not use the
2767 // response (304) to update the cache.
2768 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2769 static const Response kNetResponse1
= {
2771 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2773 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2777 // Second network response for |kUrl|.
2778 static const Response kNetResponse2
= {
2779 "HTTP/1.1 304 Not Modified",
2780 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2782 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2786 // Different etag from original response.
2787 const char kExtraRequestHeaders
[] = "If-None-Match: \"Foo2\"\r\n";
2789 ConditionalizedRequestUpdatesCacheHelper(
2790 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2793 // Test that doing an externally conditionalized request with both if-none-match
2794 // and if-modified-since updates the cache.
2795 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2796 static const Response kNetResponse1
= {
2798 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2800 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2804 // Second network response for |kUrl|.
2805 static const Response kNetResponse2
= {
2807 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2809 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2813 const char kExtraRequestHeaders
[] =
2814 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2815 "If-None-Match: \"Foo1\"\r\n";
2817 ConditionalizedRequestUpdatesCacheHelper(
2818 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2821 // Test that doing an externally conditionalized request with both if-none-match
2822 // and if-modified-since does not update the cache with only one match.
2823 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2824 static const Response kNetResponse1
= {
2826 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2828 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2832 // Second network response for |kUrl|.
2833 static const Response kNetResponse2
= {
2835 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2837 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2841 // The etag doesn't match what we have stored.
2842 const char kExtraRequestHeaders
[] =
2843 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2844 "If-None-Match: \"Foo2\"\r\n";
2846 ConditionalizedRequestUpdatesCacheHelper(
2847 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2850 // Test that doing an externally conditionalized request with both if-none-match
2851 // and if-modified-since does not update the cache with only one match.
2852 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2853 static const Response kNetResponse1
= {
2855 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2857 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2861 // Second network response for |kUrl|.
2862 static const Response kNetResponse2
= {
2864 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2866 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2870 // The modification date doesn't match what we have stored.
2871 const char kExtraRequestHeaders
[] =
2872 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2873 "If-None-Match: \"Foo1\"\r\n";
2875 ConditionalizedRequestUpdatesCacheHelper(
2876 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2879 TEST(HttpCache
, UrlContainingHash
) {
2880 MockHttpCache cache
;
2882 // Do a typical GET request -- should write an entry into our cache.
2883 MockTransaction
trans(kTypicalGET_Transaction
);
2884 RunTransactionTest(cache
.http_cache(), trans
);
2886 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2887 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2888 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2890 // Request the same URL, but this time with a reference section (hash).
2891 // Since the cache key strips the hash sections, this should be a cache hit.
2892 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2893 trans
.url
= url_with_hash
.c_str();
2894 trans
.load_flags
= LOAD_ONLY_FROM_CACHE
;
2896 RunTransactionTest(cache
.http_cache(), trans
);
2898 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2899 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2900 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2903 // Tests that we skip the cache for POST requests that do not have an upload
2905 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2906 MockHttpCache cache
;
2908 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2910 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2911 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2912 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2915 // Tests POST handling with a disabled cache (no DCHECK).
2916 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2917 MockHttpCache cache
;
2918 cache
.http_cache()->set_mode(HttpCache::Mode::DISABLE
);
2920 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2922 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2923 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2924 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2927 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2928 MockHttpCache cache
;
2930 MockTransaction
transaction(kSimplePOST_Transaction
);
2931 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2933 MockHttpRequest
request(transaction
);
2934 TestCompletionCallback callback
;
2936 scoped_ptr
<HttpTransaction
> trans
;
2937 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
2938 ASSERT_TRUE(trans
.get());
2940 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
2941 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
2945 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2946 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2947 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2950 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2951 MockHttpCache cache
;
2953 // Test that we hit the cache for POST requests.
2955 MockTransaction
transaction(kSimplePOST_Transaction
);
2957 const int64 kUploadId
= 1; // Just a dummy value.
2959 ScopedVector
<UploadElementReader
> element_readers
;
2960 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2961 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2963 MockHttpRequest
request(transaction
);
2964 request
.upload_data_stream
= &upload_data_stream
;
2966 // Populate the cache.
2967 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2969 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2970 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2971 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2974 request
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
2975 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2977 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2978 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2979 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2982 // Test that we don't hit the cache for POST requests if there is a byte range.
2983 TEST(HttpCache
, SimplePOST_WithRanges
) {
2984 MockHttpCache cache
;
2986 MockTransaction
transaction(kSimplePOST_Transaction
);
2987 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2989 const int64 kUploadId
= 1; // Just a dummy value.
2991 ScopedVector
<UploadElementReader
> element_readers
;
2992 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
2993 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2996 MockHttpRequest
request(transaction
);
2997 request
.upload_data_stream
= &upload_data_stream
;
2999 // Attempt to populate the cache.
3000 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3002 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3003 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3004 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3007 // Tests that a POST is cached separately from a previously cached GET.
3008 TEST(HttpCache
, SimplePOST_SeparateCache
) {
3009 MockHttpCache cache
;
3011 ScopedVector
<UploadElementReader
> element_readers
;
3012 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3013 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3015 MockTransaction
transaction(kSimplePOST_Transaction
);
3016 MockHttpRequest
req1(transaction
);
3017 req1
.upload_data_stream
= &upload_data_stream
;
3019 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3021 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3022 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3023 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3025 transaction
.method
= "GET";
3026 MockHttpRequest
req2(transaction
);
3028 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3030 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3031 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3032 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3035 // Tests that a successful POST invalidates a previously cached GET.
3036 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
3037 MockHttpCache cache
;
3039 MockTransaction
transaction(kSimpleGET_Transaction
);
3040 AddMockTransaction(&transaction
);
3041 MockHttpRequest
req1(transaction
);
3043 // Attempt to populate the cache.
3044 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3046 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3047 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3048 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3050 ScopedVector
<UploadElementReader
> element_readers
;
3051 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3052 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3054 transaction
.method
= "POST";
3055 transaction
.status
= "HTTP/1.1 205 No Content";
3056 MockHttpRequest
req2(transaction
);
3057 req2
.upload_data_stream
= &upload_data_stream
;
3059 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3061 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3062 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3063 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3065 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3067 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3068 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3069 EXPECT_EQ(3, cache
.disk_cache()->create_count());
3070 RemoveMockTransaction(&transaction
);
3073 // Tests that a successful POST invalidates a previously cached GET, even when
3074 // there is no upload identifier.
3075 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
3076 MockHttpCache cache
;
3078 MockTransaction
transaction(kSimpleGET_Transaction
);
3079 AddMockTransaction(&transaction
);
3080 MockHttpRequest
req1(transaction
);
3082 // Attempt to populate the cache.
3083 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3085 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3086 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3087 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3089 ScopedVector
<UploadElementReader
> element_readers
;
3090 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3091 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3093 transaction
.method
= "POST";
3094 transaction
.status
= "HTTP/1.1 205 No Content";
3095 MockHttpRequest
req2(transaction
);
3096 req2
.upload_data_stream
= &upload_data_stream
;
3098 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3100 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3101 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3102 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3104 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3106 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3107 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3108 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3109 RemoveMockTransaction(&transaction
);
3112 // Tests that processing a POST before creating the backend doesn't crash.
3113 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
3114 // This will initialize a cache object with NULL backend.
3115 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
3116 factory
->set_fail(true);
3117 factory
->FinishCreation();
3118 MockHttpCache
cache(factory
);
3120 ScopedVector
<UploadElementReader
> element_readers
;
3121 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3122 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3124 MockTransaction
transaction(kSimplePOST_Transaction
);
3125 AddMockTransaction(&transaction
);
3126 MockHttpRequest
req(transaction
);
3127 req
.upload_data_stream
= &upload_data_stream
;
3129 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
3131 RemoveMockTransaction(&transaction
);
3134 // Tests that we don't invalidate entries as a result of a failed POST.
3135 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
3136 MockHttpCache cache
;
3138 MockTransaction
transaction(kSimpleGET_Transaction
);
3139 AddMockTransaction(&transaction
);
3140 MockHttpRequest
req1(transaction
);
3142 // Attempt to populate the cache.
3143 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3145 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3146 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3147 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3149 ScopedVector
<UploadElementReader
> element_readers
;
3150 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3151 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3153 transaction
.method
= "POST";
3154 transaction
.status
= "HTTP/1.1 100 Continue";
3155 MockHttpRequest
req2(transaction
);
3156 req2
.upload_data_stream
= &upload_data_stream
;
3158 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3160 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3161 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3162 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3164 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3166 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3167 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3168 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3169 RemoveMockTransaction(&transaction
);
3172 // Tests that a HEAD request is not cached by itself.
3173 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3174 MockHttpCache cache
;
3175 MockTransaction
transaction(kSimplePOST_Transaction
);
3176 AddMockTransaction(&transaction
);
3177 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3178 transaction
.method
= "HEAD";
3180 MockHttpRequest
request(transaction
);
3181 TestCompletionCallback callback
;
3183 scoped_ptr
<HttpTransaction
> trans
;
3184 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
3185 ASSERT_TRUE(trans
.get());
3187 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
3188 ASSERT_EQ(ERR_CACHE_MISS
, callback
.GetResult(rv
));
3192 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3193 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3194 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3195 RemoveMockTransaction(&transaction
);
3198 // Tests that a HEAD request is served from a cached GET.
3199 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3200 MockHttpCache cache
;
3201 MockTransaction
transaction(kSimpleGET_Transaction
);
3202 AddMockTransaction(&transaction
);
3204 // Populate the cache.
3205 RunTransactionTest(cache
.http_cache(), transaction
);
3207 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3208 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3209 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3212 transaction
.method
= "HEAD";
3213 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3214 transaction
.data
= "";
3215 RunTransactionTest(cache
.http_cache(), transaction
);
3217 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3218 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3219 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3220 RemoveMockTransaction(&transaction
);
3223 // Tests that a read-only request served from the cache preserves CL.
3224 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3225 MockHttpCache cache
;
3226 MockTransaction
transaction(kSimpleGET_Transaction
);
3227 AddMockTransaction(&transaction
);
3228 transaction
.response_headers
= "Content-Length: 42\n";
3230 // Populate the cache.
3231 RunTransactionTest(cache
.http_cache(), transaction
);
3234 transaction
.method
= "HEAD";
3235 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3236 transaction
.data
= "";
3237 std::string headers
;
3239 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3241 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3242 RemoveMockTransaction(&transaction
);
3245 // Tests that a read-write request served from the cache preserves CL.
3246 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3247 MockHttpCache cache
;
3248 MockTransaction
transaction(kETagGET_Transaction
);
3249 AddMockTransaction(&transaction
);
3250 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3251 server_headers
.append("Content-Length: 42\n");
3252 transaction
.response_headers
= server_headers
.data();
3254 // Populate the cache.
3255 RunTransactionTest(cache
.http_cache(), transaction
);
3258 transaction
.method
= "HEAD";
3259 transaction
.data
= "";
3260 std::string headers
;
3262 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3264 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3265 RemoveMockTransaction(&transaction
);
3268 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3269 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3270 MockHttpCache cache
;
3271 MockTransaction
transaction(kSimpleGET_Transaction
);
3272 AddMockTransaction(&transaction
);
3274 // Populate the cache.
3275 RunTransactionTest(cache
.http_cache(), transaction
);
3278 transaction
.method
= "HEAD";
3279 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3280 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3281 transaction
.return_code
= ERR_CACHE_MISS
;
3282 RunTransactionTest(cache
.http_cache(), transaction
);
3284 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3285 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3286 RemoveMockTransaction(&transaction
);
3289 // Tests that a HEAD request can be served from a partialy cached resource.
3290 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3291 MockHttpCache cache
;
3292 AddMockTransaction(&kRangeGET_TransactionOK
);
3294 // Write to the cache (40-49).
3295 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3296 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3298 MockTransaction
transaction(kSimpleGET_Transaction
);
3300 transaction
.url
= kRangeGET_TransactionOK
.url
;
3301 transaction
.method
= "HEAD";
3302 transaction
.data
= "";
3303 AddMockTransaction(&transaction
);
3304 std::string headers
;
3307 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3309 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3310 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3311 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3312 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3313 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3314 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3315 RemoveMockTransaction(&transaction
);
3318 // Tests that a HEAD request can be served from a truncated resource.
3319 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3320 MockHttpCache cache
;
3321 AddMockTransaction(&kRangeGET_TransactionOK
);
3323 std::string
raw_headers("HTTP/1.1 200 OK\n"
3324 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3326 "Accept-Ranges: bytes\n"
3327 "Content-Length: 80\n");
3328 CreateTruncatedEntry(raw_headers
, &cache
);
3329 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3331 MockTransaction
transaction(kSimpleGET_Transaction
);
3333 transaction
.url
= kRangeGET_TransactionOK
.url
;
3334 transaction
.method
= "HEAD";
3335 transaction
.data
= "";
3336 AddMockTransaction(&transaction
);
3337 std::string headers
;
3340 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3342 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3343 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3344 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3345 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3346 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3347 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3348 RemoveMockTransaction(&transaction
);
3351 // Tests that a HEAD request updates the cached response.
3352 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3353 MockHttpCache cache
;
3354 MockTransaction
transaction(kTypicalGET_Transaction
);
3355 AddMockTransaction(&transaction
);
3357 // Populate the cache.
3358 RunTransactionTest(cache
.http_cache(), transaction
);
3360 // Update the cache.
3361 transaction
.method
= "HEAD";
3362 transaction
.response_headers
= "Foo: bar\n";
3363 transaction
.data
= "";
3364 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3365 std::string headers
;
3366 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3367 RemoveMockTransaction(&transaction
);
3369 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3370 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3372 MockTransaction
transaction2(kTypicalGET_Transaction
);
3373 AddMockTransaction(&transaction2
);
3375 // Make sure we are done with the previous transaction.
3376 base::MessageLoop::current()->RunUntilIdle();
3378 // Load from the cache.
3379 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3380 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3382 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3383 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3384 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3385 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3386 RemoveMockTransaction(&transaction2
);
3389 // Tests that an externally conditionalized HEAD request updates the cache.
3390 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3391 MockHttpCache cache
;
3392 MockTransaction
transaction(kTypicalGET_Transaction
);
3393 AddMockTransaction(&transaction
);
3395 // Populate the cache.
3396 RunTransactionTest(cache
.http_cache(), transaction
);
3398 // Update the cache.
3399 transaction
.method
= "HEAD";
3400 transaction
.request_headers
=
3401 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3402 transaction
.response_headers
= "Foo: bar\n";
3403 transaction
.data
= "";
3404 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3405 std::string headers
;
3406 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3407 RemoveMockTransaction(&transaction
);
3409 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3410 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3412 MockTransaction
transaction2(kTypicalGET_Transaction
);
3413 AddMockTransaction(&transaction2
);
3415 // Make sure we are done with the previous transaction.
3416 base::MessageLoop::current()->RunUntilIdle();
3418 // Load from the cache.
3419 transaction2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3420 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3422 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3423 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3424 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3425 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3426 RemoveMockTransaction(&transaction2
);
3429 // Tests that a HEAD request invalidates an old cached entry.
3430 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3431 MockHttpCache cache
;
3432 MockTransaction
transaction(kTypicalGET_Transaction
);
3433 AddMockTransaction(&transaction
);
3435 // Populate the cache.
3436 RunTransactionTest(cache
.http_cache(), transaction
);
3438 // Update the cache.
3439 transaction
.method
= "HEAD";
3440 transaction
.data
= "";
3441 RunTransactionTest(cache
.http_cache(), transaction
);
3442 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3444 // Load from the cache.
3445 transaction
.method
= "GET";
3446 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
3447 transaction
.return_code
= ERR_CACHE_MISS
;
3448 RunTransactionTest(cache
.http_cache(), transaction
);
3450 RemoveMockTransaction(&transaction
);
3453 // Tests that we do not cache the response of a PUT.
3454 TEST(HttpCache
, SimplePUT_Miss
) {
3455 MockHttpCache cache
;
3457 MockTransaction
transaction(kSimplePOST_Transaction
);
3458 transaction
.method
= "PUT";
3460 ScopedVector
<UploadElementReader
> element_readers
;
3461 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3462 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3464 MockHttpRequest
request(transaction
);
3465 request
.upload_data_stream
= &upload_data_stream
;
3467 // Attempt to populate the cache.
3468 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3470 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3471 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3472 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3475 // Tests that we invalidate entries as a result of a PUT.
3476 TEST(HttpCache
, SimplePUT_Invalidate
) {
3477 MockHttpCache cache
;
3479 MockTransaction
transaction(kSimpleGET_Transaction
);
3480 MockHttpRequest
req1(transaction
);
3482 // Attempt to populate the cache.
3483 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3485 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3486 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3487 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3489 ScopedVector
<UploadElementReader
> element_readers
;
3490 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3491 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3493 transaction
.method
= "PUT";
3494 MockHttpRequest
req2(transaction
);
3495 req2
.upload_data_stream
= &upload_data_stream
;
3497 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3499 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3500 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3501 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3503 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3505 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3506 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3507 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3510 // Tests that we invalidate entries as a result of a PUT.
3511 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3512 MockHttpCache cache
;
3514 MockTransaction
transaction(kSimpleGET_Transaction
);
3515 AddMockTransaction(&transaction
);
3516 MockHttpRequest
req1(transaction
);
3518 // Attempt to populate the cache.
3519 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3521 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3522 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3523 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3525 ScopedVector
<UploadElementReader
> element_readers
;
3526 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3527 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3529 transaction
.method
= "PUT";
3530 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3531 MockHttpRequest
req2(transaction
);
3532 req2
.upload_data_stream
= &upload_data_stream
;
3534 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3536 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3537 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3538 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3540 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3542 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3543 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3544 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3545 RemoveMockTransaction(&transaction
);
3548 // Tests that we don't invalidate entries as a result of a failed PUT.
3549 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3550 MockHttpCache cache
;
3552 MockTransaction
transaction(kSimpleGET_Transaction
);
3553 AddMockTransaction(&transaction
);
3554 MockHttpRequest
req1(transaction
);
3556 // Attempt to populate the cache.
3557 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3559 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3560 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3561 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3563 ScopedVector
<UploadElementReader
> element_readers
;
3564 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3565 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3567 transaction
.method
= "PUT";
3568 transaction
.status
= "HTTP/1.1 404 Not Found";
3569 MockHttpRequest
req2(transaction
);
3570 req2
.upload_data_stream
= &upload_data_stream
;
3572 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3574 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3575 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3576 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3578 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3580 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3581 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3582 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3583 RemoveMockTransaction(&transaction
);
3586 // Tests that we do not cache the response of a DELETE.
3587 TEST(HttpCache
, SimpleDELETE_Miss
) {
3588 MockHttpCache cache
;
3590 MockTransaction
transaction(kSimplePOST_Transaction
);
3591 transaction
.method
= "DELETE";
3593 ScopedVector
<UploadElementReader
> element_readers
;
3594 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3595 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3597 MockHttpRequest
request(transaction
);
3598 request
.upload_data_stream
= &upload_data_stream
;
3600 // Attempt to populate the cache.
3601 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3603 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3605 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3608 // Tests that we invalidate entries as a result of a DELETE.
3609 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3610 MockHttpCache cache
;
3612 MockTransaction
transaction(kSimpleGET_Transaction
);
3613 MockHttpRequest
req1(transaction
);
3615 // Attempt to populate the cache.
3616 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3618 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3619 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3620 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3622 ScopedVector
<UploadElementReader
> element_readers
;
3623 element_readers
.push_back(new UploadBytesElementReader("hello", 5));
3624 ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3626 transaction
.method
= "DELETE";
3627 MockHttpRequest
req2(transaction
);
3628 req2
.upload_data_stream
= &upload_data_stream
;
3630 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3632 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3633 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3634 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3636 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3638 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3639 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3640 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3643 // Tests that we invalidate entries as a result of a DELETE.
3644 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3645 MockHttpCache cache
;
3647 MockTransaction
transaction(kSimpleGET_Transaction
);
3648 AddMockTransaction(&transaction
);
3650 // Attempt to populate the cache.
3651 RunTransactionTest(cache
.http_cache(), transaction
);
3653 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3654 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3655 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3657 transaction
.method
= "DELETE";
3658 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3660 RunTransactionTest(cache
.http_cache(), transaction
);
3662 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3663 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3664 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3666 transaction
.method
= "GET";
3667 RunTransactionTest(cache
.http_cache(), transaction
);
3669 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3670 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3671 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3672 RemoveMockTransaction(&transaction
);
3675 // Tests that we don't invalidate entries as a result of a failed DELETE.
3676 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3677 MockHttpCache cache
;
3679 MockTransaction
transaction(kSimpleGET_Transaction
);
3680 AddMockTransaction(&transaction
);
3682 // Attempt to populate the cache.
3683 RunTransactionTest(cache
.http_cache(), transaction
);
3685 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3686 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3687 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3689 transaction
.method
= "DELETE";
3690 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3692 RunTransactionTest(cache
.http_cache(), transaction
);
3694 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3695 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3696 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3698 transaction
.method
= "GET";
3699 transaction
.status
= "HTTP/1.1 200 OK";
3700 RunTransactionTest(cache
.http_cache(), transaction
);
3702 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3703 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3704 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3705 RemoveMockTransaction(&transaction
);
3708 // Tests that we don't invalidate entries after a failed network transaction.
3709 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3710 MockHttpCache cache
;
3712 // Populate the cache.
3713 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3714 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3716 // Fail the network request.
3717 MockTransaction
transaction(kSimpleGET_Transaction
);
3718 transaction
.return_code
= ERR_FAILED
;
3719 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
3721 AddMockTransaction(&transaction
);
3722 RunTransactionTest(cache
.http_cache(), transaction
);
3723 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3724 RemoveMockTransaction(&transaction
);
3726 transaction
.load_flags
= LOAD_ONLY_FROM_CACHE
;
3727 transaction
.return_code
= OK
;
3728 AddMockTransaction(&transaction
);
3729 RunTransactionTest(cache
.http_cache(), transaction
);
3731 // Make sure the transaction didn't reach the network.
3732 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3733 RemoveMockTransaction(&transaction
);
3736 TEST(HttpCache
, RangeGET_SkipsCache
) {
3737 MockHttpCache cache
;
3739 // Test that we skip the cache for range GET requests. Eventually, we will
3740 // want to cache these, but we'll still have cases where skipping the cache
3741 // makes sense, so we want to make sure that it works properly.
3743 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3745 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3746 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3747 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3749 MockTransaction
transaction(kSimpleGET_Transaction
);
3750 transaction
.request_headers
= "If-None-Match: foo\r\n";
3751 RunTransactionTest(cache
.http_cache(), transaction
);
3753 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3754 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3755 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3757 transaction
.request_headers
=
3758 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3759 RunTransactionTest(cache
.http_cache(), transaction
);
3761 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3762 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3763 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3766 // Test that we skip the cache for range requests that include a validation
3768 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3769 MockHttpCache cache
;
3771 MockTransaction
transaction(kRangeGET_Transaction
);
3772 transaction
.request_headers
= "If-None-Match: foo\r\n"
3774 "Range: bytes = 40-49\r\n";
3775 RunTransactionTest(cache
.http_cache(), transaction
);
3777 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3778 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3779 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3781 transaction
.request_headers
=
3782 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3784 "Range: bytes = 40-49\r\n";
3785 RunTransactionTest(cache
.http_cache(), transaction
);
3787 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3788 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3789 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3791 transaction
.request_headers
= "If-Range: bla\r\n"
3793 "Range: bytes = 40-49\r\n";
3794 RunTransactionTest(cache
.http_cache(), transaction
);
3796 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3797 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3798 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3801 TEST(HttpCache
, SimpleGET_DoesntLogHeaders
) {
3802 MockHttpCache cache
;
3804 BoundTestNetLog log
;
3805 RunTransactionTestWithLog(cache
.http_cache(), kSimpleGET_Transaction
,
3808 EXPECT_FALSE(LogContainsEventType(
3809 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3812 TEST(HttpCache
, RangeGET_LogsHeaders
) {
3813 MockHttpCache cache
;
3815 BoundTestNetLog log
;
3816 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_Transaction
,
3819 EXPECT_TRUE(LogContainsEventType(
3820 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3823 TEST(HttpCache
, ExternalValidation_LogsHeaders
) {
3824 MockHttpCache cache
;
3826 BoundTestNetLog log
;
3827 MockTransaction
transaction(kSimpleGET_Transaction
);
3828 transaction
.request_headers
= "If-None-Match: foo\r\n" EXTRA_HEADER
;
3829 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3831 EXPECT_TRUE(LogContainsEventType(
3832 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3835 TEST(HttpCache
, SpecialHeaders_LogsHeaders
) {
3836 MockHttpCache cache
;
3838 BoundTestNetLog log
;
3839 MockTransaction
transaction(kSimpleGET_Transaction
);
3840 transaction
.request_headers
= "cache-control: no-cache\r\n" EXTRA_HEADER
;
3841 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3843 EXPECT_TRUE(LogContainsEventType(
3844 log
, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3847 // Tests that receiving 206 for a regular request is handled correctly.
3848 TEST(HttpCache
, GET_Crazy206
) {
3849 MockHttpCache cache
;
3851 // Write to the cache.
3852 MockTransaction
transaction(kRangeGET_TransactionOK
);
3853 AddMockTransaction(&transaction
);
3854 transaction
.request_headers
= EXTRA_HEADER
;
3855 transaction
.handler
= NULL
;
3856 RunTransactionTest(cache
.http_cache(), transaction
);
3858 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3859 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3860 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3862 // This should read again from the net.
3863 RunTransactionTest(cache
.http_cache(), transaction
);
3865 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3866 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3867 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3868 RemoveMockTransaction(&transaction
);
3871 // Tests that receiving 416 for a regular request is handled correctly.
3872 TEST(HttpCache
, GET_Crazy416
) {
3873 MockHttpCache cache
;
3875 // Write to the cache.
3876 MockTransaction
transaction(kSimpleGET_Transaction
);
3877 AddMockTransaction(&transaction
);
3878 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3879 RunTransactionTest(cache
.http_cache(), transaction
);
3881 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3882 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3883 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3885 RemoveMockTransaction(&transaction
);
3888 // Tests that we don't store partial responses that can't be validated.
3889 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3890 MockHttpCache cache
;
3891 std::string headers
;
3893 // Attempt to write to the cache (40-49).
3894 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3895 transaction
.response_headers
= "Content-Length: 10\n"
3896 "Cache-Control: max-age=3600\n"
3897 "ETag: w/\"foo\"\n";
3898 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3900 Verify206Response(headers
, 40, 49);
3901 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3902 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3903 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3905 // Now verify that there's no cached data.
3906 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3909 Verify206Response(headers
, 40, 49);
3910 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3911 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3912 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3915 // Tests failures to conditionalize byte range requests.
3916 TEST(HttpCache
, RangeGET_NoConditionalization
) {
3917 MockHttpCache cache
;
3918 cache
.FailConditionalizations();
3919 std::string headers
;
3921 // Write to the cache (40-49).
3922 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3923 transaction
.response_headers
= "Content-Length: 10\n"
3925 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3927 Verify206Response(headers
, 40, 49);
3928 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3929 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3930 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3932 // Now verify that the cached data is not used.
3933 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3936 Verify206Response(headers
, 40, 49);
3937 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3938 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3939 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3942 // Tests that restarting a partial request when the cached data cannot be
3943 // revalidated logs an event.
3944 TEST(HttpCache
, RangeGET_NoValidation_LogsRestart
) {
3945 MockHttpCache cache
;
3946 cache
.FailConditionalizations();
3948 // Write to the cache (40-49).
3949 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3950 transaction
.response_headers
= "Content-Length: 10\n"
3952 RunTransactionTest(cache
.http_cache(), transaction
);
3954 // Now verify that the cached data is not used.
3955 BoundTestNetLog log
;
3956 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_TransactionOK
,
3959 EXPECT_TRUE(LogContainsEventType(
3960 log
, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST
));
3963 // Tests that a failure to conditionalize a regular request (no range) with a
3964 // sparse entry results in a full response.
3965 TEST(HttpCache
, GET_NoConditionalization
) {
3966 MockHttpCache cache
;
3967 cache
.FailConditionalizations();
3968 std::string headers
;
3970 // Write to the cache (40-49).
3971 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3972 transaction
.response_headers
= "Content-Length: 10\n"
3974 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3976 Verify206Response(headers
, 40, 49);
3977 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3978 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3979 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3981 // Now verify that the cached data is not used.
3982 // Don't ask for a range. The cache will attempt to use the cached data but
3983 // should discard it as it cannot be validated. A regular request should go
3984 // to the server and a new entry should be created.
3985 transaction
.request_headers
= EXTRA_HEADER
;
3986 transaction
.data
= "Not a range";
3987 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3989 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
3990 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3991 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3992 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3994 // The last response was saved.
3995 RunTransactionTest(cache
.http_cache(), transaction
);
3996 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3997 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3998 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4001 // Verifies that conditionalization failures when asking for a range that would
4002 // require the cache to modify the range to ask, result in a network request
4003 // that matches the user's one.
4004 TEST(HttpCache
, RangeGET_NoConditionalization2
) {
4005 MockHttpCache cache
;
4006 cache
.FailConditionalizations();
4007 std::string headers
;
4009 // Write to the cache (40-49).
4010 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4011 transaction
.response_headers
= "Content-Length: 10\n"
4013 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4015 Verify206Response(headers
, 40, 49);
4016 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4017 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4018 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4020 // Now verify that the cached data is not used.
4021 // Ask for a range that extends before and after the cached data so that the
4022 // cache would normally mix data from three sources. After deleting the entry,
4023 // the response will come from a single network request.
4024 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4025 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4026 transaction
.response_headers
= kRangeGET_TransactionOK
.response_headers
;
4027 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4029 Verify206Response(headers
, 20, 59);
4030 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4031 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4032 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4034 // The last response was saved.
4035 RunTransactionTest(cache
.http_cache(), transaction
);
4036 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4037 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4038 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4041 // Tests that we cache partial responses that lack content-length.
4042 TEST(HttpCache
, RangeGET_NoContentLength
) {
4043 MockHttpCache cache
;
4044 std::string headers
;
4046 // Attempt to write to the cache (40-49).
4047 MockTransaction
transaction(kRangeGET_TransactionOK
);
4048 AddMockTransaction(&transaction
);
4049 transaction
.response_headers
= "ETag: \"foo\"\n"
4050 "Accept-Ranges: bytes\n"
4051 "Content-Range: bytes 40-49/80\n";
4052 transaction
.handler
= NULL
;
4053 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4055 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4056 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4057 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4059 // Now verify that there's no cached data.
4060 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
4061 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4064 Verify206Response(headers
, 40, 49);
4065 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4066 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4067 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4069 RemoveMockTransaction(&transaction
);
4072 // Tests that we can cache range requests and fetch random blocks from the
4073 // cache and the network.
4074 TEST(HttpCache
, RangeGET_OK
) {
4075 MockHttpCache cache
;
4076 AddMockTransaction(&kRangeGET_TransactionOK
);
4077 std::string headers
;
4079 // Write to the cache (40-49).
4080 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4083 Verify206Response(headers
, 40, 49);
4084 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4085 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4086 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4088 // Read from the cache (40-49).
4089 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4092 Verify206Response(headers
, 40, 49);
4093 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4094 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4095 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4097 // Make sure we are done with the previous transaction.
4098 base::MessageLoop::current()->RunUntilIdle();
4100 // Write to the cache (30-39).
4101 MockTransaction
transaction(kRangeGET_TransactionOK
);
4102 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4103 transaction
.data
= "rg: 30-39 ";
4104 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4106 Verify206Response(headers
, 30, 39);
4107 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4108 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4109 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4111 // Make sure we are done with the previous transaction.
4112 base::MessageLoop::current()->RunUntilIdle();
4114 // Write and read from the cache (20-59).
4115 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4116 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4117 BoundTestNetLog log
;
4118 LoadTimingInfo load_timing_info
;
4119 RunTransactionTestWithResponseAndGetTiming(
4120 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4123 Verify206Response(headers
, 20, 59);
4124 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4125 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4126 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4127 TestLoadTimingNetworkRequest(load_timing_info
);
4129 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4132 // Tests that we can cache range requests and fetch random blocks from the
4133 // cache and the network, with synchronous responses.
4134 TEST(HttpCache
, RangeGET_SyncOK
) {
4135 MockHttpCache cache
;
4137 MockTransaction
transaction(kRangeGET_TransactionOK
);
4138 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
4139 AddMockTransaction(&transaction
);
4141 // Write to the cache (40-49).
4142 std::string headers
;
4143 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4145 Verify206Response(headers
, 40, 49);
4146 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4147 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4148 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4150 // Read from the cache (40-49).
4151 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4153 Verify206Response(headers
, 40, 49);
4154 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4155 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4156 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4158 // Make sure we are done with the previous transaction.
4159 base::MessageLoop::current()->RunUntilIdle();
4161 // Write to the cache (30-39).
4162 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4163 transaction
.data
= "rg: 30-39 ";
4164 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4166 Verify206Response(headers
, 30, 39);
4167 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4168 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4169 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4171 // Make sure we are done with the previous transaction.
4172 base::MessageLoop::current()->RunUntilIdle();
4174 // Write and read from the cache (20-59).
4175 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4176 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4177 BoundTestNetLog log
;
4178 LoadTimingInfo load_timing_info
;
4179 RunTransactionTestWithResponseAndGetTiming(
4180 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4183 Verify206Response(headers
, 20, 59);
4184 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4185 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4186 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4187 TestLoadTimingNetworkRequest(load_timing_info
);
4189 RemoveMockTransaction(&transaction
);
4192 // Tests that we don't revalidate an entry unless we are required to do so.
4193 TEST(HttpCache
, RangeGET_Revalidate1
) {
4194 MockHttpCache cache
;
4195 std::string headers
;
4197 // Write to the cache (40-49).
4198 MockTransaction
transaction(kRangeGET_TransactionOK
);
4199 transaction
.response_headers
=
4200 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4201 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4203 "Accept-Ranges: bytes\n"
4204 "Content-Length: 10\n";
4205 AddMockTransaction(&transaction
);
4206 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4208 Verify206Response(headers
, 40, 49);
4209 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4210 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4211 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4213 // Read from the cache (40-49).
4214 BoundTestNetLog log
;
4215 LoadTimingInfo load_timing_info
;
4216 RunTransactionTestWithResponseAndGetTiming(
4217 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4220 Verify206Response(headers
, 40, 49);
4221 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4222 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4223 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4224 TestLoadTimingCachedResponse(load_timing_info
);
4226 // Read again forcing the revalidation.
4227 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4228 RunTransactionTestWithResponseAndGetTiming(
4229 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4232 Verify206Response(headers
, 40, 49);
4233 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4234 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4235 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4236 TestLoadTimingNetworkRequest(load_timing_info
);
4238 RemoveMockTransaction(&transaction
);
4241 // Checks that we revalidate an entry when the headers say so.
4242 TEST(HttpCache
, RangeGET_Revalidate2
) {
4243 MockHttpCache cache
;
4244 std::string headers
;
4246 // Write to the cache (40-49).
4247 MockTransaction
transaction(kRangeGET_TransactionOK
);
4248 transaction
.response_headers
=
4249 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4250 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4252 "Accept-Ranges: bytes\n"
4253 "Content-Length: 10\n";
4254 AddMockTransaction(&transaction
);
4255 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4257 Verify206Response(headers
, 40, 49);
4258 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4259 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4262 // Read from the cache (40-49).
4263 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4264 Verify206Response(headers
, 40, 49);
4266 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4267 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4268 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4270 RemoveMockTransaction(&transaction
);
4273 // Tests that we deal with 304s for range requests.
4274 TEST(HttpCache
, RangeGET_304
) {
4275 MockHttpCache cache
;
4276 AddMockTransaction(&kRangeGET_TransactionOK
);
4277 std::string headers
;
4279 // Write to the cache (40-49).
4280 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4283 Verify206Response(headers
, 40, 49);
4284 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4285 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4286 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4288 // Read from the cache (40-49).
4289 RangeTransactionServer handler
;
4290 handler
.set_not_modified(true);
4291 MockTransaction
transaction(kRangeGET_TransactionOK
);
4292 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4293 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4295 Verify206Response(headers
, 40, 49);
4296 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4297 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4298 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4300 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4303 // Tests that we deal with 206s when revalidating range requests.
4304 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4305 MockHttpCache cache
;
4306 AddMockTransaction(&kRangeGET_TransactionOK
);
4307 std::string headers
;
4309 // Write to the cache (40-49).
4310 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4313 Verify206Response(headers
, 40, 49);
4314 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4315 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4316 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4318 // Attempt to read from the cache (40-49).
4319 RangeTransactionServer handler
;
4320 handler
.set_modified(true);
4321 MockTransaction
transaction(kRangeGET_TransactionOK
);
4322 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4323 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4325 Verify206Response(headers
, 40, 49);
4326 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4327 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4328 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4330 // And the entry should be gone.
4331 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4332 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4333 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4334 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4336 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4339 // Tests that when a server returns 206 with a sub-range of the requested range,
4340 // and there is nothing stored in the cache, the returned response is passed to
4341 // the caller as is. In this context, a subrange means a response that starts
4342 // with the same byte that was requested, but that is not the whole range that
4344 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_NoCachedContent
) {
4345 MockHttpCache cache
;
4346 std::string headers
;
4348 // Request a large range (40-59). The server sends 40-49.
4349 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4350 transaction
.request_headers
= "Range: bytes = 40-59\r\n" EXTRA_HEADER
;
4351 transaction
.response_headers
=
4352 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4354 "Accept-Ranges: bytes\n"
4355 "Content-Length: 10\n"
4356 "Content-Range: bytes 40-49/80\n";
4357 transaction
.handler
= nullptr;
4358 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4360 Verify206Response(headers
, 40, 49);
4361 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4362 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4363 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4366 // Tests that when a server returns 206 with a sub-range of the requested range,
4367 // and there was an entry stored in the cache, the cache gets out of the way.
4368 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_CachedContent
) {
4369 MockHttpCache cache
;
4370 std::string headers
;
4372 // Write to the cache (70-79).
4373 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4374 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4375 transaction
.data
= "rg: 70-79 ";
4376 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4377 Verify206Response(headers
, 70, 79);
4379 // Request a large range (40-79). The cache will ask the server for 40-59.
4380 // The server returns 40-49. The cache should consider the server confused and
4381 // abort caching, restarting the request without caching.
4382 transaction
.request_headers
= "Range: bytes = 40-79\r\n" EXTRA_HEADER
;
4383 transaction
.response_headers
=
4384 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4386 "Accept-Ranges: bytes\n"
4387 "Content-Length: 10\n"
4388 "Content-Range: bytes 40-49/80\n";
4389 transaction
.handler
= nullptr;
4390 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4392 // Two new network requests were issued, one from the cache and another after
4393 // deleting the entry.
4394 Verify206Response(headers
, 40, 49);
4395 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4396 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4397 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4399 // The entry was deleted.
4400 RunTransactionTest(cache
.http_cache(), transaction
);
4401 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4402 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4403 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4406 // Tests that when a server returns 206 with a sub-range of the requested range,
4407 // and there was an entry stored in the cache, the cache gets out of the way,
4408 // when the caller is not using ranges.
4409 TEST(HttpCache
, GET_206ReturnsSubrangeRange_CachedContent
) {
4410 MockHttpCache cache
;
4411 std::string headers
;
4413 // Write to the cache (70-79).
4414 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4415 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4416 transaction
.data
= "rg: 70-79 ";
4417 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4418 Verify206Response(headers
, 70, 79);
4420 // Don't ask for a range. The cache will ask the server for 0-69.
4421 // The server returns 40-49. The cache should consider the server confused and
4422 // abort caching, restarting the request.
4423 // The second network request should not be a byte range request so the server
4424 // should return 200 + "Not a range"
4425 transaction
.request_headers
= "X-Return-Default-Range:\r\n" EXTRA_HEADER
;
4426 transaction
.data
= "Not a range";
4427 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4429 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4430 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4431 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4432 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4434 // The entry was deleted.
4435 RunTransactionTest(cache
.http_cache(), transaction
);
4436 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4437 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4438 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4441 // Tests that when a server returns 206 with a random range and there is
4442 // nothing stored in the cache, the returned response is passed to the caller
4443 // as is. In this context, a WrongRange means that the returned range may or may
4444 // not have any relationship with the requested range (may or may not be
4445 // contained). The important part is that the first byte doesn't match the first
4447 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_NoCachedContent
) {
4448 MockHttpCache cache
;
4449 std::string headers
;
4451 // Request a large range (30-59). The server sends (40-49).
4452 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4453 transaction
.request_headers
= "Range: bytes = 30-59\r\n" EXTRA_HEADER
;
4454 transaction
.response_headers
=
4455 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4457 "Accept-Ranges: bytes\n"
4458 "Content-Length: 10\n"
4459 "Content-Range: bytes 40-49/80\n";
4460 transaction
.handler
= nullptr;
4461 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4463 Verify206Response(headers
, 40, 49);
4464 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4465 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4466 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4468 // The entry was deleted.
4469 RunTransactionTest(cache
.http_cache(), transaction
);
4470 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4471 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4472 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4475 // Tests that when a server returns 206 with a random range and there is
4476 // an entry stored in the cache, the cache gets out of the way.
4477 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_CachedContent
) {
4478 MockHttpCache cache
;
4479 std::string headers
;
4481 // Write to the cache (70-79).
4482 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4483 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4484 transaction
.data
= "rg: 70-79 ";
4485 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4486 Verify206Response(headers
, 70, 79);
4488 // Request a large range (30-79). The cache will ask the server for 30-69.
4489 // The server returns 40-49. The cache should consider the server confused and
4490 // abort caching, returning the weird range to the caller.
4491 transaction
.request_headers
= "Range: bytes = 30-79\r\n" EXTRA_HEADER
;
4492 transaction
.response_headers
=
4493 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4495 "Accept-Ranges: bytes\n"
4496 "Content-Length: 10\n"
4497 "Content-Range: bytes 40-49/80\n";
4498 transaction
.handler
= nullptr;
4499 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4501 Verify206Response(headers
, 40, 49);
4502 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4503 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4504 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4506 // The entry was deleted.
4507 RunTransactionTest(cache
.http_cache(), transaction
);
4508 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4509 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4510 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4513 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4514 // the response matches the one provided by the server.
4515 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_NoCachedContent
) {
4516 MockHttpCache cache
;
4517 std::string headers
;
4519 // Request a large range (70-99). The server sends 70-79.
4520 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4521 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4522 transaction
.data
= "rg: 70-79 ";
4523 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4525 Verify206Response(headers
, 70, 79);
4526 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4527 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4528 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4530 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4531 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4534 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4535 // the cache automatically fixes the request.
4536 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_CachedContent
) {
4537 MockHttpCache cache
;
4538 std::string headers
;
4540 // Write to the cache (40-49).
4541 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4542 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4544 // Request a large range (70-99). The server sends 70-79.
4545 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4546 transaction
.data
= "rg: 70-79 ";
4547 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4549 Verify206Response(headers
, 70, 79);
4550 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4551 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4552 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4554 // The entry was not deleted (the range was automatically fixed).
4555 RunTransactionTest(cache
.http_cache(), transaction
);
4556 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4557 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4558 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4561 // Tests that when a caller asks for a not-satisfiable range, the server's
4562 // response is forwarded to the caller.
4563 TEST(HttpCache
, RangeGET_416_NoCachedContent
) {
4564 MockHttpCache cache
;
4565 std::string headers
;
4567 // Request a range beyond EOF (80-99).
4568 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4569 transaction
.request_headers
= "Range: bytes = 80-99\r\n" EXTRA_HEADER
;
4570 transaction
.data
= "";
4571 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
4572 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4574 EXPECT_EQ(0U, headers
.find(transaction
.status
));
4575 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4576 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4577 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4579 // The entry was deleted.
4580 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4581 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4584 // Tests that we cache 301s for range requests.
4585 TEST(HttpCache
, RangeGET_301
) {
4586 MockHttpCache cache
;
4587 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4588 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4589 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4590 transaction
.data
= "";
4591 transaction
.handler
= NULL
;
4593 // Write to the cache.
4594 RunTransactionTest(cache
.http_cache(), transaction
);
4595 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4596 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4597 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4599 // Read from the cache.
4600 RunTransactionTest(cache
.http_cache(), transaction
);
4601 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4602 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4603 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4606 // Tests that we can cache range requests when the start or end is unknown.
4607 // We start with one suffix request, followed by a request from a given point.
4608 TEST(HttpCache
, UnknownRangeGET_1
) {
4609 MockHttpCache cache
;
4610 AddMockTransaction(&kRangeGET_TransactionOK
);
4611 std::string headers
;
4613 // Write to the cache (70-79).
4614 MockTransaction
transaction(kRangeGET_TransactionOK
);
4615 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4616 transaction
.data
= "rg: 70-79 ";
4617 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4619 Verify206Response(headers
, 70, 79);
4620 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4621 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4622 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4624 // Make sure we are done with the previous transaction.
4625 base::MessageLoop::current()->RunUntilIdle();
4627 // Write and read from the cache (60-79).
4628 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4629 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4630 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4632 Verify206Response(headers
, 60, 79);
4633 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4634 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4635 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4637 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4640 // Tests that we can cache range requests when the start or end is unknown.
4641 // We start with one request from a given point, followed by a suffix request.
4642 // We'll also verify that synchronous cache responses work as intended.
4643 TEST(HttpCache
, UnknownRangeGET_2
) {
4644 MockHttpCache cache
;
4645 std::string headers
;
4647 MockTransaction
transaction(kRangeGET_TransactionOK
);
4648 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4649 TEST_MODE_SYNC_CACHE_READ
|
4650 TEST_MODE_SYNC_CACHE_WRITE
;
4651 AddMockTransaction(&transaction
);
4653 // Write to the cache (70-79).
4654 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4655 transaction
.data
= "rg: 70-79 ";
4656 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4658 Verify206Response(headers
, 70, 79);
4659 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4660 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4661 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4663 // Make sure we are done with the previous transaction.
4664 base::MessageLoop::current()->RunUntilIdle();
4666 // Write and read from the cache (60-79).
4667 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4668 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4669 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4671 Verify206Response(headers
, 60, 79);
4672 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4673 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4674 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4676 RemoveMockTransaction(&transaction
);
4679 // Tests that receiving Not Modified when asking for an open range doesn't mess
4681 TEST(HttpCache
, UnknownRangeGET_304
) {
4682 MockHttpCache cache
;
4683 std::string headers
;
4685 MockTransaction
transaction(kRangeGET_TransactionOK
);
4686 AddMockTransaction(&transaction
);
4688 RangeTransactionServer handler
;
4689 handler
.set_not_modified(true);
4691 // Ask for the end of the file, without knowing the length.
4692 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4693 transaction
.data
= "";
4694 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4696 // We just bypass the cache.
4697 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4698 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4699 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4700 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4702 RunTransactionTest(cache
.http_cache(), transaction
);
4703 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4705 RemoveMockTransaction(&transaction
);
4708 // Tests that we can handle non-range requests when we have cached a range.
4709 TEST(HttpCache
, GET_Previous206
) {
4710 MockHttpCache cache
;
4711 AddMockTransaction(&kRangeGET_TransactionOK
);
4712 std::string headers
;
4713 BoundTestNetLog log
;
4714 LoadTimingInfo load_timing_info
;
4716 // Write to the cache (40-49).
4717 RunTransactionTestWithResponseAndGetTiming(
4718 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4721 Verify206Response(headers
, 40, 49);
4722 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4723 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4724 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4725 TestLoadTimingNetworkRequest(load_timing_info
);
4727 // Write and read from the cache (0-79), when not asked for a range.
4728 MockTransaction
transaction(kRangeGET_TransactionOK
);
4729 transaction
.request_headers
= EXTRA_HEADER
;
4730 transaction
.data
= kFullRangeData
;
4731 RunTransactionTestWithResponseAndGetTiming(
4732 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4735 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4736 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4737 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4738 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4739 TestLoadTimingNetworkRequest(load_timing_info
);
4741 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4744 // Tests that we can handle non-range requests when we have cached the first
4745 // part of the object and the server replies with 304 (Not Modified).
4746 TEST(HttpCache
, GET_Previous206_NotModified
) {
4747 MockHttpCache cache
;
4749 MockTransaction
transaction(kRangeGET_TransactionOK
);
4750 AddMockTransaction(&transaction
);
4751 std::string headers
;
4752 BoundTestNetLog log
;
4753 LoadTimingInfo load_timing_info
;
4755 // Write to the cache (0-9).
4756 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4757 transaction
.data
= "rg: 00-09 ";
4758 RunTransactionTestWithResponseAndGetTiming(
4759 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4761 Verify206Response(headers
, 0, 9);
4762 TestLoadTimingNetworkRequest(load_timing_info
);
4764 // Write to the cache (70-79).
4765 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4766 transaction
.data
= "rg: 70-79 ";
4767 RunTransactionTestWithResponseAndGetTiming(
4768 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4770 Verify206Response(headers
, 70, 79);
4772 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4773 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4774 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4775 TestLoadTimingNetworkRequest(load_timing_info
);
4777 // Read from the cache (0-9), write and read from cache (10 - 79).
4778 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
4779 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4780 transaction
.data
= kFullRangeData
;
4781 RunTransactionTestWithResponseAndGetTiming(
4782 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4785 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4786 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4787 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4788 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4789 TestLoadTimingNetworkRequest(load_timing_info
);
4791 RemoveMockTransaction(&transaction
);
4794 // Tests that we can handle a regular request to a sparse entry, that results in
4795 // new content provided by the server (206).
4796 TEST(HttpCache
, GET_Previous206_NewContent
) {
4797 MockHttpCache cache
;
4798 AddMockTransaction(&kRangeGET_TransactionOK
);
4799 std::string headers
;
4801 // Write to the cache (0-9).
4802 MockTransaction
transaction(kRangeGET_TransactionOK
);
4803 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4804 transaction
.data
= "rg: 00-09 ";
4805 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4807 Verify206Response(headers
, 0, 9);
4808 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4809 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4810 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4812 // Now we'll issue a request without any range that should result first in a
4813 // 206 (when revalidating), and then in a weird standard answer: the test
4814 // server will not modify the response so we'll get the default range... a
4815 // real server will answer with 200.
4816 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4817 transaction2
.request_headers
= EXTRA_HEADER
;
4818 transaction2
.load_flags
|= LOAD_VALIDATE_CACHE
;
4819 transaction2
.data
= "Not a range";
4820 RangeTransactionServer handler
;
4821 handler
.set_modified(true);
4822 BoundTestNetLog log
;
4823 LoadTimingInfo load_timing_info
;
4824 RunTransactionTestWithResponseAndGetTiming(
4825 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4828 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4829 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4830 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4831 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4832 TestLoadTimingNetworkRequest(load_timing_info
);
4834 // Verify that the previous request deleted the entry.
4835 RunTransactionTest(cache
.http_cache(), transaction
);
4836 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4838 RemoveMockTransaction(&transaction
);
4841 // Tests that we can handle cached 206 responses that are not sparse.
4842 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4843 MockHttpCache cache
;
4845 // Create a disk cache entry that stores 206 headers while not being sparse.
4846 disk_cache::Entry
* entry
;
4847 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4850 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4851 raw_headers
.append("\n");
4852 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4854 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4856 HttpResponseInfo response
;
4857 response
.headers
= new HttpResponseHeaders(raw_headers
);
4858 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4860 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4861 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4862 kRangeGET_TransactionOK
.data
, 500));
4863 TestCompletionCallback cb
;
4864 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4865 EXPECT_EQ(len
, cb
.GetResult(rv
));
4868 // Now see that we don't use the stored entry.
4869 std::string headers
;
4870 BoundTestNetLog log
;
4871 LoadTimingInfo load_timing_info
;
4872 RunTransactionTestWithResponseAndGetTiming(
4873 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4876 // We are expecting a 200.
4877 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4878 expected_headers
.append("\n");
4879 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4880 EXPECT_EQ(expected_headers
, headers
);
4881 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4882 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4883 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4884 TestLoadTimingNetworkRequest(load_timing_info
);
4887 // Tests that we can handle cached 206 responses that are not sparse. This time
4888 // we issue a range request and expect to receive a range.
4889 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4890 MockHttpCache cache
;
4891 AddMockTransaction(&kRangeGET_TransactionOK
);
4893 // Create a disk cache entry that stores 206 headers while not being sparse.
4894 disk_cache::Entry
* entry
;
4895 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4898 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4899 raw_headers
.append("\n");
4900 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4902 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4904 HttpResponseInfo response
;
4905 response
.headers
= new HttpResponseHeaders(raw_headers
);
4906 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4908 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4909 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4910 kRangeGET_TransactionOK
.data
, 500));
4911 TestCompletionCallback cb
;
4912 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4913 EXPECT_EQ(len
, cb
.GetResult(rv
));
4916 // Now see that we don't use the stored entry.
4917 std::string headers
;
4918 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4921 // We are expecting a 206.
4922 Verify206Response(headers
, 40, 49);
4923 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4924 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4925 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4927 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4930 // Tests that we can handle cached 206 responses that can't be validated.
4931 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4932 MockHttpCache cache
;
4934 // Create a disk cache entry that stores 206 headers.
4935 disk_cache::Entry
* entry
;
4936 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4939 // Make sure that the headers cannot be validated with the server.
4940 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4941 raw_headers
.append("\n");
4942 raw_headers
.append("Content-Length: 80\n");
4944 HttpUtil::AssembleRawHeaders(raw_headers
.data(), raw_headers
.size());
4946 HttpResponseInfo response
;
4947 response
.headers
= new HttpResponseHeaders(raw_headers
);
4948 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4950 scoped_refptr
<IOBuffer
> buf(new IOBuffer(500));
4951 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4952 kRangeGET_TransactionOK
.data
, 500));
4953 TestCompletionCallback cb
;
4954 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4955 EXPECT_EQ(len
, cb
.GetResult(rv
));
4958 // Now see that we don't use the stored entry.
4959 std::string headers
;
4960 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4963 // We are expecting a 200.
4964 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4965 expected_headers
.append("\n");
4966 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4967 EXPECT_EQ(expected_headers
, headers
);
4968 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4969 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4970 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4973 // Tests that we can handle range requests with cached 200 responses.
4974 TEST(HttpCache
, RangeGET_Previous200
) {
4975 MockHttpCache cache
;
4977 // Store the whole thing with status 200.
4978 MockTransaction
transaction(kTypicalGET_Transaction
);
4979 transaction
.url
= kRangeGET_TransactionOK
.url
;
4980 transaction
.data
= kFullRangeData
;
4981 AddMockTransaction(&transaction
);
4982 RunTransactionTest(cache
.http_cache(), transaction
);
4983 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4984 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4985 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4987 RemoveMockTransaction(&transaction
);
4988 AddMockTransaction(&kRangeGET_TransactionOK
);
4990 // Now see that we use the stored entry.
4991 std::string headers
;
4992 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4993 RangeTransactionServer handler
;
4994 handler
.set_not_modified(true);
4995 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4997 // We are expecting a 206.
4998 Verify206Response(headers
, 40, 49);
4999 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5000 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5001 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5003 // The last transaction has finished so make sure the entry is deactivated.
5004 base::MessageLoop::current()->RunUntilIdle();
5006 // Make a request for an invalid range.
5007 MockTransaction
transaction3(kRangeGET_TransactionOK
);
5008 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
5009 transaction3
.data
= transaction
.data
;
5010 transaction3
.load_flags
= LOAD_PREFERRING_CACHE
;
5011 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
5012 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5013 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
5014 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
5015 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
5017 // Make sure the entry is deactivated.
5018 base::MessageLoop::current()->RunUntilIdle();
5020 // Even though the request was invalid, we should have the entry.
5021 RunTransactionTest(cache
.http_cache(), transaction2
);
5022 EXPECT_EQ(3, cache
.disk_cache()->open_count());
5024 // Make sure the entry is deactivated.
5025 base::MessageLoop::current()->RunUntilIdle();
5027 // Now we should receive a range from the server and drop the stored entry.
5028 handler
.set_not_modified(false);
5029 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5030 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5031 Verify206Response(headers
, 40, 49);
5032 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
5033 EXPECT_EQ(4, cache
.disk_cache()->open_count());
5034 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5036 RunTransactionTest(cache
.http_cache(), transaction2
);
5037 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5039 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5042 // Tests that we can handle a 200 response when dealing with sparse entries.
5043 TEST(HttpCache
, RangeRequestResultsIn200
) {
5044 MockHttpCache cache
;
5045 AddMockTransaction(&kRangeGET_TransactionOK
);
5046 std::string headers
;
5048 // Write to the cache (70-79).
5049 MockTransaction
transaction(kRangeGET_TransactionOK
);
5050 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5051 transaction
.data
= "rg: 70-79 ";
5052 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5054 Verify206Response(headers
, 70, 79);
5055 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5056 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5057 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5059 // Now we'll issue a request that results in a plain 200 response, but to
5060 // the to the same URL that we used to store sparse data, and making sure
5061 // that we ask for a range.
5062 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5063 MockTransaction
transaction2(kSimpleGET_Transaction
);
5064 transaction2
.url
= kRangeGET_TransactionOK
.url
;
5065 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5066 AddMockTransaction(&transaction2
);
5068 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5070 std::string
expected_headers(kSimpleGET_Transaction
.status
);
5071 expected_headers
.append("\n");
5072 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
5073 EXPECT_EQ(expected_headers
, headers
);
5074 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5075 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5076 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5078 RemoveMockTransaction(&transaction2
);
5081 // Tests that a range request that falls outside of the size that we know about
5082 // only deletes the entry if the resource has indeed changed.
5083 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
5084 MockHttpCache cache
;
5085 AddMockTransaction(&kRangeGET_TransactionOK
);
5086 std::string headers
;
5088 // Write to the cache (40-49).
5089 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5092 Verify206Response(headers
, 40, 49);
5093 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5094 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5095 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5097 // A weird request should not delete this entry. Ask for bytes 120-.
5098 MockTransaction
transaction(kRangeGET_TransactionOK
);
5099 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
5100 transaction
.data
= "";
5101 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5103 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
5104 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5105 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5106 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5108 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5109 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5110 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5112 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5115 // Tests that we don't delete a sparse entry when we cancel a request.
5116 TEST(HttpCache
, RangeGET_Cancel
) {
5117 MockHttpCache cache
;
5118 AddMockTransaction(&kRangeGET_TransactionOK
);
5120 MockHttpRequest
request(kRangeGET_TransactionOK
);
5122 Context
* c
= new Context();
5123 int rv
= cache
.CreateTransaction(&c
->trans
);
5126 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5127 if (rv
== ERR_IO_PENDING
)
5128 rv
= c
->callback
.WaitForResult();
5130 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5131 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5132 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5134 // Make sure that the entry has some data stored.
5135 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5136 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5137 if (rv
== ERR_IO_PENDING
)
5138 rv
= c
->callback
.WaitForResult();
5139 EXPECT_EQ(buf
->size(), rv
);
5141 // Destroy the transaction.
5144 // Verify that the entry has not been deleted.
5145 disk_cache::Entry
* entry
;
5146 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5148 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5151 // Tests that we don't delete a sparse entry when we start a new request after
5152 // cancelling the previous one.
5153 TEST(HttpCache
, RangeGET_Cancel2
) {
5154 MockHttpCache cache
;
5155 AddMockTransaction(&kRangeGET_TransactionOK
);
5157 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5158 MockHttpRequest
request(kRangeGET_TransactionOK
);
5159 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5161 Context
* c
= new Context();
5162 int rv
= cache
.CreateTransaction(&c
->trans
);
5165 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5166 if (rv
== ERR_IO_PENDING
)
5167 rv
= c
->callback
.WaitForResult();
5169 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5170 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5171 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5173 // Make sure that we revalidate the entry and read from the cache (a single
5174 // read will return while waiting for the network).
5175 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5176 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5177 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5178 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5179 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5181 // Destroy the transaction before completing the read.
5184 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5185 // message loop. This means that a new transaction will just reuse the same
5186 // active entry (no open or create).
5188 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5190 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5191 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5192 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5193 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5196 // A slight variation of the previous test, this time we cancel two requests in
5197 // a row, making sure that the second is waiting for the entry to be ready.
5198 TEST(HttpCache
, RangeGET_Cancel3
) {
5199 MockHttpCache cache
;
5200 AddMockTransaction(&kRangeGET_TransactionOK
);
5202 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5203 MockHttpRequest
request(kRangeGET_TransactionOK
);
5204 request
.load_flags
|= LOAD_VALIDATE_CACHE
;
5206 Context
* c
= new Context();
5207 int rv
= cache
.CreateTransaction(&c
->trans
);
5210 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5211 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5212 rv
= c
->callback
.WaitForResult();
5214 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5215 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5216 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5218 // Make sure that we revalidate the entry and read from the cache (a single
5219 // read will return while waiting for the network).
5220 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5221 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5222 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5223 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5224 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5226 // Destroy the transaction before completing the read.
5229 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5230 // message loop. This means that a new transaction will just reuse the same
5231 // active entry (no open or create).
5234 rv
= cache
.CreateTransaction(&c
->trans
);
5237 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5238 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5240 MockDiskEntry::IgnoreCallbacks(true);
5241 base::MessageLoop::current()->RunUntilIdle();
5242 MockDiskEntry::IgnoreCallbacks(false);
5244 // The new transaction is waiting for the query range callback.
5247 // And we should not crash when the callback is delivered.
5248 base::MessageLoop::current()->RunUntilIdle();
5250 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5251 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5252 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5253 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5256 // Tests that an invalid range response results in no cached entry.
5257 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
5258 MockHttpCache cache
;
5259 std::string headers
;
5261 MockTransaction
transaction(kRangeGET_TransactionOK
);
5262 transaction
.handler
= NULL
;
5263 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
5264 "Content-Length: 10\n";
5265 AddMockTransaction(&transaction
);
5266 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5268 std::string
expected(transaction
.status
);
5269 expected
.append("\n");
5270 expected
.append(transaction
.response_headers
);
5271 EXPECT_EQ(expected
, headers
);
5273 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5274 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5275 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5277 // Verify that we don't have a cached entry.
5278 disk_cache::Entry
* entry
;
5279 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5281 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5284 // Tests that we reject a range that doesn't match the content-length.
5285 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
5286 MockHttpCache cache
;
5287 std::string headers
;
5289 MockTransaction
transaction(kRangeGET_TransactionOK
);
5290 transaction
.handler
= NULL
;
5291 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
5292 "Content-Length: 20\n";
5293 AddMockTransaction(&transaction
);
5294 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5296 std::string
expected(transaction
.status
);
5297 expected
.append("\n");
5298 expected
.append(transaction
.response_headers
);
5299 EXPECT_EQ(expected
, headers
);
5301 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5302 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5303 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5305 // Verify that we don't have a cached entry.
5306 disk_cache::Entry
* entry
;
5307 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5309 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5312 // Tests that if a server tells us conflicting information about a resource we
5314 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
5315 MockHttpCache cache
;
5316 std::string headers
;
5318 MockTransaction
transaction(kRangeGET_TransactionOK
);
5319 transaction
.handler
= NULL
;
5320 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
5321 std::string
response_headers(transaction
.response_headers
);
5322 response_headers
.append("Content-Range: bytes 50-59/160\n");
5323 transaction
.response_headers
= response_headers
.c_str();
5324 AddMockTransaction(&transaction
);
5325 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5327 Verify206Response(headers
, 50, 59);
5328 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5329 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5330 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5332 RemoveMockTransaction(&transaction
);
5333 AddMockTransaction(&kRangeGET_TransactionOK
);
5335 // This transaction will report a resource size of 80 bytes, and we think it's
5336 // 160 so we should ignore the response.
5337 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5340 Verify206Response(headers
, 40, 49);
5341 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5342 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5343 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5345 // Verify that the entry is gone.
5346 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5347 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5348 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5349 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5352 // Tests that we handle large range values properly.
5353 TEST(HttpCache
, RangeGET_LargeValues
) {
5354 // We need a real sparse cache for this test.
5355 MockHttpCache
cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5356 std::string headers
;
5358 MockTransaction
transaction(kRangeGET_TransactionOK
);
5359 transaction
.handler
= NULL
;
5360 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
5362 transaction
.response_headers
=
5364 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5365 "Content-Length: 10\n";
5366 AddMockTransaction(&transaction
);
5367 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5369 std::string
expected(transaction
.status
);
5370 expected
.append("\n");
5371 expected
.append(transaction
.response_headers
);
5372 EXPECT_EQ(expected
, headers
);
5374 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5376 // Verify that we have a cached entry.
5377 disk_cache::Entry
* en
;
5378 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
5381 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5384 // Tests that we don't crash with a range request if the disk cache was not
5385 // initialized properly.
5386 TEST(HttpCache
, RangeGET_NoDiskCache
) {
5387 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
5388 factory
->set_fail(true);
5389 factory
->FinishCreation(); // We'll complete synchronously.
5390 MockHttpCache
cache(factory
);
5392 AddMockTransaction(&kRangeGET_TransactionOK
);
5394 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5395 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5397 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5400 // Tests that we handle byte range requests that skip the cache.
5401 TEST(HttpCache
, RangeHEAD
) {
5402 MockHttpCache cache
;
5403 AddMockTransaction(&kRangeGET_TransactionOK
);
5405 MockTransaction
transaction(kRangeGET_TransactionOK
);
5406 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5407 transaction
.method
= "HEAD";
5408 transaction
.data
= "rg: 70-79 ";
5410 std::string headers
;
5411 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5413 Verify206Response(headers
, 70, 79);
5414 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5415 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5416 EXPECT_EQ(0, cache
.disk_cache()->create_count());
5418 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5421 // Tests that we don't crash when after reading from the cache we issue a
5422 // request for the next range and the server gives us a 200 synchronously.
5423 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
5424 MockHttpCache cache
;
5426 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5427 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
5428 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
5429 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
5431 // Write to the cache.
5432 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5434 // And now read from the cache and the network.
5435 RangeTransactionServer handler
;
5436 handler
.set_bad_200(true);
5437 transaction
.data
= "Not a range";
5438 BoundTestNetLog log
;
5439 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
5441 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
5442 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5443 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5444 EXPECT_TRUE(LogContainsEventType(
5445 log
, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST
));
5448 // Tests that when the server gives us less data than expected, we don't keep
5449 // asking for more data.
5450 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
5451 MockHttpCache cache
;
5453 // First, check with an empty cache (WRITE mode).
5454 MockTransaction
transaction(kRangeGET_TransactionOK
);
5455 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
5456 transaction
.data
= "rg: 40-"; // Less than expected.
5457 transaction
.handler
= NULL
;
5458 std::string
headers(transaction
.response_headers
);
5459 headers
.append("Content-Range: bytes 40-49/80\n");
5460 transaction
.response_headers
= headers
.c_str();
5462 AddMockTransaction(&transaction
);
5464 // Write to the cache.
5465 RunTransactionTest(cache
.http_cache(), transaction
);
5467 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5468 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5469 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5471 // Now verify that even in READ_WRITE mode, we forward the bad response to
5473 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5474 transaction
.data
= "rg: 60-"; // Less than expected.
5475 headers
= kRangeGET_TransactionOK
.response_headers
;
5476 headers
.append("Content-Range: bytes 60-69/80\n");
5477 transaction
.response_headers
= headers
.c_str();
5479 RunTransactionTest(cache
.http_cache(), transaction
);
5481 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5482 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5483 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5485 RemoveMockTransaction(&transaction
);
5488 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5489 // This test hits a NOTREACHED so it is a release mode only test.
5490 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5491 MockHttpCache cache
;
5492 AddMockTransaction(&kRangeGET_TransactionOK
);
5494 // Write to the cache (40-49).
5495 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5496 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5497 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5498 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5500 // Force this transaction to read from the cache.
5501 MockTransaction
transaction(kRangeGET_TransactionOK
);
5502 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
5504 MockHttpRequest
request(transaction
);
5505 TestCompletionCallback callback
;
5507 scoped_ptr
<HttpTransaction
> trans
;
5508 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
5510 ASSERT_TRUE(trans
.get());
5512 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
5513 if (rv
== ERR_IO_PENDING
)
5514 rv
= callback
.WaitForResult();
5515 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
5519 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5520 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5521 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5523 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5527 // Tests the handling of the "truncation" flag.
5528 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5529 MockHttpCache cache
;
5530 disk_cache::Entry
* entry
;
5531 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5534 std::string
headers("HTTP/1.1 200 OK");
5535 headers
= HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5536 HttpResponseInfo response
;
5537 response
.headers
= new HttpResponseHeaders(headers
);
5539 // Set the last argument for this to be an incomplete request.
5540 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5541 bool truncated
= false;
5542 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5543 EXPECT_TRUE(truncated
);
5545 // And now test the opposite case.
5546 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5548 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5549 EXPECT_FALSE(truncated
);
5553 // Tests basic pickling/unpickling of HttpResponseInfo.
5554 TEST(HttpCache
, PersistHttpResponseInfo
) {
5555 // Set some fields (add more if needed.)
5556 HttpResponseInfo response1
;
5557 response1
.was_cached
= false;
5558 response1
.socket_address
= HostPortPair("1.2.3.4", 80);
5559 response1
.headers
= new HttpResponseHeaders("HTTP/1.1 200 OK");
5563 response1
.Persist(&pickle
, false, false);
5566 HttpResponseInfo response2
;
5567 bool response_truncated
;
5568 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5569 EXPECT_FALSE(response_truncated
);
5572 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5573 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5574 EXPECT_EQ(80, response2
.socket_address
.port());
5575 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5578 // Tests that we delete an entry when the request is cancelled before starting
5579 // to read from the network.
5580 TEST(HttpCache
, DoomOnDestruction
) {
5581 MockHttpCache cache
;
5583 MockHttpRequest
request(kSimpleGET_Transaction
);
5585 Context
* c
= new Context();
5586 int rv
= cache
.CreateTransaction(&c
->trans
);
5589 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5590 if (rv
== ERR_IO_PENDING
)
5591 c
->result
= c
->callback
.WaitForResult();
5593 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5594 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5595 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5597 // Destroy the transaction. We only have the headers so we should delete this
5601 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5603 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5605 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5608 // Tests that we delete an entry when the request is cancelled if the response
5609 // does not have content-length and strong validators.
5610 TEST(HttpCache
, DoomOnDestruction2
) {
5611 MockHttpCache cache
;
5613 MockHttpRequest
request(kSimpleGET_Transaction
);
5615 Context
* c
= new Context();
5616 int rv
= cache
.CreateTransaction(&c
->trans
);
5619 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5620 if (rv
== ERR_IO_PENDING
)
5621 rv
= c
->callback
.WaitForResult();
5623 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5624 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5625 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5627 // Make sure that the entry has some data stored.
5628 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5629 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5630 if (rv
== ERR_IO_PENDING
)
5631 rv
= c
->callback
.WaitForResult();
5632 EXPECT_EQ(buf
->size(), rv
);
5634 // Destroy the transaction.
5637 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5639 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5640 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5641 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5644 // Tests that we delete an entry when the request is cancelled if the response
5645 // has an "Accept-Ranges: none" header.
5646 TEST(HttpCache
, DoomOnDestruction3
) {
5647 MockHttpCache cache
;
5649 MockTransaction
transaction(kSimpleGET_Transaction
);
5650 transaction
.response_headers
=
5651 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5652 "Content-Length: 22\n"
5653 "Accept-Ranges: none\n"
5654 "Etag: \"foopy\"\n";
5655 AddMockTransaction(&transaction
);
5656 MockHttpRequest
request(transaction
);
5658 Context
* c
= new Context();
5659 int rv
= cache
.CreateTransaction(&c
->trans
);
5662 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5663 if (rv
== ERR_IO_PENDING
)
5664 rv
= c
->callback
.WaitForResult();
5666 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5667 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5668 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5670 // Make sure that the entry has some data stored.
5671 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5672 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5673 if (rv
== ERR_IO_PENDING
)
5674 rv
= c
->callback
.WaitForResult();
5675 EXPECT_EQ(buf
->size(), rv
);
5677 // Destroy the transaction.
5680 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5682 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5683 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5684 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5686 RemoveMockTransaction(&transaction
);
5689 // Tests that we mark an entry as incomplete when the request is cancelled.
5690 TEST(HttpCache
, SetTruncatedFlag
) {
5691 MockHttpCache cache
;
5693 MockTransaction
transaction(kSimpleGET_Transaction
);
5694 transaction
.response_headers
=
5695 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5696 "Content-Length: 22\n"
5697 "Etag: \"foopy\"\n";
5698 AddMockTransaction(&transaction
);
5699 MockHttpRequest
request(transaction
);
5701 scoped_ptr
<Context
> c(new Context());
5703 int rv
= cache
.CreateTransaction(&c
->trans
);
5706 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5707 if (rv
== ERR_IO_PENDING
)
5708 rv
= c
->callback
.WaitForResult();
5710 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5711 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5712 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5714 // Make sure that the entry has some data stored.
5715 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(10));
5716 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5717 if (rv
== ERR_IO_PENDING
)
5718 rv
= c
->callback
.WaitForResult();
5719 EXPECT_EQ(buf
->size(), rv
);
5721 // We want to cancel the request when the transaction is busy.
5722 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5723 EXPECT_EQ(ERR_IO_PENDING
, rv
);
5724 EXPECT_FALSE(c
->callback
.have_result());
5726 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5728 // Destroy the transaction.
5730 MockHttpCache::SetTestMode(0);
5733 // Make sure that we don't invoke the callback. We may have an issue if the
5734 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5735 // could end up with the transaction being deleted twice if we send any
5736 // notification from the transaction destructor (see http://crbug.com/31723).
5737 EXPECT_FALSE(c
->callback
.have_result());
5739 // Verify that the entry is marked as incomplete.
5740 disk_cache::Entry
* entry
;
5741 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5742 HttpResponseInfo response
;
5743 bool truncated
= false;
5744 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5745 EXPECT_TRUE(truncated
);
5748 RemoveMockTransaction(&transaction
);
5751 // Tests that we don't mark an entry as truncated when we read everything.
5752 TEST(HttpCache
, DontSetTruncatedFlag
) {
5753 MockHttpCache cache
;
5755 MockTransaction
transaction(kSimpleGET_Transaction
);
5756 transaction
.response_headers
=
5757 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5758 "Content-Length: 22\n"
5759 "Etag: \"foopy\"\n";
5760 AddMockTransaction(&transaction
);
5761 MockHttpRequest
request(transaction
);
5763 scoped_ptr
<Context
> c(new Context());
5764 int rv
= cache
.CreateTransaction(&c
->trans
);
5767 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5768 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5771 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(22));
5772 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5773 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5775 // Destroy the transaction.
5778 // Verify that the entry is not marked as truncated.
5779 disk_cache::Entry
* entry
;
5780 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5781 HttpResponseInfo response
;
5782 bool truncated
= true;
5783 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5784 EXPECT_FALSE(truncated
);
5787 RemoveMockTransaction(&transaction
);
5790 // Tests that we can continue with a request that was interrupted.
5791 TEST(HttpCache
, GET_IncompleteResource
) {
5792 MockHttpCache cache
;
5793 AddMockTransaction(&kRangeGET_TransactionOK
);
5795 std::string
raw_headers("HTTP/1.1 200 OK\n"
5796 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5798 "Accept-Ranges: bytes\n"
5799 "Content-Length: 80\n");
5800 CreateTruncatedEntry(raw_headers
, &cache
);
5802 // Now make a regular request.
5803 std::string headers
;
5804 MockTransaction
transaction(kRangeGET_TransactionOK
);
5805 transaction
.request_headers
= EXTRA_HEADER
;
5806 transaction
.data
= kFullRangeData
;
5807 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5809 // We update the headers with the ones received while revalidating.
5810 std::string
expected_headers(
5812 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5813 "Accept-Ranges: bytes\n"
5815 "Content-Length: 80\n");
5817 EXPECT_EQ(expected_headers
, headers
);
5818 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5819 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5820 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5822 // Verify that the disk entry was updated.
5823 disk_cache::Entry
* entry
;
5824 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5825 EXPECT_EQ(80, entry
->GetDataSize(1));
5826 bool truncated
= true;
5827 HttpResponseInfo response
;
5828 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5829 EXPECT_FALSE(truncated
);
5832 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5835 // Tests the handling of no-store when revalidating a truncated entry.
5836 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5837 MockHttpCache cache
;
5838 AddMockTransaction(&kRangeGET_TransactionOK
);
5840 std::string
raw_headers("HTTP/1.1 200 OK\n"
5841 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5843 "Accept-Ranges: bytes\n"
5844 "Content-Length: 80\n");
5845 CreateTruncatedEntry(raw_headers
, &cache
);
5846 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5848 // Now make a regular request.
5849 MockTransaction
transaction(kRangeGET_TransactionOK
);
5850 transaction
.request_headers
= EXTRA_HEADER
;
5851 std::string
response_headers(transaction
.response_headers
);
5852 response_headers
+= ("Cache-Control: no-store\n");
5853 transaction
.response_headers
= response_headers
.c_str();
5854 transaction
.data
= kFullRangeData
;
5855 AddMockTransaction(&transaction
);
5857 std::string headers
;
5858 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5860 // We update the headers with the ones received while revalidating.
5861 std::string
expected_headers(
5863 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5864 "Accept-Ranges: bytes\n"
5865 "Cache-Control: no-store\n"
5867 "Content-Length: 80\n");
5869 EXPECT_EQ(expected_headers
, headers
);
5870 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5871 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5872 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5874 // Verify that the disk entry was deleted.
5875 disk_cache::Entry
* entry
;
5876 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5877 RemoveMockTransaction(&transaction
);
5880 // Tests cancelling a request after the server sent no-store.
5881 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5882 MockHttpCache cache
;
5883 AddMockTransaction(&kRangeGET_TransactionOK
);
5885 std::string
raw_headers("HTTP/1.1 200 OK\n"
5886 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5888 "Accept-Ranges: bytes\n"
5889 "Content-Length: 80\n");
5890 CreateTruncatedEntry(raw_headers
, &cache
);
5891 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5893 // Now make a regular request.
5894 MockTransaction
transaction(kRangeGET_TransactionOK
);
5895 transaction
.request_headers
= EXTRA_HEADER
;
5896 std::string
response_headers(transaction
.response_headers
);
5897 response_headers
+= ("Cache-Control: no-store\n");
5898 transaction
.response_headers
= response_headers
.c_str();
5899 transaction
.data
= kFullRangeData
;
5900 AddMockTransaction(&transaction
);
5902 MockHttpRequest
request(transaction
);
5903 Context
* c
= new Context();
5905 int rv
= cache
.CreateTransaction(&c
->trans
);
5908 // Queue another request to this transaction. We have to start this request
5909 // before the first one gets the response from the server and dooms the entry,
5910 // otherwise it will just create a new entry without being queued to the first
5912 Context
* pending
= new Context();
5913 ASSERT_EQ(OK
, cache
.CreateTransaction(&pending
->trans
));
5915 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
5916 EXPECT_EQ(ERR_IO_PENDING
,
5917 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5919 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
5921 // Make sure that the entry has some data stored.
5922 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(5));
5923 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5924 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5926 // Cancel the requests.
5930 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5931 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5932 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5934 base::MessageLoop::current()->RunUntilIdle();
5935 RemoveMockTransaction(&transaction
);
5938 // Tests that we delete truncated entries if the server changes its mind midway.
5939 TEST(HttpCache
, GET_IncompleteResource2
) {
5940 MockHttpCache cache
;
5941 AddMockTransaction(&kRangeGET_TransactionOK
);
5943 // Content-length will be intentionally bad.
5944 std::string
raw_headers("HTTP/1.1 200 OK\n"
5945 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5947 "Accept-Ranges: bytes\n"
5948 "Content-Length: 50\n");
5949 CreateTruncatedEntry(raw_headers
, &cache
);
5951 // Now make a regular request. We expect the code to fail the validation and
5952 // retry the request without using byte ranges.
5953 std::string headers
;
5954 MockTransaction
transaction(kRangeGET_TransactionOK
);
5955 transaction
.request_headers
= EXTRA_HEADER
;
5956 transaction
.data
= "Not a range";
5957 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5959 // The server will return 200 instead of a byte range.
5960 std::string
expected_headers(
5962 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5964 EXPECT_EQ(expected_headers
, headers
);
5965 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5966 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5967 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5969 // Verify that the disk entry was deleted.
5970 disk_cache::Entry
* entry
;
5971 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5972 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5975 // Tests that we always validate a truncated request.
5976 TEST(HttpCache
, GET_IncompleteResource3
) {
5977 MockHttpCache cache
;
5978 AddMockTransaction(&kRangeGET_TransactionOK
);
5980 // This should not require validation for 10 hours.
5981 std::string
raw_headers("HTTP/1.1 200 OK\n"
5982 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5984 "Cache-Control: max-age= 36000\n"
5985 "Accept-Ranges: bytes\n"
5986 "Content-Length: 80\n");
5987 CreateTruncatedEntry(raw_headers
, &cache
);
5989 // Now make a regular request.
5990 std::string headers
;
5991 MockTransaction
transaction(kRangeGET_TransactionOK
);
5992 transaction
.request_headers
= EXTRA_HEADER
;
5993 transaction
.data
= kFullRangeData
;
5995 scoped_ptr
<Context
> c(new Context
);
5996 int rv
= cache
.CreateTransaction(&c
->trans
);
5999 MockHttpRequest
request(transaction
);
6000 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6001 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6003 // We should have checked with the server before finishing Start().
6004 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6005 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6006 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6008 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6011 // Tests that we handle 401s for truncated resources.
6012 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
6013 MockHttpCache cache
;
6014 AddMockTransaction(&kRangeGET_TransactionOK
);
6016 std::string
raw_headers("HTTP/1.1 200 OK\n"
6017 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6019 "Accept-Ranges: bytes\n"
6020 "Content-Length: 80\n");
6021 CreateTruncatedEntry(raw_headers
, &cache
);
6023 // Now make a regular request.
6024 MockTransaction
transaction(kRangeGET_TransactionOK
);
6025 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
6027 transaction
.data
= kFullRangeData
;
6028 RangeTransactionServer handler
;
6030 scoped_ptr
<Context
> c(new Context
);
6031 int rv
= cache
.CreateTransaction(&c
->trans
);
6034 MockHttpRequest
request(transaction
);
6035 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6036 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6038 const HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
6039 ASSERT_TRUE(response
);
6040 ASSERT_EQ(401, response
->headers
->response_code());
6041 rv
= c
->trans
->RestartWithAuth(AuthCredentials(), c
->callback
.callback());
6042 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6043 response
= c
->trans
->GetResponseInfo();
6044 ASSERT_TRUE(response
);
6045 ASSERT_EQ(200, response
->headers
->response_code());
6047 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
6048 c
.reset(); // The destructor could delete the entry.
6049 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6051 // Verify that the entry was not deleted.
6052 disk_cache::Entry
* entry
;
6053 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6056 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6059 // Tests that we cache a 200 response to the validation request.
6060 TEST(HttpCache
, GET_IncompleteResource4
) {
6061 MockHttpCache cache
;
6062 AddMockTransaction(&kRangeGET_TransactionOK
);
6064 std::string
raw_headers("HTTP/1.1 200 OK\n"
6065 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6067 "Accept-Ranges: bytes\n"
6068 "Content-Length: 80\n");
6069 CreateTruncatedEntry(raw_headers
, &cache
);
6071 // Now make a regular request.
6072 std::string headers
;
6073 MockTransaction
transaction(kRangeGET_TransactionOK
);
6074 transaction
.request_headers
= EXTRA_HEADER
;
6075 transaction
.data
= "Not a range";
6076 RangeTransactionServer handler
;
6077 handler
.set_bad_200(true);
6078 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
6080 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6081 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6082 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6084 // Verify that the disk entry was updated.
6085 disk_cache::Entry
* entry
;
6086 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6087 EXPECT_EQ(11, entry
->GetDataSize(1));
6088 bool truncated
= true;
6089 HttpResponseInfo response
;
6090 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6091 EXPECT_FALSE(truncated
);
6094 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6097 // Tests that when we cancel a request that was interrupted, we mark it again
6099 TEST(HttpCache
, GET_CancelIncompleteResource
) {
6100 MockHttpCache cache
;
6101 AddMockTransaction(&kRangeGET_TransactionOK
);
6103 std::string
raw_headers("HTTP/1.1 200 OK\n"
6104 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6106 "Accept-Ranges: bytes\n"
6107 "Content-Length: 80\n");
6108 CreateTruncatedEntry(raw_headers
, &cache
);
6110 // Now make a regular request.
6111 MockTransaction
transaction(kRangeGET_TransactionOK
);
6112 transaction
.request_headers
= EXTRA_HEADER
;
6114 MockHttpRequest
request(transaction
);
6115 Context
* c
= new Context();
6116 int rv
= cache
.CreateTransaction(&c
->trans
);
6119 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), BoundNetLog());
6120 EXPECT_EQ(OK
, c
->callback
.GetResult(rv
));
6122 // Read 20 bytes from the cache, and 10 from the net.
6123 scoped_refptr
<IOBuffer
> buf(new IOBuffer(100));
6124 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
6125 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
6126 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
6127 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
6129 // At this point, we are already reading so canceling the request should leave
6133 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6134 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6135 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6137 // Verify that the disk entry was updated: now we have 30 bytes.
6138 disk_cache::Entry
* entry
;
6139 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6140 EXPECT_EQ(30, entry
->GetDataSize(1));
6141 bool truncated
= false;
6142 HttpResponseInfo response
;
6143 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6144 EXPECT_TRUE(truncated
);
6146 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6149 // Tests that we can handle range requests when we have a truncated entry.
6150 TEST(HttpCache
, RangeGET_IncompleteResource
) {
6151 MockHttpCache cache
;
6152 AddMockTransaction(&kRangeGET_TransactionOK
);
6154 // Content-length will be intentionally bogus.
6155 std::string
raw_headers("HTTP/1.1 200 OK\n"
6156 "Last-Modified: something\n"
6158 "Accept-Ranges: bytes\n"
6159 "Content-Length: 10\n");
6160 CreateTruncatedEntry(raw_headers
, &cache
);
6162 // Now make a range request.
6163 std::string headers
;
6164 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
6167 Verify206Response(headers
, 40, 49);
6168 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6169 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6170 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6172 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6175 TEST(HttpCache
, SyncRead
) {
6176 MockHttpCache cache
;
6178 // This test ensures that a read that completes synchronously does not cause
6181 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6182 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
6183 TEST_MODE_SYNC_CACHE_READ
|
6184 TEST_MODE_SYNC_CACHE_WRITE
);
6186 MockHttpRequest
r1(transaction
),
6190 TestTransactionConsumer
c1(DEFAULT_PRIORITY
, cache
.http_cache()),
6191 c2(DEFAULT_PRIORITY
, cache
.http_cache()),
6192 c3(DEFAULT_PRIORITY
, cache
.http_cache());
6194 c1
.Start(&r1
, BoundNetLog());
6196 r2
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6197 c2
.Start(&r2
, BoundNetLog());
6199 r3
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6200 c3
.Start(&r3
, BoundNetLog());
6202 base::MessageLoop::current()->Run();
6204 EXPECT_TRUE(c1
.is_done());
6205 EXPECT_TRUE(c2
.is_done());
6206 EXPECT_TRUE(c3
.is_done());
6208 EXPECT_EQ(OK
, c1
.error());
6209 EXPECT_EQ(OK
, c2
.error());
6210 EXPECT_EQ(OK
, c3
.error());
6213 TEST(HttpCache
, ValidationResultsIn200
) {
6214 MockHttpCache cache
;
6216 // This test ensures that a conditional request, which results in a 200
6217 // instead of a 304, properly truncates the existing response data.
6219 // write to the cache
6220 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6222 // force this transaction to validate the cache
6223 MockTransaction
transaction(kETagGET_Transaction
);
6224 transaction
.load_flags
|= LOAD_VALIDATE_CACHE
;
6225 RunTransactionTest(cache
.http_cache(), transaction
);
6227 // read from the cache
6228 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6231 TEST(HttpCache
, CachedRedirect
) {
6232 MockHttpCache cache
;
6234 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
6235 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
6236 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
6238 MockHttpRequest
request(kTestTransaction
);
6239 TestCompletionCallback callback
;
6241 // Write to the cache.
6243 scoped_ptr
<HttpTransaction
> trans
;
6244 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6246 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6247 if (rv
== ERR_IO_PENDING
)
6248 rv
= callback
.WaitForResult();
6251 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6254 EXPECT_EQ(info
->headers
->response_code(), 301);
6256 std::string location
;
6257 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6258 EXPECT_EQ(location
, "http://www.bar.com/");
6260 // Mark the transaction as completed so it is cached.
6261 trans
->DoneReading();
6263 // Destroy transaction when going out of scope. We have not actually
6264 // read the response body -- want to test that it is still getting cached.
6266 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6267 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6268 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6270 // Active entries in the cache are not retired synchronously. Make
6271 // sure the next run hits the MockHttpCache and open_count is
6273 base::MessageLoop::current()->RunUntilIdle();
6275 // Read from the cache.
6277 scoped_ptr
<HttpTransaction
> trans
;
6278 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6280 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6281 if (rv
== ERR_IO_PENDING
)
6282 rv
= callback
.WaitForResult();
6285 const HttpResponseInfo
* info
= trans
->GetResponseInfo();
6288 EXPECT_EQ(info
->headers
->response_code(), 301);
6290 std::string location
;
6291 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6292 EXPECT_EQ(location
, "http://www.bar.com/");
6294 // Mark the transaction as completed so it is cached.
6295 trans
->DoneReading();
6297 // Destroy transaction when going out of scope. We have not actually
6298 // read the response body -- want to test that it is still getting cached.
6300 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6301 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6302 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6305 // Verify that no-cache resources are stored in cache, but are not fetched from
6306 // cache during normal loads.
6307 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
6308 MockHttpCache cache
;
6310 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6311 transaction
.response_headers
= "cache-control: no-cache\n";
6314 RunTransactionTest(cache
.http_cache(), transaction
);
6316 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6317 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6318 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6320 // Try loading again; it should result in a network fetch.
6321 RunTransactionTest(cache
.http_cache(), transaction
);
6323 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6324 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6325 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6327 disk_cache::Entry
* entry
;
6328 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6332 // Verify that no-cache resources are stored in cache and fetched from cache
6333 // when the LOAD_PREFERRING_CACHE flag is set.
6334 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
6335 MockHttpCache cache
;
6337 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6338 transaction
.response_headers
= "cache-control: no-cache\n";
6341 RunTransactionTest(cache
.http_cache(), transaction
);
6343 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6344 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6345 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6347 // Try loading again with LOAD_PREFERRING_CACHE.
6348 transaction
.load_flags
= LOAD_PREFERRING_CACHE
;
6349 RunTransactionTest(cache
.http_cache(), transaction
);
6351 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6352 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6353 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6355 disk_cache::Entry
* entry
;
6356 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6360 TEST(HttpCache
, CacheControlNoStore
) {
6361 MockHttpCache cache
;
6363 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6364 transaction
.response_headers
= "cache-control: no-store\n";
6367 RunTransactionTest(cache
.http_cache(), transaction
);
6369 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6370 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6371 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6373 // try loading again; it should result in a network fetch
6374 RunTransactionTest(cache
.http_cache(), transaction
);
6376 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6377 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6378 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6380 disk_cache::Entry
* entry
;
6381 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6384 TEST(HttpCache
, CacheControlNoStore2
) {
6385 // this test is similar to the above test, except that the initial response
6386 // is cachable, but when it is validated, no-store is received causing the
6387 // cached document to be deleted.
6388 MockHttpCache cache
;
6390 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6393 RunTransactionTest(cache
.http_cache(), transaction
);
6395 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6396 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6397 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6399 // try loading again; it should result in a network fetch
6400 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6401 transaction
.response_headers
= "cache-control: no-store\n";
6402 RunTransactionTest(cache
.http_cache(), transaction
);
6404 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6405 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6406 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6408 disk_cache::Entry
* entry
;
6409 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6412 TEST(HttpCache
, CacheControlNoStore3
) {
6413 // this test is similar to the above test, except that the response is a 304
6414 // instead of a 200. this should never happen in practice, but it seems like
6415 // a good thing to verify that we still destroy the cache entry.
6416 MockHttpCache cache
;
6418 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6421 RunTransactionTest(cache
.http_cache(), transaction
);
6423 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6424 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6425 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6427 // try loading again; it should result in a network fetch
6428 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
6429 transaction
.response_headers
= "cache-control: no-store\n";
6430 transaction
.status
= "HTTP/1.1 304 Not Modified";
6431 RunTransactionTest(cache
.http_cache(), transaction
);
6433 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6434 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6435 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6437 disk_cache::Entry
* entry
;
6438 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6441 // Ensure that we don't cache requests served over bad HTTPS.
6442 TEST(HttpCache
, SimpleGET_SSLError
) {
6443 MockHttpCache cache
;
6445 MockTransaction transaction
= kSimpleGET_Transaction
;
6446 transaction
.cert_status
= CERT_STATUS_REVOKED
;
6447 ScopedMockTransaction
scoped_transaction(transaction
);
6449 // write to the cache
6450 RunTransactionTest(cache
.http_cache(), transaction
);
6452 // Test that it was not cached.
6453 transaction
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
6455 MockHttpRequest
request(transaction
);
6456 TestCompletionCallback callback
;
6458 scoped_ptr
<HttpTransaction
> trans
;
6459 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6461 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6462 if (rv
== ERR_IO_PENDING
)
6463 rv
= callback
.WaitForResult();
6464 ASSERT_EQ(ERR_CACHE_MISS
, rv
);
6467 // Ensure that we don't crash by if left-behind transactions.
6468 TEST(HttpCache
, OutlivedTransactions
) {
6469 MockHttpCache
* cache
= new MockHttpCache
;
6471 scoped_ptr
<HttpTransaction
> trans
;
6472 EXPECT_EQ(OK
, cache
->CreateTransaction(&trans
));
6478 // Test that the disabled mode works.
6479 TEST(HttpCache
, CacheDisabledMode
) {
6480 MockHttpCache cache
;
6482 // write to the cache
6483 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6485 // go into disabled mode
6486 cache
.http_cache()->set_mode(HttpCache::DISABLE
);
6488 // force this transaction to write to the cache again
6489 MockTransaction
transaction(kSimpleGET_Transaction
);
6491 RunTransactionTest(cache
.http_cache(), transaction
);
6493 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6494 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6495 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6498 // Other tests check that the response headers of the cached response
6499 // get updated on 304. Here we specifically check that the
6500 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6501 // fields also gets updated.
6502 // http://crbug.com/20594.
6503 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6504 MockHttpCache cache
;
6506 const char kUrl
[] = "http://foobar";
6507 const char kData
[] = "body";
6509 MockTransaction mock_network_response
= { 0 };
6510 mock_network_response
.url
= kUrl
;
6512 AddMockTransaction(&mock_network_response
);
6514 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6516 MockTransaction request
= { 0 };
6518 request
.method
= "GET";
6519 request
.request_headers
= "\r\n";
6520 request
.data
= kData
;
6522 static const Response kNetResponse1
= {
6524 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6525 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6529 kNetResponse1
.AssignTo(&mock_network_response
);
6531 RunTransactionTest(cache
.http_cache(), request
);
6533 // Request |kUrl| again, this time validating the cache and getting
6536 request
.load_flags
= LOAD_VALIDATE_CACHE
;
6538 static const Response kNetResponse2
= {
6539 "HTTP/1.1 304 Not Modified",
6540 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6544 kNetResponse2
.AssignTo(&mock_network_response
);
6546 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6547 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6549 mock_network_response
.request_time
= request_time
;
6550 mock_network_response
.response_time
= response_time
;
6552 HttpResponseInfo response
;
6553 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6555 // The request and response times should have been updated.
6556 EXPECT_EQ(request_time
.ToInternalValue(),
6557 response
.request_time
.ToInternalValue());
6558 EXPECT_EQ(response_time
.ToInternalValue(),
6559 response
.response_time
.ToInternalValue());
6561 std::string headers
;
6562 response
.headers
->GetNormalizedHeaders(&headers
);
6564 EXPECT_EQ("HTTP/1.1 200 OK\n"
6565 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6566 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6569 RemoveMockTransaction(&mock_network_response
);
6572 // Tests that we can write metadata to an entry.
6573 TEST(HttpCache
, WriteMetadata_OK
) {
6574 MockHttpCache cache
;
6576 // Write to the cache
6577 HttpResponseInfo response
;
6578 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6580 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6583 cache
.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY
, Time::Now(),
6586 // Write meta data to the same entry.
6587 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6588 memset(buf
->data(), 0, buf
->size());
6589 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6590 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6591 DEFAULT_PRIORITY
, response
.response_time
,
6592 buf
.get(), buf
->size());
6594 // Release the buffer before the operation takes place.
6597 // Makes sure we finish pending operations.
6598 base::MessageLoop::current()->RunUntilIdle();
6600 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6602 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6603 EXPECT_EQ(50, response
.metadata
->size());
6604 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6606 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6607 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6608 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6611 // Tests that we only write metadata to an entry if the time stamp matches.
6612 TEST(HttpCache
, WriteMetadata_Fail
) {
6613 MockHttpCache cache
;
6615 // Write to the cache
6616 HttpResponseInfo response
;
6617 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6619 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6621 // Attempt to write meta data to the same entry.
6622 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6623 memset(buf
->data(), 0, buf
->size());
6624 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6625 base::Time expected_time
= response
.response_time
-
6626 base::TimeDelta::FromMilliseconds(20);
6627 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6628 DEFAULT_PRIORITY
, expected_time
, buf
.get(),
6631 // Makes sure we finish pending operations.
6632 base::MessageLoop::current()->RunUntilIdle();
6634 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6636 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6638 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6639 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6640 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6643 // Tests that we can read metadata after validating the entry and with READ mode
6645 TEST(HttpCache
, ReadMetadata
) {
6646 MockHttpCache cache
;
6648 // Write to the cache
6649 HttpResponseInfo response
;
6650 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6651 kTypicalGET_Transaction
, &response
);
6652 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6654 // Write meta data to the same entry.
6655 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(50));
6656 memset(buf
->data(), 0, buf
->size());
6657 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6658 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6659 DEFAULT_PRIORITY
, response
.response_time
,
6660 buf
.get(), buf
->size());
6662 // Makes sure we finish pending operations.
6663 base::MessageLoop::current()->RunUntilIdle();
6665 // Start with a READ mode transaction.
6666 MockTransaction
trans1(kTypicalGET_Transaction
);
6667 trans1
.load_flags
= LOAD_ONLY_FROM_CACHE
;
6669 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6670 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6671 EXPECT_EQ(50, response
.metadata
->size());
6672 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6674 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6675 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6676 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6677 base::MessageLoop::current()->RunUntilIdle();
6679 // Now make sure that the entry is re-validated with the server.
6680 trans1
.load_flags
= LOAD_VALIDATE_CACHE
;
6681 trans1
.status
= "HTTP/1.1 304 Not Modified";
6682 AddMockTransaction(&trans1
);
6684 response
.metadata
= NULL
;
6685 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6686 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6688 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6689 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6690 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6691 base::MessageLoop::current()->RunUntilIdle();
6692 RemoveMockTransaction(&trans1
);
6694 // Now return 200 when validating the entry so the metadata will be lost.
6695 MockTransaction
trans2(kTypicalGET_Transaction
);
6696 trans2
.load_flags
= LOAD_VALIDATE_CACHE
;
6697 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6698 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6700 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6701 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6702 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6705 // Tests that we don't mark entries as truncated when a filter detects the end
6707 TEST(HttpCache
, FilterCompletion
) {
6708 MockHttpCache cache
;
6709 TestCompletionCallback callback
;
6712 scoped_ptr
<HttpTransaction
> trans
;
6713 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6715 MockHttpRequest
request(kSimpleGET_Transaction
);
6716 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6717 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6719 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6720 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6721 EXPECT_GT(callback
.GetResult(rv
), 0);
6723 // Now make sure that the entry is preserved.
6724 trans
->DoneReading();
6727 // Make sure that the ActiveEntry is gone.
6728 base::MessageLoop::current()->RunUntilIdle();
6730 // Read from the cache.
6731 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6733 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6734 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6735 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6738 // Tests that we don't mark entries as truncated and release the cache
6739 // entry when DoneReading() is called before any Read() calls, such as
6741 TEST(HttpCache
, DoneReading
) {
6742 MockHttpCache cache
;
6743 TestCompletionCallback callback
;
6745 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6746 transaction
.data
= "";
6748 scoped_ptr
<HttpTransaction
> trans
;
6749 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6751 MockHttpRequest
request(transaction
);
6752 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6753 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6755 trans
->DoneReading();
6756 // Leave the transaction around.
6758 // Make sure that the ActiveEntry is gone.
6759 base::MessageLoop::current()->RunUntilIdle();
6761 // Read from the cache. This should not deadlock.
6762 RunTransactionTest(cache
.http_cache(), transaction
);
6764 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6765 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6766 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6769 // Tests that we stop caching when told.
6770 TEST(HttpCache
, StopCachingDeletesEntry
) {
6771 MockHttpCache cache
;
6772 TestCompletionCallback callback
;
6773 MockHttpRequest
request(kSimpleGET_Transaction
);
6776 scoped_ptr
<HttpTransaction
> trans
;
6777 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6779 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6780 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6782 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6783 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6784 EXPECT_EQ(10, callback
.GetResult(rv
));
6786 trans
->StopCaching();
6788 // We should be able to keep reading.
6789 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6790 EXPECT_GT(callback
.GetResult(rv
), 0);
6791 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6792 EXPECT_EQ(0, callback
.GetResult(rv
));
6795 // Make sure that the ActiveEntry is gone.
6796 base::MessageLoop::current()->RunUntilIdle();
6798 // Verify that the entry is gone.
6799 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6801 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6802 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6803 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6806 // Tests that we stop caching when told, even if DoneReading is called
6807 // after StopCaching.
6808 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6809 MockHttpCache cache
;
6810 TestCompletionCallback callback
;
6811 MockHttpRequest
request(kSimpleGET_Transaction
);
6814 scoped_ptr
<HttpTransaction
> trans
;
6815 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6817 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6818 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6820 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6821 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6822 EXPECT_EQ(10, callback
.GetResult(rv
));
6824 trans
->StopCaching();
6826 // We should be able to keep reading.
6827 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6828 EXPECT_GT(callback
.GetResult(rv
), 0);
6829 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6830 EXPECT_EQ(0, callback
.GetResult(rv
));
6832 // We should be able to call DoneReading.
6833 trans
->DoneReading();
6836 // Make sure that the ActiveEntry is gone.
6837 base::MessageLoop::current()->RunUntilIdle();
6839 // Verify that the entry is gone.
6840 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6842 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6843 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6844 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6847 // Tests that we stop caching when told, when using auth.
6848 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6849 MockHttpCache cache
;
6850 TestCompletionCallback callback
;
6851 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6852 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6853 AddMockTransaction(&mock_transaction
);
6854 MockHttpRequest
request(mock_transaction
);
6857 scoped_ptr
<HttpTransaction
> trans
;
6858 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6860 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6861 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6863 trans
->StopCaching();
6865 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6866 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6867 EXPECT_EQ(callback
.GetResult(rv
), 10);
6869 RemoveMockTransaction(&mock_transaction
);
6871 // Make sure that the ActiveEntry is gone.
6872 base::MessageLoop::current()->RunUntilIdle();
6874 // Verify that the entry is gone.
6875 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6877 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6878 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6879 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6882 // Tests that when we are told to stop caching we don't throw away valid data.
6883 TEST(HttpCache
, StopCachingSavesEntry
) {
6884 MockHttpCache cache
;
6885 TestCompletionCallback callback
;
6886 MockHttpRequest
request(kSimpleGET_Transaction
);
6889 scoped_ptr
<HttpTransaction
> trans
;
6890 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6892 // Force a response that can be resumed.
6893 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6894 AddMockTransaction(&mock_transaction
);
6895 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6896 "Content-Length: 42\n"
6899 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6900 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6902 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6903 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6904 EXPECT_EQ(callback
.GetResult(rv
), 10);
6906 trans
->StopCaching();
6908 // We should be able to keep reading.
6909 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6910 EXPECT_GT(callback
.GetResult(rv
), 0);
6911 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6912 EXPECT_EQ(callback
.GetResult(rv
), 0);
6914 RemoveMockTransaction(&mock_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 // Tests that we handle truncated enries when StopCaching is called.
6928 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6929 MockHttpCache cache
;
6930 TestCompletionCallback callback
;
6931 MockHttpRequest
request(kRangeGET_TransactionOK
);
6932 request
.extra_headers
.Clear();
6933 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6934 AddMockTransaction(&kRangeGET_TransactionOK
);
6936 std::string
raw_headers("HTTP/1.1 200 OK\n"
6937 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6939 "Accept-Ranges: bytes\n"
6940 "Content-Length: 80\n");
6941 CreateTruncatedEntry(raw_headers
, &cache
);
6944 // Now make a regular request.
6945 scoped_ptr
<HttpTransaction
> trans
;
6946 ASSERT_EQ(OK
, cache
.CreateTransaction(&trans
));
6948 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
6949 EXPECT_EQ(OK
, callback
.GetResult(rv
));
6951 scoped_refptr
<IOBuffer
> buf(new IOBuffer(256));
6952 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6953 EXPECT_EQ(callback
.GetResult(rv
), 10);
6955 // This is actually going to do nothing.
6956 trans
->StopCaching();
6958 // We should be able to keep reading.
6959 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6960 EXPECT_GT(callback
.GetResult(rv
), 0);
6961 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6962 EXPECT_GT(callback
.GetResult(rv
), 0);
6963 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6964 EXPECT_EQ(callback
.GetResult(rv
), 0);
6967 // Verify that the disk entry was updated.
6968 disk_cache::Entry
* entry
;
6969 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6970 EXPECT_EQ(80, entry
->GetDataSize(1));
6971 bool truncated
= true;
6972 HttpResponseInfo response
;
6973 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6974 EXPECT_FALSE(truncated
);
6977 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6980 // Tests that we detect truncated resources from the net when there is
6981 // a Content-Length header.
6982 TEST(HttpCache
, TruncatedByContentLength
) {
6983 MockHttpCache cache
;
6984 TestCompletionCallback callback
;
6986 MockTransaction
transaction(kSimpleGET_Transaction
);
6987 AddMockTransaction(&transaction
);
6988 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6989 "Content-Length: 100\n";
6990 RunTransactionTest(cache
.http_cache(), transaction
);
6991 RemoveMockTransaction(&transaction
);
6993 // Read from the cache.
6994 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6996 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6997 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6998 EXPECT_EQ(2, cache
.disk_cache()->create_count());
7001 // Tests that we actually flag entries as truncated when we detect an error
7003 TEST(HttpCache
, TruncatedByContentLength2
) {
7004 MockHttpCache cache
;
7005 TestCompletionCallback callback
;
7007 MockTransaction
transaction(kSimpleGET_Transaction
);
7008 AddMockTransaction(&transaction
);
7009 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
7010 "Content-Length: 100\n"
7012 RunTransactionTest(cache
.http_cache(), transaction
);
7013 RemoveMockTransaction(&transaction
);
7015 // Verify that the entry is marked as incomplete.
7016 disk_cache::Entry
* entry
;
7017 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
7018 HttpResponseInfo response
;
7019 bool truncated
= false;
7020 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
7021 EXPECT_TRUE(truncated
);
7025 // Make sure that calling SetPriority on a cache transaction passes on
7026 // its priority updates to its underlying network transaction.
7027 TEST(HttpCache
, SetPriority
) {
7028 MockHttpCache cache
;
7030 scoped_ptr
<HttpTransaction
> trans
;
7031 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
7033 // Shouldn't crash, but doesn't do anything either.
7034 trans
->SetPriority(LOW
);
7036 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7037 EXPECT_EQ(DEFAULT_PRIORITY
,
7038 cache
.network_layer()->last_create_transaction_priority());
7040 HttpRequestInfo info
;
7041 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7042 TestCompletionCallback callback
;
7043 EXPECT_EQ(ERR_IO_PENDING
,
7044 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7046 EXPECT_TRUE(cache
.network_layer()->last_transaction());
7047 if (cache
.network_layer()->last_transaction()) {
7048 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
7049 EXPECT_EQ(LOW
, cache
.network_layer()->last_transaction()->priority());
7052 trans
->SetPriority(HIGHEST
);
7054 if (cache
.network_layer()->last_transaction()) {
7055 EXPECT_EQ(LOW
, cache
.network_layer()->last_create_transaction_priority());
7056 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_transaction()->priority());
7059 EXPECT_EQ(OK
, callback
.WaitForResult());
7062 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7063 // transaction passes on its argument to the underlying network transaction.
7064 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
7065 MockHttpCache cache
;
7067 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
7068 scoped_ptr
<HttpTransaction
> trans
;
7069 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(IDLE
, &trans
));
7071 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7073 HttpRequestInfo info
;
7074 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7075 TestCompletionCallback callback
;
7076 EXPECT_EQ(ERR_IO_PENDING
,
7077 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7079 ASSERT_TRUE(cache
.network_layer()->last_transaction());
7080 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
7081 websocket_handshake_stream_create_helper());
7082 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
7083 EXPECT_EQ(&create_helper
,
7084 cache
.network_layer()->last_transaction()->
7085 websocket_handshake_stream_create_helper());
7086 EXPECT_EQ(OK
, callback
.WaitForResult());
7089 // Make sure that a cache transaction passes on its priority to
7090 // newly-created network transactions.
7091 TEST(HttpCache
, SetPriorityNewTransaction
) {
7092 MockHttpCache cache
;
7093 AddMockTransaction(&kRangeGET_TransactionOK
);
7095 std::string
raw_headers("HTTP/1.1 200 OK\n"
7096 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7098 "Accept-Ranges: bytes\n"
7099 "Content-Length: 80\n");
7100 CreateTruncatedEntry(raw_headers
, &cache
);
7102 // Now make a regular request.
7103 std::string headers
;
7104 MockTransaction
transaction(kRangeGET_TransactionOK
);
7105 transaction
.request_headers
= EXTRA_HEADER
;
7106 transaction
.data
= kFullRangeData
;
7108 scoped_ptr
<HttpTransaction
> trans
;
7109 ASSERT_EQ(OK
, cache
.http_cache()->CreateTransaction(MEDIUM
, &trans
));
7110 EXPECT_EQ(DEFAULT_PRIORITY
,
7111 cache
.network_layer()->last_create_transaction_priority());
7113 MockHttpRequest
info(transaction
);
7114 TestCompletionCallback callback
;
7115 EXPECT_EQ(ERR_IO_PENDING
,
7116 trans
->Start(&info
, callback
.callback(), BoundNetLog()));
7117 EXPECT_EQ(OK
, callback
.WaitForResult());
7119 EXPECT_EQ(MEDIUM
, cache
.network_layer()->last_create_transaction_priority());
7121 trans
->SetPriority(HIGHEST
);
7122 // Should trigger a new network transaction and pick up the new
7124 ReadAndVerifyTransaction(trans
.get(), transaction
);
7126 EXPECT_EQ(HIGHEST
, cache
.network_layer()->last_create_transaction_priority());
7128 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7131 int64
RunTransactionAndGetReceivedBytes(
7132 MockHttpCache
& cache
,
7133 const MockTransaction
& trans_info
) {
7134 int64 received_bytes
= -1;
7135 RunTransactionTestBase(cache
.http_cache(), trans_info
,
7136 MockHttpRequest(trans_info
), NULL
, BoundNetLog(), NULL
,
7138 return received_bytes
;
7141 int64
TransactionSize(const MockTransaction
& transaction
) {
7142 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
7143 strlen(transaction
.data
);
7146 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
7147 MockHttpCache cache
;
7149 MockTransaction
transaction(kSimpleGET_Transaction
);
7150 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7151 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7153 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7154 EXPECT_EQ(0, received_bytes
);
7157 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
7158 MockHttpCache cache
;
7160 ScopedMockTransaction
transaction(kETagGET_Transaction
);
7161 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7162 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7164 transaction
.load_flags
= LOAD_VALIDATE_CACHE
;
7165 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
7166 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7167 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7170 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
7171 MockHttpCache cache
;
7173 MockTransaction
transaction(kTypicalGET_Transaction
);
7174 transaction
.request_headers
= "Foo: bar\r\n";
7175 transaction
.response_headers
=
7176 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7177 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7179 "Cache-Control: max-age=0\n"
7181 AddMockTransaction(&transaction
);
7182 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7183 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7185 RevalidationServer server
;
7186 transaction
.handler
= server
.Handler
;
7187 transaction
.request_headers
= "Foo: none\r\n";
7188 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7189 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7191 RemoveMockTransaction(&transaction
);
7194 TEST(HttpCache
, ReceivedBytesRange
) {
7195 MockHttpCache cache
;
7196 AddMockTransaction(&kRangeGET_TransactionOK
);
7197 MockTransaction
transaction(kRangeGET_TransactionOK
);
7199 // Read bytes 40-49 from the network.
7200 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7201 int64 range_response_size
= TransactionSize(transaction
);
7202 EXPECT_EQ(range_response_size
, received_bytes
);
7204 // Read bytes 40-49 from the cache.
7205 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7206 EXPECT_EQ(0, received_bytes
);
7207 base::MessageLoop::current()->RunUntilIdle();
7209 // Read bytes 30-39 from the network.
7210 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
7211 transaction
.data
= "rg: 30-39 ";
7212 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7213 EXPECT_EQ(range_response_size
, received_bytes
);
7214 base::MessageLoop::current()->RunUntilIdle();
7216 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7217 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
7218 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7219 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7220 EXPECT_EQ(range_response_size
* 2, received_bytes
);
7222 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7225 class HttpCachePrefetchValidationTest
: public ::testing::Test
{
7227 static const int kMaxAgeSecs
= 100;
7228 static const int kRequireValidationSecs
= kMaxAgeSecs
+ 1;
7230 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction
) {
7231 DCHECK_LT(kMaxAgeSecs
, prefetch_reuse_mins() * kNumSecondsPerMinute
);
7233 clock_
= new base::SimpleTestClock();
7234 cache_
.http_cache()->SetClockForTesting(make_scoped_ptr(clock_
));
7235 cache_
.network_layer()->SetClock(clock_
);
7237 transaction_
.response_headers
= "Cache-Control: max-age=100\n";
7240 bool TransactionRequiredNetwork(int load_flags
) {
7241 int pre_transaction_count
= transaction_count();
7242 transaction_
.load_flags
= load_flags
;
7243 RunTransactionTest(cache_
.http_cache(), transaction_
);
7244 return pre_transaction_count
!= transaction_count();
7247 void AdvanceTime(int seconds
) {
7248 clock_
->Advance(base::TimeDelta::FromSeconds(seconds
));
7251 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins
; }
7253 // How many times this test has sent requests to the (fake) origin
7254 // server. Every test case needs to make at least one request to initialise
7256 int transaction_count() {
7257 return cache_
.network_layer()->transaction_count();
7260 MockHttpCache cache_
;
7261 ScopedMockTransaction transaction_
;
7262 std::string response_headers_
;
7263 base::SimpleTestClock
* clock_
;
7266 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationShortlyAfterPrefetch
) {
7267 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7268 AdvanceTime(kRequireValidationSecs
);
7269 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7272 TEST_F(HttpCachePrefetchValidationTest
, ValidateLongAfterPrefetch
) {
7273 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7274 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute
);
7275 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7278 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceOnly
) {
7279 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7280 AdvanceTime(kRequireValidationSecs
);
7281 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7282 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7285 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceReadOnly
) {
7286 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7287 AdvanceTime(kRequireValidationSecs
);
7288 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE
));
7289 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7292 TEST_F(HttpCachePrefetchValidationTest
, BypassCacheOverwritesPrefetch
) {
7293 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7294 AdvanceTime(kRequireValidationSecs
);
7295 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE
));
7296 AdvanceTime(kRequireValidationSecs
);
7297 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7300 TEST_F(HttpCachePrefetchValidationTest
,
7301 SkipValidationOnExistingEntryThatNeedsValidation
) {
7302 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7303 AdvanceTime(kRequireValidationSecs
);
7304 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7305 AdvanceTime(kRequireValidationSecs
);
7306 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7307 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7310 TEST_F(HttpCachePrefetchValidationTest
,
7311 SkipValidationOnExistingEntryThatDoesNotNeedValidation
) {
7312 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7313 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7314 AdvanceTime(kRequireValidationSecs
);
7315 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7316 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL
));
7319 TEST_F(HttpCachePrefetchValidationTest
, PrefetchMultipleTimes
) {
7320 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7321 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7322 AdvanceTime(kRequireValidationSecs
);
7323 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7326 TEST_F(HttpCachePrefetchValidationTest
, ValidateOnDelayedSecondPrefetch
) {
7327 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7328 AdvanceTime(kRequireValidationSecs
);
7329 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH
));
7330 AdvanceTime(kRequireValidationSecs
);
7331 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL
));
7334 // Framework for tests of stale-while-revalidate related functionality. With
7335 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
7336 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
7337 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
7338 // synchronous revalidation.
7339 class HttpCacheStaleWhileRevalidateTest
: public ::testing::Test
{
7341 HttpCacheStaleWhileRevalidateTest()
7342 : transaction_(kSimpleGET_Transaction
),
7344 stale_while_revalidate_(7200),
7345 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
7346 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(true);
7349 // RunTransactionTest() with the arguments from this fixture.
7350 void RunFixtureTransactionTest() {
7351 std::string response_headers
= base::StringPrintf(
7354 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
7357 stale_while_revalidate_
);
7358 transaction_
.response_headers
= response_headers
.c_str();
7359 RunTransactionTest(cache_
.http_cache(), transaction_
);
7360 transaction_
.response_headers
= "";
7363 // How many times this test has sent requests to the (fake) origin
7364 // server. Every test case needs to make at least one request to initialise
7366 int transaction_count() {
7367 return cache_
.network_layer()->transaction_count();
7370 // How many times an existing cache entry was opened during the test case.
7371 int open_count() { return cache_
.disk_cache()->open_count(); }
7373 MockHttpCache cache_
;
7374 ScopedMockTransaction transaction_
;
7376 int stale_while_revalidate_
;
7377 std::string validator_
;
7380 static void CheckResourceFreshnessHeader(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("Resource-Freshness", &value
));
7386 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
7389 // Verify that the Resource-Freshness header is sent on a revalidation if the
7390 // stale-while-revalidate directive was on the response.
7391 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderSent
) {
7392 age_
= 10801; // Outside the stale-while-revalidate window.
7394 // Write to the cache.
7395 RunFixtureTransactionTest();
7397 EXPECT_EQ(1, transaction_count());
7399 // Send the request again and check that Resource-Freshness header is added.
7400 transaction_
.handler
= CheckResourceFreshnessHeader
;
7402 RunFixtureTransactionTest();
7404 EXPECT_EQ(2, transaction_count());
7407 static void CheckResourceFreshnessAbsent(const HttpRequestInfo
* request
,
7408 std::string
* response_status
,
7409 std::string
* response_headers
,
7410 std::string
* response_data
) {
7411 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7414 // Verify that the Resource-Freshness header is not sent when
7415 // stale-while-revalidate is 0.
7416 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderNotSent
) {
7418 stale_while_revalidate_
= 0;
7420 // Write to the cache.
7421 RunFixtureTransactionTest();
7423 EXPECT_EQ(1, transaction_count());
7425 // Send the request again and check that Resource-Freshness header is absent.
7426 transaction_
.handler
= CheckResourceFreshnessAbsent
;
7428 RunFixtureTransactionTest();
7430 EXPECT_EQ(2, transaction_count());
7433 // Verify that when stale-while-revalidate applies the response is read from
7435 TEST_F(HttpCacheStaleWhileRevalidateTest
, ReadFromCache
) {
7436 // Write to the cache.
7437 RunFixtureTransactionTest();
7439 EXPECT_EQ(0, open_count());
7440 EXPECT_EQ(1, transaction_count());
7442 // Read back from the cache.
7443 RunFixtureTransactionTest();
7445 EXPECT_EQ(1, open_count());
7446 EXPECT_EQ(1, transaction_count());
7449 // Verify that when stale-while-revalidate applies an asynchronous request is
7451 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestSent
) {
7452 // Write to the cache.
7453 RunFixtureTransactionTest();
7455 EXPECT_EQ(1, transaction_count());
7457 // Read back from the cache.
7458 RunFixtureTransactionTest();
7460 EXPECT_EQ(1, transaction_count());
7462 // Let the async request execute.
7463 base::RunLoop().RunUntilIdle();
7464 EXPECT_EQ(2, transaction_count());
7467 // Verify that tearing down the HttpCache with an async revalidation in progress
7468 // does not break anything (this test is most likely to find problems when run
7469 // with a memory checker such as AddressSanitizer).
7470 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncTearDown
) {
7471 // Write to the cache.
7472 RunFixtureTransactionTest();
7474 // Read back from the cache.
7475 RunFixtureTransactionTest();
7478 static void CheckIfModifiedSinceHeader(const HttpRequestInfo
* request
,
7479 std::string
* response_status
,
7480 std::string
* response_headers
,
7481 std::string
* response_data
) {
7483 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-Modified-Since", &value
));
7484 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value
);
7487 // Verify that the async revalidation contains an If-Modified-Since header.
7488 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfModifiedSince
) {
7489 // Write to the cache.
7490 RunFixtureTransactionTest();
7492 transaction_
.handler
= CheckIfModifiedSinceHeader
;
7494 // Read back from the cache.
7495 RunFixtureTransactionTest();
7498 static void CheckIfNoneMatchHeader(const HttpRequestInfo
* request
,
7499 std::string
* response_status
,
7500 std::string
* response_headers
,
7501 std::string
* response_data
) {
7503 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-None-Match", &value
));
7504 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value
);
7507 // If the response had ETag rather than Last-Modified, then that is used to
7508 // conditionalise the response.
7509 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfNoneMatch
) {
7510 validator_
= "Etag: \"40a1-1320-4f6adefa22a40\"";
7512 // Write to the cache.
7513 RunFixtureTransactionTest();
7515 transaction_
.handler
= CheckIfNoneMatchHeader
;
7517 // Read back from the cache.
7518 RunFixtureTransactionTest();
7521 static void CheckResourceFreshnessHeaderPresent(const HttpRequestInfo
* request
,
7522 std::string
* response_status
,
7523 std::string
* response_headers
,
7524 std::string
* response_data
) {
7525 EXPECT_TRUE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7528 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestHasResourceFreshness
) {
7529 // Write to the cache.
7530 RunFixtureTransactionTest();
7532 transaction_
.handler
= CheckResourceFreshnessHeaderPresent
;
7534 // Read back from the cache.
7535 RunFixtureTransactionTest();
7538 // Verify that when age > max-age + stale-while-revalidate stale results are
7540 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedIfTooStale
) {
7543 // Write to the cache.
7544 RunFixtureTransactionTest();
7546 EXPECT_EQ(0, open_count());
7547 EXPECT_EQ(1, transaction_count());
7549 // Reading back reads from the network.
7550 RunFixtureTransactionTest();
7552 EXPECT_EQ(1, open_count());
7553 EXPECT_EQ(2, transaction_count());
7556 // HEAD requests should be able to take advantage of stale-while-revalidate.
7557 TEST_F(HttpCacheStaleWhileRevalidateTest
, WorksForHeadMethod
) {
7558 // Write to the cache. This has to be a GET request; HEAD requests don't
7559 // create new cache entries.
7560 RunFixtureTransactionTest();
7562 EXPECT_EQ(0, open_count());
7563 EXPECT_EQ(1, transaction_count());
7565 // Read back from the cache, and trigger an asynchronous HEAD request.
7566 transaction_
.method
= "HEAD";
7567 transaction_
.data
= "";
7569 RunFixtureTransactionTest();
7571 EXPECT_EQ(1, open_count());
7572 EXPECT_EQ(1, transaction_count());
7574 // Let the network request proceed.
7575 base::RunLoop().RunUntilIdle();
7577 EXPECT_EQ(2, transaction_count());
7580 // POST requests should not use stale-while-revalidate.
7581 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedToPost
) {
7582 transaction_
= ScopedMockTransaction(kSimplePOST_Transaction
);
7584 // Write to the cache.
7585 RunFixtureTransactionTest();
7587 EXPECT_EQ(0, open_count());
7588 EXPECT_EQ(1, transaction_count());
7590 // Reading back reads from the network.
7591 RunFixtureTransactionTest();
7593 EXPECT_EQ(0, open_count());
7594 EXPECT_EQ(2, transaction_count());
7597 static void CheckUrlMatches(const HttpRequestInfo
* request
,
7598 std::string
* response_status
,
7599 std::string
* response_headers
,
7600 std::string
* response_data
) {
7601 EXPECT_EQ("http://www.google.com/", request
->url
.spec());
7604 // Async revalidation is issued to the original URL.
7605 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestUrlMatches
) {
7606 transaction_
.url
= "http://www.google.com/";
7607 // Write to the cache.
7608 RunFixtureTransactionTest();
7610 // Read back from the cache.
7611 RunFixtureTransactionTest();
7613 EXPECT_EQ(1, transaction_count());
7615 transaction_
.handler
= CheckUrlMatches
;
7617 // Let the async request execute and perform the check.
7618 base::RunLoop().RunUntilIdle();
7619 EXPECT_EQ(2, transaction_count());
7622 class SyncLoadFlagTest
: public HttpCacheStaleWhileRevalidateTest
,
7623 public ::testing::WithParamInterface
<int> {};
7625 // Flags which should always cause the request to be synchronous.
7626 TEST_P(SyncLoadFlagTest
, MustBeSynchronous
) {
7627 transaction_
.load_flags
|= GetParam();
7628 // Write to the cache.
7629 RunFixtureTransactionTest();
7631 EXPECT_EQ(1, transaction_count());
7633 // Reading back reads from the network.
7634 RunFixtureTransactionTest();
7636 EXPECT_EQ(2, transaction_count());
7639 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate
,
7641 ::testing::Values(LOAD_VALIDATE_CACHE
,
7643 LOAD_DISABLE_CACHE
));
7645 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7646 PreferringCacheDoesNotTriggerAsyncRequest
) {
7647 transaction_
.load_flags
|= LOAD_PREFERRING_CACHE
;
7648 // Write to the cache.
7649 RunFixtureTransactionTest();
7651 EXPECT_EQ(1, transaction_count());
7653 // Reading back reads from the cache.
7654 RunFixtureTransactionTest();
7656 EXPECT_EQ(1, transaction_count());
7658 // If there was an async transaction created, it would run now.
7659 base::RunLoop().RunUntilIdle();
7661 // There was no async transaction.
7662 EXPECT_EQ(1, transaction_count());
7665 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotUsedWhenDisabled
) {
7666 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7667 // Write to the cache.
7668 RunFixtureTransactionTest();
7670 EXPECT_EQ(1, transaction_count());
7672 // A synchronous revalidation is performed.
7673 RunFixtureTransactionTest();
7675 EXPECT_EQ(2, transaction_count());
7678 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7679 OnlyFromCacheDoesNotTriggerAsyncRequest
) {
7680 transaction_
.load_flags
|= LOAD_ONLY_FROM_CACHE
;
7681 transaction_
.return_code
= ERR_CACHE_MISS
;
7683 // Writing to the cache should fail, because we are avoiding the network.
7684 RunFixtureTransactionTest();
7686 EXPECT_EQ(0, transaction_count());
7688 base::RunLoop().RunUntilIdle();
7691 EXPECT_EQ(0, transaction_count());
7694 // A certificate error during an asynchronous fetch should cause the next fetch
7695 // to proceed synchronously.
7696 // TODO(ricea): In future, only certificate errors which require user
7697 // interaction should fail the asynchronous revalidation, and they should cause
7698 // the next revalidation to be synchronous rather than requiring a total
7699 // refetch. This test will need to be updated appropriately.
7700 TEST_F(HttpCacheStaleWhileRevalidateTest
, CertificateErrorCausesRefetch
) {
7701 // Write to the cache.
7702 RunFixtureTransactionTest();
7704 EXPECT_EQ(1, transaction_count());
7706 // Now read back. RunTransactionTestBase() expects to receive the network
7707 // error back from the HttpCache::Transaction, but since the cache request
7708 // will return OK we need to duplicate some of its implementation here.
7709 transaction_
.return_code
= ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
7710 TestCompletionCallback callback
;
7711 scoped_ptr
<HttpTransaction
> trans
;
7712 int rv
= cache_
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
7714 ASSERT_TRUE(trans
.get());
7716 MockHttpRequest
request(transaction_
);
7717 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
7718 ASSERT_EQ(ERR_IO_PENDING
, rv
);
7719 ASSERT_EQ(OK
, callback
.WaitForResult());
7720 ReadAndVerifyTransaction(trans
.get(), transaction_
);
7722 EXPECT_EQ(1, transaction_count());
7724 // Allow the asynchronous fetch to run.
7725 base::RunLoop().RunUntilIdle();
7727 EXPECT_EQ(2, transaction_count());
7729 // Now run the transaction again. It should run synchronously.
7730 transaction_
.return_code
= OK
;
7731 RunFixtureTransactionTest();
7733 EXPECT_EQ(3, transaction_count());
7736 // Ensure that the response cached by the asynchronous request is not truncated,
7737 // even if the server is slow.
7738 TEST_F(HttpCacheStaleWhileRevalidateTest
, EntireResponseCached
) {
7739 transaction_
.test_mode
= TEST_MODE_SLOW_READ
;
7740 // Write to the cache.
7741 RunFixtureTransactionTest();
7743 // Read back from the cache.
7744 RunFixtureTransactionTest();
7746 // Let the async request execute.
7747 base::RunLoop().RunUntilIdle();
7749 // The cache entry should still be complete.
7750 transaction_
.load_flags
= LOAD_ONLY_FROM_CACHE
;
7751 RunFixtureTransactionTest();
7754 // Verify that there are no race conditions in the completely synchronous case.
7755 TEST_F(HttpCacheStaleWhileRevalidateTest
, SynchronousCaseWorks
) {
7756 transaction_
.test_mode
= TEST_MODE_SYNC_ALL
;
7757 // Write to the cache.
7758 RunFixtureTransactionTest();
7760 EXPECT_EQ(1, transaction_count());
7762 // Read back from the cache.
7763 RunFixtureTransactionTest();
7765 EXPECT_EQ(1, transaction_count());
7767 // Let the async request execute.
7768 base::RunLoop().RunUntilIdle();
7769 EXPECT_EQ(2, transaction_count());
7772 static void CheckLoadFlagsAsyncRevalidation(const HttpRequestInfo
* request
,
7773 std::string
* response_status
,
7774 std::string
* response_headers
,
7775 std::string
* response_data
) {
7776 EXPECT_EQ(LOAD_ASYNC_REVALIDATION
, request
->load_flags
);
7779 // Check that the load flags on the async request are the same as the load flags
7780 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7781 TEST_F(HttpCacheStaleWhileRevalidateTest
, LoadFlagsAsyncRevalidation
) {
7782 transaction_
.load_flags
= LOAD_NORMAL
;
7783 // Write to the cache.
7784 RunFixtureTransactionTest();
7786 EXPECT_EQ(1, transaction_count());
7788 // Read back from the cache.
7789 RunFixtureTransactionTest();
7791 EXPECT_EQ(1, transaction_count());
7793 transaction_
.handler
= CheckLoadFlagsAsyncRevalidation
;
7794 // Let the async request execute.
7795 base::RunLoop().RunUntilIdle();
7796 EXPECT_EQ(2, transaction_count());
7799 static void SimpleMockAuthHandler(const HttpRequestInfo
* request
,
7800 std::string
* response_status
,
7801 std::string
* response_headers
,
7802 std::string
* response_data
) {
7803 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
7804 !request
->extra_headers
.HasHeader("Authorization")) {
7805 response_status
->assign("HTTP/1.1 401 Unauthorized");
7806 response_headers
->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7809 response_status
->assign("HTTP/1.1 200 OK");
7812 TEST_F(HttpCacheStaleWhileRevalidateTest
, RestartForAuth
) {
7813 // Write to the cache.
7814 RunFixtureTransactionTest();
7816 EXPECT_EQ(1, transaction_count());
7818 // Now make the transaction require auth.
7819 transaction_
.request_headers
= "X-Require-Mock-Auth: dummy\r\n\r\n";
7820 transaction_
.handler
= SimpleMockAuthHandler
;
7822 // Read back from the cache.
7823 RunFixtureTransactionTest();
7825 EXPECT_EQ(1, transaction_count());
7827 // Let the async request execute.
7828 base::RunLoop().RunUntilIdle();
7830 EXPECT_EQ(2, transaction_count());
7833 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7834 // take place on a sparse entry.
7835 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7836 MockHttpCache cache
;
7838 // Create a transaction for bytes 0-9.
7839 MockHttpRequest
request(kRangeGET_TransactionOK
);
7840 MockTransaction
transaction(kRangeGET_TransactionOK
);
7841 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7842 transaction
.data
= "rg: 00-09 ";
7843 AddMockTransaction(&transaction
);
7845 TestCompletionCallback callback
;
7846 scoped_ptr
<HttpTransaction
> trans
;
7847 int rv
= cache
.http_cache()->CreateTransaction(DEFAULT_PRIORITY
, &trans
);
7849 ASSERT_TRUE(trans
.get());
7851 // Start our transaction.
7852 trans
->Start(&request
, callback
.callback(), BoundNetLog());
7854 // A second transaction on a different part of the file (the default
7855 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7856 // the already pending transaction.
7857 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7859 // Let the first transaction complete.
7860 callback
.WaitForResult();
7862 RemoveMockTransaction(&transaction
);
7865 // Makes sure that a request stops using the cache when the response headers
7866 // with "Cache-Control: no-store" arrives. That means that another request for
7867 // the same URL can be processed before the response body of the original
7869 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7870 MockHttpCache cache
;
7871 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7872 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7873 MockHttpRequest
request(mock_transaction
);
7875 scoped_ptr
<Context
> first(new Context
);
7876 first
->result
= cache
.CreateTransaction(&first
->trans
);
7877 ASSERT_EQ(OK
, first
->result
);
7878 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7880 first
->trans
->Start(&request
, first
->callback
.callback(), BoundNetLog());
7881 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7883 base::MessageLoop::current()->RunUntilIdle();
7884 EXPECT_EQ(LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7885 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7886 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7887 "Cache-Control", "no-store"));
7888 // Here we have read the response header but not read the response body yet.
7890 // Let us create the second (read) transaction.
7891 scoped_ptr
<Context
> second(new Context
);
7892 second
->result
= cache
.CreateTransaction(&second
->trans
);
7893 ASSERT_EQ(OK
, second
->result
);
7894 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7895 second
->result
= second
->trans
->Start(&request
, second
->callback
.callback(),
7898 // Here the second transaction proceeds without reading the first body.
7899 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7900 base::MessageLoop::current()->RunUntilIdle();
7901 EXPECT_EQ(LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7902 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7903 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7904 "Cache-Control", "no-store"));
7905 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);