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 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
500 net::WebSocketHandshakeStreamBase
* CreateBasicStream(
501 scoped_ptr
<net::ClientSocketHandle
> connect
,
502 bool using_proxy
) override
{
505 net::WebSocketHandshakeStreamBase
* CreateSpdyStream(
506 const base::WeakPtr
<net::SpdySession
>& session
,
507 bool use_relative_url
) override
{
512 // Returns true if |entry| is not one of the log types paid attention to in this
513 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
515 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry
& entry
) {
516 switch (entry
.type
) {
517 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
518 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
519 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
520 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
521 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
522 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO
:
529 // Modifies |entries| to only include log entries created by the cache layer and
530 // asserted on in these tests.
531 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList
* entries
) {
532 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
533 &ShouldIgnoreLogEntry
),
540 //-----------------------------------------------------------------------------
543 TEST(HttpCache
, CreateThenDestroy
) {
546 scoped_ptr
<net::HttpTransaction
> trans
;
547 EXPECT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
548 ASSERT_TRUE(trans
.get());
551 TEST(HttpCache
, GetBackend
) {
552 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(0));
554 disk_cache::Backend
* backend
;
555 net::TestCompletionCallback cb
;
556 // This will lazily initialize the backend.
557 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
558 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
561 TEST(HttpCache
, SimpleGET
) {
563 net::CapturingBoundNetLog log
;
564 net::LoadTimingInfo load_timing_info
;
566 // Write to the cache.
567 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
568 log
.bound(), &load_timing_info
);
570 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
571 EXPECT_EQ(0, cache
.disk_cache()->open_count());
572 EXPECT_EQ(1, cache
.disk_cache()->create_count());
573 TestLoadTimingNetworkRequest(load_timing_info
);
576 TEST(HttpCache
, SimpleGETNoDiskCache
) {
579 cache
.disk_cache()->set_fail_requests();
581 net::CapturingBoundNetLog log
;
582 net::LoadTimingInfo load_timing_info
;
584 // Read from the network, and don't use the cache.
585 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
586 log
.bound(), &load_timing_info
);
588 // Check that the NetLog was filled as expected.
589 // (We attempted to both Open and Create entries, but both failed).
590 net::CapturingNetLog::CapturedEntryList entries
;
591 log
.GetEntries(&entries
);
592 FilterLogEntries(&entries
);
594 EXPECT_EQ(6u, entries
.size());
595 EXPECT_TRUE(net::LogContainsBeginEvent(
596 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
597 EXPECT_TRUE(net::LogContainsEndEvent(
598 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
599 EXPECT_TRUE(net::LogContainsBeginEvent(
600 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
601 EXPECT_TRUE(net::LogContainsEndEvent(
602 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
603 EXPECT_TRUE(net::LogContainsBeginEvent(
604 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
605 EXPECT_TRUE(net::LogContainsEndEvent(
606 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
608 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
609 EXPECT_EQ(0, cache
.disk_cache()->open_count());
610 EXPECT_EQ(0, cache
.disk_cache()->create_count());
611 TestLoadTimingNetworkRequest(load_timing_info
);
614 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
615 // This will initialize a cache object with NULL backend.
616 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
617 factory
->set_fail(true);
618 factory
->FinishCreation(); // We'll complete synchronously.
619 MockHttpCache
cache(factory
);
621 // Read from the network, and don't use the cache.
622 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
624 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
625 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
628 // Tests that IOBuffers are not referenced after IO completes.
629 TEST(HttpCache
, ReleaseBuffer
) {
632 // Write to the cache.
633 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
635 MockHttpRequest
request(kSimpleGET_Transaction
);
636 scoped_ptr
<net::HttpTransaction
> trans
;
637 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
639 const int kBufferSize
= 10;
640 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(kBufferSize
));
641 net::ReleaseBufferCompletionCallback
cb(buffer
.get());
643 int rv
= trans
->Start(&request
, cb
.callback(), net::BoundNetLog());
644 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
646 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
647 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
650 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
653 cache
.disk_cache()->set_soft_failures(true);
655 // Read from the network, and fail to write to the cache.
656 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
658 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
659 EXPECT_EQ(0, cache
.disk_cache()->open_count());
660 EXPECT_EQ(1, cache
.disk_cache()->create_count());
662 // This one should see an empty cache again.
663 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
665 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
666 EXPECT_EQ(0, cache
.disk_cache()->open_count());
667 EXPECT_EQ(2, cache
.disk_cache()->create_count());
670 // Tests that disk failures after the transaction has started don't cause the
672 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
675 MockHttpRequest
request(kSimpleGET_Transaction
);
677 scoped_ptr
<Context
> c(new Context());
678 int rv
= cache
.CreateTransaction(&c
->trans
);
679 ASSERT_EQ(net::OK
, rv
);
681 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
682 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
683 rv
= c
->callback
.WaitForResult();
685 // Start failing request now.
686 cache
.disk_cache()->set_soft_failures(true);
688 // We have to open the entry again to propagate the failure flag.
689 disk_cache::Entry
* en
;
690 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
693 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
696 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
697 EXPECT_EQ(1, cache
.disk_cache()->open_count());
698 EXPECT_EQ(1, cache
.disk_cache()->create_count());
700 // This one should see an empty cache again.
701 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
703 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
704 EXPECT_EQ(1, cache
.disk_cache()->open_count());
705 EXPECT_EQ(2, cache
.disk_cache()->create_count());
708 // Tests that we handle failures to read from the cache.
709 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
712 // Read from the network, and write to the cache.
713 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
715 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
716 EXPECT_EQ(0, cache
.disk_cache()->open_count());
717 EXPECT_EQ(1, cache
.disk_cache()->create_count());
719 cache
.disk_cache()->set_soft_failures(true);
721 // Now fail to read from the cache.
722 scoped_ptr
<Context
> c(new Context());
723 int rv
= cache
.CreateTransaction(&c
->trans
);
724 ASSERT_EQ(net::OK
, rv
);
726 MockHttpRequest
request(kSimpleGET_Transaction
);
727 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
728 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
730 // Now verify that the entry was removed from the cache.
731 cache
.disk_cache()->set_soft_failures(false);
733 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
734 EXPECT_EQ(1, cache
.disk_cache()->open_count());
735 EXPECT_EQ(2, cache
.disk_cache()->create_count());
737 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
739 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
740 EXPECT_EQ(1, cache
.disk_cache()->open_count());
741 EXPECT_EQ(3, cache
.disk_cache()->create_count());
744 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
747 net::CapturingBoundNetLog log
;
748 net::LoadTimingInfo load_timing_info
;
750 // Write to the cache.
751 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
752 log
.bound(), &load_timing_info
);
754 // Check that the NetLog was filled as expected.
755 net::CapturingNetLog::CapturedEntryList entries
;
756 log
.GetEntries(&entries
);
757 FilterLogEntries(&entries
);
759 EXPECT_EQ(8u, entries
.size());
760 EXPECT_TRUE(net::LogContainsBeginEvent(
761 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
762 EXPECT_TRUE(net::LogContainsEndEvent(
763 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
764 EXPECT_TRUE(net::LogContainsBeginEvent(
765 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
766 EXPECT_TRUE(net::LogContainsEndEvent(
767 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
768 EXPECT_TRUE(net::LogContainsBeginEvent(
769 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
770 EXPECT_TRUE(net::LogContainsEndEvent(
771 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
772 EXPECT_TRUE(net::LogContainsBeginEvent(
773 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
774 EXPECT_TRUE(net::LogContainsEndEvent(
775 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
777 TestLoadTimingNetworkRequest(load_timing_info
);
779 // Force this transaction to read from the cache.
780 MockTransaction
transaction(kSimpleGET_Transaction
);
781 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
785 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
788 // Check that the NetLog was filled as expected.
789 log
.GetEntries(&entries
);
790 FilterLogEntries(&entries
);
792 EXPECT_EQ(8u, entries
.size());
793 EXPECT_TRUE(net::LogContainsBeginEvent(
794 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
795 EXPECT_TRUE(net::LogContainsEndEvent(
796 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
797 EXPECT_TRUE(net::LogContainsBeginEvent(
798 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
799 EXPECT_TRUE(net::LogContainsEndEvent(
800 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
801 EXPECT_TRUE(net::LogContainsBeginEvent(
802 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
803 EXPECT_TRUE(net::LogContainsEndEvent(
804 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
805 EXPECT_TRUE(net::LogContainsBeginEvent(
806 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
807 EXPECT_TRUE(net::LogContainsEndEvent(
808 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
810 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
811 EXPECT_EQ(1, cache
.disk_cache()->open_count());
812 EXPECT_EQ(1, cache
.disk_cache()->create_count());
813 TestLoadTimingCachedResponse(load_timing_info
);
816 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
819 // force this transaction to read from the cache
820 MockTransaction
transaction(kSimpleGET_Transaction
);
821 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
823 MockHttpRequest
request(transaction
);
824 net::TestCompletionCallback callback
;
826 scoped_ptr
<net::HttpTransaction
> trans
;
827 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
829 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
830 if (rv
== net::ERR_IO_PENDING
)
831 rv
= callback
.WaitForResult();
832 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
836 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
837 EXPECT_EQ(0, cache
.disk_cache()->open_count());
838 EXPECT_EQ(0, cache
.disk_cache()->create_count());
841 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
844 // write to the cache
845 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
847 // force this transaction to read from the cache if valid
848 MockTransaction
transaction(kSimpleGET_Transaction
);
849 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
851 RunTransactionTest(cache
.http_cache(), transaction
);
853 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
854 EXPECT_EQ(1, cache
.disk_cache()->open_count());
855 EXPECT_EQ(1, cache
.disk_cache()->create_count());
858 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
861 // force this transaction to read from the cache if valid
862 MockTransaction
transaction(kSimpleGET_Transaction
);
863 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
865 RunTransactionTest(cache
.http_cache(), transaction
);
867 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
868 EXPECT_EQ(0, cache
.disk_cache()->open_count());
869 EXPECT_EQ(1, cache
.disk_cache()->create_count());
872 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
873 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
876 // Write to the cache.
877 MockTransaction
transaction(kSimpleGET_Transaction
);
878 transaction
.request_headers
= "Foo: bar\r\n";
879 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
881 AddMockTransaction(&transaction
);
882 RunTransactionTest(cache
.http_cache(), transaction
);
884 // Read from the cache.
885 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
886 RunTransactionTest(cache
.http_cache(), transaction
);
888 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
889 EXPECT_EQ(1, cache
.disk_cache()->open_count());
890 EXPECT_EQ(1, cache
.disk_cache()->create_count());
891 RemoveMockTransaction(&transaction
);
894 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
895 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
898 // Write to the cache.
899 MockTransaction
transaction(kSimpleGET_Transaction
);
900 transaction
.request_headers
= "Foo: bar\r\n";
901 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
903 AddMockTransaction(&transaction
);
904 RunTransactionTest(cache
.http_cache(), transaction
);
906 // Attempt to read from the cache... this is a vary mismatch that must reach
907 // the network again.
908 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
909 transaction
.request_headers
= "Foo: none\r\n";
910 net::CapturingBoundNetLog log
;
911 net::LoadTimingInfo load_timing_info
;
912 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
915 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
916 EXPECT_EQ(1, cache
.disk_cache()->open_count());
917 EXPECT_EQ(1, cache
.disk_cache()->create_count());
918 TestLoadTimingNetworkRequest(load_timing_info
);
919 RemoveMockTransaction(&transaction
);
922 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
924 TEST(HttpCache
, SimpleGET_CacheOverride_Network
) {
928 MockTransaction
transaction(kSimpleGET_Transaction
);
929 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
930 transaction
.response_headers
= "Cache-Control: no-cache\n";
932 AddMockTransaction(&transaction
);
933 RunTransactionTest(cache
.http_cache(), transaction
);
934 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
935 EXPECT_EQ(1, cache
.disk_cache()->create_count());
936 RemoveMockTransaction(&transaction
);
938 // Re-run transaction; make sure the result came from the network,
940 transaction
.data
= "Changed data.";
941 AddMockTransaction(&transaction
);
942 net::HttpResponseInfo response_info
;
943 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
946 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
947 EXPECT_FALSE(response_info
.server_data_unavailable
);
948 EXPECT_TRUE(response_info
.network_accessed
);
950 RemoveMockTransaction(&transaction
);
953 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
955 TEST(HttpCache
, SimpleGET_CacheOverride_Offline
) {
959 MockTransaction
transaction(kSimpleGET_Transaction
);
960 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
961 transaction
.response_headers
= "Cache-Control: no-cache\n";
963 AddMockTransaction(&transaction
);
964 RunTransactionTest(cache
.http_cache(), transaction
);
965 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
966 EXPECT_EQ(1, cache
.disk_cache()->create_count());
967 RemoveMockTransaction(&transaction
);
969 // Network failure with offline error; should return cache entry above +
970 // flag signalling stale data.
971 transaction
.return_code
= net::ERR_NAME_NOT_RESOLVED
;
972 AddMockTransaction(&transaction
);
974 MockHttpRequest
request(transaction
);
975 net::TestCompletionCallback callback
;
976 scoped_ptr
<net::HttpTransaction
> trans
;
977 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
978 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
979 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
981 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
982 ASSERT_TRUE(response_info
);
983 EXPECT_TRUE(response_info
->server_data_unavailable
);
984 EXPECT_TRUE(response_info
->was_cached
);
985 EXPECT_FALSE(response_info
->network_accessed
);
986 ReadAndVerifyTransaction(trans
.get(), transaction
);
987 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
989 RemoveMockTransaction(&transaction
);
992 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
993 // non-offline failure.
994 TEST(HttpCache
, SimpleGET_CacheOverride_NonOffline
) {
998 MockTransaction
transaction(kSimpleGET_Transaction
);
999 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
1000 transaction
.response_headers
= "Cache-Control: no-cache\n";
1002 AddMockTransaction(&transaction
);
1003 RunTransactionTest(cache
.http_cache(), transaction
);
1004 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1005 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1006 RemoveMockTransaction(&transaction
);
1008 // Network failure with non-offline error; should fail with that error.
1009 transaction
.return_code
= net::ERR_PROXY_CONNECTION_FAILED
;
1010 AddMockTransaction(&transaction
);
1012 net::HttpResponseInfo response_info2
;
1013 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1016 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1017 EXPECT_FALSE(response_info2
.server_data_unavailable
);
1019 RemoveMockTransaction(&transaction
);
1022 // Tests that was_cached was set properly on a failure, even if the cached
1023 // response wasn't returned.
1024 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
1025 MockHttpCache cache
;
1028 MockTransaction
transaction(kSimpleGET_Transaction
);
1029 transaction
.response_headers
= "Cache-Control: no-cache\n";
1031 AddMockTransaction(&transaction
);
1032 RunTransactionTest(cache
.http_cache(), transaction
);
1033 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1034 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1035 RemoveMockTransaction(&transaction
);
1037 // Network failure with error; should fail but have was_cached set.
1038 transaction
.return_code
= net::ERR_FAILED
;
1039 AddMockTransaction(&transaction
);
1041 MockHttpRequest
request(transaction
);
1042 net::TestCompletionCallback callback
;
1043 scoped_ptr
<net::HttpTransaction
> trans
;
1044 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
1045 EXPECT_EQ(net::OK
, rv
);
1046 ASSERT_TRUE(trans
.get());
1047 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1048 EXPECT_EQ(net::ERR_FAILED
, callback
.GetResult(rv
));
1050 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1051 ASSERT_TRUE(response_info
);
1052 EXPECT_TRUE(response_info
->was_cached
);
1053 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1055 RemoveMockTransaction(&transaction
);
1058 // Confirm if we have an empty cache, a read is marked as network verified.
1059 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1060 MockHttpCache cache
;
1062 // write to the cache
1063 net::HttpResponseInfo response_info
;
1064 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1067 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1068 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1069 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1070 EXPECT_TRUE(response_info
.network_accessed
);
1073 // Confirm if we have a fresh entry in cache, it isn't marked as
1074 // network verified.
1075 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1076 MockHttpCache cache
;
1079 MockTransaction
transaction(kSimpleGET_Transaction
);
1081 RunTransactionTest(cache
.http_cache(), transaction
);
1082 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1083 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1085 // Re-run transaction; make sure we don't mark the network as accessed.
1086 net::HttpResponseInfo response_info
;
1087 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1090 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1091 EXPECT_FALSE(response_info
.server_data_unavailable
);
1092 EXPECT_FALSE(response_info
.network_accessed
);
1095 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1096 MockHttpCache cache
;
1098 // Write to the cache.
1099 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1101 // Force this transaction to write to the cache again.
1102 MockTransaction
transaction(kSimpleGET_Transaction
);
1103 transaction
.load_flags
|= net::LOAD_BYPASS_CACHE
;
1105 net::CapturingBoundNetLog log
;
1106 net::LoadTimingInfo load_timing_info
;
1108 // Write to the cache.
1109 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1112 // Check that the NetLog was filled as expected.
1113 net::CapturingNetLog::CapturedEntryList entries
;
1114 log
.GetEntries(&entries
);
1115 FilterLogEntries(&entries
);
1117 EXPECT_EQ(8u, entries
.size());
1118 EXPECT_TRUE(net::LogContainsBeginEvent(
1119 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1120 EXPECT_TRUE(net::LogContainsEndEvent(
1121 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1122 EXPECT_TRUE(net::LogContainsBeginEvent(
1123 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1124 EXPECT_TRUE(net::LogContainsEndEvent(
1125 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1126 EXPECT_TRUE(net::LogContainsBeginEvent(
1127 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1128 EXPECT_TRUE(net::LogContainsEndEvent(
1129 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1130 EXPECT_TRUE(net::LogContainsBeginEvent(
1131 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1132 EXPECT_TRUE(net::LogContainsEndEvent(
1133 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1135 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1136 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1137 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1138 TestLoadTimingNetworkRequest(load_timing_info
);
1141 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1142 MockHttpCache cache
;
1144 // write to the cache
1145 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1147 // force this transaction to write to the cache again
1148 MockTransaction
transaction(kSimpleGET_Transaction
);
1149 transaction
.request_headers
= "pragma: no-cache\r\n";
1151 RunTransactionTest(cache
.http_cache(), transaction
);
1153 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1154 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1155 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1158 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1159 MockHttpCache cache
;
1161 // write to the cache
1162 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1164 // force this transaction to write to the cache again
1165 MockTransaction
transaction(kSimpleGET_Transaction
);
1166 transaction
.request_headers
= "cache-control: no-cache\r\n";
1168 RunTransactionTest(cache
.http_cache(), transaction
);
1170 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1171 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1172 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1175 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1176 MockHttpCache cache
;
1178 // Write to the cache.
1179 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1181 // Read from the cache.
1182 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1184 // Force this transaction to validate the cache.
1185 MockTransaction
transaction(kSimpleGET_Transaction
);
1186 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
1188 net::HttpResponseInfo response_info
;
1189 net::CapturingBoundNetLog log
;
1190 net::LoadTimingInfo load_timing_info
;
1191 RunTransactionTestWithResponseInfoAndGetTiming(
1192 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1195 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1196 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1197 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1198 EXPECT_TRUE(response_info
.network_accessed
);
1199 TestLoadTimingNetworkRequest(load_timing_info
);
1202 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1203 MockHttpCache cache
;
1205 // write to the cache
1206 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1208 // read from the cache
1209 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1211 // force this transaction to validate the cache
1212 MockTransaction
transaction(kSimpleGET_Transaction
);
1213 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1215 RunTransactionTest(cache
.http_cache(), transaction
);
1217 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1218 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1219 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1222 static void PreserveRequestHeaders_Handler(
1223 const net::HttpRequestInfo
* request
,
1224 std::string
* response_status
,
1225 std::string
* response_headers
,
1226 std::string
* response_data
) {
1227 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1230 // Tests that we don't remove extra headers for simple requests.
1231 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1232 MockHttpCache cache
;
1234 MockTransaction
transaction(kSimpleGET_Transaction
);
1235 transaction
.handler
= PreserveRequestHeaders_Handler
;
1236 transaction
.request_headers
= EXTRA_HEADER
;
1237 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1238 AddMockTransaction(&transaction
);
1240 // Write, then revalidate the entry.
1241 RunTransactionTest(cache
.http_cache(), transaction
);
1242 RunTransactionTest(cache
.http_cache(), transaction
);
1244 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1245 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1246 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1247 RemoveMockTransaction(&transaction
);
1250 // Tests that we don't remove extra headers for conditionalized requests.
1251 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1252 MockHttpCache cache
;
1254 // Write to the cache.
1255 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1257 MockTransaction
transaction(kETagGET_Transaction
);
1258 transaction
.handler
= PreserveRequestHeaders_Handler
;
1259 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1261 AddMockTransaction(&transaction
);
1263 RunTransactionTest(cache
.http_cache(), transaction
);
1265 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1266 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1267 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1268 RemoveMockTransaction(&transaction
);
1271 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1272 MockHttpCache cache
;
1274 MockHttpRequest
request(kSimpleGET_Transaction
);
1276 std::vector
<Context
*> context_list
;
1277 const int kNumTransactions
= 5;
1279 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1280 context_list
.push_back(new Context());
1281 Context
* c
= context_list
[i
];
1283 c
->result
= cache
.CreateTransaction(&c
->trans
);
1284 ASSERT_EQ(net::OK
, c
->result
);
1285 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1287 c
->result
= c
->trans
->Start(
1288 &request
, c
->callback
.callback(), net::BoundNetLog());
1291 // All requests are waiting for the active entry.
1292 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1293 Context
* c
= context_list
[i
];
1294 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1297 // Allow all requests to move from the Create queue to the active entry.
1298 base::MessageLoop::current()->RunUntilIdle();
1300 // The first request should be a writer at this point, and the subsequent
1301 // requests should be pending.
1303 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1304 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1305 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1307 // All requests depend on the writer, and the writer is between Start and
1309 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1310 Context
* c
= context_list
[i
];
1311 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1314 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1315 Context
* c
= context_list
[i
];
1316 if (c
->result
== net::ERR_IO_PENDING
)
1317 c
->result
= c
->callback
.WaitForResult();
1318 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1321 // We should not have had to re-open the disk entry
1323 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1324 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1325 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1327 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1328 Context
* c
= context_list
[i
];
1333 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1334 // If cancelling a request is racing with another request for the same resource
1335 // finishing, we have to make sure that we remove both transactions from the
1337 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1338 MockHttpCache cache
;
1340 MockHttpRequest
request(kSimpleGET_Transaction
);
1341 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1342 reader_request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
1344 std::vector
<Context
*> context_list
;
1345 const int kNumTransactions
= 5;
1347 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1348 context_list
.push_back(new Context());
1349 Context
* c
= context_list
[i
];
1351 c
->result
= cache
.CreateTransaction(&c
->trans
);
1352 ASSERT_EQ(net::OK
, c
->result
);
1354 MockHttpRequest
* this_request
= &request
;
1355 if (i
== 1 || i
== 2)
1356 this_request
= &reader_request
;
1358 c
->result
= c
->trans
->Start(
1359 this_request
, c
->callback
.callback(), net::BoundNetLog());
1362 // Allow all requests to move from the Create queue to the active entry.
1363 base::MessageLoop::current()->RunUntilIdle();
1365 // The first request should be a writer at this point, and the subsequent
1366 // requests should be pending.
1368 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1369 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1370 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1372 Context
* c
= context_list
[0];
1373 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1374 c
->result
= c
->callback
.WaitForResult();
1375 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1377 // Now we have 2 active readers and two queued transactions.
1379 EXPECT_EQ(net::LOAD_STATE_IDLE
,
1380 context_list
[2]->trans
->GetLoadState());
1381 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
,
1382 context_list
[3]->trans
->GetLoadState());
1384 c
= context_list
[1];
1385 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1386 c
->result
= c
->callback
.WaitForResult();
1387 if (c
->result
== net::OK
)
1388 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1390 // At this point we have one reader, two pending transactions and a task on
1391 // the queue to move to the next transaction. Now we cancel the request that
1392 // is the current reader, and expect the queued task to be able to start the
1395 c
= context_list
[2];
1398 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1399 Context
* c
= context_list
[i
];
1400 if (c
->result
== net::ERR_IO_PENDING
)
1401 c
->result
= c
->callback
.WaitForResult();
1402 if (c
->result
== net::OK
)
1403 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1406 // We should not have had to re-open the disk entry.
1408 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1409 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1410 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1412 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1413 Context
* c
= context_list
[i
];
1418 // Tests that we can doom an entry with pending transactions and delete one of
1419 // the pending transactions before the first one completes.
1420 // See http://code.google.com/p/chromium/issues/detail?id=25588
1421 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1422 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1423 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1425 MockHttpRequest
request(kSimpleGET_Transaction
);
1426 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1427 writer_request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1429 ScopedVector
<Context
> context_list
;
1430 const int kNumTransactions
= 4;
1432 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1433 context_list
.push_back(new Context());
1434 Context
* c
= context_list
[i
];
1436 c
->result
= cache
.CreateTransaction(&c
->trans
);
1437 ASSERT_EQ(net::OK
, c
->result
);
1439 MockHttpRequest
* this_request
= &request
;
1441 this_request
= &writer_request
;
1443 c
->result
= c
->trans
->Start(
1444 this_request
, c
->callback
.callback(), net::BoundNetLog());
1447 // The first request should be a writer at this point, and the two subsequent
1448 // requests should be pending. The last request doomed the first entry.
1450 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1452 // Cancel the first queued transaction.
1453 delete context_list
[1];
1454 context_list
.get()[1] = NULL
;
1456 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1459 Context
* c
= context_list
[i
];
1460 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1461 c
->result
= c
->callback
.WaitForResult();
1462 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1466 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1467 // We may attempt to delete an entry synchronously with the act of adding a new
1468 // transaction to said entry.
1469 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1470 MockHttpCache cache
;
1472 // The headers will be served right from the call to Start() the request.
1473 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1474 FastTransactionServer request_handler
;
1475 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1477 std::vector
<Context
*> context_list
;
1478 const int kNumTransactions
= 3;
1480 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1481 context_list
.push_back(new Context());
1482 Context
* c
= context_list
[i
];
1484 c
->result
= cache
.CreateTransaction(&c
->trans
);
1485 ASSERT_EQ(net::OK
, c
->result
);
1487 c
->result
= c
->trans
->Start(
1488 &request
, c
->callback
.callback(), net::BoundNetLog());
1491 // Allow all requests to move from the Create queue to the active entry.
1492 base::MessageLoop::current()->RunUntilIdle();
1494 // The first request should be a writer at this point, and the subsequent
1495 // requests should be pending.
1497 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1498 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1499 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1501 // Now, make sure that the second request asks for the entry not to be stored.
1502 request_handler
.set_no_store(true);
1504 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1505 Context
* c
= context_list
[i
];
1506 if (c
->result
== net::ERR_IO_PENDING
)
1507 c
->result
= c
->callback
.WaitForResult();
1508 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1512 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1513 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1514 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1516 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1519 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1520 MockHttpCache cache
;
1522 MockHttpRequest
request(kSimpleGET_Transaction
);
1524 std::vector
<Context
*> context_list
;
1525 const int kNumTransactions
= 2;
1527 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1528 context_list
.push_back(new Context());
1529 Context
* c
= context_list
[i
];
1531 c
->result
= cache
.CreateTransaction(&c
->trans
);
1532 ASSERT_EQ(net::OK
, c
->result
);
1534 c
->result
= c
->trans
->Start(
1535 &request
, c
->callback
.callback(), net::BoundNetLog());
1538 // Allow all requests to move from the Create queue to the active entry.
1539 base::MessageLoop::current()->RunUntilIdle();
1541 // The first request should be a writer at this point, and the subsequent
1542 // requests should be pending.
1544 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1545 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1546 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1548 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1549 Context
* c
= context_list
[i
];
1550 if (c
->result
== net::ERR_IO_PENDING
)
1551 c
->result
= c
->callback
.WaitForResult();
1552 // Destroy only the first transaction.
1555 context_list
[i
] = NULL
;
1559 // Complete the rest of the transactions.
1560 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1561 Context
* c
= context_list
[i
];
1562 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1565 // We should have had to re-open the disk entry.
1567 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1568 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1569 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1571 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1572 Context
* c
= context_list
[i
];
1577 // Tests that we can cancel requests that are queued waiting to open the disk
1579 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1580 MockHttpCache cache
;
1582 MockHttpRequest
request(kSimpleGET_Transaction
);
1584 std::vector
<Context
*> context_list
;
1585 const int kNumTransactions
= 5;
1587 for (int i
= 0; i
< kNumTransactions
; i
++) {
1588 context_list
.push_back(new Context());
1589 Context
* c
= context_list
[i
];
1591 c
->result
= cache
.CreateTransaction(&c
->trans
);
1592 ASSERT_EQ(net::OK
, c
->result
);
1594 c
->result
= c
->trans
->Start(
1595 &request
, c
->callback
.callback(), net::BoundNetLog());
1598 // The first request should be creating the disk cache entry and the others
1599 // should be pending.
1601 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1602 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1603 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1605 // Cancel a request from the pending queue.
1606 delete context_list
[3];
1607 context_list
[3] = NULL
;
1609 // Cancel the request that is creating the entry. This will force the pending
1610 // operations to restart.
1611 delete context_list
[0];
1612 context_list
[0] = NULL
;
1614 // Complete the rest of the transactions.
1615 for (int i
= 1; i
< kNumTransactions
; i
++) {
1616 Context
* c
= context_list
[i
];
1618 c
->result
= c
->callback
.GetResult(c
->result
);
1619 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1623 // We should have had to re-create the disk entry.
1625 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1626 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1627 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1629 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1630 delete context_list
[i
];
1634 // Tests that we can cancel a single request to open a disk cache entry.
1635 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1636 MockHttpCache cache
;
1638 MockHttpRequest
request(kSimpleGET_Transaction
);
1640 Context
* c
= new Context();
1642 c
->result
= cache
.CreateTransaction(&c
->trans
);
1643 ASSERT_EQ(net::OK
, c
->result
);
1645 c
->result
= c
->trans
->Start(
1646 &request
, c
->callback
.callback(), net::BoundNetLog());
1647 EXPECT_EQ(net::ERR_IO_PENDING
, c
->result
);
1649 // Release the reference that the mock disk cache keeps for this entry, so
1650 // that we test that the http cache handles the cancellation correctly.
1651 cache
.disk_cache()->ReleaseAll();
1654 base::MessageLoop::current()->RunUntilIdle();
1655 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1658 // Tests that we delete/create entries even if multiple requests are queued.
1659 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1660 MockHttpCache cache
;
1662 MockHttpRequest
request(kSimpleGET_Transaction
);
1663 request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1665 std::vector
<Context
*> context_list
;
1666 const int kNumTransactions
= 5;
1668 for (int i
= 0; i
< kNumTransactions
; i
++) {
1669 context_list
.push_back(new Context());
1670 Context
* c
= context_list
[i
];
1672 c
->result
= cache
.CreateTransaction(&c
->trans
);
1673 ASSERT_EQ(net::OK
, c
->result
);
1675 c
->result
= c
->trans
->Start(
1676 &request
, c
->callback
.callback(), net::BoundNetLog());
1679 // The first request should be deleting the disk cache entry and the others
1680 // should be pending.
1682 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1683 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1684 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1686 // Complete the transactions.
1687 for (int i
= 0; i
< kNumTransactions
; i
++) {
1688 Context
* c
= context_list
[i
];
1689 c
->result
= c
->callback
.GetResult(c
->result
);
1690 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1693 // We should have had to re-create the disk entry multiple times.
1695 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1696 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1697 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1699 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1700 delete context_list
[i
];
1704 // Tests that a (simulated) timeout allows transactions waiting on the cache
1705 // lock to continue.
1706 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1707 MockHttpCache cache
;
1708 cache
.BypassCacheLock();
1710 MockHttpRequest
request(kSimpleGET_Transaction
);
1712 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c1
.trans
));
1713 ASSERT_EQ(net::ERR_IO_PENDING
,
1714 c1
.trans
->Start(&request
, c1
.callback
.callback(),
1715 net::BoundNetLog()));
1716 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c2
.trans
));
1717 ASSERT_EQ(net::ERR_IO_PENDING
,
1718 c2
.trans
->Start(&request
, c2
.callback
.callback(),
1719 net::BoundNetLog()));
1721 // The second request is queued after the first one.
1723 c2
.callback
.WaitForResult();
1724 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1726 // Complete the first transaction.
1727 c1
.callback
.WaitForResult();
1728 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1731 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1732 MockHttpCache cache
;
1734 // write to the cache
1735 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1737 MockHttpRequest
request(kSimpleGET_Transaction
);
1738 net::TestCompletionCallback callback
;
1740 scoped_ptr
<net::HttpTransaction
> trans
;
1741 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1742 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1743 if (rv
== net::ERR_IO_PENDING
)
1744 rv
= callback
.WaitForResult();
1745 ASSERT_EQ(net::OK
, rv
);
1747 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
1748 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1749 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1751 // Test that destroying the transaction while it is reading from the cache
1755 // Make sure we pump any pending events, which should include a call to
1756 // HttpCache::Transaction::OnCacheReadCompleted.
1757 base::MessageLoop::current()->RunUntilIdle();
1760 // Tests that we can delete the HttpCache and deal with queued transactions
1761 // ("waiting for the backend" as opposed to Active or Doomed entries).
1762 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1763 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1764 new MockBackendNoCbFactory()));
1766 MockHttpRequest
request(kSimpleGET_Transaction
);
1768 std::vector
<Context
*> context_list
;
1769 const int kNumTransactions
= 5;
1771 for (int i
= 0; i
< kNumTransactions
; i
++) {
1772 context_list
.push_back(new Context());
1773 Context
* c
= context_list
[i
];
1775 c
->result
= cache
->CreateTransaction(&c
->trans
);
1776 ASSERT_EQ(net::OK
, c
->result
);
1778 c
->result
= c
->trans
->Start(
1779 &request
, c
->callback
.callback(), net::BoundNetLog());
1782 // The first request should be creating the disk cache entry and the others
1783 // should be pending.
1785 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1786 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1787 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1791 // There is not much to do with the transactions at this point... they are
1792 // waiting for a callback that will not fire.
1793 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1794 delete context_list
[i
];
1798 // Tests that we queue requests when initializing the backend.
1799 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1800 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1801 MockHttpCache
cache(factory
);
1803 MockHttpRequest
request0(kSimpleGET_Transaction
);
1804 MockHttpRequest
request1(kTypicalGET_Transaction
);
1805 MockHttpRequest
request2(kETagGET_Transaction
);
1807 std::vector
<Context
*> context_list
;
1808 const int kNumTransactions
= 3;
1810 for (int i
= 0; i
< kNumTransactions
; i
++) {
1811 context_list
.push_back(new Context());
1812 Context
* c
= context_list
[i
];
1814 c
->result
= cache
.CreateTransaction(&c
->trans
);
1815 ASSERT_EQ(net::OK
, c
->result
);
1818 context_list
[0]->result
= context_list
[0]->trans
->Start(
1819 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1820 context_list
[1]->result
= context_list
[1]->trans
->Start(
1821 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1822 context_list
[2]->result
= context_list
[2]->trans
->Start(
1823 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1825 // Just to make sure that everything is still pending.
1826 base::MessageLoop::current()->RunUntilIdle();
1828 // The first request should be creating the disk cache.
1829 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1831 factory
->FinishCreation();
1833 base::MessageLoop::current()->RunUntilIdle();
1834 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1835 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1837 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1838 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1839 delete context_list
[i
];
1843 // Tests that we can cancel requests that are queued waiting for the backend
1844 // to be initialized.
1845 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1846 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1847 MockHttpCache
cache(factory
);
1849 MockHttpRequest
request0(kSimpleGET_Transaction
);
1850 MockHttpRequest
request1(kTypicalGET_Transaction
);
1851 MockHttpRequest
request2(kETagGET_Transaction
);
1853 std::vector
<Context
*> context_list
;
1854 const int kNumTransactions
= 3;
1856 for (int i
= 0; i
< kNumTransactions
; i
++) {
1857 context_list
.push_back(new Context());
1858 Context
* c
= context_list
[i
];
1860 c
->result
= cache
.CreateTransaction(&c
->trans
);
1861 ASSERT_EQ(net::OK
, c
->result
);
1864 context_list
[0]->result
= context_list
[0]->trans
->Start(
1865 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1866 context_list
[1]->result
= context_list
[1]->trans
->Start(
1867 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1868 context_list
[2]->result
= context_list
[2]->trans
->Start(
1869 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1871 // Just to make sure that everything is still pending.
1872 base::MessageLoop::current()->RunUntilIdle();
1874 // The first request should be creating the disk cache.
1875 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1877 // Cancel a request from the pending queue.
1878 delete context_list
[1];
1879 context_list
[1] = NULL
;
1881 // Cancel the request that is creating the entry.
1882 delete context_list
[0];
1883 context_list
[0] = NULL
;
1885 // Complete the last transaction.
1886 factory
->FinishCreation();
1888 context_list
[2]->result
=
1889 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1890 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1892 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1893 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1895 delete context_list
[2];
1898 // Tests that we can delete the cache while creating the backend.
1899 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1900 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1901 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1903 MockHttpRequest
request(kSimpleGET_Transaction
);
1905 scoped_ptr
<Context
> c(new Context());
1906 c
->result
= cache
->CreateTransaction(&c
->trans
);
1907 ASSERT_EQ(net::OK
, c
->result
);
1909 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1911 // Just to make sure that everything is still pending.
1912 base::MessageLoop::current()->RunUntilIdle();
1914 // The request should be creating the disk cache.
1915 EXPECT_FALSE(c
->callback
.have_result());
1917 // We cannot call FinishCreation because the factory itself will go away with
1918 // the cache, so grab the callback and attempt to use it.
1919 net::CompletionCallback callback
= factory
->callback();
1920 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1923 base::MessageLoop::current()->RunUntilIdle();
1926 callback
.Run(net::ERR_ABORTED
);
1929 // Tests that we can delete the cache while creating the backend, from within
1930 // one of the callbacks.
1931 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1932 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1933 MockHttpCache
* cache
= new MockHttpCache(factory
);
1935 DeleteCacheCompletionCallback
cb(cache
);
1936 disk_cache::Backend
* backend
;
1937 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1938 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1940 // Now let's queue a regular transaction
1941 MockHttpRequest
request(kSimpleGET_Transaction
);
1943 scoped_ptr
<Context
> c(new Context());
1944 c
->result
= cache
->CreateTransaction(&c
->trans
);
1945 ASSERT_EQ(net::OK
, c
->result
);
1947 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1949 // And another direct backend request.
1950 net::TestCompletionCallback cb2
;
1951 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1952 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1954 // Just to make sure that everything is still pending.
1955 base::MessageLoop::current()->RunUntilIdle();
1957 // The request should be queued.
1958 EXPECT_FALSE(c
->callback
.have_result());
1960 // Generate the callback.
1961 factory
->FinishCreation();
1962 rv
= cb
.WaitForResult();
1964 // The cache should be gone by now.
1965 base::MessageLoop::current()->RunUntilIdle();
1966 EXPECT_EQ(net::OK
, c
->callback
.GetResult(c
->result
));
1967 EXPECT_FALSE(cb2
.have_result());
1970 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
1971 MockHttpCache cache
;
1973 // write to the cache
1974 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
1976 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1977 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1978 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1980 // Get the same URL again, but this time we expect it to result
1981 // in a conditional request.
1982 net::CapturingBoundNetLog log
;
1983 net::LoadTimingInfo load_timing_info
;
1984 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
1985 log
.bound(), &load_timing_info
);
1987 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1988 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1989 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1990 TestLoadTimingNetworkRequest(load_timing_info
);
1993 static void ETagGet_ConditionalRequest_Handler(
1994 const net::HttpRequestInfo
* request
,
1995 std::string
* response_status
,
1996 std::string
* response_headers
,
1997 std::string
* response_data
) {
1999 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2000 response_status
->assign("HTTP/1.1 304 Not Modified");
2001 response_headers
->assign(kETagGET_Transaction
.response_headers
);
2002 response_data
->clear();
2005 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
2006 MockHttpCache cache
;
2008 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2010 // write to the cache
2011 RunTransactionTest(cache
.http_cache(), transaction
);
2013 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2014 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2015 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2017 // Get the same URL again, but this time we expect it to result
2018 // in a conditional request.
2019 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2020 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
2021 net::CapturingBoundNetLog log
;
2022 net::LoadTimingInfo load_timing_info
;
2023 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2026 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2027 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2028 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2029 TestLoadTimingNetworkRequest(load_timing_info
);
2032 class RevalidationServer
{
2034 RevalidationServer() {
2035 s_etag_used_
= false;
2036 s_last_modified_used_
= false;
2039 bool EtagUsed() { return s_etag_used_
; }
2040 bool LastModifiedUsed() { return s_last_modified_used_
; }
2042 static void Handler(const net::HttpRequestInfo
* request
,
2043 std::string
* response_status
,
2044 std::string
* response_headers
,
2045 std::string
* response_data
);
2048 static bool s_etag_used_
;
2049 static bool s_last_modified_used_
;
2051 bool RevalidationServer::s_etag_used_
= false;
2052 bool RevalidationServer::s_last_modified_used_
= false;
2054 void RevalidationServer::Handler(const net::HttpRequestInfo
* request
,
2055 std::string
* response_status
,
2056 std::string
* response_headers
,
2057 std::string
* response_data
) {
2058 if (request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
))
2059 s_etag_used_
= true;
2061 if (request
->extra_headers
.HasHeader(
2062 net::HttpRequestHeaders::kIfModifiedSince
)) {
2063 s_last_modified_used_
= true;
2066 if (s_etag_used_
|| s_last_modified_used_
) {
2067 response_status
->assign("HTTP/1.1 304 Not Modified");
2068 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2069 response_data
->clear();
2071 response_status
->assign(kTypicalGET_Transaction
.status
);
2072 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2073 response_data
->assign(kTypicalGET_Transaction
.data
);
2077 // Tests revalidation after a vary match.
2078 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMatch
) {
2079 MockHttpCache cache
;
2081 // Write to the cache.
2082 MockTransaction
transaction(kTypicalGET_Transaction
);
2083 transaction
.request_headers
= "Foo: bar\r\n";
2084 transaction
.response_headers
=
2085 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2086 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2088 "Cache-Control: max-age=0\n"
2090 AddMockTransaction(&transaction
);
2091 RunTransactionTest(cache
.http_cache(), transaction
);
2093 // Read from the cache.
2094 RevalidationServer server
;
2095 transaction
.handler
= server
.Handler
;
2096 net::CapturingBoundNetLog log
;
2097 net::LoadTimingInfo load_timing_info
;
2098 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2101 EXPECT_TRUE(server
.EtagUsed());
2102 EXPECT_TRUE(server
.LastModifiedUsed());
2103 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2104 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2105 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2106 TestLoadTimingNetworkRequest(load_timing_info
);
2107 RemoveMockTransaction(&transaction
);
2110 // Tests revalidation after a vary mismatch if etag is present.
2111 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMismatch
) {
2112 MockHttpCache cache
;
2114 // Write to the cache.
2115 MockTransaction
transaction(kTypicalGET_Transaction
);
2116 transaction
.request_headers
= "Foo: bar\r\n";
2117 transaction
.response_headers
=
2118 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2119 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2121 "Cache-Control: max-age=0\n"
2123 AddMockTransaction(&transaction
);
2124 RunTransactionTest(cache
.http_cache(), transaction
);
2126 // Read from the cache and revalidate the entry.
2127 RevalidationServer server
;
2128 transaction
.handler
= server
.Handler
;
2129 transaction
.request_headers
= "Foo: none\r\n";
2130 net::CapturingBoundNetLog log
;
2131 net::LoadTimingInfo load_timing_info
;
2132 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2135 EXPECT_TRUE(server
.EtagUsed());
2136 EXPECT_FALSE(server
.LastModifiedUsed());
2137 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2138 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2139 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2140 TestLoadTimingNetworkRequest(load_timing_info
);
2141 RemoveMockTransaction(&transaction
);
2144 // Tests lack of revalidation after a vary mismatch and no etag.
2145 TEST(HttpCache
, SimpleGET_LoadDontValidateCache_VaryMismatch
) {
2146 MockHttpCache cache
;
2148 // Write to the cache.
2149 MockTransaction
transaction(kTypicalGET_Transaction
);
2150 transaction
.request_headers
= "Foo: bar\r\n";
2151 transaction
.response_headers
=
2152 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2153 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2154 "Cache-Control: max-age=0\n"
2156 AddMockTransaction(&transaction
);
2157 RunTransactionTest(cache
.http_cache(), transaction
);
2159 // Read from the cache and don't revalidate the entry.
2160 RevalidationServer server
;
2161 transaction
.handler
= server
.Handler
;
2162 transaction
.request_headers
= "Foo: none\r\n";
2163 net::CapturingBoundNetLog log
;
2164 net::LoadTimingInfo load_timing_info
;
2165 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2168 EXPECT_FALSE(server
.EtagUsed());
2169 EXPECT_FALSE(server
.LastModifiedUsed());
2170 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2171 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2172 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2173 TestLoadTimingNetworkRequest(load_timing_info
);
2174 RemoveMockTransaction(&transaction
);
2177 static void ETagGet_UnconditionalRequest_Handler(
2178 const net::HttpRequestInfo
* request
,
2179 std::string
* response_status
,
2180 std::string
* response_headers
,
2181 std::string
* response_data
) {
2183 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2186 TEST(HttpCache
, ETagGET_Http10
) {
2187 MockHttpCache cache
;
2189 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2190 transaction
.status
= "HTTP/1.0 200 OK";
2192 // Write to the cache.
2193 RunTransactionTest(cache
.http_cache(), transaction
);
2195 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2196 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2197 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2199 // Get the same URL again, without generating a conditional request.
2200 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2201 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2202 RunTransactionTest(cache
.http_cache(), transaction
);
2204 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2205 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2206 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2209 TEST(HttpCache
, ETagGET_Http10_Range
) {
2210 MockHttpCache cache
;
2212 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2213 transaction
.status
= "HTTP/1.0 200 OK";
2215 // Write to the cache.
2216 RunTransactionTest(cache
.http_cache(), transaction
);
2218 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2219 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2220 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2222 // Get the same URL again, but use a byte range request.
2223 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2224 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2225 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2226 RunTransactionTest(cache
.http_cache(), transaction
);
2228 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2229 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2230 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2233 static void ETagGet_ConditionalRequest_NoStore_Handler(
2234 const net::HttpRequestInfo
* request
,
2235 std::string
* response_status
,
2236 std::string
* response_headers
,
2237 std::string
* response_data
) {
2239 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2240 response_status
->assign("HTTP/1.1 304 Not Modified");
2241 response_headers
->assign("Cache-Control: no-store\n");
2242 response_data
->clear();
2245 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2246 MockHttpCache cache
;
2248 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2250 // Write to the cache.
2251 RunTransactionTest(cache
.http_cache(), transaction
);
2253 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2254 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2255 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2257 // Get the same URL again, but this time we expect it to result
2258 // in a conditional request.
2259 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2260 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2261 RunTransactionTest(cache
.http_cache(), transaction
);
2263 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2264 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2265 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2267 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2269 // Write to the cache again. This should create a new entry.
2270 RunTransactionTest(cache
.http_cache(), transaction2
);
2272 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2273 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2274 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2277 // Helper that does 4 requests using HttpCache:
2279 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2280 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2281 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2283 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2285 static void ConditionalizedRequestUpdatesCacheHelper(
2286 const Response
& net_response_1
,
2287 const Response
& net_response_2
,
2288 const Response
& cached_response_2
,
2289 const char* extra_request_headers
) {
2290 MockHttpCache cache
;
2292 // The URL we will be requesting.
2293 const char* kUrl
= "http://foobar.com/main.css";
2295 // Junk network response.
2296 static const Response kUnexpectedResponse
= {
2297 "HTTP/1.1 500 Unexpected",
2298 "Server: unexpected_header",
2302 // We will control the network layer's responses for |kUrl| using
2303 // |mock_network_response|.
2304 MockTransaction mock_network_response
= { 0 };
2305 mock_network_response
.url
= kUrl
;
2306 AddMockTransaction(&mock_network_response
);
2308 // Request |kUrl| for the first time. It should hit the network and
2309 // receive |kNetResponse1|, which it saves into the HTTP cache.
2311 MockTransaction request
= { 0 };
2313 request
.method
= "GET";
2314 request
.request_headers
= "";
2316 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2317 net_response_1
.AssignTo(&request
); // Expected result.
2319 std::string response_headers
;
2320 RunTransactionTestWithResponse(
2321 cache
.http_cache(), request
, &response_headers
);
2323 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2324 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2325 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2326 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2328 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2329 // cache, so we don't hit the network.
2331 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2333 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2334 net_response_1
.AssignTo(&request
); // Expected result.
2336 RunTransactionTestWithResponse(
2337 cache
.http_cache(), request
, &response_headers
);
2339 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2340 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2341 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2342 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2344 // Request |kUrl| yet again, but this time give the request an
2345 // "If-Modified-Since" header. This will cause the request to re-hit the
2346 // network. However now the network response is going to be
2347 // different -- this simulates a change made to the CSS file.
2349 request
.request_headers
= extra_request_headers
;
2350 request
.load_flags
= net::LOAD_NORMAL
;
2352 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2353 net_response_2
.AssignTo(&request
); // Expected result.
2355 RunTransactionTestWithResponse(
2356 cache
.http_cache(), request
, &response_headers
);
2358 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2359 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2360 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2361 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2363 // Finally, request |kUrl| again. This request should be serviced from
2364 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2365 // and NOT |kNetResponse1|. The previous step should have replaced the
2366 // value in the cache with the modified response.
2368 request
.request_headers
= "";
2369 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2371 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2372 cached_response_2
.AssignTo(&request
); // Expected result.
2374 RunTransactionTestWithResponse(
2375 cache
.http_cache(), request
, &response_headers
);
2377 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2378 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2379 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2380 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2382 RemoveMockTransaction(&mock_network_response
);
2385 // Check that when an "if-modified-since" header is attached
2386 // to the request, the result still updates the cached entry.
2387 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2388 // First network response for |kUrl|.
2389 static const Response kNetResponse1
= {
2391 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2392 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2396 // Second network response for |kUrl|.
2397 static const Response kNetResponse2
= {
2399 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2400 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2404 const char* extra_headers
=
2405 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2407 ConditionalizedRequestUpdatesCacheHelper(
2408 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2411 // Check that when an "if-none-match" header is attached
2412 // to the request, the result updates the cached entry.
2413 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2414 // First network response for |kUrl|.
2415 static const Response kNetResponse1
= {
2417 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2419 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2423 // Second network response for |kUrl|.
2424 static const Response kNetResponse2
= {
2426 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2428 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2432 const char* extra_headers
= "If-None-Match: \"ETAG1\"\r\n";
2434 ConditionalizedRequestUpdatesCacheHelper(
2435 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2438 // Check that when an "if-modified-since" header is attached
2439 // to a request, the 304 (not modified result) result updates the cached
2440 // headers, and the 304 response is returned rather than the cached response.
2441 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2442 // First network response for |kUrl|.
2443 static const Response kNetResponse1
= {
2445 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2447 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2451 // Second network response for |kUrl|.
2452 static const Response kNetResponse2
= {
2453 "HTTP/1.1 304 Not Modified",
2454 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2456 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2460 static const Response kCachedResponse2
= {
2462 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2464 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2468 const char* extra_headers
=
2469 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2471 ConditionalizedRequestUpdatesCacheHelper(
2472 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2475 // Test that when doing an externally conditionalized if-modified-since
2476 // and there is no corresponding cache entry, a new cache entry is NOT
2477 // created (304 response).
2478 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2479 MockHttpCache cache
;
2481 const char* kUrl
= "http://foobar.com/main.css";
2483 static const Response kNetResponse
= {
2484 "HTTP/1.1 304 Not Modified",
2485 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2486 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2490 const char* kExtraRequestHeaders
=
2491 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2493 // We will control the network layer's responses for |kUrl| using
2494 // |mock_network_response|.
2495 MockTransaction mock_network_response
= { 0 };
2496 mock_network_response
.url
= kUrl
;
2497 AddMockTransaction(&mock_network_response
);
2499 MockTransaction request
= { 0 };
2501 request
.method
= "GET";
2502 request
.request_headers
= kExtraRequestHeaders
;
2504 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2505 kNetResponse
.AssignTo(&request
); // Expected result.
2507 std::string response_headers
;
2508 RunTransactionTestWithResponse(
2509 cache
.http_cache(), request
, &response_headers
);
2511 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2512 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2513 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2514 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2516 RemoveMockTransaction(&mock_network_response
);
2519 // Test that when doing an externally conditionalized if-modified-since
2520 // and there is no corresponding cache entry, a new cache entry is NOT
2521 // created (200 response).
2522 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2523 MockHttpCache cache
;
2525 const char* kUrl
= "http://foobar.com/main.css";
2527 static const Response kNetResponse
= {
2529 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2530 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2534 const char* kExtraRequestHeaders
=
2535 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2537 // We will control the network layer's responses for |kUrl| using
2538 // |mock_network_response|.
2539 MockTransaction mock_network_response
= { 0 };
2540 mock_network_response
.url
= kUrl
;
2541 AddMockTransaction(&mock_network_response
);
2543 MockTransaction request
= { 0 };
2545 request
.method
= "GET";
2546 request
.request_headers
= kExtraRequestHeaders
;
2548 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2549 kNetResponse
.AssignTo(&request
); // Expected result.
2551 std::string response_headers
;
2552 RunTransactionTestWithResponse(
2553 cache
.http_cache(), request
, &response_headers
);
2555 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2556 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2557 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2558 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2560 RemoveMockTransaction(&mock_network_response
);
2563 // Test that when doing an externally conditionalized if-modified-since
2564 // if the date does not match the cache entry's last-modified date,
2565 // then we do NOT use the response (304) to update the cache.
2566 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2567 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2568 static const Response kNetResponse1
= {
2570 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2572 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2576 // Second network response for |kUrl|.
2577 static const Response kNetResponse2
= {
2578 "HTTP/1.1 304 Not Modified",
2579 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2581 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2585 // This is two days in the future from the original response's last-modified
2587 const char* kExtraRequestHeaders
=
2588 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2590 ConditionalizedRequestUpdatesCacheHelper(
2591 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2594 // Test that when doing an externally conditionalized if-none-match
2595 // if the etag does not match the cache entry's etag, then we do not use the
2596 // response (304) to update the cache.
2597 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2598 static const Response kNetResponse1
= {
2600 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2602 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2606 // Second network response for |kUrl|.
2607 static const Response kNetResponse2
= {
2608 "HTTP/1.1 304 Not Modified",
2609 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2611 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2615 // Different etag from original response.
2616 const char* kExtraRequestHeaders
= "If-None-Match: \"Foo2\"\r\n";
2618 ConditionalizedRequestUpdatesCacheHelper(
2619 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2622 // Test that doing an externally conditionalized request with both if-none-match
2623 // and if-modified-since updates the cache.
2624 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2625 static const Response kNetResponse1
= {
2627 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2629 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2633 // Second network response for |kUrl|.
2634 static const Response kNetResponse2
= {
2636 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2638 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2642 const char* kExtraRequestHeaders
=
2643 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2644 "If-None-Match: \"Foo1\"\r\n";
2646 ConditionalizedRequestUpdatesCacheHelper(
2647 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2650 // Test that doing an externally conditionalized request with both if-none-match
2651 // and if-modified-since does not update the cache with only one match.
2652 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2653 static const Response kNetResponse1
= {
2655 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2657 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2661 // Second network response for |kUrl|.
2662 static const Response kNetResponse2
= {
2664 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2666 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2670 // The etag doesn't match what we have stored.
2671 const char* kExtraRequestHeaders
=
2672 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2673 "If-None-Match: \"Foo2\"\r\n";
2675 ConditionalizedRequestUpdatesCacheHelper(
2676 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2679 // Test that doing an externally conditionalized request with both if-none-match
2680 // and if-modified-since does not update the cache with only one match.
2681 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2682 static const Response kNetResponse1
= {
2684 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2686 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2690 // Second network response for |kUrl|.
2691 static const Response kNetResponse2
= {
2693 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2695 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2699 // The modification date doesn't match what we have stored.
2700 const char* kExtraRequestHeaders
=
2701 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2702 "If-None-Match: \"Foo1\"\r\n";
2704 ConditionalizedRequestUpdatesCacheHelper(
2705 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2708 TEST(HttpCache
, UrlContainingHash
) {
2709 MockHttpCache cache
;
2711 // Do a typical GET request -- should write an entry into our cache.
2712 MockTransaction
trans(kTypicalGET_Transaction
);
2713 RunTransactionTest(cache
.http_cache(), trans
);
2715 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2716 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2717 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2719 // Request the same URL, but this time with a reference section (hash).
2720 // Since the cache key strips the hash sections, this should be a cache hit.
2721 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2722 trans
.url
= url_with_hash
.c_str();
2723 trans
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2725 RunTransactionTest(cache
.http_cache(), trans
);
2727 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2728 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2729 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2732 // Tests that we skip the cache for POST requests that do not have an upload
2734 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2735 MockHttpCache cache
;
2737 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2739 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2740 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2741 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2744 // Tests POST handling with a disabled cache (no DCHECK).
2745 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2746 MockHttpCache cache
;
2747 cache
.http_cache()->set_mode(net::HttpCache::Mode::DISABLE
);
2749 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2751 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2752 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2753 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2756 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2757 MockHttpCache cache
;
2759 MockTransaction
transaction(kSimplePOST_Transaction
);
2760 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2762 MockHttpRequest
request(transaction
);
2763 net::TestCompletionCallback callback
;
2765 scoped_ptr
<net::HttpTransaction
> trans
;
2766 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
2767 ASSERT_TRUE(trans
.get());
2769 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
2770 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
2774 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2775 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2776 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2779 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2780 MockHttpCache cache
;
2782 // Test that we hit the cache for POST requests.
2784 MockTransaction
transaction(kSimplePOST_Transaction
);
2786 const int64 kUploadId
= 1; // Just a dummy value.
2788 ScopedVector
<net::UploadElementReader
> element_readers
;
2789 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2790 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2792 MockHttpRequest
request(transaction
);
2793 request
.upload_data_stream
= &upload_data_stream
;
2795 // Populate the cache.
2796 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2798 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2799 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2800 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2803 request
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2804 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2806 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2807 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2808 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2811 // Test that we don't hit the cache for POST requests if there is a byte range.
2812 TEST(HttpCache
, SimplePOST_WithRanges
) {
2813 MockHttpCache cache
;
2815 MockTransaction
transaction(kSimplePOST_Transaction
);
2816 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2818 const int64 kUploadId
= 1; // Just a dummy value.
2820 ScopedVector
<net::UploadElementReader
> element_readers
;
2821 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2822 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2825 MockHttpRequest
request(transaction
);
2826 request
.upload_data_stream
= &upload_data_stream
;
2828 // Attempt to populate the cache.
2829 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2831 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2832 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2833 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2836 // Tests that a POST is cached separately from a previously cached GET.
2837 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2838 MockHttpCache cache
;
2840 ScopedVector
<net::UploadElementReader
> element_readers
;
2841 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2842 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2844 MockTransaction
transaction(kSimplePOST_Transaction
);
2845 MockHttpRequest
req1(transaction
);
2846 req1
.upload_data_stream
= &upload_data_stream
;
2848 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2850 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2851 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2852 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2854 transaction
.method
= "GET";
2855 MockHttpRequest
req2(transaction
);
2857 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2859 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2860 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2861 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2864 // Tests that a successful POST invalidates a previously cached GET.
2865 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2866 MockHttpCache cache
;
2868 MockTransaction
transaction(kSimpleGET_Transaction
);
2869 AddMockTransaction(&transaction
);
2870 MockHttpRequest
req1(transaction
);
2872 // Attempt to populate the cache.
2873 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2875 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2876 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2877 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2879 ScopedVector
<net::UploadElementReader
> element_readers
;
2880 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2881 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2883 transaction
.method
= "POST";
2884 transaction
.status
= "HTTP/1.1 205 No Content";
2885 MockHttpRequest
req2(transaction
);
2886 req2
.upload_data_stream
= &upload_data_stream
;
2888 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2890 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2891 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2892 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2894 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2896 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2897 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2898 EXPECT_EQ(3, cache
.disk_cache()->create_count());
2899 RemoveMockTransaction(&transaction
);
2902 // Tests that a successful POST invalidates a previously cached GET, even when
2903 // there is no upload identifier.
2904 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
2905 MockHttpCache cache
;
2907 MockTransaction
transaction(kSimpleGET_Transaction
);
2908 AddMockTransaction(&transaction
);
2909 MockHttpRequest
req1(transaction
);
2911 // Attempt to populate the cache.
2912 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2914 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2915 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2916 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2918 ScopedVector
<net::UploadElementReader
> element_readers
;
2919 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2920 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2922 transaction
.method
= "POST";
2923 transaction
.status
= "HTTP/1.1 205 No Content";
2924 MockHttpRequest
req2(transaction
);
2925 req2
.upload_data_stream
= &upload_data_stream
;
2927 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2929 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2930 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2931 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2933 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2935 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2936 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2937 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2938 RemoveMockTransaction(&transaction
);
2941 // Tests that processing a POST before creating the backend doesn't crash.
2942 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
2943 // This will initialize a cache object with NULL backend.
2944 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
2945 factory
->set_fail(true);
2946 factory
->FinishCreation();
2947 MockHttpCache
cache(factory
);
2949 ScopedVector
<net::UploadElementReader
> element_readers
;
2950 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2951 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2953 MockTransaction
transaction(kSimplePOST_Transaction
);
2954 AddMockTransaction(&transaction
);
2955 MockHttpRequest
req(transaction
);
2956 req
.upload_data_stream
= &upload_data_stream
;
2958 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
2960 RemoveMockTransaction(&transaction
);
2963 // Tests that we don't invalidate entries as a result of a failed POST.
2964 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
2965 MockHttpCache cache
;
2967 MockTransaction
transaction(kSimpleGET_Transaction
);
2968 AddMockTransaction(&transaction
);
2969 MockHttpRequest
req1(transaction
);
2971 // Attempt to populate the cache.
2972 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2974 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2975 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2976 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2978 ScopedVector
<net::UploadElementReader
> element_readers
;
2979 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2980 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2982 transaction
.method
= "POST";
2983 transaction
.status
= "HTTP/1.1 100 Continue";
2984 MockHttpRequest
req2(transaction
);
2985 req2
.upload_data_stream
= &upload_data_stream
;
2987 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2989 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2990 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2991 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2993 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2995 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2996 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2997 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2998 RemoveMockTransaction(&transaction
);
3001 // Tests that a HEAD request is not cached by itself.
3002 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3003 MockHttpCache cache
;
3004 MockTransaction
transaction(kSimplePOST_Transaction
);
3005 AddMockTransaction(&transaction
);
3006 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3007 transaction
.method
= "HEAD";
3009 MockHttpRequest
request(transaction
);
3010 net::TestCompletionCallback callback
;
3012 scoped_ptr
<net::HttpTransaction
> trans
;
3013 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
3014 ASSERT_TRUE(trans
.get());
3016 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
3017 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
3021 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3022 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3023 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3024 RemoveMockTransaction(&transaction
);
3027 // Tests that a HEAD request is served from a cached GET.
3028 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3029 MockHttpCache cache
;
3030 MockTransaction
transaction(kSimpleGET_Transaction
);
3031 AddMockTransaction(&transaction
);
3033 // Populate the cache.
3034 RunTransactionTest(cache
.http_cache(), transaction
);
3036 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3037 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3038 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3041 transaction
.method
= "HEAD";
3042 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3043 transaction
.data
= "";
3044 RunTransactionTest(cache
.http_cache(), transaction
);
3046 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3047 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3048 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3049 RemoveMockTransaction(&transaction
);
3052 // Tests that a read-only request served from the cache preserves CL.
3053 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3054 MockHttpCache cache
;
3055 MockTransaction
transaction(kSimpleGET_Transaction
);
3056 AddMockTransaction(&transaction
);
3057 transaction
.response_headers
= "Content-Length: 42\n";
3059 // Populate the cache.
3060 RunTransactionTest(cache
.http_cache(), transaction
);
3063 transaction
.method
= "HEAD";
3064 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3065 transaction
.data
= "";
3066 std::string headers
;
3068 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3070 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3071 RemoveMockTransaction(&transaction
);
3074 // Tests that a read-write request served from the cache preserves CL.
3075 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3076 MockHttpCache cache
;
3077 MockTransaction
transaction(kETagGET_Transaction
);
3078 AddMockTransaction(&transaction
);
3079 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3080 server_headers
.append("Content-Length: 42\n");
3081 transaction
.response_headers
= server_headers
.data();
3083 // Populate the cache.
3084 RunTransactionTest(cache
.http_cache(), transaction
);
3087 transaction
.method
= "HEAD";
3088 transaction
.data
= "";
3089 std::string headers
;
3091 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3093 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3094 RemoveMockTransaction(&transaction
);
3097 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3098 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3099 MockHttpCache cache
;
3100 MockTransaction
transaction(kSimpleGET_Transaction
);
3101 AddMockTransaction(&transaction
);
3103 // Populate the cache.
3104 RunTransactionTest(cache
.http_cache(), transaction
);
3107 transaction
.method
= "HEAD";
3108 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3109 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3110 transaction
.return_code
= net::ERR_CACHE_MISS
;
3111 RunTransactionTest(cache
.http_cache(), transaction
);
3113 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3114 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3115 RemoveMockTransaction(&transaction
);
3118 // Tests that a HEAD request can be served from a partialy cached resource.
3119 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3120 MockHttpCache cache
;
3121 AddMockTransaction(&kRangeGET_TransactionOK
);
3123 // Write to the cache (40-49).
3124 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3125 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3127 MockTransaction
transaction(kSimpleGET_Transaction
);
3129 transaction
.url
= kRangeGET_TransactionOK
.url
;
3130 transaction
.method
= "HEAD";
3131 transaction
.data
= "";
3132 AddMockTransaction(&transaction
);
3133 std::string headers
;
3136 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3138 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3139 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length"));
3140 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3141 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3142 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3143 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3144 RemoveMockTransaction(&transaction
);
3147 // Tests that a HEAD request can be served from a truncated resource.
3148 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3149 MockHttpCache cache
;
3150 AddMockTransaction(&kRangeGET_TransactionOK
);
3152 std::string
raw_headers("HTTP/1.1 200 OK\n"
3153 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3155 "Accept-Ranges: bytes\n"
3156 "Content-Length: 80\n");
3157 CreateTruncatedEntry(raw_headers
, &cache
);
3158 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3160 MockTransaction
transaction(kSimpleGET_Transaction
);
3162 transaction
.url
= kRangeGET_TransactionOK
.url
;
3163 transaction
.method
= "HEAD";
3164 transaction
.data
= "";
3165 AddMockTransaction(&transaction
);
3166 std::string headers
;
3169 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3171 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3172 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3173 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3174 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3175 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3176 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3177 RemoveMockTransaction(&transaction
);
3180 // Tests that a HEAD request updates the cached response.
3181 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3182 MockHttpCache cache
;
3183 MockTransaction
transaction(kTypicalGET_Transaction
);
3184 AddMockTransaction(&transaction
);
3186 // Populate the cache.
3187 RunTransactionTest(cache
.http_cache(), transaction
);
3189 // Update the cache.
3190 transaction
.method
= "HEAD";
3191 transaction
.response_headers
= "Foo: bar\n";
3192 transaction
.data
= "";
3193 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3194 std::string headers
;
3195 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3196 RemoveMockTransaction(&transaction
);
3198 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3199 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3201 MockTransaction
transaction2(kTypicalGET_Transaction
);
3202 AddMockTransaction(&transaction2
);
3204 // Make sure we are done with the previous transaction.
3205 base::MessageLoop::current()->RunUntilIdle();
3207 // Load from the cache.
3208 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3209 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3211 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3212 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3213 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3214 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3215 RemoveMockTransaction(&transaction2
);
3218 // Tests that an externally conditionalized HEAD request updates the cache.
3219 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3220 MockHttpCache cache
;
3221 MockTransaction
transaction(kTypicalGET_Transaction
);
3222 AddMockTransaction(&transaction
);
3224 // Populate the cache.
3225 RunTransactionTest(cache
.http_cache(), transaction
);
3227 // Update the cache.
3228 transaction
.method
= "HEAD";
3229 transaction
.request_headers
=
3230 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3231 transaction
.response_headers
= "Foo: bar\n";
3232 transaction
.data
= "";
3233 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3234 std::string headers
;
3235 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3236 RemoveMockTransaction(&transaction
);
3238 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3239 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3241 MockTransaction
transaction2(kTypicalGET_Transaction
);
3242 AddMockTransaction(&transaction2
);
3244 // Make sure we are done with the previous transaction.
3245 base::MessageLoop::current()->RunUntilIdle();
3247 // Load from the cache.
3248 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3249 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3251 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3252 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3253 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3254 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3255 RemoveMockTransaction(&transaction2
);
3258 // Tests that a HEAD request invalidates an old cached entry.
3259 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3260 MockHttpCache cache
;
3261 MockTransaction
transaction(kTypicalGET_Transaction
);
3262 AddMockTransaction(&transaction
);
3264 // Populate the cache.
3265 RunTransactionTest(cache
.http_cache(), transaction
);
3267 // Update the cache.
3268 transaction
.method
= "HEAD";
3269 transaction
.data
= "";
3270 RunTransactionTest(cache
.http_cache(), transaction
);
3271 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3273 // Load from the cache.
3274 transaction
.method
= "GET";
3275 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3276 transaction
.return_code
= net::ERR_CACHE_MISS
;
3277 RunTransactionTest(cache
.http_cache(), transaction
);
3279 RemoveMockTransaction(&transaction
);
3282 // Tests that we do not cache the response of a PUT.
3283 TEST(HttpCache
, SimplePUT_Miss
) {
3284 MockHttpCache cache
;
3286 MockTransaction
transaction(kSimplePOST_Transaction
);
3287 transaction
.method
= "PUT";
3289 ScopedVector
<net::UploadElementReader
> element_readers
;
3290 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3291 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3293 MockHttpRequest
request(transaction
);
3294 request
.upload_data_stream
= &upload_data_stream
;
3296 // Attempt to populate the cache.
3297 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3299 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3300 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3301 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3304 // Tests that we invalidate entries as a result of a PUT.
3305 TEST(HttpCache
, SimplePUT_Invalidate
) {
3306 MockHttpCache cache
;
3308 MockTransaction
transaction(kSimpleGET_Transaction
);
3309 MockHttpRequest
req1(transaction
);
3311 // Attempt to populate the cache.
3312 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3314 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3315 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3316 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3318 ScopedVector
<net::UploadElementReader
> element_readers
;
3319 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3320 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3322 transaction
.method
= "PUT";
3323 MockHttpRequest
req2(transaction
);
3324 req2
.upload_data_stream
= &upload_data_stream
;
3326 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3328 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3329 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3330 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3332 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3334 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3335 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3336 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3339 // Tests that we invalidate entries as a result of a PUT.
3340 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3341 MockHttpCache cache
;
3343 MockTransaction
transaction(kSimpleGET_Transaction
);
3344 AddMockTransaction(&transaction
);
3345 MockHttpRequest
req1(transaction
);
3347 // Attempt to populate the cache.
3348 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3350 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3351 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3352 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3354 ScopedVector
<net::UploadElementReader
> element_readers
;
3355 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3356 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3358 transaction
.method
= "PUT";
3359 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3360 MockHttpRequest
req2(transaction
);
3361 req2
.upload_data_stream
= &upload_data_stream
;
3363 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3365 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3366 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3367 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3369 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3371 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3372 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3373 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3374 RemoveMockTransaction(&transaction
);
3377 // Tests that we don't invalidate entries as a result of a failed PUT.
3378 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3379 MockHttpCache cache
;
3381 MockTransaction
transaction(kSimpleGET_Transaction
);
3382 AddMockTransaction(&transaction
);
3383 MockHttpRequest
req1(transaction
);
3385 // Attempt to populate the cache.
3386 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3388 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3389 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3390 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3392 ScopedVector
<net::UploadElementReader
> element_readers
;
3393 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3394 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3396 transaction
.method
= "PUT";
3397 transaction
.status
= "HTTP/1.1 404 Not Found";
3398 MockHttpRequest
req2(transaction
);
3399 req2
.upload_data_stream
= &upload_data_stream
;
3401 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3403 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3404 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3405 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3407 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3409 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3410 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3411 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3412 RemoveMockTransaction(&transaction
);
3415 // Tests that we do not cache the response of a DELETE.
3416 TEST(HttpCache
, SimpleDELETE_Miss
) {
3417 MockHttpCache cache
;
3419 MockTransaction
transaction(kSimplePOST_Transaction
);
3420 transaction
.method
= "DELETE";
3422 ScopedVector
<net::UploadElementReader
> element_readers
;
3423 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3424 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3426 MockHttpRequest
request(transaction
);
3427 request
.upload_data_stream
= &upload_data_stream
;
3429 // Attempt to populate the cache.
3430 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3432 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3433 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3434 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3437 // Tests that we invalidate entries as a result of a DELETE.
3438 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3439 MockHttpCache cache
;
3441 MockTransaction
transaction(kSimpleGET_Transaction
);
3442 MockHttpRequest
req1(transaction
);
3444 // Attempt to populate the cache.
3445 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3447 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3448 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3449 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3451 ScopedVector
<net::UploadElementReader
> element_readers
;
3452 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3453 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3455 transaction
.method
= "DELETE";
3456 MockHttpRequest
req2(transaction
);
3457 req2
.upload_data_stream
= &upload_data_stream
;
3459 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3461 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3462 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3463 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3465 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3467 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3468 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3469 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3472 // Tests that we invalidate entries as a result of a DELETE.
3473 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3474 MockHttpCache cache
;
3476 MockTransaction
transaction(kSimpleGET_Transaction
);
3477 AddMockTransaction(&transaction
);
3479 // Attempt to populate the cache.
3480 RunTransactionTest(cache
.http_cache(), transaction
);
3482 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3483 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3484 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3486 transaction
.method
= "DELETE";
3487 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3489 RunTransactionTest(cache
.http_cache(), transaction
);
3491 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3492 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3493 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3495 transaction
.method
= "GET";
3496 RunTransactionTest(cache
.http_cache(), transaction
);
3498 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3499 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3500 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3501 RemoveMockTransaction(&transaction
);
3504 // Tests that we don't invalidate entries as a result of a failed DELETE.
3505 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3506 MockHttpCache cache
;
3508 MockTransaction
transaction(kSimpleGET_Transaction
);
3509 AddMockTransaction(&transaction
);
3511 // Attempt to populate the cache.
3512 RunTransactionTest(cache
.http_cache(), transaction
);
3514 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3515 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3516 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3518 transaction
.method
= "DELETE";
3519 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3521 RunTransactionTest(cache
.http_cache(), transaction
);
3523 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3524 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3525 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3527 transaction
.method
= "GET";
3528 transaction
.status
= "HTTP/1.1 200 OK";
3529 RunTransactionTest(cache
.http_cache(), transaction
);
3531 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3532 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3533 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3534 RemoveMockTransaction(&transaction
);
3537 // Tests that we don't invalidate entries after a failed network transaction.
3538 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3539 MockHttpCache cache
;
3541 // Populate the cache.
3542 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3543 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3545 // Fail the network request.
3546 MockTransaction
transaction(kSimpleGET_Transaction
);
3547 transaction
.return_code
= net::ERR_FAILED
;
3548 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3550 AddMockTransaction(&transaction
);
3551 RunTransactionTest(cache
.http_cache(), transaction
);
3552 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3553 RemoveMockTransaction(&transaction
);
3555 transaction
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
3556 transaction
.return_code
= net::OK
;
3557 AddMockTransaction(&transaction
);
3558 RunTransactionTest(cache
.http_cache(), transaction
);
3560 // Make sure the transaction didn't reach the network.
3561 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3562 RemoveMockTransaction(&transaction
);
3565 TEST(HttpCache
, RangeGET_SkipsCache
) {
3566 MockHttpCache cache
;
3568 // Test that we skip the cache for range GET requests. Eventually, we will
3569 // want to cache these, but we'll still have cases where skipping the cache
3570 // makes sense, so we want to make sure that it works properly.
3572 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3574 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3575 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3576 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3578 MockTransaction
transaction(kSimpleGET_Transaction
);
3579 transaction
.request_headers
= "If-None-Match: foo\r\n";
3580 RunTransactionTest(cache
.http_cache(), transaction
);
3582 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3583 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3584 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3586 transaction
.request_headers
=
3587 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3588 RunTransactionTest(cache
.http_cache(), transaction
);
3590 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3591 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3592 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3595 // Test that we skip the cache for range requests that include a validation
3597 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3598 MockHttpCache cache
;
3600 MockTransaction
transaction(kRangeGET_Transaction
);
3601 transaction
.request_headers
= "If-None-Match: foo\r\n"
3603 "Range: bytes = 40-49\r\n";
3604 RunTransactionTest(cache
.http_cache(), transaction
);
3606 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3607 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3608 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3610 transaction
.request_headers
=
3611 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3613 "Range: bytes = 40-49\r\n";
3614 RunTransactionTest(cache
.http_cache(), transaction
);
3616 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3617 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3618 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3620 transaction
.request_headers
= "If-Range: bla\r\n"
3622 "Range: bytes = 40-49\r\n";
3623 RunTransactionTest(cache
.http_cache(), transaction
);
3625 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3626 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3627 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3630 // Tests that receiving 206 for a regular request is handled correctly.
3631 TEST(HttpCache
, GET_Crazy206
) {
3632 MockHttpCache cache
;
3634 // Write to the cache.
3635 MockTransaction
transaction(kRangeGET_TransactionOK
);
3636 AddMockTransaction(&transaction
);
3637 transaction
.request_headers
= EXTRA_HEADER
;
3638 transaction
.handler
= NULL
;
3639 RunTransactionTest(cache
.http_cache(), transaction
);
3641 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3642 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3643 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3645 // This should read again from the net.
3646 RunTransactionTest(cache
.http_cache(), transaction
);
3648 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3649 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3650 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3651 RemoveMockTransaction(&transaction
);
3654 // Tests that receiving 416 for a regular request is handled correctly.
3655 TEST(HttpCache
, GET_Crazy416
) {
3656 MockHttpCache cache
;
3658 // Write to the cache.
3659 MockTransaction
transaction(kSimpleGET_Transaction
);
3660 AddMockTransaction(&transaction
);
3661 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3662 RunTransactionTest(cache
.http_cache(), transaction
);
3664 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3665 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3666 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3668 RemoveMockTransaction(&transaction
);
3671 // Tests that we store partial responses that can't be validated, as they can
3672 // be used for requests that don't require revalidation.
3673 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3674 MockHttpCache cache
;
3675 std::string headers
;
3677 // Write to the cache (40-49).
3678 MockTransaction
transaction(kRangeGET_TransactionOK
);
3679 AddMockTransaction(&transaction
);
3680 transaction
.response_headers
= "Content-Length: 10\n"
3681 "Cache-Control: max-age=3600\n"
3682 "ETag: w/\"foo\"\n";
3683 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3685 Verify206Response(headers
, 40, 49);
3686 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3687 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3688 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3690 // Now verify that there's cached data.
3691 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3694 Verify206Response(headers
, 40, 49);
3695 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3696 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3697 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3699 RemoveMockTransaction(&transaction
);
3702 // Tests failures to validate cache partial responses that lack strong
3704 TEST(HttpCache
, RangeGET_NoValidation
) {
3705 MockHttpCache cache
;
3706 std::string headers
;
3708 // Write to the cache (40-49).
3709 MockTransaction
transaction(kRangeGET_TransactionOK
);
3710 AddMockTransaction(&transaction
);
3711 transaction
.response_headers
= "Content-Length: 10\n"
3712 "ETag: w/\"foo\"\n";
3713 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3715 Verify206Response(headers
, 40, 49);
3716 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3717 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3718 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3720 // Now verify that the cached data is not used.
3721 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3724 Verify206Response(headers
, 40, 49);
3725 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3726 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3727 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3729 RemoveMockTransaction(&transaction
);
3732 // Tests that we cache partial responses that lack content-length.
3733 TEST(HttpCache
, RangeGET_NoContentLength
) {
3734 MockHttpCache cache
;
3735 std::string headers
;
3737 // Attempt to write to the cache (40-49).
3738 MockTransaction
transaction(kRangeGET_TransactionOK
);
3739 AddMockTransaction(&transaction
);
3740 transaction
.response_headers
= "ETag: \"foo\"\n"
3741 "Accept-Ranges: bytes\n"
3742 "Content-Range: bytes 40-49/80\n";
3743 transaction
.handler
= NULL
;
3744 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3746 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3747 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3748 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3750 // Now verify that there's no cached data.
3751 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
3752 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3755 Verify206Response(headers
, 40, 49);
3756 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3757 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3758 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3760 RemoveMockTransaction(&transaction
);
3763 // Tests that we can cache range requests and fetch random blocks from the
3764 // cache and the network.
3765 TEST(HttpCache
, RangeGET_OK
) {
3766 MockHttpCache cache
;
3767 AddMockTransaction(&kRangeGET_TransactionOK
);
3768 std::string headers
;
3770 // Write to the cache (40-49).
3771 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3774 Verify206Response(headers
, 40, 49);
3775 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3776 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3777 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3779 // Read from the cache (40-49).
3780 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3783 Verify206Response(headers
, 40, 49);
3784 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3785 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3786 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3788 // Make sure we are done with the previous transaction.
3789 base::MessageLoop::current()->RunUntilIdle();
3791 // Write to the cache (30-39).
3792 MockTransaction
transaction(kRangeGET_TransactionOK
);
3793 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3794 transaction
.data
= "rg: 30-39 ";
3795 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3797 Verify206Response(headers
, 30, 39);
3798 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3799 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3800 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3802 // Make sure we are done with the previous transaction.
3803 base::MessageLoop::current()->RunUntilIdle();
3805 // Write and read from the cache (20-59).
3806 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3807 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3808 net::CapturingBoundNetLog log
;
3809 net::LoadTimingInfo load_timing_info
;
3810 RunTransactionTestWithResponseAndGetTiming(
3811 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3814 Verify206Response(headers
, 20, 59);
3815 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3816 EXPECT_EQ(3, cache
.disk_cache()->open_count());
3817 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3818 TestLoadTimingNetworkRequest(load_timing_info
);
3820 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3823 // Checks that with a cache backend having Sparse IO unimplementes the cache
3824 // entry would be doomed after a range request.
3825 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3826 TEST(HttpCache
, RangeGET_SparseNotImplemented
) {
3827 MockHttpCache cache
;
3828 cache
.disk_cache()->set_fail_sparse_requests();
3830 // Run a cacheable request to prime the cache.
3831 MockTransaction
transaction(kTypicalGET_Transaction
);
3832 transaction
.url
= kRangeGET_TransactionOK
.url
;
3833 AddMockTransaction(&transaction
);
3834 RunTransactionTest(cache
.http_cache(), transaction
);
3835 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3836 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3837 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3839 // Verify that we added the entry.
3840 disk_cache::Entry
* entry
;
3841 net::TestCompletionCallback cb
;
3842 int rv
= cache
.disk_cache()->OpenEntry(transaction
.url
,
3845 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
3846 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3848 RemoveMockTransaction(&transaction
);
3850 // Request the range with the backend that does not support it.
3851 MockTransaction
transaction2(kRangeGET_TransactionOK
);
3852 std::string headers
;
3853 AddMockTransaction(&transaction2
);
3854 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3855 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3856 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3857 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3859 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3860 // if it was re-created later, so this effectively checks that the old data is
3862 disk_cache::Entry
* entry2
;
3863 rv
= cache
.disk_cache()->OpenEntry(transaction2
.url
,
3866 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE
, cb
.GetResult(rv
));
3867 RemoveMockTransaction(&transaction2
);
3870 TEST(HttpCache
, RangeGET_SparseNotImplementedOnEmptyCache
) {
3871 MockHttpCache cache
;
3872 cache
.disk_cache()->set_fail_sparse_requests();
3874 // Request the range with the backend that does not support it.
3875 MockTransaction
transaction(kRangeGET_TransactionOK
);
3876 std::string headers
;
3877 AddMockTransaction(&transaction
);
3878 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3879 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3880 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3881 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3883 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3884 // if it was re-created later, so this effectively checks that the old data is
3885 // gone as a result of a failed range write.
3886 disk_cache::Entry
* entry
;
3887 net::TestCompletionCallback cb
;
3888 int rv
= cache
.disk_cache()->OpenEntry(transaction
.url
,
3891 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE
, cb
.GetResult(rv
));
3892 RemoveMockTransaction(&transaction
);
3895 // Tests that we can cache range requests and fetch random blocks from the
3896 // cache and the network, with synchronous responses.
3897 TEST(HttpCache
, RangeGET_SyncOK
) {
3898 MockHttpCache cache
;
3900 MockTransaction
transaction(kRangeGET_TransactionOK
);
3901 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
3902 AddMockTransaction(&transaction
);
3904 // Write to the cache (40-49).
3905 std::string headers
;
3906 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3908 Verify206Response(headers
, 40, 49);
3909 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3910 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3911 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3913 // Read from the cache (40-49).
3914 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3916 Verify206Response(headers
, 40, 49);
3917 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3918 EXPECT_EQ(0, 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 to the cache (30-39).
3925 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3926 transaction
.data
= "rg: 30-39 ";
3927 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3929 Verify206Response(headers
, 30, 39);
3930 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3931 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3932 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3934 // Make sure we are done with the previous transaction.
3935 base::MessageLoop::current()->RunUntilIdle();
3937 // Write and read from the cache (20-59).
3938 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3939 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3940 net::CapturingBoundNetLog log
;
3941 net::LoadTimingInfo load_timing_info
;
3942 RunTransactionTestWithResponseAndGetTiming(
3943 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3946 Verify206Response(headers
, 20, 59);
3947 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3948 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3949 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3950 TestLoadTimingNetworkRequest(load_timing_info
);
3952 RemoveMockTransaction(&transaction
);
3955 // Tests that we don't revalidate an entry unless we are required to do so.
3956 TEST(HttpCache
, RangeGET_Revalidate1
) {
3957 MockHttpCache cache
;
3958 std::string headers
;
3960 // Write to the cache (40-49).
3961 MockTransaction
transaction(kRangeGET_TransactionOK
);
3962 transaction
.response_headers
=
3963 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3964 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3966 "Accept-Ranges: bytes\n"
3967 "Content-Length: 10\n";
3968 AddMockTransaction(&transaction
);
3969 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3971 Verify206Response(headers
, 40, 49);
3972 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3973 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3974 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3976 // Read from the cache (40-49).
3977 net::CapturingBoundNetLog log
;
3978 net::LoadTimingInfo load_timing_info
;
3979 RunTransactionTestWithResponseAndGetTiming(
3980 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3983 Verify206Response(headers
, 40, 49);
3984 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3985 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3986 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3987 TestLoadTimingCachedResponse(load_timing_info
);
3989 // Read again forcing the revalidation.
3990 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3991 RunTransactionTestWithResponseAndGetTiming(
3992 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3995 Verify206Response(headers
, 40, 49);
3996 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3997 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3998 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3999 TestLoadTimingNetworkRequest(load_timing_info
);
4001 RemoveMockTransaction(&transaction
);
4004 // Checks that we revalidate an entry when the headers say so.
4005 TEST(HttpCache
, RangeGET_Revalidate2
) {
4006 MockHttpCache cache
;
4007 std::string headers
;
4009 // Write to the cache (40-49).
4010 MockTransaction
transaction(kRangeGET_TransactionOK
);
4011 transaction
.response_headers
=
4012 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4013 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4015 "Accept-Ranges: bytes\n"
4016 "Content-Length: 10\n";
4017 AddMockTransaction(&transaction
);
4018 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4020 Verify206Response(headers
, 40, 49);
4021 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4022 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4023 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4025 // Read from the cache (40-49).
4026 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4027 Verify206Response(headers
, 40, 49);
4029 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4030 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4031 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4033 RemoveMockTransaction(&transaction
);
4036 // Tests that we deal with 304s for range requests.
4037 TEST(HttpCache
, RangeGET_304
) {
4038 MockHttpCache cache
;
4039 AddMockTransaction(&kRangeGET_TransactionOK
);
4040 std::string headers
;
4042 // Write to the cache (40-49).
4043 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4046 Verify206Response(headers
, 40, 49);
4047 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4048 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4049 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4051 // Read from the cache (40-49).
4052 RangeTransactionServer handler
;
4053 handler
.set_not_modified(true);
4054 MockTransaction
transaction(kRangeGET_TransactionOK
);
4055 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4056 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4058 Verify206Response(headers
, 40, 49);
4059 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4060 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4061 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4063 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4066 // Tests that we deal with 206s when revalidating range requests.
4067 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4068 MockHttpCache cache
;
4069 AddMockTransaction(&kRangeGET_TransactionOK
);
4070 std::string headers
;
4072 // Write to the cache (40-49).
4073 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4076 Verify206Response(headers
, 40, 49);
4077 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4078 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4079 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4081 // Attempt to read from the cache (40-49).
4082 RangeTransactionServer handler
;
4083 handler
.set_modified(true);
4084 MockTransaction
transaction(kRangeGET_TransactionOK
);
4085 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4086 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4088 Verify206Response(headers
, 40, 49);
4089 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4090 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4091 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4093 // And the entry should be gone.
4094 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4095 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4096 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4097 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4099 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4102 // Tests that we cache 301s for range requests.
4103 TEST(HttpCache
, RangeGET_301
) {
4104 MockHttpCache cache
;
4105 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4106 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4107 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4108 transaction
.data
= "";
4109 transaction
.handler
= NULL
;
4110 AddMockTransaction(&transaction
);
4112 // Write to the cache.
4113 RunTransactionTest(cache
.http_cache(), transaction
);
4114 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4115 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4116 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4118 // Read from the cache.
4119 RunTransactionTest(cache
.http_cache(), transaction
);
4120 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4121 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4122 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4124 RemoveMockTransaction(&transaction
);
4127 // Tests that we can cache range requests when the start or end is unknown.
4128 // We start with one suffix request, followed by a request from a given point.
4129 TEST(HttpCache
, UnknownRangeGET_1
) {
4130 MockHttpCache cache
;
4131 AddMockTransaction(&kRangeGET_TransactionOK
);
4132 std::string headers
;
4134 // Write to the cache (70-79).
4135 MockTransaction
transaction(kRangeGET_TransactionOK
);
4136 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4137 transaction
.data
= "rg: 70-79 ";
4138 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4140 Verify206Response(headers
, 70, 79);
4141 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4142 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4143 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4145 // Make sure we are done with the previous transaction.
4146 base::MessageLoop::current()->RunUntilIdle();
4148 // Write and read from the cache (60-79).
4149 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4150 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4151 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4153 Verify206Response(headers
, 60, 79);
4154 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4155 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4156 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4158 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4161 // Tests that we can cache range requests when the start or end is unknown.
4162 // We start with one request from a given point, followed by a suffix request.
4163 // We'll also verify that synchronous cache responses work as intended.
4164 TEST(HttpCache
, UnknownRangeGET_2
) {
4165 MockHttpCache cache
;
4166 std::string headers
;
4168 MockTransaction
transaction(kRangeGET_TransactionOK
);
4169 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4170 TEST_MODE_SYNC_CACHE_READ
|
4171 TEST_MODE_SYNC_CACHE_WRITE
;
4172 AddMockTransaction(&transaction
);
4174 // Write to the cache (70-79).
4175 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4176 transaction
.data
= "rg: 70-79 ";
4177 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4179 Verify206Response(headers
, 70, 79);
4180 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4181 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4182 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4184 // Make sure we are done with the previous transaction.
4185 base::MessageLoop::current()->RunUntilIdle();
4187 // Write and read from the cache (60-79).
4188 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4189 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4190 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4192 Verify206Response(headers
, 60, 79);
4193 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4194 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4195 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4197 RemoveMockTransaction(&transaction
);
4200 // Tests that receiving Not Modified when asking for an open range doesn't mess
4202 TEST(HttpCache
, UnknownRangeGET_304
) {
4203 MockHttpCache cache
;
4204 std::string headers
;
4206 MockTransaction
transaction(kRangeGET_TransactionOK
);
4207 AddMockTransaction(&transaction
);
4209 RangeTransactionServer handler
;
4210 handler
.set_not_modified(true);
4212 // Ask for the end of the file, without knowing the length.
4213 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4214 transaction
.data
= "";
4215 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4217 // We just bypass the cache.
4218 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4219 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4220 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4221 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4223 RunTransactionTest(cache
.http_cache(), transaction
);
4224 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4226 RemoveMockTransaction(&transaction
);
4229 // Tests that we can handle non-range requests when we have cached a range.
4230 TEST(HttpCache
, GET_Previous206
) {
4231 MockHttpCache cache
;
4232 AddMockTransaction(&kRangeGET_TransactionOK
);
4233 std::string headers
;
4234 net::CapturingBoundNetLog log
;
4235 net::LoadTimingInfo load_timing_info
;
4237 // Write to the cache (40-49).
4238 RunTransactionTestWithResponseAndGetTiming(
4239 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4242 Verify206Response(headers
, 40, 49);
4243 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4244 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4246 TestLoadTimingNetworkRequest(load_timing_info
);
4248 // Write and read from the cache (0-79), when not asked for a range.
4249 MockTransaction
transaction(kRangeGET_TransactionOK
);
4250 transaction
.request_headers
= EXTRA_HEADER
;
4251 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4252 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4253 RunTransactionTestWithResponseAndGetTiming(
4254 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4257 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4258 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4259 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4261 TestLoadTimingNetworkRequest(load_timing_info
);
4263 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4266 // Tests that we can handle non-range requests when we have cached the first
4267 // part of the object and the server replies with 304 (Not Modified).
4268 TEST(HttpCache
, GET_Previous206_NotModified
) {
4269 MockHttpCache cache
;
4271 MockTransaction
transaction(kRangeGET_TransactionOK
);
4272 AddMockTransaction(&transaction
);
4273 std::string headers
;
4274 net::CapturingBoundNetLog log
;
4275 net::LoadTimingInfo load_timing_info
;
4277 // Write to the cache (0-9).
4278 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4279 transaction
.data
= "rg: 00-09 ";
4280 RunTransactionTestWithResponseAndGetTiming(
4281 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4283 Verify206Response(headers
, 0, 9);
4284 TestLoadTimingNetworkRequest(load_timing_info
);
4286 // Write to the cache (70-79).
4287 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4288 transaction
.data
= "rg: 70-79 ";
4289 RunTransactionTestWithResponseAndGetTiming(
4290 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4292 Verify206Response(headers
, 70, 79);
4294 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4295 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4296 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4297 TestLoadTimingNetworkRequest(load_timing_info
);
4299 // Read from the cache (0-9), write and read from cache (10 - 79).
4300 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4301 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4302 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4303 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4304 RunTransactionTestWithResponseAndGetTiming(
4305 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4308 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4309 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4310 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4311 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4312 TestLoadTimingNetworkRequest(load_timing_info
);
4314 RemoveMockTransaction(&transaction
);
4317 // Tests that we can handle a regular request to a sparse entry, that results in
4318 // new content provided by the server (206).
4319 TEST(HttpCache
, GET_Previous206_NewContent
) {
4320 MockHttpCache cache
;
4321 AddMockTransaction(&kRangeGET_TransactionOK
);
4322 std::string headers
;
4324 // Write to the cache (0-9).
4325 MockTransaction
transaction(kRangeGET_TransactionOK
);
4326 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4327 transaction
.data
= "rg: 00-09 ";
4328 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4330 Verify206Response(headers
, 0, 9);
4331 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4332 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4333 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4335 // Now we'll issue a request without any range that should result first in a
4336 // 206 (when revalidating), and then in a weird standard answer: the test
4337 // server will not modify the response so we'll get the default range... a
4338 // real server will answer with 200.
4339 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4340 transaction2
.request_headers
= EXTRA_HEADER
;
4341 transaction2
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4342 transaction2
.data
= "Not a range";
4343 RangeTransactionServer handler
;
4344 handler
.set_modified(true);
4345 net::CapturingBoundNetLog log
;
4346 net::LoadTimingInfo load_timing_info
;
4347 RunTransactionTestWithResponseAndGetTiming(
4348 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4351 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4352 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4353 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4354 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4355 TestLoadTimingNetworkRequest(load_timing_info
);
4357 // Verify that the previous request deleted the entry.
4358 RunTransactionTest(cache
.http_cache(), transaction
);
4359 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4361 RemoveMockTransaction(&transaction
);
4364 // Tests that we can handle cached 206 responses that are not sparse.
4365 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4366 MockHttpCache cache
;
4368 // Create a disk cache entry that stores 206 headers while not being sparse.
4369 disk_cache::Entry
* entry
;
4370 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4373 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4374 raw_headers
.append("\n");
4375 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4376 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4377 raw_headers
.size());
4379 net::HttpResponseInfo response
;
4380 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4381 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4383 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4384 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4385 kRangeGET_TransactionOK
.data
, 500));
4386 net::TestCompletionCallback cb
;
4387 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4388 EXPECT_EQ(len
, cb
.GetResult(rv
));
4391 // Now see that we don't use the stored entry.
4392 std::string headers
;
4393 net::CapturingBoundNetLog log
;
4394 net::LoadTimingInfo load_timing_info
;
4395 RunTransactionTestWithResponseAndGetTiming(
4396 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4399 // We are expecting a 200.
4400 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4401 expected_headers
.append("\n");
4402 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4403 EXPECT_EQ(expected_headers
, headers
);
4404 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4405 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4406 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4407 TestLoadTimingNetworkRequest(load_timing_info
);
4410 // Tests that we can handle cached 206 responses that are not sparse. This time
4411 // we issue a range request and expect to receive a range.
4412 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4413 MockHttpCache cache
;
4414 AddMockTransaction(&kRangeGET_TransactionOK
);
4416 // Create a disk cache entry that stores 206 headers while not being sparse.
4417 disk_cache::Entry
* entry
;
4418 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4421 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4422 raw_headers
.append("\n");
4423 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4424 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4425 raw_headers
.size());
4427 net::HttpResponseInfo response
;
4428 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4429 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4431 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4432 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4433 kRangeGET_TransactionOK
.data
, 500));
4434 net::TestCompletionCallback cb
;
4435 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4436 EXPECT_EQ(len
, cb
.GetResult(rv
));
4439 // Now see that we don't use the stored entry.
4440 std::string headers
;
4441 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4444 // We are expecting a 206.
4445 Verify206Response(headers
, 40, 49);
4446 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4447 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4448 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4450 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4453 // Tests that we can handle cached 206 responses that can't be validated.
4454 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4455 MockHttpCache cache
;
4457 // Create a disk cache entry that stores 206 headers.
4458 disk_cache::Entry
* entry
;
4459 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4462 // Make sure that the headers cannot be validated with the server.
4463 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4464 raw_headers
.append("\n");
4465 raw_headers
.append("Content-Length: 80\n");
4466 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4467 raw_headers
.size());
4469 net::HttpResponseInfo response
;
4470 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4471 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4473 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4474 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4475 kRangeGET_TransactionOK
.data
, 500));
4476 net::TestCompletionCallback cb
;
4477 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4478 EXPECT_EQ(len
, cb
.GetResult(rv
));
4481 // Now see that we don't use the stored entry.
4482 std::string headers
;
4483 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4486 // We are expecting a 200.
4487 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4488 expected_headers
.append("\n");
4489 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4490 EXPECT_EQ(expected_headers
, headers
);
4491 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4492 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4493 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4496 // Tests that we can handle range requests with cached 200 responses.
4497 TEST(HttpCache
, RangeGET_Previous200
) {
4498 MockHttpCache cache
;
4500 // Store the whole thing with status 200.
4501 MockTransaction
transaction(kTypicalGET_Transaction
);
4502 transaction
.url
= kRangeGET_TransactionOK
.url
;
4503 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4504 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4505 AddMockTransaction(&transaction
);
4506 RunTransactionTest(cache
.http_cache(), transaction
);
4507 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4508 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4509 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4511 RemoveMockTransaction(&transaction
);
4512 AddMockTransaction(&kRangeGET_TransactionOK
);
4514 // Now see that we use the stored entry.
4515 std::string headers
;
4516 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4517 RangeTransactionServer handler
;
4518 handler
.set_not_modified(true);
4519 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4521 // We are expecting a 206.
4522 Verify206Response(headers
, 40, 49);
4523 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4524 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4525 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4527 // The last transaction has finished so make sure the entry is deactivated.
4528 base::MessageLoop::current()->RunUntilIdle();
4530 // Make a request for an invalid range.
4531 MockTransaction
transaction3(kRangeGET_TransactionOK
);
4532 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
4533 transaction3
.data
= transaction
.data
;
4534 transaction3
.load_flags
= net::LOAD_PREFERRING_CACHE
;
4535 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
4536 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4537 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
4538 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
4539 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
4541 // Make sure the entry is deactivated.
4542 base::MessageLoop::current()->RunUntilIdle();
4544 // Even though the request was invalid, we should have the entry.
4545 RunTransactionTest(cache
.http_cache(), transaction2
);
4546 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4548 // Make sure the entry is deactivated.
4549 base::MessageLoop::current()->RunUntilIdle();
4551 // Now we should receive a range from the server and drop the stored entry.
4552 handler
.set_not_modified(false);
4553 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4554 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4555 Verify206Response(headers
, 40, 49);
4556 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4557 EXPECT_EQ(4, cache
.disk_cache()->open_count());
4558 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4560 RunTransactionTest(cache
.http_cache(), transaction2
);
4561 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4563 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4566 // Tests that we can handle a 200 response when dealing with sparse entries.
4567 TEST(HttpCache
, RangeRequestResultsIn200
) {
4568 MockHttpCache cache
;
4569 AddMockTransaction(&kRangeGET_TransactionOK
);
4570 std::string headers
;
4572 // Write to the cache (70-79).
4573 MockTransaction
transaction(kRangeGET_TransactionOK
);
4574 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4575 transaction
.data
= "rg: 70-79 ";
4576 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4578 Verify206Response(headers
, 70, 79);
4579 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4580 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4581 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4583 // Now we'll issue a request that results in a plain 200 response, but to
4584 // the to the same URL that we used to store sparse data, and making sure
4585 // that we ask for a range.
4586 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4587 MockTransaction
transaction2(kSimpleGET_Transaction
);
4588 transaction2
.url
= kRangeGET_TransactionOK
.url
;
4589 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4590 AddMockTransaction(&transaction2
);
4592 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4594 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4595 expected_headers
.append("\n");
4596 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4597 EXPECT_EQ(expected_headers
, headers
);
4598 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4599 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4600 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4602 RemoveMockTransaction(&transaction2
);
4605 // Tests that a range request that falls outside of the size that we know about
4606 // only deletes the entry if the resource has indeed changed.
4607 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
4608 MockHttpCache cache
;
4609 AddMockTransaction(&kRangeGET_TransactionOK
);
4610 std::string headers
;
4612 // Write to the cache (40-49).
4613 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4616 Verify206Response(headers
, 40, 49);
4617 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4618 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4619 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4621 // A weird request should not delete this entry. Ask for bytes 120-.
4622 MockTransaction
transaction(kRangeGET_TransactionOK
);
4623 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
4624 transaction
.data
= "";
4625 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4627 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
4628 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4629 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4630 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4632 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4633 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4634 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4636 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4639 // Tests that we don't delete a sparse entry when we cancel a request.
4640 TEST(HttpCache
, RangeGET_Cancel
) {
4641 MockHttpCache cache
;
4642 AddMockTransaction(&kRangeGET_TransactionOK
);
4644 MockHttpRequest
request(kRangeGET_TransactionOK
);
4646 Context
* c
= new Context();
4647 int rv
= cache
.CreateTransaction(&c
->trans
);
4648 ASSERT_EQ(net::OK
, rv
);
4650 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4651 if (rv
== net::ERR_IO_PENDING
)
4652 rv
= c
->callback
.WaitForResult();
4654 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4655 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4656 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4658 // Make sure that the entry has some data stored.
4659 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
4660 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4661 if (rv
== net::ERR_IO_PENDING
)
4662 rv
= c
->callback
.WaitForResult();
4663 EXPECT_EQ(buf
->size(), rv
);
4665 // Destroy the transaction.
4668 // Verify that the entry has not been deleted.
4669 disk_cache::Entry
* entry
;
4670 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4672 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4675 // Tests that we don't delete a sparse entry when we start a new request after
4676 // cancelling the previous one.
4677 TEST(HttpCache
, RangeGET_Cancel2
) {
4678 MockHttpCache cache
;
4679 AddMockTransaction(&kRangeGET_TransactionOK
);
4681 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4682 MockHttpRequest
request(kRangeGET_TransactionOK
);
4683 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4685 Context
* c
= new Context();
4686 int rv
= cache
.CreateTransaction(&c
->trans
);
4687 ASSERT_EQ(net::OK
, rv
);
4689 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4690 if (rv
== net::ERR_IO_PENDING
)
4691 rv
= c
->callback
.WaitForResult();
4693 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4694 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4695 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4697 // Make sure that we revalidate the entry and read from the cache (a single
4698 // read will return while waiting for the network).
4699 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
4700 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4701 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
4702 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4703 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4705 // Destroy the transaction before completing the read.
4708 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4709 // message loop. This means that a new transaction will just reuse the same
4710 // active entry (no open or create).
4712 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4714 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4715 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4716 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4717 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4720 // A slight variation of the previous test, this time we cancel two requests in
4721 // a row, making sure that the second is waiting for the entry to be ready.
4722 TEST(HttpCache
, RangeGET_Cancel3
) {
4723 MockHttpCache cache
;
4724 AddMockTransaction(&kRangeGET_TransactionOK
);
4726 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4727 MockHttpRequest
request(kRangeGET_TransactionOK
);
4728 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4730 Context
* c
= new Context();
4731 int rv
= cache
.CreateTransaction(&c
->trans
);
4732 ASSERT_EQ(net::OK
, rv
);
4734 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4735 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4736 rv
= c
->callback
.WaitForResult();
4738 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4739 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4740 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4742 // Make sure that we revalidate the entry and read from the cache (a single
4743 // read will return while waiting for the network).
4744 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
4745 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4746 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
4747 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4748 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4750 // Destroy the transaction before completing the read.
4753 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4754 // message loop. This means that a new transaction will just reuse the same
4755 // active entry (no open or create).
4758 rv
= cache
.CreateTransaction(&c
->trans
);
4759 ASSERT_EQ(net::OK
, rv
);
4761 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4762 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4764 MockDiskEntry::IgnoreCallbacks(true);
4765 base::MessageLoop::current()->RunUntilIdle();
4766 MockDiskEntry::IgnoreCallbacks(false);
4768 // The new transaction is waiting for the query range callback.
4771 // And we should not crash when the callback is delivered.
4772 base::MessageLoop::current()->RunUntilIdle();
4774 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4775 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4776 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4777 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4780 // Tests that an invalid range response results in no cached entry.
4781 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
4782 MockHttpCache cache
;
4783 std::string headers
;
4785 MockTransaction
transaction(kRangeGET_TransactionOK
);
4786 transaction
.handler
= NULL
;
4787 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
4788 "Content-Length: 10\n";
4789 AddMockTransaction(&transaction
);
4790 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4792 std::string
expected(transaction
.status
);
4793 expected
.append("\n");
4794 expected
.append(transaction
.response_headers
);
4795 EXPECT_EQ(expected
, headers
);
4797 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4798 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4799 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4801 // Verify that we don't have a cached entry.
4802 disk_cache::Entry
* entry
;
4803 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4805 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4808 // Tests that we reject a range that doesn't match the content-length.
4809 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
4810 MockHttpCache cache
;
4811 std::string headers
;
4813 MockTransaction
transaction(kRangeGET_TransactionOK
);
4814 transaction
.handler
= NULL
;
4815 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
4816 "Content-Length: 20\n";
4817 AddMockTransaction(&transaction
);
4818 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4820 std::string
expected(transaction
.status
);
4821 expected
.append("\n");
4822 expected
.append(transaction
.response_headers
);
4823 EXPECT_EQ(expected
, headers
);
4825 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4826 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4827 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4829 // Verify that we don't have a cached entry.
4830 disk_cache::Entry
* entry
;
4831 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4833 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4836 // Tests that if a server tells us conflicting information about a resource we
4837 // ignore the response.
4838 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
4839 MockHttpCache cache
;
4840 std::string headers
;
4842 MockTransaction
transaction(kRangeGET_TransactionOK
);
4843 transaction
.handler
= NULL
;
4844 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
4845 std::string
response_headers(transaction
.response_headers
);
4846 response_headers
.append("Content-Range: bytes 50-59/160\n");
4847 transaction
.response_headers
= response_headers
.c_str();
4848 AddMockTransaction(&transaction
);
4849 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4851 Verify206Response(headers
, 50, 59);
4852 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4853 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4854 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4856 RemoveMockTransaction(&transaction
);
4857 AddMockTransaction(&kRangeGET_TransactionOK
);
4859 // This transaction will report a resource size of 80 bytes, and we think it's
4860 // 160 so we should ignore the response.
4861 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4864 Verify206Response(headers
, 40, 49);
4865 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4866 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4867 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4869 // Verify that we cached the first response but not the second one.
4870 disk_cache::Entry
* en
;
4871 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
4873 int64 cached_start
= 0;
4874 net::TestCompletionCallback cb
;
4875 int rv
= en
->GetAvailableRange(40, 20, &cached_start
, cb
.callback());
4876 EXPECT_EQ(10, cb
.GetResult(rv
));
4877 EXPECT_EQ(50, cached_start
);
4880 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4883 // Tests that we handle large range values properly.
4884 TEST(HttpCache
, RangeGET_LargeValues
) {
4885 // We need a real sparse cache for this test.
4886 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4887 std::string headers
;
4889 MockTransaction
transaction(kRangeGET_TransactionOK
);
4890 transaction
.handler
= NULL
;
4891 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
4893 transaction
.response_headers
=
4895 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4896 "Content-Length: 10\n";
4897 AddMockTransaction(&transaction
);
4898 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4900 std::string
expected(transaction
.status
);
4901 expected
.append("\n");
4902 expected
.append(transaction
.response_headers
);
4903 EXPECT_EQ(expected
, headers
);
4905 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4907 // Verify that we have a cached entry.
4908 disk_cache::Entry
* en
;
4909 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
4912 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4915 // Tests that we don't crash with a range request if the disk cache was not
4916 // initialized properly.
4917 TEST(HttpCache
, RangeGET_NoDiskCache
) {
4918 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
4919 factory
->set_fail(true);
4920 factory
->FinishCreation(); // We'll complete synchronously.
4921 MockHttpCache
cache(factory
);
4923 AddMockTransaction(&kRangeGET_TransactionOK
);
4925 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4926 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4928 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4931 // Tests that we handle byte range requests that skip the cache.
4932 TEST(HttpCache
, RangeHEAD
) {
4933 MockHttpCache cache
;
4934 AddMockTransaction(&kRangeGET_TransactionOK
);
4936 MockTransaction
transaction(kRangeGET_TransactionOK
);
4937 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4938 transaction
.method
= "HEAD";
4939 transaction
.data
= "rg: 70-79 ";
4941 std::string headers
;
4942 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4944 Verify206Response(headers
, 70, 79);
4945 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4946 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4947 EXPECT_EQ(0, cache
.disk_cache()->create_count());
4949 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4952 // Tests that we don't crash when after reading from the cache we issue a
4953 // request for the next range and the server gives us a 200 synchronously.
4954 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
4955 MockHttpCache cache
;
4957 MockTransaction
transaction(kRangeGET_TransactionOK
);
4958 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
4959 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
4960 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4961 AddMockTransaction(&transaction
);
4963 // Write to the cache.
4964 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4966 // And now read from the cache and the network.
4967 RangeTransactionServer handler
;
4968 handler
.set_bad_200(true);
4969 transaction
.data
= "Not a range";
4970 RunTransactionTest(cache
.http_cache(), transaction
);
4972 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4973 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4974 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4976 RemoveMockTransaction(&transaction
);
4979 // Tests that when the server gives us less data than expected, we don't keep
4980 // asking for more data.
4981 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
4982 MockHttpCache cache
;
4984 // First, check with an empty cache (WRITE mode).
4985 MockTransaction
transaction(kRangeGET_TransactionOK
);
4986 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
4987 transaction
.data
= "rg: 40-"; // Less than expected.
4988 transaction
.handler
= NULL
;
4989 std::string
headers(transaction
.response_headers
);
4990 headers
.append("Content-Range: bytes 40-49/80\n");
4991 transaction
.response_headers
= headers
.c_str();
4993 AddMockTransaction(&transaction
);
4995 // Write to the cache.
4996 RunTransactionTest(cache
.http_cache(), transaction
);
4998 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4999 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5000 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5002 // Now verify that even in READ_WRITE mode, we forward the bad response to
5004 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5005 transaction
.data
= "rg: 60-"; // Less than expected.
5006 headers
= kRangeGET_TransactionOK
.response_headers
;
5007 headers
.append("Content-Range: bytes 60-69/80\n");
5008 transaction
.response_headers
= headers
.c_str();
5010 RunTransactionTest(cache
.http_cache(), transaction
);
5012 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5013 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5014 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5016 RemoveMockTransaction(&transaction
);
5019 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5020 // This test hits a NOTREACHED so it is a release mode only test.
5021 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5022 MockHttpCache cache
;
5023 AddMockTransaction(&kRangeGET_TransactionOK
);
5025 // Write to the cache (40-49).
5026 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5027 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5028 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5029 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5031 // Force this transaction to read from the cache.
5032 MockTransaction
transaction(kRangeGET_TransactionOK
);
5033 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5035 MockHttpRequest
request(transaction
);
5036 net::TestCompletionCallback callback
;
5038 scoped_ptr
<net::HttpTransaction
> trans
;
5039 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
5040 EXPECT_EQ(net::OK
, rv
);
5041 ASSERT_TRUE(trans
.get());
5043 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5044 if (rv
== net::ERR_IO_PENDING
)
5045 rv
= callback
.WaitForResult();
5046 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5050 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5051 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5052 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5054 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5058 // Tests the handling of the "truncation" flag.
5059 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5060 MockHttpCache cache
;
5061 disk_cache::Entry
* entry
;
5062 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5065 std::string
headers("HTTP/1.1 200 OK");
5066 headers
= net::HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5067 net::HttpResponseInfo response
;
5068 response
.headers
= new net::HttpResponseHeaders(headers
);
5070 // Set the last argument for this to be an incomplete request.
5071 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5072 bool truncated
= false;
5073 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5074 EXPECT_TRUE(truncated
);
5076 // And now test the opposite case.
5077 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5079 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5080 EXPECT_FALSE(truncated
);
5084 // Tests basic pickling/unpickling of HttpResponseInfo.
5085 TEST(HttpCache
, PersistHttpResponseInfo
) {
5086 // Set some fields (add more if needed.)
5087 net::HttpResponseInfo response1
;
5088 response1
.was_cached
= false;
5089 response1
.socket_address
= net::HostPortPair("1.2.3.4", 80);
5090 response1
.headers
= new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5094 response1
.Persist(&pickle
, false, false);
5097 net::HttpResponseInfo response2
;
5098 bool response_truncated
;
5099 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5100 EXPECT_FALSE(response_truncated
);
5103 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5104 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5105 EXPECT_EQ(80, response2
.socket_address
.port());
5106 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5109 // Tests that we delete an entry when the request is cancelled before starting
5110 // to read from the network.
5111 TEST(HttpCache
, DoomOnDestruction
) {
5112 MockHttpCache cache
;
5114 MockHttpRequest
request(kSimpleGET_Transaction
);
5116 Context
* c
= new Context();
5117 int rv
= cache
.CreateTransaction(&c
->trans
);
5118 ASSERT_EQ(net::OK
, rv
);
5120 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5121 if (rv
== net::ERR_IO_PENDING
)
5122 c
->result
= c
->callback
.WaitForResult();
5124 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5125 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5126 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5128 // Destroy the transaction. We only have the headers so we should delete this
5132 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5134 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5135 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5136 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5139 // Tests that we delete an entry when the request is cancelled if the response
5140 // does not have content-length and strong validators.
5141 TEST(HttpCache
, DoomOnDestruction2
) {
5142 MockHttpCache cache
;
5144 MockHttpRequest
request(kSimpleGET_Transaction
);
5146 Context
* c
= new Context();
5147 int rv
= cache
.CreateTransaction(&c
->trans
);
5148 ASSERT_EQ(net::OK
, rv
);
5150 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5151 if (rv
== net::ERR_IO_PENDING
)
5152 rv
= c
->callback
.WaitForResult();
5154 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5155 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5156 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5158 // Make sure that the entry has some data stored.
5159 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5160 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5161 if (rv
== net::ERR_IO_PENDING
)
5162 rv
= c
->callback
.WaitForResult();
5163 EXPECT_EQ(buf
->size(), rv
);
5165 // Destroy the transaction.
5168 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5170 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5171 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5172 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5175 // Tests that we delete an entry when the request is cancelled if the response
5176 // has an "Accept-Ranges: none" header.
5177 TEST(HttpCache
, DoomOnDestruction3
) {
5178 MockHttpCache cache
;
5180 MockTransaction
transaction(kSimpleGET_Transaction
);
5181 transaction
.response_headers
=
5182 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5183 "Content-Length: 22\n"
5184 "Accept-Ranges: none\n"
5185 "Etag: \"foopy\"\n";
5186 AddMockTransaction(&transaction
);
5187 MockHttpRequest
request(transaction
);
5189 Context
* c
= new Context();
5190 int rv
= cache
.CreateTransaction(&c
->trans
);
5191 ASSERT_EQ(net::OK
, rv
);
5193 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5194 if (rv
== net::ERR_IO_PENDING
)
5195 rv
= c
->callback
.WaitForResult();
5197 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5198 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5199 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5201 // Make sure that the entry has some data stored.
5202 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5203 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5204 if (rv
== net::ERR_IO_PENDING
)
5205 rv
= c
->callback
.WaitForResult();
5206 EXPECT_EQ(buf
->size(), rv
);
5208 // Destroy the transaction.
5211 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5213 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5214 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5215 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5217 RemoveMockTransaction(&transaction
);
5220 // Tests that we mark an entry as incomplete when the request is cancelled.
5221 TEST(HttpCache
, SetTruncatedFlag
) {
5222 MockHttpCache cache
;
5224 MockTransaction
transaction(kSimpleGET_Transaction
);
5225 transaction
.response_headers
=
5226 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5227 "Content-Length: 22\n"
5228 "Etag: \"foopy\"\n";
5229 AddMockTransaction(&transaction
);
5230 MockHttpRequest
request(transaction
);
5232 scoped_ptr
<Context
> c(new Context());
5234 int rv
= cache
.CreateTransaction(&c
->trans
);
5235 ASSERT_EQ(net::OK
, rv
);
5237 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5238 if (rv
== net::ERR_IO_PENDING
)
5239 rv
= c
->callback
.WaitForResult();
5241 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5242 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5243 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5245 // Make sure that the entry has some data stored.
5246 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5247 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5248 if (rv
== net::ERR_IO_PENDING
)
5249 rv
= c
->callback
.WaitForResult();
5250 EXPECT_EQ(buf
->size(), rv
);
5252 // We want to cancel the request when the transaction is busy.
5253 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5254 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5255 EXPECT_FALSE(c
->callback
.have_result());
5257 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5259 // Destroy the transaction.
5261 MockHttpCache::SetTestMode(0);
5264 // Make sure that we don't invoke the callback. We may have an issue if the
5265 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5266 // could end up with the transaction being deleted twice if we send any
5267 // notification from the transaction destructor (see http://crbug.com/31723).
5268 EXPECT_FALSE(c
->callback
.have_result());
5270 // Verify that the entry is marked as incomplete.
5271 disk_cache::Entry
* entry
;
5272 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5273 net::HttpResponseInfo response
;
5274 bool truncated
= false;
5275 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5276 EXPECT_TRUE(truncated
);
5279 RemoveMockTransaction(&transaction
);
5282 // Tests that we don't mark an entry as truncated when we read everything.
5283 TEST(HttpCache
, DontSetTruncatedFlag
) {
5284 MockHttpCache cache
;
5286 MockTransaction
transaction(kSimpleGET_Transaction
);
5287 transaction
.response_headers
=
5288 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5289 "Content-Length: 22\n"
5290 "Etag: \"foopy\"\n";
5291 AddMockTransaction(&transaction
);
5292 MockHttpRequest
request(transaction
);
5294 scoped_ptr
<Context
> c(new Context());
5295 int rv
= cache
.CreateTransaction(&c
->trans
);
5296 ASSERT_EQ(net::OK
, rv
);
5298 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5299 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5302 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(22));
5303 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5304 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5306 // Destroy the transaction.
5309 // Verify that the entry is not marked as truncated.
5310 disk_cache::Entry
* entry
;
5311 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5312 net::HttpResponseInfo response
;
5313 bool truncated
= true;
5314 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5315 EXPECT_FALSE(truncated
);
5318 RemoveMockTransaction(&transaction
);
5321 // Tests that we can continue with a request that was interrupted.
5322 TEST(HttpCache
, GET_IncompleteResource
) {
5323 MockHttpCache cache
;
5324 AddMockTransaction(&kRangeGET_TransactionOK
);
5326 std::string
raw_headers("HTTP/1.1 200 OK\n"
5327 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5329 "Accept-Ranges: bytes\n"
5330 "Content-Length: 80\n");
5331 CreateTruncatedEntry(raw_headers
, &cache
);
5333 // Now make a regular request.
5334 std::string headers
;
5335 MockTransaction
transaction(kRangeGET_TransactionOK
);
5336 transaction
.request_headers
= EXTRA_HEADER
;
5337 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5338 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5339 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5341 // We update the headers with the ones received while revalidating.
5342 std::string
expected_headers(
5344 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5345 "Accept-Ranges: bytes\n"
5347 "Content-Length: 80\n");
5349 EXPECT_EQ(expected_headers
, headers
);
5350 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5351 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5352 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5354 // Verify that the disk entry was updated.
5355 disk_cache::Entry
* entry
;
5356 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5357 EXPECT_EQ(80, entry
->GetDataSize(1));
5358 bool truncated
= true;
5359 net::HttpResponseInfo response
;
5360 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5361 EXPECT_FALSE(truncated
);
5364 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5367 // Tests the handling of no-store when revalidating a truncated entry.
5368 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5369 MockHttpCache cache
;
5370 AddMockTransaction(&kRangeGET_TransactionOK
);
5372 std::string
raw_headers("HTTP/1.1 200 OK\n"
5373 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5375 "Accept-Ranges: bytes\n"
5376 "Content-Length: 80\n");
5377 CreateTruncatedEntry(raw_headers
, &cache
);
5378 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5380 // Now make a regular request.
5381 MockTransaction
transaction(kRangeGET_TransactionOK
);
5382 transaction
.request_headers
= EXTRA_HEADER
;
5383 std::string
response_headers(transaction
.response_headers
);
5384 response_headers
+= ("Cache-Control: no-store\n");
5385 transaction
.response_headers
= response_headers
.c_str();
5386 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5387 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5388 AddMockTransaction(&transaction
);
5390 std::string headers
;
5391 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5393 // We update the headers with the ones received while revalidating.
5394 std::string
expected_headers(
5396 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5397 "Accept-Ranges: bytes\n"
5398 "Cache-Control: no-store\n"
5400 "Content-Length: 80\n");
5402 EXPECT_EQ(expected_headers
, headers
);
5403 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5404 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5405 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5407 // Verify that the disk entry was deleted.
5408 disk_cache::Entry
* entry
;
5409 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5410 RemoveMockTransaction(&transaction
);
5413 // Tests cancelling a request after the server sent no-store.
5414 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5415 MockHttpCache cache
;
5416 AddMockTransaction(&kRangeGET_TransactionOK
);
5418 std::string
raw_headers("HTTP/1.1 200 OK\n"
5419 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5421 "Accept-Ranges: bytes\n"
5422 "Content-Length: 80\n");
5423 CreateTruncatedEntry(raw_headers
, &cache
);
5424 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5426 // Now make a regular request.
5427 MockTransaction
transaction(kRangeGET_TransactionOK
);
5428 transaction
.request_headers
= EXTRA_HEADER
;
5429 std::string
response_headers(transaction
.response_headers
);
5430 response_headers
+= ("Cache-Control: no-store\n");
5431 transaction
.response_headers
= response_headers
.c_str();
5432 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5433 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5434 AddMockTransaction(&transaction
);
5436 MockHttpRequest
request(transaction
);
5437 Context
* c
= new Context();
5439 int rv
= cache
.CreateTransaction(&c
->trans
);
5440 ASSERT_EQ(net::OK
, rv
);
5442 // Queue another request to this transaction. We have to start this request
5443 // before the first one gets the response from the server and dooms the entry,
5444 // otherwise it will just create a new entry without being queued to the first
5446 Context
* pending
= new Context();
5447 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&pending
->trans
));
5449 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5450 EXPECT_EQ(net::ERR_IO_PENDING
,
5451 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5452 net::BoundNetLog()));
5453 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5455 // Make sure that the entry has some data stored.
5456 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5457 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5458 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5460 // Cancel the requests.
5464 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5465 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5466 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5468 base::MessageLoop::current()->RunUntilIdle();
5469 RemoveMockTransaction(&transaction
);
5472 // Tests that we delete truncated entries if the server changes its mind midway.
5473 TEST(HttpCache
, GET_IncompleteResource2
) {
5474 MockHttpCache cache
;
5475 AddMockTransaction(&kRangeGET_TransactionOK
);
5477 // Content-length will be intentionally bad.
5478 std::string
raw_headers("HTTP/1.1 200 OK\n"
5479 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5481 "Accept-Ranges: bytes\n"
5482 "Content-Length: 50\n");
5483 CreateTruncatedEntry(raw_headers
, &cache
);
5485 // Now make a regular request. We expect the code to fail the validation and
5486 // retry the request without using byte ranges.
5487 std::string headers
;
5488 MockTransaction
transaction(kRangeGET_TransactionOK
);
5489 transaction
.request_headers
= EXTRA_HEADER
;
5490 transaction
.data
= "Not a range";
5491 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5493 // The server will return 200 instead of a byte range.
5494 std::string
expected_headers(
5496 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5498 EXPECT_EQ(expected_headers
, headers
);
5499 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5500 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5501 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5503 // Verify that the disk entry was deleted.
5504 disk_cache::Entry
* entry
;
5505 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5506 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5509 // Tests that we always validate a truncated request.
5510 TEST(HttpCache
, GET_IncompleteResource3
) {
5511 MockHttpCache cache
;
5512 AddMockTransaction(&kRangeGET_TransactionOK
);
5514 // This should not require validation for 10 hours.
5515 std::string
raw_headers("HTTP/1.1 200 OK\n"
5516 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5518 "Cache-Control: max-age= 36000\n"
5519 "Accept-Ranges: bytes\n"
5520 "Content-Length: 80\n");
5521 CreateTruncatedEntry(raw_headers
, &cache
);
5523 // Now make a regular request.
5524 std::string headers
;
5525 MockTransaction
transaction(kRangeGET_TransactionOK
);
5526 transaction
.request_headers
= EXTRA_HEADER
;
5527 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5528 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5530 scoped_ptr
<Context
> c(new Context
);
5531 int rv
= cache
.CreateTransaction(&c
->trans
);
5532 ASSERT_EQ(net::OK
, rv
);
5534 MockHttpRequest
request(transaction
);
5535 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5536 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5538 // We should have checked with the server before finishing Start().
5539 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5540 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5541 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5543 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5546 // Tests that we handle 401s for truncated resources.
5547 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
5548 MockHttpCache cache
;
5549 AddMockTransaction(&kRangeGET_TransactionOK
);
5551 std::string
raw_headers("HTTP/1.1 200 OK\n"
5552 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5554 "Accept-Ranges: bytes\n"
5555 "Content-Length: 80\n");
5556 CreateTruncatedEntry(raw_headers
, &cache
);
5558 // Now make a regular request.
5559 MockTransaction
transaction(kRangeGET_TransactionOK
);
5560 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
5562 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5563 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5564 RangeTransactionServer handler
;
5566 scoped_ptr
<Context
> c(new Context
);
5567 int rv
= cache
.CreateTransaction(&c
->trans
);
5568 ASSERT_EQ(net::OK
, rv
);
5570 MockHttpRequest
request(transaction
);
5571 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5572 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5574 const net::HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
5575 ASSERT_TRUE(response
);
5576 ASSERT_EQ(401, response
->headers
->response_code());
5577 rv
= c
->trans
->RestartWithAuth(net::AuthCredentials(),
5578 c
->callback
.callback());
5579 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5580 response
= c
->trans
->GetResponseInfo();
5581 ASSERT_TRUE(response
);
5582 ASSERT_EQ(200, response
->headers
->response_code());
5584 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
5585 c
.reset(); // The destructor could delete the entry.
5586 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5588 // Verify that the entry was not deleted.
5589 disk_cache::Entry
* entry
;
5590 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5593 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5596 // Tests that we cache a 200 response to the validation request.
5597 TEST(HttpCache
, GET_IncompleteResource4
) {
5598 MockHttpCache cache
;
5599 AddMockTransaction(&kRangeGET_TransactionOK
);
5601 std::string
raw_headers("HTTP/1.1 200 OK\n"
5602 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5604 "Accept-Ranges: bytes\n"
5605 "Content-Length: 80\n");
5606 CreateTruncatedEntry(raw_headers
, &cache
);
5608 // Now make a regular request.
5609 std::string headers
;
5610 MockTransaction
transaction(kRangeGET_TransactionOK
);
5611 transaction
.request_headers
= EXTRA_HEADER
;
5612 transaction
.data
= "Not a range";
5613 RangeTransactionServer handler
;
5614 handler
.set_bad_200(true);
5615 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5617 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5618 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5619 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5621 // Verify that the disk entry was updated.
5622 disk_cache::Entry
* entry
;
5623 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5624 EXPECT_EQ(11, entry
->GetDataSize(1));
5625 bool truncated
= true;
5626 net::HttpResponseInfo response
;
5627 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5628 EXPECT_FALSE(truncated
);
5631 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5634 // Tests that when we cancel a request that was interrupted, we mark it again
5636 TEST(HttpCache
, GET_CancelIncompleteResource
) {
5637 MockHttpCache cache
;
5638 AddMockTransaction(&kRangeGET_TransactionOK
);
5640 std::string
raw_headers("HTTP/1.1 200 OK\n"
5641 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5643 "Accept-Ranges: bytes\n"
5644 "Content-Length: 80\n");
5645 CreateTruncatedEntry(raw_headers
, &cache
);
5647 // Now make a regular request.
5648 MockTransaction
transaction(kRangeGET_TransactionOK
);
5649 transaction
.request_headers
= EXTRA_HEADER
;
5651 MockHttpRequest
request(transaction
);
5652 Context
* c
= new Context();
5653 int rv
= cache
.CreateTransaction(&c
->trans
);
5654 ASSERT_EQ(net::OK
, rv
);
5656 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5657 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5659 // Read 20 bytes from the cache, and 10 from the net.
5660 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
5661 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
5662 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
5663 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
5664 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
5666 // At this point, we are already reading so canceling the request should leave
5670 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5671 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5672 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5674 // Verify that the disk entry was updated: now we have 30 bytes.
5675 disk_cache::Entry
* entry
;
5676 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5677 EXPECT_EQ(30, entry
->GetDataSize(1));
5678 bool truncated
= false;
5679 net::HttpResponseInfo response
;
5680 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5681 EXPECT_TRUE(truncated
);
5683 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5686 // Tests that we can handle range requests when we have a truncated entry.
5687 TEST(HttpCache
, RangeGET_IncompleteResource
) {
5688 MockHttpCache cache
;
5689 AddMockTransaction(&kRangeGET_TransactionOK
);
5691 // Content-length will be intentionally bogus.
5692 std::string
raw_headers("HTTP/1.1 200 OK\n"
5693 "Last-Modified: something\n"
5695 "Accept-Ranges: bytes\n"
5696 "Content-Length: 10\n");
5697 CreateTruncatedEntry(raw_headers
, &cache
);
5699 // Now make a range request.
5700 std::string headers
;
5701 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5704 Verify206Response(headers
, 40, 49);
5705 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5706 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5707 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5709 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5712 TEST(HttpCache
, SyncRead
) {
5713 MockHttpCache cache
;
5715 // This test ensures that a read that completes synchronously does not cause
5718 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5719 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
5720 TEST_MODE_SYNC_CACHE_READ
|
5721 TEST_MODE_SYNC_CACHE_WRITE
);
5723 MockHttpRequest
r1(transaction
),
5727 TestTransactionConsumer
c1(net::DEFAULT_PRIORITY
, cache
.http_cache()),
5728 c2(net::DEFAULT_PRIORITY
, cache
.http_cache()),
5729 c3(net::DEFAULT_PRIORITY
, cache
.http_cache());
5731 c1
.Start(&r1
, net::BoundNetLog());
5733 r2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5734 c2
.Start(&r2
, net::BoundNetLog());
5736 r3
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5737 c3
.Start(&r3
, net::BoundNetLog());
5739 base::MessageLoop::current()->Run();
5741 EXPECT_TRUE(c1
.is_done());
5742 EXPECT_TRUE(c2
.is_done());
5743 EXPECT_TRUE(c3
.is_done());
5745 EXPECT_EQ(net::OK
, c1
.error());
5746 EXPECT_EQ(net::OK
, c2
.error());
5747 EXPECT_EQ(net::OK
, c3
.error());
5750 TEST(HttpCache
, ValidationResultsIn200
) {
5751 MockHttpCache cache
;
5753 // This test ensures that a conditional request, which results in a 200
5754 // instead of a 304, properly truncates the existing response data.
5756 // write to the cache
5757 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
5759 // force this transaction to validate the cache
5760 MockTransaction
transaction(kETagGET_Transaction
);
5761 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5762 RunTransactionTest(cache
.http_cache(), transaction
);
5764 // read from the cache
5765 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
5768 TEST(HttpCache
, CachedRedirect
) {
5769 MockHttpCache cache
;
5771 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
5772 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
5773 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
5775 MockHttpRequest
request(kTestTransaction
);
5776 net::TestCompletionCallback callback
;
5778 // Write to the cache.
5780 scoped_ptr
<net::HttpTransaction
> trans
;
5781 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5783 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5784 if (rv
== net::ERR_IO_PENDING
)
5785 rv
= callback
.WaitForResult();
5786 ASSERT_EQ(net::OK
, rv
);
5788 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
5791 EXPECT_EQ(info
->headers
->response_code(), 301);
5793 std::string location
;
5794 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
5795 EXPECT_EQ(location
, "http://www.bar.com/");
5797 // Mark the transaction as completed so it is cached.
5798 trans
->DoneReading();
5800 // Destroy transaction when going out of scope. We have not actually
5801 // read the response body -- want to test that it is still getting cached.
5803 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5804 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5805 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5807 // Active entries in the cache are not retired synchronously. Make
5808 // sure the next run hits the MockHttpCache and open_count is
5810 base::MessageLoop::current()->RunUntilIdle();
5812 // Read from the cache.
5814 scoped_ptr
<net::HttpTransaction
> trans
;
5815 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5817 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5818 if (rv
== net::ERR_IO_PENDING
)
5819 rv
= callback
.WaitForResult();
5820 ASSERT_EQ(net::OK
, rv
);
5822 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
5825 EXPECT_EQ(info
->headers
->response_code(), 301);
5827 std::string location
;
5828 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
5829 EXPECT_EQ(location
, "http://www.bar.com/");
5831 // Mark the transaction as completed so it is cached.
5832 trans
->DoneReading();
5834 // Destroy transaction when going out of scope. We have not actually
5835 // read the response body -- want to test that it is still getting cached.
5837 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5838 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5839 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5842 // Verify that no-cache resources are stored in cache, but are not fetched from
5843 // cache during normal loads.
5844 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
5845 MockHttpCache cache
;
5847 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5848 transaction
.response_headers
= "cache-control: no-cache\n";
5851 RunTransactionTest(cache
.http_cache(), transaction
);
5853 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5854 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5855 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5857 // Try loading again; it should result in a network fetch.
5858 RunTransactionTest(cache
.http_cache(), transaction
);
5860 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5861 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5862 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5864 disk_cache::Entry
* entry
;
5865 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5869 // Verify that no-cache resources are stored in cache and fetched from cache
5870 // when the LOAD_PREFERRING_CACHE flag is set.
5871 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
5872 MockHttpCache cache
;
5874 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5875 transaction
.response_headers
= "cache-control: no-cache\n";
5878 RunTransactionTest(cache
.http_cache(), transaction
);
5880 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5881 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5882 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5884 // Try loading again with LOAD_PREFERRING_CACHE.
5885 transaction
.load_flags
= net::LOAD_PREFERRING_CACHE
;
5886 RunTransactionTest(cache
.http_cache(), transaction
);
5888 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5889 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5890 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5892 disk_cache::Entry
* entry
;
5893 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5897 TEST(HttpCache
, CacheControlNoStore
) {
5898 MockHttpCache cache
;
5900 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5901 transaction
.response_headers
= "cache-control: no-store\n";
5904 RunTransactionTest(cache
.http_cache(), transaction
);
5906 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5907 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5908 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5910 // try loading again; it should result in a network fetch
5911 RunTransactionTest(cache
.http_cache(), transaction
);
5913 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5914 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5915 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5917 disk_cache::Entry
* entry
;
5918 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5921 TEST(HttpCache
, CacheControlNoStore2
) {
5922 // this test is similar to the above test, except that the initial response
5923 // is cachable, but when it is validated, no-store is received causing the
5924 // cached document to be deleted.
5925 MockHttpCache cache
;
5927 ScopedMockTransaction
transaction(kETagGET_Transaction
);
5930 RunTransactionTest(cache
.http_cache(), transaction
);
5932 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5933 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5934 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5936 // try loading again; it should result in a network fetch
5937 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
5938 transaction
.response_headers
= "cache-control: no-store\n";
5939 RunTransactionTest(cache
.http_cache(), transaction
);
5941 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5942 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5943 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5945 disk_cache::Entry
* entry
;
5946 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5949 TEST(HttpCache
, CacheControlNoStore3
) {
5950 // this test is similar to the above test, except that the response is a 304
5951 // instead of a 200. this should never happen in practice, but it seems like
5952 // a good thing to verify that we still destroy the cache entry.
5953 MockHttpCache cache
;
5955 ScopedMockTransaction
transaction(kETagGET_Transaction
);
5958 RunTransactionTest(cache
.http_cache(), transaction
);
5960 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5961 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5962 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5964 // try loading again; it should result in a network fetch
5965 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
5966 transaction
.response_headers
= "cache-control: no-store\n";
5967 transaction
.status
= "HTTP/1.1 304 Not Modified";
5968 RunTransactionTest(cache
.http_cache(), transaction
);
5970 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5971 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5972 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5974 disk_cache::Entry
* entry
;
5975 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5978 // Ensure that we don't cache requests served over bad HTTPS.
5979 TEST(HttpCache
, SimpleGET_SSLError
) {
5980 MockHttpCache cache
;
5982 MockTransaction transaction
= kSimpleGET_Transaction
;
5983 transaction
.cert_status
= net::CERT_STATUS_REVOKED
;
5984 ScopedMockTransaction
scoped_transaction(transaction
);
5986 // write to the cache
5987 RunTransactionTest(cache
.http_cache(), transaction
);
5989 // Test that it was not cached.
5990 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5992 MockHttpRequest
request(transaction
);
5993 net::TestCompletionCallback callback
;
5995 scoped_ptr
<net::HttpTransaction
> trans
;
5996 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5998 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5999 if (rv
== net::ERR_IO_PENDING
)
6000 rv
= callback
.WaitForResult();
6001 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
6004 // Ensure that we don't crash by if left-behind transactions.
6005 TEST(HttpCache
, OutlivedTransactions
) {
6006 MockHttpCache
* cache
= new MockHttpCache
;
6008 scoped_ptr
<net::HttpTransaction
> trans
;
6009 EXPECT_EQ(net::OK
, cache
->CreateTransaction(&trans
));
6015 // Test that the disabled mode works.
6016 TEST(HttpCache
, CacheDisabledMode
) {
6017 MockHttpCache cache
;
6019 // write to the cache
6020 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6022 // go into disabled mode
6023 cache
.http_cache()->set_mode(net::HttpCache::DISABLE
);
6025 // force this transaction to write to the cache again
6026 MockTransaction
transaction(kSimpleGET_Transaction
);
6028 RunTransactionTest(cache
.http_cache(), transaction
);
6030 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6031 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6032 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6035 // Other tests check that the response headers of the cached response
6036 // get updated on 304. Here we specifically check that the
6037 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6038 // fields also gets updated.
6039 // http://crbug.com/20594.
6040 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6041 MockHttpCache cache
;
6043 const char* kUrl
= "http://foobar";
6044 const char* kData
= "body";
6046 MockTransaction mock_network_response
= { 0 };
6047 mock_network_response
.url
= kUrl
;
6049 AddMockTransaction(&mock_network_response
);
6051 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6053 MockTransaction request
= { 0 };
6055 request
.method
= "GET";
6056 request
.request_headers
= "\r\n";
6057 request
.data
= kData
;
6059 static const Response kNetResponse1
= {
6061 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6062 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6066 kNetResponse1
.AssignTo(&mock_network_response
);
6068 RunTransactionTest(cache
.http_cache(), request
);
6070 // Request |kUrl| again, this time validating the cache and getting
6073 request
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6075 static const Response kNetResponse2
= {
6076 "HTTP/1.1 304 Not Modified",
6077 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6081 kNetResponse2
.AssignTo(&mock_network_response
);
6083 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6084 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6086 mock_network_response
.request_time
= request_time
;
6087 mock_network_response
.response_time
= response_time
;
6089 net::HttpResponseInfo response
;
6090 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6092 // The request and response times should have been updated.
6093 EXPECT_EQ(request_time
.ToInternalValue(),
6094 response
.request_time
.ToInternalValue());
6095 EXPECT_EQ(response_time
.ToInternalValue(),
6096 response
.response_time
.ToInternalValue());
6098 std::string headers
;
6099 response
.headers
->GetNormalizedHeaders(&headers
);
6101 EXPECT_EQ("HTTP/1.1 200 OK\n"
6102 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6103 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6106 RemoveMockTransaction(&mock_network_response
);
6109 // Tests that we can write metadata to an entry.
6110 TEST(HttpCache
, WriteMetadata_OK
) {
6111 MockHttpCache cache
;
6113 // Write to the cache
6114 net::HttpResponseInfo response
;
6115 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6117 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6120 cache
.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY
,
6121 Time::Now(), NULL
, 0);
6123 // Write meta data to the same entry.
6124 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6125 memset(buf
->data(), 0, buf
->size());
6126 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6127 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6128 net::DEFAULT_PRIORITY
,
6129 response
.response_time
,
6133 // Release the buffer before the operation takes place.
6136 // Makes sure we finish pending operations.
6137 base::MessageLoop::current()->RunUntilIdle();
6139 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6141 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6142 EXPECT_EQ(50, response
.metadata
->size());
6143 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6145 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6146 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6147 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6150 // Tests that we only write metadata to an entry if the time stamp matches.
6151 TEST(HttpCache
, WriteMetadata_Fail
) {
6152 MockHttpCache cache
;
6154 // Write to the cache
6155 net::HttpResponseInfo response
;
6156 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6158 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6160 // Attempt to write meta data to the same entry.
6161 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6162 memset(buf
->data(), 0, buf
->size());
6163 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6164 base::Time expected_time
= response
.response_time
-
6165 base::TimeDelta::FromMilliseconds(20);
6166 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6167 net::DEFAULT_PRIORITY
,
6172 // Makes sure we finish pending operations.
6173 base::MessageLoop::current()->RunUntilIdle();
6175 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6177 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6179 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6180 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6181 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6184 // Tests that we can read metadata after validating the entry and with READ mode
6186 TEST(HttpCache
, ReadMetadata
) {
6187 MockHttpCache cache
;
6189 // Write to the cache
6190 net::HttpResponseInfo response
;
6191 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6192 kTypicalGET_Transaction
, &response
);
6193 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6195 // Write meta data to the same entry.
6196 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6197 memset(buf
->data(), 0, buf
->size());
6198 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6199 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6200 net::DEFAULT_PRIORITY
,
6201 response
.response_time
,
6205 // Makes sure we finish pending operations.
6206 base::MessageLoop::current()->RunUntilIdle();
6208 // Start with a READ mode transaction.
6209 MockTransaction
trans1(kTypicalGET_Transaction
);
6210 trans1
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
6212 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6213 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6214 EXPECT_EQ(50, response
.metadata
->size());
6215 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6217 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6218 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6219 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6220 base::MessageLoop::current()->RunUntilIdle();
6222 // Now make sure that the entry is re-validated with the server.
6223 trans1
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6224 trans1
.status
= "HTTP/1.1 304 Not Modified";
6225 AddMockTransaction(&trans1
);
6227 response
.metadata
= NULL
;
6228 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6229 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6231 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6232 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6233 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6234 base::MessageLoop::current()->RunUntilIdle();
6235 RemoveMockTransaction(&trans1
);
6237 // Now return 200 when validating the entry so the metadata will be lost.
6238 MockTransaction
trans2(kTypicalGET_Transaction
);
6239 trans2
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6240 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6241 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6243 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6244 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6248 // Tests that we don't mark entries as truncated when a filter detects the end
6250 TEST(HttpCache
, FilterCompletion
) {
6251 MockHttpCache cache
;
6252 net::TestCompletionCallback callback
;
6255 scoped_ptr
<net::HttpTransaction
> trans
;
6256 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6258 MockHttpRequest
request(kSimpleGET_Transaction
);
6259 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6260 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6262 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6263 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6264 EXPECT_GT(callback
.GetResult(rv
), 0);
6266 // Now make sure that the entry is preserved.
6267 trans
->DoneReading();
6270 // Make sure that the ActiveEntry is gone.
6271 base::MessageLoop::current()->RunUntilIdle();
6273 // Read from the cache.
6274 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6276 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6277 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6278 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6281 // Tests that we don't mark entries as truncated and release the cache
6282 // entry when DoneReading() is called before any Read() calls, such as
6284 TEST(HttpCache
, DoneReading
) {
6285 MockHttpCache cache
;
6286 net::TestCompletionCallback callback
;
6288 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6289 transaction
.data
= "";
6291 scoped_ptr
<net::HttpTransaction
> trans
;
6292 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6294 MockHttpRequest
request(transaction
);
6295 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6296 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6298 trans
->DoneReading();
6299 // Leave the transaction around.
6301 // Make sure that the ActiveEntry is gone.
6302 base::MessageLoop::current()->RunUntilIdle();
6304 // Read from the cache. This should not deadlock.
6305 RunTransactionTest(cache
.http_cache(), transaction
);
6307 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6308 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6309 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6312 // Tests that we stop caching when told.
6313 TEST(HttpCache
, StopCachingDeletesEntry
) {
6314 MockHttpCache cache
;
6315 net::TestCompletionCallback callback
;
6316 MockHttpRequest
request(kSimpleGET_Transaction
);
6319 scoped_ptr
<net::HttpTransaction
> trans
;
6320 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6322 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6323 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6325 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6326 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6327 EXPECT_EQ(10, callback
.GetResult(rv
));
6329 trans
->StopCaching();
6331 // We should be able to keep reading.
6332 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6333 EXPECT_GT(callback
.GetResult(rv
), 0);
6334 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6335 EXPECT_EQ(0, callback
.GetResult(rv
));
6338 // Make sure that the ActiveEntry is gone.
6339 base::MessageLoop::current()->RunUntilIdle();
6341 // Verify that the entry is gone.
6342 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6344 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6345 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6346 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6349 // Tests that we stop caching when told, even if DoneReading is called
6350 // after StopCaching.
6351 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6352 MockHttpCache cache
;
6353 net::TestCompletionCallback callback
;
6354 MockHttpRequest
request(kSimpleGET_Transaction
);
6357 scoped_ptr
<net::HttpTransaction
> trans
;
6358 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6360 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6361 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6363 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6364 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6365 EXPECT_EQ(10, callback
.GetResult(rv
));
6367 trans
->StopCaching();
6369 // We should be able to keep reading.
6370 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6371 EXPECT_GT(callback
.GetResult(rv
), 0);
6372 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6373 EXPECT_EQ(0, callback
.GetResult(rv
));
6375 // We should be able to call DoneReading.
6376 trans
->DoneReading();
6379 // Make sure that the ActiveEntry is gone.
6380 base::MessageLoop::current()->RunUntilIdle();
6382 // Verify that the entry is gone.
6383 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6385 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6386 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6387 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6390 // Tests that we stop caching when told, when using auth.
6391 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6392 MockHttpCache cache
;
6393 net::TestCompletionCallback callback
;
6394 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6395 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6396 AddMockTransaction(&mock_transaction
);
6397 MockHttpRequest
request(mock_transaction
);
6400 scoped_ptr
<net::HttpTransaction
> trans
;
6401 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6403 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6404 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6406 trans
->StopCaching();
6408 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6409 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6410 EXPECT_EQ(callback
.GetResult(rv
), 10);
6412 RemoveMockTransaction(&mock_transaction
);
6414 // Make sure that the ActiveEntry is gone.
6415 base::MessageLoop::current()->RunUntilIdle();
6417 // Verify that the entry is gone.
6418 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6420 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6421 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6422 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6425 // Tests that when we are told to stop caching we don't throw away valid data.
6426 TEST(HttpCache
, StopCachingSavesEntry
) {
6427 MockHttpCache cache
;
6428 net::TestCompletionCallback callback
;
6429 MockHttpRequest
request(kSimpleGET_Transaction
);
6432 scoped_ptr
<net::HttpTransaction
> trans
;
6433 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6435 // Force a response that can be resumed.
6436 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6437 AddMockTransaction(&mock_transaction
);
6438 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6439 "Content-Length: 42\n"
6442 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6443 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6445 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6446 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6447 EXPECT_EQ(callback
.GetResult(rv
), 10);
6449 trans
->StopCaching();
6451 // We should be able to keep reading.
6452 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6453 EXPECT_GT(callback
.GetResult(rv
), 0);
6454 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6455 EXPECT_EQ(callback
.GetResult(rv
), 0);
6457 RemoveMockTransaction(&mock_transaction
);
6460 // Verify that the entry is marked as incomplete.
6461 disk_cache::Entry
* entry
;
6462 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6463 net::HttpResponseInfo response
;
6464 bool truncated
= false;
6465 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6466 EXPECT_TRUE(truncated
);
6470 // Tests that we handle truncated enries when StopCaching is called.
6471 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6472 MockHttpCache cache
;
6473 net::TestCompletionCallback callback
;
6474 MockHttpRequest
request(kRangeGET_TransactionOK
);
6475 request
.extra_headers
.Clear();
6476 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6477 AddMockTransaction(&kRangeGET_TransactionOK
);
6479 std::string
raw_headers("HTTP/1.1 200 OK\n"
6480 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6482 "Accept-Ranges: bytes\n"
6483 "Content-Length: 80\n");
6484 CreateTruncatedEntry(raw_headers
, &cache
);
6487 // Now make a regular request.
6488 scoped_ptr
<net::HttpTransaction
> trans
;
6489 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6491 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6492 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6494 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6495 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6496 EXPECT_EQ(callback
.GetResult(rv
), 10);
6498 // This is actually going to do nothing.
6499 trans
->StopCaching();
6501 // We should be able to keep reading.
6502 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6503 EXPECT_GT(callback
.GetResult(rv
), 0);
6504 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6505 EXPECT_GT(callback
.GetResult(rv
), 0);
6506 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6507 EXPECT_EQ(callback
.GetResult(rv
), 0);
6510 // Verify that the disk entry was updated.
6511 disk_cache::Entry
* entry
;
6512 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6513 EXPECT_EQ(80, entry
->GetDataSize(1));
6514 bool truncated
= true;
6515 net::HttpResponseInfo response
;
6516 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6517 EXPECT_FALSE(truncated
);
6520 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6523 // Tests that we detect truncated resources from the net when there is
6524 // a Content-Length header.
6525 TEST(HttpCache
, TruncatedByContentLength
) {
6526 MockHttpCache cache
;
6527 net::TestCompletionCallback callback
;
6529 MockTransaction
transaction(kSimpleGET_Transaction
);
6530 AddMockTransaction(&transaction
);
6531 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6532 "Content-Length: 100\n";
6533 RunTransactionTest(cache
.http_cache(), transaction
);
6534 RemoveMockTransaction(&transaction
);
6536 // Read from the cache.
6537 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6539 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6540 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6541 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6544 // Tests that we actually flag entries as truncated when we detect an error
6546 TEST(HttpCache
, TruncatedByContentLength2
) {
6547 MockHttpCache cache
;
6548 net::TestCompletionCallback callback
;
6550 MockTransaction
transaction(kSimpleGET_Transaction
);
6551 AddMockTransaction(&transaction
);
6552 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6553 "Content-Length: 100\n"
6555 RunTransactionTest(cache
.http_cache(), transaction
);
6556 RemoveMockTransaction(&transaction
);
6558 // Verify that the entry is marked as incomplete.
6559 disk_cache::Entry
* entry
;
6560 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6561 net::HttpResponseInfo response
;
6562 bool truncated
= false;
6563 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6564 EXPECT_TRUE(truncated
);
6568 // Make sure that calling SetPriority on a cache transaction passes on
6569 // its priority updates to its underlying network transaction.
6570 TEST(HttpCache
, SetPriority
) {
6571 MockHttpCache cache
;
6573 scoped_ptr
<net::HttpTransaction
> trans
;
6574 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6576 // Shouldn't crash, but doesn't do anything either.
6577 trans
->SetPriority(net::LOW
);
6579 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6580 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6581 cache
.network_layer()->last_create_transaction_priority());
6583 net::HttpRequestInfo info
;
6584 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6585 net::TestCompletionCallback callback
;
6586 EXPECT_EQ(net::ERR_IO_PENDING
,
6587 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6589 EXPECT_TRUE(cache
.network_layer()->last_transaction());
6590 if (cache
.network_layer()->last_transaction()) {
6592 cache
.network_layer()->last_create_transaction_priority());
6594 cache
.network_layer()->last_transaction()->priority());
6597 trans
->SetPriority(net::HIGHEST
);
6599 if (cache
.network_layer()->last_transaction()) {
6601 cache
.network_layer()->last_create_transaction_priority());
6602 EXPECT_EQ(net::HIGHEST
,
6603 cache
.network_layer()->last_transaction()->priority());
6606 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6609 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6610 // transaction passes on its argument to the underlying network transaction.
6611 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
6612 MockHttpCache cache
;
6614 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
6615 scoped_ptr
<net::HttpTransaction
> trans
;
6616 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6618 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6620 net::HttpRequestInfo info
;
6621 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6622 net::TestCompletionCallback callback
;
6623 EXPECT_EQ(net::ERR_IO_PENDING
,
6624 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6626 ASSERT_TRUE(cache
.network_layer()->last_transaction());
6627 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
6628 websocket_handshake_stream_create_helper());
6629 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
6630 EXPECT_EQ(&create_helper
,
6631 cache
.network_layer()->last_transaction()->
6632 websocket_handshake_stream_create_helper());
6633 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6636 // Make sure that a cache transaction passes on its priority to
6637 // newly-created network transactions.
6638 TEST(HttpCache
, SetPriorityNewTransaction
) {
6639 MockHttpCache cache
;
6640 AddMockTransaction(&kRangeGET_TransactionOK
);
6642 std::string
raw_headers("HTTP/1.1 200 OK\n"
6643 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6645 "Accept-Ranges: bytes\n"
6646 "Content-Length: 80\n");
6647 CreateTruncatedEntry(raw_headers
, &cache
);
6649 // Now make a regular request.
6650 std::string headers
;
6651 MockTransaction
transaction(kRangeGET_TransactionOK
);
6652 transaction
.request_headers
= EXTRA_HEADER
;
6653 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6654 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6656 scoped_ptr
<net::HttpTransaction
> trans
;
6658 cache
.http_cache()->CreateTransaction(net::MEDIUM
, &trans
));
6659 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6660 cache
.network_layer()->last_create_transaction_priority());
6662 MockHttpRequest
info(transaction
);
6663 net::TestCompletionCallback callback
;
6664 EXPECT_EQ(net::ERR_IO_PENDING
,
6665 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6666 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6668 EXPECT_EQ(net::MEDIUM
,
6669 cache
.network_layer()->last_create_transaction_priority());
6671 trans
->SetPriority(net::HIGHEST
);
6672 // Should trigger a new network transaction and pick up the new
6674 ReadAndVerifyTransaction(trans
.get(), transaction
);
6676 EXPECT_EQ(net::HIGHEST
,
6677 cache
.network_layer()->last_create_transaction_priority());
6679 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6682 int64
RunTransactionAndGetReceivedBytes(
6683 MockHttpCache
& cache
,
6684 const MockTransaction
& trans_info
) {
6685 int64 received_bytes
= -1;
6686 RunTransactionTestBase(cache
.http_cache(), trans_info
,
6687 MockHttpRequest(trans_info
), NULL
, net::BoundNetLog(),
6688 NULL
, &received_bytes
);
6689 return received_bytes
;
6692 int64
TransactionSize(const MockTransaction
& transaction
) {
6693 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
6694 strlen(transaction
.data
);
6697 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
6698 MockHttpCache cache
;
6700 MockTransaction
transaction(kSimpleGET_Transaction
);
6701 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6702 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6704 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6705 EXPECT_EQ(0, received_bytes
);
6708 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
6709 MockHttpCache cache
;
6711 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6712 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6713 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6715 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6716 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
6717 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6718 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6721 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
6722 MockHttpCache cache
;
6724 MockTransaction
transaction(kTypicalGET_Transaction
);
6725 transaction
.request_headers
= "Foo: bar\r\n";
6726 transaction
.response_headers
=
6727 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6728 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6730 "Cache-Control: max-age=0\n"
6732 AddMockTransaction(&transaction
);
6733 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6734 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6736 RevalidationServer server
;
6737 transaction
.handler
= server
.Handler
;
6738 transaction
.request_headers
= "Foo: none\r\n";
6739 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6740 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6742 RemoveMockTransaction(&transaction
);
6745 TEST(HttpCache
, ReceivedBytesRange
) {
6746 MockHttpCache cache
;
6747 AddMockTransaction(&kRangeGET_TransactionOK
);
6748 MockTransaction
transaction(kRangeGET_TransactionOK
);
6750 // Read bytes 40-49 from the network.
6751 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6752 int64 range_response_size
= TransactionSize(transaction
);
6753 EXPECT_EQ(range_response_size
, received_bytes
);
6755 // Read bytes 40-49 from the cache.
6756 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6757 EXPECT_EQ(0, received_bytes
);
6758 base::MessageLoop::current()->RunUntilIdle();
6760 // Read bytes 30-39 from the network.
6761 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
6762 transaction
.data
= "rg: 30-39 ";
6763 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6764 EXPECT_EQ(range_response_size
, received_bytes
);
6765 base::MessageLoop::current()->RunUntilIdle();
6767 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6768 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
6769 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6770 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6771 EXPECT_EQ(range_response_size
* 2, received_bytes
);
6773 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6776 // Framework for tests of stale-while-revalidate related functionality. With
6777 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
6778 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
6779 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
6780 // synchronous revalidation.
6781 class HttpCacheStaleWhileRevalidateTest
: public ::testing::Test
{
6783 HttpCacheStaleWhileRevalidateTest()
6784 : transaction_(kSimpleGET_Transaction
),
6786 stale_while_revalidate_(7200),
6787 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
6788 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(true);
6791 // RunTransactionTest() with the arguments from this fixture.
6792 void RunFixtureTransactionTest() {
6793 std::string response_headers
= base::StringPrintf(
6796 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
6799 stale_while_revalidate_
);
6800 transaction_
.response_headers
= response_headers
.c_str();
6801 RunTransactionTest(cache_
.http_cache(), transaction_
);
6802 transaction_
.response_headers
= "";
6805 // How many times this test has sent requests to the (fake) origin
6806 // server. Every test case needs to make at least one request to initialise
6808 int transaction_count() {
6809 return cache_
.network_layer()->transaction_count();
6812 // How many times an existing cache entry was opened during the test case.
6813 int open_count() { return cache_
.disk_cache()->open_count(); }
6815 MockHttpCache cache_
;
6816 ScopedMockTransaction transaction_
;
6818 int stale_while_revalidate_
;
6819 std::string validator_
;
6822 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo
* request
,
6823 std::string
* response_status
,
6824 std::string
* response_headers
,
6825 std::string
* response_data
) {
6827 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
6828 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
6831 // Verify that the Resource-Freshness header is sent on a revalidation if the
6832 // stale-while-revalidate directive was on the response.
6833 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderSent
) {
6834 age_
= 10801; // Outside the stale-while-revalidate window.
6836 // Write to the cache.
6837 RunFixtureTransactionTest();
6839 EXPECT_EQ(1, transaction_count());
6841 // Send the request again and check that Resource-Freshness header is added.
6842 transaction_
.handler
= CheckResourceFreshnessHeader
;
6844 RunFixtureTransactionTest();
6846 EXPECT_EQ(2, transaction_count());
6849 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo
* request
,
6850 std::string
* response_status
,
6851 std::string
* response_headers
,
6852 std::string
* response_data
) {
6853 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
6856 // Verify that the Resource-Freshness header is not sent when
6857 // stale-while-revalidate is 0.
6858 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderNotSent
) {
6860 stale_while_revalidate_
= 0;
6862 // Write to the cache.
6863 RunFixtureTransactionTest();
6865 EXPECT_EQ(1, transaction_count());
6867 // Send the request again and check that Resource-Freshness header is absent.
6868 transaction_
.handler
= CheckResourceFreshnessAbsent
;
6870 RunFixtureTransactionTest();
6872 EXPECT_EQ(2, transaction_count());
6875 // Verify that when stale-while-revalidate applies the response is read from
6877 TEST_F(HttpCacheStaleWhileRevalidateTest
, ReadFromCache
) {
6878 // Write to the cache.
6879 RunFixtureTransactionTest();
6881 EXPECT_EQ(0, open_count());
6882 EXPECT_EQ(1, transaction_count());
6884 // Read back from the cache.
6885 RunFixtureTransactionTest();
6887 EXPECT_EQ(1, open_count());
6888 EXPECT_EQ(1, transaction_count());
6891 // Verify that when stale-while-revalidate applies an asynchronous request is
6893 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestSent
) {
6894 // Write to the cache.
6895 RunFixtureTransactionTest();
6897 EXPECT_EQ(1, transaction_count());
6899 // Read back from the cache.
6900 RunFixtureTransactionTest();
6902 EXPECT_EQ(1, transaction_count());
6904 // Let the async request execute.
6905 base::RunLoop().RunUntilIdle();
6906 EXPECT_EQ(2, transaction_count());
6909 // Verify that tearing down the HttpCache with an async revalidation in progress
6910 // does not break anything (this test is most likely to find problems when run
6911 // with a memory checker such as AddressSanitizer).
6912 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncTearDown
) {
6913 // Write to the cache.
6914 RunFixtureTransactionTest();
6916 // Read back from the cache.
6917 RunFixtureTransactionTest();
6920 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo
* request
,
6921 std::string
* response_status
,
6922 std::string
* response_headers
,
6923 std::string
* response_data
) {
6925 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-Modified-Since", &value
));
6926 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value
);
6929 // Verify that the async revalidation contains an If-Modified-Since header.
6930 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfModifiedSince
) {
6931 // Write to the cache.
6932 RunFixtureTransactionTest();
6934 transaction_
.handler
= CheckIfModifiedSinceHeader
;
6936 // Read back from the cache.
6937 RunFixtureTransactionTest();
6940 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo
* request
,
6941 std::string
* response_status
,
6942 std::string
* response_headers
,
6943 std::string
* response_data
) {
6945 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-None-Match", &value
));
6946 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value
);
6949 // If the response had ETag rather than Last-Modified, then that is used to
6950 // conditionalise the response.
6951 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfNoneMatch
) {
6952 validator_
= "Etag: \"40a1-1320-4f6adefa22a40\"";
6954 // Write to the cache.
6955 RunFixtureTransactionTest();
6957 transaction_
.handler
= CheckIfNoneMatchHeader
;
6959 // Read back from the cache.
6960 RunFixtureTransactionTest();
6963 static void CheckResourceFreshnessHeaderPresent(
6964 const net::HttpRequestInfo
* request
,
6965 std::string
* response_status
,
6966 std::string
* response_headers
,
6967 std::string
* response_data
) {
6968 EXPECT_TRUE(request
->extra_headers
.HasHeader("Resource-Freshness"));
6971 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestHasResourceFreshness
) {
6972 // Write to the cache.
6973 RunFixtureTransactionTest();
6975 transaction_
.handler
= CheckResourceFreshnessHeaderPresent
;
6977 // Read back from the cache.
6978 RunFixtureTransactionTest();
6981 // Verify that when age > max-age + stale-while-revalidate stale results are
6983 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedIfTooStale
) {
6986 // Write to the cache.
6987 RunFixtureTransactionTest();
6989 EXPECT_EQ(0, open_count());
6990 EXPECT_EQ(1, transaction_count());
6992 // Reading back reads from the network.
6993 RunFixtureTransactionTest();
6995 EXPECT_EQ(1, open_count());
6996 EXPECT_EQ(2, transaction_count());
6999 // HEAD requests should be able to take advantage of stale-while-revalidate.
7000 TEST_F(HttpCacheStaleWhileRevalidateTest
, WorksForHeadMethod
) {
7001 // Write to the cache. This has to be a GET request; HEAD requests don't
7002 // create new cache entries.
7003 RunFixtureTransactionTest();
7005 EXPECT_EQ(0, open_count());
7006 EXPECT_EQ(1, transaction_count());
7008 // Read back from the cache, and trigger an asynchronous HEAD request.
7009 transaction_
.method
= "HEAD";
7010 transaction_
.data
= "";
7012 RunFixtureTransactionTest();
7014 EXPECT_EQ(1, open_count());
7015 EXPECT_EQ(1, transaction_count());
7017 // Let the network request proceed.
7018 base::RunLoop().RunUntilIdle();
7020 EXPECT_EQ(2, transaction_count());
7023 // POST requests should not use stale-while-revalidate.
7024 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedToPost
) {
7025 transaction_
= ScopedMockTransaction(kSimplePOST_Transaction
);
7027 // Write to the cache.
7028 RunFixtureTransactionTest();
7030 EXPECT_EQ(0, open_count());
7031 EXPECT_EQ(1, transaction_count());
7033 // Reading back reads from the network.
7034 RunFixtureTransactionTest();
7036 EXPECT_EQ(0, open_count());
7037 EXPECT_EQ(2, transaction_count());
7040 static void CheckUrlMatches(const net::HttpRequestInfo
* request
,
7041 std::string
* response_status
,
7042 std::string
* response_headers
,
7043 std::string
* response_data
) {
7044 EXPECT_EQ("http://www.google.com/", request
->url
.spec());
7047 // Async revalidation is issued to the original URL.
7048 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestUrlMatches
) {
7049 transaction_
.url
= "http://www.google.com/";
7050 // Write to the cache.
7051 RunFixtureTransactionTest();
7053 // Read back from the cache.
7054 RunFixtureTransactionTest();
7056 EXPECT_EQ(1, transaction_count());
7058 transaction_
.handler
= CheckUrlMatches
;
7060 // Let the async request execute and perform the check.
7061 base::RunLoop().RunUntilIdle();
7062 EXPECT_EQ(2, transaction_count());
7065 class SyncLoadFlagTest
: public HttpCacheStaleWhileRevalidateTest
,
7066 public ::testing::WithParamInterface
<int> {};
7068 // Flags which should always cause the request to be synchronous.
7069 TEST_P(SyncLoadFlagTest
, MustBeSynchronous
) {
7070 transaction_
.load_flags
|= GetParam();
7071 // Write to the cache.
7072 RunFixtureTransactionTest();
7074 EXPECT_EQ(1, transaction_count());
7076 // Reading back reads from the network.
7077 RunFixtureTransactionTest();
7079 EXPECT_EQ(2, transaction_count());
7082 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate
,
7084 ::testing::Values(net::LOAD_VALIDATE_CACHE
,
7085 net::LOAD_BYPASS_CACHE
,
7086 net::LOAD_DISABLE_CACHE
));
7088 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7089 PreferringCacheDoesNotTriggerAsyncRequest
) {
7090 transaction_
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
7091 // Write to the cache.
7092 RunFixtureTransactionTest();
7094 EXPECT_EQ(1, transaction_count());
7096 // Reading back reads from the cache.
7097 RunFixtureTransactionTest();
7099 EXPECT_EQ(1, transaction_count());
7101 // If there was an async transaction created, it would run now.
7102 base::RunLoop().RunUntilIdle();
7104 // There was no async transaction.
7105 EXPECT_EQ(1, transaction_count());
7108 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotUsedWhenDisabled
) {
7109 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7110 // Write to the cache.
7111 RunFixtureTransactionTest();
7113 EXPECT_EQ(1, transaction_count());
7115 // A synchronous revalidation is performed.
7116 RunFixtureTransactionTest();
7118 EXPECT_EQ(2, transaction_count());
7121 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7122 OnlyFromCacheDoesNotTriggerAsyncRequest
) {
7123 transaction_
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
7124 transaction_
.return_code
= net::ERR_CACHE_MISS
;
7126 // Writing to the cache should fail, because we are avoiding the network.
7127 RunFixtureTransactionTest();
7129 EXPECT_EQ(0, transaction_count());
7131 base::RunLoop().RunUntilIdle();
7134 EXPECT_EQ(0, transaction_count());
7137 // A certificate error during an asynchronous fetch should cause the next fetch
7138 // to proceed synchronously.
7139 // TODO(ricea): In future, only certificate errors which require user
7140 // interaction should fail the asynchronous revalidation, and they should cause
7141 // the next revalidation to be synchronous rather than requiring a total
7142 // refetch. This test will need to be updated appropriately.
7143 TEST_F(HttpCacheStaleWhileRevalidateTest
, CertificateErrorCausesRefetch
) {
7144 // Write to the cache.
7145 RunFixtureTransactionTest();
7147 EXPECT_EQ(1, transaction_count());
7149 // Now read back. RunTransactionTestBase() expects to receive the network
7150 // error back from the HttpCache::Transaction, but since the cache request
7151 // will return OK we need to duplicate some of its implementation here.
7152 transaction_
.return_code
= net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
7153 net::TestCompletionCallback callback
;
7154 scoped_ptr
<net::HttpTransaction
> trans
;
7156 cache_
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7157 EXPECT_EQ(net::OK
, rv
);
7158 ASSERT_TRUE(trans
.get());
7160 MockHttpRequest
request(transaction_
);
7161 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7162 ASSERT_EQ(net::ERR_IO_PENDING
, rv
);
7163 ASSERT_EQ(net::OK
, callback
.WaitForResult());
7164 ReadAndVerifyTransaction(trans
.get(), transaction_
);
7166 EXPECT_EQ(1, transaction_count());
7168 // Allow the asynchronous fetch to run.
7169 base::RunLoop().RunUntilIdle();
7171 EXPECT_EQ(2, transaction_count());
7173 // Now run the transaction again. It should run synchronously.
7174 transaction_
.return_code
= net::OK
;
7175 RunFixtureTransactionTest();
7177 EXPECT_EQ(3, transaction_count());
7180 // Ensure that the response cached by the asynchronous request is not truncated,
7181 // even if the server is slow.
7182 TEST_F(HttpCacheStaleWhileRevalidateTest
, EntireResponseCached
) {
7183 transaction_
.test_mode
= TEST_MODE_SLOW_READ
;
7184 // Write to the cache.
7185 RunFixtureTransactionTest();
7187 // Read back from the cache.
7188 RunFixtureTransactionTest();
7190 // Let the async request execute.
7191 base::RunLoop().RunUntilIdle();
7193 // The cache entry should still be complete.
7194 transaction_
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
7195 RunFixtureTransactionTest();
7198 // Verify that there are no race conditions in the completely synchronous case.
7199 TEST_F(HttpCacheStaleWhileRevalidateTest
, SynchronousCaseWorks
) {
7200 transaction_
.test_mode
= TEST_MODE_SYNC_ALL
;
7201 // Write to the cache.
7202 RunFixtureTransactionTest();
7204 EXPECT_EQ(1, transaction_count());
7206 // Read back from the cache.
7207 RunFixtureTransactionTest();
7209 EXPECT_EQ(1, transaction_count());
7211 // Let the async request execute.
7212 base::RunLoop().RunUntilIdle();
7213 EXPECT_EQ(2, transaction_count());
7216 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo
* request
,
7217 std::string
* response_status
,
7218 std::string
* response_headers
,
7219 std::string
* response_data
) {
7220 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION
, request
->load_flags
);
7223 // Check that the load flags on the async request are the same as the load flags
7224 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7225 TEST_F(HttpCacheStaleWhileRevalidateTest
, LoadFlagsAsyncRevalidation
) {
7226 transaction_
.load_flags
= net::LOAD_NORMAL
;
7227 // Write to the cache.
7228 RunFixtureTransactionTest();
7230 EXPECT_EQ(1, transaction_count());
7232 // Read back from the cache.
7233 RunFixtureTransactionTest();
7235 EXPECT_EQ(1, transaction_count());
7237 transaction_
.handler
= CheckLoadFlagsAsyncRevalidation
;
7238 // Let the async request execute.
7239 base::RunLoop().RunUntilIdle();
7240 EXPECT_EQ(2, transaction_count());
7243 static void SimpleMockAuthHandler(const net::HttpRequestInfo
* request
,
7244 std::string
* response_status
,
7245 std::string
* response_headers
,
7246 std::string
* response_data
) {
7247 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
7248 !request
->extra_headers
.HasHeader("Authorization")) {
7249 response_status
->assign("HTTP/1.1 401 Unauthorized");
7250 response_headers
->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7253 response_status
->assign("HTTP/1.1 200 OK");
7256 TEST_F(HttpCacheStaleWhileRevalidateTest
, RestartForAuth
) {
7257 // Write to the cache.
7258 RunFixtureTransactionTest();
7260 EXPECT_EQ(1, transaction_count());
7262 // Now make the transaction require auth.
7263 transaction_
.request_headers
= "X-Require-Mock-Auth: dummy\r\n\r\n";
7264 transaction_
.handler
= SimpleMockAuthHandler
;
7266 // Read back from the cache.
7267 RunFixtureTransactionTest();
7269 EXPECT_EQ(1, transaction_count());
7271 // Let the async request execute.
7272 base::RunLoop().RunUntilIdle();
7274 EXPECT_EQ(2, transaction_count());
7277 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7278 // take place on a sparse entry.
7279 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7280 MockHttpCache cache
;
7282 // Create a transaction for bytes 0-9.
7283 MockHttpRequest
request(kRangeGET_TransactionOK
);
7284 MockTransaction
transaction(kRangeGET_TransactionOK
);
7285 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7286 transaction
.data
= "rg: 00-09 ";
7287 AddMockTransaction(&transaction
);
7289 net::TestCompletionCallback callback
;
7290 scoped_ptr
<net::HttpTransaction
> trans
;
7291 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7292 EXPECT_EQ(net::OK
, rv
);
7293 ASSERT_TRUE(trans
.get());
7295 // Start our transaction.
7296 trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7298 // A second transaction on a different part of the file (the default
7299 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7300 // the already pending transaction.
7301 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7303 // Let the first transaction complete.
7304 callback
.WaitForResult();
7306 RemoveMockTransaction(&transaction
);
7309 // Makes sure that a request stops using the cache when the response headers
7310 // with "Cache-Control: no-store" arrives. That means that another request for
7311 // the same URL can be processed before the response body of the original
7313 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7314 MockHttpCache cache
;
7315 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7316 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7317 MockHttpRequest
request(mock_transaction
);
7319 scoped_ptr
<Context
> first(new Context
);
7320 first
->result
= cache
.CreateTransaction(&first
->trans
);
7321 ASSERT_EQ(net::OK
, first
->result
);
7322 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7323 first
->result
= first
->trans
->Start(
7324 &request
, first
->callback
.callback(), net::BoundNetLog());
7325 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7327 base::MessageLoop::current()->RunUntilIdle();
7328 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7329 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7330 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7331 "Cache-Control", "no-store"));
7332 // Here we have read the response header but not read the response body yet.
7334 // Let us create the second (read) transaction.
7335 scoped_ptr
<Context
> second(new Context
);
7336 second
->result
= cache
.CreateTransaction(&second
->trans
);
7337 ASSERT_EQ(net::OK
, second
->result
);
7338 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7339 second
->result
= second
->trans
->Start(
7340 &request
, second
->callback
.callback(), net::BoundNetLog());
7342 // Here the second transaction proceeds without reading the first body.
7343 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7344 base::MessageLoop::current()->RunUntilIdle();
7345 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7346 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7347 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7348 "Cache-Control", "no-store"));
7349 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);