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 "net/base/cache_type.h"
17 #include "net/base/elements_upload_data_stream.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/load_flags.h"
20 #include "net/base/load_timing_info.h"
21 #include "net/base/load_timing_info_test_util.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/net_log_unittest.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_request_headers.h"
29 #include "net/http/http_request_info.h"
30 #include "net/http/http_response_headers.h"
31 #include "net/http/http_response_info.h"
32 #include "net/http/http_transaction.h"
33 #include "net/http/http_transaction_test_util.h"
34 #include "net/http/http_util.h"
35 #include "net/http/mock_http_cache.h"
36 #include "net/socket/client_socket_handle.h"
37 #include "net/ssl/ssl_cert_request_info.h"
38 #include "net/websockets/websocket_handshake_stream_base.h"
39 #include "testing/gtest/include/gtest/gtest.h"
45 // Tests the load timing values of a request that goes through a
46 // MockNetworkTransaction.
47 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo
& load_timing_info
) {
48 EXPECT_FALSE(load_timing_info
.socket_reused
);
49 EXPECT_NE(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
51 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
52 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
54 net::ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
55 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
56 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
57 load_timing_info
.send_start
);
59 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
61 // Set by URLRequest / URLRequestHttpJob, at a higher level.
62 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
63 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
64 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
67 // Tests the load timing values of a request that receives a cached response.
68 void TestLoadTimingCachedResponse(const net::LoadTimingInfo
& load_timing_info
) {
69 EXPECT_FALSE(load_timing_info
.socket_reused
);
70 EXPECT_EQ(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
72 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
73 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
75 net::ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
77 // Only the send start / end times should be sent, and they should have the
79 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
80 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
82 // Set by URLRequest / URLRequestHttpJob, at a higher level.
83 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
84 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
85 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
88 class DeleteCacheCompletionCallback
: public net::TestCompletionCallbackBase
{
90 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
92 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
93 base::Unretained(this))) {
96 const net::CompletionCallback
& callback() const { return callback_
; }
99 void OnComplete(int result
) {
104 MockHttpCache
* cache_
;
105 net::CompletionCallback callback_
;
107 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
110 //-----------------------------------------------------------------------------
113 void ReadAndVerifyTransaction(net::HttpTransaction
* trans
,
114 const MockTransaction
& trans_info
) {
116 int rv
= ReadTransaction(trans
, &content
);
118 EXPECT_EQ(net::OK
, rv
);
119 std::string
expected(trans_info
.data
);
120 EXPECT_EQ(expected
, content
);
123 void RunTransactionTestBase(net::HttpCache
* cache
,
124 const MockTransaction
& trans_info
,
125 const MockHttpRequest
& request
,
126 net::HttpResponseInfo
* response_info
,
127 const net::BoundNetLog
& net_log
,
128 net::LoadTimingInfo
* load_timing_info
,
129 int64
* received_bytes
) {
130 net::TestCompletionCallback callback
;
132 // write to the cache
134 scoped_ptr
<net::HttpTransaction
> trans
;
135 int rv
= cache
->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
136 EXPECT_EQ(net::OK
, rv
);
137 ASSERT_TRUE(trans
.get());
139 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
140 if (rv
== net::ERR_IO_PENDING
)
141 rv
= callback
.WaitForResult();
142 ASSERT_EQ(trans_info
.return_code
, rv
);
147 const net::HttpResponseInfo
* response
= trans
->GetResponseInfo();
148 ASSERT_TRUE(response
);
151 *response_info
= *response
;
153 if (load_timing_info
) {
154 // If a fake network connection is used, need a NetLog to get a fake socket
156 EXPECT_TRUE(net_log
.net_log());
157 *load_timing_info
= net::LoadTimingInfo();
158 trans
->GetLoadTimingInfo(load_timing_info
);
161 ReadAndVerifyTransaction(trans
.get(), trans_info
);
164 *received_bytes
= trans
->GetTotalReceivedBytes();
167 void RunTransactionTestWithRequest(net::HttpCache
* cache
,
168 const MockTransaction
& trans_info
,
169 const MockHttpRequest
& request
,
170 net::HttpResponseInfo
* response_info
) {
171 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
172 net::BoundNetLog(), NULL
, NULL
);
175 void RunTransactionTestAndGetTiming(net::HttpCache
* cache
,
176 const MockTransaction
& trans_info
,
177 const net::BoundNetLog
& log
,
178 net::LoadTimingInfo
* load_timing_info
) {
179 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
180 NULL
, log
, load_timing_info
, NULL
);
183 void RunTransactionTest(net::HttpCache
* cache
,
184 const MockTransaction
& trans_info
) {
185 RunTransactionTestAndGetTiming(cache
, trans_info
, net::BoundNetLog(), NULL
);
188 void RunTransactionTestWithResponseInfo(net::HttpCache
* cache
,
189 const MockTransaction
& trans_info
,
190 net::HttpResponseInfo
* response
) {
191 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
195 void RunTransactionTestWithResponseInfoAndGetTiming(
196 net::HttpCache
* cache
,
197 const MockTransaction
& trans_info
,
198 net::HttpResponseInfo
* response
,
199 const net::BoundNetLog
& log
,
200 net::LoadTimingInfo
* load_timing_info
) {
201 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
202 response
, log
, load_timing_info
, NULL
);
205 void RunTransactionTestWithResponse(net::HttpCache
* cache
,
206 const MockTransaction
& trans_info
,
207 std::string
* response_headers
) {
208 net::HttpResponseInfo response
;
209 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
210 response
.headers
->GetNormalizedHeaders(response_headers
);
213 void RunTransactionTestWithResponseAndGetTiming(
214 net::HttpCache
* cache
,
215 const MockTransaction
& trans_info
,
216 std::string
* response_headers
,
217 const net::BoundNetLog
& log
,
218 net::LoadTimingInfo
* load_timing_info
) {
219 net::HttpResponseInfo response
;
220 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
221 &response
, log
, load_timing_info
, NULL
);
222 response
.headers
->GetNormalizedHeaders(response_headers
);
225 // This class provides a handler for kFastNoStoreGET_Transaction so that the
226 // no-store header can be included on demand.
227 class FastTransactionServer
{
229 FastTransactionServer() {
232 ~FastTransactionServer() {}
234 void set_no_store(bool value
) { no_store
= value
; }
236 static void FastNoStoreHandler(const net::HttpRequestInfo
* request
,
237 std::string
* response_status
,
238 std::string
* response_headers
,
239 std::string
* response_data
) {
241 *response_headers
= "Cache-Control: no-store\n";
245 static bool no_store
;
246 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
248 bool FastTransactionServer::no_store
;
250 const MockTransaction kFastNoStoreGET_Transaction
= {
251 "http://www.google.com/nostore",
255 net::LOAD_VALIDATE_CACHE
,
257 "Cache-Control: max-age=10000\n",
259 "<html><body>Google Blah Blah</body></html>",
260 TEST_MODE_SYNC_NET_START
,
261 &FastTransactionServer::FastNoStoreHandler
,
266 // This class provides a handler for kRangeGET_TransactionOK so that the range
267 // request can be served on demand.
268 class RangeTransactionServer
{
270 RangeTransactionServer() {
271 not_modified_
= false;
275 ~RangeTransactionServer() {
276 not_modified_
= false;
281 // Returns only 416 or 304 when set.
282 void set_not_modified(bool value
) { not_modified_
= value
; }
284 // Returns 206 when revalidating a range (instead of 304).
285 void set_modified(bool value
) { modified_
= value
; }
287 // Returns 200 instead of 206 (a malformed response overall).
288 void set_bad_200(bool value
) { bad_200_
= value
; }
290 static void RangeHandler(const net::HttpRequestInfo
* request
,
291 std::string
* response_status
,
292 std::string
* response_headers
,
293 std::string
* response_data
);
296 static bool not_modified_
;
297 static bool modified_
;
298 static bool bad_200_
;
299 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
301 bool RangeTransactionServer::not_modified_
= false;
302 bool RangeTransactionServer::modified_
= false;
303 bool RangeTransactionServer::bad_200_
= false;
305 // A dummy extra header that must be preserved on a given request.
307 // EXTRA_HEADER_LINE doesn't include a line terminator because it
308 // will be passed to AddHeaderFromString() which doesn't accept them.
309 #define EXTRA_HEADER_LINE "Extra: header"
311 // EXTRA_HEADER contains a line terminator, as expected by
312 // AddHeadersFromString() (_not_ AddHeaderFromString()).
313 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
315 static const char kExtraHeaderKey
[] = "Extra";
318 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo
* request
,
319 std::string
* response_status
,
320 std::string
* response_headers
,
321 std::string
* response_data
) {
322 if (request
->extra_headers
.IsEmpty()) {
323 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
324 response_data
->clear();
328 // We want to make sure we don't delete extra headers.
329 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
331 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
332 !request
->extra_headers
.HasHeader("Authorization")) {
333 response_status
->assign("HTTP/1.1 401 Unauthorized");
334 response_data
->assign("WWW-Authenticate: Foo\n");
339 response_status
->assign("HTTP/1.1 304 Not Modified");
340 response_data
->clear();
344 std::vector
<net::HttpByteRange
> ranges
;
345 std::string range_header
;
346 if (!request
->extra_headers
.GetHeader(
347 net::HttpRequestHeaders::kRange
, &range_header
) ||
348 !net::HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
349 ranges
.size() != 1) {
350 // This is not a byte range request. We return 200.
351 response_status
->assign("HTTP/1.1 200 OK");
352 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
353 response_data
->assign("Not a range");
357 // We can handle this range request.
358 net::HttpByteRange byte_range
= ranges
[0];
359 if (byte_range
.first_byte_position() > 79) {
360 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
361 response_data
->clear();
365 EXPECT_TRUE(byte_range
.ComputeBounds(80));
366 int start
= static_cast<int>(byte_range
.first_byte_position());
367 int end
= static_cast<int>(byte_range
.last_byte_position());
371 std::string content_range
= base::StringPrintf(
372 "Content-Range: bytes %d-%d/80\n", start
, end
);
373 response_headers
->append(content_range
);
375 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
378 EXPECT_EQ(0, end
% 10);
381 EXPECT_EQ(9, (end
- start
) % 10);
382 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
383 base::StringAppendF(&data
, "rg: %02d-%02d ",
384 block_start
, block_start
+ 9);
387 *response_data
= data
;
389 if (end
- start
!= 9) {
390 // We also have to fix content-length.
391 int len
= end
- start
+ 1;
392 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
394 response_headers
->replace(response_headers
->find("Content-Length:"),
395 content_length
.size(), content_length
);
398 response_status
->assign("HTTP/1.1 304 Not Modified");
399 response_data
->clear();
403 const MockTransaction kRangeGET_TransactionOK
= {
404 "http://www.google.com/range",
407 "Range: bytes = 40-49\r\n"
410 "HTTP/1.1 206 Partial Content",
411 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
413 "Accept-Ranges: bytes\n"
414 "Content-Length: 10\n",
418 &RangeTransactionServer::RangeHandler
,
423 // Verifies the response headers (|response|) match a partial content
424 // response for the range starting at |start| and ending at |end|.
425 void Verify206Response(std::string response
, int start
, int end
) {
426 std::string
raw_headers(net::HttpUtil::AssembleRawHeaders(response
.data(),
428 scoped_refptr
<net::HttpResponseHeaders
> headers(
429 new net::HttpResponseHeaders(raw_headers
));
431 ASSERT_EQ(206, headers
->response_code());
433 int64 range_start
, range_end
, object_size
;
435 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
436 int64 content_length
= headers
->GetContentLength();
438 int length
= end
- start
+ 1;
439 ASSERT_EQ(length
, content_length
);
440 ASSERT_EQ(start
, range_start
);
441 ASSERT_EQ(end
, range_end
);
444 // Creates a truncated entry that can be resumed using byte ranges.
445 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
446 // Create a disk cache entry that stores an incomplete resource.
447 disk_cache::Entry
* entry
;
448 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
451 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
454 net::HttpResponseInfo response
;
455 response
.response_time
= base::Time::Now();
456 response
.request_time
= base::Time::Now();
457 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
458 // Set the last argument for this to be an incomplete request.
459 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
461 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
462 int len
= static_cast<int>(base::strlcpy(buf
->data(),
463 "rg: 00-09 rg: 10-19 ", 100));
464 net::TestCompletionCallback cb
;
465 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
466 EXPECT_EQ(len
, cb
.GetResult(rv
));
470 // Helper to represent a network HTTP response.
472 // Set this response into |trans|.
473 void AssignTo(MockTransaction
* trans
) const {
474 trans
->status
= status
;
475 trans
->response_headers
= headers
;
479 std::string
status_and_headers() const {
480 return std::string(status
) + "\n" + std::string(headers
);
489 Context() : result(net::ERR_IO_PENDING
) {}
492 net::TestCompletionCallback callback
;
493 scoped_ptr
<net::HttpTransaction
> trans
;
496 class FakeWebSocketHandshakeStreamCreateHelper
497 : public net::WebSocketHandshakeStreamBase::CreateHelper
{
499 virtual ~FakeWebSocketHandshakeStreamCreateHelper() {}
500 virtual net::WebSocketHandshakeStreamBase
* CreateBasicStream(
501 scoped_ptr
<net::ClientSocketHandle
> connect
, bool using_proxy
) override
{
504 virtual net::WebSocketHandshakeStreamBase
* CreateSpdyStream(
505 const base::WeakPtr
<net::SpdySession
>& session
,
506 bool use_relative_url
) override
{
511 // Returns true if |entry| is not one of the log types paid attention to in this
512 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
514 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry
& entry
) {
515 switch (entry
.type
) {
516 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
517 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
518 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
519 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
520 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
521 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO
:
528 // Modifies |entries| to only include log entries created by the cache layer and
529 // asserted on in these tests.
530 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList
* entries
) {
531 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
532 &ShouldIgnoreLogEntry
),
539 //-----------------------------------------------------------------------------
542 TEST(HttpCache
, CreateThenDestroy
) {
545 scoped_ptr
<net::HttpTransaction
> trans
;
546 EXPECT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
547 ASSERT_TRUE(trans
.get());
550 TEST(HttpCache
, GetBackend
) {
551 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(0));
553 disk_cache::Backend
* backend
;
554 net::TestCompletionCallback cb
;
555 // This will lazily initialize the backend.
556 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
557 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
560 TEST(HttpCache
, SimpleGET
) {
562 net::CapturingBoundNetLog log
;
563 net::LoadTimingInfo load_timing_info
;
565 // Write to the cache.
566 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
567 log
.bound(), &load_timing_info
);
569 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
570 EXPECT_EQ(0, cache
.disk_cache()->open_count());
571 EXPECT_EQ(1, cache
.disk_cache()->create_count());
572 TestLoadTimingNetworkRequest(load_timing_info
);
575 TEST(HttpCache
, SimpleGETNoDiskCache
) {
578 cache
.disk_cache()->set_fail_requests();
580 net::CapturingBoundNetLog log
;
581 net::LoadTimingInfo load_timing_info
;
583 // Read from the network, and don't use the cache.
584 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
585 log
.bound(), &load_timing_info
);
587 // Check that the NetLog was filled as expected.
588 // (We attempted to both Open and Create entries, but both failed).
589 net::CapturingNetLog::CapturedEntryList entries
;
590 log
.GetEntries(&entries
);
591 FilterLogEntries(&entries
);
593 EXPECT_EQ(6u, entries
.size());
594 EXPECT_TRUE(net::LogContainsBeginEvent(
595 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
596 EXPECT_TRUE(net::LogContainsEndEvent(
597 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
598 EXPECT_TRUE(net::LogContainsBeginEvent(
599 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
600 EXPECT_TRUE(net::LogContainsEndEvent(
601 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
602 EXPECT_TRUE(net::LogContainsBeginEvent(
603 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
604 EXPECT_TRUE(net::LogContainsEndEvent(
605 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
607 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
608 EXPECT_EQ(0, cache
.disk_cache()->open_count());
609 EXPECT_EQ(0, cache
.disk_cache()->create_count());
610 TestLoadTimingNetworkRequest(load_timing_info
);
613 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
614 // This will initialize a cache object with NULL backend.
615 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
616 factory
->set_fail(true);
617 factory
->FinishCreation(); // We'll complete synchronously.
618 MockHttpCache
cache(factory
);
620 // Read from the network, and don't use the cache.
621 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
623 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
624 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
627 // Tests that IOBuffers are not referenced after IO completes.
628 TEST(HttpCache
, ReleaseBuffer
) {
631 // Write to the cache.
632 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
634 MockHttpRequest
request(kSimpleGET_Transaction
);
635 scoped_ptr
<net::HttpTransaction
> trans
;
636 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
638 const int kBufferSize
= 10;
639 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(kBufferSize
));
640 net::ReleaseBufferCompletionCallback
cb(buffer
.get());
642 int rv
= trans
->Start(&request
, cb
.callback(), net::BoundNetLog());
643 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
645 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
646 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
649 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
652 cache
.disk_cache()->set_soft_failures(true);
654 // Read from the network, and fail to write to the cache.
655 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
657 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
658 EXPECT_EQ(0, cache
.disk_cache()->open_count());
659 EXPECT_EQ(1, cache
.disk_cache()->create_count());
661 // This one should see an empty cache again.
662 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
664 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
665 EXPECT_EQ(0, cache
.disk_cache()->open_count());
666 EXPECT_EQ(2, cache
.disk_cache()->create_count());
669 // Tests that disk failures after the transaction has started don't cause the
671 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
674 MockHttpRequest
request(kSimpleGET_Transaction
);
676 scoped_ptr
<Context
> c(new Context());
677 int rv
= cache
.CreateTransaction(&c
->trans
);
678 ASSERT_EQ(net::OK
, rv
);
680 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
681 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
682 rv
= c
->callback
.WaitForResult();
684 // Start failing request now.
685 cache
.disk_cache()->set_soft_failures(true);
687 // We have to open the entry again to propagate the failure flag.
688 disk_cache::Entry
* en
;
689 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
692 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
695 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
696 EXPECT_EQ(1, cache
.disk_cache()->open_count());
697 EXPECT_EQ(1, cache
.disk_cache()->create_count());
699 // This one should see an empty cache again.
700 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
702 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
703 EXPECT_EQ(1, cache
.disk_cache()->open_count());
704 EXPECT_EQ(2, cache
.disk_cache()->create_count());
707 // Tests that we handle failures to read from the cache.
708 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
711 // Read from the network, and write to the cache.
712 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
714 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
715 EXPECT_EQ(0, cache
.disk_cache()->open_count());
716 EXPECT_EQ(1, cache
.disk_cache()->create_count());
718 cache
.disk_cache()->set_soft_failures(true);
720 // Now fail to read from the cache.
721 scoped_ptr
<Context
> c(new Context());
722 int rv
= cache
.CreateTransaction(&c
->trans
);
723 ASSERT_EQ(net::OK
, rv
);
725 MockHttpRequest
request(kSimpleGET_Transaction
);
726 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
727 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
729 // Now verify that the entry was removed from the cache.
730 cache
.disk_cache()->set_soft_failures(false);
732 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
733 EXPECT_EQ(1, cache
.disk_cache()->open_count());
734 EXPECT_EQ(2, cache
.disk_cache()->create_count());
736 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
738 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
739 EXPECT_EQ(1, cache
.disk_cache()->open_count());
740 EXPECT_EQ(3, cache
.disk_cache()->create_count());
743 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
746 net::CapturingBoundNetLog log
;
747 net::LoadTimingInfo load_timing_info
;
749 // Write to the cache.
750 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
751 log
.bound(), &load_timing_info
);
753 // Check that the NetLog was filled as expected.
754 net::CapturingNetLog::CapturedEntryList entries
;
755 log
.GetEntries(&entries
);
756 FilterLogEntries(&entries
);
758 EXPECT_EQ(8u, entries
.size());
759 EXPECT_TRUE(net::LogContainsBeginEvent(
760 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
761 EXPECT_TRUE(net::LogContainsEndEvent(
762 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
763 EXPECT_TRUE(net::LogContainsBeginEvent(
764 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
765 EXPECT_TRUE(net::LogContainsEndEvent(
766 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
767 EXPECT_TRUE(net::LogContainsBeginEvent(
768 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
769 EXPECT_TRUE(net::LogContainsEndEvent(
770 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
771 EXPECT_TRUE(net::LogContainsBeginEvent(
772 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
773 EXPECT_TRUE(net::LogContainsEndEvent(
774 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
776 TestLoadTimingNetworkRequest(load_timing_info
);
778 // Force this transaction to read from the cache.
779 MockTransaction
transaction(kSimpleGET_Transaction
);
780 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
784 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
787 // Check that the NetLog was filled as expected.
788 log
.GetEntries(&entries
);
789 FilterLogEntries(&entries
);
791 EXPECT_EQ(8u, entries
.size());
792 EXPECT_TRUE(net::LogContainsBeginEvent(
793 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
794 EXPECT_TRUE(net::LogContainsEndEvent(
795 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
796 EXPECT_TRUE(net::LogContainsBeginEvent(
797 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
798 EXPECT_TRUE(net::LogContainsEndEvent(
799 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
800 EXPECT_TRUE(net::LogContainsBeginEvent(
801 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
802 EXPECT_TRUE(net::LogContainsEndEvent(
803 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
804 EXPECT_TRUE(net::LogContainsBeginEvent(
805 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
806 EXPECT_TRUE(net::LogContainsEndEvent(
807 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
809 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
810 EXPECT_EQ(1, cache
.disk_cache()->open_count());
811 EXPECT_EQ(1, cache
.disk_cache()->create_count());
812 TestLoadTimingCachedResponse(load_timing_info
);
815 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
818 // force this transaction to read from the cache
819 MockTransaction
transaction(kSimpleGET_Transaction
);
820 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
822 MockHttpRequest
request(transaction
);
823 net::TestCompletionCallback callback
;
825 scoped_ptr
<net::HttpTransaction
> trans
;
826 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
828 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
829 if (rv
== net::ERR_IO_PENDING
)
830 rv
= callback
.WaitForResult();
831 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
835 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
836 EXPECT_EQ(0, cache
.disk_cache()->open_count());
837 EXPECT_EQ(0, cache
.disk_cache()->create_count());
840 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
843 // write to the cache
844 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
846 // force this transaction to read from the cache if valid
847 MockTransaction
transaction(kSimpleGET_Transaction
);
848 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
850 RunTransactionTest(cache
.http_cache(), transaction
);
852 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
853 EXPECT_EQ(1, cache
.disk_cache()->open_count());
854 EXPECT_EQ(1, cache
.disk_cache()->create_count());
857 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
860 // force this transaction to read from the cache if valid
861 MockTransaction
transaction(kSimpleGET_Transaction
);
862 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
864 RunTransactionTest(cache
.http_cache(), transaction
);
866 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
867 EXPECT_EQ(0, cache
.disk_cache()->open_count());
868 EXPECT_EQ(1, cache
.disk_cache()->create_count());
871 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
872 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
875 // Write to the cache.
876 MockTransaction
transaction(kSimpleGET_Transaction
);
877 transaction
.request_headers
= "Foo: bar\r\n";
878 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
880 AddMockTransaction(&transaction
);
881 RunTransactionTest(cache
.http_cache(), transaction
);
883 // Read from the cache.
884 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
885 RunTransactionTest(cache
.http_cache(), transaction
);
887 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
888 EXPECT_EQ(1, cache
.disk_cache()->open_count());
889 EXPECT_EQ(1, cache
.disk_cache()->create_count());
890 RemoveMockTransaction(&transaction
);
893 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
894 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
897 // Write to the cache.
898 MockTransaction
transaction(kSimpleGET_Transaction
);
899 transaction
.request_headers
= "Foo: bar\r\n";
900 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
902 AddMockTransaction(&transaction
);
903 RunTransactionTest(cache
.http_cache(), transaction
);
905 // Attempt to read from the cache... this is a vary mismatch that must reach
906 // the network again.
907 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
908 transaction
.request_headers
= "Foo: none\r\n";
909 net::CapturingBoundNetLog log
;
910 net::LoadTimingInfo load_timing_info
;
911 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
914 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
915 EXPECT_EQ(1, cache
.disk_cache()->open_count());
916 EXPECT_EQ(1, cache
.disk_cache()->create_count());
917 TestLoadTimingNetworkRequest(load_timing_info
);
918 RemoveMockTransaction(&transaction
);
921 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
923 TEST(HttpCache
, SimpleGET_CacheOverride_Network
) {
927 MockTransaction
transaction(kSimpleGET_Transaction
);
928 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
929 transaction
.response_headers
= "Cache-Control: no-cache\n";
931 AddMockTransaction(&transaction
);
932 RunTransactionTest(cache
.http_cache(), transaction
);
933 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
934 EXPECT_EQ(1, cache
.disk_cache()->create_count());
935 RemoveMockTransaction(&transaction
);
937 // Re-run transaction; make sure the result came from the network,
939 transaction
.data
= "Changed data.";
940 AddMockTransaction(&transaction
);
941 net::HttpResponseInfo response_info
;
942 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
945 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
946 EXPECT_FALSE(response_info
.server_data_unavailable
);
947 EXPECT_TRUE(response_info
.network_accessed
);
949 RemoveMockTransaction(&transaction
);
952 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
954 TEST(HttpCache
, SimpleGET_CacheOverride_Offline
) {
958 MockTransaction
transaction(kSimpleGET_Transaction
);
959 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
960 transaction
.response_headers
= "Cache-Control: no-cache\n";
962 AddMockTransaction(&transaction
);
963 RunTransactionTest(cache
.http_cache(), transaction
);
964 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
965 EXPECT_EQ(1, cache
.disk_cache()->create_count());
966 RemoveMockTransaction(&transaction
);
968 // Network failure with offline error; should return cache entry above +
969 // flag signalling stale data.
970 transaction
.return_code
= net::ERR_NAME_NOT_RESOLVED
;
971 AddMockTransaction(&transaction
);
973 MockHttpRequest
request(transaction
);
974 net::TestCompletionCallback callback
;
975 scoped_ptr
<net::HttpTransaction
> trans
;
976 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
977 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
978 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
980 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
981 ASSERT_TRUE(response_info
);
982 EXPECT_TRUE(response_info
->server_data_unavailable
);
983 EXPECT_TRUE(response_info
->was_cached
);
984 EXPECT_FALSE(response_info
->network_accessed
);
985 ReadAndVerifyTransaction(trans
.get(), transaction
);
986 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
988 RemoveMockTransaction(&transaction
);
991 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
992 // non-offline failure.
993 TEST(HttpCache
, SimpleGET_CacheOverride_NonOffline
) {
997 MockTransaction
transaction(kSimpleGET_Transaction
);
998 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
999 transaction
.response_headers
= "Cache-Control: no-cache\n";
1001 AddMockTransaction(&transaction
);
1002 RunTransactionTest(cache
.http_cache(), transaction
);
1003 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1004 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1005 RemoveMockTransaction(&transaction
);
1007 // Network failure with non-offline error; should fail with that error.
1008 transaction
.return_code
= net::ERR_PROXY_CONNECTION_FAILED
;
1009 AddMockTransaction(&transaction
);
1011 net::HttpResponseInfo response_info2
;
1012 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1015 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1016 EXPECT_FALSE(response_info2
.server_data_unavailable
);
1018 RemoveMockTransaction(&transaction
);
1021 // Tests that was_cached was set properly on a failure, even if the cached
1022 // response wasn't returned.
1023 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
1024 MockHttpCache cache
;
1027 MockTransaction
transaction(kSimpleGET_Transaction
);
1028 transaction
.response_headers
= "Cache-Control: no-cache\n";
1030 AddMockTransaction(&transaction
);
1031 RunTransactionTest(cache
.http_cache(), transaction
);
1032 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1033 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1034 RemoveMockTransaction(&transaction
);
1036 // Network failure with error; should fail but have was_cached set.
1037 transaction
.return_code
= net::ERR_FAILED
;
1038 AddMockTransaction(&transaction
);
1040 MockHttpRequest
request(transaction
);
1041 net::TestCompletionCallback callback
;
1042 scoped_ptr
<net::HttpTransaction
> trans
;
1043 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
1044 EXPECT_EQ(net::OK
, rv
);
1045 ASSERT_TRUE(trans
.get());
1046 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1047 EXPECT_EQ(net::ERR_FAILED
, callback
.GetResult(rv
));
1049 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1050 ASSERT_TRUE(response_info
);
1051 EXPECT_TRUE(response_info
->was_cached
);
1052 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1054 RemoveMockTransaction(&transaction
);
1057 // Confirm if we have an empty cache, a read is marked as network verified.
1058 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1059 MockHttpCache cache
;
1061 // write to the cache
1062 net::HttpResponseInfo response_info
;
1063 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1066 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1067 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1068 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1069 EXPECT_TRUE(response_info
.network_accessed
);
1072 // Confirm if we have a fresh entry in cache, it isn't marked as
1073 // network verified.
1074 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1075 MockHttpCache cache
;
1078 MockTransaction
transaction(kSimpleGET_Transaction
);
1080 RunTransactionTest(cache
.http_cache(), transaction
);
1081 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1082 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1084 // Re-run transaction; make sure we don't mark the network as accessed.
1085 net::HttpResponseInfo response_info
;
1086 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1089 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1090 EXPECT_FALSE(response_info
.server_data_unavailable
);
1091 EXPECT_FALSE(response_info
.network_accessed
);
1094 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1095 MockHttpCache cache
;
1097 // Write to the cache.
1098 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1100 // Force this transaction to write to the cache again.
1101 MockTransaction
transaction(kSimpleGET_Transaction
);
1102 transaction
.load_flags
|= net::LOAD_BYPASS_CACHE
;
1104 net::CapturingBoundNetLog log
;
1105 net::LoadTimingInfo load_timing_info
;
1107 // Write to the cache.
1108 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1111 // Check that the NetLog was filled as expected.
1112 net::CapturingNetLog::CapturedEntryList entries
;
1113 log
.GetEntries(&entries
);
1114 FilterLogEntries(&entries
);
1116 EXPECT_EQ(8u, entries
.size());
1117 EXPECT_TRUE(net::LogContainsBeginEvent(
1118 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1119 EXPECT_TRUE(net::LogContainsEndEvent(
1120 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1121 EXPECT_TRUE(net::LogContainsBeginEvent(
1122 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1123 EXPECT_TRUE(net::LogContainsEndEvent(
1124 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1125 EXPECT_TRUE(net::LogContainsBeginEvent(
1126 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1127 EXPECT_TRUE(net::LogContainsEndEvent(
1128 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1129 EXPECT_TRUE(net::LogContainsBeginEvent(
1130 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1131 EXPECT_TRUE(net::LogContainsEndEvent(
1132 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1134 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1135 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1136 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1137 TestLoadTimingNetworkRequest(load_timing_info
);
1140 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1141 MockHttpCache cache
;
1143 // write to the cache
1144 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1146 // force this transaction to write to the cache again
1147 MockTransaction
transaction(kSimpleGET_Transaction
);
1148 transaction
.request_headers
= "pragma: no-cache\r\n";
1150 RunTransactionTest(cache
.http_cache(), transaction
);
1152 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1153 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1154 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1157 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1158 MockHttpCache cache
;
1160 // write to the cache
1161 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1163 // force this transaction to write to the cache again
1164 MockTransaction
transaction(kSimpleGET_Transaction
);
1165 transaction
.request_headers
= "cache-control: no-cache\r\n";
1167 RunTransactionTest(cache
.http_cache(), transaction
);
1169 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1170 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1171 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1174 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1175 MockHttpCache cache
;
1177 // Write to the cache.
1178 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1180 // Read from the cache.
1181 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1183 // Force this transaction to validate the cache.
1184 MockTransaction
transaction(kSimpleGET_Transaction
);
1185 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
1187 net::HttpResponseInfo response_info
;
1188 net::CapturingBoundNetLog log
;
1189 net::LoadTimingInfo load_timing_info
;
1190 RunTransactionTestWithResponseInfoAndGetTiming(
1191 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1194 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1195 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1196 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1197 EXPECT_TRUE(response_info
.network_accessed
);
1198 TestLoadTimingNetworkRequest(load_timing_info
);
1201 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1202 MockHttpCache cache
;
1204 // write to the cache
1205 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1207 // read from the cache
1208 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1210 // force this transaction to validate the cache
1211 MockTransaction
transaction(kSimpleGET_Transaction
);
1212 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1214 RunTransactionTest(cache
.http_cache(), transaction
);
1216 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1217 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1218 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1221 static void PreserveRequestHeaders_Handler(
1222 const net::HttpRequestInfo
* request
,
1223 std::string
* response_status
,
1224 std::string
* response_headers
,
1225 std::string
* response_data
) {
1226 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1229 // Tests that we don't remove extra headers for simple requests.
1230 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1231 MockHttpCache cache
;
1233 MockTransaction
transaction(kSimpleGET_Transaction
);
1234 transaction
.handler
= PreserveRequestHeaders_Handler
;
1235 transaction
.request_headers
= EXTRA_HEADER
;
1236 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1237 AddMockTransaction(&transaction
);
1239 // Write, then revalidate the entry.
1240 RunTransactionTest(cache
.http_cache(), transaction
);
1241 RunTransactionTest(cache
.http_cache(), transaction
);
1243 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1244 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1246 RemoveMockTransaction(&transaction
);
1249 // Tests that we don't remove extra headers for conditionalized requests.
1250 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1251 MockHttpCache cache
;
1253 // Write to the cache.
1254 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1256 MockTransaction
transaction(kETagGET_Transaction
);
1257 transaction
.handler
= PreserveRequestHeaders_Handler
;
1258 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1260 AddMockTransaction(&transaction
);
1262 RunTransactionTest(cache
.http_cache(), transaction
);
1264 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1265 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1266 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1267 RemoveMockTransaction(&transaction
);
1270 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1271 MockHttpCache cache
;
1273 MockHttpRequest
request(kSimpleGET_Transaction
);
1275 std::vector
<Context
*> context_list
;
1276 const int kNumTransactions
= 5;
1278 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1279 context_list
.push_back(new Context());
1280 Context
* c
= context_list
[i
];
1282 c
->result
= cache
.CreateTransaction(&c
->trans
);
1283 ASSERT_EQ(net::OK
, c
->result
);
1284 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1286 c
->result
= c
->trans
->Start(
1287 &request
, c
->callback
.callback(), net::BoundNetLog());
1290 // All requests are waiting for the active entry.
1291 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1292 Context
* c
= context_list
[i
];
1293 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1296 // Allow all requests to move from the Create queue to the active entry.
1297 base::MessageLoop::current()->RunUntilIdle();
1299 // The first request should be a writer at this point, and the subsequent
1300 // requests should be pending.
1302 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1303 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1304 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1306 // All requests depend on the writer, and the writer is between Start and
1308 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1309 Context
* c
= context_list
[i
];
1310 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1313 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1314 Context
* c
= context_list
[i
];
1315 if (c
->result
== net::ERR_IO_PENDING
)
1316 c
->result
= c
->callback
.WaitForResult();
1317 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1320 // We should not have had to re-open the disk entry
1322 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1323 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1324 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1326 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1327 Context
* c
= context_list
[i
];
1332 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1333 // If cancelling a request is racing with another request for the same resource
1334 // finishing, we have to make sure that we remove both transactions from the
1336 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1337 MockHttpCache cache
;
1339 MockHttpRequest
request(kSimpleGET_Transaction
);
1340 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1341 reader_request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
1343 std::vector
<Context
*> context_list
;
1344 const int kNumTransactions
= 5;
1346 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1347 context_list
.push_back(new Context());
1348 Context
* c
= context_list
[i
];
1350 c
->result
= cache
.CreateTransaction(&c
->trans
);
1351 ASSERT_EQ(net::OK
, c
->result
);
1353 MockHttpRequest
* this_request
= &request
;
1354 if (i
== 1 || i
== 2)
1355 this_request
= &reader_request
;
1357 c
->result
= c
->trans
->Start(
1358 this_request
, c
->callback
.callback(), net::BoundNetLog());
1361 // Allow all requests to move from the Create queue to the active entry.
1362 base::MessageLoop::current()->RunUntilIdle();
1364 // The first request should be a writer at this point, and the subsequent
1365 // requests should be pending.
1367 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1368 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1369 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1371 Context
* c
= context_list
[0];
1372 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1373 c
->result
= c
->callback
.WaitForResult();
1374 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1376 // Now we have 2 active readers and two queued transactions.
1378 EXPECT_EQ(net::LOAD_STATE_IDLE
,
1379 context_list
[2]->trans
->GetLoadState());
1380 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
,
1381 context_list
[3]->trans
->GetLoadState());
1383 c
= context_list
[1];
1384 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1385 c
->result
= c
->callback
.WaitForResult();
1386 if (c
->result
== net::OK
)
1387 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1389 // At this point we have one reader, two pending transactions and a task on
1390 // the queue to move to the next transaction. Now we cancel the request that
1391 // is the current reader, and expect the queued task to be able to start the
1394 c
= context_list
[2];
1397 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1398 Context
* c
= context_list
[i
];
1399 if (c
->result
== net::ERR_IO_PENDING
)
1400 c
->result
= c
->callback
.WaitForResult();
1401 if (c
->result
== net::OK
)
1402 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1405 // We should not have had to re-open the disk entry.
1407 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1408 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1409 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1411 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1412 Context
* c
= context_list
[i
];
1417 // Tests that we can doom an entry with pending transactions and delete one of
1418 // the pending transactions before the first one completes.
1419 // See http://code.google.com/p/chromium/issues/detail?id=25588
1420 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1421 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1422 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1424 MockHttpRequest
request(kSimpleGET_Transaction
);
1425 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1426 writer_request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1428 ScopedVector
<Context
> context_list
;
1429 const int kNumTransactions
= 4;
1431 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1432 context_list
.push_back(new Context());
1433 Context
* c
= context_list
[i
];
1435 c
->result
= cache
.CreateTransaction(&c
->trans
);
1436 ASSERT_EQ(net::OK
, c
->result
);
1438 MockHttpRequest
* this_request
= &request
;
1440 this_request
= &writer_request
;
1442 c
->result
= c
->trans
->Start(
1443 this_request
, c
->callback
.callback(), net::BoundNetLog());
1446 // The first request should be a writer at this point, and the two subsequent
1447 // requests should be pending. The last request doomed the first entry.
1449 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1451 // Cancel the first queued transaction.
1452 delete context_list
[1];
1453 context_list
.get()[1] = NULL
;
1455 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1458 Context
* c
= context_list
[i
];
1459 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1460 c
->result
= c
->callback
.WaitForResult();
1461 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1465 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1466 // We may attempt to delete an entry synchronously with the act of adding a new
1467 // transaction to said entry.
1468 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1469 MockHttpCache cache
;
1471 // The headers will be served right from the call to Start() the request.
1472 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1473 FastTransactionServer request_handler
;
1474 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1476 std::vector
<Context
*> context_list
;
1477 const int kNumTransactions
= 3;
1479 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1480 context_list
.push_back(new Context());
1481 Context
* c
= context_list
[i
];
1483 c
->result
= cache
.CreateTransaction(&c
->trans
);
1484 ASSERT_EQ(net::OK
, c
->result
);
1486 c
->result
= c
->trans
->Start(
1487 &request
, c
->callback
.callback(), net::BoundNetLog());
1490 // Allow all requests to move from the Create queue to the active entry.
1491 base::MessageLoop::current()->RunUntilIdle();
1493 // The first request should be a writer at this point, and the subsequent
1494 // requests should be pending.
1496 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1497 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1498 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1500 // Now, make sure that the second request asks for the entry not to be stored.
1501 request_handler
.set_no_store(true);
1503 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1504 Context
* c
= context_list
[i
];
1505 if (c
->result
== net::ERR_IO_PENDING
)
1506 c
->result
= c
->callback
.WaitForResult();
1507 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1511 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1512 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1513 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1515 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1518 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1519 MockHttpCache cache
;
1521 MockHttpRequest
request(kSimpleGET_Transaction
);
1523 std::vector
<Context
*> context_list
;
1524 const int kNumTransactions
= 2;
1526 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1527 context_list
.push_back(new Context());
1528 Context
* c
= context_list
[i
];
1530 c
->result
= cache
.CreateTransaction(&c
->trans
);
1531 ASSERT_EQ(net::OK
, c
->result
);
1533 c
->result
= c
->trans
->Start(
1534 &request
, c
->callback
.callback(), net::BoundNetLog());
1537 // Allow all requests to move from the Create queue to the active entry.
1538 base::MessageLoop::current()->RunUntilIdle();
1540 // The first request should be a writer at this point, and the subsequent
1541 // requests should be pending.
1543 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1544 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1545 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1547 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1548 Context
* c
= context_list
[i
];
1549 if (c
->result
== net::ERR_IO_PENDING
)
1550 c
->result
= c
->callback
.WaitForResult();
1551 // Destroy only the first transaction.
1554 context_list
[i
] = NULL
;
1558 // Complete the rest of the transactions.
1559 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1560 Context
* c
= context_list
[i
];
1561 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1564 // We should have had to re-open the disk entry.
1566 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1567 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1568 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1570 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1571 Context
* c
= context_list
[i
];
1576 // Tests that we can cancel requests that are queued waiting to open the disk
1578 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1579 MockHttpCache cache
;
1581 MockHttpRequest
request(kSimpleGET_Transaction
);
1583 std::vector
<Context
*> context_list
;
1584 const int kNumTransactions
= 5;
1586 for (int i
= 0; i
< kNumTransactions
; i
++) {
1587 context_list
.push_back(new Context());
1588 Context
* c
= context_list
[i
];
1590 c
->result
= cache
.CreateTransaction(&c
->trans
);
1591 ASSERT_EQ(net::OK
, c
->result
);
1593 c
->result
= c
->trans
->Start(
1594 &request
, c
->callback
.callback(), net::BoundNetLog());
1597 // The first request should be creating the disk cache entry and the others
1598 // should be pending.
1600 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1601 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1602 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1604 // Cancel a request from the pending queue.
1605 delete context_list
[3];
1606 context_list
[3] = NULL
;
1608 // Cancel the request that is creating the entry. This will force the pending
1609 // operations to restart.
1610 delete context_list
[0];
1611 context_list
[0] = NULL
;
1613 // Complete the rest of the transactions.
1614 for (int i
= 1; i
< kNumTransactions
; i
++) {
1615 Context
* c
= context_list
[i
];
1617 c
->result
= c
->callback
.GetResult(c
->result
);
1618 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1622 // We should have had to re-create the disk entry.
1624 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1625 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1626 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1628 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1629 delete context_list
[i
];
1633 // Tests that we can cancel a single request to open a disk cache entry.
1634 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1635 MockHttpCache cache
;
1637 MockHttpRequest
request(kSimpleGET_Transaction
);
1639 Context
* c
= new Context();
1641 c
->result
= cache
.CreateTransaction(&c
->trans
);
1642 ASSERT_EQ(net::OK
, c
->result
);
1644 c
->result
= c
->trans
->Start(
1645 &request
, c
->callback
.callback(), net::BoundNetLog());
1646 EXPECT_EQ(net::ERR_IO_PENDING
, c
->result
);
1648 // Release the reference that the mock disk cache keeps for this entry, so
1649 // that we test that the http cache handles the cancellation correctly.
1650 cache
.disk_cache()->ReleaseAll();
1653 base::MessageLoop::current()->RunUntilIdle();
1654 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1657 // Tests that we delete/create entries even if multiple requests are queued.
1658 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1659 MockHttpCache cache
;
1661 MockHttpRequest
request(kSimpleGET_Transaction
);
1662 request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1664 std::vector
<Context
*> context_list
;
1665 const int kNumTransactions
= 5;
1667 for (int i
= 0; i
< kNumTransactions
; i
++) {
1668 context_list
.push_back(new Context());
1669 Context
* c
= context_list
[i
];
1671 c
->result
= cache
.CreateTransaction(&c
->trans
);
1672 ASSERT_EQ(net::OK
, c
->result
);
1674 c
->result
= c
->trans
->Start(
1675 &request
, c
->callback
.callback(), net::BoundNetLog());
1678 // The first request should be deleting the disk cache entry and the others
1679 // should be pending.
1681 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1682 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1683 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1685 // Complete the transactions.
1686 for (int i
= 0; i
< kNumTransactions
; i
++) {
1687 Context
* c
= context_list
[i
];
1688 c
->result
= c
->callback
.GetResult(c
->result
);
1689 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1692 // We should have had to re-create the disk entry multiple times.
1694 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1695 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1696 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1698 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1699 delete context_list
[i
];
1703 // Tests that a (simulated) timeout allows transactions waiting on the cache
1704 // lock to continue.
1705 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1706 MockHttpCache cache
;
1707 cache
.BypassCacheLock();
1709 MockHttpRequest
request(kSimpleGET_Transaction
);
1711 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c1
.trans
));
1712 ASSERT_EQ(net::ERR_IO_PENDING
,
1713 c1
.trans
->Start(&request
, c1
.callback
.callback(),
1714 net::BoundNetLog()));
1715 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c2
.trans
));
1716 ASSERT_EQ(net::ERR_IO_PENDING
,
1717 c2
.trans
->Start(&request
, c2
.callback
.callback(),
1718 net::BoundNetLog()));
1720 // The second request is queued after the first one.
1722 c2
.callback
.WaitForResult();
1723 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1725 // Complete the first transaction.
1726 c1
.callback
.WaitForResult();
1727 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1730 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1731 MockHttpCache cache
;
1733 // write to the cache
1734 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1736 MockHttpRequest
request(kSimpleGET_Transaction
);
1737 net::TestCompletionCallback callback
;
1739 scoped_ptr
<net::HttpTransaction
> trans
;
1740 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1741 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1742 if (rv
== net::ERR_IO_PENDING
)
1743 rv
= callback
.WaitForResult();
1744 ASSERT_EQ(net::OK
, rv
);
1746 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
1747 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1748 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1750 // Test that destroying the transaction while it is reading from the cache
1754 // Make sure we pump any pending events, which should include a call to
1755 // HttpCache::Transaction::OnCacheReadCompleted.
1756 base::MessageLoop::current()->RunUntilIdle();
1759 // Tests that we can delete the HttpCache and deal with queued transactions
1760 // ("waiting for the backend" as opposed to Active or Doomed entries).
1761 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1762 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1763 new MockBackendNoCbFactory()));
1765 MockHttpRequest
request(kSimpleGET_Transaction
);
1767 std::vector
<Context
*> context_list
;
1768 const int kNumTransactions
= 5;
1770 for (int i
= 0; i
< kNumTransactions
; i
++) {
1771 context_list
.push_back(new Context());
1772 Context
* c
= context_list
[i
];
1774 c
->result
= cache
->CreateTransaction(&c
->trans
);
1775 ASSERT_EQ(net::OK
, c
->result
);
1777 c
->result
= c
->trans
->Start(
1778 &request
, c
->callback
.callback(), net::BoundNetLog());
1781 // The first request should be creating the disk cache entry and the others
1782 // should be pending.
1784 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1785 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1786 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1790 // There is not much to do with the transactions at this point... they are
1791 // waiting for a callback that will not fire.
1792 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1793 delete context_list
[i
];
1797 // Tests that we queue requests when initializing the backend.
1798 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1799 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1800 MockHttpCache
cache(factory
);
1802 MockHttpRequest
request0(kSimpleGET_Transaction
);
1803 MockHttpRequest
request1(kTypicalGET_Transaction
);
1804 MockHttpRequest
request2(kETagGET_Transaction
);
1806 std::vector
<Context
*> context_list
;
1807 const int kNumTransactions
= 3;
1809 for (int i
= 0; i
< kNumTransactions
; i
++) {
1810 context_list
.push_back(new Context());
1811 Context
* c
= context_list
[i
];
1813 c
->result
= cache
.CreateTransaction(&c
->trans
);
1814 ASSERT_EQ(net::OK
, c
->result
);
1817 context_list
[0]->result
= context_list
[0]->trans
->Start(
1818 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1819 context_list
[1]->result
= context_list
[1]->trans
->Start(
1820 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1821 context_list
[2]->result
= context_list
[2]->trans
->Start(
1822 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1824 // Just to make sure that everything is still pending.
1825 base::MessageLoop::current()->RunUntilIdle();
1827 // The first request should be creating the disk cache.
1828 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1830 factory
->FinishCreation();
1832 base::MessageLoop::current()->RunUntilIdle();
1833 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1834 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1836 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1837 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1838 delete context_list
[i
];
1842 // Tests that we can cancel requests that are queued waiting for the backend
1843 // to be initialized.
1844 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1845 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1846 MockHttpCache
cache(factory
);
1848 MockHttpRequest
request0(kSimpleGET_Transaction
);
1849 MockHttpRequest
request1(kTypicalGET_Transaction
);
1850 MockHttpRequest
request2(kETagGET_Transaction
);
1852 std::vector
<Context
*> context_list
;
1853 const int kNumTransactions
= 3;
1855 for (int i
= 0; i
< kNumTransactions
; i
++) {
1856 context_list
.push_back(new Context());
1857 Context
* c
= context_list
[i
];
1859 c
->result
= cache
.CreateTransaction(&c
->trans
);
1860 ASSERT_EQ(net::OK
, c
->result
);
1863 context_list
[0]->result
= context_list
[0]->trans
->Start(
1864 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1865 context_list
[1]->result
= context_list
[1]->trans
->Start(
1866 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1867 context_list
[2]->result
= context_list
[2]->trans
->Start(
1868 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1870 // Just to make sure that everything is still pending.
1871 base::MessageLoop::current()->RunUntilIdle();
1873 // The first request should be creating the disk cache.
1874 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1876 // Cancel a request from the pending queue.
1877 delete context_list
[1];
1878 context_list
[1] = NULL
;
1880 // Cancel the request that is creating the entry.
1881 delete context_list
[0];
1882 context_list
[0] = NULL
;
1884 // Complete the last transaction.
1885 factory
->FinishCreation();
1887 context_list
[2]->result
=
1888 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1889 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1891 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1892 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1894 delete context_list
[2];
1897 // Tests that we can delete the cache while creating the backend.
1898 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1899 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1900 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1902 MockHttpRequest
request(kSimpleGET_Transaction
);
1904 scoped_ptr
<Context
> c(new Context());
1905 c
->result
= cache
->CreateTransaction(&c
->trans
);
1906 ASSERT_EQ(net::OK
, c
->result
);
1908 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1910 // Just to make sure that everything is still pending.
1911 base::MessageLoop::current()->RunUntilIdle();
1913 // The request should be creating the disk cache.
1914 EXPECT_FALSE(c
->callback
.have_result());
1916 // We cannot call FinishCreation because the factory itself will go away with
1917 // the cache, so grab the callback and attempt to use it.
1918 net::CompletionCallback callback
= factory
->callback();
1919 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1922 base::MessageLoop::current()->RunUntilIdle();
1925 callback
.Run(net::ERR_ABORTED
);
1928 // Tests that we can delete the cache while creating the backend, from within
1929 // one of the callbacks.
1930 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1931 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1932 MockHttpCache
* cache
= new MockHttpCache(factory
);
1934 DeleteCacheCompletionCallback
cb(cache
);
1935 disk_cache::Backend
* backend
;
1936 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1937 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1939 // Now let's queue a regular transaction
1940 MockHttpRequest
request(kSimpleGET_Transaction
);
1942 scoped_ptr
<Context
> c(new Context());
1943 c
->result
= cache
->CreateTransaction(&c
->trans
);
1944 ASSERT_EQ(net::OK
, c
->result
);
1946 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1948 // And another direct backend request.
1949 net::TestCompletionCallback cb2
;
1950 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1951 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1953 // Just to make sure that everything is still pending.
1954 base::MessageLoop::current()->RunUntilIdle();
1956 // The request should be queued.
1957 EXPECT_FALSE(c
->callback
.have_result());
1959 // Generate the callback.
1960 factory
->FinishCreation();
1961 rv
= cb
.WaitForResult();
1963 // The cache should be gone by now.
1964 base::MessageLoop::current()->RunUntilIdle();
1965 EXPECT_EQ(net::OK
, c
->callback
.GetResult(c
->result
));
1966 EXPECT_FALSE(cb2
.have_result());
1969 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
1970 MockHttpCache cache
;
1972 // write to the cache
1973 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
1975 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1976 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1977 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1979 // Get the same URL again, but this time we expect it to result
1980 // in a conditional request.
1981 net::CapturingBoundNetLog log
;
1982 net::LoadTimingInfo load_timing_info
;
1983 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
1984 log
.bound(), &load_timing_info
);
1986 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1987 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1988 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1989 TestLoadTimingNetworkRequest(load_timing_info
);
1992 static void ETagGet_ConditionalRequest_Handler(
1993 const net::HttpRequestInfo
* request
,
1994 std::string
* response_status
,
1995 std::string
* response_headers
,
1996 std::string
* response_data
) {
1998 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
1999 response_status
->assign("HTTP/1.1 304 Not Modified");
2000 response_headers
->assign(kETagGET_Transaction
.response_headers
);
2001 response_data
->clear();
2004 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
2005 MockHttpCache cache
;
2007 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2009 // write to the cache
2010 RunTransactionTest(cache
.http_cache(), transaction
);
2012 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2013 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2014 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2016 // Get the same URL again, but this time we expect it to result
2017 // in a conditional request.
2018 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2019 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
2020 net::CapturingBoundNetLog log
;
2021 net::LoadTimingInfo load_timing_info
;
2022 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2025 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2026 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2027 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2028 TestLoadTimingNetworkRequest(load_timing_info
);
2031 class RevalidationServer
{
2033 RevalidationServer() {
2034 s_etag_used_
= false;
2035 s_last_modified_used_
= false;
2038 bool EtagUsed() { return s_etag_used_
; }
2039 bool LastModifiedUsed() { return s_last_modified_used_
; }
2041 static void Handler(const net::HttpRequestInfo
* request
,
2042 std::string
* response_status
,
2043 std::string
* response_headers
,
2044 std::string
* response_data
);
2047 static bool s_etag_used_
;
2048 static bool s_last_modified_used_
;
2050 bool RevalidationServer::s_etag_used_
= false;
2051 bool RevalidationServer::s_last_modified_used_
= false;
2053 void RevalidationServer::Handler(const net::HttpRequestInfo
* request
,
2054 std::string
* response_status
,
2055 std::string
* response_headers
,
2056 std::string
* response_data
) {
2057 if (request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
))
2058 s_etag_used_
= true;
2060 if (request
->extra_headers
.HasHeader(
2061 net::HttpRequestHeaders::kIfModifiedSince
)) {
2062 s_last_modified_used_
= true;
2065 if (s_etag_used_
|| s_last_modified_used_
) {
2066 response_status
->assign("HTTP/1.1 304 Not Modified");
2067 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2068 response_data
->clear();
2070 response_status
->assign(kTypicalGET_Transaction
.status
);
2071 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2072 response_data
->assign(kTypicalGET_Transaction
.data
);
2076 // Tests revalidation after a vary match.
2077 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMatch
) {
2078 MockHttpCache cache
;
2080 // Write to the cache.
2081 MockTransaction
transaction(kTypicalGET_Transaction
);
2082 transaction
.request_headers
= "Foo: bar\r\n";
2083 transaction
.response_headers
=
2084 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2085 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2087 "Cache-Control: max-age=0\n"
2089 AddMockTransaction(&transaction
);
2090 RunTransactionTest(cache
.http_cache(), transaction
);
2092 // Read from the cache.
2093 RevalidationServer server
;
2094 transaction
.handler
= server
.Handler
;
2095 net::CapturingBoundNetLog log
;
2096 net::LoadTimingInfo load_timing_info
;
2097 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2100 EXPECT_TRUE(server
.EtagUsed());
2101 EXPECT_TRUE(server
.LastModifiedUsed());
2102 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2103 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2104 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2105 TestLoadTimingNetworkRequest(load_timing_info
);
2106 RemoveMockTransaction(&transaction
);
2109 // Tests revalidation after a vary mismatch if etag is present.
2110 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMismatch
) {
2111 MockHttpCache cache
;
2113 // Write to the cache.
2114 MockTransaction
transaction(kTypicalGET_Transaction
);
2115 transaction
.request_headers
= "Foo: bar\r\n";
2116 transaction
.response_headers
=
2117 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2118 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2120 "Cache-Control: max-age=0\n"
2122 AddMockTransaction(&transaction
);
2123 RunTransactionTest(cache
.http_cache(), transaction
);
2125 // Read from the cache and revalidate the entry.
2126 RevalidationServer server
;
2127 transaction
.handler
= server
.Handler
;
2128 transaction
.request_headers
= "Foo: none\r\n";
2129 net::CapturingBoundNetLog log
;
2130 net::LoadTimingInfo load_timing_info
;
2131 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2134 EXPECT_TRUE(server
.EtagUsed());
2135 EXPECT_FALSE(server
.LastModifiedUsed());
2136 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2137 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2138 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2139 TestLoadTimingNetworkRequest(load_timing_info
);
2140 RemoveMockTransaction(&transaction
);
2143 // Tests lack of revalidation after a vary mismatch and no etag.
2144 TEST(HttpCache
, SimpleGET_LoadDontValidateCache_VaryMismatch
) {
2145 MockHttpCache cache
;
2147 // Write to the cache.
2148 MockTransaction
transaction(kTypicalGET_Transaction
);
2149 transaction
.request_headers
= "Foo: bar\r\n";
2150 transaction
.response_headers
=
2151 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2152 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2153 "Cache-Control: max-age=0\n"
2155 AddMockTransaction(&transaction
);
2156 RunTransactionTest(cache
.http_cache(), transaction
);
2158 // Read from the cache and don't revalidate the entry.
2159 RevalidationServer server
;
2160 transaction
.handler
= server
.Handler
;
2161 transaction
.request_headers
= "Foo: none\r\n";
2162 net::CapturingBoundNetLog log
;
2163 net::LoadTimingInfo load_timing_info
;
2164 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2167 EXPECT_FALSE(server
.EtagUsed());
2168 EXPECT_FALSE(server
.LastModifiedUsed());
2169 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2170 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2171 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2172 TestLoadTimingNetworkRequest(load_timing_info
);
2173 RemoveMockTransaction(&transaction
);
2176 static void ETagGet_UnconditionalRequest_Handler(
2177 const net::HttpRequestInfo
* request
,
2178 std::string
* response_status
,
2179 std::string
* response_headers
,
2180 std::string
* response_data
) {
2182 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2185 TEST(HttpCache
, ETagGET_Http10
) {
2186 MockHttpCache cache
;
2188 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2189 transaction
.status
= "HTTP/1.0 200 OK";
2191 // Write to the cache.
2192 RunTransactionTest(cache
.http_cache(), transaction
);
2194 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2195 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2196 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2198 // Get the same URL again, without generating a conditional request.
2199 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2200 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2201 RunTransactionTest(cache
.http_cache(), transaction
);
2203 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2204 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2205 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2208 TEST(HttpCache
, ETagGET_Http10_Range
) {
2209 MockHttpCache cache
;
2211 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2212 transaction
.status
= "HTTP/1.0 200 OK";
2214 // Write to the cache.
2215 RunTransactionTest(cache
.http_cache(), transaction
);
2217 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2218 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2219 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2221 // Get the same URL again, but use a byte range request.
2222 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2223 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2224 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2225 RunTransactionTest(cache
.http_cache(), transaction
);
2227 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2228 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2229 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2232 static void ETagGet_ConditionalRequest_NoStore_Handler(
2233 const net::HttpRequestInfo
* request
,
2234 std::string
* response_status
,
2235 std::string
* response_headers
,
2236 std::string
* response_data
) {
2238 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2239 response_status
->assign("HTTP/1.1 304 Not Modified");
2240 response_headers
->assign("Cache-Control: no-store\n");
2241 response_data
->clear();
2244 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2245 MockHttpCache cache
;
2247 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2249 // Write to the cache.
2250 RunTransactionTest(cache
.http_cache(), transaction
);
2252 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2253 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2254 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2256 // Get the same URL again, but this time we expect it to result
2257 // in a conditional request.
2258 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2259 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2260 RunTransactionTest(cache
.http_cache(), transaction
);
2262 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2263 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2264 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2266 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2268 // Write to the cache again. This should create a new entry.
2269 RunTransactionTest(cache
.http_cache(), transaction2
);
2271 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2272 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2273 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2276 // Helper that does 4 requests using HttpCache:
2278 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2279 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2280 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2282 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2284 static void ConditionalizedRequestUpdatesCacheHelper(
2285 const Response
& net_response_1
,
2286 const Response
& net_response_2
,
2287 const Response
& cached_response_2
,
2288 const char* extra_request_headers
) {
2289 MockHttpCache cache
;
2291 // The URL we will be requesting.
2292 const char* kUrl
= "http://foobar.com/main.css";
2294 // Junk network response.
2295 static const Response kUnexpectedResponse
= {
2296 "HTTP/1.1 500 Unexpected",
2297 "Server: unexpected_header",
2301 // We will control the network layer's responses for |kUrl| using
2302 // |mock_network_response|.
2303 MockTransaction mock_network_response
= { 0 };
2304 mock_network_response
.url
= kUrl
;
2305 AddMockTransaction(&mock_network_response
);
2307 // Request |kUrl| for the first time. It should hit the network and
2308 // receive |kNetResponse1|, which it saves into the HTTP cache.
2310 MockTransaction request
= { 0 };
2312 request
.method
= "GET";
2313 request
.request_headers
= "";
2315 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2316 net_response_1
.AssignTo(&request
); // Expected result.
2318 std::string response_headers
;
2319 RunTransactionTestWithResponse(
2320 cache
.http_cache(), request
, &response_headers
);
2322 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2323 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2324 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2325 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2327 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2328 // cache, so we don't hit the network.
2330 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2332 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2333 net_response_1
.AssignTo(&request
); // Expected result.
2335 RunTransactionTestWithResponse(
2336 cache
.http_cache(), request
, &response_headers
);
2338 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2339 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2340 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2341 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2343 // Request |kUrl| yet again, but this time give the request an
2344 // "If-Modified-Since" header. This will cause the request to re-hit the
2345 // network. However now the network response is going to be
2346 // different -- this simulates a change made to the CSS file.
2348 request
.request_headers
= extra_request_headers
;
2349 request
.load_flags
= net::LOAD_NORMAL
;
2351 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2352 net_response_2
.AssignTo(&request
); // Expected result.
2354 RunTransactionTestWithResponse(
2355 cache
.http_cache(), request
, &response_headers
);
2357 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2358 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2359 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2360 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2362 // Finally, request |kUrl| again. This request should be serviced from
2363 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2364 // and NOT |kNetResponse1|. The previous step should have replaced the
2365 // value in the cache with the modified response.
2367 request
.request_headers
= "";
2368 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2370 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2371 cached_response_2
.AssignTo(&request
); // Expected result.
2373 RunTransactionTestWithResponse(
2374 cache
.http_cache(), request
, &response_headers
);
2376 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2377 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2378 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2379 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2381 RemoveMockTransaction(&mock_network_response
);
2384 // Check that when an "if-modified-since" header is attached
2385 // to the request, the result still updates the cached entry.
2386 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2387 // First network response for |kUrl|.
2388 static const Response kNetResponse1
= {
2390 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2391 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2395 // Second network response for |kUrl|.
2396 static const Response kNetResponse2
= {
2398 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2399 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2403 const char* extra_headers
=
2404 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2406 ConditionalizedRequestUpdatesCacheHelper(
2407 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2410 // Check that when an "if-none-match" header is attached
2411 // to the request, the result updates the cached entry.
2412 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2413 // First network response for |kUrl|.
2414 static const Response kNetResponse1
= {
2416 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2418 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2422 // Second network response for |kUrl|.
2423 static const Response kNetResponse2
= {
2425 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2427 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2431 const char* extra_headers
= "If-None-Match: \"ETAG1\"\r\n";
2433 ConditionalizedRequestUpdatesCacheHelper(
2434 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2437 // Check that when an "if-modified-since" header is attached
2438 // to a request, the 304 (not modified result) result updates the cached
2439 // headers, and the 304 response is returned rather than the cached response.
2440 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2441 // First network response for |kUrl|.
2442 static const Response kNetResponse1
= {
2444 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2446 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2450 // Second network response for |kUrl|.
2451 static const Response kNetResponse2
= {
2452 "HTTP/1.1 304 Not Modified",
2453 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2455 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2459 static const Response kCachedResponse2
= {
2461 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2463 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2467 const char* extra_headers
=
2468 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2470 ConditionalizedRequestUpdatesCacheHelper(
2471 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2474 // Test that when doing an externally conditionalized if-modified-since
2475 // and there is no corresponding cache entry, a new cache entry is NOT
2476 // created (304 response).
2477 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2478 MockHttpCache cache
;
2480 const char* kUrl
= "http://foobar.com/main.css";
2482 static const Response kNetResponse
= {
2483 "HTTP/1.1 304 Not Modified",
2484 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2485 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2489 const char* kExtraRequestHeaders
=
2490 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2492 // We will control the network layer's responses for |kUrl| using
2493 // |mock_network_response|.
2494 MockTransaction mock_network_response
= { 0 };
2495 mock_network_response
.url
= kUrl
;
2496 AddMockTransaction(&mock_network_response
);
2498 MockTransaction request
= { 0 };
2500 request
.method
= "GET";
2501 request
.request_headers
= kExtraRequestHeaders
;
2503 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2504 kNetResponse
.AssignTo(&request
); // Expected result.
2506 std::string response_headers
;
2507 RunTransactionTestWithResponse(
2508 cache
.http_cache(), request
, &response_headers
);
2510 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2511 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2512 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2513 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2515 RemoveMockTransaction(&mock_network_response
);
2518 // Test that when doing an externally conditionalized if-modified-since
2519 // and there is no corresponding cache entry, a new cache entry is NOT
2520 // created (200 response).
2521 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2522 MockHttpCache cache
;
2524 const char* kUrl
= "http://foobar.com/main.css";
2526 static const Response kNetResponse
= {
2528 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2529 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2533 const char* kExtraRequestHeaders
=
2534 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2536 // We will control the network layer's responses for |kUrl| using
2537 // |mock_network_response|.
2538 MockTransaction mock_network_response
= { 0 };
2539 mock_network_response
.url
= kUrl
;
2540 AddMockTransaction(&mock_network_response
);
2542 MockTransaction request
= { 0 };
2544 request
.method
= "GET";
2545 request
.request_headers
= kExtraRequestHeaders
;
2547 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2548 kNetResponse
.AssignTo(&request
); // Expected result.
2550 std::string response_headers
;
2551 RunTransactionTestWithResponse(
2552 cache
.http_cache(), request
, &response_headers
);
2554 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2555 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2556 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2557 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2559 RemoveMockTransaction(&mock_network_response
);
2562 // Test that when doing an externally conditionalized if-modified-since
2563 // if the date does not match the cache entry's last-modified date,
2564 // then we do NOT use the response (304) to update the cache.
2565 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2566 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2567 static const Response kNetResponse1
= {
2569 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2571 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2575 // Second network response for |kUrl|.
2576 static const Response kNetResponse2
= {
2577 "HTTP/1.1 304 Not Modified",
2578 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2580 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2584 // This is two days in the future from the original response's last-modified
2586 const char* kExtraRequestHeaders
=
2587 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2589 ConditionalizedRequestUpdatesCacheHelper(
2590 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2593 // Test that when doing an externally conditionalized if-none-match
2594 // if the etag does not match the cache entry's etag, then we do not use the
2595 // response (304) to update the cache.
2596 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2597 static const Response kNetResponse1
= {
2599 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2601 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2605 // Second network response for |kUrl|.
2606 static const Response kNetResponse2
= {
2607 "HTTP/1.1 304 Not Modified",
2608 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2610 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2614 // Different etag from original response.
2615 const char* kExtraRequestHeaders
= "If-None-Match: \"Foo2\"\r\n";
2617 ConditionalizedRequestUpdatesCacheHelper(
2618 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2621 // Test that doing an externally conditionalized request with both if-none-match
2622 // and if-modified-since updates the cache.
2623 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2624 static const Response kNetResponse1
= {
2626 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2628 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2632 // Second network response for |kUrl|.
2633 static const Response kNetResponse2
= {
2635 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2637 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2641 const char* kExtraRequestHeaders
=
2642 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2643 "If-None-Match: \"Foo1\"\r\n";
2645 ConditionalizedRequestUpdatesCacheHelper(
2646 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2649 // Test that doing an externally conditionalized request with both if-none-match
2650 // and if-modified-since does not update the cache with only one match.
2651 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2652 static const Response kNetResponse1
= {
2654 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2656 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2660 // Second network response for |kUrl|.
2661 static const Response kNetResponse2
= {
2663 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2665 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2669 // The etag doesn't match what we have stored.
2670 const char* kExtraRequestHeaders
=
2671 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2672 "If-None-Match: \"Foo2\"\r\n";
2674 ConditionalizedRequestUpdatesCacheHelper(
2675 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2678 // Test that doing an externally conditionalized request with both if-none-match
2679 // and if-modified-since does not update the cache with only one match.
2680 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2681 static const Response kNetResponse1
= {
2683 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2685 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2689 // Second network response for |kUrl|.
2690 static const Response kNetResponse2
= {
2692 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2694 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2698 // The modification date doesn't match what we have stored.
2699 const char* kExtraRequestHeaders
=
2700 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2701 "If-None-Match: \"Foo1\"\r\n";
2703 ConditionalizedRequestUpdatesCacheHelper(
2704 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2707 TEST(HttpCache
, UrlContainingHash
) {
2708 MockHttpCache cache
;
2710 // Do a typical GET request -- should write an entry into our cache.
2711 MockTransaction
trans(kTypicalGET_Transaction
);
2712 RunTransactionTest(cache
.http_cache(), trans
);
2714 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2715 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2716 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2718 // Request the same URL, but this time with a reference section (hash).
2719 // Since the cache key strips the hash sections, this should be a cache hit.
2720 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2721 trans
.url
= url_with_hash
.c_str();
2722 trans
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2724 RunTransactionTest(cache
.http_cache(), trans
);
2726 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2727 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2728 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2731 // Tests that we skip the cache for POST requests that do not have an upload
2733 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2734 MockHttpCache cache
;
2736 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2738 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2739 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2740 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2743 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2744 MockHttpCache cache
;
2746 MockTransaction
transaction(kSimplePOST_Transaction
);
2747 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2749 MockHttpRequest
request(transaction
);
2750 net::TestCompletionCallback callback
;
2752 scoped_ptr
<net::HttpTransaction
> trans
;
2753 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
2754 ASSERT_TRUE(trans
.get());
2756 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
2757 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
2761 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2762 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2763 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2766 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2767 MockHttpCache cache
;
2769 // Test that we hit the cache for POST requests.
2771 MockTransaction
transaction(kSimplePOST_Transaction
);
2773 const int64 kUploadId
= 1; // Just a dummy value.
2775 ScopedVector
<net::UploadElementReader
> element_readers
;
2776 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2777 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2779 MockHttpRequest
request(transaction
);
2780 request
.upload_data_stream
= &upload_data_stream
;
2782 // Populate the cache.
2783 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2785 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2786 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2787 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2790 request
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2791 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2793 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2794 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2795 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2798 // Test that we don't hit the cache for POST requests if there is a byte range.
2799 TEST(HttpCache
, SimplePOST_WithRanges
) {
2800 MockHttpCache cache
;
2802 MockTransaction
transaction(kSimplePOST_Transaction
);
2803 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2805 const int64 kUploadId
= 1; // Just a dummy value.
2807 ScopedVector
<net::UploadElementReader
> element_readers
;
2808 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2809 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2812 MockHttpRequest
request(transaction
);
2813 request
.upload_data_stream
= &upload_data_stream
;
2815 // Attempt to populate the cache.
2816 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2818 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2819 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2820 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2823 // Tests that a POST is cached separately from a previously cached GET.
2824 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2825 MockHttpCache cache
;
2827 ScopedVector
<net::UploadElementReader
> element_readers
;
2828 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2829 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2831 MockTransaction
transaction(kSimplePOST_Transaction
);
2832 MockHttpRequest
req1(transaction
);
2833 req1
.upload_data_stream
= &upload_data_stream
;
2835 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2837 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2838 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2839 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2841 transaction
.method
= "GET";
2842 MockHttpRequest
req2(transaction
);
2844 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2846 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2847 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2848 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2851 // Tests that a successful POST invalidates a previously cached GET.
2852 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2853 MockHttpCache cache
;
2855 MockTransaction
transaction(kSimpleGET_Transaction
);
2856 AddMockTransaction(&transaction
);
2857 MockHttpRequest
req1(transaction
);
2859 // Attempt to populate the cache.
2860 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2862 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2863 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2864 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2866 ScopedVector
<net::UploadElementReader
> element_readers
;
2867 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2868 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2870 transaction
.method
= "POST";
2871 transaction
.status
= "HTTP/1.1 205 No Content";
2872 MockHttpRequest
req2(transaction
);
2873 req2
.upload_data_stream
= &upload_data_stream
;
2875 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2877 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2878 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2879 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2881 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2883 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2884 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2885 EXPECT_EQ(3, cache
.disk_cache()->create_count());
2886 RemoveMockTransaction(&transaction
);
2889 // Tests that a successful POST invalidates a previously cached GET, even when
2890 // there is no upload identifier.
2891 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
2892 MockHttpCache cache
;
2894 MockTransaction
transaction(kSimpleGET_Transaction
);
2895 AddMockTransaction(&transaction
);
2896 MockHttpRequest
req1(transaction
);
2898 // Attempt to populate the cache.
2899 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2901 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2902 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2903 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2905 ScopedVector
<net::UploadElementReader
> element_readers
;
2906 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2907 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2909 transaction
.method
= "POST";
2910 transaction
.status
= "HTTP/1.1 205 No Content";
2911 MockHttpRequest
req2(transaction
);
2912 req2
.upload_data_stream
= &upload_data_stream
;
2914 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2916 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2917 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2918 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2920 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2922 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2923 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2924 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2925 RemoveMockTransaction(&transaction
);
2928 // Tests that processing a POST before creating the backend doesn't crash.
2929 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
2930 // This will initialize a cache object with NULL backend.
2931 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
2932 factory
->set_fail(true);
2933 factory
->FinishCreation();
2934 MockHttpCache
cache(factory
);
2936 ScopedVector
<net::UploadElementReader
> element_readers
;
2937 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2938 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2940 MockTransaction
transaction(kSimplePOST_Transaction
);
2941 AddMockTransaction(&transaction
);
2942 MockHttpRequest
req(transaction
);
2943 req
.upload_data_stream
= &upload_data_stream
;
2945 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
2947 RemoveMockTransaction(&transaction
);
2950 // Tests that we don't invalidate entries as a result of a failed POST.
2951 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
2952 MockHttpCache cache
;
2954 MockTransaction
transaction(kSimpleGET_Transaction
);
2955 AddMockTransaction(&transaction
);
2956 MockHttpRequest
req1(transaction
);
2958 // Attempt to populate the cache.
2959 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2961 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2962 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2963 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2965 ScopedVector
<net::UploadElementReader
> element_readers
;
2966 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2967 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2969 transaction
.method
= "POST";
2970 transaction
.status
= "HTTP/1.1 100 Continue";
2971 MockHttpRequest
req2(transaction
);
2972 req2
.upload_data_stream
= &upload_data_stream
;
2974 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2976 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2977 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2978 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2980 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2982 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2983 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2984 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2985 RemoveMockTransaction(&transaction
);
2988 // Tests that a HEAD request is not cached by itself.
2989 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
2990 MockHttpCache cache
;
2991 MockTransaction
transaction(kSimplePOST_Transaction
);
2992 AddMockTransaction(&transaction
);
2993 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2994 transaction
.method
= "HEAD";
2996 MockHttpRequest
request(transaction
);
2997 net::TestCompletionCallback callback
;
2999 scoped_ptr
<net::HttpTransaction
> trans
;
3000 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
3001 ASSERT_TRUE(trans
.get());
3003 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
3004 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
3008 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3009 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3010 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3011 RemoveMockTransaction(&transaction
);
3014 // Tests that a HEAD request is served from a cached GET.
3015 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3016 MockHttpCache cache
;
3017 MockTransaction
transaction(kSimpleGET_Transaction
);
3018 AddMockTransaction(&transaction
);
3020 // Populate the cache.
3021 RunTransactionTest(cache
.http_cache(), transaction
);
3023 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3024 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3025 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3028 transaction
.method
= "HEAD";
3029 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3030 transaction
.data
= "";
3031 RunTransactionTest(cache
.http_cache(), transaction
);
3033 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3034 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3035 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3036 RemoveMockTransaction(&transaction
);
3039 // Tests that a read-only request served from the cache preserves CL.
3040 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3041 MockHttpCache cache
;
3042 MockTransaction
transaction(kSimpleGET_Transaction
);
3043 AddMockTransaction(&transaction
);
3044 transaction
.response_headers
= "Content-Length: 42\n";
3046 // Populate the cache.
3047 RunTransactionTest(cache
.http_cache(), transaction
);
3050 transaction
.method
= "HEAD";
3051 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3052 transaction
.data
= "";
3053 std::string headers
;
3055 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3057 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3058 RemoveMockTransaction(&transaction
);
3061 // Tests that a read-write request served from the cache preserves CL.
3062 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3063 MockHttpCache cache
;
3064 MockTransaction
transaction(kETagGET_Transaction
);
3065 AddMockTransaction(&transaction
);
3066 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3067 server_headers
.append("Content-Length: 42\n");
3068 transaction
.response_headers
= server_headers
.data();
3070 // Populate the cache.
3071 RunTransactionTest(cache
.http_cache(), transaction
);
3074 transaction
.method
= "HEAD";
3075 transaction
.data
= "";
3076 std::string headers
;
3078 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3080 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3081 RemoveMockTransaction(&transaction
);
3084 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3085 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3086 MockHttpCache cache
;
3087 MockTransaction
transaction(kSimpleGET_Transaction
);
3088 AddMockTransaction(&transaction
);
3090 // Populate the cache.
3091 RunTransactionTest(cache
.http_cache(), transaction
);
3094 transaction
.method
= "HEAD";
3095 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3096 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3097 transaction
.return_code
= net::ERR_CACHE_MISS
;
3098 RunTransactionTest(cache
.http_cache(), transaction
);
3100 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3101 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3102 RemoveMockTransaction(&transaction
);
3105 // Tests that a HEAD request can be served from a partialy cached resource.
3106 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3107 MockHttpCache cache
;
3108 AddMockTransaction(&kRangeGET_TransactionOK
);
3110 // Write to the cache (40-49).
3111 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3112 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3114 MockTransaction
transaction(kSimpleGET_Transaction
);
3116 transaction
.url
= kRangeGET_TransactionOK
.url
;
3117 transaction
.method
= "HEAD";
3118 transaction
.data
= "";
3119 AddMockTransaction(&transaction
);
3120 std::string headers
;
3123 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3125 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3126 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length"));
3127 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3128 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3129 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3130 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3131 RemoveMockTransaction(&transaction
);
3134 // Tests that a HEAD request can be served from a truncated resource.
3135 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3136 MockHttpCache cache
;
3137 AddMockTransaction(&kRangeGET_TransactionOK
);
3139 std::string
raw_headers("HTTP/1.1 200 OK\n"
3140 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3142 "Accept-Ranges: bytes\n"
3143 "Content-Length: 80\n");
3144 CreateTruncatedEntry(raw_headers
, &cache
);
3145 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3147 MockTransaction
transaction(kSimpleGET_Transaction
);
3149 transaction
.url
= kRangeGET_TransactionOK
.url
;
3150 transaction
.method
= "HEAD";
3151 transaction
.data
= "";
3152 AddMockTransaction(&transaction
);
3153 std::string headers
;
3156 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3158 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3159 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3160 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3161 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3162 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3163 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3164 RemoveMockTransaction(&transaction
);
3167 // Tests that a HEAD request updates the cached response.
3168 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3169 MockHttpCache cache
;
3170 MockTransaction
transaction(kTypicalGET_Transaction
);
3171 AddMockTransaction(&transaction
);
3173 // Populate the cache.
3174 RunTransactionTest(cache
.http_cache(), transaction
);
3176 // Update the cache.
3177 transaction
.method
= "HEAD";
3178 transaction
.response_headers
= "Foo: bar\n";
3179 transaction
.data
= "";
3180 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3181 std::string headers
;
3182 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3183 RemoveMockTransaction(&transaction
);
3185 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3186 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3188 MockTransaction
transaction2(kTypicalGET_Transaction
);
3189 AddMockTransaction(&transaction2
);
3191 // Make sure we are done with the previous transaction.
3192 base::MessageLoop::current()->RunUntilIdle();
3194 // Load from the cache.
3195 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3196 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3198 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3199 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3200 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3201 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3202 RemoveMockTransaction(&transaction2
);
3205 // Tests that an externally conditionalized HEAD request updates the cache.
3206 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3207 MockHttpCache cache
;
3208 MockTransaction
transaction(kTypicalGET_Transaction
);
3209 AddMockTransaction(&transaction
);
3211 // Populate the cache.
3212 RunTransactionTest(cache
.http_cache(), transaction
);
3214 // Update the cache.
3215 transaction
.method
= "HEAD";
3216 transaction
.request_headers
=
3217 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3218 transaction
.response_headers
= "Foo: bar\n";
3219 transaction
.data
= "";
3220 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3221 std::string headers
;
3222 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3223 RemoveMockTransaction(&transaction
);
3225 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3226 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3228 MockTransaction
transaction2(kTypicalGET_Transaction
);
3229 AddMockTransaction(&transaction2
);
3231 // Make sure we are done with the previous transaction.
3232 base::MessageLoop::current()->RunUntilIdle();
3234 // Load from the cache.
3235 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3236 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3238 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3239 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3240 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3241 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3242 RemoveMockTransaction(&transaction2
);
3245 // Tests that a HEAD request invalidates an old cached entry.
3246 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3247 MockHttpCache cache
;
3248 MockTransaction
transaction(kTypicalGET_Transaction
);
3249 AddMockTransaction(&transaction
);
3251 // Populate the cache.
3252 RunTransactionTest(cache
.http_cache(), transaction
);
3254 // Update the cache.
3255 transaction
.method
= "HEAD";
3256 transaction
.data
= "";
3257 RunTransactionTest(cache
.http_cache(), transaction
);
3258 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3260 // Load from the cache.
3261 transaction
.method
= "GET";
3262 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3263 transaction
.return_code
= net::ERR_CACHE_MISS
;
3264 RunTransactionTest(cache
.http_cache(), transaction
);
3266 RemoveMockTransaction(&transaction
);
3269 // Tests that we do not cache the response of a PUT.
3270 TEST(HttpCache
, SimplePUT_Miss
) {
3271 MockHttpCache cache
;
3273 MockTransaction
transaction(kSimplePOST_Transaction
);
3274 transaction
.method
= "PUT";
3276 ScopedVector
<net::UploadElementReader
> element_readers
;
3277 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3278 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3280 MockHttpRequest
request(transaction
);
3281 request
.upload_data_stream
= &upload_data_stream
;
3283 // Attempt to populate the cache.
3284 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3286 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3287 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3288 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3291 // Tests that we invalidate entries as a result of a PUT.
3292 TEST(HttpCache
, SimplePUT_Invalidate
) {
3293 MockHttpCache cache
;
3295 MockTransaction
transaction(kSimpleGET_Transaction
);
3296 MockHttpRequest
req1(transaction
);
3298 // Attempt to populate the cache.
3299 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3301 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3302 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3303 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3305 ScopedVector
<net::UploadElementReader
> element_readers
;
3306 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3307 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3309 transaction
.method
= "PUT";
3310 MockHttpRequest
req2(transaction
);
3311 req2
.upload_data_stream
= &upload_data_stream
;
3313 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3315 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3316 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3317 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3319 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3321 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3322 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3323 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3326 // Tests that we invalidate entries as a result of a PUT.
3327 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3328 MockHttpCache cache
;
3330 MockTransaction
transaction(kSimpleGET_Transaction
);
3331 AddMockTransaction(&transaction
);
3332 MockHttpRequest
req1(transaction
);
3334 // Attempt to populate the cache.
3335 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3337 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3338 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3339 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3341 ScopedVector
<net::UploadElementReader
> element_readers
;
3342 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3343 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3345 transaction
.method
= "PUT";
3346 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3347 MockHttpRequest
req2(transaction
);
3348 req2
.upload_data_stream
= &upload_data_stream
;
3350 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3352 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3353 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3354 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3356 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3358 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3359 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3360 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3361 RemoveMockTransaction(&transaction
);
3364 // Tests that we don't invalidate entries as a result of a failed PUT.
3365 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3366 MockHttpCache cache
;
3368 MockTransaction
transaction(kSimpleGET_Transaction
);
3369 AddMockTransaction(&transaction
);
3370 MockHttpRequest
req1(transaction
);
3372 // Attempt to populate the cache.
3373 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3375 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3376 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3377 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3379 ScopedVector
<net::UploadElementReader
> element_readers
;
3380 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3381 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3383 transaction
.method
= "PUT";
3384 transaction
.status
= "HTTP/1.1 404 Not Found";
3385 MockHttpRequest
req2(transaction
);
3386 req2
.upload_data_stream
= &upload_data_stream
;
3388 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3390 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3391 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3392 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3394 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3396 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3397 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3398 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3399 RemoveMockTransaction(&transaction
);
3402 // Tests that we do not cache the response of a DELETE.
3403 TEST(HttpCache
, SimpleDELETE_Miss
) {
3404 MockHttpCache cache
;
3406 MockTransaction
transaction(kSimplePOST_Transaction
);
3407 transaction
.method
= "DELETE";
3409 ScopedVector
<net::UploadElementReader
> element_readers
;
3410 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3411 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3413 MockHttpRequest
request(transaction
);
3414 request
.upload_data_stream
= &upload_data_stream
;
3416 // Attempt to populate the cache.
3417 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3419 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3420 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3421 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3424 // Tests that we invalidate entries as a result of a DELETE.
3425 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3426 MockHttpCache cache
;
3428 MockTransaction
transaction(kSimpleGET_Transaction
);
3429 MockHttpRequest
req1(transaction
);
3431 // Attempt to populate the cache.
3432 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3434 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3435 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3436 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3438 ScopedVector
<net::UploadElementReader
> element_readers
;
3439 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3440 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3442 transaction
.method
= "DELETE";
3443 MockHttpRequest
req2(transaction
);
3444 req2
.upload_data_stream
= &upload_data_stream
;
3446 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3448 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3449 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3450 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3452 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3454 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3455 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3456 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3459 // Tests that we invalidate entries as a result of a DELETE.
3460 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3461 MockHttpCache cache
;
3463 MockTransaction
transaction(kSimpleGET_Transaction
);
3464 AddMockTransaction(&transaction
);
3466 // Attempt to populate the cache.
3467 RunTransactionTest(cache
.http_cache(), transaction
);
3469 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3470 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3471 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3473 transaction
.method
= "DELETE";
3474 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3476 RunTransactionTest(cache
.http_cache(), transaction
);
3478 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3479 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3480 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3482 transaction
.method
= "GET";
3483 RunTransactionTest(cache
.http_cache(), transaction
);
3485 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3486 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3487 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3488 RemoveMockTransaction(&transaction
);
3491 // Tests that we don't invalidate entries as a result of a failed DELETE.
3492 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3493 MockHttpCache cache
;
3495 MockTransaction
transaction(kSimpleGET_Transaction
);
3496 AddMockTransaction(&transaction
);
3498 // Attempt to populate the cache.
3499 RunTransactionTest(cache
.http_cache(), transaction
);
3501 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3502 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3503 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3505 transaction
.method
= "DELETE";
3506 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3508 RunTransactionTest(cache
.http_cache(), transaction
);
3510 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3511 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3512 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3514 transaction
.method
= "GET";
3515 transaction
.status
= "HTTP/1.1 200 OK";
3516 RunTransactionTest(cache
.http_cache(), transaction
);
3518 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3519 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3520 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3521 RemoveMockTransaction(&transaction
);
3524 // Tests that we don't invalidate entries after a failed network transaction.
3525 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3526 MockHttpCache cache
;
3528 // Populate the cache.
3529 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3530 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3532 // Fail the network request.
3533 MockTransaction
transaction(kSimpleGET_Transaction
);
3534 transaction
.return_code
= net::ERR_FAILED
;
3535 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3537 AddMockTransaction(&transaction
);
3538 RunTransactionTest(cache
.http_cache(), transaction
);
3539 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3540 RemoveMockTransaction(&transaction
);
3542 transaction
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
3543 transaction
.return_code
= net::OK
;
3544 AddMockTransaction(&transaction
);
3545 RunTransactionTest(cache
.http_cache(), transaction
);
3547 // Make sure the transaction didn't reach the network.
3548 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3549 RemoveMockTransaction(&transaction
);
3552 TEST(HttpCache
, RangeGET_SkipsCache
) {
3553 MockHttpCache cache
;
3555 // Test that we skip the cache for range GET requests. Eventually, we will
3556 // want to cache these, but we'll still have cases where skipping the cache
3557 // makes sense, so we want to make sure that it works properly.
3559 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3561 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3562 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3563 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3565 MockTransaction
transaction(kSimpleGET_Transaction
);
3566 transaction
.request_headers
= "If-None-Match: foo\r\n";
3567 RunTransactionTest(cache
.http_cache(), transaction
);
3569 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3570 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3571 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3573 transaction
.request_headers
=
3574 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3575 RunTransactionTest(cache
.http_cache(), transaction
);
3577 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3578 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3579 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3582 // Test that we skip the cache for range requests that include a validation
3584 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3585 MockHttpCache cache
;
3587 MockTransaction
transaction(kRangeGET_Transaction
);
3588 transaction
.request_headers
= "If-None-Match: foo\r\n"
3590 "Range: bytes = 40-49\r\n";
3591 RunTransactionTest(cache
.http_cache(), transaction
);
3593 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3594 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3595 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3597 transaction
.request_headers
=
3598 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3600 "Range: bytes = 40-49\r\n";
3601 RunTransactionTest(cache
.http_cache(), transaction
);
3603 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3605 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3607 transaction
.request_headers
= "If-Range: bla\r\n"
3609 "Range: bytes = 40-49\r\n";
3610 RunTransactionTest(cache
.http_cache(), transaction
);
3612 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3613 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3614 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3617 // Tests that receiving 206 for a regular request is handled correctly.
3618 TEST(HttpCache
, GET_Crazy206
) {
3619 MockHttpCache cache
;
3621 // Write to the cache.
3622 MockTransaction
transaction(kRangeGET_TransactionOK
);
3623 AddMockTransaction(&transaction
);
3624 transaction
.request_headers
= EXTRA_HEADER
;
3625 transaction
.handler
= NULL
;
3626 RunTransactionTest(cache
.http_cache(), transaction
);
3628 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3629 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3630 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3632 // This should read again from the net.
3633 RunTransactionTest(cache
.http_cache(), transaction
);
3635 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3636 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3637 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3638 RemoveMockTransaction(&transaction
);
3641 // Tests that receiving 416 for a regular request is handled correctly.
3642 TEST(HttpCache
, GET_Crazy416
) {
3643 MockHttpCache cache
;
3645 // Write to the cache.
3646 MockTransaction
transaction(kSimpleGET_Transaction
);
3647 AddMockTransaction(&transaction
);
3648 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3649 RunTransactionTest(cache
.http_cache(), transaction
);
3651 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3652 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3653 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3655 RemoveMockTransaction(&transaction
);
3658 // Tests that we store partial responses that can't be validated, as they can
3659 // be used for requests that don't require revalidation.
3660 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3661 MockHttpCache cache
;
3662 std::string headers
;
3664 // Write to the cache (40-49).
3665 MockTransaction
transaction(kRangeGET_TransactionOK
);
3666 AddMockTransaction(&transaction
);
3667 transaction
.response_headers
= "Content-Length: 10\n"
3668 "Cache-Control: max-age=3600\n"
3669 "ETag: w/\"foo\"\n";
3670 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3672 Verify206Response(headers
, 40, 49);
3673 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3674 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3675 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3677 // Now verify that there's cached data.
3678 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3681 Verify206Response(headers
, 40, 49);
3682 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3683 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3684 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3686 RemoveMockTransaction(&transaction
);
3689 // Tests failures to validate cache partial responses that lack strong
3691 TEST(HttpCache
, RangeGET_NoValidation
) {
3692 MockHttpCache cache
;
3693 std::string headers
;
3695 // Write to the cache (40-49).
3696 MockTransaction
transaction(kRangeGET_TransactionOK
);
3697 AddMockTransaction(&transaction
);
3698 transaction
.response_headers
= "Content-Length: 10\n"
3699 "ETag: w/\"foo\"\n";
3700 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3702 Verify206Response(headers
, 40, 49);
3703 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3704 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3705 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3707 // Now verify that the cached data is not used.
3708 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3711 Verify206Response(headers
, 40, 49);
3712 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3713 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3714 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3716 RemoveMockTransaction(&transaction
);
3719 // Tests that we cache partial responses that lack content-length.
3720 TEST(HttpCache
, RangeGET_NoContentLength
) {
3721 MockHttpCache cache
;
3722 std::string headers
;
3724 // Attempt to write to the cache (40-49).
3725 MockTransaction
transaction(kRangeGET_TransactionOK
);
3726 AddMockTransaction(&transaction
);
3727 transaction
.response_headers
= "ETag: \"foo\"\n"
3728 "Accept-Ranges: bytes\n"
3729 "Content-Range: bytes 40-49/80\n";
3730 transaction
.handler
= NULL
;
3731 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3733 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3734 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3735 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3737 // Now verify that there's no cached data.
3738 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
3739 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3742 Verify206Response(headers
, 40, 49);
3743 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3744 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3745 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3747 RemoveMockTransaction(&transaction
);
3750 // Tests that we can cache range requests and fetch random blocks from the
3751 // cache and the network.
3752 TEST(HttpCache
, RangeGET_OK
) {
3753 MockHttpCache cache
;
3754 AddMockTransaction(&kRangeGET_TransactionOK
);
3755 std::string headers
;
3757 // Write to the cache (40-49).
3758 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3761 Verify206Response(headers
, 40, 49);
3762 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3763 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3764 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3766 // Read from the cache (40-49).
3767 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3770 Verify206Response(headers
, 40, 49);
3771 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3772 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3773 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3775 // Make sure we are done with the previous transaction.
3776 base::MessageLoop::current()->RunUntilIdle();
3778 // Write to the cache (30-39).
3779 MockTransaction
transaction(kRangeGET_TransactionOK
);
3780 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3781 transaction
.data
= "rg: 30-39 ";
3782 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3784 Verify206Response(headers
, 30, 39);
3785 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3786 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3787 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3789 // Make sure we are done with the previous transaction.
3790 base::MessageLoop::current()->RunUntilIdle();
3792 // Write and read from the cache (20-59).
3793 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3794 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3795 net::CapturingBoundNetLog log
;
3796 net::LoadTimingInfo load_timing_info
;
3797 RunTransactionTestWithResponseAndGetTiming(
3798 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3801 Verify206Response(headers
, 20, 59);
3802 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3803 EXPECT_EQ(3, cache
.disk_cache()->open_count());
3804 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3805 TestLoadTimingNetworkRequest(load_timing_info
);
3807 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3810 // Checks that with a cache backend having Sparse IO unimplementes the cache
3811 // entry would be doomed after a range request.
3812 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3813 TEST(HttpCache
, RangeGET_SparseNotImplemented
) {
3814 MockHttpCache cache
;
3815 cache
.disk_cache()->set_fail_sparse_requests();
3817 // Run a cacheable request to prime the cache.
3818 MockTransaction
transaction(kTypicalGET_Transaction
);
3819 transaction
.url
= kRangeGET_TransactionOK
.url
;
3820 AddMockTransaction(&transaction
);
3821 RunTransactionTest(cache
.http_cache(), transaction
);
3822 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3823 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3824 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3826 // Verify that we added the entry.
3827 disk_cache::Entry
* entry
;
3828 net::TestCompletionCallback cb
;
3829 int rv
= cache
.disk_cache()->OpenEntry(transaction
.url
,
3832 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
3833 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3835 RemoveMockTransaction(&transaction
);
3837 // Request the range with the backend that does not support it.
3838 MockTransaction
transaction2(kRangeGET_TransactionOK
);
3839 std::string headers
;
3840 AddMockTransaction(&transaction2
);
3841 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3842 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3843 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3844 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3846 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3847 // if it was re-created later, so this effectively checks that the old data is
3849 disk_cache::Entry
* entry2
;
3850 rv
= cache
.disk_cache()->OpenEntry(transaction2
.url
,
3853 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE
, cb
.GetResult(rv
));
3854 RemoveMockTransaction(&transaction2
);
3857 TEST(HttpCache
, RangeGET_SparseNotImplementedOnEmptyCache
) {
3858 MockHttpCache cache
;
3859 cache
.disk_cache()->set_fail_sparse_requests();
3861 // Request the range with the backend that does not support it.
3862 MockTransaction
transaction(kRangeGET_TransactionOK
);
3863 std::string headers
;
3864 AddMockTransaction(&transaction
);
3865 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3866 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3867 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3868 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3870 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3871 // if it was re-created later, so this effectively checks that the old data is
3872 // gone as a result of a failed range write.
3873 disk_cache::Entry
* entry
;
3874 net::TestCompletionCallback cb
;
3875 int rv
= cache
.disk_cache()->OpenEntry(transaction
.url
,
3878 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE
, cb
.GetResult(rv
));
3879 RemoveMockTransaction(&transaction
);
3882 // Tests that we can cache range requests and fetch random blocks from the
3883 // cache and the network, with synchronous responses.
3884 TEST(HttpCache
, RangeGET_SyncOK
) {
3885 MockHttpCache cache
;
3887 MockTransaction
transaction(kRangeGET_TransactionOK
);
3888 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
3889 AddMockTransaction(&transaction
);
3891 // Write to the cache (40-49).
3892 std::string headers
;
3893 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3895 Verify206Response(headers
, 40, 49);
3896 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3897 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3898 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3900 // Read from the cache (40-49).
3901 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3903 Verify206Response(headers
, 40, 49);
3904 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3905 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3906 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3908 // Make sure we are done with the previous transaction.
3909 base::MessageLoop::current()->RunUntilIdle();
3911 // Write to the cache (30-39).
3912 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3913 transaction
.data
= "rg: 30-39 ";
3914 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3916 Verify206Response(headers
, 30, 39);
3917 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3918 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3919 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3921 // Make sure we are done with the previous transaction.
3922 base::MessageLoop::current()->RunUntilIdle();
3924 // Write and read from the cache (20-59).
3925 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3926 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3927 net::CapturingBoundNetLog log
;
3928 net::LoadTimingInfo load_timing_info
;
3929 RunTransactionTestWithResponseAndGetTiming(
3930 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3933 Verify206Response(headers
, 20, 59);
3934 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3935 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3936 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3937 TestLoadTimingNetworkRequest(load_timing_info
);
3939 RemoveMockTransaction(&transaction
);
3942 // Tests that we don't revalidate an entry unless we are required to do so.
3943 TEST(HttpCache
, RangeGET_Revalidate1
) {
3944 MockHttpCache cache
;
3945 std::string headers
;
3947 // Write to the cache (40-49).
3948 MockTransaction
transaction(kRangeGET_TransactionOK
);
3949 transaction
.response_headers
=
3950 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3951 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3953 "Accept-Ranges: bytes\n"
3954 "Content-Length: 10\n";
3955 AddMockTransaction(&transaction
);
3956 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3958 Verify206Response(headers
, 40, 49);
3959 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3960 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3961 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3963 // Read from the cache (40-49).
3964 net::CapturingBoundNetLog log
;
3965 net::LoadTimingInfo load_timing_info
;
3966 RunTransactionTestWithResponseAndGetTiming(
3967 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3970 Verify206Response(headers
, 40, 49);
3971 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3972 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3973 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3974 TestLoadTimingCachedResponse(load_timing_info
);
3976 // Read again forcing the revalidation.
3977 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3978 RunTransactionTestWithResponseAndGetTiming(
3979 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3982 Verify206Response(headers
, 40, 49);
3983 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3984 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3985 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3986 TestLoadTimingNetworkRequest(load_timing_info
);
3988 RemoveMockTransaction(&transaction
);
3991 // Checks that we revalidate an entry when the headers say so.
3992 TEST(HttpCache
, RangeGET_Revalidate2
) {
3993 MockHttpCache cache
;
3994 std::string headers
;
3996 // Write to the cache (40-49).
3997 MockTransaction
transaction(kRangeGET_TransactionOK
);
3998 transaction
.response_headers
=
3999 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4000 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4002 "Accept-Ranges: bytes\n"
4003 "Content-Length: 10\n";
4004 AddMockTransaction(&transaction
);
4005 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4007 Verify206Response(headers
, 40, 49);
4008 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4009 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4010 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4012 // Read from the cache (40-49).
4013 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4014 Verify206Response(headers
, 40, 49);
4016 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4017 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4018 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4020 RemoveMockTransaction(&transaction
);
4023 // Tests that we deal with 304s for range requests.
4024 TEST(HttpCache
, RangeGET_304
) {
4025 MockHttpCache cache
;
4026 AddMockTransaction(&kRangeGET_TransactionOK
);
4027 std::string headers
;
4029 // Write to the cache (40-49).
4030 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4033 Verify206Response(headers
, 40, 49);
4034 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4035 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4036 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4038 // Read from the cache (40-49).
4039 RangeTransactionServer handler
;
4040 handler
.set_not_modified(true);
4041 MockTransaction
transaction(kRangeGET_TransactionOK
);
4042 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4043 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4045 Verify206Response(headers
, 40, 49);
4046 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4047 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4048 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4050 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4053 // Tests that we deal with 206s when revalidating range requests.
4054 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4055 MockHttpCache cache
;
4056 AddMockTransaction(&kRangeGET_TransactionOK
);
4057 std::string headers
;
4059 // Write to the cache (40-49).
4060 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4063 Verify206Response(headers
, 40, 49);
4064 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4065 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4066 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4068 // Attempt to read from the cache (40-49).
4069 RangeTransactionServer handler
;
4070 handler
.set_modified(true);
4071 MockTransaction
transaction(kRangeGET_TransactionOK
);
4072 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4073 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4075 Verify206Response(headers
, 40, 49);
4076 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4077 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4078 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4080 // And the entry should be gone.
4081 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4082 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4083 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4084 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4086 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4089 // Tests that we cache 301s for range requests.
4090 TEST(HttpCache
, RangeGET_301
) {
4091 MockHttpCache cache
;
4092 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4093 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4094 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4095 transaction
.data
= "";
4096 transaction
.handler
= NULL
;
4097 AddMockTransaction(&transaction
);
4099 // Write to the cache.
4100 RunTransactionTest(cache
.http_cache(), transaction
);
4101 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4102 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4103 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4105 // Read from the cache.
4106 RunTransactionTest(cache
.http_cache(), transaction
);
4107 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4108 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4109 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4111 RemoveMockTransaction(&transaction
);
4114 // Tests that we can cache range requests when the start or end is unknown.
4115 // We start with one suffix request, followed by a request from a given point.
4116 TEST(HttpCache
, UnknownRangeGET_1
) {
4117 MockHttpCache cache
;
4118 AddMockTransaction(&kRangeGET_TransactionOK
);
4119 std::string headers
;
4121 // Write to the cache (70-79).
4122 MockTransaction
transaction(kRangeGET_TransactionOK
);
4123 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4124 transaction
.data
= "rg: 70-79 ";
4125 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4127 Verify206Response(headers
, 70, 79);
4128 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4129 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4130 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4132 // Make sure we are done with the previous transaction.
4133 base::MessageLoop::current()->RunUntilIdle();
4135 // Write and read from the cache (60-79).
4136 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4137 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4138 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4140 Verify206Response(headers
, 60, 79);
4141 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4142 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4143 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4145 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4148 // Tests that we can cache range requests when the start or end is unknown.
4149 // We start with one request from a given point, followed by a suffix request.
4150 // We'll also verify that synchronous cache responses work as intended.
4151 TEST(HttpCache
, UnknownRangeGET_2
) {
4152 MockHttpCache cache
;
4153 std::string headers
;
4155 MockTransaction
transaction(kRangeGET_TransactionOK
);
4156 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4157 TEST_MODE_SYNC_CACHE_READ
|
4158 TEST_MODE_SYNC_CACHE_WRITE
;
4159 AddMockTransaction(&transaction
);
4161 // Write to the cache (70-79).
4162 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4163 transaction
.data
= "rg: 70-79 ";
4164 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4166 Verify206Response(headers
, 70, 79);
4167 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4168 EXPECT_EQ(0, 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 (60-79).
4175 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4176 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4177 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4179 Verify206Response(headers
, 60, 79);
4180 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4181 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4182 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4184 RemoveMockTransaction(&transaction
);
4187 // Tests that receiving Not Modified when asking for an open range doesn't mess
4189 TEST(HttpCache
, UnknownRangeGET_304
) {
4190 MockHttpCache cache
;
4191 std::string headers
;
4193 MockTransaction
transaction(kRangeGET_TransactionOK
);
4194 AddMockTransaction(&transaction
);
4196 RangeTransactionServer handler
;
4197 handler
.set_not_modified(true);
4199 // Ask for the end of the file, without knowing the length.
4200 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4201 transaction
.data
= "";
4202 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4204 // We just bypass the cache.
4205 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4206 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4207 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4208 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4210 RunTransactionTest(cache
.http_cache(), transaction
);
4211 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4213 RemoveMockTransaction(&transaction
);
4216 // Tests that we can handle non-range requests when we have cached a range.
4217 TEST(HttpCache
, GET_Previous206
) {
4218 MockHttpCache cache
;
4219 AddMockTransaction(&kRangeGET_TransactionOK
);
4220 std::string headers
;
4221 net::CapturingBoundNetLog log
;
4222 net::LoadTimingInfo load_timing_info
;
4224 // Write to the cache (40-49).
4225 RunTransactionTestWithResponseAndGetTiming(
4226 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4229 Verify206Response(headers
, 40, 49);
4230 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4231 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4232 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4233 TestLoadTimingNetworkRequest(load_timing_info
);
4235 // Write and read from the cache (0-79), when not asked for a range.
4236 MockTransaction
transaction(kRangeGET_TransactionOK
);
4237 transaction
.request_headers
= EXTRA_HEADER
;
4238 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4239 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4240 RunTransactionTestWithResponseAndGetTiming(
4241 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4244 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4245 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4246 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4247 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4248 TestLoadTimingNetworkRequest(load_timing_info
);
4250 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4253 // Tests that we can handle non-range requests when we have cached the first
4254 // part of the object and the server replies with 304 (Not Modified).
4255 TEST(HttpCache
, GET_Previous206_NotModified
) {
4256 MockHttpCache cache
;
4258 MockTransaction
transaction(kRangeGET_TransactionOK
);
4259 AddMockTransaction(&transaction
);
4260 std::string headers
;
4261 net::CapturingBoundNetLog log
;
4262 net::LoadTimingInfo load_timing_info
;
4264 // Write to the cache (0-9).
4265 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4266 transaction
.data
= "rg: 00-09 ";
4267 RunTransactionTestWithResponseAndGetTiming(
4268 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4270 Verify206Response(headers
, 0, 9);
4271 TestLoadTimingNetworkRequest(load_timing_info
);
4273 // Write to the cache (70-79).
4274 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4275 transaction
.data
= "rg: 70-79 ";
4276 RunTransactionTestWithResponseAndGetTiming(
4277 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4279 Verify206Response(headers
, 70, 79);
4281 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4282 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4283 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4284 TestLoadTimingNetworkRequest(load_timing_info
);
4286 // Read from the cache (0-9), write and read from cache (10 - 79).
4287 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4288 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4289 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4290 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4291 RunTransactionTestWithResponseAndGetTiming(
4292 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4295 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4296 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4297 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4298 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4299 TestLoadTimingNetworkRequest(load_timing_info
);
4301 RemoveMockTransaction(&transaction
);
4304 // Tests that we can handle a regular request to a sparse entry, that results in
4305 // new content provided by the server (206).
4306 TEST(HttpCache
, GET_Previous206_NewContent
) {
4307 MockHttpCache cache
;
4308 AddMockTransaction(&kRangeGET_TransactionOK
);
4309 std::string headers
;
4311 // Write to the cache (0-9).
4312 MockTransaction
transaction(kRangeGET_TransactionOK
);
4313 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4314 transaction
.data
= "rg: 00-09 ";
4315 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4317 Verify206Response(headers
, 0, 9);
4318 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4319 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4320 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4322 // Now we'll issue a request without any range that should result first in a
4323 // 206 (when revalidating), and then in a weird standard answer: the test
4324 // server will not modify the response so we'll get the default range... a
4325 // real server will answer with 200.
4326 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4327 transaction2
.request_headers
= EXTRA_HEADER
;
4328 transaction2
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4329 transaction2
.data
= "Not a range";
4330 RangeTransactionServer handler
;
4331 handler
.set_modified(true);
4332 net::CapturingBoundNetLog log
;
4333 net::LoadTimingInfo load_timing_info
;
4334 RunTransactionTestWithResponseAndGetTiming(
4335 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4338 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4339 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4340 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4341 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4342 TestLoadTimingNetworkRequest(load_timing_info
);
4344 // Verify that the previous request deleted the entry.
4345 RunTransactionTest(cache
.http_cache(), transaction
);
4346 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4348 RemoveMockTransaction(&transaction
);
4351 // Tests that we can handle cached 206 responses that are not sparse.
4352 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4353 MockHttpCache cache
;
4355 // Create a disk cache entry that stores 206 headers while not being sparse.
4356 disk_cache::Entry
* entry
;
4357 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4360 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4361 raw_headers
.append("\n");
4362 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4363 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4364 raw_headers
.size());
4366 net::HttpResponseInfo response
;
4367 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4368 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4370 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4371 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4372 kRangeGET_TransactionOK
.data
, 500));
4373 net::TestCompletionCallback cb
;
4374 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4375 EXPECT_EQ(len
, cb
.GetResult(rv
));
4378 // Now see that we don't use the stored entry.
4379 std::string headers
;
4380 net::CapturingBoundNetLog log
;
4381 net::LoadTimingInfo load_timing_info
;
4382 RunTransactionTestWithResponseAndGetTiming(
4383 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4386 // We are expecting a 200.
4387 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4388 expected_headers
.append("\n");
4389 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4390 EXPECT_EQ(expected_headers
, headers
);
4391 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4392 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4393 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4394 TestLoadTimingNetworkRequest(load_timing_info
);
4397 // Tests that we can handle cached 206 responses that are not sparse. This time
4398 // we issue a range request and expect to receive a range.
4399 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4400 MockHttpCache cache
;
4401 AddMockTransaction(&kRangeGET_TransactionOK
);
4403 // Create a disk cache entry that stores 206 headers while not being sparse.
4404 disk_cache::Entry
* entry
;
4405 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4408 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4409 raw_headers
.append("\n");
4410 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4411 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4412 raw_headers
.size());
4414 net::HttpResponseInfo response
;
4415 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4416 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4418 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4419 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4420 kRangeGET_TransactionOK
.data
, 500));
4421 net::TestCompletionCallback cb
;
4422 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4423 EXPECT_EQ(len
, cb
.GetResult(rv
));
4426 // Now see that we don't use the stored entry.
4427 std::string headers
;
4428 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4431 // We are expecting a 206.
4432 Verify206Response(headers
, 40, 49);
4433 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4434 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4435 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4437 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4440 // Tests that we can handle cached 206 responses that can't be validated.
4441 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4442 MockHttpCache cache
;
4444 // Create a disk cache entry that stores 206 headers.
4445 disk_cache::Entry
* entry
;
4446 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4449 // Make sure that the headers cannot be validated with the server.
4450 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4451 raw_headers
.append("\n");
4452 raw_headers
.append("Content-Length: 80\n");
4453 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4454 raw_headers
.size());
4456 net::HttpResponseInfo response
;
4457 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4458 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4460 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4461 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4462 kRangeGET_TransactionOK
.data
, 500));
4463 net::TestCompletionCallback cb
;
4464 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4465 EXPECT_EQ(len
, cb
.GetResult(rv
));
4468 // Now see that we don't use the stored entry.
4469 std::string headers
;
4470 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4473 // We are expecting a 200.
4474 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4475 expected_headers
.append("\n");
4476 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4477 EXPECT_EQ(expected_headers
, headers
);
4478 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4479 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4480 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4483 // Tests that we can handle range requests with cached 200 responses.
4484 TEST(HttpCache
, RangeGET_Previous200
) {
4485 MockHttpCache cache
;
4487 // Store the whole thing with status 200.
4488 MockTransaction
transaction(kTypicalGET_Transaction
);
4489 transaction
.url
= kRangeGET_TransactionOK
.url
;
4490 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4491 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4492 AddMockTransaction(&transaction
);
4493 RunTransactionTest(cache
.http_cache(), transaction
);
4494 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4495 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4496 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4498 RemoveMockTransaction(&transaction
);
4499 AddMockTransaction(&kRangeGET_TransactionOK
);
4501 // Now see that we use the stored entry.
4502 std::string headers
;
4503 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4504 RangeTransactionServer handler
;
4505 handler
.set_not_modified(true);
4506 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4508 // We are expecting a 206.
4509 Verify206Response(headers
, 40, 49);
4510 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4511 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4512 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4514 // The last transaction has finished so make sure the entry is deactivated.
4515 base::MessageLoop::current()->RunUntilIdle();
4517 // Make a request for an invalid range.
4518 MockTransaction
transaction3(kRangeGET_TransactionOK
);
4519 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
4520 transaction3
.data
= transaction
.data
;
4521 transaction3
.load_flags
= net::LOAD_PREFERRING_CACHE
;
4522 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
4523 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4524 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
4525 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
4526 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
4528 // Make sure the entry is deactivated.
4529 base::MessageLoop::current()->RunUntilIdle();
4531 // Even though the request was invalid, we should have the entry.
4532 RunTransactionTest(cache
.http_cache(), transaction2
);
4533 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4535 // Make sure the entry is deactivated.
4536 base::MessageLoop::current()->RunUntilIdle();
4538 // Now we should receive a range from the server and drop the stored entry.
4539 handler
.set_not_modified(false);
4540 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4541 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4542 Verify206Response(headers
, 40, 49);
4543 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4544 EXPECT_EQ(4, cache
.disk_cache()->open_count());
4545 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4547 RunTransactionTest(cache
.http_cache(), transaction2
);
4548 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4550 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4553 // Tests that we can handle a 200 response when dealing with sparse entries.
4554 TEST(HttpCache
, RangeRequestResultsIn200
) {
4555 MockHttpCache cache
;
4556 AddMockTransaction(&kRangeGET_TransactionOK
);
4557 std::string headers
;
4559 // Write to the cache (70-79).
4560 MockTransaction
transaction(kRangeGET_TransactionOK
);
4561 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4562 transaction
.data
= "rg: 70-79 ";
4563 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4565 Verify206Response(headers
, 70, 79);
4566 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4567 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4568 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4570 // Now we'll issue a request that results in a plain 200 response, but to
4571 // the to the same URL that we used to store sparse data, and making sure
4572 // that we ask for a range.
4573 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4574 MockTransaction
transaction2(kSimpleGET_Transaction
);
4575 transaction2
.url
= kRangeGET_TransactionOK
.url
;
4576 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4577 AddMockTransaction(&transaction2
);
4579 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4581 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4582 expected_headers
.append("\n");
4583 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4584 EXPECT_EQ(expected_headers
, headers
);
4585 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4586 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4587 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4589 RemoveMockTransaction(&transaction2
);
4592 // Tests that a range request that falls outside of the size that we know about
4593 // only deletes the entry if the resource has indeed changed.
4594 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
4595 MockHttpCache cache
;
4596 AddMockTransaction(&kRangeGET_TransactionOK
);
4597 std::string headers
;
4599 // Write to the cache (40-49).
4600 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4603 Verify206Response(headers
, 40, 49);
4604 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4605 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4606 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4608 // A weird request should not delete this entry. Ask for bytes 120-.
4609 MockTransaction
transaction(kRangeGET_TransactionOK
);
4610 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
4611 transaction
.data
= "";
4612 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4614 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
4615 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4616 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4617 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4619 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4620 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4621 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4623 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4626 // Tests that we don't delete a sparse entry when we cancel a request.
4627 TEST(HttpCache
, RangeGET_Cancel
) {
4628 MockHttpCache cache
;
4629 AddMockTransaction(&kRangeGET_TransactionOK
);
4631 MockHttpRequest
request(kRangeGET_TransactionOK
);
4633 Context
* c
= new Context();
4634 int rv
= cache
.CreateTransaction(&c
->trans
);
4635 ASSERT_EQ(net::OK
, rv
);
4637 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4638 if (rv
== net::ERR_IO_PENDING
)
4639 rv
= c
->callback
.WaitForResult();
4641 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4642 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4643 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4645 // Make sure that the entry has some data stored.
4646 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
4647 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4648 if (rv
== net::ERR_IO_PENDING
)
4649 rv
= c
->callback
.WaitForResult();
4650 EXPECT_EQ(buf
->size(), rv
);
4652 // Destroy the transaction.
4655 // Verify that the entry has not been deleted.
4656 disk_cache::Entry
* entry
;
4657 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4659 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4662 // Tests that we don't delete a sparse entry when we start a new request after
4663 // cancelling the previous one.
4664 TEST(HttpCache
, RangeGET_Cancel2
) {
4665 MockHttpCache cache
;
4666 AddMockTransaction(&kRangeGET_TransactionOK
);
4668 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4669 MockHttpRequest
request(kRangeGET_TransactionOK
);
4670 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4672 Context
* c
= new Context();
4673 int rv
= cache
.CreateTransaction(&c
->trans
);
4674 ASSERT_EQ(net::OK
, rv
);
4676 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4677 if (rv
== net::ERR_IO_PENDING
)
4678 rv
= c
->callback
.WaitForResult();
4680 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4681 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4682 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4684 // Make sure that we revalidate the entry and read from the cache (a single
4685 // read will return while waiting for the network).
4686 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
4687 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4688 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
4689 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4690 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4692 // Destroy the transaction before completing the read.
4695 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4696 // message loop. This means that a new transaction will just reuse the same
4697 // active entry (no open or create).
4699 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4701 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4702 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4703 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4704 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4707 // A slight variation of the previous test, this time we cancel two requests in
4708 // a row, making sure that the second is waiting for the entry to be ready.
4709 TEST(HttpCache
, RangeGET_Cancel3
) {
4710 MockHttpCache cache
;
4711 AddMockTransaction(&kRangeGET_TransactionOK
);
4713 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4714 MockHttpRequest
request(kRangeGET_TransactionOK
);
4715 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4717 Context
* c
= new Context();
4718 int rv
= cache
.CreateTransaction(&c
->trans
);
4719 ASSERT_EQ(net::OK
, rv
);
4721 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4722 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4723 rv
= c
->callback
.WaitForResult();
4725 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4726 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4727 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4729 // Make sure that we revalidate the entry and read from the cache (a single
4730 // read will return while waiting for the network).
4731 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
4732 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4733 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
4734 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4735 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4737 // Destroy the transaction before completing the read.
4740 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4741 // message loop. This means that a new transaction will just reuse the same
4742 // active entry (no open or create).
4745 rv
= cache
.CreateTransaction(&c
->trans
);
4746 ASSERT_EQ(net::OK
, rv
);
4748 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4749 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4751 MockDiskEntry::IgnoreCallbacks(true);
4752 base::MessageLoop::current()->RunUntilIdle();
4753 MockDiskEntry::IgnoreCallbacks(false);
4755 // The new transaction is waiting for the query range callback.
4758 // And we should not crash when the callback is delivered.
4759 base::MessageLoop::current()->RunUntilIdle();
4761 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4762 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4763 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4764 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4767 // Tests that an invalid range response results in no cached entry.
4768 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
4769 MockHttpCache cache
;
4770 std::string headers
;
4772 MockTransaction
transaction(kRangeGET_TransactionOK
);
4773 transaction
.handler
= NULL
;
4774 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
4775 "Content-Length: 10\n";
4776 AddMockTransaction(&transaction
);
4777 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4779 std::string
expected(transaction
.status
);
4780 expected
.append("\n");
4781 expected
.append(transaction
.response_headers
);
4782 EXPECT_EQ(expected
, headers
);
4784 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4785 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4786 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4788 // Verify that we don't have a cached entry.
4789 disk_cache::Entry
* entry
;
4790 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4792 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4795 // Tests that we reject a range that doesn't match the content-length.
4796 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
4797 MockHttpCache cache
;
4798 std::string headers
;
4800 MockTransaction
transaction(kRangeGET_TransactionOK
);
4801 transaction
.handler
= NULL
;
4802 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
4803 "Content-Length: 20\n";
4804 AddMockTransaction(&transaction
);
4805 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4807 std::string
expected(transaction
.status
);
4808 expected
.append("\n");
4809 expected
.append(transaction
.response_headers
);
4810 EXPECT_EQ(expected
, headers
);
4812 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4813 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4814 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4816 // Verify that we don't have a cached entry.
4817 disk_cache::Entry
* entry
;
4818 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4820 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4823 // Tests that if a server tells us conflicting information about a resource we
4824 // ignore the response.
4825 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
4826 MockHttpCache cache
;
4827 std::string headers
;
4829 MockTransaction
transaction(kRangeGET_TransactionOK
);
4830 transaction
.handler
= NULL
;
4831 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
4832 std::string
response_headers(transaction
.response_headers
);
4833 response_headers
.append("Content-Range: bytes 50-59/160\n");
4834 transaction
.response_headers
= response_headers
.c_str();
4835 AddMockTransaction(&transaction
);
4836 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4838 Verify206Response(headers
, 50, 59);
4839 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4840 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4841 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4843 RemoveMockTransaction(&transaction
);
4844 AddMockTransaction(&kRangeGET_TransactionOK
);
4846 // This transaction will report a resource size of 80 bytes, and we think it's
4847 // 160 so we should ignore the response.
4848 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4851 Verify206Response(headers
, 40, 49);
4852 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4853 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4854 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4856 // Verify that we cached the first response but not the second one.
4857 disk_cache::Entry
* en
;
4858 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
4860 int64 cached_start
= 0;
4861 net::TestCompletionCallback cb
;
4862 int rv
= en
->GetAvailableRange(40, 20, &cached_start
, cb
.callback());
4863 EXPECT_EQ(10, cb
.GetResult(rv
));
4864 EXPECT_EQ(50, cached_start
);
4867 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4870 // Tests that we handle large range values properly.
4871 TEST(HttpCache
, RangeGET_LargeValues
) {
4872 // We need a real sparse cache for this test.
4873 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4874 std::string headers
;
4876 MockTransaction
transaction(kRangeGET_TransactionOK
);
4877 transaction
.handler
= NULL
;
4878 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
4880 transaction
.response_headers
=
4882 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4883 "Content-Length: 10\n";
4884 AddMockTransaction(&transaction
);
4885 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4887 std::string
expected(transaction
.status
);
4888 expected
.append("\n");
4889 expected
.append(transaction
.response_headers
);
4890 EXPECT_EQ(expected
, headers
);
4892 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4894 // Verify that we have a cached entry.
4895 disk_cache::Entry
* en
;
4896 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
4899 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4902 // Tests that we don't crash with a range request if the disk cache was not
4903 // initialized properly.
4904 TEST(HttpCache
, RangeGET_NoDiskCache
) {
4905 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
4906 factory
->set_fail(true);
4907 factory
->FinishCreation(); // We'll complete synchronously.
4908 MockHttpCache
cache(factory
);
4910 AddMockTransaction(&kRangeGET_TransactionOK
);
4912 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4913 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4915 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4918 // Tests that we handle byte range requests that skip the cache.
4919 TEST(HttpCache
, RangeHEAD
) {
4920 MockHttpCache cache
;
4921 AddMockTransaction(&kRangeGET_TransactionOK
);
4923 MockTransaction
transaction(kRangeGET_TransactionOK
);
4924 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4925 transaction
.method
= "HEAD";
4926 transaction
.data
= "rg: 70-79 ";
4928 std::string headers
;
4929 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4931 Verify206Response(headers
, 70, 79);
4932 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4933 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4934 EXPECT_EQ(0, cache
.disk_cache()->create_count());
4936 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4939 // Tests that we don't crash when after reading from the cache we issue a
4940 // request for the next range and the server gives us a 200 synchronously.
4941 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
4942 MockHttpCache cache
;
4944 MockTransaction
transaction(kRangeGET_TransactionOK
);
4945 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
4946 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
4947 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4948 AddMockTransaction(&transaction
);
4950 // Write to the cache.
4951 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4953 // And now read from the cache and the network.
4954 RangeTransactionServer handler
;
4955 handler
.set_bad_200(true);
4956 transaction
.data
= "Not a range";
4957 RunTransactionTest(cache
.http_cache(), transaction
);
4959 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4960 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4961 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4963 RemoveMockTransaction(&transaction
);
4966 // Tests that when the server gives us less data than expected, we don't keep
4967 // asking for more data.
4968 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
4969 MockHttpCache cache
;
4971 // First, check with an empty cache (WRITE mode).
4972 MockTransaction
transaction(kRangeGET_TransactionOK
);
4973 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
4974 transaction
.data
= "rg: 40-"; // Less than expected.
4975 transaction
.handler
= NULL
;
4976 std::string
headers(transaction
.response_headers
);
4977 headers
.append("Content-Range: bytes 40-49/80\n");
4978 transaction
.response_headers
= headers
.c_str();
4980 AddMockTransaction(&transaction
);
4982 // Write to the cache.
4983 RunTransactionTest(cache
.http_cache(), transaction
);
4985 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4986 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4987 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4989 // Now verify that even in READ_WRITE mode, we forward the bad response to
4991 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
4992 transaction
.data
= "rg: 60-"; // Less than expected.
4993 headers
= kRangeGET_TransactionOK
.response_headers
;
4994 headers
.append("Content-Range: bytes 60-69/80\n");
4995 transaction
.response_headers
= headers
.c_str();
4997 RunTransactionTest(cache
.http_cache(), transaction
);
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 RemoveMockTransaction(&transaction
);
5006 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5007 // This test hits a NOTREACHED so it is a release mode only test.
5008 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5009 MockHttpCache cache
;
5010 AddMockTransaction(&kRangeGET_TransactionOK
);
5012 // Write to the cache (40-49).
5013 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5014 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5015 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5016 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5018 // Force this transaction to read from the cache.
5019 MockTransaction
transaction(kRangeGET_TransactionOK
);
5020 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5022 MockHttpRequest
request(transaction
);
5023 net::TestCompletionCallback callback
;
5025 scoped_ptr
<net::HttpTransaction
> trans
;
5026 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
5027 EXPECT_EQ(net::OK
, rv
);
5028 ASSERT_TRUE(trans
.get());
5030 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5031 if (rv
== net::ERR_IO_PENDING
)
5032 rv
= callback
.WaitForResult();
5033 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5037 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5038 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5039 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5041 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5045 // Tests the handling of the "truncation" flag.
5046 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5047 MockHttpCache cache
;
5048 disk_cache::Entry
* entry
;
5049 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5052 std::string
headers("HTTP/1.1 200 OK");
5053 headers
= net::HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5054 net::HttpResponseInfo response
;
5055 response
.headers
= new net::HttpResponseHeaders(headers
);
5057 // Set the last argument for this to be an incomplete request.
5058 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5059 bool truncated
= false;
5060 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5061 EXPECT_TRUE(truncated
);
5063 // And now test the opposite case.
5064 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5066 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5067 EXPECT_FALSE(truncated
);
5071 // Tests basic pickling/unpickling of HttpResponseInfo.
5072 TEST(HttpCache
, PersistHttpResponseInfo
) {
5073 // Set some fields (add more if needed.)
5074 net::HttpResponseInfo response1
;
5075 response1
.was_cached
= false;
5076 response1
.socket_address
= net::HostPortPair("1.2.3.4", 80);
5077 response1
.headers
= new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5081 response1
.Persist(&pickle
, false, false);
5084 net::HttpResponseInfo response2
;
5085 bool response_truncated
;
5086 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5087 EXPECT_FALSE(response_truncated
);
5090 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5091 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5092 EXPECT_EQ(80, response2
.socket_address
.port());
5093 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5096 // Tests that we delete an entry when the request is cancelled before starting
5097 // to read from the network.
5098 TEST(HttpCache
, DoomOnDestruction
) {
5099 MockHttpCache cache
;
5101 MockHttpRequest
request(kSimpleGET_Transaction
);
5103 Context
* c
= new Context();
5104 int rv
= cache
.CreateTransaction(&c
->trans
);
5105 ASSERT_EQ(net::OK
, rv
);
5107 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5108 if (rv
== net::ERR_IO_PENDING
)
5109 c
->result
= c
->callback
.WaitForResult();
5111 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5112 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5113 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5115 // Destroy the transaction. We only have the headers so we should delete this
5119 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5121 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5122 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5123 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5126 // Tests that we delete an entry when the request is cancelled if the response
5127 // does not have content-length and strong validators.
5128 TEST(HttpCache
, DoomOnDestruction2
) {
5129 MockHttpCache cache
;
5131 MockHttpRequest
request(kSimpleGET_Transaction
);
5133 Context
* c
= new Context();
5134 int rv
= cache
.CreateTransaction(&c
->trans
);
5135 ASSERT_EQ(net::OK
, rv
);
5137 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5138 if (rv
== net::ERR_IO_PENDING
)
5139 rv
= c
->callback
.WaitForResult();
5141 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5142 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5143 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5145 // Make sure that the entry has some data stored.
5146 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5147 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5148 if (rv
== net::ERR_IO_PENDING
)
5149 rv
= c
->callback
.WaitForResult();
5150 EXPECT_EQ(buf
->size(), rv
);
5152 // Destroy the transaction.
5155 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5157 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5158 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5159 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5162 // Tests that we delete an entry when the request is cancelled if the response
5163 // has an "Accept-Ranges: none" header.
5164 TEST(HttpCache
, DoomOnDestruction3
) {
5165 MockHttpCache cache
;
5167 MockTransaction
transaction(kSimpleGET_Transaction
);
5168 transaction
.response_headers
=
5169 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5170 "Content-Length: 22\n"
5171 "Accept-Ranges: none\n"
5172 "Etag: \"foopy\"\n";
5173 AddMockTransaction(&transaction
);
5174 MockHttpRequest
request(transaction
);
5176 Context
* c
= new Context();
5177 int rv
= cache
.CreateTransaction(&c
->trans
);
5178 ASSERT_EQ(net::OK
, rv
);
5180 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5181 if (rv
== net::ERR_IO_PENDING
)
5182 rv
= c
->callback
.WaitForResult();
5184 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5185 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5186 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5188 // Make sure that the entry has some data stored.
5189 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5190 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5191 if (rv
== net::ERR_IO_PENDING
)
5192 rv
= c
->callback
.WaitForResult();
5193 EXPECT_EQ(buf
->size(), rv
);
5195 // Destroy the transaction.
5198 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5200 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5201 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5202 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5204 RemoveMockTransaction(&transaction
);
5207 // Tests that we mark an entry as incomplete when the request is cancelled.
5208 TEST(HttpCache
, SetTruncatedFlag
) {
5209 MockHttpCache cache
;
5211 MockTransaction
transaction(kSimpleGET_Transaction
);
5212 transaction
.response_headers
=
5213 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5214 "Content-Length: 22\n"
5215 "Etag: \"foopy\"\n";
5216 AddMockTransaction(&transaction
);
5217 MockHttpRequest
request(transaction
);
5219 scoped_ptr
<Context
> c(new Context());
5221 int rv
= cache
.CreateTransaction(&c
->trans
);
5222 ASSERT_EQ(net::OK
, rv
);
5224 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5225 if (rv
== net::ERR_IO_PENDING
)
5226 rv
= c
->callback
.WaitForResult();
5228 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5229 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5230 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5232 // Make sure that the entry has some data stored.
5233 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5234 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5235 if (rv
== net::ERR_IO_PENDING
)
5236 rv
= c
->callback
.WaitForResult();
5237 EXPECT_EQ(buf
->size(), rv
);
5239 // We want to cancel the request when the transaction is busy.
5240 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5241 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5242 EXPECT_FALSE(c
->callback
.have_result());
5244 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5246 // Destroy the transaction.
5248 MockHttpCache::SetTestMode(0);
5251 // Make sure that we don't invoke the callback. We may have an issue if the
5252 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5253 // could end up with the transaction being deleted twice if we send any
5254 // notification from the transaction destructor (see http://crbug.com/31723).
5255 EXPECT_FALSE(c
->callback
.have_result());
5257 // Verify that the entry is marked as incomplete.
5258 disk_cache::Entry
* entry
;
5259 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5260 net::HttpResponseInfo response
;
5261 bool truncated
= false;
5262 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5263 EXPECT_TRUE(truncated
);
5266 RemoveMockTransaction(&transaction
);
5269 // Tests that we don't mark an entry as truncated when we read everything.
5270 TEST(HttpCache
, DontSetTruncatedFlag
) {
5271 MockHttpCache cache
;
5273 MockTransaction
transaction(kSimpleGET_Transaction
);
5274 transaction
.response_headers
=
5275 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5276 "Content-Length: 22\n"
5277 "Etag: \"foopy\"\n";
5278 AddMockTransaction(&transaction
);
5279 MockHttpRequest
request(transaction
);
5281 scoped_ptr
<Context
> c(new Context());
5282 int rv
= cache
.CreateTransaction(&c
->trans
);
5283 ASSERT_EQ(net::OK
, rv
);
5285 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5286 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5289 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(22));
5290 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5291 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5293 // Destroy the transaction.
5296 // Verify that the entry is not marked as truncated.
5297 disk_cache::Entry
* entry
;
5298 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5299 net::HttpResponseInfo response
;
5300 bool truncated
= true;
5301 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5302 EXPECT_FALSE(truncated
);
5305 RemoveMockTransaction(&transaction
);
5308 // Tests that we can continue with a request that was interrupted.
5309 TEST(HttpCache
, GET_IncompleteResource
) {
5310 MockHttpCache cache
;
5311 AddMockTransaction(&kRangeGET_TransactionOK
);
5313 std::string
raw_headers("HTTP/1.1 200 OK\n"
5314 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5316 "Accept-Ranges: bytes\n"
5317 "Content-Length: 80\n");
5318 CreateTruncatedEntry(raw_headers
, &cache
);
5320 // Now make a regular request.
5321 std::string headers
;
5322 MockTransaction
transaction(kRangeGET_TransactionOK
);
5323 transaction
.request_headers
= EXTRA_HEADER
;
5324 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5325 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5326 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5328 // We update the headers with the ones received while revalidating.
5329 std::string
expected_headers(
5331 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5332 "Accept-Ranges: bytes\n"
5334 "Content-Length: 80\n");
5336 EXPECT_EQ(expected_headers
, headers
);
5337 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5338 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5339 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5341 // Verify that the disk entry was updated.
5342 disk_cache::Entry
* entry
;
5343 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5344 EXPECT_EQ(80, entry
->GetDataSize(1));
5345 bool truncated
= true;
5346 net::HttpResponseInfo response
;
5347 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5348 EXPECT_FALSE(truncated
);
5351 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5354 // Tests the handling of no-store when revalidating a truncated entry.
5355 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5356 MockHttpCache cache
;
5357 AddMockTransaction(&kRangeGET_TransactionOK
);
5359 std::string
raw_headers("HTTP/1.1 200 OK\n"
5360 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5362 "Accept-Ranges: bytes\n"
5363 "Content-Length: 80\n");
5364 CreateTruncatedEntry(raw_headers
, &cache
);
5365 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5367 // Now make a regular request.
5368 MockTransaction
transaction(kRangeGET_TransactionOK
);
5369 transaction
.request_headers
= EXTRA_HEADER
;
5370 std::string
response_headers(transaction
.response_headers
);
5371 response_headers
+= ("Cache-Control: no-store\n");
5372 transaction
.response_headers
= response_headers
.c_str();
5373 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5374 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5375 AddMockTransaction(&transaction
);
5377 std::string headers
;
5378 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5380 // We update the headers with the ones received while revalidating.
5381 std::string
expected_headers(
5383 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5384 "Accept-Ranges: bytes\n"
5385 "Cache-Control: no-store\n"
5387 "Content-Length: 80\n");
5389 EXPECT_EQ(expected_headers
, headers
);
5390 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5391 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5392 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5394 // Verify that the disk entry was deleted.
5395 disk_cache::Entry
* entry
;
5396 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5397 RemoveMockTransaction(&transaction
);
5400 // Tests cancelling a request after the server sent no-store.
5401 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5402 MockHttpCache cache
;
5403 AddMockTransaction(&kRangeGET_TransactionOK
);
5405 std::string
raw_headers("HTTP/1.1 200 OK\n"
5406 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5408 "Accept-Ranges: bytes\n"
5409 "Content-Length: 80\n");
5410 CreateTruncatedEntry(raw_headers
, &cache
);
5411 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5413 // Now make a regular request.
5414 MockTransaction
transaction(kRangeGET_TransactionOK
);
5415 transaction
.request_headers
= EXTRA_HEADER
;
5416 std::string
response_headers(transaction
.response_headers
);
5417 response_headers
+= ("Cache-Control: no-store\n");
5418 transaction
.response_headers
= response_headers
.c_str();
5419 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5420 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5421 AddMockTransaction(&transaction
);
5423 MockHttpRequest
request(transaction
);
5424 Context
* c
= new Context();
5426 int rv
= cache
.CreateTransaction(&c
->trans
);
5427 ASSERT_EQ(net::OK
, rv
);
5429 // Queue another request to this transaction. We have to start this request
5430 // before the first one gets the response from the server and dooms the entry,
5431 // otherwise it will just create a new entry without being queued to the first
5433 Context
* pending
= new Context();
5434 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&pending
->trans
));
5436 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5437 EXPECT_EQ(net::ERR_IO_PENDING
,
5438 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5439 net::BoundNetLog()));
5440 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5442 // Make sure that the entry has some data stored.
5443 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5444 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5445 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5447 // Cancel the requests.
5451 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5453 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5455 base::MessageLoop::current()->RunUntilIdle();
5456 RemoveMockTransaction(&transaction
);
5459 // Tests that we delete truncated entries if the server changes its mind midway.
5460 TEST(HttpCache
, GET_IncompleteResource2
) {
5461 MockHttpCache cache
;
5462 AddMockTransaction(&kRangeGET_TransactionOK
);
5464 // Content-length will be intentionally bad.
5465 std::string
raw_headers("HTTP/1.1 200 OK\n"
5466 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5468 "Accept-Ranges: bytes\n"
5469 "Content-Length: 50\n");
5470 CreateTruncatedEntry(raw_headers
, &cache
);
5472 // Now make a regular request. We expect the code to fail the validation and
5473 // retry the request without using byte ranges.
5474 std::string headers
;
5475 MockTransaction
transaction(kRangeGET_TransactionOK
);
5476 transaction
.request_headers
= EXTRA_HEADER
;
5477 transaction
.data
= "Not a range";
5478 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5480 // The server will return 200 instead of a byte range.
5481 std::string
expected_headers(
5483 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5485 EXPECT_EQ(expected_headers
, headers
);
5486 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5487 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5488 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5490 // Verify that the disk entry was deleted.
5491 disk_cache::Entry
* entry
;
5492 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5493 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5496 // Tests that we always validate a truncated request.
5497 TEST(HttpCache
, GET_IncompleteResource3
) {
5498 MockHttpCache cache
;
5499 AddMockTransaction(&kRangeGET_TransactionOK
);
5501 // This should not require validation for 10 hours.
5502 std::string
raw_headers("HTTP/1.1 200 OK\n"
5503 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5505 "Cache-Control: max-age= 36000\n"
5506 "Accept-Ranges: bytes\n"
5507 "Content-Length: 80\n");
5508 CreateTruncatedEntry(raw_headers
, &cache
);
5510 // Now make a regular request.
5511 std::string headers
;
5512 MockTransaction
transaction(kRangeGET_TransactionOK
);
5513 transaction
.request_headers
= EXTRA_HEADER
;
5514 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5515 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5517 scoped_ptr
<Context
> c(new Context
);
5518 int rv
= cache
.CreateTransaction(&c
->trans
);
5519 ASSERT_EQ(net::OK
, rv
);
5521 MockHttpRequest
request(transaction
);
5522 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5523 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5525 // We should have checked with the server before finishing Start().
5526 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5527 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5528 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5530 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5533 // Tests that we handle 401s for truncated resources.
5534 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
5535 MockHttpCache cache
;
5536 AddMockTransaction(&kRangeGET_TransactionOK
);
5538 std::string
raw_headers("HTTP/1.1 200 OK\n"
5539 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5541 "Accept-Ranges: bytes\n"
5542 "Content-Length: 80\n");
5543 CreateTruncatedEntry(raw_headers
, &cache
);
5545 // Now make a regular request.
5546 MockTransaction
transaction(kRangeGET_TransactionOK
);
5547 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
5549 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5550 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5551 RangeTransactionServer handler
;
5553 scoped_ptr
<Context
> c(new Context
);
5554 int rv
= cache
.CreateTransaction(&c
->trans
);
5555 ASSERT_EQ(net::OK
, rv
);
5557 MockHttpRequest
request(transaction
);
5558 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5559 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5561 const net::HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
5562 ASSERT_TRUE(response
);
5563 ASSERT_EQ(401, response
->headers
->response_code());
5564 rv
= c
->trans
->RestartWithAuth(net::AuthCredentials(),
5565 c
->callback
.callback());
5566 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5567 response
= c
->trans
->GetResponseInfo();
5568 ASSERT_TRUE(response
);
5569 ASSERT_EQ(200, response
->headers
->response_code());
5571 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
5572 c
.reset(); // The destructor could delete the entry.
5573 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5575 // Verify that the entry was not deleted.
5576 disk_cache::Entry
* entry
;
5577 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5580 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5583 // Tests that we cache a 200 response to the validation request.
5584 TEST(HttpCache
, GET_IncompleteResource4
) {
5585 MockHttpCache cache
;
5586 AddMockTransaction(&kRangeGET_TransactionOK
);
5588 std::string
raw_headers("HTTP/1.1 200 OK\n"
5589 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5591 "Accept-Ranges: bytes\n"
5592 "Content-Length: 80\n");
5593 CreateTruncatedEntry(raw_headers
, &cache
);
5595 // Now make a regular request.
5596 std::string headers
;
5597 MockTransaction
transaction(kRangeGET_TransactionOK
);
5598 transaction
.request_headers
= EXTRA_HEADER
;
5599 transaction
.data
= "Not a range";
5600 RangeTransactionServer handler
;
5601 handler
.set_bad_200(true);
5602 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5604 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5605 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5606 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5608 // Verify that the disk entry was updated.
5609 disk_cache::Entry
* entry
;
5610 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5611 EXPECT_EQ(11, entry
->GetDataSize(1));
5612 bool truncated
= true;
5613 net::HttpResponseInfo response
;
5614 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5615 EXPECT_FALSE(truncated
);
5618 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5621 // Tests that when we cancel a request that was interrupted, we mark it again
5623 TEST(HttpCache
, GET_CancelIncompleteResource
) {
5624 MockHttpCache cache
;
5625 AddMockTransaction(&kRangeGET_TransactionOK
);
5627 std::string
raw_headers("HTTP/1.1 200 OK\n"
5628 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5630 "Accept-Ranges: bytes\n"
5631 "Content-Length: 80\n");
5632 CreateTruncatedEntry(raw_headers
, &cache
);
5634 // Now make a regular request.
5635 MockTransaction
transaction(kRangeGET_TransactionOK
);
5636 transaction
.request_headers
= EXTRA_HEADER
;
5638 MockHttpRequest
request(transaction
);
5639 Context
* c
= new Context();
5640 int rv
= cache
.CreateTransaction(&c
->trans
);
5641 ASSERT_EQ(net::OK
, rv
);
5643 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5644 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5646 // Read 20 bytes from the cache, and 10 from the net.
5647 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
5648 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
5649 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
5650 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
5651 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
5653 // At this point, we are already reading so canceling the request should leave
5657 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5658 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5659 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5661 // Verify that the disk entry was updated: now we have 30 bytes.
5662 disk_cache::Entry
* entry
;
5663 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5664 EXPECT_EQ(30, entry
->GetDataSize(1));
5665 bool truncated
= false;
5666 net::HttpResponseInfo response
;
5667 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5668 EXPECT_TRUE(truncated
);
5670 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5673 // Tests that we can handle range requests when we have a truncated entry.
5674 TEST(HttpCache
, RangeGET_IncompleteResource
) {
5675 MockHttpCache cache
;
5676 AddMockTransaction(&kRangeGET_TransactionOK
);
5678 // Content-length will be intentionally bogus.
5679 std::string
raw_headers("HTTP/1.1 200 OK\n"
5680 "Last-Modified: something\n"
5682 "Accept-Ranges: bytes\n"
5683 "Content-Length: 10\n");
5684 CreateTruncatedEntry(raw_headers
, &cache
);
5686 // Now make a range request.
5687 std::string headers
;
5688 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5691 Verify206Response(headers
, 40, 49);
5692 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5693 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5694 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5696 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5699 TEST(HttpCache
, SyncRead
) {
5700 MockHttpCache cache
;
5702 // This test ensures that a read that completes synchronously does not cause
5705 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5706 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
5707 TEST_MODE_SYNC_CACHE_READ
|
5708 TEST_MODE_SYNC_CACHE_WRITE
);
5710 MockHttpRequest
r1(transaction
),
5714 TestTransactionConsumer
c1(net::DEFAULT_PRIORITY
, cache
.http_cache()),
5715 c2(net::DEFAULT_PRIORITY
, cache
.http_cache()),
5716 c3(net::DEFAULT_PRIORITY
, cache
.http_cache());
5718 c1
.Start(&r1
, net::BoundNetLog());
5720 r2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5721 c2
.Start(&r2
, net::BoundNetLog());
5723 r3
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5724 c3
.Start(&r3
, net::BoundNetLog());
5726 base::MessageLoop::current()->Run();
5728 EXPECT_TRUE(c1
.is_done());
5729 EXPECT_TRUE(c2
.is_done());
5730 EXPECT_TRUE(c3
.is_done());
5732 EXPECT_EQ(net::OK
, c1
.error());
5733 EXPECT_EQ(net::OK
, c2
.error());
5734 EXPECT_EQ(net::OK
, c3
.error());
5737 TEST(HttpCache
, ValidationResultsIn200
) {
5738 MockHttpCache cache
;
5740 // This test ensures that a conditional request, which results in a 200
5741 // instead of a 304, properly truncates the existing response data.
5743 // write to the cache
5744 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
5746 // force this transaction to validate the cache
5747 MockTransaction
transaction(kETagGET_Transaction
);
5748 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5749 RunTransactionTest(cache
.http_cache(), transaction
);
5751 // read from the cache
5752 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
5755 TEST(HttpCache
, CachedRedirect
) {
5756 MockHttpCache cache
;
5758 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
5759 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
5760 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
5762 MockHttpRequest
request(kTestTransaction
);
5763 net::TestCompletionCallback callback
;
5765 // Write to the cache.
5767 scoped_ptr
<net::HttpTransaction
> trans
;
5768 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5770 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5771 if (rv
== net::ERR_IO_PENDING
)
5772 rv
= callback
.WaitForResult();
5773 ASSERT_EQ(net::OK
, rv
);
5775 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
5778 EXPECT_EQ(info
->headers
->response_code(), 301);
5780 std::string location
;
5781 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
5782 EXPECT_EQ(location
, "http://www.bar.com/");
5784 // Mark the transaction as completed so it is cached.
5785 trans
->DoneReading();
5787 // Destroy transaction when going out of scope. We have not actually
5788 // read the response body -- want to test that it is still getting cached.
5790 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5791 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5792 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5794 // Active entries in the cache are not retired synchronously. Make
5795 // sure the next run hits the MockHttpCache and open_count is
5797 base::MessageLoop::current()->RunUntilIdle();
5799 // Read from the cache.
5801 scoped_ptr
<net::HttpTransaction
> trans
;
5802 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5804 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5805 if (rv
== net::ERR_IO_PENDING
)
5806 rv
= callback
.WaitForResult();
5807 ASSERT_EQ(net::OK
, rv
);
5809 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
5812 EXPECT_EQ(info
->headers
->response_code(), 301);
5814 std::string location
;
5815 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
5816 EXPECT_EQ(location
, "http://www.bar.com/");
5818 // Mark the transaction as completed so it is cached.
5819 trans
->DoneReading();
5821 // Destroy transaction when going out of scope. We have not actually
5822 // read the response body -- want to test that it is still getting cached.
5824 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5825 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5826 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5829 // Verify that no-cache resources are stored in cache, but are not fetched from
5830 // cache during normal loads.
5831 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
5832 MockHttpCache cache
;
5834 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5835 transaction
.response_headers
= "cache-control: no-cache\n";
5838 RunTransactionTest(cache
.http_cache(), transaction
);
5840 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5841 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5842 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5844 // Try loading again; it should result in a network fetch.
5845 RunTransactionTest(cache
.http_cache(), transaction
);
5847 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5848 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5849 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5851 disk_cache::Entry
* entry
;
5852 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5856 // Verify that no-cache resources are stored in cache and fetched from cache
5857 // when the LOAD_PREFERRING_CACHE flag is set.
5858 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
5859 MockHttpCache cache
;
5861 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5862 transaction
.response_headers
= "cache-control: no-cache\n";
5865 RunTransactionTest(cache
.http_cache(), transaction
);
5867 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5868 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5869 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5871 // Try loading again with LOAD_PREFERRING_CACHE.
5872 transaction
.load_flags
= net::LOAD_PREFERRING_CACHE
;
5873 RunTransactionTest(cache
.http_cache(), transaction
);
5875 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5876 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5877 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5879 disk_cache::Entry
* entry
;
5880 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5884 TEST(HttpCache
, CacheControlNoStore
) {
5885 MockHttpCache cache
;
5887 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5888 transaction
.response_headers
= "cache-control: no-store\n";
5891 RunTransactionTest(cache
.http_cache(), transaction
);
5893 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5894 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5895 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5897 // try loading again; it should result in a network fetch
5898 RunTransactionTest(cache
.http_cache(), transaction
);
5900 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5901 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5902 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5904 disk_cache::Entry
* entry
;
5905 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5908 TEST(HttpCache
, CacheControlNoStore2
) {
5909 // this test is similar to the above test, except that the initial response
5910 // is cachable, but when it is validated, no-store is received causing the
5911 // cached document to be deleted.
5912 MockHttpCache cache
;
5914 ScopedMockTransaction
transaction(kETagGET_Transaction
);
5917 RunTransactionTest(cache
.http_cache(), transaction
);
5919 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5920 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5921 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5923 // try loading again; it should result in a network fetch
5924 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
5925 transaction
.response_headers
= "cache-control: no-store\n";
5926 RunTransactionTest(cache
.http_cache(), transaction
);
5928 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5929 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5930 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5932 disk_cache::Entry
* entry
;
5933 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5936 TEST(HttpCache
, CacheControlNoStore3
) {
5937 // this test is similar to the above test, except that the response is a 304
5938 // instead of a 200. this should never happen in practice, but it seems like
5939 // a good thing to verify that we still destroy the cache entry.
5940 MockHttpCache cache
;
5942 ScopedMockTransaction
transaction(kETagGET_Transaction
);
5945 RunTransactionTest(cache
.http_cache(), transaction
);
5947 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5948 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5949 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5951 // try loading again; it should result in a network fetch
5952 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
5953 transaction
.response_headers
= "cache-control: no-store\n";
5954 transaction
.status
= "HTTP/1.1 304 Not Modified";
5955 RunTransactionTest(cache
.http_cache(), transaction
);
5957 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5958 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5959 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5961 disk_cache::Entry
* entry
;
5962 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5965 // Ensure that we don't cache requests served over bad HTTPS.
5966 TEST(HttpCache
, SimpleGET_SSLError
) {
5967 MockHttpCache cache
;
5969 MockTransaction transaction
= kSimpleGET_Transaction
;
5970 transaction
.cert_status
= net::CERT_STATUS_REVOKED
;
5971 ScopedMockTransaction
scoped_transaction(transaction
);
5973 // write to the cache
5974 RunTransactionTest(cache
.http_cache(), transaction
);
5976 // Test that it was not cached.
5977 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5979 MockHttpRequest
request(transaction
);
5980 net::TestCompletionCallback callback
;
5982 scoped_ptr
<net::HttpTransaction
> trans
;
5983 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5985 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5986 if (rv
== net::ERR_IO_PENDING
)
5987 rv
= callback
.WaitForResult();
5988 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5991 // Ensure that we don't crash by if left-behind transactions.
5992 TEST(HttpCache
, OutlivedTransactions
) {
5993 MockHttpCache
* cache
= new MockHttpCache
;
5995 scoped_ptr
<net::HttpTransaction
> trans
;
5996 EXPECT_EQ(net::OK
, cache
->CreateTransaction(&trans
));
6002 // Test that the disabled mode works.
6003 TEST(HttpCache
, CacheDisabledMode
) {
6004 MockHttpCache cache
;
6006 // write to the cache
6007 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6009 // go into disabled mode
6010 cache
.http_cache()->set_mode(net::HttpCache::DISABLE
);
6012 // force this transaction to write to the cache again
6013 MockTransaction
transaction(kSimpleGET_Transaction
);
6015 RunTransactionTest(cache
.http_cache(), transaction
);
6017 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6018 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6019 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6022 // Other tests check that the response headers of the cached response
6023 // get updated on 304. Here we specifically check that the
6024 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6025 // fields also gets updated.
6026 // http://crbug.com/20594.
6027 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6028 MockHttpCache cache
;
6030 const char* kUrl
= "http://foobar";
6031 const char* kData
= "body";
6033 MockTransaction mock_network_response
= { 0 };
6034 mock_network_response
.url
= kUrl
;
6036 AddMockTransaction(&mock_network_response
);
6038 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6040 MockTransaction request
= { 0 };
6042 request
.method
= "GET";
6043 request
.request_headers
= "\r\n";
6044 request
.data
= kData
;
6046 static const Response kNetResponse1
= {
6048 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6049 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6053 kNetResponse1
.AssignTo(&mock_network_response
);
6055 RunTransactionTest(cache
.http_cache(), request
);
6057 // Request |kUrl| again, this time validating the cache and getting
6060 request
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6062 static const Response kNetResponse2
= {
6063 "HTTP/1.1 304 Not Modified",
6064 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6068 kNetResponse2
.AssignTo(&mock_network_response
);
6070 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6071 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6073 mock_network_response
.request_time
= request_time
;
6074 mock_network_response
.response_time
= response_time
;
6076 net::HttpResponseInfo response
;
6077 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6079 // The request and response times should have been updated.
6080 EXPECT_EQ(request_time
.ToInternalValue(),
6081 response
.request_time
.ToInternalValue());
6082 EXPECT_EQ(response_time
.ToInternalValue(),
6083 response
.response_time
.ToInternalValue());
6085 std::string headers
;
6086 response
.headers
->GetNormalizedHeaders(&headers
);
6088 EXPECT_EQ("HTTP/1.1 200 OK\n"
6089 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6090 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6093 RemoveMockTransaction(&mock_network_response
);
6096 // Tests that we can write metadata to an entry.
6097 TEST(HttpCache
, WriteMetadata_OK
) {
6098 MockHttpCache cache
;
6100 // Write to the cache
6101 net::HttpResponseInfo response
;
6102 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6104 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6107 cache
.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY
,
6108 Time::Now(), NULL
, 0);
6110 // Write meta data to the same entry.
6111 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6112 memset(buf
->data(), 0, buf
->size());
6113 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6114 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6115 net::DEFAULT_PRIORITY
,
6116 response
.response_time
,
6120 // Release the buffer before the operation takes place.
6123 // Makes sure we finish pending operations.
6124 base::MessageLoop::current()->RunUntilIdle();
6126 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6128 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6129 EXPECT_EQ(50, response
.metadata
->size());
6130 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6132 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6133 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6134 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6137 // Tests that we only write metadata to an entry if the time stamp matches.
6138 TEST(HttpCache
, WriteMetadata_Fail
) {
6139 MockHttpCache cache
;
6141 // Write to the cache
6142 net::HttpResponseInfo response
;
6143 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6145 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6147 // Attempt to write meta data to the same entry.
6148 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6149 memset(buf
->data(), 0, buf
->size());
6150 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6151 base::Time expected_time
= response
.response_time
-
6152 base::TimeDelta::FromMilliseconds(20);
6153 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6154 net::DEFAULT_PRIORITY
,
6159 // Makes sure we finish pending operations.
6160 base::MessageLoop::current()->RunUntilIdle();
6162 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6164 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6166 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6167 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6168 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6171 // Tests that we can read metadata after validating the entry and with READ mode
6173 TEST(HttpCache
, ReadMetadata
) {
6174 MockHttpCache cache
;
6176 // Write to the cache
6177 net::HttpResponseInfo response
;
6178 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6179 kTypicalGET_Transaction
, &response
);
6180 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6182 // Write meta data to the same entry.
6183 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6184 memset(buf
->data(), 0, buf
->size());
6185 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6186 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6187 net::DEFAULT_PRIORITY
,
6188 response
.response_time
,
6192 // Makes sure we finish pending operations.
6193 base::MessageLoop::current()->RunUntilIdle();
6195 // Start with a READ mode transaction.
6196 MockTransaction
trans1(kTypicalGET_Transaction
);
6197 trans1
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
6199 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6200 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6201 EXPECT_EQ(50, response
.metadata
->size());
6202 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6204 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6205 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6206 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6207 base::MessageLoop::current()->RunUntilIdle();
6209 // Now make sure that the entry is re-validated with the server.
6210 trans1
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6211 trans1
.status
= "HTTP/1.1 304 Not Modified";
6212 AddMockTransaction(&trans1
);
6214 response
.metadata
= NULL
;
6215 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6216 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6218 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6219 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6220 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6221 base::MessageLoop::current()->RunUntilIdle();
6222 RemoveMockTransaction(&trans1
);
6224 // Now return 200 when validating the entry so the metadata will be lost.
6225 MockTransaction
trans2(kTypicalGET_Transaction
);
6226 trans2
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6227 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6228 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6230 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6231 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6232 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6235 // Tests that we don't mark entries as truncated when a filter detects the end
6237 TEST(HttpCache
, FilterCompletion
) {
6238 MockHttpCache cache
;
6239 net::TestCompletionCallback callback
;
6242 scoped_ptr
<net::HttpTransaction
> trans
;
6243 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6245 MockHttpRequest
request(kSimpleGET_Transaction
);
6246 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6247 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6249 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6250 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6251 EXPECT_GT(callback
.GetResult(rv
), 0);
6253 // Now make sure that the entry is preserved.
6254 trans
->DoneReading();
6257 // Make sure that the ActiveEntry is gone.
6258 base::MessageLoop::current()->RunUntilIdle();
6260 // Read from the cache.
6261 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6263 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6264 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6265 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6268 // Tests that we don't mark entries as truncated and release the cache
6269 // entry when DoneReading() is called before any Read() calls, such as
6271 TEST(HttpCache
, DoneReading
) {
6272 MockHttpCache cache
;
6273 net::TestCompletionCallback callback
;
6275 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6276 transaction
.data
= "";
6278 scoped_ptr
<net::HttpTransaction
> trans
;
6279 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6281 MockHttpRequest
request(transaction
);
6282 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6283 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6285 trans
->DoneReading();
6286 // Leave the transaction around.
6288 // Make sure that the ActiveEntry is gone.
6289 base::MessageLoop::current()->RunUntilIdle();
6291 // Read from the cache. This should not deadlock.
6292 RunTransactionTest(cache
.http_cache(), transaction
);
6294 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6295 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6296 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6299 // Tests that we stop caching when told.
6300 TEST(HttpCache
, StopCachingDeletesEntry
) {
6301 MockHttpCache cache
;
6302 net::TestCompletionCallback callback
;
6303 MockHttpRequest
request(kSimpleGET_Transaction
);
6306 scoped_ptr
<net::HttpTransaction
> trans
;
6307 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6309 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6310 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6312 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6313 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6314 EXPECT_EQ(10, callback
.GetResult(rv
));
6316 trans
->StopCaching();
6318 // We should be able to keep reading.
6319 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6320 EXPECT_GT(callback
.GetResult(rv
), 0);
6321 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6322 EXPECT_EQ(0, callback
.GetResult(rv
));
6325 // Make sure that the ActiveEntry is gone.
6326 base::MessageLoop::current()->RunUntilIdle();
6328 // Verify that the entry is gone.
6329 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6331 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6332 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6333 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6336 // Tests that we stop caching when told, even if DoneReading is called
6337 // after StopCaching.
6338 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6339 MockHttpCache cache
;
6340 net::TestCompletionCallback callback
;
6341 MockHttpRequest
request(kSimpleGET_Transaction
);
6344 scoped_ptr
<net::HttpTransaction
> trans
;
6345 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6347 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6348 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6350 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6351 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6352 EXPECT_EQ(10, callback
.GetResult(rv
));
6354 trans
->StopCaching();
6356 // We should be able to keep reading.
6357 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6358 EXPECT_GT(callback
.GetResult(rv
), 0);
6359 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6360 EXPECT_EQ(0, callback
.GetResult(rv
));
6362 // We should be able to call DoneReading.
6363 trans
->DoneReading();
6366 // Make sure that the ActiveEntry is gone.
6367 base::MessageLoop::current()->RunUntilIdle();
6369 // Verify that the entry is gone.
6370 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6372 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6373 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6374 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6377 // Tests that we stop caching when told, when using auth.
6378 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6379 MockHttpCache cache
;
6380 net::TestCompletionCallback callback
;
6381 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6382 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6383 AddMockTransaction(&mock_transaction
);
6384 MockHttpRequest
request(mock_transaction
);
6387 scoped_ptr
<net::HttpTransaction
> trans
;
6388 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6390 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6391 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6393 trans
->StopCaching();
6395 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6396 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6397 EXPECT_EQ(callback
.GetResult(rv
), 10);
6399 RemoveMockTransaction(&mock_transaction
);
6401 // Make sure that the ActiveEntry is gone.
6402 base::MessageLoop::current()->RunUntilIdle();
6404 // Verify that the entry is gone.
6405 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6407 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6408 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6409 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6412 // Tests that when we are told to stop caching we don't throw away valid data.
6413 TEST(HttpCache
, StopCachingSavesEntry
) {
6414 MockHttpCache cache
;
6415 net::TestCompletionCallback callback
;
6416 MockHttpRequest
request(kSimpleGET_Transaction
);
6419 scoped_ptr
<net::HttpTransaction
> trans
;
6420 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6422 // Force a response that can be resumed.
6423 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6424 AddMockTransaction(&mock_transaction
);
6425 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6426 "Content-Length: 42\n"
6429 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6430 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6432 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6433 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6434 EXPECT_EQ(callback
.GetResult(rv
), 10);
6436 trans
->StopCaching();
6438 // We should be able to keep reading.
6439 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6440 EXPECT_GT(callback
.GetResult(rv
), 0);
6441 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6442 EXPECT_EQ(callback
.GetResult(rv
), 0);
6444 RemoveMockTransaction(&mock_transaction
);
6447 // Verify that the entry is marked as incomplete.
6448 disk_cache::Entry
* entry
;
6449 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6450 net::HttpResponseInfo response
;
6451 bool truncated
= false;
6452 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6453 EXPECT_TRUE(truncated
);
6457 // Tests that we handle truncated enries when StopCaching is called.
6458 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6459 MockHttpCache cache
;
6460 net::TestCompletionCallback callback
;
6461 MockHttpRequest
request(kRangeGET_TransactionOK
);
6462 request
.extra_headers
.Clear();
6463 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6464 AddMockTransaction(&kRangeGET_TransactionOK
);
6466 std::string
raw_headers("HTTP/1.1 200 OK\n"
6467 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6469 "Accept-Ranges: bytes\n"
6470 "Content-Length: 80\n");
6471 CreateTruncatedEntry(raw_headers
, &cache
);
6474 // Now make a regular request.
6475 scoped_ptr
<net::HttpTransaction
> trans
;
6476 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6478 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6479 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6481 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6482 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6483 EXPECT_EQ(callback
.GetResult(rv
), 10);
6485 // This is actually going to do nothing.
6486 trans
->StopCaching();
6488 // We should be able to keep reading.
6489 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6490 EXPECT_GT(callback
.GetResult(rv
), 0);
6491 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6492 EXPECT_GT(callback
.GetResult(rv
), 0);
6493 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6494 EXPECT_EQ(callback
.GetResult(rv
), 0);
6497 // Verify that the disk entry was updated.
6498 disk_cache::Entry
* entry
;
6499 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6500 EXPECT_EQ(80, entry
->GetDataSize(1));
6501 bool truncated
= true;
6502 net::HttpResponseInfo response
;
6503 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6504 EXPECT_FALSE(truncated
);
6507 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6510 // Tests that we detect truncated resources from the net when there is
6511 // a Content-Length header.
6512 TEST(HttpCache
, TruncatedByContentLength
) {
6513 MockHttpCache cache
;
6514 net::TestCompletionCallback callback
;
6516 MockTransaction
transaction(kSimpleGET_Transaction
);
6517 AddMockTransaction(&transaction
);
6518 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6519 "Content-Length: 100\n";
6520 RunTransactionTest(cache
.http_cache(), transaction
);
6521 RemoveMockTransaction(&transaction
);
6523 // Read from the cache.
6524 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6526 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6527 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6528 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6531 // Tests that we actually flag entries as truncated when we detect an error
6533 TEST(HttpCache
, TruncatedByContentLength2
) {
6534 MockHttpCache cache
;
6535 net::TestCompletionCallback callback
;
6537 MockTransaction
transaction(kSimpleGET_Transaction
);
6538 AddMockTransaction(&transaction
);
6539 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6540 "Content-Length: 100\n"
6542 RunTransactionTest(cache
.http_cache(), transaction
);
6543 RemoveMockTransaction(&transaction
);
6545 // Verify that the entry is marked as incomplete.
6546 disk_cache::Entry
* entry
;
6547 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6548 net::HttpResponseInfo response
;
6549 bool truncated
= false;
6550 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6551 EXPECT_TRUE(truncated
);
6555 // Make sure that calling SetPriority on a cache transaction passes on
6556 // its priority updates to its underlying network transaction.
6557 TEST(HttpCache
, SetPriority
) {
6558 MockHttpCache cache
;
6560 scoped_ptr
<net::HttpTransaction
> trans
;
6561 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6563 // Shouldn't crash, but doesn't do anything either.
6564 trans
->SetPriority(net::LOW
);
6566 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6567 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6568 cache
.network_layer()->last_create_transaction_priority());
6570 net::HttpRequestInfo info
;
6571 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6572 net::TestCompletionCallback callback
;
6573 EXPECT_EQ(net::ERR_IO_PENDING
,
6574 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6576 EXPECT_TRUE(cache
.network_layer()->last_transaction());
6577 if (cache
.network_layer()->last_transaction()) {
6579 cache
.network_layer()->last_create_transaction_priority());
6581 cache
.network_layer()->last_transaction()->priority());
6584 trans
->SetPriority(net::HIGHEST
);
6586 if (cache
.network_layer()->last_transaction()) {
6588 cache
.network_layer()->last_create_transaction_priority());
6589 EXPECT_EQ(net::HIGHEST
,
6590 cache
.network_layer()->last_transaction()->priority());
6593 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6596 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6597 // transaction passes on its argument to the underlying network transaction.
6598 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
6599 MockHttpCache cache
;
6601 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
6602 scoped_ptr
<net::HttpTransaction
> trans
;
6603 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6605 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6607 net::HttpRequestInfo info
;
6608 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6609 net::TestCompletionCallback callback
;
6610 EXPECT_EQ(net::ERR_IO_PENDING
,
6611 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6613 ASSERT_TRUE(cache
.network_layer()->last_transaction());
6614 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
6615 websocket_handshake_stream_create_helper());
6616 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
6617 EXPECT_EQ(&create_helper
,
6618 cache
.network_layer()->last_transaction()->
6619 websocket_handshake_stream_create_helper());
6620 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6623 // Make sure that a cache transaction passes on its priority to
6624 // newly-created network transactions.
6625 TEST(HttpCache
, SetPriorityNewTransaction
) {
6626 MockHttpCache cache
;
6627 AddMockTransaction(&kRangeGET_TransactionOK
);
6629 std::string
raw_headers("HTTP/1.1 200 OK\n"
6630 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6632 "Accept-Ranges: bytes\n"
6633 "Content-Length: 80\n");
6634 CreateTruncatedEntry(raw_headers
, &cache
);
6636 // Now make a regular request.
6637 std::string headers
;
6638 MockTransaction
transaction(kRangeGET_TransactionOK
);
6639 transaction
.request_headers
= EXTRA_HEADER
;
6640 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6641 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6643 scoped_ptr
<net::HttpTransaction
> trans
;
6645 cache
.http_cache()->CreateTransaction(net::MEDIUM
, &trans
));
6646 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6647 cache
.network_layer()->last_create_transaction_priority());
6649 MockHttpRequest
info(transaction
);
6650 net::TestCompletionCallback callback
;
6651 EXPECT_EQ(net::ERR_IO_PENDING
,
6652 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6653 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6655 EXPECT_EQ(net::MEDIUM
,
6656 cache
.network_layer()->last_create_transaction_priority());
6658 trans
->SetPriority(net::HIGHEST
);
6659 // Should trigger a new network transaction and pick up the new
6661 ReadAndVerifyTransaction(trans
.get(), transaction
);
6663 EXPECT_EQ(net::HIGHEST
,
6664 cache
.network_layer()->last_create_transaction_priority());
6666 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6669 int64
RunTransactionAndGetReceivedBytes(
6670 MockHttpCache
& cache
,
6671 const MockTransaction
& trans_info
) {
6672 int64 received_bytes
= -1;
6673 RunTransactionTestBase(cache
.http_cache(), trans_info
,
6674 MockHttpRequest(trans_info
), NULL
, net::BoundNetLog(),
6675 NULL
, &received_bytes
);
6676 return received_bytes
;
6679 int64
TransactionSize(const MockTransaction
& transaction
) {
6680 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
6681 strlen(transaction
.data
);
6684 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
6685 MockHttpCache cache
;
6687 MockTransaction
transaction(kSimpleGET_Transaction
);
6688 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6689 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6691 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6692 EXPECT_EQ(0, received_bytes
);
6695 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
6696 MockHttpCache cache
;
6698 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6699 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6700 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6702 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6703 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
6704 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6705 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6708 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
6709 MockHttpCache cache
;
6711 MockTransaction
transaction(kTypicalGET_Transaction
);
6712 transaction
.request_headers
= "Foo: bar\r\n";
6713 transaction
.response_headers
=
6714 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6715 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6717 "Cache-Control: max-age=0\n"
6719 AddMockTransaction(&transaction
);
6720 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6721 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6723 RevalidationServer server
;
6724 transaction
.handler
= server
.Handler
;
6725 transaction
.request_headers
= "Foo: none\r\n";
6726 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6727 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6729 RemoveMockTransaction(&transaction
);
6732 TEST(HttpCache
, ReceivedBytesRange
) {
6733 MockHttpCache cache
;
6734 AddMockTransaction(&kRangeGET_TransactionOK
);
6735 MockTransaction
transaction(kRangeGET_TransactionOK
);
6737 // Read bytes 40-49 from the network.
6738 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6739 int64 range_response_size
= TransactionSize(transaction
);
6740 EXPECT_EQ(range_response_size
, received_bytes
);
6742 // Read bytes 40-49 from the cache.
6743 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6744 EXPECT_EQ(0, received_bytes
);
6745 base::MessageLoop::current()->RunUntilIdle();
6747 // Read bytes 30-39 from the network.
6748 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
6749 transaction
.data
= "rg: 30-39 ";
6750 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6751 EXPECT_EQ(range_response_size
, received_bytes
);
6752 base::MessageLoop::current()->RunUntilIdle();
6754 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6755 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
6756 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6757 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6758 EXPECT_EQ(range_response_size
* 2, received_bytes
);
6760 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6763 // Framework for tests of stale-while-revalidate related functionality. With
6764 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
6765 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
6766 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
6767 // synchronous revalidation.
6768 class HttpCacheStaleWhileRevalidateTest
: public ::testing::Test
{
6770 HttpCacheStaleWhileRevalidateTest()
6771 : transaction_(kSimpleGET_Transaction
),
6773 stale_while_revalidate_(7200),
6774 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
6775 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(true);
6778 // RunTransactionTest() with the arguments from this fixture.
6779 void RunFixtureTransactionTest() {
6780 std::string response_headers
= base::StringPrintf(
6783 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
6786 stale_while_revalidate_
);
6787 transaction_
.response_headers
= response_headers
.c_str();
6788 RunTransactionTest(cache_
.http_cache(), transaction_
);
6789 transaction_
.response_headers
= "";
6792 // How many times this test has sent requests to the (fake) origin
6793 // server. Every test case needs to make at least one request to initialise
6795 int transaction_count() {
6796 return cache_
.network_layer()->transaction_count();
6799 // How many times an existing cache entry was opened during the test case.
6800 int open_count() { return cache_
.disk_cache()->open_count(); }
6802 MockHttpCache cache_
;
6803 ScopedMockTransaction transaction_
;
6805 int stale_while_revalidate_
;
6806 std::string validator_
;
6809 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo
* request
,
6810 std::string
* response_status
,
6811 std::string
* response_headers
,
6812 std::string
* response_data
) {
6814 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
6815 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
6818 // Verify that the Resource-Freshness header is sent on a revalidation if the
6819 // stale-while-revalidate directive was on the response.
6820 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderSent
) {
6821 age_
= 10801; // Outside the stale-while-revalidate window.
6823 // Write to the cache.
6824 RunFixtureTransactionTest();
6826 EXPECT_EQ(1, transaction_count());
6828 // Send the request again and check that Resource-Freshness header is added.
6829 transaction_
.handler
= CheckResourceFreshnessHeader
;
6831 RunFixtureTransactionTest();
6833 EXPECT_EQ(2, transaction_count());
6836 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo
* request
,
6837 std::string
* response_status
,
6838 std::string
* response_headers
,
6839 std::string
* response_data
) {
6840 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
6843 // Verify that the Resource-Freshness header is not sent when
6844 // stale-while-revalidate is 0.
6845 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderNotSent
) {
6847 stale_while_revalidate_
= 0;
6849 // Write to the cache.
6850 RunFixtureTransactionTest();
6852 EXPECT_EQ(1, transaction_count());
6854 // Send the request again and check that Resource-Freshness header is absent.
6855 transaction_
.handler
= CheckResourceFreshnessAbsent
;
6857 RunFixtureTransactionTest();
6859 EXPECT_EQ(2, transaction_count());
6862 // Verify that when stale-while-revalidate applies the response is read from
6864 TEST_F(HttpCacheStaleWhileRevalidateTest
, ReadFromCache
) {
6865 // Write to the cache.
6866 RunFixtureTransactionTest();
6868 EXPECT_EQ(0, open_count());
6869 EXPECT_EQ(1, transaction_count());
6871 // Read back from the cache.
6872 RunFixtureTransactionTest();
6874 EXPECT_EQ(1, open_count());
6875 EXPECT_EQ(1, transaction_count());
6878 // Verify that when stale-while-revalidate applies an asynchronous request is
6880 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestSent
) {
6881 // Write to the cache.
6882 RunFixtureTransactionTest();
6884 EXPECT_EQ(1, transaction_count());
6886 // Read back from the cache.
6887 RunFixtureTransactionTest();
6889 EXPECT_EQ(1, transaction_count());
6891 // Let the async request execute.
6892 base::RunLoop().RunUntilIdle();
6893 EXPECT_EQ(2, transaction_count());
6896 // Verify that tearing down the HttpCache with an async revalidation in progress
6897 // does not break anything (this test is most likely to find problems when run
6898 // with a memory checker such as AddressSanitizer).
6899 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncTearDown
) {
6900 // Write to the cache.
6901 RunFixtureTransactionTest();
6903 // Read back from the cache.
6904 RunFixtureTransactionTest();
6907 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo
* request
,
6908 std::string
* response_status
,
6909 std::string
* response_headers
,
6910 std::string
* response_data
) {
6912 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-Modified-Since", &value
));
6913 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value
);
6916 // Verify that the async revalidation contains an If-Modified-Since header.
6917 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfModifiedSince
) {
6918 // Write to the cache.
6919 RunFixtureTransactionTest();
6921 transaction_
.handler
= CheckIfModifiedSinceHeader
;
6923 // Read back from the cache.
6924 RunFixtureTransactionTest();
6927 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo
* request
,
6928 std::string
* response_status
,
6929 std::string
* response_headers
,
6930 std::string
* response_data
) {
6932 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-None-Match", &value
));
6933 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value
);
6936 // If the response had ETag rather than Last-Modified, then that is used to
6937 // conditionalise the response.
6938 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfNoneMatch
) {
6939 validator_
= "Etag: \"40a1-1320-4f6adefa22a40\"";
6941 // Write to the cache.
6942 RunFixtureTransactionTest();
6944 transaction_
.handler
= CheckIfNoneMatchHeader
;
6946 // Read back from the cache.
6947 RunFixtureTransactionTest();
6950 static void CheckResourceFreshnessHeaderPresent(
6951 const net::HttpRequestInfo
* request
,
6952 std::string
* response_status
,
6953 std::string
* response_headers
,
6954 std::string
* response_data
) {
6955 EXPECT_TRUE(request
->extra_headers
.HasHeader("Resource-Freshness"));
6958 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestHasResourceFreshness
) {
6959 // Write to the cache.
6960 RunFixtureTransactionTest();
6962 transaction_
.handler
= CheckResourceFreshnessHeaderPresent
;
6964 // Read back from the cache.
6965 RunFixtureTransactionTest();
6968 // Verify that when age > max-age + stale-while-revalidate stale results are
6970 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedIfTooStale
) {
6973 // Write to the cache.
6974 RunFixtureTransactionTest();
6976 EXPECT_EQ(0, open_count());
6977 EXPECT_EQ(1, transaction_count());
6979 // Reading back reads from the network.
6980 RunFixtureTransactionTest();
6982 EXPECT_EQ(1, open_count());
6983 EXPECT_EQ(2, transaction_count());
6986 // HEAD requests should be able to take advantage of stale-while-revalidate.
6987 TEST_F(HttpCacheStaleWhileRevalidateTest
, WorksForHeadMethod
) {
6988 // Write to the cache. This has to be a GET request; HEAD requests don't
6989 // create new cache entries.
6990 RunFixtureTransactionTest();
6992 EXPECT_EQ(0, open_count());
6993 EXPECT_EQ(1, transaction_count());
6995 // Read back from the cache, and trigger an asynchronous HEAD request.
6996 transaction_
.method
= "HEAD";
6997 transaction_
.data
= "";
6999 RunFixtureTransactionTest();
7001 EXPECT_EQ(1, open_count());
7002 EXPECT_EQ(1, transaction_count());
7004 // Let the network request proceed.
7005 base::RunLoop().RunUntilIdle();
7007 EXPECT_EQ(2, transaction_count());
7010 // POST requests should not use stale-while-revalidate.
7011 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedToPost
) {
7012 transaction_
= ScopedMockTransaction(kSimplePOST_Transaction
);
7014 // Write to the cache.
7015 RunFixtureTransactionTest();
7017 EXPECT_EQ(0, open_count());
7018 EXPECT_EQ(1, transaction_count());
7020 // Reading back reads from the network.
7021 RunFixtureTransactionTest();
7023 EXPECT_EQ(0, open_count());
7024 EXPECT_EQ(2, transaction_count());
7027 static void CheckUrlMatches(const net::HttpRequestInfo
* request
,
7028 std::string
* response_status
,
7029 std::string
* response_headers
,
7030 std::string
* response_data
) {
7031 EXPECT_EQ("http://www.google.com/", request
->url
.spec());
7034 // Async revalidation is issued to the original URL.
7035 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestUrlMatches
) {
7036 transaction_
.url
= "http://www.google.com/";
7037 // Write to the cache.
7038 RunFixtureTransactionTest();
7040 // Read back from the cache.
7041 RunFixtureTransactionTest();
7043 EXPECT_EQ(1, transaction_count());
7045 transaction_
.handler
= CheckUrlMatches
;
7047 // Let the async request execute and perform the check.
7048 base::RunLoop().RunUntilIdle();
7049 EXPECT_EQ(2, transaction_count());
7052 class SyncLoadFlagTest
: public HttpCacheStaleWhileRevalidateTest
,
7053 public ::testing::WithParamInterface
<int> {};
7055 // Flags which should always cause the request to be synchronous.
7056 TEST_P(SyncLoadFlagTest
, MustBeSynchronous
) {
7057 transaction_
.load_flags
|= GetParam();
7058 // Write to the cache.
7059 RunFixtureTransactionTest();
7061 EXPECT_EQ(1, transaction_count());
7063 // Reading back reads from the network.
7064 RunFixtureTransactionTest();
7066 EXPECT_EQ(2, transaction_count());
7069 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate
,
7071 ::testing::Values(net::LOAD_VALIDATE_CACHE
,
7072 net::LOAD_BYPASS_CACHE
,
7073 net::LOAD_DISABLE_CACHE
));
7075 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7076 PreferringCacheDoesNotTriggerAsyncRequest
) {
7077 transaction_
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
7078 // Write to the cache.
7079 RunFixtureTransactionTest();
7081 EXPECT_EQ(1, transaction_count());
7083 // Reading back reads from the cache.
7084 RunFixtureTransactionTest();
7086 EXPECT_EQ(1, transaction_count());
7088 // If there was an async transaction created, it would run now.
7089 base::RunLoop().RunUntilIdle();
7091 // There was no async transaction.
7092 EXPECT_EQ(1, transaction_count());
7095 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotUsedWhenDisabled
) {
7096 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7097 // Write to the cache.
7098 RunFixtureTransactionTest();
7100 EXPECT_EQ(1, transaction_count());
7102 // A synchronous revalidation is performed.
7103 RunFixtureTransactionTest();
7105 EXPECT_EQ(2, transaction_count());
7108 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7109 OnlyFromCacheDoesNotTriggerAsyncRequest
) {
7110 transaction_
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
7111 transaction_
.return_code
= net::ERR_CACHE_MISS
;
7113 // Writing to the cache should fail, because we are avoiding the network.
7114 RunFixtureTransactionTest();
7116 EXPECT_EQ(0, transaction_count());
7118 base::RunLoop().RunUntilIdle();
7121 EXPECT_EQ(0, transaction_count());
7124 // A certificate error during an asynchronous fetch should cause the next fetch
7125 // to proceed synchronously.
7126 // TODO(ricea): In future, only certificate errors which require user
7127 // interaction should fail the asynchronous revalidation, and they should cause
7128 // the next revalidation to be synchronous rather than requiring a total
7129 // refetch. This test will need to be updated appropriately.
7130 TEST_F(HttpCacheStaleWhileRevalidateTest
, CertificateErrorCausesRefetch
) {
7131 // Write to the cache.
7132 RunFixtureTransactionTest();
7134 EXPECT_EQ(1, transaction_count());
7136 // Now read back. RunTransactionTestBase() expects to receive the network
7137 // error back from the HttpCache::Transaction, but since the cache request
7138 // will return OK we need to duplicate some of its implementation here.
7139 transaction_
.return_code
= net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
7140 net::TestCompletionCallback callback
;
7141 scoped_ptr
<net::HttpTransaction
> trans
;
7143 cache_
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7144 EXPECT_EQ(net::OK
, rv
);
7145 ASSERT_TRUE(trans
.get());
7147 MockHttpRequest
request(transaction_
);
7148 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7149 ASSERT_EQ(net::ERR_IO_PENDING
, rv
);
7150 ASSERT_EQ(net::OK
, callback
.WaitForResult());
7151 ReadAndVerifyTransaction(trans
.get(), transaction_
);
7153 EXPECT_EQ(1, transaction_count());
7155 // Allow the asynchronous fetch to run.
7156 base::RunLoop().RunUntilIdle();
7158 EXPECT_EQ(2, transaction_count());
7160 // Now run the transaction again. It should run synchronously.
7161 transaction_
.return_code
= net::OK
;
7162 RunFixtureTransactionTest();
7164 EXPECT_EQ(3, transaction_count());
7167 // Ensure that the response cached by the asynchronous request is not truncated,
7168 // even if the server is slow.
7169 TEST_F(HttpCacheStaleWhileRevalidateTest
, EntireResponseCached
) {
7170 transaction_
.test_mode
= TEST_MODE_SLOW_READ
;
7171 // Write to the cache.
7172 RunFixtureTransactionTest();
7174 // Read back from the cache.
7175 RunFixtureTransactionTest();
7177 // Let the async request execute.
7178 base::RunLoop().RunUntilIdle();
7180 // The cache entry should still be complete.
7181 transaction_
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
7182 RunFixtureTransactionTest();
7185 // Verify that there are no race conditions in the completely synchronous case.
7186 TEST_F(HttpCacheStaleWhileRevalidateTest
, SynchronousCaseWorks
) {
7187 transaction_
.test_mode
= TEST_MODE_SYNC_ALL
;
7188 // Write to the cache.
7189 RunFixtureTransactionTest();
7191 EXPECT_EQ(1, transaction_count());
7193 // Read back from the cache.
7194 RunFixtureTransactionTest();
7196 EXPECT_EQ(1, transaction_count());
7198 // Let the async request execute.
7199 base::RunLoop().RunUntilIdle();
7200 EXPECT_EQ(2, transaction_count());
7203 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo
* request
,
7204 std::string
* response_status
,
7205 std::string
* response_headers
,
7206 std::string
* response_data
) {
7207 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION
, request
->load_flags
);
7210 // Check that the load flags on the async request are the same as the load flags
7211 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7212 TEST_F(HttpCacheStaleWhileRevalidateTest
, LoadFlagsAsyncRevalidation
) {
7213 transaction_
.load_flags
= net::LOAD_NORMAL
;
7214 // Write to the cache.
7215 RunFixtureTransactionTest();
7217 EXPECT_EQ(1, transaction_count());
7219 // Read back from the cache.
7220 RunFixtureTransactionTest();
7222 EXPECT_EQ(1, transaction_count());
7224 transaction_
.handler
= CheckLoadFlagsAsyncRevalidation
;
7225 // Let the async request execute.
7226 base::RunLoop().RunUntilIdle();
7227 EXPECT_EQ(2, transaction_count());
7230 static void SimpleMockAuthHandler(const net::HttpRequestInfo
* request
,
7231 std::string
* response_status
,
7232 std::string
* response_headers
,
7233 std::string
* response_data
) {
7234 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
7235 !request
->extra_headers
.HasHeader("Authorization")) {
7236 response_status
->assign("HTTP/1.1 401 Unauthorized");
7237 response_headers
->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7240 response_status
->assign("HTTP/1.1 200 OK");
7243 TEST_F(HttpCacheStaleWhileRevalidateTest
, RestartForAuth
) {
7244 // Write to the cache.
7245 RunFixtureTransactionTest();
7247 EXPECT_EQ(1, transaction_count());
7249 // Now make the transaction require auth.
7250 transaction_
.request_headers
= "X-Require-Mock-Auth: dummy\r\n\r\n";
7251 transaction_
.handler
= SimpleMockAuthHandler
;
7253 // Read back from the cache.
7254 RunFixtureTransactionTest();
7256 EXPECT_EQ(1, transaction_count());
7258 // Let the async request execute.
7259 base::RunLoop().RunUntilIdle();
7261 EXPECT_EQ(2, transaction_count());
7264 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7265 // take place on a sparse entry.
7266 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7267 MockHttpCache cache
;
7269 // Create a transaction for bytes 0-9.
7270 MockHttpRequest
request(kRangeGET_TransactionOK
);
7271 MockTransaction
transaction(kRangeGET_TransactionOK
);
7272 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7273 transaction
.data
= "rg: 00-09 ";
7274 AddMockTransaction(&transaction
);
7276 net::TestCompletionCallback callback
;
7277 scoped_ptr
<net::HttpTransaction
> trans
;
7278 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7279 EXPECT_EQ(net::OK
, rv
);
7280 ASSERT_TRUE(trans
.get());
7282 // Start our transaction.
7283 trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7285 // A second transaction on a different part of the file (the default
7286 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7287 // the already pending transaction.
7288 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7290 // Let the first transaction complete.
7291 callback
.WaitForResult();
7293 RemoveMockTransaction(&transaction
);
7296 // Makes sure that a request stops using the cache when the response headers
7297 // with "Cache-Control: no-store" arrives. That means that another request for
7298 // the same URL can be processed before the response body of the original
7300 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7301 MockHttpCache cache
;
7302 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7303 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7304 MockHttpRequest
request(mock_transaction
);
7306 scoped_ptr
<Context
> first(new Context
);
7307 first
->result
= cache
.CreateTransaction(&first
->trans
);
7308 ASSERT_EQ(net::OK
, first
->result
);
7309 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7310 first
->result
= first
->trans
->Start(
7311 &request
, first
->callback
.callback(), net::BoundNetLog());
7312 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7314 base::MessageLoop::current()->RunUntilIdle();
7315 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7316 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7317 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7318 "Cache-Control", "no-store"));
7319 // Here we have read the response header but not read the response body yet.
7321 // Let us create the second (read) transaction.
7322 scoped_ptr
<Context
> second(new Context
);
7323 second
->result
= cache
.CreateTransaction(&second
->trans
);
7324 ASSERT_EQ(net::OK
, second
->result
);
7325 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7326 second
->result
= second
->trans
->Start(
7327 &request
, second
->callback
.callback(), net::BoundNetLog());
7329 // Here the second transaction proceeds without reading the first body.
7330 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7331 base::MessageLoop::current()->RunUntilIdle();
7332 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7333 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7334 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7335 "Cache-Control", "no-store"));
7336 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);