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/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "net/base/cache_type.h"
16 #include "net/base/host_port_pair.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/load_timing_info.h"
19 #include "net/base/load_timing_info_test_util.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_log_unittest.h"
22 #include "net/base/upload_bytes_element_reader.h"
23 #include "net/base/upload_data_stream.h"
24 #include "net/cert/cert_status_flags.h"
25 #include "net/disk_cache/disk_cache.h"
26 #include "net/http/http_byte_range.h"
27 #include "net/http/http_request_headers.h"
28 #include "net/http/http_request_info.h"
29 #include "net/http/http_response_headers.h"
30 #include "net/http/http_response_info.h"
31 #include "net/http/http_transaction.h"
32 #include "net/http/http_transaction_test_util.h"
33 #include "net/http/http_util.h"
34 #include "net/http/mock_http_cache.h"
35 #include "net/socket/client_socket_handle.h"
36 #include "net/ssl/ssl_cert_request_info.h"
37 #include "net/websockets/websocket_handshake_stream_base.h"
38 #include "testing/gtest/include/gtest/gtest.h"
44 // Tests the load timing values of a request that goes through a
45 // MockNetworkTransaction.
46 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo
& load_timing_info
) {
47 EXPECT_FALSE(load_timing_info
.socket_reused
);
48 EXPECT_NE(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
50 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
51 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
53 net::ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
54 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
55 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
56 load_timing_info
.send_start
);
58 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
60 // Set by URLRequest / URLRequestHttpJob, at a higher level.
61 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
62 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
63 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
66 // Tests the load timing values of a request that receives a cached response.
67 void TestLoadTimingCachedResponse(const net::LoadTimingInfo
& load_timing_info
) {
68 EXPECT_FALSE(load_timing_info
.socket_reused
);
69 EXPECT_EQ(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
71 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
72 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
74 net::ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
76 // Only the send start / end times should be sent, and they should have the
78 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
79 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
81 // Set by URLRequest / URLRequestHttpJob, at a higher level.
82 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
83 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
84 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
87 class DeleteCacheCompletionCallback
: public net::TestCompletionCallbackBase
{
89 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
91 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
92 base::Unretained(this))) {
95 const net::CompletionCallback
& callback() const { return callback_
; }
98 void OnComplete(int result
) {
103 MockHttpCache
* cache_
;
104 net::CompletionCallback callback_
;
106 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
109 //-----------------------------------------------------------------------------
112 void ReadAndVerifyTransaction(net::HttpTransaction
* trans
,
113 const MockTransaction
& trans_info
) {
115 int rv
= ReadTransaction(trans
, &content
);
117 EXPECT_EQ(net::OK
, rv
);
118 std::string
expected(trans_info
.data
);
119 EXPECT_EQ(expected
, content
);
122 void RunTransactionTestBase(net::HttpCache
* cache
,
123 const MockTransaction
& trans_info
,
124 const MockHttpRequest
& request
,
125 net::HttpResponseInfo
* response_info
,
126 const net::BoundNetLog
& net_log
,
127 net::LoadTimingInfo
* load_timing_info
,
128 int64
* received_bytes
) {
129 net::TestCompletionCallback callback
;
131 // write to the cache
133 scoped_ptr
<net::HttpTransaction
> trans
;
134 int rv
= cache
->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
135 EXPECT_EQ(net::OK
, rv
);
136 ASSERT_TRUE(trans
.get());
138 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
139 if (rv
== net::ERR_IO_PENDING
)
140 rv
= callback
.WaitForResult();
141 ASSERT_EQ(trans_info
.return_code
, rv
);
146 const net::HttpResponseInfo
* response
= trans
->GetResponseInfo();
147 ASSERT_TRUE(response
);
150 *response_info
= *response
;
152 if (load_timing_info
) {
153 // If a fake network connection is used, need a NetLog to get a fake socket
155 EXPECT_TRUE(net_log
.net_log());
156 *load_timing_info
= net::LoadTimingInfo();
157 trans
->GetLoadTimingInfo(load_timing_info
);
160 ReadAndVerifyTransaction(trans
.get(), trans_info
);
163 *received_bytes
= trans
->GetTotalReceivedBytes();
166 void RunTransactionTestWithRequest(net::HttpCache
* cache
,
167 const MockTransaction
& trans_info
,
168 const MockHttpRequest
& request
,
169 net::HttpResponseInfo
* response_info
) {
170 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
171 net::BoundNetLog(), NULL
, NULL
);
174 void RunTransactionTestAndGetTiming(net::HttpCache
* cache
,
175 const MockTransaction
& trans_info
,
176 const net::BoundNetLog
& log
,
177 net::LoadTimingInfo
* load_timing_info
) {
178 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
179 NULL
, log
, load_timing_info
, NULL
);
182 void RunTransactionTest(net::HttpCache
* cache
,
183 const MockTransaction
& trans_info
) {
184 RunTransactionTestAndGetTiming(cache
, trans_info
, net::BoundNetLog(), NULL
);
187 void RunTransactionTestWithResponseInfo(net::HttpCache
* cache
,
188 const MockTransaction
& trans_info
,
189 net::HttpResponseInfo
* response
) {
190 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
194 void RunTransactionTestWithResponseInfoAndGetTiming(
195 net::HttpCache
* cache
,
196 const MockTransaction
& trans_info
,
197 net::HttpResponseInfo
* response
,
198 const net::BoundNetLog
& log
,
199 net::LoadTimingInfo
* load_timing_info
) {
200 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
201 response
, log
, load_timing_info
, NULL
);
204 void RunTransactionTestWithResponse(net::HttpCache
* cache
,
205 const MockTransaction
& trans_info
,
206 std::string
* response_headers
) {
207 net::HttpResponseInfo response
;
208 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
209 response
.headers
->GetNormalizedHeaders(response_headers
);
212 void RunTransactionTestWithResponseAndGetTiming(
213 net::HttpCache
* cache
,
214 const MockTransaction
& trans_info
,
215 std::string
* response_headers
,
216 const net::BoundNetLog
& log
,
217 net::LoadTimingInfo
* load_timing_info
) {
218 net::HttpResponseInfo response
;
219 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
220 &response
, log
, load_timing_info
, NULL
);
221 response
.headers
->GetNormalizedHeaders(response_headers
);
224 // This class provides a handler for kFastNoStoreGET_Transaction so that the
225 // no-store header can be included on demand.
226 class FastTransactionServer
{
228 FastTransactionServer() {
231 ~FastTransactionServer() {}
233 void set_no_store(bool value
) { no_store
= value
; }
235 static void FastNoStoreHandler(const net::HttpRequestInfo
* request
,
236 std::string
* response_status
,
237 std::string
* response_headers
,
238 std::string
* response_data
) {
240 *response_headers
= "Cache-Control: no-store\n";
244 static bool no_store
;
245 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
247 bool FastTransactionServer::no_store
;
249 const MockTransaction kFastNoStoreGET_Transaction
= {
250 "http://www.google.com/nostore",
254 net::LOAD_VALIDATE_CACHE
,
256 "Cache-Control: max-age=10000\n",
258 "<html><body>Google Blah Blah</body></html>",
259 TEST_MODE_SYNC_NET_START
,
260 &FastTransactionServer::FastNoStoreHandler
,
265 // This class provides a handler for kRangeGET_TransactionOK so that the range
266 // request can be served on demand.
267 class RangeTransactionServer
{
269 RangeTransactionServer() {
270 not_modified_
= false;
274 ~RangeTransactionServer() {
275 not_modified_
= false;
280 // Returns only 416 or 304 when set.
281 void set_not_modified(bool value
) { not_modified_
= value
; }
283 // Returns 206 when revalidating a range (instead of 304).
284 void set_modified(bool value
) { modified_
= value
; }
286 // Returns 200 instead of 206 (a malformed response overall).
287 void set_bad_200(bool value
) { bad_200_
= value
; }
289 static void RangeHandler(const net::HttpRequestInfo
* request
,
290 std::string
* response_status
,
291 std::string
* response_headers
,
292 std::string
* response_data
);
295 static bool not_modified_
;
296 static bool modified_
;
297 static bool bad_200_
;
298 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
300 bool RangeTransactionServer::not_modified_
= false;
301 bool RangeTransactionServer::modified_
= false;
302 bool RangeTransactionServer::bad_200_
= false;
304 // A dummy extra header that must be preserved on a given request.
306 // EXTRA_HEADER_LINE doesn't include a line terminator because it
307 // will be passed to AddHeaderFromString() which doesn't accept them.
308 #define EXTRA_HEADER_LINE "Extra: header"
310 // EXTRA_HEADER contains a line terminator, as expected by
311 // AddHeadersFromString() (_not_ AddHeaderFromString()).
312 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
314 static const char kExtraHeaderKey
[] = "Extra";
317 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo
* request
,
318 std::string
* response_status
,
319 std::string
* response_headers
,
320 std::string
* response_data
) {
321 if (request
->extra_headers
.IsEmpty()) {
322 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
323 response_data
->clear();
327 // We want to make sure we don't delete extra headers.
328 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
330 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
331 !request
->extra_headers
.HasHeader("Authorization")) {
332 response_status
->assign("HTTP/1.1 401 Unauthorized");
333 response_data
->assign("WWW-Authenticate: Foo\n");
338 response_status
->assign("HTTP/1.1 304 Not Modified");
339 response_data
->clear();
343 std::vector
<net::HttpByteRange
> ranges
;
344 std::string range_header
;
345 if (!request
->extra_headers
.GetHeader(
346 net::HttpRequestHeaders::kRange
, &range_header
) ||
347 !net::HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
348 ranges
.size() != 1) {
349 // This is not a byte range request. We return 200.
350 response_status
->assign("HTTP/1.1 200 OK");
351 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
352 response_data
->assign("Not a range");
356 // We can handle this range request.
357 net::HttpByteRange byte_range
= ranges
[0];
358 if (byte_range
.first_byte_position() > 79) {
359 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
360 response_data
->clear();
364 EXPECT_TRUE(byte_range
.ComputeBounds(80));
365 int start
= static_cast<int>(byte_range
.first_byte_position());
366 int end
= static_cast<int>(byte_range
.last_byte_position());
370 std::string content_range
= base::StringPrintf(
371 "Content-Range: bytes %d-%d/80\n", start
, end
);
372 response_headers
->append(content_range
);
374 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
377 EXPECT_EQ(0, end
% 10);
380 EXPECT_EQ(9, (end
- start
) % 10);
381 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
382 base::StringAppendF(&data
, "rg: %02d-%02d ",
383 block_start
, block_start
+ 9);
386 *response_data
= data
;
388 if (end
- start
!= 9) {
389 // We also have to fix content-length.
390 int len
= end
- start
+ 1;
391 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
393 response_headers
->replace(response_headers
->find("Content-Length:"),
394 content_length
.size(), content_length
);
397 response_status
->assign("HTTP/1.1 304 Not Modified");
398 response_data
->clear();
402 const MockTransaction kRangeGET_TransactionOK
= {
403 "http://www.google.com/range",
406 "Range: bytes = 40-49\r\n"
409 "HTTP/1.1 206 Partial Content",
410 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
412 "Accept-Ranges: bytes\n"
413 "Content-Length: 10\n",
417 &RangeTransactionServer::RangeHandler
,
422 // Verifies the response headers (|response|) match a partial content
423 // response for the range starting at |start| and ending at |end|.
424 void Verify206Response(std::string response
, int start
, int end
) {
425 std::string
raw_headers(net::HttpUtil::AssembleRawHeaders(response
.data(),
427 scoped_refptr
<net::HttpResponseHeaders
> headers(
428 new net::HttpResponseHeaders(raw_headers
));
430 ASSERT_EQ(206, headers
->response_code());
432 int64 range_start
, range_end
, object_size
;
434 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
435 int64 content_length
= headers
->GetContentLength();
437 int length
= end
- start
+ 1;
438 ASSERT_EQ(length
, content_length
);
439 ASSERT_EQ(start
, range_start
);
440 ASSERT_EQ(end
, range_end
);
443 // Creates a truncated entry that can be resumed using byte ranges.
444 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
445 // Create a disk cache entry that stores an incomplete resource.
446 disk_cache::Entry
* entry
;
447 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
450 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
453 net::HttpResponseInfo response
;
454 response
.response_time
= base::Time::Now();
455 response
.request_time
= base::Time::Now();
456 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
457 // Set the last argument for this to be an incomplete request.
458 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
460 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
461 int len
= static_cast<int>(base::strlcpy(buf
->data(),
462 "rg: 00-09 rg: 10-19 ", 100));
463 net::TestCompletionCallback cb
;
464 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
465 EXPECT_EQ(len
, cb
.GetResult(rv
));
469 // Helper to represent a network HTTP response.
471 // Set this response into |trans|.
472 void AssignTo(MockTransaction
* trans
) const {
473 trans
->status
= status
;
474 trans
->response_headers
= headers
;
478 std::string
status_and_headers() const {
479 return std::string(status
) + "\n" + std::string(headers
);
488 Context() : result(net::ERR_IO_PENDING
) {}
491 net::TestCompletionCallback callback
;
492 scoped_ptr
<net::HttpTransaction
> trans
;
495 class FakeWebSocketHandshakeStreamCreateHelper
496 : public net::WebSocketHandshakeStreamBase::CreateHelper
{
498 virtual ~FakeWebSocketHandshakeStreamCreateHelper() {}
499 virtual net::WebSocketHandshakeStreamBase
* CreateBasicStream(
500 scoped_ptr
<net::ClientSocketHandle
> connect
, bool using_proxy
) OVERRIDE
{
503 virtual net::WebSocketHandshakeStreamBase
* CreateSpdyStream(
504 const base::WeakPtr
<net::SpdySession
>& session
,
505 bool use_relative_url
) OVERRIDE
{
510 // Returns true if |entry| is not one of the log types paid attention to in this
511 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
513 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry
& entry
) {
514 switch (entry
.type
) {
515 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
516 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
517 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
518 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
519 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
520 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO
:
527 // Modifies |entries| to only include log entries created by the cache layer and
528 // asserted on in these tests.
529 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList
* entries
) {
530 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
531 &ShouldIgnoreLogEntry
),
538 //-----------------------------------------------------------------------------
541 TEST(HttpCache
, CreateThenDestroy
) {
544 scoped_ptr
<net::HttpTransaction
> trans
;
545 EXPECT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
546 ASSERT_TRUE(trans
.get());
549 TEST(HttpCache
, GetBackend
) {
550 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(0));
552 disk_cache::Backend
* backend
;
553 net::TestCompletionCallback cb
;
554 // This will lazily initialize the backend.
555 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
556 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
559 TEST(HttpCache
, SimpleGET
) {
561 net::CapturingBoundNetLog log
;
562 net::LoadTimingInfo load_timing_info
;
564 // Write to the cache.
565 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
566 log
.bound(), &load_timing_info
);
568 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
569 EXPECT_EQ(0, cache
.disk_cache()->open_count());
570 EXPECT_EQ(1, cache
.disk_cache()->create_count());
571 TestLoadTimingNetworkRequest(load_timing_info
);
574 TEST(HttpCache
, SimpleGETNoDiskCache
) {
577 cache
.disk_cache()->set_fail_requests();
579 net::CapturingBoundNetLog log
;
580 net::LoadTimingInfo load_timing_info
;
582 // Read from the network, and don't use the cache.
583 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
584 log
.bound(), &load_timing_info
);
586 // Check that the NetLog was filled as expected.
587 // (We attempted to both Open and Create entries, but both failed).
588 net::CapturingNetLog::CapturedEntryList entries
;
589 log
.GetEntries(&entries
);
590 FilterLogEntries(&entries
);
592 EXPECT_EQ(6u, entries
.size());
593 EXPECT_TRUE(net::LogContainsBeginEvent(
594 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
595 EXPECT_TRUE(net::LogContainsEndEvent(
596 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
597 EXPECT_TRUE(net::LogContainsBeginEvent(
598 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
599 EXPECT_TRUE(net::LogContainsEndEvent(
600 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
601 EXPECT_TRUE(net::LogContainsBeginEvent(
602 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
603 EXPECT_TRUE(net::LogContainsEndEvent(
604 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
606 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
607 EXPECT_EQ(0, cache
.disk_cache()->open_count());
608 EXPECT_EQ(0, cache
.disk_cache()->create_count());
609 TestLoadTimingNetworkRequest(load_timing_info
);
612 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
613 // This will initialize a cache object with NULL backend.
614 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
615 factory
->set_fail(true);
616 factory
->FinishCreation(); // We'll complete synchronously.
617 MockHttpCache
cache(factory
);
619 // Read from the network, and don't use the cache.
620 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
622 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
623 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
626 // Tests that IOBuffers are not referenced after IO completes.
627 TEST(HttpCache
, ReleaseBuffer
) {
630 // Write to the cache.
631 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
633 MockHttpRequest
request(kSimpleGET_Transaction
);
634 scoped_ptr
<net::HttpTransaction
> trans
;
635 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
637 const int kBufferSize
= 10;
638 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(kBufferSize
));
639 net::ReleaseBufferCompletionCallback
cb(buffer
.get());
641 int rv
= trans
->Start(&request
, cb
.callback(), net::BoundNetLog());
642 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
644 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
645 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
648 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
651 cache
.disk_cache()->set_soft_failures(true);
653 // Read from the network, and fail to write to the cache.
654 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
656 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
657 EXPECT_EQ(0, cache
.disk_cache()->open_count());
658 EXPECT_EQ(1, cache
.disk_cache()->create_count());
660 // This one should see an empty cache again.
661 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
663 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
664 EXPECT_EQ(0, cache
.disk_cache()->open_count());
665 EXPECT_EQ(2, cache
.disk_cache()->create_count());
668 // Tests that disk failures after the transaction has started don't cause the
670 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
673 MockHttpRequest
request(kSimpleGET_Transaction
);
675 scoped_ptr
<Context
> c(new Context());
676 int rv
= cache
.CreateTransaction(&c
->trans
);
677 ASSERT_EQ(net::OK
, rv
);
679 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
680 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
681 rv
= c
->callback
.WaitForResult();
683 // Start failing request now.
684 cache
.disk_cache()->set_soft_failures(true);
686 // We have to open the entry again to propagate the failure flag.
687 disk_cache::Entry
* en
;
688 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
691 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
694 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
695 EXPECT_EQ(1, cache
.disk_cache()->open_count());
696 EXPECT_EQ(1, cache
.disk_cache()->create_count());
698 // This one should see an empty cache again.
699 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
701 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
702 EXPECT_EQ(1, cache
.disk_cache()->open_count());
703 EXPECT_EQ(2, cache
.disk_cache()->create_count());
706 // Tests that we handle failures to read from the cache.
707 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
710 // Read from the network, and write to the cache.
711 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
713 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
714 EXPECT_EQ(0, cache
.disk_cache()->open_count());
715 EXPECT_EQ(1, cache
.disk_cache()->create_count());
717 cache
.disk_cache()->set_soft_failures(true);
719 // Now fail to read from the cache.
720 scoped_ptr
<Context
> c(new Context());
721 int rv
= cache
.CreateTransaction(&c
->trans
);
722 ASSERT_EQ(net::OK
, rv
);
724 MockHttpRequest
request(kSimpleGET_Transaction
);
725 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
726 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
728 // Now verify that the entry was removed from the cache.
729 cache
.disk_cache()->set_soft_failures(false);
731 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
732 EXPECT_EQ(1, cache
.disk_cache()->open_count());
733 EXPECT_EQ(2, cache
.disk_cache()->create_count());
735 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
737 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
738 EXPECT_EQ(1, cache
.disk_cache()->open_count());
739 EXPECT_EQ(3, cache
.disk_cache()->create_count());
742 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
745 net::CapturingBoundNetLog log
;
746 net::LoadTimingInfo load_timing_info
;
748 // Write to the cache.
749 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
750 log
.bound(), &load_timing_info
);
752 // Check that the NetLog was filled as expected.
753 net::CapturingNetLog::CapturedEntryList entries
;
754 log
.GetEntries(&entries
);
755 FilterLogEntries(&entries
);
757 EXPECT_EQ(8u, entries
.size());
758 EXPECT_TRUE(net::LogContainsBeginEvent(
759 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
760 EXPECT_TRUE(net::LogContainsEndEvent(
761 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
762 EXPECT_TRUE(net::LogContainsBeginEvent(
763 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
764 EXPECT_TRUE(net::LogContainsEndEvent(
765 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
766 EXPECT_TRUE(net::LogContainsBeginEvent(
767 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
768 EXPECT_TRUE(net::LogContainsEndEvent(
769 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
770 EXPECT_TRUE(net::LogContainsBeginEvent(
771 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
772 EXPECT_TRUE(net::LogContainsEndEvent(
773 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
775 TestLoadTimingNetworkRequest(load_timing_info
);
777 // Force this transaction to read from the cache.
778 MockTransaction
transaction(kSimpleGET_Transaction
);
779 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
783 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
786 // Check that the NetLog was filled as expected.
787 log
.GetEntries(&entries
);
788 FilterLogEntries(&entries
);
790 EXPECT_EQ(8u, entries
.size());
791 EXPECT_TRUE(net::LogContainsBeginEvent(
792 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
793 EXPECT_TRUE(net::LogContainsEndEvent(
794 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
795 EXPECT_TRUE(net::LogContainsBeginEvent(
796 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
797 EXPECT_TRUE(net::LogContainsEndEvent(
798 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
799 EXPECT_TRUE(net::LogContainsBeginEvent(
800 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
801 EXPECT_TRUE(net::LogContainsEndEvent(
802 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
803 EXPECT_TRUE(net::LogContainsBeginEvent(
804 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
805 EXPECT_TRUE(net::LogContainsEndEvent(
806 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
808 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
809 EXPECT_EQ(1, cache
.disk_cache()->open_count());
810 EXPECT_EQ(1, cache
.disk_cache()->create_count());
811 TestLoadTimingCachedResponse(load_timing_info
);
814 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
817 // force this transaction to read from the cache
818 MockTransaction
transaction(kSimpleGET_Transaction
);
819 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
821 MockHttpRequest
request(transaction
);
822 net::TestCompletionCallback callback
;
824 scoped_ptr
<net::HttpTransaction
> trans
;
825 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
827 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
828 if (rv
== net::ERR_IO_PENDING
)
829 rv
= callback
.WaitForResult();
830 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
834 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
835 EXPECT_EQ(0, cache
.disk_cache()->open_count());
836 EXPECT_EQ(0, cache
.disk_cache()->create_count());
839 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
842 // write to the cache
843 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
845 // force this transaction to read from the cache if valid
846 MockTransaction
transaction(kSimpleGET_Transaction
);
847 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
849 RunTransactionTest(cache
.http_cache(), transaction
);
851 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
852 EXPECT_EQ(1, cache
.disk_cache()->open_count());
853 EXPECT_EQ(1, cache
.disk_cache()->create_count());
856 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
859 // force this transaction to read from the cache if valid
860 MockTransaction
transaction(kSimpleGET_Transaction
);
861 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
863 RunTransactionTest(cache
.http_cache(), transaction
);
865 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
866 EXPECT_EQ(0, cache
.disk_cache()->open_count());
867 EXPECT_EQ(1, cache
.disk_cache()->create_count());
870 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
871 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
874 // Write to the cache.
875 MockTransaction
transaction(kSimpleGET_Transaction
);
876 transaction
.request_headers
= "Foo: bar\r\n";
877 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
879 AddMockTransaction(&transaction
);
880 RunTransactionTest(cache
.http_cache(), transaction
);
882 // Read from the cache.
883 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
884 RunTransactionTest(cache
.http_cache(), transaction
);
886 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
887 EXPECT_EQ(1, cache
.disk_cache()->open_count());
888 EXPECT_EQ(1, cache
.disk_cache()->create_count());
889 RemoveMockTransaction(&transaction
);
892 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
893 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
896 // Write to the cache.
897 MockTransaction
transaction(kSimpleGET_Transaction
);
898 transaction
.request_headers
= "Foo: bar\r\n";
899 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
901 AddMockTransaction(&transaction
);
902 RunTransactionTest(cache
.http_cache(), transaction
);
904 // Attempt to read from the cache... this is a vary mismatch that must reach
905 // the network again.
906 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
907 transaction
.request_headers
= "Foo: none\r\n";
908 net::CapturingBoundNetLog log
;
909 net::LoadTimingInfo load_timing_info
;
910 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
913 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
914 EXPECT_EQ(1, cache
.disk_cache()->open_count());
915 EXPECT_EQ(1, cache
.disk_cache()->create_count());
916 TestLoadTimingNetworkRequest(load_timing_info
);
917 RemoveMockTransaction(&transaction
);
920 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
922 TEST(HttpCache
, SimpleGET_CacheOverride_Network
) {
926 MockTransaction
transaction(kSimpleGET_Transaction
);
927 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
928 transaction
.response_headers
= "Cache-Control: no-cache\n";
930 AddMockTransaction(&transaction
);
931 RunTransactionTest(cache
.http_cache(), transaction
);
932 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
933 EXPECT_EQ(1, cache
.disk_cache()->create_count());
934 RemoveMockTransaction(&transaction
);
936 // Re-run transaction; make sure the result came from the network,
938 transaction
.data
= "Changed data.";
939 AddMockTransaction(&transaction
);
940 net::HttpResponseInfo response_info
;
941 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
944 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
945 EXPECT_FALSE(response_info
.server_data_unavailable
);
946 EXPECT_TRUE(response_info
.network_accessed
);
948 RemoveMockTransaction(&transaction
);
951 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
953 TEST(HttpCache
, SimpleGET_CacheOverride_Offline
) {
957 MockTransaction
transaction(kSimpleGET_Transaction
);
958 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
959 transaction
.response_headers
= "Cache-Control: no-cache\n";
961 AddMockTransaction(&transaction
);
962 RunTransactionTest(cache
.http_cache(), transaction
);
963 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
964 EXPECT_EQ(1, cache
.disk_cache()->create_count());
965 RemoveMockTransaction(&transaction
);
967 // Network failure with offline error; should return cache entry above +
968 // flag signalling stale data.
969 transaction
.return_code
= net::ERR_NAME_NOT_RESOLVED
;
970 AddMockTransaction(&transaction
);
972 MockHttpRequest
request(transaction
);
973 net::TestCompletionCallback callback
;
974 scoped_ptr
<net::HttpTransaction
> trans
;
975 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
976 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
977 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
979 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
980 ASSERT_TRUE(response_info
);
981 EXPECT_TRUE(response_info
->server_data_unavailable
);
982 EXPECT_TRUE(response_info
->was_cached
);
983 EXPECT_FALSE(response_info
->network_accessed
);
984 ReadAndVerifyTransaction(trans
.get(), transaction
);
985 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
987 RemoveMockTransaction(&transaction
);
990 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
991 // non-offline failure.
992 TEST(HttpCache
, SimpleGET_CacheOverride_NonOffline
) {
996 MockTransaction
transaction(kSimpleGET_Transaction
);
997 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
998 transaction
.response_headers
= "Cache-Control: no-cache\n";
1000 AddMockTransaction(&transaction
);
1001 RunTransactionTest(cache
.http_cache(), transaction
);
1002 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1003 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1004 RemoveMockTransaction(&transaction
);
1006 // Network failure with non-offline error; should fail with that error.
1007 transaction
.return_code
= net::ERR_PROXY_CONNECTION_FAILED
;
1008 AddMockTransaction(&transaction
);
1010 net::HttpResponseInfo response_info2
;
1011 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1014 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1015 EXPECT_FALSE(response_info2
.server_data_unavailable
);
1017 RemoveMockTransaction(&transaction
);
1020 // Tests that was_cached was set properly on a failure, even if the cached
1021 // response wasn't returned.
1022 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
1023 MockHttpCache cache
;
1026 MockTransaction
transaction(kSimpleGET_Transaction
);
1027 transaction
.response_headers
= "Cache-Control: no-cache\n";
1029 AddMockTransaction(&transaction
);
1030 RunTransactionTest(cache
.http_cache(), transaction
);
1031 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1032 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1033 RemoveMockTransaction(&transaction
);
1035 // Network failure with error; should fail but have was_cached set.
1036 transaction
.return_code
= net::ERR_FAILED
;
1037 AddMockTransaction(&transaction
);
1039 MockHttpRequest
request(transaction
);
1040 net::TestCompletionCallback callback
;
1041 scoped_ptr
<net::HttpTransaction
> trans
;
1042 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
1043 EXPECT_EQ(net::OK
, rv
);
1044 ASSERT_TRUE(trans
.get());
1045 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1046 EXPECT_EQ(net::ERR_FAILED
, callback
.GetResult(rv
));
1048 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1049 ASSERT_TRUE(response_info
);
1050 EXPECT_TRUE(response_info
->was_cached
);
1051 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1053 RemoveMockTransaction(&transaction
);
1056 // Confirm if we have an empty cache, a read is marked as network verified.
1057 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1058 MockHttpCache cache
;
1060 // write to the cache
1061 net::HttpResponseInfo response_info
;
1062 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1065 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1066 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1067 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1068 EXPECT_TRUE(response_info
.network_accessed
);
1071 // Confirm if we have a fresh entry in cache, it isn't marked as
1072 // network verified.
1073 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1074 MockHttpCache cache
;
1077 MockTransaction
transaction(kSimpleGET_Transaction
);
1079 RunTransactionTest(cache
.http_cache(), transaction
);
1080 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1081 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1083 // Re-run transaction; make sure we don't mark the network as accessed.
1084 net::HttpResponseInfo response_info
;
1085 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1088 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1089 EXPECT_FALSE(response_info
.server_data_unavailable
);
1090 EXPECT_FALSE(response_info
.network_accessed
);
1093 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1094 MockHttpCache cache
;
1096 // Write to the cache.
1097 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1099 // Force this transaction to write to the cache again.
1100 MockTransaction
transaction(kSimpleGET_Transaction
);
1101 transaction
.load_flags
|= net::LOAD_BYPASS_CACHE
;
1103 net::CapturingBoundNetLog log
;
1104 net::LoadTimingInfo load_timing_info
;
1106 // Write to the cache.
1107 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1110 // Check that the NetLog was filled as expected.
1111 net::CapturingNetLog::CapturedEntryList entries
;
1112 log
.GetEntries(&entries
);
1113 FilterLogEntries(&entries
);
1115 EXPECT_EQ(8u, entries
.size());
1116 EXPECT_TRUE(net::LogContainsBeginEvent(
1117 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1118 EXPECT_TRUE(net::LogContainsEndEvent(
1119 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1120 EXPECT_TRUE(net::LogContainsBeginEvent(
1121 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1122 EXPECT_TRUE(net::LogContainsEndEvent(
1123 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1124 EXPECT_TRUE(net::LogContainsBeginEvent(
1125 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1126 EXPECT_TRUE(net::LogContainsEndEvent(
1127 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1128 EXPECT_TRUE(net::LogContainsBeginEvent(
1129 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1130 EXPECT_TRUE(net::LogContainsEndEvent(
1131 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1133 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1134 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1135 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1136 TestLoadTimingNetworkRequest(load_timing_info
);
1139 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1140 MockHttpCache cache
;
1142 // write to the cache
1143 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1145 // force this transaction to write to the cache again
1146 MockTransaction
transaction(kSimpleGET_Transaction
);
1147 transaction
.request_headers
= "pragma: no-cache\r\n";
1149 RunTransactionTest(cache
.http_cache(), transaction
);
1151 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1152 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1153 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1156 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1157 MockHttpCache cache
;
1159 // write to the cache
1160 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1162 // force this transaction to write to the cache again
1163 MockTransaction
transaction(kSimpleGET_Transaction
);
1164 transaction
.request_headers
= "cache-control: no-cache\r\n";
1166 RunTransactionTest(cache
.http_cache(), transaction
);
1168 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1169 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1170 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1173 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1174 MockHttpCache cache
;
1176 // Write to the cache.
1177 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1179 // Read from the cache.
1180 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1182 // Force this transaction to validate the cache.
1183 MockTransaction
transaction(kSimpleGET_Transaction
);
1184 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
1186 net::HttpResponseInfo response_info
;
1187 net::CapturingBoundNetLog log
;
1188 net::LoadTimingInfo load_timing_info
;
1189 RunTransactionTestWithResponseInfoAndGetTiming(
1190 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1193 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1194 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1195 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1196 EXPECT_TRUE(response_info
.network_accessed
);
1197 TestLoadTimingNetworkRequest(load_timing_info
);
1200 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1201 MockHttpCache cache
;
1203 // write to the cache
1204 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1206 // read from the cache
1207 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1209 // force this transaction to validate the cache
1210 MockTransaction
transaction(kSimpleGET_Transaction
);
1211 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1213 RunTransactionTest(cache
.http_cache(), transaction
);
1215 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1216 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1217 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1220 static void PreserveRequestHeaders_Handler(
1221 const net::HttpRequestInfo
* request
,
1222 std::string
* response_status
,
1223 std::string
* response_headers
,
1224 std::string
* response_data
) {
1225 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1228 // Tests that we don't remove extra headers for simple requests.
1229 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1230 MockHttpCache cache
;
1232 MockTransaction
transaction(kSimpleGET_Transaction
);
1233 transaction
.handler
= PreserveRequestHeaders_Handler
;
1234 transaction
.request_headers
= EXTRA_HEADER
;
1235 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1236 AddMockTransaction(&transaction
);
1238 // Write, then revalidate the entry.
1239 RunTransactionTest(cache
.http_cache(), transaction
);
1240 RunTransactionTest(cache
.http_cache(), transaction
);
1242 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1243 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1244 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1245 RemoveMockTransaction(&transaction
);
1248 // Tests that we don't remove extra headers for conditionalized requests.
1249 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1250 MockHttpCache cache
;
1252 // Write to the cache.
1253 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1255 MockTransaction
transaction(kETagGET_Transaction
);
1256 transaction
.handler
= PreserveRequestHeaders_Handler
;
1257 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1259 AddMockTransaction(&transaction
);
1261 RunTransactionTest(cache
.http_cache(), transaction
);
1263 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1264 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1265 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1266 RemoveMockTransaction(&transaction
);
1269 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1270 MockHttpCache cache
;
1272 MockHttpRequest
request(kSimpleGET_Transaction
);
1274 std::vector
<Context
*> context_list
;
1275 const int kNumTransactions
= 5;
1277 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1278 context_list
.push_back(new Context());
1279 Context
* c
= context_list
[i
];
1281 c
->result
= cache
.CreateTransaction(&c
->trans
);
1282 ASSERT_EQ(net::OK
, c
->result
);
1283 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1285 c
->result
= c
->trans
->Start(
1286 &request
, c
->callback
.callback(), net::BoundNetLog());
1289 // All requests are waiting for the active entry.
1290 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1291 Context
* c
= context_list
[i
];
1292 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1295 // Allow all requests to move from the Create queue to the active entry.
1296 base::MessageLoop::current()->RunUntilIdle();
1298 // The first request should be a writer at this point, and the subsequent
1299 // requests should be pending.
1301 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1302 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1303 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1305 // All requests depend on the writer, and the writer is between Start and
1307 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1308 Context
* c
= context_list
[i
];
1309 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1312 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1313 Context
* c
= context_list
[i
];
1314 if (c
->result
== net::ERR_IO_PENDING
)
1315 c
->result
= c
->callback
.WaitForResult();
1316 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1319 // We should not have had to re-open the disk entry
1321 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1322 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1323 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1325 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1326 Context
* c
= context_list
[i
];
1331 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1332 // If cancelling a request is racing with another request for the same resource
1333 // finishing, we have to make sure that we remove both transactions from the
1335 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1336 MockHttpCache cache
;
1338 MockHttpRequest
request(kSimpleGET_Transaction
);
1339 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1340 reader_request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
1342 std::vector
<Context
*> context_list
;
1343 const int kNumTransactions
= 5;
1345 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1346 context_list
.push_back(new Context());
1347 Context
* c
= context_list
[i
];
1349 c
->result
= cache
.CreateTransaction(&c
->trans
);
1350 ASSERT_EQ(net::OK
, c
->result
);
1352 MockHttpRequest
* this_request
= &request
;
1353 if (i
== 1 || i
== 2)
1354 this_request
= &reader_request
;
1356 c
->result
= c
->trans
->Start(
1357 this_request
, c
->callback
.callback(), net::BoundNetLog());
1360 // Allow all requests to move from the Create queue to the active entry.
1361 base::MessageLoop::current()->RunUntilIdle();
1363 // The first request should be a writer at this point, and the subsequent
1364 // requests should be pending.
1366 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1367 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1368 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1370 Context
* c
= context_list
[0];
1371 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1372 c
->result
= c
->callback
.WaitForResult();
1373 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1375 // Now we have 2 active readers and two queued transactions.
1377 EXPECT_EQ(net::LOAD_STATE_IDLE
,
1378 context_list
[2]->trans
->GetLoadState());
1379 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
,
1380 context_list
[3]->trans
->GetLoadState());
1382 c
= context_list
[1];
1383 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1384 c
->result
= c
->callback
.WaitForResult();
1385 if (c
->result
== net::OK
)
1386 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1388 // At this point we have one reader, two pending transactions and a task on
1389 // the queue to move to the next transaction. Now we cancel the request that
1390 // is the current reader, and expect the queued task to be able to start the
1393 c
= context_list
[2];
1396 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1397 Context
* c
= context_list
[i
];
1398 if (c
->result
== net::ERR_IO_PENDING
)
1399 c
->result
= c
->callback
.WaitForResult();
1400 if (c
->result
== net::OK
)
1401 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1404 // We should not have had to re-open the disk entry.
1406 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1407 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1408 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1410 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1411 Context
* c
= context_list
[i
];
1416 // Tests that we can doom an entry with pending transactions and delete one of
1417 // the pending transactions before the first one completes.
1418 // See http://code.google.com/p/chromium/issues/detail?id=25588
1419 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1420 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1421 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1423 MockHttpRequest
request(kSimpleGET_Transaction
);
1424 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1425 writer_request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1427 ScopedVector
<Context
> context_list
;
1428 const int kNumTransactions
= 4;
1430 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1431 context_list
.push_back(new Context());
1432 Context
* c
= context_list
[i
];
1434 c
->result
= cache
.CreateTransaction(&c
->trans
);
1435 ASSERT_EQ(net::OK
, c
->result
);
1437 MockHttpRequest
* this_request
= &request
;
1439 this_request
= &writer_request
;
1441 c
->result
= c
->trans
->Start(
1442 this_request
, c
->callback
.callback(), net::BoundNetLog());
1445 // The first request should be a writer at this point, and the two subsequent
1446 // requests should be pending. The last request doomed the first entry.
1448 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1450 // Cancel the first queued transaction.
1451 delete context_list
[1];
1452 context_list
.get()[1] = NULL
;
1454 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1457 Context
* c
= context_list
[i
];
1458 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1459 c
->result
= c
->callback
.WaitForResult();
1460 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1464 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1465 // We may attempt to delete an entry synchronously with the act of adding a new
1466 // transaction to said entry.
1467 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1468 MockHttpCache cache
;
1470 // The headers will be served right from the call to Start() the request.
1471 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1472 FastTransactionServer request_handler
;
1473 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1475 std::vector
<Context
*> context_list
;
1476 const int kNumTransactions
= 3;
1478 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1479 context_list
.push_back(new Context());
1480 Context
* c
= context_list
[i
];
1482 c
->result
= cache
.CreateTransaction(&c
->trans
);
1483 ASSERT_EQ(net::OK
, c
->result
);
1485 c
->result
= c
->trans
->Start(
1486 &request
, c
->callback
.callback(), net::BoundNetLog());
1489 // Allow all requests to move from the Create queue to the active entry.
1490 base::MessageLoop::current()->RunUntilIdle();
1492 // The first request should be a writer at this point, and the subsequent
1493 // requests should be pending.
1495 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1496 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1497 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1499 // Now, make sure that the second request asks for the entry not to be stored.
1500 request_handler
.set_no_store(true);
1502 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1503 Context
* c
= context_list
[i
];
1504 if (c
->result
== net::ERR_IO_PENDING
)
1505 c
->result
= c
->callback
.WaitForResult();
1506 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1510 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1511 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1512 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1514 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1517 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1518 MockHttpCache cache
;
1520 MockHttpRequest
request(kSimpleGET_Transaction
);
1522 std::vector
<Context
*> context_list
;
1523 const int kNumTransactions
= 2;
1525 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1526 context_list
.push_back(new Context());
1527 Context
* c
= context_list
[i
];
1529 c
->result
= cache
.CreateTransaction(&c
->trans
);
1530 ASSERT_EQ(net::OK
, c
->result
);
1532 c
->result
= c
->trans
->Start(
1533 &request
, c
->callback
.callback(), net::BoundNetLog());
1536 // Allow all requests to move from the Create queue to the active entry.
1537 base::MessageLoop::current()->RunUntilIdle();
1539 // The first request should be a writer at this point, and the subsequent
1540 // requests should be pending.
1542 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1543 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1544 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1546 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1547 Context
* c
= context_list
[i
];
1548 if (c
->result
== net::ERR_IO_PENDING
)
1549 c
->result
= c
->callback
.WaitForResult();
1550 // Destroy only the first transaction.
1553 context_list
[i
] = NULL
;
1557 // Complete the rest of the transactions.
1558 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1559 Context
* c
= context_list
[i
];
1560 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1563 // We should have had to re-open the disk entry.
1565 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1566 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1567 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1569 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1570 Context
* c
= context_list
[i
];
1575 // Tests that we can cancel requests that are queued waiting to open the disk
1577 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1578 MockHttpCache cache
;
1580 MockHttpRequest
request(kSimpleGET_Transaction
);
1582 std::vector
<Context
*> context_list
;
1583 const int kNumTransactions
= 5;
1585 for (int i
= 0; i
< kNumTransactions
; i
++) {
1586 context_list
.push_back(new Context());
1587 Context
* c
= context_list
[i
];
1589 c
->result
= cache
.CreateTransaction(&c
->trans
);
1590 ASSERT_EQ(net::OK
, c
->result
);
1592 c
->result
= c
->trans
->Start(
1593 &request
, c
->callback
.callback(), net::BoundNetLog());
1596 // The first request should be creating the disk cache entry and the others
1597 // should be pending.
1599 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1600 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1601 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1603 // Cancel a request from the pending queue.
1604 delete context_list
[3];
1605 context_list
[3] = NULL
;
1607 // Cancel the request that is creating the entry. This will force the pending
1608 // operations to restart.
1609 delete context_list
[0];
1610 context_list
[0] = NULL
;
1612 // Complete the rest of the transactions.
1613 for (int i
= 1; i
< kNumTransactions
; i
++) {
1614 Context
* c
= context_list
[i
];
1616 c
->result
= c
->callback
.GetResult(c
->result
);
1617 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1621 // We should have had to re-create the disk entry.
1623 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1624 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1625 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1627 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1628 delete context_list
[i
];
1632 // Tests that we can cancel a single request to open a disk cache entry.
1633 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1634 MockHttpCache cache
;
1636 MockHttpRequest
request(kSimpleGET_Transaction
);
1638 Context
* c
= new Context();
1640 c
->result
= cache
.CreateTransaction(&c
->trans
);
1641 ASSERT_EQ(net::OK
, c
->result
);
1643 c
->result
= c
->trans
->Start(
1644 &request
, c
->callback
.callback(), net::BoundNetLog());
1645 EXPECT_EQ(net::ERR_IO_PENDING
, c
->result
);
1647 // Release the reference that the mock disk cache keeps for this entry, so
1648 // that we test that the http cache handles the cancellation correctly.
1649 cache
.disk_cache()->ReleaseAll();
1652 base::MessageLoop::current()->RunUntilIdle();
1653 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1656 // Tests that we delete/create entries even if multiple requests are queued.
1657 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1658 MockHttpCache cache
;
1660 MockHttpRequest
request(kSimpleGET_Transaction
);
1661 request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1663 std::vector
<Context
*> context_list
;
1664 const int kNumTransactions
= 5;
1666 for (int i
= 0; i
< kNumTransactions
; i
++) {
1667 context_list
.push_back(new Context());
1668 Context
* c
= context_list
[i
];
1670 c
->result
= cache
.CreateTransaction(&c
->trans
);
1671 ASSERT_EQ(net::OK
, c
->result
);
1673 c
->result
= c
->trans
->Start(
1674 &request
, c
->callback
.callback(), net::BoundNetLog());
1677 // The first request should be deleting the disk cache entry and the others
1678 // should be pending.
1680 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1681 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1682 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1684 // Complete the transactions.
1685 for (int i
= 0; i
< kNumTransactions
; i
++) {
1686 Context
* c
= context_list
[i
];
1687 c
->result
= c
->callback
.GetResult(c
->result
);
1688 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1691 // We should have had to re-create the disk entry multiple times.
1693 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1694 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1695 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1697 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1698 delete context_list
[i
];
1702 // Tests that a (simulated) timeout allows transactions waiting on the cache
1703 // lock to continue.
1704 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1705 MockHttpCache cache
;
1706 cache
.BypassCacheLock();
1708 MockHttpRequest
request(kSimpleGET_Transaction
);
1710 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c1
.trans
));
1711 ASSERT_EQ(net::ERR_IO_PENDING
,
1712 c1
.trans
->Start(&request
, c1
.callback
.callback(),
1713 net::BoundNetLog()));
1714 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c2
.trans
));
1715 ASSERT_EQ(net::ERR_IO_PENDING
,
1716 c2
.trans
->Start(&request
, c2
.callback
.callback(),
1717 net::BoundNetLog()));
1719 // The second request is queued after the first one.
1721 c2
.callback
.WaitForResult();
1722 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1724 // Complete the first transaction.
1725 c1
.callback
.WaitForResult();
1726 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1729 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1730 MockHttpCache cache
;
1732 // write to the cache
1733 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1735 MockHttpRequest
request(kSimpleGET_Transaction
);
1736 net::TestCompletionCallback callback
;
1738 scoped_ptr
<net::HttpTransaction
> trans
;
1739 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1740 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1741 if (rv
== net::ERR_IO_PENDING
)
1742 rv
= callback
.WaitForResult();
1743 ASSERT_EQ(net::OK
, rv
);
1745 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
1746 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1747 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1749 // Test that destroying the transaction while it is reading from the cache
1753 // Make sure we pump any pending events, which should include a call to
1754 // HttpCache::Transaction::OnCacheReadCompleted.
1755 base::MessageLoop::current()->RunUntilIdle();
1758 // Tests that we can delete the HttpCache and deal with queued transactions
1759 // ("waiting for the backend" as opposed to Active or Doomed entries).
1760 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1761 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1762 new MockBackendNoCbFactory()));
1764 MockHttpRequest
request(kSimpleGET_Transaction
);
1766 std::vector
<Context
*> context_list
;
1767 const int kNumTransactions
= 5;
1769 for (int i
= 0; i
< kNumTransactions
; i
++) {
1770 context_list
.push_back(new Context());
1771 Context
* c
= context_list
[i
];
1773 c
->result
= cache
->CreateTransaction(&c
->trans
);
1774 ASSERT_EQ(net::OK
, c
->result
);
1776 c
->result
= c
->trans
->Start(
1777 &request
, c
->callback
.callback(), net::BoundNetLog());
1780 // The first request should be creating the disk cache entry and the others
1781 // should be pending.
1783 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1784 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1785 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1789 // There is not much to do with the transactions at this point... they are
1790 // waiting for a callback that will not fire.
1791 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1792 delete context_list
[i
];
1796 // Tests that we queue requests when initializing the backend.
1797 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1798 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1799 MockHttpCache
cache(factory
);
1801 MockHttpRequest
request0(kSimpleGET_Transaction
);
1802 MockHttpRequest
request1(kTypicalGET_Transaction
);
1803 MockHttpRequest
request2(kETagGET_Transaction
);
1805 std::vector
<Context
*> context_list
;
1806 const int kNumTransactions
= 3;
1808 for (int i
= 0; i
< kNumTransactions
; i
++) {
1809 context_list
.push_back(new Context());
1810 Context
* c
= context_list
[i
];
1812 c
->result
= cache
.CreateTransaction(&c
->trans
);
1813 ASSERT_EQ(net::OK
, c
->result
);
1816 context_list
[0]->result
= context_list
[0]->trans
->Start(
1817 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1818 context_list
[1]->result
= context_list
[1]->trans
->Start(
1819 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1820 context_list
[2]->result
= context_list
[2]->trans
->Start(
1821 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1823 // Just to make sure that everything is still pending.
1824 base::MessageLoop::current()->RunUntilIdle();
1826 // The first request should be creating the disk cache.
1827 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1829 factory
->FinishCreation();
1831 base::MessageLoop::current()->RunUntilIdle();
1832 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1833 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1835 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1836 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1837 delete context_list
[i
];
1841 // Tests that we can cancel requests that are queued waiting for the backend
1842 // to be initialized.
1843 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1844 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1845 MockHttpCache
cache(factory
);
1847 MockHttpRequest
request0(kSimpleGET_Transaction
);
1848 MockHttpRequest
request1(kTypicalGET_Transaction
);
1849 MockHttpRequest
request2(kETagGET_Transaction
);
1851 std::vector
<Context
*> context_list
;
1852 const int kNumTransactions
= 3;
1854 for (int i
= 0; i
< kNumTransactions
; i
++) {
1855 context_list
.push_back(new Context());
1856 Context
* c
= context_list
[i
];
1858 c
->result
= cache
.CreateTransaction(&c
->trans
);
1859 ASSERT_EQ(net::OK
, c
->result
);
1862 context_list
[0]->result
= context_list
[0]->trans
->Start(
1863 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1864 context_list
[1]->result
= context_list
[1]->trans
->Start(
1865 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1866 context_list
[2]->result
= context_list
[2]->trans
->Start(
1867 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1869 // Just to make sure that everything is still pending.
1870 base::MessageLoop::current()->RunUntilIdle();
1872 // The first request should be creating the disk cache.
1873 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1875 // Cancel a request from the pending queue.
1876 delete context_list
[1];
1877 context_list
[1] = NULL
;
1879 // Cancel the request that is creating the entry.
1880 delete context_list
[0];
1881 context_list
[0] = NULL
;
1883 // Complete the last transaction.
1884 factory
->FinishCreation();
1886 context_list
[2]->result
=
1887 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1888 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1890 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1891 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1893 delete context_list
[2];
1896 // Tests that we can delete the cache while creating the backend.
1897 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1898 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1899 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1901 MockHttpRequest
request(kSimpleGET_Transaction
);
1903 scoped_ptr
<Context
> c(new Context());
1904 c
->result
= cache
->CreateTransaction(&c
->trans
);
1905 ASSERT_EQ(net::OK
, c
->result
);
1907 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1909 // Just to make sure that everything is still pending.
1910 base::MessageLoop::current()->RunUntilIdle();
1912 // The request should be creating the disk cache.
1913 EXPECT_FALSE(c
->callback
.have_result());
1915 // We cannot call FinishCreation because the factory itself will go away with
1916 // the cache, so grab the callback and attempt to use it.
1917 net::CompletionCallback callback
= factory
->callback();
1918 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1921 base::MessageLoop::current()->RunUntilIdle();
1924 callback
.Run(net::ERR_ABORTED
);
1927 // Tests that we can delete the cache while creating the backend, from within
1928 // one of the callbacks.
1929 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1930 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1931 MockHttpCache
* cache
= new MockHttpCache(factory
);
1933 DeleteCacheCompletionCallback
cb(cache
);
1934 disk_cache::Backend
* backend
;
1935 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1936 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1938 // Now let's queue a regular transaction
1939 MockHttpRequest
request(kSimpleGET_Transaction
);
1941 scoped_ptr
<Context
> c(new Context());
1942 c
->result
= cache
->CreateTransaction(&c
->trans
);
1943 ASSERT_EQ(net::OK
, c
->result
);
1945 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1947 // And another direct backend request.
1948 net::TestCompletionCallback cb2
;
1949 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1950 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1952 // Just to make sure that everything is still pending.
1953 base::MessageLoop::current()->RunUntilIdle();
1955 // The request should be queued.
1956 EXPECT_FALSE(c
->callback
.have_result());
1958 // Generate the callback.
1959 factory
->FinishCreation();
1960 rv
= cb
.WaitForResult();
1962 // The cache should be gone by now.
1963 base::MessageLoop::current()->RunUntilIdle();
1964 EXPECT_EQ(net::OK
, c
->callback
.GetResult(c
->result
));
1965 EXPECT_FALSE(cb2
.have_result());
1968 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
1969 MockHttpCache cache
;
1971 // write to the cache
1972 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
1974 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1975 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1976 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1978 // Get the same URL again, but this time we expect it to result
1979 // in a conditional request.
1980 net::CapturingBoundNetLog log
;
1981 net::LoadTimingInfo load_timing_info
;
1982 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
1983 log
.bound(), &load_timing_info
);
1985 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1986 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1987 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1988 TestLoadTimingNetworkRequest(load_timing_info
);
1991 static void ETagGet_ConditionalRequest_Handler(
1992 const net::HttpRequestInfo
* request
,
1993 std::string
* response_status
,
1994 std::string
* response_headers
,
1995 std::string
* response_data
) {
1997 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
1998 response_status
->assign("HTTP/1.1 304 Not Modified");
1999 response_headers
->assign(kETagGET_Transaction
.response_headers
);
2000 response_data
->clear();
2003 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
2004 MockHttpCache cache
;
2006 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2008 // write to the cache
2009 RunTransactionTest(cache
.http_cache(), transaction
);
2011 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2012 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2013 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2015 // Get the same URL again, but this time we expect it to result
2016 // in a conditional request.
2017 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2018 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
2019 net::CapturingBoundNetLog log
;
2020 net::LoadTimingInfo load_timing_info
;
2021 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2024 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2025 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2026 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2027 TestLoadTimingNetworkRequest(load_timing_info
);
2030 class RevalidationServer
{
2032 RevalidationServer() {
2033 s_etag_used_
= false;
2034 s_last_modified_used_
= false;
2037 bool EtagUsed() { return s_etag_used_
; }
2038 bool LastModifiedUsed() { return s_last_modified_used_
; }
2040 static void Handler(const net::HttpRequestInfo
* request
,
2041 std::string
* response_status
,
2042 std::string
* response_headers
,
2043 std::string
* response_data
);
2046 static bool s_etag_used_
;
2047 static bool s_last_modified_used_
;
2049 bool RevalidationServer::s_etag_used_
= false;
2050 bool RevalidationServer::s_last_modified_used_
= false;
2052 void RevalidationServer::Handler(const net::HttpRequestInfo
* request
,
2053 std::string
* response_status
,
2054 std::string
* response_headers
,
2055 std::string
* response_data
) {
2056 if (request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
))
2057 s_etag_used_
= true;
2059 if (request
->extra_headers
.HasHeader(
2060 net::HttpRequestHeaders::kIfModifiedSince
)) {
2061 s_last_modified_used_
= true;
2064 if (s_etag_used_
|| s_last_modified_used_
) {
2065 response_status
->assign("HTTP/1.1 304 Not Modified");
2066 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2067 response_data
->clear();
2069 response_status
->assign(kTypicalGET_Transaction
.status
);
2070 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2071 response_data
->assign(kTypicalGET_Transaction
.data
);
2075 // Tests revalidation after a vary match.
2076 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMatch
) {
2077 MockHttpCache cache
;
2079 // Write to the cache.
2080 MockTransaction
transaction(kTypicalGET_Transaction
);
2081 transaction
.request_headers
= "Foo: bar\r\n";
2082 transaction
.response_headers
=
2083 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2084 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2086 "Cache-Control: max-age=0\n"
2088 AddMockTransaction(&transaction
);
2089 RunTransactionTest(cache
.http_cache(), transaction
);
2091 // Read from the cache.
2092 RevalidationServer server
;
2093 transaction
.handler
= server
.Handler
;
2094 net::CapturingBoundNetLog log
;
2095 net::LoadTimingInfo load_timing_info
;
2096 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2099 EXPECT_TRUE(server
.EtagUsed());
2100 EXPECT_TRUE(server
.LastModifiedUsed());
2101 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2102 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2103 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2104 TestLoadTimingNetworkRequest(load_timing_info
);
2105 RemoveMockTransaction(&transaction
);
2108 // Tests revalidation after a vary mismatch if etag is present.
2109 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMismatch
) {
2110 MockHttpCache cache
;
2112 // Write to the cache.
2113 MockTransaction
transaction(kTypicalGET_Transaction
);
2114 transaction
.request_headers
= "Foo: bar\r\n";
2115 transaction
.response_headers
=
2116 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2117 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2119 "Cache-Control: max-age=0\n"
2121 AddMockTransaction(&transaction
);
2122 RunTransactionTest(cache
.http_cache(), transaction
);
2124 // Read from the cache and revalidate the entry.
2125 RevalidationServer server
;
2126 transaction
.handler
= server
.Handler
;
2127 transaction
.request_headers
= "Foo: none\r\n";
2128 net::CapturingBoundNetLog log
;
2129 net::LoadTimingInfo load_timing_info
;
2130 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2133 EXPECT_TRUE(server
.EtagUsed());
2134 EXPECT_FALSE(server
.LastModifiedUsed());
2135 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2136 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2137 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2138 TestLoadTimingNetworkRequest(load_timing_info
);
2139 RemoveMockTransaction(&transaction
);
2142 // Tests lack of revalidation after a vary mismatch and no etag.
2143 TEST(HttpCache
, SimpleGET_LoadDontValidateCache_VaryMismatch
) {
2144 MockHttpCache cache
;
2146 // Write to the cache.
2147 MockTransaction
transaction(kTypicalGET_Transaction
);
2148 transaction
.request_headers
= "Foo: bar\r\n";
2149 transaction
.response_headers
=
2150 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2151 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2152 "Cache-Control: max-age=0\n"
2154 AddMockTransaction(&transaction
);
2155 RunTransactionTest(cache
.http_cache(), transaction
);
2157 // Read from the cache and don't revalidate the entry.
2158 RevalidationServer server
;
2159 transaction
.handler
= server
.Handler
;
2160 transaction
.request_headers
= "Foo: none\r\n";
2161 net::CapturingBoundNetLog log
;
2162 net::LoadTimingInfo load_timing_info
;
2163 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2166 EXPECT_FALSE(server
.EtagUsed());
2167 EXPECT_FALSE(server
.LastModifiedUsed());
2168 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2169 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2170 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2171 TestLoadTimingNetworkRequest(load_timing_info
);
2172 RemoveMockTransaction(&transaction
);
2175 static void ETagGet_UnconditionalRequest_Handler(
2176 const net::HttpRequestInfo
* request
,
2177 std::string
* response_status
,
2178 std::string
* response_headers
,
2179 std::string
* response_data
) {
2181 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2184 TEST(HttpCache
, ETagGET_Http10
) {
2185 MockHttpCache cache
;
2187 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2188 transaction
.status
= "HTTP/1.0 200 OK";
2190 // Write to the cache.
2191 RunTransactionTest(cache
.http_cache(), transaction
);
2193 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2194 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2195 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2197 // Get the same URL again, without generating a conditional request.
2198 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2199 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2200 RunTransactionTest(cache
.http_cache(), transaction
);
2202 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2203 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2204 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2207 TEST(HttpCache
, ETagGET_Http10_Range
) {
2208 MockHttpCache cache
;
2210 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2211 transaction
.status
= "HTTP/1.0 200 OK";
2213 // Write to the cache.
2214 RunTransactionTest(cache
.http_cache(), transaction
);
2216 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2217 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2218 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2220 // Get the same URL again, but use a byte range request.
2221 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2222 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2223 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2224 RunTransactionTest(cache
.http_cache(), transaction
);
2226 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2227 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2228 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2231 static void ETagGet_ConditionalRequest_NoStore_Handler(
2232 const net::HttpRequestInfo
* request
,
2233 std::string
* response_status
,
2234 std::string
* response_headers
,
2235 std::string
* response_data
) {
2237 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2238 response_status
->assign("HTTP/1.1 304 Not Modified");
2239 response_headers
->assign("Cache-Control: no-store\n");
2240 response_data
->clear();
2243 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2244 MockHttpCache cache
;
2246 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2248 // Write to the cache.
2249 RunTransactionTest(cache
.http_cache(), transaction
);
2251 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2252 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2253 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2255 // Get the same URL again, but this time we expect it to result
2256 // in a conditional request.
2257 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2258 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2259 RunTransactionTest(cache
.http_cache(), transaction
);
2261 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2262 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2263 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2265 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2267 // Write to the cache again. This should create a new entry.
2268 RunTransactionTest(cache
.http_cache(), transaction2
);
2270 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2271 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2272 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2275 // Helper that does 4 requests using HttpCache:
2277 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2278 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2279 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2281 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2283 static void ConditionalizedRequestUpdatesCacheHelper(
2284 const Response
& net_response_1
,
2285 const Response
& net_response_2
,
2286 const Response
& cached_response_2
,
2287 const char* extra_request_headers
) {
2288 MockHttpCache cache
;
2290 // The URL we will be requesting.
2291 const char* kUrl
= "http://foobar.com/main.css";
2293 // Junk network response.
2294 static const Response kUnexpectedResponse
= {
2295 "HTTP/1.1 500 Unexpected",
2296 "Server: unexpected_header",
2300 // We will control the network layer's responses for |kUrl| using
2301 // |mock_network_response|.
2302 MockTransaction mock_network_response
= { 0 };
2303 mock_network_response
.url
= kUrl
;
2304 AddMockTransaction(&mock_network_response
);
2306 // Request |kUrl| for the first time. It should hit the network and
2307 // receive |kNetResponse1|, which it saves into the HTTP cache.
2309 MockTransaction request
= { 0 };
2311 request
.method
= "GET";
2312 request
.request_headers
= "";
2314 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2315 net_response_1
.AssignTo(&request
); // Expected result.
2317 std::string response_headers
;
2318 RunTransactionTestWithResponse(
2319 cache
.http_cache(), request
, &response_headers
);
2321 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2322 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2323 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2324 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2326 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2327 // cache, so we don't hit the network.
2329 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2331 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2332 net_response_1
.AssignTo(&request
); // Expected result.
2334 RunTransactionTestWithResponse(
2335 cache
.http_cache(), request
, &response_headers
);
2337 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2338 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2339 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2340 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2342 // Request |kUrl| yet again, but this time give the request an
2343 // "If-Modified-Since" header. This will cause the request to re-hit the
2344 // network. However now the network response is going to be
2345 // different -- this simulates a change made to the CSS file.
2347 request
.request_headers
= extra_request_headers
;
2348 request
.load_flags
= net::LOAD_NORMAL
;
2350 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2351 net_response_2
.AssignTo(&request
); // Expected result.
2353 RunTransactionTestWithResponse(
2354 cache
.http_cache(), request
, &response_headers
);
2356 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2357 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2358 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2359 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2361 // Finally, request |kUrl| again. This request should be serviced from
2362 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2363 // and NOT |kNetResponse1|. The previous step should have replaced the
2364 // value in the cache with the modified response.
2366 request
.request_headers
= "";
2367 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2369 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2370 cached_response_2
.AssignTo(&request
); // Expected result.
2372 RunTransactionTestWithResponse(
2373 cache
.http_cache(), request
, &response_headers
);
2375 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2376 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2377 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2378 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2380 RemoveMockTransaction(&mock_network_response
);
2383 // Check that when an "if-modified-since" header is attached
2384 // to the request, the result still updates the cached entry.
2385 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2386 // First network response for |kUrl|.
2387 static const Response kNetResponse1
= {
2389 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2390 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2394 // Second network response for |kUrl|.
2395 static const Response kNetResponse2
= {
2397 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2398 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2402 const char* extra_headers
=
2403 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2405 ConditionalizedRequestUpdatesCacheHelper(
2406 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2409 // Check that when an "if-none-match" header is attached
2410 // to the request, the result updates the cached entry.
2411 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2412 // First network response for |kUrl|.
2413 static const Response kNetResponse1
= {
2415 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2417 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2421 // Second network response for |kUrl|.
2422 static const Response kNetResponse2
= {
2424 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2426 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2430 const char* extra_headers
= "If-None-Match: \"ETAG1\"\r\n";
2432 ConditionalizedRequestUpdatesCacheHelper(
2433 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2436 // Check that when an "if-modified-since" header is attached
2437 // to a request, the 304 (not modified result) result updates the cached
2438 // headers, and the 304 response is returned rather than the cached response.
2439 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2440 // First network response for |kUrl|.
2441 static const Response kNetResponse1
= {
2443 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2445 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2449 // Second network response for |kUrl|.
2450 static const Response kNetResponse2
= {
2451 "HTTP/1.1 304 Not Modified",
2452 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2454 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2458 static const Response kCachedResponse2
= {
2460 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2462 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2466 const char* extra_headers
=
2467 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2469 ConditionalizedRequestUpdatesCacheHelper(
2470 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2473 // Test that when doing an externally conditionalized if-modified-since
2474 // and there is no corresponding cache entry, a new cache entry is NOT
2475 // created (304 response).
2476 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2477 MockHttpCache cache
;
2479 const char* kUrl
= "http://foobar.com/main.css";
2481 static const Response kNetResponse
= {
2482 "HTTP/1.1 304 Not Modified",
2483 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2484 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2488 const char* kExtraRequestHeaders
=
2489 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2491 // We will control the network layer's responses for |kUrl| using
2492 // |mock_network_response|.
2493 MockTransaction mock_network_response
= { 0 };
2494 mock_network_response
.url
= kUrl
;
2495 AddMockTransaction(&mock_network_response
);
2497 MockTransaction request
= { 0 };
2499 request
.method
= "GET";
2500 request
.request_headers
= kExtraRequestHeaders
;
2502 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2503 kNetResponse
.AssignTo(&request
); // Expected result.
2505 std::string response_headers
;
2506 RunTransactionTestWithResponse(
2507 cache
.http_cache(), request
, &response_headers
);
2509 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2510 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2511 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2512 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2514 RemoveMockTransaction(&mock_network_response
);
2517 // Test that when doing an externally conditionalized if-modified-since
2518 // and there is no corresponding cache entry, a new cache entry is NOT
2519 // created (200 response).
2520 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2521 MockHttpCache cache
;
2523 const char* kUrl
= "http://foobar.com/main.css";
2525 static const Response kNetResponse
= {
2527 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2528 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2532 const char* kExtraRequestHeaders
=
2533 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2535 // We will control the network layer's responses for |kUrl| using
2536 // |mock_network_response|.
2537 MockTransaction mock_network_response
= { 0 };
2538 mock_network_response
.url
= kUrl
;
2539 AddMockTransaction(&mock_network_response
);
2541 MockTransaction request
= { 0 };
2543 request
.method
= "GET";
2544 request
.request_headers
= kExtraRequestHeaders
;
2546 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2547 kNetResponse
.AssignTo(&request
); // Expected result.
2549 std::string response_headers
;
2550 RunTransactionTestWithResponse(
2551 cache
.http_cache(), request
, &response_headers
);
2553 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2554 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2555 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2556 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2558 RemoveMockTransaction(&mock_network_response
);
2561 // Test that when doing an externally conditionalized if-modified-since
2562 // if the date does not match the cache entry's last-modified date,
2563 // then we do NOT use the response (304) to update the cache.
2564 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2565 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2566 static const Response kNetResponse1
= {
2568 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2570 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2574 // Second network response for |kUrl|.
2575 static const Response kNetResponse2
= {
2576 "HTTP/1.1 304 Not Modified",
2577 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2579 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2583 // This is two days in the future from the original response's last-modified
2585 const char* kExtraRequestHeaders
=
2586 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2588 ConditionalizedRequestUpdatesCacheHelper(
2589 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2592 // Test that when doing an externally conditionalized if-none-match
2593 // if the etag does not match the cache entry's etag, then we do not use the
2594 // response (304) to update the cache.
2595 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2596 static const Response kNetResponse1
= {
2598 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2600 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2604 // Second network response for |kUrl|.
2605 static const Response kNetResponse2
= {
2606 "HTTP/1.1 304 Not Modified",
2607 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2609 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2613 // Different etag from original response.
2614 const char* kExtraRequestHeaders
= "If-None-Match: \"Foo2\"\r\n";
2616 ConditionalizedRequestUpdatesCacheHelper(
2617 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2620 // Test that doing an externally conditionalized request with both if-none-match
2621 // and if-modified-since updates the cache.
2622 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2623 static const Response kNetResponse1
= {
2625 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2627 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2631 // Second network response for |kUrl|.
2632 static const Response kNetResponse2
= {
2634 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2636 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2640 const char* kExtraRequestHeaders
=
2641 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2642 "If-None-Match: \"Foo1\"\r\n";
2644 ConditionalizedRequestUpdatesCacheHelper(
2645 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2648 // Test that doing an externally conditionalized request with both if-none-match
2649 // and if-modified-since does not update the cache with only one match.
2650 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2651 static const Response kNetResponse1
= {
2653 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2655 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2659 // Second network response for |kUrl|.
2660 static const Response kNetResponse2
= {
2662 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2664 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2668 // The etag doesn't match what we have stored.
2669 const char* kExtraRequestHeaders
=
2670 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2671 "If-None-Match: \"Foo2\"\r\n";
2673 ConditionalizedRequestUpdatesCacheHelper(
2674 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2677 // Test that doing an externally conditionalized request with both if-none-match
2678 // and if-modified-since does not update the cache with only one match.
2679 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2680 static const Response kNetResponse1
= {
2682 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2684 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2688 // Second network response for |kUrl|.
2689 static const Response kNetResponse2
= {
2691 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2693 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2697 // The modification date doesn't match what we have stored.
2698 const char* kExtraRequestHeaders
=
2699 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2700 "If-None-Match: \"Foo1\"\r\n";
2702 ConditionalizedRequestUpdatesCacheHelper(
2703 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2706 TEST(HttpCache
, UrlContainingHash
) {
2707 MockHttpCache cache
;
2709 // Do a typical GET request -- should write an entry into our cache.
2710 MockTransaction
trans(kTypicalGET_Transaction
);
2711 RunTransactionTest(cache
.http_cache(), trans
);
2713 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2714 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2715 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2717 // Request the same URL, but this time with a reference section (hash).
2718 // Since the cache key strips the hash sections, this should be a cache hit.
2719 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2720 trans
.url
= url_with_hash
.c_str();
2721 trans
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2723 RunTransactionTest(cache
.http_cache(), trans
);
2725 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2726 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2727 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2730 // Tests that we skip the cache for POST requests that do not have an upload
2732 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2733 MockHttpCache cache
;
2735 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2737 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2738 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2739 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2742 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2743 MockHttpCache cache
;
2745 MockTransaction
transaction(kSimplePOST_Transaction
);
2746 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2748 MockHttpRequest
request(transaction
);
2749 net::TestCompletionCallback callback
;
2751 scoped_ptr
<net::HttpTransaction
> trans
;
2752 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
2753 ASSERT_TRUE(trans
.get());
2755 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
2756 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
2760 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2761 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2762 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2765 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2766 MockHttpCache cache
;
2768 // Test that we hit the cache for POST requests.
2770 MockTransaction
transaction(kSimplePOST_Transaction
);
2772 const int64 kUploadId
= 1; // Just a dummy value.
2774 ScopedVector
<net::UploadElementReader
> element_readers
;
2775 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2776 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), kUploadId
);
2777 MockHttpRequest
request(transaction
);
2778 request
.upload_data_stream
= &upload_data_stream
;
2780 // Populate the cache.
2781 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2783 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2784 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2785 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2788 request
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2789 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2791 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2792 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2793 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2796 // Test that we don't hit the cache for POST requests if there is a byte range.
2797 TEST(HttpCache
, SimplePOST_WithRanges
) {
2798 MockHttpCache cache
;
2800 MockTransaction
transaction(kSimplePOST_Transaction
);
2801 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2803 const int64 kUploadId
= 1; // Just a dummy value.
2805 ScopedVector
<net::UploadElementReader
> element_readers
;
2806 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2807 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), kUploadId
);
2809 MockHttpRequest
request(transaction
);
2810 request
.upload_data_stream
= &upload_data_stream
;
2812 // Attempt to populate the cache.
2813 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2815 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2816 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2817 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2820 // Tests that a POST is cached separately from a previously cached GET.
2821 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2822 MockHttpCache cache
;
2824 ScopedVector
<net::UploadElementReader
> element_readers
;
2825 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2826 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2828 MockTransaction
transaction(kSimplePOST_Transaction
);
2829 MockHttpRequest
req1(transaction
);
2830 req1
.upload_data_stream
= &upload_data_stream
;
2832 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2834 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2835 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2836 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2838 transaction
.method
= "GET";
2839 MockHttpRequest
req2(transaction
);
2841 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2843 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2844 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2845 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2848 // Tests that a successful POST invalidates a previously cached GET.
2849 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2850 MockHttpCache cache
;
2852 MockTransaction
transaction(kSimpleGET_Transaction
);
2853 AddMockTransaction(&transaction
);
2854 MockHttpRequest
req1(transaction
);
2856 // Attempt to populate the cache.
2857 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2859 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2860 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2861 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2863 ScopedVector
<net::UploadElementReader
> element_readers
;
2864 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2865 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2867 transaction
.method
= "POST";
2868 transaction
.status
= "HTTP/1.1 205 No Content";
2869 MockHttpRequest
req2(transaction
);
2870 req2
.upload_data_stream
= &upload_data_stream
;
2872 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2874 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2875 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2876 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2878 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2880 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2881 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2882 EXPECT_EQ(3, cache
.disk_cache()->create_count());
2883 RemoveMockTransaction(&transaction
);
2886 // Tests that a successful POST invalidates a previously cached GET, even when
2887 // there is no upload identifier.
2888 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
2889 MockHttpCache cache
;
2891 MockTransaction
transaction(kSimpleGET_Transaction
);
2892 AddMockTransaction(&transaction
);
2893 MockHttpRequest
req1(transaction
);
2895 // Attempt to populate the cache.
2896 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2898 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2899 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2900 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2902 ScopedVector
<net::UploadElementReader
> element_readers
;
2903 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2904 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2906 transaction
.method
= "POST";
2907 transaction
.status
= "HTTP/1.1 205 No Content";
2908 MockHttpRequest
req2(transaction
);
2909 req2
.upload_data_stream
= &upload_data_stream
;
2911 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2913 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2914 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2915 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2917 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2919 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2920 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2921 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2922 RemoveMockTransaction(&transaction
);
2925 // Tests that processing a POST before creating the backend doesn't crash.
2926 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
2927 // This will initialize a cache object with NULL backend.
2928 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
2929 factory
->set_fail(true);
2930 factory
->FinishCreation();
2931 MockHttpCache
cache(factory
);
2933 ScopedVector
<net::UploadElementReader
> element_readers
;
2934 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2935 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2937 MockTransaction
transaction(kSimplePOST_Transaction
);
2938 AddMockTransaction(&transaction
);
2939 MockHttpRequest
req(transaction
);
2940 req
.upload_data_stream
= &upload_data_stream
;
2942 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
2944 RemoveMockTransaction(&transaction
);
2947 // Tests that we don't invalidate entries as a result of a failed POST.
2948 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
2949 MockHttpCache cache
;
2951 MockTransaction
transaction(kSimpleGET_Transaction
);
2952 AddMockTransaction(&transaction
);
2953 MockHttpRequest
req1(transaction
);
2955 // Attempt to populate the cache.
2956 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2958 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2959 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2960 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2962 ScopedVector
<net::UploadElementReader
> element_readers
;
2963 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2964 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2966 transaction
.method
= "POST";
2967 transaction
.status
= "HTTP/1.1 100 Continue";
2968 MockHttpRequest
req2(transaction
);
2969 req2
.upload_data_stream
= &upload_data_stream
;
2971 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2973 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2974 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2975 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2977 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2979 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2980 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2981 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2982 RemoveMockTransaction(&transaction
);
2985 // Tests that a HEAD request is not cached by itself.
2986 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
2987 MockHttpCache cache
;
2988 MockTransaction
transaction(kSimplePOST_Transaction
);
2989 AddMockTransaction(&transaction
);
2990 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2991 transaction
.method
= "HEAD";
2993 MockHttpRequest
request(transaction
);
2994 net::TestCompletionCallback callback
;
2996 scoped_ptr
<net::HttpTransaction
> trans
;
2997 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
2998 ASSERT_TRUE(trans
.get());
3000 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
3001 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
3005 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3006 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3007 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3008 RemoveMockTransaction(&transaction
);
3011 // Tests that a HEAD request is served from a cached GET.
3012 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3013 MockHttpCache cache
;
3014 MockTransaction
transaction(kSimpleGET_Transaction
);
3015 AddMockTransaction(&transaction
);
3017 // Populate the cache.
3018 RunTransactionTest(cache
.http_cache(), transaction
);
3020 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3021 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3022 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3025 transaction
.method
= "HEAD";
3026 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3027 transaction
.data
= "";
3028 RunTransactionTest(cache
.http_cache(), transaction
);
3030 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3031 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3032 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3033 RemoveMockTransaction(&transaction
);
3036 // Tests that a read-only request served from the cache preserves CL.
3037 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3038 MockHttpCache cache
;
3039 MockTransaction
transaction(kSimpleGET_Transaction
);
3040 AddMockTransaction(&transaction
);
3041 transaction
.response_headers
= "Content-Length: 42\n";
3043 // Populate the cache.
3044 RunTransactionTest(cache
.http_cache(), transaction
);
3047 transaction
.method
= "HEAD";
3048 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3049 transaction
.data
= "";
3050 std::string headers
;
3052 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3054 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3055 RemoveMockTransaction(&transaction
);
3058 // Tests that a read-write request served from the cache preserves CL.
3059 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3060 MockHttpCache cache
;
3061 MockTransaction
transaction(kETagGET_Transaction
);
3062 AddMockTransaction(&transaction
);
3063 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3064 server_headers
.append("Content-Length: 42\n");
3065 transaction
.response_headers
= server_headers
.data();
3067 // Populate the cache.
3068 RunTransactionTest(cache
.http_cache(), transaction
);
3071 transaction
.method
= "HEAD";
3072 transaction
.data
= "";
3073 std::string headers
;
3075 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3077 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3078 RemoveMockTransaction(&transaction
);
3081 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3082 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3083 MockHttpCache cache
;
3084 MockTransaction
transaction(kSimpleGET_Transaction
);
3085 AddMockTransaction(&transaction
);
3087 // Populate the cache.
3088 RunTransactionTest(cache
.http_cache(), transaction
);
3091 transaction
.method
= "HEAD";
3092 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3093 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3094 transaction
.return_code
= net::ERR_CACHE_MISS
;
3095 RunTransactionTest(cache
.http_cache(), transaction
);
3097 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3098 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3099 RemoveMockTransaction(&transaction
);
3102 // Tests that a HEAD request can be served from a partialy cached resource.
3103 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3104 MockHttpCache cache
;
3105 AddMockTransaction(&kRangeGET_TransactionOK
);
3107 // Write to the cache (40-49).
3108 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3109 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3111 MockTransaction
transaction(kSimpleGET_Transaction
);
3113 transaction
.url
= kRangeGET_TransactionOK
.url
;
3114 transaction
.method
= "HEAD";
3115 transaction
.data
= "";
3116 AddMockTransaction(&transaction
);
3117 std::string headers
;
3120 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3122 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3123 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length"));
3124 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3125 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3126 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3127 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3128 RemoveMockTransaction(&transaction
);
3131 // Tests that a HEAD request can be served from a truncated resource.
3132 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3133 MockHttpCache cache
;
3134 AddMockTransaction(&kRangeGET_TransactionOK
);
3136 std::string
raw_headers("HTTP/1.1 200 OK\n"
3137 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3139 "Accept-Ranges: bytes\n"
3140 "Content-Length: 80\n");
3141 CreateTruncatedEntry(raw_headers
, &cache
);
3142 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3144 MockTransaction
transaction(kSimpleGET_Transaction
);
3146 transaction
.url
= kRangeGET_TransactionOK
.url
;
3147 transaction
.method
= "HEAD";
3148 transaction
.data
= "";
3149 AddMockTransaction(&transaction
);
3150 std::string headers
;
3153 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3155 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3156 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3157 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3158 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3159 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3160 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3161 RemoveMockTransaction(&transaction
);
3164 // Tests that a HEAD request updates the cached response.
3165 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3166 MockHttpCache cache
;
3167 MockTransaction
transaction(kTypicalGET_Transaction
);
3168 AddMockTransaction(&transaction
);
3170 // Populate the cache.
3171 RunTransactionTest(cache
.http_cache(), transaction
);
3173 // Update the cache.
3174 transaction
.method
= "HEAD";
3175 transaction
.response_headers
= "Foo: bar\n";
3176 transaction
.data
= "";
3177 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3178 std::string headers
;
3179 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3180 RemoveMockTransaction(&transaction
);
3182 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3183 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3185 MockTransaction
transaction2(kTypicalGET_Transaction
);
3186 AddMockTransaction(&transaction2
);
3188 // Make sure we are done with the previous transaction.
3189 base::MessageLoop::current()->RunUntilIdle();
3191 // Load from the cache.
3192 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3193 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3195 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3196 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3197 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3198 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3199 RemoveMockTransaction(&transaction2
);
3202 // Tests that an externally conditionalized HEAD request updates the cache.
3203 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3204 MockHttpCache cache
;
3205 MockTransaction
transaction(kTypicalGET_Transaction
);
3206 AddMockTransaction(&transaction
);
3208 // Populate the cache.
3209 RunTransactionTest(cache
.http_cache(), transaction
);
3211 // Update the cache.
3212 transaction
.method
= "HEAD";
3213 transaction
.request_headers
=
3214 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3215 transaction
.response_headers
= "Foo: bar\n";
3216 transaction
.data
= "";
3217 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3218 std::string headers
;
3219 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3220 RemoveMockTransaction(&transaction
);
3222 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3223 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3225 MockTransaction
transaction2(kTypicalGET_Transaction
);
3226 AddMockTransaction(&transaction2
);
3228 // Make sure we are done with the previous transaction.
3229 base::MessageLoop::current()->RunUntilIdle();
3231 // Load from the cache.
3232 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3233 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3235 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3236 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3237 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3238 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3239 RemoveMockTransaction(&transaction2
);
3242 // Tests that a HEAD request invalidates an old cached entry.
3243 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3244 MockHttpCache cache
;
3245 MockTransaction
transaction(kTypicalGET_Transaction
);
3246 AddMockTransaction(&transaction
);
3248 // Populate the cache.
3249 RunTransactionTest(cache
.http_cache(), transaction
);
3251 // Update the cache.
3252 transaction
.method
= "HEAD";
3253 transaction
.data
= "";
3254 RunTransactionTest(cache
.http_cache(), transaction
);
3255 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3257 // Load from the cache.
3258 transaction
.method
= "GET";
3259 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3260 transaction
.return_code
= net::ERR_CACHE_MISS
;
3261 RunTransactionTest(cache
.http_cache(), transaction
);
3263 RemoveMockTransaction(&transaction
);
3266 // Tests that we do not cache the response of a PUT.
3267 TEST(HttpCache
, SimplePUT_Miss
) {
3268 MockHttpCache cache
;
3270 MockTransaction
transaction(kSimplePOST_Transaction
);
3271 transaction
.method
= "PUT";
3273 ScopedVector
<net::UploadElementReader
> element_readers
;
3274 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3275 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3277 MockHttpRequest
request(transaction
);
3278 request
.upload_data_stream
= &upload_data_stream
;
3280 // Attempt to populate the cache.
3281 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3283 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3284 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3285 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3288 // Tests that we invalidate entries as a result of a PUT.
3289 TEST(HttpCache
, SimplePUT_Invalidate
) {
3290 MockHttpCache cache
;
3292 MockTransaction
transaction(kSimpleGET_Transaction
);
3293 MockHttpRequest
req1(transaction
);
3295 // Attempt to populate the cache.
3296 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3298 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3299 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3300 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3302 ScopedVector
<net::UploadElementReader
> element_readers
;
3303 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3304 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3306 transaction
.method
= "PUT";
3307 MockHttpRequest
req2(transaction
);
3308 req2
.upload_data_stream
= &upload_data_stream
;
3310 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3312 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3313 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3314 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3316 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3318 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3319 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3320 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3323 // Tests that we invalidate entries as a result of a PUT.
3324 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3325 MockHttpCache cache
;
3327 MockTransaction
transaction(kSimpleGET_Transaction
);
3328 AddMockTransaction(&transaction
);
3329 MockHttpRequest
req1(transaction
);
3331 // Attempt to populate the cache.
3332 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3334 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3335 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3336 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3338 ScopedVector
<net::UploadElementReader
> element_readers
;
3339 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3340 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3342 transaction
.method
= "PUT";
3343 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3344 MockHttpRequest
req2(transaction
);
3345 req2
.upload_data_stream
= &upload_data_stream
;
3347 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3349 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3350 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3351 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3353 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3355 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3356 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3357 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3358 RemoveMockTransaction(&transaction
);
3361 // Tests that we don't invalidate entries as a result of a failed PUT.
3362 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3363 MockHttpCache cache
;
3365 MockTransaction
transaction(kSimpleGET_Transaction
);
3366 AddMockTransaction(&transaction
);
3367 MockHttpRequest
req1(transaction
);
3369 // Attempt to populate the cache.
3370 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3372 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3373 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3374 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3376 ScopedVector
<net::UploadElementReader
> element_readers
;
3377 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3378 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3380 transaction
.method
= "PUT";
3381 transaction
.status
= "HTTP/1.1 404 Not Found";
3382 MockHttpRequest
req2(transaction
);
3383 req2
.upload_data_stream
= &upload_data_stream
;
3385 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3387 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3388 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3389 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3391 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3393 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3394 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3395 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3396 RemoveMockTransaction(&transaction
);
3399 // Tests that we do not cache the response of a DELETE.
3400 TEST(HttpCache
, SimpleDELETE_Miss
) {
3401 MockHttpCache cache
;
3403 MockTransaction
transaction(kSimplePOST_Transaction
);
3404 transaction
.method
= "DELETE";
3406 ScopedVector
<net::UploadElementReader
> element_readers
;
3407 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3408 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3410 MockHttpRequest
request(transaction
);
3411 request
.upload_data_stream
= &upload_data_stream
;
3413 // Attempt to populate the cache.
3414 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3416 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3417 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3418 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3421 // Tests that we invalidate entries as a result of a DELETE.
3422 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3423 MockHttpCache cache
;
3425 MockTransaction
transaction(kSimpleGET_Transaction
);
3426 MockHttpRequest
req1(transaction
);
3428 // Attempt to populate the cache.
3429 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3431 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3432 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3433 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3435 ScopedVector
<net::UploadElementReader
> element_readers
;
3436 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3437 net::UploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3439 transaction
.method
= "DELETE";
3440 MockHttpRequest
req2(transaction
);
3441 req2
.upload_data_stream
= &upload_data_stream
;
3443 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3445 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3446 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3447 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3449 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3451 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3452 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3453 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3456 // Tests that we invalidate entries as a result of a DELETE.
3457 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3458 MockHttpCache cache
;
3460 MockTransaction
transaction(kSimpleGET_Transaction
);
3461 AddMockTransaction(&transaction
);
3463 // Attempt to populate the cache.
3464 RunTransactionTest(cache
.http_cache(), transaction
);
3466 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3467 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3468 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3470 transaction
.method
= "DELETE";
3471 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3473 RunTransactionTest(cache
.http_cache(), transaction
);
3475 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3476 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3477 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3479 transaction
.method
= "GET";
3480 RunTransactionTest(cache
.http_cache(), transaction
);
3482 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3483 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3484 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3485 RemoveMockTransaction(&transaction
);
3488 // Tests that we don't invalidate entries as a result of a failed DELETE.
3489 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3490 MockHttpCache cache
;
3492 MockTransaction
transaction(kSimpleGET_Transaction
);
3493 AddMockTransaction(&transaction
);
3495 // Attempt to populate the cache.
3496 RunTransactionTest(cache
.http_cache(), transaction
);
3498 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3499 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3500 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3502 transaction
.method
= "DELETE";
3503 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3505 RunTransactionTest(cache
.http_cache(), transaction
);
3507 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3508 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3509 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3511 transaction
.method
= "GET";
3512 transaction
.status
= "HTTP/1.1 200 OK";
3513 RunTransactionTest(cache
.http_cache(), transaction
);
3515 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3516 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3517 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3518 RemoveMockTransaction(&transaction
);
3521 // Tests that we don't invalidate entries after a failed network transaction.
3522 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3523 MockHttpCache cache
;
3525 // Populate the cache.
3526 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3527 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3529 // Fail the network request.
3530 MockTransaction
transaction(kSimpleGET_Transaction
);
3531 transaction
.return_code
= net::ERR_FAILED
;
3532 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3534 AddMockTransaction(&transaction
);
3535 RunTransactionTest(cache
.http_cache(), transaction
);
3536 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3537 RemoveMockTransaction(&transaction
);
3539 transaction
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
3540 transaction
.return_code
= net::OK
;
3541 AddMockTransaction(&transaction
);
3542 RunTransactionTest(cache
.http_cache(), transaction
);
3544 // Make sure the transaction didn't reach the network.
3545 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3546 RemoveMockTransaction(&transaction
);
3549 TEST(HttpCache
, RangeGET_SkipsCache
) {
3550 MockHttpCache cache
;
3552 // Test that we skip the cache for range GET requests. Eventually, we will
3553 // want to cache these, but we'll still have cases where skipping the cache
3554 // makes sense, so we want to make sure that it works properly.
3556 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3558 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3559 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3560 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3562 MockTransaction
transaction(kSimpleGET_Transaction
);
3563 transaction
.request_headers
= "If-None-Match: foo\r\n";
3564 RunTransactionTest(cache
.http_cache(), transaction
);
3566 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3567 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3568 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3570 transaction
.request_headers
=
3571 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3572 RunTransactionTest(cache
.http_cache(), transaction
);
3574 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3575 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3576 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3579 // Test that we skip the cache for range requests that include a validation
3581 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3582 MockHttpCache cache
;
3584 MockTransaction
transaction(kRangeGET_Transaction
);
3585 transaction
.request_headers
= "If-None-Match: foo\r\n"
3587 "Range: bytes = 40-49\r\n";
3588 RunTransactionTest(cache
.http_cache(), transaction
);
3590 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3591 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3592 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3594 transaction
.request_headers
=
3595 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3597 "Range: bytes = 40-49\r\n";
3598 RunTransactionTest(cache
.http_cache(), transaction
);
3600 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3601 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3602 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3604 transaction
.request_headers
= "If-Range: bla\r\n"
3606 "Range: bytes = 40-49\r\n";
3607 RunTransactionTest(cache
.http_cache(), transaction
);
3609 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3610 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3611 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3614 // Tests that receiving 206 for a regular request is handled correctly.
3615 TEST(HttpCache
, GET_Crazy206
) {
3616 MockHttpCache cache
;
3618 // Write to the cache.
3619 MockTransaction
transaction(kRangeGET_TransactionOK
);
3620 AddMockTransaction(&transaction
);
3621 transaction
.request_headers
= EXTRA_HEADER
;
3622 transaction
.handler
= NULL
;
3623 RunTransactionTest(cache
.http_cache(), transaction
);
3625 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3626 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3627 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3629 // This should read again from the net.
3630 RunTransactionTest(cache
.http_cache(), transaction
);
3632 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3633 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3634 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3635 RemoveMockTransaction(&transaction
);
3638 // Tests that receiving 416 for a regular request is handled correctly.
3639 TEST(HttpCache
, GET_Crazy416
) {
3640 MockHttpCache cache
;
3642 // Write to the cache.
3643 MockTransaction
transaction(kSimpleGET_Transaction
);
3644 AddMockTransaction(&transaction
);
3645 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3646 RunTransactionTest(cache
.http_cache(), transaction
);
3648 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3649 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3650 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3652 RemoveMockTransaction(&transaction
);
3655 // Tests that we don't cache partial responses that can't be validated.
3656 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3657 MockHttpCache cache
;
3658 std::string headers
;
3660 // Attempt to write to the cache (40-49).
3661 MockTransaction
transaction(kRangeGET_TransactionOK
);
3662 AddMockTransaction(&transaction
);
3663 transaction
.response_headers
= "Content-Length: 10\n"
3664 "ETag: w/\"foo\"\n";
3665 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3667 Verify206Response(headers
, 40, 49);
3668 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3669 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3670 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3672 // Now verify that there's no cached data.
3673 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3676 Verify206Response(headers
, 40, 49);
3677 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3678 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3679 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3681 RemoveMockTransaction(&transaction
);
3684 // Tests that we cache partial responses that lack content-length.
3685 TEST(HttpCache
, RangeGET_NoContentLength
) {
3686 MockHttpCache cache
;
3687 std::string headers
;
3689 // Attempt to write to the cache (40-49).
3690 MockTransaction
transaction(kRangeGET_TransactionOK
);
3691 AddMockTransaction(&transaction
);
3692 transaction
.response_headers
= "ETag: \"foo\"\n"
3693 "Accept-Ranges: bytes\n"
3694 "Content-Range: bytes 40-49/80\n";
3695 transaction
.handler
= NULL
;
3696 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3698 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3699 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3700 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3702 // Now verify that there's no cached data.
3703 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
3704 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3707 Verify206Response(headers
, 40, 49);
3708 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3709 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3710 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3712 RemoveMockTransaction(&transaction
);
3715 // Tests that we can cache range requests and fetch random blocks from the
3716 // cache and the network.
3717 TEST(HttpCache
, RangeGET_OK
) {
3718 MockHttpCache cache
;
3719 AddMockTransaction(&kRangeGET_TransactionOK
);
3720 std::string headers
;
3722 // Write to the cache (40-49).
3723 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3726 Verify206Response(headers
, 40, 49);
3727 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3728 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3729 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3731 // Read from the cache (40-49).
3732 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3735 Verify206Response(headers
, 40, 49);
3736 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3737 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3738 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3740 // Make sure we are done with the previous transaction.
3741 base::MessageLoop::current()->RunUntilIdle();
3743 // Write to the cache (30-39).
3744 MockTransaction
transaction(kRangeGET_TransactionOK
);
3745 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3746 transaction
.data
= "rg: 30-39 ";
3747 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3749 Verify206Response(headers
, 30, 39);
3750 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3751 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3752 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3754 // Make sure we are done with the previous transaction.
3755 base::MessageLoop::current()->RunUntilIdle();
3757 // Write and read from the cache (20-59).
3758 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3759 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3760 net::CapturingBoundNetLog log
;
3761 net::LoadTimingInfo load_timing_info
;
3762 RunTransactionTestWithResponseAndGetTiming(
3763 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3766 Verify206Response(headers
, 20, 59);
3767 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3768 EXPECT_EQ(3, cache
.disk_cache()->open_count());
3769 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3770 TestLoadTimingNetworkRequest(load_timing_info
);
3772 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3775 // Checks that with a cache backend having Sparse IO unimplementes the cache
3776 // entry would be doomed after a range request.
3777 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3778 TEST(HttpCache
, RangeGET_SparseNotImplemented
) {
3779 MockHttpCache cache
;
3780 cache
.disk_cache()->set_fail_sparse_requests();
3782 // Run a cacheable request to prime the cache.
3783 MockTransaction
transaction(kTypicalGET_Transaction
);
3784 transaction
.url
= kRangeGET_TransactionOK
.url
;
3785 AddMockTransaction(&transaction
);
3786 RunTransactionTest(cache
.http_cache(), transaction
);
3787 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3788 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3789 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3791 // Verify that we added the entry.
3792 disk_cache::Entry
* entry
;
3793 net::TestCompletionCallback cb
;
3794 int rv
= cache
.disk_cache()->OpenEntry(transaction
.url
,
3797 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
3798 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3800 RemoveMockTransaction(&transaction
);
3802 // Request the range with the backend that does not support it.
3803 MockTransaction
transaction2(kRangeGET_TransactionOK
);
3804 std::string headers
;
3805 AddMockTransaction(&transaction2
);
3806 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3807 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3808 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3809 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3811 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3812 // if it was re-created later, so this effectively checks that the old data is
3814 disk_cache::Entry
* entry2
;
3815 rv
= cache
.disk_cache()->OpenEntry(transaction2
.url
,
3818 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE
, cb
.GetResult(rv
));
3819 RemoveMockTransaction(&transaction2
);
3822 TEST(HttpCache
, RangeGET_SparseNotImplementedOnEmptyCache
) {
3823 MockHttpCache cache
;
3824 cache
.disk_cache()->set_fail_sparse_requests();
3826 // Request the range with the backend that does not support it.
3827 MockTransaction
transaction(kRangeGET_TransactionOK
);
3828 std::string headers
;
3829 AddMockTransaction(&transaction
);
3830 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3831 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3832 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3833 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3835 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3836 // if it was re-created later, so this effectively checks that the old data is
3837 // gone as a result of a failed range write.
3838 disk_cache::Entry
* entry
;
3839 net::TestCompletionCallback cb
;
3840 int rv
= cache
.disk_cache()->OpenEntry(transaction
.url
,
3843 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE
, cb
.GetResult(rv
));
3844 RemoveMockTransaction(&transaction
);
3847 // Tests that we can cache range requests and fetch random blocks from the
3848 // cache and the network, with synchronous responses.
3849 TEST(HttpCache
, RangeGET_SyncOK
) {
3850 MockHttpCache cache
;
3852 MockTransaction
transaction(kRangeGET_TransactionOK
);
3853 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
3854 AddMockTransaction(&transaction
);
3856 // Write to the cache (40-49).
3857 std::string headers
;
3858 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3860 Verify206Response(headers
, 40, 49);
3861 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3862 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3863 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3865 // Read from the cache (40-49).
3866 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3868 Verify206Response(headers
, 40, 49);
3869 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3870 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3871 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3873 // Make sure we are done with the previous transaction.
3874 base::MessageLoop::current()->RunUntilIdle();
3876 // Write to the cache (30-39).
3877 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3878 transaction
.data
= "rg: 30-39 ";
3879 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3881 Verify206Response(headers
, 30, 39);
3882 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3883 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3884 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3886 // Make sure we are done with the previous transaction.
3887 base::MessageLoop::current()->RunUntilIdle();
3889 // Write and read from the cache (20-59).
3890 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3891 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3892 net::CapturingBoundNetLog log
;
3893 net::LoadTimingInfo load_timing_info
;
3894 RunTransactionTestWithResponseAndGetTiming(
3895 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3898 Verify206Response(headers
, 20, 59);
3899 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3900 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3901 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3902 TestLoadTimingNetworkRequest(load_timing_info
);
3904 RemoveMockTransaction(&transaction
);
3907 // Tests that we don't revalidate an entry unless we are required to do so.
3908 TEST(HttpCache
, RangeGET_Revalidate1
) {
3909 MockHttpCache cache
;
3910 std::string headers
;
3912 // Write to the cache (40-49).
3913 MockTransaction
transaction(kRangeGET_TransactionOK
);
3914 transaction
.response_headers
=
3915 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3916 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3918 "Accept-Ranges: bytes\n"
3919 "Content-Length: 10\n";
3920 AddMockTransaction(&transaction
);
3921 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3923 Verify206Response(headers
, 40, 49);
3924 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3925 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3926 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3928 // Read from the cache (40-49).
3929 net::CapturingBoundNetLog log
;
3930 net::LoadTimingInfo load_timing_info
;
3931 RunTransactionTestWithResponseAndGetTiming(
3932 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3935 Verify206Response(headers
, 40, 49);
3936 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3937 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3938 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3939 TestLoadTimingCachedResponse(load_timing_info
);
3941 // Read again forcing the revalidation.
3942 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3943 RunTransactionTestWithResponseAndGetTiming(
3944 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3947 Verify206Response(headers
, 40, 49);
3948 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3949 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3950 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3951 TestLoadTimingNetworkRequest(load_timing_info
);
3953 RemoveMockTransaction(&transaction
);
3956 // Checks that we revalidate an entry when the headers say so.
3957 TEST(HttpCache
, RangeGET_Revalidate2
) {
3958 MockHttpCache cache
;
3959 std::string headers
;
3961 // Write to the cache (40-49).
3962 MockTransaction
transaction(kRangeGET_TransactionOK
);
3963 transaction
.response_headers
=
3964 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3965 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
3967 "Accept-Ranges: bytes\n"
3968 "Content-Length: 10\n";
3969 AddMockTransaction(&transaction
);
3970 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3972 Verify206Response(headers
, 40, 49);
3973 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3974 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3975 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3977 // Read from the cache (40-49).
3978 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3979 Verify206Response(headers
, 40, 49);
3981 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3982 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3983 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3985 RemoveMockTransaction(&transaction
);
3988 // Tests that we deal with 304s for range requests.
3989 TEST(HttpCache
, RangeGET_304
) {
3990 MockHttpCache cache
;
3991 AddMockTransaction(&kRangeGET_TransactionOK
);
3992 std::string headers
;
3994 // Write to the cache (40-49).
3995 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3998 Verify206Response(headers
, 40, 49);
3999 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4000 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4001 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4003 // Read from the cache (40-49).
4004 RangeTransactionServer handler
;
4005 handler
.set_not_modified(true);
4006 MockTransaction
transaction(kRangeGET_TransactionOK
);
4007 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4008 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4010 Verify206Response(headers
, 40, 49);
4011 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4012 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4013 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4015 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4018 // Tests that we deal with 206s when revalidating range requests.
4019 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4020 MockHttpCache cache
;
4021 AddMockTransaction(&kRangeGET_TransactionOK
);
4022 std::string headers
;
4024 // Write to the cache (40-49).
4025 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4028 Verify206Response(headers
, 40, 49);
4029 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4030 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4031 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4033 // Attempt to read from the cache (40-49).
4034 RangeTransactionServer handler
;
4035 handler
.set_modified(true);
4036 MockTransaction
transaction(kRangeGET_TransactionOK
);
4037 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4038 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4040 Verify206Response(headers
, 40, 49);
4041 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4042 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4043 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4045 // And the entry should be gone.
4046 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4047 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4048 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4049 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4051 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4054 // Tests that we cache 301s for range requests.
4055 TEST(HttpCache
, RangeGET_301
) {
4056 MockHttpCache cache
;
4057 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4058 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4059 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4060 transaction
.data
= "";
4061 transaction
.handler
= NULL
;
4062 AddMockTransaction(&transaction
);
4064 // Write to the cache.
4065 RunTransactionTest(cache
.http_cache(), transaction
);
4066 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4067 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4068 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4070 // Read from the cache.
4071 RunTransactionTest(cache
.http_cache(), transaction
);
4072 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4073 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4074 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4076 RemoveMockTransaction(&transaction
);
4079 // Tests that we can cache range requests when the start or end is unknown.
4080 // We start with one suffix request, followed by a request from a given point.
4081 TEST(HttpCache
, UnknownRangeGET_1
) {
4082 MockHttpCache cache
;
4083 AddMockTransaction(&kRangeGET_TransactionOK
);
4084 std::string headers
;
4086 // Write to the cache (70-79).
4087 MockTransaction
transaction(kRangeGET_TransactionOK
);
4088 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4089 transaction
.data
= "rg: 70-79 ";
4090 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4092 Verify206Response(headers
, 70, 79);
4093 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4094 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4095 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4097 // Make sure we are done with the previous transaction.
4098 base::MessageLoop::current()->RunUntilIdle();
4100 // Write and read from the cache (60-79).
4101 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4102 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4103 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4105 Verify206Response(headers
, 60, 79);
4106 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4107 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4108 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4110 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4113 // Tests that we can cache range requests when the start or end is unknown.
4114 // We start with one request from a given point, followed by a suffix request.
4115 // We'll also verify that synchronous cache responses work as intended.
4116 TEST(HttpCache
, UnknownRangeGET_2
) {
4117 MockHttpCache cache
;
4118 std::string headers
;
4120 MockTransaction
transaction(kRangeGET_TransactionOK
);
4121 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4122 TEST_MODE_SYNC_CACHE_READ
|
4123 TEST_MODE_SYNC_CACHE_WRITE
;
4124 AddMockTransaction(&transaction
);
4126 // Write to the cache (70-79).
4127 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4128 transaction
.data
= "rg: 70-79 ";
4129 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4131 Verify206Response(headers
, 70, 79);
4132 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4133 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4134 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4136 // Make sure we are done with the previous transaction.
4137 base::MessageLoop::current()->RunUntilIdle();
4139 // Write and read from the cache (60-79).
4140 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4141 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4142 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4144 Verify206Response(headers
, 60, 79);
4145 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4146 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4147 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4149 RemoveMockTransaction(&transaction
);
4152 // Tests that receiving Not Modified when asking for an open range doesn't mess
4154 TEST(HttpCache
, UnknownRangeGET_304
) {
4155 MockHttpCache cache
;
4156 std::string headers
;
4158 MockTransaction
transaction(kRangeGET_TransactionOK
);
4159 AddMockTransaction(&transaction
);
4161 RangeTransactionServer handler
;
4162 handler
.set_not_modified(true);
4164 // Ask for the end of the file, without knowing the length.
4165 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4166 transaction
.data
= "";
4167 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4169 // We just bypass the cache.
4170 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4171 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4172 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4173 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4175 RunTransactionTest(cache
.http_cache(), transaction
);
4176 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4178 RemoveMockTransaction(&transaction
);
4181 // Tests that we can handle non-range requests when we have cached a range.
4182 TEST(HttpCache
, GET_Previous206
) {
4183 MockHttpCache cache
;
4184 AddMockTransaction(&kRangeGET_TransactionOK
);
4185 std::string headers
;
4186 net::CapturingBoundNetLog log
;
4187 net::LoadTimingInfo load_timing_info
;
4189 // Write to the cache (40-49).
4190 RunTransactionTestWithResponseAndGetTiming(
4191 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4194 Verify206Response(headers
, 40, 49);
4195 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4196 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4197 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4198 TestLoadTimingNetworkRequest(load_timing_info
);
4200 // Write and read from the cache (0-79), when not asked for a range.
4201 MockTransaction
transaction(kRangeGET_TransactionOK
);
4202 transaction
.request_headers
= EXTRA_HEADER
;
4203 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4204 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4205 RunTransactionTestWithResponseAndGetTiming(
4206 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4209 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4210 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4211 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4212 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4213 TestLoadTimingNetworkRequest(load_timing_info
);
4215 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4218 // Tests that we can handle non-range requests when we have cached the first
4219 // part of the object and the server replies with 304 (Not Modified).
4220 TEST(HttpCache
, GET_Previous206_NotModified
) {
4221 MockHttpCache cache
;
4223 MockTransaction
transaction(kRangeGET_TransactionOK
);
4224 AddMockTransaction(&transaction
);
4225 std::string headers
;
4226 net::CapturingBoundNetLog log
;
4227 net::LoadTimingInfo load_timing_info
;
4229 // Write to the cache (0-9).
4230 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4231 transaction
.data
= "rg: 00-09 ";
4232 RunTransactionTestWithResponseAndGetTiming(
4233 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4235 Verify206Response(headers
, 0, 9);
4236 TestLoadTimingNetworkRequest(load_timing_info
);
4238 // Write to the cache (70-79).
4239 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4240 transaction
.data
= "rg: 70-79 ";
4241 RunTransactionTestWithResponseAndGetTiming(
4242 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4244 Verify206Response(headers
, 70, 79);
4246 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4247 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4248 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4249 TestLoadTimingNetworkRequest(load_timing_info
);
4251 // Read from the cache (0-9), write and read from cache (10 - 79).
4252 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4253 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4254 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4255 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4256 RunTransactionTestWithResponseAndGetTiming(
4257 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4260 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4261 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4262 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4263 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4264 TestLoadTimingNetworkRequest(load_timing_info
);
4266 RemoveMockTransaction(&transaction
);
4269 // Tests that we can handle a regular request to a sparse entry, that results in
4270 // new content provided by the server (206).
4271 TEST(HttpCache
, GET_Previous206_NewContent
) {
4272 MockHttpCache cache
;
4273 AddMockTransaction(&kRangeGET_TransactionOK
);
4274 std::string headers
;
4276 // Write to the cache (0-9).
4277 MockTransaction
transaction(kRangeGET_TransactionOK
);
4278 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4279 transaction
.data
= "rg: 00-09 ";
4280 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4282 Verify206Response(headers
, 0, 9);
4283 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4284 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4285 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4287 // Now we'll issue a request without any range that should result first in a
4288 // 206 (when revalidating), and then in a weird standard answer: the test
4289 // server will not modify the response so we'll get the default range... a
4290 // real server will answer with 200.
4291 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4292 transaction2
.request_headers
= EXTRA_HEADER
;
4293 transaction2
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4294 transaction2
.data
= "Not a range";
4295 RangeTransactionServer handler
;
4296 handler
.set_modified(true);
4297 net::CapturingBoundNetLog log
;
4298 net::LoadTimingInfo load_timing_info
;
4299 RunTransactionTestWithResponseAndGetTiming(
4300 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4303 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4304 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4305 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4306 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4307 TestLoadTimingNetworkRequest(load_timing_info
);
4309 // Verify that the previous request deleted the entry.
4310 RunTransactionTest(cache
.http_cache(), transaction
);
4311 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4313 RemoveMockTransaction(&transaction
);
4316 // Tests that we can handle cached 206 responses that are not sparse.
4317 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4318 MockHttpCache cache
;
4320 // Create a disk cache entry that stores 206 headers while not being sparse.
4321 disk_cache::Entry
* entry
;
4322 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4325 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4326 raw_headers
.append("\n");
4327 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4328 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4329 raw_headers
.size());
4331 net::HttpResponseInfo response
;
4332 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4333 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4335 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4336 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4337 kRangeGET_TransactionOK
.data
, 500));
4338 net::TestCompletionCallback cb
;
4339 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4340 EXPECT_EQ(len
, cb
.GetResult(rv
));
4343 // Now see that we don't use the stored entry.
4344 std::string headers
;
4345 net::CapturingBoundNetLog log
;
4346 net::LoadTimingInfo load_timing_info
;
4347 RunTransactionTestWithResponseAndGetTiming(
4348 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4351 // We are expecting a 200.
4352 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4353 expected_headers
.append("\n");
4354 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4355 EXPECT_EQ(expected_headers
, headers
);
4356 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4357 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4358 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4359 TestLoadTimingNetworkRequest(load_timing_info
);
4362 // Tests that we can handle cached 206 responses that are not sparse. This time
4363 // we issue a range request and expect to receive a range.
4364 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4365 MockHttpCache cache
;
4366 AddMockTransaction(&kRangeGET_TransactionOK
);
4368 // Create a disk cache entry that stores 206 headers while not being sparse.
4369 disk_cache::Entry
* entry
;
4370 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.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 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4396 // We are expecting a 206.
4397 Verify206Response(headers
, 40, 49);
4398 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4399 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4400 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4402 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4405 // Tests that we can handle cached 206 responses that can't be validated.
4406 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4407 MockHttpCache cache
;
4409 // Create a disk cache entry that stores 206 headers.
4410 disk_cache::Entry
* entry
;
4411 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4414 // Make sure that the headers cannot be validated with the server.
4415 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4416 raw_headers
.append("\n");
4417 raw_headers
.append("Content-Length: 80\n");
4418 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4419 raw_headers
.size());
4421 net::HttpResponseInfo response
;
4422 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4423 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4425 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4426 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4427 kRangeGET_TransactionOK
.data
, 500));
4428 net::TestCompletionCallback cb
;
4429 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4430 EXPECT_EQ(len
, cb
.GetResult(rv
));
4433 // Now see that we don't use the stored entry.
4434 std::string headers
;
4435 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4438 // We are expecting a 200.
4439 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4440 expected_headers
.append("\n");
4441 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4442 EXPECT_EQ(expected_headers
, headers
);
4443 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4444 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4445 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4448 // Tests that we can handle range requests with cached 200 responses.
4449 TEST(HttpCache
, RangeGET_Previous200
) {
4450 MockHttpCache cache
;
4452 // Store the whole thing with status 200.
4453 MockTransaction
transaction(kTypicalGET_Transaction
);
4454 transaction
.url
= kRangeGET_TransactionOK
.url
;
4455 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4456 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4457 AddMockTransaction(&transaction
);
4458 RunTransactionTest(cache
.http_cache(), transaction
);
4459 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4460 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4461 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4463 RemoveMockTransaction(&transaction
);
4464 AddMockTransaction(&kRangeGET_TransactionOK
);
4466 // Now see that we use the stored entry.
4467 std::string headers
;
4468 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4469 RangeTransactionServer handler
;
4470 handler
.set_not_modified(true);
4471 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4473 // We are expecting a 206.
4474 Verify206Response(headers
, 40, 49);
4475 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4476 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4477 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4479 // The last transaction has finished so make sure the entry is deactivated.
4480 base::MessageLoop::current()->RunUntilIdle();
4482 // Make a request for an invalid range.
4483 MockTransaction
transaction3(kRangeGET_TransactionOK
);
4484 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
4485 transaction3
.data
= transaction
.data
;
4486 transaction3
.load_flags
= net::LOAD_PREFERRING_CACHE
;
4487 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
4488 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4489 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
4490 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
4491 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
4493 // Make sure the entry is deactivated.
4494 base::MessageLoop::current()->RunUntilIdle();
4496 // Even though the request was invalid, we should have the entry.
4497 RunTransactionTest(cache
.http_cache(), transaction2
);
4498 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4500 // Make sure the entry is deactivated.
4501 base::MessageLoop::current()->RunUntilIdle();
4503 // Now we should receive a range from the server and drop the stored entry.
4504 handler
.set_not_modified(false);
4505 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4506 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4507 Verify206Response(headers
, 40, 49);
4508 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4509 EXPECT_EQ(4, cache
.disk_cache()->open_count());
4510 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4512 RunTransactionTest(cache
.http_cache(), transaction2
);
4513 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4515 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4518 // Tests that we can handle a 200 response when dealing with sparse entries.
4519 TEST(HttpCache
, RangeRequestResultsIn200
) {
4520 MockHttpCache cache
;
4521 AddMockTransaction(&kRangeGET_TransactionOK
);
4522 std::string headers
;
4524 // Write to the cache (70-79).
4525 MockTransaction
transaction(kRangeGET_TransactionOK
);
4526 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4527 transaction
.data
= "rg: 70-79 ";
4528 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4530 Verify206Response(headers
, 70, 79);
4531 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4532 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4533 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4535 // Now we'll issue a request that results in a plain 200 response, but to
4536 // the to the same URL that we used to store sparse data, and making sure
4537 // that we ask for a range.
4538 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4539 MockTransaction
transaction2(kSimpleGET_Transaction
);
4540 transaction2
.url
= kRangeGET_TransactionOK
.url
;
4541 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4542 AddMockTransaction(&transaction2
);
4544 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4546 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4547 expected_headers
.append("\n");
4548 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4549 EXPECT_EQ(expected_headers
, headers
);
4550 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4551 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4552 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4554 RemoveMockTransaction(&transaction2
);
4557 // Tests that a range request that falls outside of the size that we know about
4558 // only deletes the entry if the resource has indeed changed.
4559 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
4560 MockHttpCache cache
;
4561 AddMockTransaction(&kRangeGET_TransactionOK
);
4562 std::string headers
;
4564 // Write to the cache (40-49).
4565 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4568 Verify206Response(headers
, 40, 49);
4569 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4570 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4571 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4573 // A weird request should not delete this entry. Ask for bytes 120-.
4574 MockTransaction
transaction(kRangeGET_TransactionOK
);
4575 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
4576 transaction
.data
= "";
4577 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4579 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
4580 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4581 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4582 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4584 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4585 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4586 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4588 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4591 // Tests that we don't delete a sparse entry when we cancel a request.
4592 TEST(HttpCache
, RangeGET_Cancel
) {
4593 MockHttpCache cache
;
4594 AddMockTransaction(&kRangeGET_TransactionOK
);
4596 MockHttpRequest
request(kRangeGET_TransactionOK
);
4598 Context
* c
= new Context();
4599 int rv
= cache
.CreateTransaction(&c
->trans
);
4600 ASSERT_EQ(net::OK
, rv
);
4602 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4603 if (rv
== net::ERR_IO_PENDING
)
4604 rv
= c
->callback
.WaitForResult();
4606 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4607 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4608 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4610 // Make sure that the entry has some data stored.
4611 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
4612 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4613 if (rv
== net::ERR_IO_PENDING
)
4614 rv
= c
->callback
.WaitForResult();
4615 EXPECT_EQ(buf
->size(), rv
);
4617 // Destroy the transaction.
4620 // Verify that the entry has not been deleted.
4621 disk_cache::Entry
* entry
;
4622 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4624 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4627 // Tests that we don't delete a sparse entry when we start a new request after
4628 // cancelling the previous one.
4629 TEST(HttpCache
, RangeGET_Cancel2
) {
4630 MockHttpCache cache
;
4631 AddMockTransaction(&kRangeGET_TransactionOK
);
4633 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4634 MockHttpRequest
request(kRangeGET_TransactionOK
);
4635 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4637 Context
* c
= new Context();
4638 int rv
= cache
.CreateTransaction(&c
->trans
);
4639 ASSERT_EQ(net::OK
, rv
);
4641 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4642 if (rv
== net::ERR_IO_PENDING
)
4643 rv
= c
->callback
.WaitForResult();
4645 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4646 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4647 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4649 // Make sure that we revalidate the entry and read from the cache (a single
4650 // read will return while waiting for the network).
4651 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
4652 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4653 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
4654 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4655 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4657 // Destroy the transaction before completing the read.
4660 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4661 // message loop. This means that a new transaction will just reuse the same
4662 // active entry (no open or create).
4664 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4666 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4667 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4668 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4669 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4672 // A slight variation of the previous test, this time we cancel two requests in
4673 // a row, making sure that the second is waiting for the entry to be ready.
4674 TEST(HttpCache
, RangeGET_Cancel3
) {
4675 MockHttpCache cache
;
4676 AddMockTransaction(&kRangeGET_TransactionOK
);
4678 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4679 MockHttpRequest
request(kRangeGET_TransactionOK
);
4680 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4682 Context
* c
= new Context();
4683 int rv
= cache
.CreateTransaction(&c
->trans
);
4684 ASSERT_EQ(net::OK
, rv
);
4686 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4687 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4688 rv
= c
->callback
.WaitForResult();
4690 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4691 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4692 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4694 // Make sure that we revalidate the entry and read from the cache (a single
4695 // read will return while waiting for the network).
4696 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
4697 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4698 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
4699 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4700 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4702 // Destroy the transaction before completing the read.
4705 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4706 // message loop. This means that a new transaction will just reuse the same
4707 // active entry (no open or create).
4710 rv
= cache
.CreateTransaction(&c
->trans
);
4711 ASSERT_EQ(net::OK
, rv
);
4713 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4714 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
4716 MockDiskEntry::IgnoreCallbacks(true);
4717 base::MessageLoop::current()->RunUntilIdle();
4718 MockDiskEntry::IgnoreCallbacks(false);
4720 // The new transaction is waiting for the query range callback.
4723 // And we should not crash when the callback is delivered.
4724 base::MessageLoop::current()->RunUntilIdle();
4726 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4727 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4728 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4729 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4732 // Tests that an invalid range response results in no cached entry.
4733 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
4734 MockHttpCache cache
;
4735 std::string headers
;
4737 MockTransaction
transaction(kRangeGET_TransactionOK
);
4738 transaction
.handler
= NULL
;
4739 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
4740 "Content-Length: 10\n";
4741 AddMockTransaction(&transaction
);
4742 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4744 std::string
expected(transaction
.status
);
4745 expected
.append("\n");
4746 expected
.append(transaction
.response_headers
);
4747 EXPECT_EQ(expected
, headers
);
4749 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4750 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4751 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4753 // Verify that we don't have a cached entry.
4754 disk_cache::Entry
* entry
;
4755 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4757 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4760 // Tests that we reject a range that doesn't match the content-length.
4761 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
4762 MockHttpCache cache
;
4763 std::string headers
;
4765 MockTransaction
transaction(kRangeGET_TransactionOK
);
4766 transaction
.handler
= NULL
;
4767 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
4768 "Content-Length: 20\n";
4769 AddMockTransaction(&transaction
);
4770 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4772 std::string
expected(transaction
.status
);
4773 expected
.append("\n");
4774 expected
.append(transaction
.response_headers
);
4775 EXPECT_EQ(expected
, headers
);
4777 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4778 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4779 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4781 // Verify that we don't have a cached entry.
4782 disk_cache::Entry
* entry
;
4783 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
4785 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4788 // Tests that if a server tells us conflicting information about a resource we
4789 // ignore the response.
4790 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
4791 MockHttpCache cache
;
4792 std::string headers
;
4794 MockTransaction
transaction(kRangeGET_TransactionOK
);
4795 transaction
.handler
= NULL
;
4796 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
4797 std::string
response_headers(transaction
.response_headers
);
4798 response_headers
.append("Content-Range: bytes 50-59/160\n");
4799 transaction
.response_headers
= response_headers
.c_str();
4800 AddMockTransaction(&transaction
);
4801 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4803 Verify206Response(headers
, 50, 59);
4804 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4805 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4806 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4808 RemoveMockTransaction(&transaction
);
4809 AddMockTransaction(&kRangeGET_TransactionOK
);
4811 // This transaction will report a resource size of 80 bytes, and we think it's
4812 // 160 so we should ignore the response.
4813 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4816 Verify206Response(headers
, 40, 49);
4817 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4818 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4819 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4821 // Verify that we cached the first response but not the second one.
4822 disk_cache::Entry
* en
;
4823 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
4825 int64 cached_start
= 0;
4826 net::TestCompletionCallback cb
;
4827 int rv
= en
->GetAvailableRange(40, 20, &cached_start
, cb
.callback());
4828 EXPECT_EQ(10, cb
.GetResult(rv
));
4829 EXPECT_EQ(50, cached_start
);
4832 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4835 // Tests that we handle large range values properly.
4836 TEST(HttpCache
, RangeGET_LargeValues
) {
4837 // We need a real sparse cache for this test.
4838 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4839 std::string headers
;
4841 MockTransaction
transaction(kRangeGET_TransactionOK
);
4842 transaction
.handler
= NULL
;
4843 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
4845 transaction
.response_headers
=
4847 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4848 "Content-Length: 10\n";
4849 AddMockTransaction(&transaction
);
4850 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4852 std::string
expected(transaction
.status
);
4853 expected
.append("\n");
4854 expected
.append(transaction
.response_headers
);
4855 EXPECT_EQ(expected
, headers
);
4857 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4859 // Verify that we have a cached entry.
4860 disk_cache::Entry
* en
;
4861 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
4864 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4867 // Tests that we don't crash with a range request if the disk cache was not
4868 // initialized properly.
4869 TEST(HttpCache
, RangeGET_NoDiskCache
) {
4870 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
4871 factory
->set_fail(true);
4872 factory
->FinishCreation(); // We'll complete synchronously.
4873 MockHttpCache
cache(factory
);
4875 AddMockTransaction(&kRangeGET_TransactionOK
);
4877 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4878 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4880 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4883 // Tests that we handle byte range requests that skip the cache.
4884 TEST(HttpCache
, RangeHEAD
) {
4885 MockHttpCache cache
;
4886 AddMockTransaction(&kRangeGET_TransactionOK
);
4888 MockTransaction
transaction(kRangeGET_TransactionOK
);
4889 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4890 transaction
.method
= "HEAD";
4891 transaction
.data
= "rg: 70-79 ";
4893 std::string headers
;
4894 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4896 Verify206Response(headers
, 70, 79);
4897 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4898 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4899 EXPECT_EQ(0, cache
.disk_cache()->create_count());
4901 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4904 // Tests that we don't crash when after reading from the cache we issue a
4905 // request for the next range and the server gives us a 200 synchronously.
4906 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
4907 MockHttpCache cache
;
4909 MockTransaction
transaction(kRangeGET_TransactionOK
);
4910 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
4911 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
4912 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4913 AddMockTransaction(&transaction
);
4915 // Write to the cache.
4916 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4918 // And now read from the cache and the network.
4919 RangeTransactionServer handler
;
4920 handler
.set_bad_200(true);
4921 transaction
.data
= "Not a range";
4922 RunTransactionTest(cache
.http_cache(), transaction
);
4924 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4925 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4926 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4928 RemoveMockTransaction(&transaction
);
4931 // Tests that when the server gives us less data than expected, we don't keep
4932 // asking for more data.
4933 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
4934 MockHttpCache cache
;
4936 // First, check with an empty cache (WRITE mode).
4937 MockTransaction
transaction(kRangeGET_TransactionOK
);
4938 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
4939 transaction
.data
= "rg: 40-"; // Less than expected.
4940 transaction
.handler
= NULL
;
4941 std::string
headers(transaction
.response_headers
);
4942 headers
.append("Content-Range: bytes 40-49/80\n");
4943 transaction
.response_headers
= headers
.c_str();
4945 AddMockTransaction(&transaction
);
4947 // Write to the cache.
4948 RunTransactionTest(cache
.http_cache(), transaction
);
4950 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4951 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4952 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4954 // Now verify that even in READ_WRITE mode, we forward the bad response to
4956 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
4957 transaction
.data
= "rg: 60-"; // Less than expected.
4958 headers
= kRangeGET_TransactionOK
.response_headers
;
4959 headers
.append("Content-Range: bytes 60-69/80\n");
4960 transaction
.response_headers
= headers
.c_str();
4962 RunTransactionTest(cache
.http_cache(), transaction
);
4964 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4965 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4966 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4968 RemoveMockTransaction(&transaction
);
4971 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
4972 // This test hits a NOTREACHED so it is a release mode only test.
4973 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
4974 MockHttpCache cache
;
4975 AddMockTransaction(&kRangeGET_TransactionOK
);
4977 // Write to the cache (40-49).
4978 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4979 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4980 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4981 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4983 // Force this transaction to read from the cache.
4984 MockTransaction
transaction(kRangeGET_TransactionOK
);
4985 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
4987 MockHttpRequest
request(transaction
);
4988 net::TestCompletionCallback callback
;
4990 scoped_ptr
<net::HttpTransaction
> trans
;
4991 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
4992 EXPECT_EQ(net::OK
, rv
);
4993 ASSERT_TRUE(trans
.get());
4995 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
4996 if (rv
== net::ERR_IO_PENDING
)
4997 rv
= callback
.WaitForResult();
4998 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5002 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5003 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5004 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5006 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5010 // Tests the handling of the "truncation" flag.
5011 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5012 MockHttpCache cache
;
5013 disk_cache::Entry
* entry
;
5014 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5017 std::string
headers("HTTP/1.1 200 OK");
5018 headers
= net::HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5019 net::HttpResponseInfo response
;
5020 response
.headers
= new net::HttpResponseHeaders(headers
);
5022 // Set the last argument for this to be an incomplete request.
5023 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5024 bool truncated
= false;
5025 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5026 EXPECT_TRUE(truncated
);
5028 // And now test the opposite case.
5029 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5031 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5032 EXPECT_FALSE(truncated
);
5036 // Tests basic pickling/unpickling of HttpResponseInfo.
5037 TEST(HttpCache
, PersistHttpResponseInfo
) {
5038 // Set some fields (add more if needed.)
5039 net::HttpResponseInfo response1
;
5040 response1
.was_cached
= false;
5041 response1
.socket_address
= net::HostPortPair("1.2.3.4", 80);
5042 response1
.headers
= new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5046 response1
.Persist(&pickle
, false, false);
5049 net::HttpResponseInfo response2
;
5050 bool response_truncated
;
5051 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5052 EXPECT_FALSE(response_truncated
);
5055 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5056 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5057 EXPECT_EQ(80, response2
.socket_address
.port());
5058 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5061 // Tests that we delete an entry when the request is cancelled before starting
5062 // to read from the network.
5063 TEST(HttpCache
, DoomOnDestruction
) {
5064 MockHttpCache cache
;
5066 MockHttpRequest
request(kSimpleGET_Transaction
);
5068 Context
* c
= new Context();
5069 int rv
= cache
.CreateTransaction(&c
->trans
);
5070 ASSERT_EQ(net::OK
, rv
);
5072 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5073 if (rv
== net::ERR_IO_PENDING
)
5074 c
->result
= c
->callback
.WaitForResult();
5076 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5077 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5078 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5080 // Destroy the transaction. We only have the headers so we should delete this
5084 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5086 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5087 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5088 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5091 // Tests that we delete an entry when the request is cancelled if the response
5092 // does not have content-length and strong validators.
5093 TEST(HttpCache
, DoomOnDestruction2
) {
5094 MockHttpCache cache
;
5096 MockHttpRequest
request(kSimpleGET_Transaction
);
5098 Context
* c
= new Context();
5099 int rv
= cache
.CreateTransaction(&c
->trans
);
5100 ASSERT_EQ(net::OK
, rv
);
5102 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5103 if (rv
== net::ERR_IO_PENDING
)
5104 rv
= c
->callback
.WaitForResult();
5106 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5107 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5108 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5110 // Make sure that the entry has some data stored.
5111 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5112 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5113 if (rv
== net::ERR_IO_PENDING
)
5114 rv
= c
->callback
.WaitForResult();
5115 EXPECT_EQ(buf
->size(), rv
);
5117 // Destroy the transaction.
5120 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5122 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5123 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5124 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5127 // Tests that we delete an entry when the request is cancelled if the response
5128 // has an "Accept-Ranges: none" header.
5129 TEST(HttpCache
, DoomOnDestruction3
) {
5130 MockHttpCache cache
;
5132 MockTransaction
transaction(kSimpleGET_Transaction
);
5133 transaction
.response_headers
=
5134 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5135 "Content-Length: 22\n"
5136 "Accept-Ranges: none\n"
5137 "Etag: \"foopy\"\n";
5138 AddMockTransaction(&transaction
);
5139 MockHttpRequest
request(transaction
);
5141 Context
* c
= new Context();
5142 int rv
= cache
.CreateTransaction(&c
->trans
);
5143 ASSERT_EQ(net::OK
, rv
);
5145 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5146 if (rv
== net::ERR_IO_PENDING
)
5147 rv
= c
->callback
.WaitForResult();
5149 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5150 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5151 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5153 // Make sure that the entry has some data stored.
5154 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5155 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5156 if (rv
== net::ERR_IO_PENDING
)
5157 rv
= c
->callback
.WaitForResult();
5158 EXPECT_EQ(buf
->size(), rv
);
5160 // Destroy the transaction.
5163 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5165 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5166 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5167 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5169 RemoveMockTransaction(&transaction
);
5172 // Tests that we mark an entry as incomplete when the request is cancelled.
5173 TEST(HttpCache
, SetTruncatedFlag
) {
5174 MockHttpCache cache
;
5176 MockTransaction
transaction(kSimpleGET_Transaction
);
5177 transaction
.response_headers
=
5178 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5179 "Content-Length: 22\n"
5180 "Etag: \"foopy\"\n";
5181 AddMockTransaction(&transaction
);
5182 MockHttpRequest
request(transaction
);
5184 scoped_ptr
<Context
> c(new Context());
5186 int rv
= cache
.CreateTransaction(&c
->trans
);
5187 ASSERT_EQ(net::OK
, rv
);
5189 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5190 if (rv
== net::ERR_IO_PENDING
)
5191 rv
= c
->callback
.WaitForResult();
5193 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5194 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5195 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5197 // Make sure that the entry has some data stored.
5198 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5199 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5200 if (rv
== net::ERR_IO_PENDING
)
5201 rv
= c
->callback
.WaitForResult();
5202 EXPECT_EQ(buf
->size(), rv
);
5204 // We want to cancel the request when the transaction is busy.
5205 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5206 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5207 EXPECT_FALSE(c
->callback
.have_result());
5209 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5211 // Destroy the transaction.
5213 MockHttpCache::SetTestMode(0);
5216 // Make sure that we don't invoke the callback. We may have an issue if the
5217 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5218 // could end up with the transaction being deleted twice if we send any
5219 // notification from the transaction destructor (see http://crbug.com/31723).
5220 EXPECT_FALSE(c
->callback
.have_result());
5222 // Verify that the entry is marked as incomplete.
5223 disk_cache::Entry
* entry
;
5224 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5225 net::HttpResponseInfo response
;
5226 bool truncated
= false;
5227 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5228 EXPECT_TRUE(truncated
);
5231 RemoveMockTransaction(&transaction
);
5234 // Tests that we don't mark an entry as truncated when we read everything.
5235 TEST(HttpCache
, DontSetTruncatedFlag
) {
5236 MockHttpCache cache
;
5238 MockTransaction
transaction(kSimpleGET_Transaction
);
5239 transaction
.response_headers
=
5240 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5241 "Content-Length: 22\n"
5242 "Etag: \"foopy\"\n";
5243 AddMockTransaction(&transaction
);
5244 MockHttpRequest
request(transaction
);
5246 scoped_ptr
<Context
> c(new Context());
5247 int rv
= cache
.CreateTransaction(&c
->trans
);
5248 ASSERT_EQ(net::OK
, rv
);
5250 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5251 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5254 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(22));
5255 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5256 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5258 // Destroy the transaction.
5261 // Verify that the entry is not marked as truncated.
5262 disk_cache::Entry
* entry
;
5263 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5264 net::HttpResponseInfo response
;
5265 bool truncated
= true;
5266 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5267 EXPECT_FALSE(truncated
);
5270 RemoveMockTransaction(&transaction
);
5273 // Tests that we can continue with a request that was interrupted.
5274 TEST(HttpCache
, GET_IncompleteResource
) {
5275 MockHttpCache cache
;
5276 AddMockTransaction(&kRangeGET_TransactionOK
);
5278 std::string
raw_headers("HTTP/1.1 200 OK\n"
5279 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5281 "Accept-Ranges: bytes\n"
5282 "Content-Length: 80\n");
5283 CreateTruncatedEntry(raw_headers
, &cache
);
5285 // Now make a regular request.
5286 std::string headers
;
5287 MockTransaction
transaction(kRangeGET_TransactionOK
);
5288 transaction
.request_headers
= EXTRA_HEADER
;
5289 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5290 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5291 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5293 // We update the headers with the ones received while revalidating.
5294 std::string
expected_headers(
5296 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5297 "Accept-Ranges: bytes\n"
5299 "Content-Length: 80\n");
5301 EXPECT_EQ(expected_headers
, headers
);
5302 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5303 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5304 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5306 // Verify that the disk entry was updated.
5307 disk_cache::Entry
* entry
;
5308 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5309 EXPECT_EQ(80, entry
->GetDataSize(1));
5310 bool truncated
= true;
5311 net::HttpResponseInfo response
;
5312 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5313 EXPECT_FALSE(truncated
);
5316 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5319 // Tests the handling of no-store when revalidating a truncated entry.
5320 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5321 MockHttpCache cache
;
5322 AddMockTransaction(&kRangeGET_TransactionOK
);
5324 std::string
raw_headers("HTTP/1.1 200 OK\n"
5325 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5327 "Accept-Ranges: bytes\n"
5328 "Content-Length: 80\n");
5329 CreateTruncatedEntry(raw_headers
, &cache
);
5330 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5332 // Now make a regular request.
5333 MockTransaction
transaction(kRangeGET_TransactionOK
);
5334 transaction
.request_headers
= EXTRA_HEADER
;
5335 std::string
response_headers(transaction
.response_headers
);
5336 response_headers
+= ("Cache-Control: no-store\n");
5337 transaction
.response_headers
= response_headers
.c_str();
5338 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5339 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5340 AddMockTransaction(&transaction
);
5342 std::string headers
;
5343 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5345 // We update the headers with the ones received while revalidating.
5346 std::string
expected_headers(
5348 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5349 "Accept-Ranges: bytes\n"
5350 "Cache-Control: no-store\n"
5352 "Content-Length: 80\n");
5354 EXPECT_EQ(expected_headers
, headers
);
5355 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5356 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5357 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5359 // Verify that the disk entry was deleted.
5360 disk_cache::Entry
* entry
;
5361 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5362 RemoveMockTransaction(&transaction
);
5365 // Tests cancelling a request after the server sent no-store.
5366 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5367 MockHttpCache cache
;
5368 AddMockTransaction(&kRangeGET_TransactionOK
);
5370 std::string
raw_headers("HTTP/1.1 200 OK\n"
5371 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5373 "Accept-Ranges: bytes\n"
5374 "Content-Length: 80\n");
5375 CreateTruncatedEntry(raw_headers
, &cache
);
5376 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5378 // Now make a regular request.
5379 MockTransaction
transaction(kRangeGET_TransactionOK
);
5380 transaction
.request_headers
= EXTRA_HEADER
;
5381 std::string
response_headers(transaction
.response_headers
);
5382 response_headers
+= ("Cache-Control: no-store\n");
5383 transaction
.response_headers
= response_headers
.c_str();
5384 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5385 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5386 AddMockTransaction(&transaction
);
5388 MockHttpRequest
request(transaction
);
5389 Context
* c
= new Context();
5391 int rv
= cache
.CreateTransaction(&c
->trans
);
5392 ASSERT_EQ(net::OK
, rv
);
5394 // Queue another request to this transaction. We have to start this request
5395 // before the first one gets the response from the server and dooms the entry,
5396 // otherwise it will just create a new entry without being queued to the first
5398 Context
* pending
= new Context();
5399 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&pending
->trans
));
5401 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5402 EXPECT_EQ(net::ERR_IO_PENDING
,
5403 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5404 net::BoundNetLog()));
5405 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5407 // Make sure that the entry has some data stored.
5408 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5409 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5410 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5412 // Cancel the requests.
5416 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5417 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5418 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5420 base::MessageLoop::current()->RunUntilIdle();
5421 RemoveMockTransaction(&transaction
);
5424 // Tests that we delete truncated entries if the server changes its mind midway.
5425 TEST(HttpCache
, GET_IncompleteResource2
) {
5426 MockHttpCache cache
;
5427 AddMockTransaction(&kRangeGET_TransactionOK
);
5429 // Content-length will be intentionally bad.
5430 std::string
raw_headers("HTTP/1.1 200 OK\n"
5431 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5433 "Accept-Ranges: bytes\n"
5434 "Content-Length: 50\n");
5435 CreateTruncatedEntry(raw_headers
, &cache
);
5437 // Now make a regular request. We expect the code to fail the validation and
5438 // retry the request without using byte ranges.
5439 std::string headers
;
5440 MockTransaction
transaction(kRangeGET_TransactionOK
);
5441 transaction
.request_headers
= EXTRA_HEADER
;
5442 transaction
.data
= "Not a range";
5443 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5445 // The server will return 200 instead of a byte range.
5446 std::string
expected_headers(
5448 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5450 EXPECT_EQ(expected_headers
, headers
);
5451 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5453 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5455 // Verify that the disk entry was deleted.
5456 disk_cache::Entry
* entry
;
5457 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5458 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5461 // Tests that we always validate a truncated request.
5462 TEST(HttpCache
, GET_IncompleteResource3
) {
5463 MockHttpCache cache
;
5464 AddMockTransaction(&kRangeGET_TransactionOK
);
5466 // This should not require validation for 10 hours.
5467 std::string
raw_headers("HTTP/1.1 200 OK\n"
5468 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5470 "Cache-Control: max-age= 36000\n"
5471 "Accept-Ranges: bytes\n"
5472 "Content-Length: 80\n");
5473 CreateTruncatedEntry(raw_headers
, &cache
);
5475 // Now make a regular request.
5476 std::string headers
;
5477 MockTransaction
transaction(kRangeGET_TransactionOK
);
5478 transaction
.request_headers
= EXTRA_HEADER
;
5479 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5480 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5482 scoped_ptr
<Context
> c(new Context
);
5483 int rv
= cache
.CreateTransaction(&c
->trans
);
5484 ASSERT_EQ(net::OK
, rv
);
5486 MockHttpRequest
request(transaction
);
5487 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5488 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5490 // We should have checked with the server before finishing Start().
5491 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5492 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5493 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5495 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5498 // Tests that we handle 401s for truncated resources.
5499 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
5500 MockHttpCache cache
;
5501 AddMockTransaction(&kRangeGET_TransactionOK
);
5503 std::string
raw_headers("HTTP/1.1 200 OK\n"
5504 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5506 "Accept-Ranges: bytes\n"
5507 "Content-Length: 80\n");
5508 CreateTruncatedEntry(raw_headers
, &cache
);
5510 // Now make a regular request.
5511 MockTransaction
transaction(kRangeGET_TransactionOK
);
5512 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
5514 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5515 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5516 RangeTransactionServer handler
;
5518 scoped_ptr
<Context
> c(new Context
);
5519 int rv
= cache
.CreateTransaction(&c
->trans
);
5520 ASSERT_EQ(net::OK
, rv
);
5522 MockHttpRequest
request(transaction
);
5523 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5524 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5526 const net::HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
5527 ASSERT_TRUE(response
);
5528 ASSERT_EQ(401, response
->headers
->response_code());
5529 rv
= c
->trans
->RestartWithAuth(net::AuthCredentials(),
5530 c
->callback
.callback());
5531 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5532 response
= c
->trans
->GetResponseInfo();
5533 ASSERT_TRUE(response
);
5534 ASSERT_EQ(200, response
->headers
->response_code());
5536 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
5537 c
.reset(); // The destructor could delete the entry.
5538 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5540 // Verify that the entry was not deleted.
5541 disk_cache::Entry
* entry
;
5542 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5545 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5548 // Tests that we cache a 200 response to the validation request.
5549 TEST(HttpCache
, GET_IncompleteResource4
) {
5550 MockHttpCache cache
;
5551 AddMockTransaction(&kRangeGET_TransactionOK
);
5553 std::string
raw_headers("HTTP/1.1 200 OK\n"
5554 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5556 "Accept-Ranges: bytes\n"
5557 "Content-Length: 80\n");
5558 CreateTruncatedEntry(raw_headers
, &cache
);
5560 // Now make a regular request.
5561 std::string headers
;
5562 MockTransaction
transaction(kRangeGET_TransactionOK
);
5563 transaction
.request_headers
= EXTRA_HEADER
;
5564 transaction
.data
= "Not a range";
5565 RangeTransactionServer handler
;
5566 handler
.set_bad_200(true);
5567 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5569 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5570 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5571 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5573 // Verify that the disk entry was updated.
5574 disk_cache::Entry
* entry
;
5575 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5576 EXPECT_EQ(11, entry
->GetDataSize(1));
5577 bool truncated
= true;
5578 net::HttpResponseInfo response
;
5579 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5580 EXPECT_FALSE(truncated
);
5583 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5586 // Tests that when we cancel a request that was interrupted, we mark it again
5588 TEST(HttpCache
, GET_CancelIncompleteResource
) {
5589 MockHttpCache cache
;
5590 AddMockTransaction(&kRangeGET_TransactionOK
);
5592 std::string
raw_headers("HTTP/1.1 200 OK\n"
5593 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5595 "Accept-Ranges: bytes\n"
5596 "Content-Length: 80\n");
5597 CreateTruncatedEntry(raw_headers
, &cache
);
5599 // Now make a regular request.
5600 MockTransaction
transaction(kRangeGET_TransactionOK
);
5601 transaction
.request_headers
= EXTRA_HEADER
;
5603 MockHttpRequest
request(transaction
);
5604 Context
* c
= new Context();
5605 int rv
= cache
.CreateTransaction(&c
->trans
);
5606 ASSERT_EQ(net::OK
, rv
);
5608 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5609 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5611 // Read 20 bytes from the cache, and 10 from the net.
5612 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
5613 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
5614 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
5615 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
5616 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
5618 // At this point, we are already reading so canceling the request should leave
5622 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5623 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5624 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5626 // Verify that the disk entry was updated: now we have 30 bytes.
5627 disk_cache::Entry
* entry
;
5628 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5629 EXPECT_EQ(30, entry
->GetDataSize(1));
5630 bool truncated
= false;
5631 net::HttpResponseInfo response
;
5632 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5633 EXPECT_TRUE(truncated
);
5635 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5638 // Tests that we can handle range requests when we have a truncated entry.
5639 TEST(HttpCache
, RangeGET_IncompleteResource
) {
5640 MockHttpCache cache
;
5641 AddMockTransaction(&kRangeGET_TransactionOK
);
5643 // Content-length will be intentionally bogus.
5644 std::string
raw_headers("HTTP/1.1 200 OK\n"
5645 "Last-Modified: something\n"
5647 "Accept-Ranges: bytes\n"
5648 "Content-Length: 10\n");
5649 CreateTruncatedEntry(raw_headers
, &cache
);
5651 // Now make a range request.
5652 std::string headers
;
5653 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5656 Verify206Response(headers
, 40, 49);
5657 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5658 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5659 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5661 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5664 TEST(HttpCache
, SyncRead
) {
5665 MockHttpCache cache
;
5667 // This test ensures that a read that completes synchronously does not cause
5670 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5671 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
5672 TEST_MODE_SYNC_CACHE_READ
|
5673 TEST_MODE_SYNC_CACHE_WRITE
);
5675 MockHttpRequest
r1(transaction
),
5679 TestTransactionConsumer
c1(net::DEFAULT_PRIORITY
, cache
.http_cache()),
5680 c2(net::DEFAULT_PRIORITY
, cache
.http_cache()),
5681 c3(net::DEFAULT_PRIORITY
, cache
.http_cache());
5683 c1
.Start(&r1
, net::BoundNetLog());
5685 r2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5686 c2
.Start(&r2
, net::BoundNetLog());
5688 r3
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5689 c3
.Start(&r3
, net::BoundNetLog());
5691 base::MessageLoop::current()->Run();
5693 EXPECT_TRUE(c1
.is_done());
5694 EXPECT_TRUE(c2
.is_done());
5695 EXPECT_TRUE(c3
.is_done());
5697 EXPECT_EQ(net::OK
, c1
.error());
5698 EXPECT_EQ(net::OK
, c2
.error());
5699 EXPECT_EQ(net::OK
, c3
.error());
5702 TEST(HttpCache
, ValidationResultsIn200
) {
5703 MockHttpCache cache
;
5705 // This test ensures that a conditional request, which results in a 200
5706 // instead of a 304, properly truncates the existing response data.
5708 // write to the cache
5709 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
5711 // force this transaction to validate the cache
5712 MockTransaction
transaction(kETagGET_Transaction
);
5713 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5714 RunTransactionTest(cache
.http_cache(), transaction
);
5716 // read from the cache
5717 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
5720 TEST(HttpCache
, CachedRedirect
) {
5721 MockHttpCache cache
;
5723 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
5724 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
5725 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
5727 MockHttpRequest
request(kTestTransaction
);
5728 net::TestCompletionCallback callback
;
5730 // Write to the cache.
5732 scoped_ptr
<net::HttpTransaction
> trans
;
5733 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5735 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5736 if (rv
== net::ERR_IO_PENDING
)
5737 rv
= callback
.WaitForResult();
5738 ASSERT_EQ(net::OK
, rv
);
5740 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
5743 EXPECT_EQ(info
->headers
->response_code(), 301);
5745 std::string location
;
5746 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
5747 EXPECT_EQ(location
, "http://www.bar.com/");
5749 // Mark the transaction as completed so it is cached.
5750 trans
->DoneReading();
5752 // Destroy transaction when going out of scope. We have not actually
5753 // read the response body -- want to test that it is still getting cached.
5755 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5756 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5757 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5759 // Active entries in the cache are not retired synchronously. Make
5760 // sure the next run hits the MockHttpCache and open_count is
5762 base::MessageLoop::current()->RunUntilIdle();
5764 // Read from the cache.
5766 scoped_ptr
<net::HttpTransaction
> trans
;
5767 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5769 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5770 if (rv
== net::ERR_IO_PENDING
)
5771 rv
= callback
.WaitForResult();
5772 ASSERT_EQ(net::OK
, rv
);
5774 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
5777 EXPECT_EQ(info
->headers
->response_code(), 301);
5779 std::string location
;
5780 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
5781 EXPECT_EQ(location
, "http://www.bar.com/");
5783 // Mark the transaction as completed so it is cached.
5784 trans
->DoneReading();
5786 // Destroy transaction when going out of scope. We have not actually
5787 // read the response body -- want to test that it is still getting cached.
5789 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5790 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5791 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5794 // Verify that no-cache resources are stored in cache, but are not fetched from
5795 // cache during normal loads.
5796 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
5797 MockHttpCache cache
;
5799 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5800 transaction
.response_headers
= "cache-control: no-cache\n";
5803 RunTransactionTest(cache
.http_cache(), transaction
);
5805 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5806 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5807 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5809 // Try loading again; it should result in a network fetch.
5810 RunTransactionTest(cache
.http_cache(), transaction
);
5812 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5813 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5814 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5816 disk_cache::Entry
* entry
;
5817 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5821 // Verify that no-cache resources are stored in cache and fetched from cache
5822 // when the LOAD_PREFERRING_CACHE flag is set.
5823 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
5824 MockHttpCache cache
;
5826 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5827 transaction
.response_headers
= "cache-control: no-cache\n";
5830 RunTransactionTest(cache
.http_cache(), transaction
);
5832 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5833 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5834 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5836 // Try loading again with LOAD_PREFERRING_CACHE.
5837 transaction
.load_flags
= net::LOAD_PREFERRING_CACHE
;
5838 RunTransactionTest(cache
.http_cache(), transaction
);
5840 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5841 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5842 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5844 disk_cache::Entry
* entry
;
5845 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5849 TEST(HttpCache
, CacheControlNoStore
) {
5850 MockHttpCache cache
;
5852 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
5853 transaction
.response_headers
= "cache-control: no-store\n";
5856 RunTransactionTest(cache
.http_cache(), transaction
);
5858 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5859 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5860 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5862 // try loading again; it should result in a network fetch
5863 RunTransactionTest(cache
.http_cache(), transaction
);
5865 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5866 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5867 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5869 disk_cache::Entry
* entry
;
5870 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5873 TEST(HttpCache
, CacheControlNoStore2
) {
5874 // this test is similar to the above test, except that the initial response
5875 // is cachable, but when it is validated, no-store is received causing the
5876 // cached document to be deleted.
5877 MockHttpCache cache
;
5879 ScopedMockTransaction
transaction(kETagGET_Transaction
);
5882 RunTransactionTest(cache
.http_cache(), transaction
);
5884 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5885 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5886 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5888 // try loading again; it should result in a network fetch
5889 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
5890 transaction
.response_headers
= "cache-control: no-store\n";
5891 RunTransactionTest(cache
.http_cache(), transaction
);
5893 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5894 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5895 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5897 disk_cache::Entry
* entry
;
5898 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5901 TEST(HttpCache
, CacheControlNoStore3
) {
5902 // this test is similar to the above test, except that the response is a 304
5903 // instead of a 200. this should never happen in practice, but it seems like
5904 // a good thing to verify that we still destroy the cache entry.
5905 MockHttpCache cache
;
5907 ScopedMockTransaction
transaction(kETagGET_Transaction
);
5910 RunTransactionTest(cache
.http_cache(), transaction
);
5912 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5913 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5914 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5916 // try loading again; it should result in a network fetch
5917 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
5918 transaction
.response_headers
= "cache-control: no-store\n";
5919 transaction
.status
= "HTTP/1.1 304 Not Modified";
5920 RunTransactionTest(cache
.http_cache(), transaction
);
5922 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5923 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5924 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5926 disk_cache::Entry
* entry
;
5927 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
5930 // Ensure that we don't cache requests served over bad HTTPS.
5931 TEST(HttpCache
, SimpleGET_SSLError
) {
5932 MockHttpCache cache
;
5934 MockTransaction transaction
= kSimpleGET_Transaction
;
5935 transaction
.cert_status
= net::CERT_STATUS_REVOKED
;
5936 ScopedMockTransaction
scoped_transaction(transaction
);
5938 // write to the cache
5939 RunTransactionTest(cache
.http_cache(), transaction
);
5941 // Test that it was not cached.
5942 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5944 MockHttpRequest
request(transaction
);
5945 net::TestCompletionCallback callback
;
5947 scoped_ptr
<net::HttpTransaction
> trans
;
5948 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
5950 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5951 if (rv
== net::ERR_IO_PENDING
)
5952 rv
= callback
.WaitForResult();
5953 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5956 // Ensure that we don't crash by if left-behind transactions.
5957 TEST(HttpCache
, OutlivedTransactions
) {
5958 MockHttpCache
* cache
= new MockHttpCache
;
5960 scoped_ptr
<net::HttpTransaction
> trans
;
5961 EXPECT_EQ(net::OK
, cache
->CreateTransaction(&trans
));
5967 // Test that the disabled mode works.
5968 TEST(HttpCache
, CacheDisabledMode
) {
5969 MockHttpCache cache
;
5971 // write to the cache
5972 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5974 // go into disabled mode
5975 cache
.http_cache()->set_mode(net::HttpCache::DISABLE
);
5977 // force this transaction to write to the cache again
5978 MockTransaction
transaction(kSimpleGET_Transaction
);
5980 RunTransactionTest(cache
.http_cache(), transaction
);
5982 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5983 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5984 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5987 // Other tests check that the response headers of the cached response
5988 // get updated on 304. Here we specifically check that the
5989 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5990 // fields also gets updated.
5991 // http://crbug.com/20594.
5992 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
5993 MockHttpCache cache
;
5995 const char* kUrl
= "http://foobar";
5996 const char* kData
= "body";
5998 MockTransaction mock_network_response
= { 0 };
5999 mock_network_response
.url
= kUrl
;
6001 AddMockTransaction(&mock_network_response
);
6003 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6005 MockTransaction request
= { 0 };
6007 request
.method
= "GET";
6008 request
.request_headers
= "\r\n";
6009 request
.data
= kData
;
6011 static const Response kNetResponse1
= {
6013 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6014 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6018 kNetResponse1
.AssignTo(&mock_network_response
);
6020 RunTransactionTest(cache
.http_cache(), request
);
6022 // Request |kUrl| again, this time validating the cache and getting
6025 request
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6027 static const Response kNetResponse2
= {
6028 "HTTP/1.1 304 Not Modified",
6029 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6033 kNetResponse2
.AssignTo(&mock_network_response
);
6035 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6036 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6038 mock_network_response
.request_time
= request_time
;
6039 mock_network_response
.response_time
= response_time
;
6041 net::HttpResponseInfo response
;
6042 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6044 // The request and response times should have been updated.
6045 EXPECT_EQ(request_time
.ToInternalValue(),
6046 response
.request_time
.ToInternalValue());
6047 EXPECT_EQ(response_time
.ToInternalValue(),
6048 response
.response_time
.ToInternalValue());
6050 std::string headers
;
6051 response
.headers
->GetNormalizedHeaders(&headers
);
6053 EXPECT_EQ("HTTP/1.1 200 OK\n"
6054 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6055 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6058 RemoveMockTransaction(&mock_network_response
);
6061 // Tests that we can write metadata to an entry.
6062 TEST(HttpCache
, WriteMetadata_OK
) {
6063 MockHttpCache cache
;
6065 // Write to the cache
6066 net::HttpResponseInfo response
;
6067 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6069 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6072 cache
.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY
,
6073 Time::Now(), NULL
, 0);
6075 // Write meta data to the same entry.
6076 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6077 memset(buf
->data(), 0, buf
->size());
6078 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6079 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6080 net::DEFAULT_PRIORITY
,
6081 response
.response_time
,
6085 // Release the buffer before the operation takes place.
6088 // Makes sure we finish pending operations.
6089 base::MessageLoop::current()->RunUntilIdle();
6091 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6093 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6094 EXPECT_EQ(50, response
.metadata
->size());
6095 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6097 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6098 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6099 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6102 // Tests that we only write metadata to an entry if the time stamp matches.
6103 TEST(HttpCache
, WriteMetadata_Fail
) {
6104 MockHttpCache cache
;
6106 // Write to the cache
6107 net::HttpResponseInfo response
;
6108 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6110 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6112 // Attempt to write meta data to the same entry.
6113 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6114 memset(buf
->data(), 0, buf
->size());
6115 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6116 base::Time expected_time
= response
.response_time
-
6117 base::TimeDelta::FromMilliseconds(20);
6118 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6119 net::DEFAULT_PRIORITY
,
6124 // Makes sure we finish pending operations.
6125 base::MessageLoop::current()->RunUntilIdle();
6127 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6129 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6131 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6132 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6133 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6136 // Tests that we can read metadata after validating the entry and with READ mode
6138 TEST(HttpCache
, ReadMetadata
) {
6139 MockHttpCache cache
;
6141 // Write to the cache
6142 net::HttpResponseInfo response
;
6143 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6144 kTypicalGET_Transaction
, &response
);
6145 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6147 // Write meta data to the same entry.
6148 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6149 memset(buf
->data(), 0, buf
->size());
6150 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6151 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6152 net::DEFAULT_PRIORITY
,
6153 response
.response_time
,
6157 // Makes sure we finish pending operations.
6158 base::MessageLoop::current()->RunUntilIdle();
6160 // Start with a READ mode transaction.
6161 MockTransaction
trans1(kTypicalGET_Transaction
);
6162 trans1
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
6164 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6165 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6166 EXPECT_EQ(50, response
.metadata
->size());
6167 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6169 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6170 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6171 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6172 base::MessageLoop::current()->RunUntilIdle();
6174 // Now make sure that the entry is re-validated with the server.
6175 trans1
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6176 trans1
.status
= "HTTP/1.1 304 Not Modified";
6177 AddMockTransaction(&trans1
);
6179 response
.metadata
= NULL
;
6180 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6181 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6183 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6184 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6185 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6186 base::MessageLoop::current()->RunUntilIdle();
6187 RemoveMockTransaction(&trans1
);
6189 // Now return 200 when validating the entry so the metadata will be lost.
6190 MockTransaction
trans2(kTypicalGET_Transaction
);
6191 trans2
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6192 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6193 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6195 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6196 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6197 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6200 // Tests that we don't mark entries as truncated when a filter detects the end
6202 TEST(HttpCache
, FilterCompletion
) {
6203 MockHttpCache cache
;
6204 net::TestCompletionCallback callback
;
6207 scoped_ptr
<net::HttpTransaction
> trans
;
6208 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6210 MockHttpRequest
request(kSimpleGET_Transaction
);
6211 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6212 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6214 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6215 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6216 EXPECT_GT(callback
.GetResult(rv
), 0);
6218 // Now make sure that the entry is preserved.
6219 trans
->DoneReading();
6222 // Make sure that the ActiveEntry is gone.
6223 base::MessageLoop::current()->RunUntilIdle();
6225 // Read from the cache.
6226 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6228 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6229 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6230 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6233 // Tests that we don't mark entries as truncated and release the cache
6234 // entry when DoneReading() is called before any Read() calls, such as
6236 TEST(HttpCache
, DoneReading
) {
6237 MockHttpCache cache
;
6238 net::TestCompletionCallback callback
;
6240 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6241 transaction
.data
= "";
6243 scoped_ptr
<net::HttpTransaction
> trans
;
6244 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6246 MockHttpRequest
request(transaction
);
6247 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6248 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6250 trans
->DoneReading();
6251 // Leave the transaction around.
6253 // Make sure that the ActiveEntry is gone.
6254 base::MessageLoop::current()->RunUntilIdle();
6256 // Read from the cache. This should not deadlock.
6257 RunTransactionTest(cache
.http_cache(), transaction
);
6259 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6260 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6261 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6264 // Tests that we stop caching when told.
6265 TEST(HttpCache
, StopCachingDeletesEntry
) {
6266 MockHttpCache cache
;
6267 net::TestCompletionCallback callback
;
6268 MockHttpRequest
request(kSimpleGET_Transaction
);
6271 scoped_ptr
<net::HttpTransaction
> trans
;
6272 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6274 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6275 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6277 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6278 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6279 EXPECT_EQ(10, callback
.GetResult(rv
));
6281 trans
->StopCaching();
6283 // We should be able to keep reading.
6284 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6285 EXPECT_GT(callback
.GetResult(rv
), 0);
6286 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6287 EXPECT_EQ(0, callback
.GetResult(rv
));
6290 // Make sure that the ActiveEntry is gone.
6291 base::MessageLoop::current()->RunUntilIdle();
6293 // Verify that the entry is gone.
6294 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6296 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6297 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6298 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6301 // Tests that we stop caching when told, even if DoneReading is called
6302 // after StopCaching.
6303 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6304 MockHttpCache cache
;
6305 net::TestCompletionCallback callback
;
6306 MockHttpRequest
request(kSimpleGET_Transaction
);
6309 scoped_ptr
<net::HttpTransaction
> trans
;
6310 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6312 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6313 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6315 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6316 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6317 EXPECT_EQ(10, callback
.GetResult(rv
));
6319 trans
->StopCaching();
6321 // We should be able to keep reading.
6322 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6323 EXPECT_GT(callback
.GetResult(rv
), 0);
6324 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6325 EXPECT_EQ(0, callback
.GetResult(rv
));
6327 // We should be able to call DoneReading.
6328 trans
->DoneReading();
6331 // Make sure that the ActiveEntry is gone.
6332 base::MessageLoop::current()->RunUntilIdle();
6334 // Verify that the entry is gone.
6335 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6337 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6338 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6339 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6342 // Tests that we stop caching when told, when using auth.
6343 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6344 MockHttpCache cache
;
6345 net::TestCompletionCallback callback
;
6346 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6347 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6348 AddMockTransaction(&mock_transaction
);
6349 MockHttpRequest
request(mock_transaction
);
6352 scoped_ptr
<net::HttpTransaction
> trans
;
6353 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6355 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6356 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6358 trans
->StopCaching();
6360 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6361 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6362 EXPECT_EQ(callback
.GetResult(rv
), 10);
6364 RemoveMockTransaction(&mock_transaction
);
6366 // Make sure that the ActiveEntry is gone.
6367 base::MessageLoop::current()->RunUntilIdle();
6369 // Verify that the entry is gone.
6370 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6372 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6373 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6374 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6377 // Tests that when we are told to stop caching we don't throw away valid data.
6378 TEST(HttpCache
, StopCachingSavesEntry
) {
6379 MockHttpCache cache
;
6380 net::TestCompletionCallback callback
;
6381 MockHttpRequest
request(kSimpleGET_Transaction
);
6384 scoped_ptr
<net::HttpTransaction
> trans
;
6385 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6387 // Force a response that can be resumed.
6388 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6389 AddMockTransaction(&mock_transaction
);
6390 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6391 "Content-Length: 42\n"
6394 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6395 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6397 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6398 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6399 EXPECT_EQ(callback
.GetResult(rv
), 10);
6401 trans
->StopCaching();
6403 // We should be able to keep reading.
6404 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6405 EXPECT_GT(callback
.GetResult(rv
), 0);
6406 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6407 EXPECT_EQ(callback
.GetResult(rv
), 0);
6409 RemoveMockTransaction(&mock_transaction
);
6412 // Verify that the entry is marked as incomplete.
6413 disk_cache::Entry
* entry
;
6414 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6415 net::HttpResponseInfo response
;
6416 bool truncated
= false;
6417 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6418 EXPECT_TRUE(truncated
);
6422 // Tests that we handle truncated enries when StopCaching is called.
6423 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6424 MockHttpCache cache
;
6425 net::TestCompletionCallback callback
;
6426 MockHttpRequest
request(kRangeGET_TransactionOK
);
6427 request
.extra_headers
.Clear();
6428 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6429 AddMockTransaction(&kRangeGET_TransactionOK
);
6431 std::string
raw_headers("HTTP/1.1 200 OK\n"
6432 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6434 "Accept-Ranges: bytes\n"
6435 "Content-Length: 80\n");
6436 CreateTruncatedEntry(raw_headers
, &cache
);
6439 // Now make a regular request.
6440 scoped_ptr
<net::HttpTransaction
> trans
;
6441 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6443 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6444 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6446 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6447 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6448 EXPECT_EQ(callback
.GetResult(rv
), 10);
6450 // This is actually going to do nothing.
6451 trans
->StopCaching();
6453 // We should be able to keep reading.
6454 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6455 EXPECT_GT(callback
.GetResult(rv
), 0);
6456 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6457 EXPECT_GT(callback
.GetResult(rv
), 0);
6458 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6459 EXPECT_EQ(callback
.GetResult(rv
), 0);
6462 // Verify that the disk entry was updated.
6463 disk_cache::Entry
* entry
;
6464 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6465 EXPECT_EQ(80, entry
->GetDataSize(1));
6466 bool truncated
= true;
6467 net::HttpResponseInfo response
;
6468 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6469 EXPECT_FALSE(truncated
);
6472 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6475 // Tests that we detect truncated resources from the net when there is
6476 // a Content-Length header.
6477 TEST(HttpCache
, TruncatedByContentLength
) {
6478 MockHttpCache cache
;
6479 net::TestCompletionCallback callback
;
6481 MockTransaction
transaction(kSimpleGET_Transaction
);
6482 AddMockTransaction(&transaction
);
6483 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6484 "Content-Length: 100\n";
6485 RunTransactionTest(cache
.http_cache(), transaction
);
6486 RemoveMockTransaction(&transaction
);
6488 // Read from the cache.
6489 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6491 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6492 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6493 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6496 // Tests that we actually flag entries as truncated when we detect an error
6498 TEST(HttpCache
, TruncatedByContentLength2
) {
6499 MockHttpCache cache
;
6500 net::TestCompletionCallback callback
;
6502 MockTransaction
transaction(kSimpleGET_Transaction
);
6503 AddMockTransaction(&transaction
);
6504 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6505 "Content-Length: 100\n"
6507 RunTransactionTest(cache
.http_cache(), transaction
);
6508 RemoveMockTransaction(&transaction
);
6510 // Verify that the entry is marked as incomplete.
6511 disk_cache::Entry
* entry
;
6512 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6513 net::HttpResponseInfo response
;
6514 bool truncated
= false;
6515 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6516 EXPECT_TRUE(truncated
);
6520 // Make sure that calling SetPriority on a cache transaction passes on
6521 // its priority updates to its underlying network transaction.
6522 TEST(HttpCache
, SetPriority
) {
6523 MockHttpCache cache
;
6525 scoped_ptr
<net::HttpTransaction
> trans
;
6526 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6528 // Shouldn't crash, but doesn't do anything either.
6529 trans
->SetPriority(net::LOW
);
6531 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6532 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6533 cache
.network_layer()->last_create_transaction_priority());
6535 net::HttpRequestInfo info
;
6536 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6537 net::TestCompletionCallback callback
;
6538 EXPECT_EQ(net::ERR_IO_PENDING
,
6539 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6541 EXPECT_TRUE(cache
.network_layer()->last_transaction());
6542 if (cache
.network_layer()->last_transaction()) {
6544 cache
.network_layer()->last_create_transaction_priority());
6546 cache
.network_layer()->last_transaction()->priority());
6549 trans
->SetPriority(net::HIGHEST
);
6551 if (cache
.network_layer()->last_transaction()) {
6553 cache
.network_layer()->last_create_transaction_priority());
6554 EXPECT_EQ(net::HIGHEST
,
6555 cache
.network_layer()->last_transaction()->priority());
6558 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6561 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6562 // transaction passes on its argument to the underlying network transaction.
6563 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
6564 MockHttpCache cache
;
6566 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
6567 scoped_ptr
<net::HttpTransaction
> trans
;
6568 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6570 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6572 net::HttpRequestInfo info
;
6573 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6574 net::TestCompletionCallback callback
;
6575 EXPECT_EQ(net::ERR_IO_PENDING
,
6576 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6578 ASSERT_TRUE(cache
.network_layer()->last_transaction());
6579 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
6580 websocket_handshake_stream_create_helper());
6581 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
6582 EXPECT_EQ(&create_helper
,
6583 cache
.network_layer()->last_transaction()->
6584 websocket_handshake_stream_create_helper());
6585 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6588 // Make sure that a cache transaction passes on its priority to
6589 // newly-created network transactions.
6590 TEST(HttpCache
, SetPriorityNewTransaction
) {
6591 MockHttpCache cache
;
6592 AddMockTransaction(&kRangeGET_TransactionOK
);
6594 std::string
raw_headers("HTTP/1.1 200 OK\n"
6595 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6597 "Accept-Ranges: bytes\n"
6598 "Content-Length: 80\n");
6599 CreateTruncatedEntry(raw_headers
, &cache
);
6601 // Now make a regular request.
6602 std::string headers
;
6603 MockTransaction
transaction(kRangeGET_TransactionOK
);
6604 transaction
.request_headers
= EXTRA_HEADER
;
6605 transaction
.data
= "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6606 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6608 scoped_ptr
<net::HttpTransaction
> trans
;
6610 cache
.http_cache()->CreateTransaction(net::MEDIUM
, &trans
));
6611 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6612 cache
.network_layer()->last_create_transaction_priority());
6614 MockHttpRequest
info(transaction
);
6615 net::TestCompletionCallback callback
;
6616 EXPECT_EQ(net::ERR_IO_PENDING
,
6617 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6618 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6620 EXPECT_EQ(net::MEDIUM
,
6621 cache
.network_layer()->last_create_transaction_priority());
6623 trans
->SetPriority(net::HIGHEST
);
6624 // Should trigger a new network transaction and pick up the new
6626 ReadAndVerifyTransaction(trans
.get(), transaction
);
6628 EXPECT_EQ(net::HIGHEST
,
6629 cache
.network_layer()->last_create_transaction_priority());
6631 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6634 int64
RunTransactionAndGetReceivedBytes(
6635 MockHttpCache
& cache
,
6636 const MockTransaction
& trans_info
) {
6637 int64 received_bytes
= -1;
6638 RunTransactionTestBase(cache
.http_cache(), trans_info
,
6639 MockHttpRequest(trans_info
), NULL
, net::BoundNetLog(),
6640 NULL
, &received_bytes
);
6641 return received_bytes
;
6644 int64
TransactionSize(const MockTransaction
& transaction
) {
6645 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
6646 strlen(transaction
.data
);
6649 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
6650 MockHttpCache cache
;
6652 MockTransaction
transaction(kSimpleGET_Transaction
);
6653 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6654 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6656 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6657 EXPECT_EQ(0, received_bytes
);
6660 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
6661 MockHttpCache cache
;
6663 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6664 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6665 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6667 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6668 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
6669 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6670 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6673 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
6674 MockHttpCache cache
;
6676 MockTransaction
transaction(kTypicalGET_Transaction
);
6677 transaction
.request_headers
= "Foo: bar\r\n";
6678 transaction
.response_headers
=
6679 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6680 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6682 "Cache-Control: max-age=0\n"
6684 AddMockTransaction(&transaction
);
6685 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6686 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6688 RevalidationServer server
;
6689 transaction
.handler
= server
.Handler
;
6690 transaction
.request_headers
= "Foo: none\r\n";
6691 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6692 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
6694 RemoveMockTransaction(&transaction
);
6697 TEST(HttpCache
, ReceivedBytesRange
) {
6698 MockHttpCache cache
;
6699 AddMockTransaction(&kRangeGET_TransactionOK
);
6700 MockTransaction
transaction(kRangeGET_TransactionOK
);
6702 // Read bytes 40-49 from the network.
6703 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6704 int64 range_response_size
= TransactionSize(transaction
);
6705 EXPECT_EQ(range_response_size
, received_bytes
);
6707 // Read bytes 40-49 from the cache.
6708 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6709 EXPECT_EQ(0, received_bytes
);
6710 base::MessageLoop::current()->RunUntilIdle();
6712 // Read bytes 30-39 from the network.
6713 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
6714 transaction
.data
= "rg: 30-39 ";
6715 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6716 EXPECT_EQ(range_response_size
, received_bytes
);
6717 base::MessageLoop::current()->RunUntilIdle();
6719 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6720 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
6721 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6722 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
6723 EXPECT_EQ(range_response_size
* 2, received_bytes
);
6725 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6728 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo
* request
,
6729 std::string
* response_status
,
6730 std::string
* response_headers
,
6731 std::string
* response_data
) {
6733 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
6734 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
6737 // Verify that the Resource-Freshness header is sent on a revalidation if the
6738 // stale-while-revalidate directive was on the response.
6739 TEST(HttpCache
, ResourceFreshnessHeaderSent
) {
6740 MockHttpCache cache
;
6742 ScopedMockTransaction
stale_while_revalidate_transaction(
6743 kSimpleGET_Transaction
);
6744 stale_while_revalidate_transaction
.response_headers
=
6745 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6747 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
6749 // Write to the cache.
6750 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
6752 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6754 // Send the request again and check that Resource-Freshness header is added.
6755 stale_while_revalidate_transaction
.handler
= CheckResourceFreshnessHeader
;
6757 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
6759 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6762 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo
* request
,
6763 std::string
* response_status
,
6764 std::string
* response_headers
,
6765 std::string
* response_data
) {
6766 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
6769 // Verify that the Resource-Freshness header is not sent when
6770 // stale-while-revalidate is 0.
6771 TEST(HttpCache
, ResourceFreshnessHeaderNotSent
) {
6772 MockHttpCache cache
;
6774 ScopedMockTransaction
stale_while_revalidate_transaction(
6775 kSimpleGET_Transaction
);
6776 stale_while_revalidate_transaction
.response_headers
=
6777 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6779 "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
6781 // Write to the cache.
6782 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
6784 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6786 // Send the request again and check that Resource-Freshness header is absent.
6787 stale_while_revalidate_transaction
.handler
= CheckResourceFreshnessAbsent
;
6789 RunTransactionTest(cache
.http_cache(), stale_while_revalidate_transaction
);
6791 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6794 // Tests that we allow multiple simultaneous, non-overlapping transactions to
6795 // take place on a sparse entry.
6796 TEST(HttpCache
, RangeGET_MultipleRequests
) {
6797 MockHttpCache cache
;
6799 // Create a transaction for bytes 0-9.
6800 MockHttpRequest
request(kRangeGET_TransactionOK
);
6801 MockTransaction
transaction(kRangeGET_TransactionOK
);
6802 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
6803 transaction
.data
= "rg: 00-09 ";
6804 AddMockTransaction(&transaction
);
6806 net::TestCompletionCallback callback
;
6807 scoped_ptr
<net::HttpTransaction
> trans
;
6808 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
6809 EXPECT_EQ(net::OK
, rv
);
6810 ASSERT_TRUE(trans
.get());
6812 // Start our transaction.
6813 trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6815 // A second transaction on a different part of the file (the default
6816 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
6817 // the already pending transaction.
6818 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
6820 // Let the first transaction complete.
6821 callback
.WaitForResult();
6823 RemoveMockTransaction(&transaction
);