1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/http_cache.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "net/base/cache_type.h"
17 #include "net/base/elements_upload_data_stream.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/load_flags.h"
20 #include "net/base/load_timing_info.h"
21 #include "net/base/load_timing_info_test_util.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/net_log_unittest.h"
24 #include "net/base/upload_bytes_element_reader.h"
25 #include "net/cert/cert_status_flags.h"
26 #include "net/disk_cache/disk_cache.h"
27 #include "net/http/http_byte_range.h"
28 #include "net/http/http_request_headers.h"
29 #include "net/http/http_request_info.h"
30 #include "net/http/http_response_headers.h"
31 #include "net/http/http_response_info.h"
32 #include "net/http/http_transaction.h"
33 #include "net/http/http_transaction_test_util.h"
34 #include "net/http/http_util.h"
35 #include "net/http/mock_http_cache.h"
36 #include "net/socket/client_socket_handle.h"
37 #include "net/ssl/ssl_cert_request_info.h"
38 #include "net/websockets/websocket_handshake_stream_base.h"
39 #include "testing/gtest/include/gtest/gtest.h"
45 // Tests the load timing values of a request that goes through a
46 // MockNetworkTransaction.
47 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo
& load_timing_info
) {
48 EXPECT_FALSE(load_timing_info
.socket_reused
);
49 EXPECT_NE(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
51 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
52 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
54 net::ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
55 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
56 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
57 load_timing_info
.send_start
);
59 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
61 // Set by URLRequest / URLRequestHttpJob, at a higher level.
62 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
63 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
64 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
67 // Tests the load timing values of a request that receives a cached response.
68 void TestLoadTimingCachedResponse(const net::LoadTimingInfo
& load_timing_info
) {
69 EXPECT_FALSE(load_timing_info
.socket_reused
);
70 EXPECT_EQ(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
72 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
73 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
75 net::ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
77 // Only the send start / end times should be sent, and they should have the
79 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
80 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
82 // Set by URLRequest / URLRequestHttpJob, at a higher level.
83 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
84 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
85 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
88 class DeleteCacheCompletionCallback
: public net::TestCompletionCallbackBase
{
90 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
92 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
93 base::Unretained(this))) {
96 const net::CompletionCallback
& callback() const { return callback_
; }
99 void OnComplete(int result
) {
104 MockHttpCache
* cache_
;
105 net::CompletionCallback callback_
;
107 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
110 //-----------------------------------------------------------------------------
113 void ReadAndVerifyTransaction(net::HttpTransaction
* trans
,
114 const MockTransaction
& trans_info
) {
116 int rv
= ReadTransaction(trans
, &content
);
118 EXPECT_EQ(net::OK
, rv
);
119 std::string
expected(trans_info
.data
);
120 EXPECT_EQ(expected
, content
);
123 void RunTransactionTestBase(net::HttpCache
* cache
,
124 const MockTransaction
& trans_info
,
125 const MockHttpRequest
& request
,
126 net::HttpResponseInfo
* response_info
,
127 const net::BoundNetLog
& net_log
,
128 net::LoadTimingInfo
* load_timing_info
,
129 int64
* received_bytes
) {
130 net::TestCompletionCallback callback
;
132 // write to the cache
134 scoped_ptr
<net::HttpTransaction
> trans
;
135 int rv
= cache
->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
136 EXPECT_EQ(net::OK
, rv
);
137 ASSERT_TRUE(trans
.get());
139 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
140 if (rv
== net::ERR_IO_PENDING
)
141 rv
= callback
.WaitForResult();
142 ASSERT_EQ(trans_info
.return_code
, rv
);
147 const net::HttpResponseInfo
* response
= trans
->GetResponseInfo();
148 ASSERT_TRUE(response
);
151 *response_info
= *response
;
153 if (load_timing_info
) {
154 // If a fake network connection is used, need a NetLog to get a fake socket
156 EXPECT_TRUE(net_log
.net_log());
157 *load_timing_info
= net::LoadTimingInfo();
158 trans
->GetLoadTimingInfo(load_timing_info
);
161 ReadAndVerifyTransaction(trans
.get(), trans_info
);
164 *received_bytes
= trans
->GetTotalReceivedBytes();
167 void RunTransactionTestWithRequest(net::HttpCache
* cache
,
168 const MockTransaction
& trans_info
,
169 const MockHttpRequest
& request
,
170 net::HttpResponseInfo
* response_info
) {
171 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
172 net::BoundNetLog(), NULL
, NULL
);
175 void RunTransactionTestAndGetTiming(net::HttpCache
* cache
,
176 const MockTransaction
& trans_info
,
177 const net::BoundNetLog
& log
,
178 net::LoadTimingInfo
* load_timing_info
) {
179 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
180 NULL
, log
, load_timing_info
, NULL
);
183 void RunTransactionTest(net::HttpCache
* cache
,
184 const MockTransaction
& trans_info
) {
185 RunTransactionTestAndGetTiming(cache
, trans_info
, net::BoundNetLog(), NULL
);
188 void RunTransactionTestWithLog(net::HttpCache
* cache
,
189 const MockTransaction
& trans_info
,
190 const net::BoundNetLog
& log
) {
191 RunTransactionTestAndGetTiming(cache
, trans_info
, log
, NULL
);
194 void RunTransactionTestWithResponseInfo(net::HttpCache
* cache
,
195 const MockTransaction
& trans_info
,
196 net::HttpResponseInfo
* response
) {
197 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
201 void RunTransactionTestWithResponseInfoAndGetTiming(
202 net::HttpCache
* cache
,
203 const MockTransaction
& trans_info
,
204 net::HttpResponseInfo
* response
,
205 const net::BoundNetLog
& log
,
206 net::LoadTimingInfo
* load_timing_info
) {
207 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
208 response
, log
, load_timing_info
, NULL
);
211 void RunTransactionTestWithResponse(net::HttpCache
* cache
,
212 const MockTransaction
& trans_info
,
213 std::string
* response_headers
) {
214 net::HttpResponseInfo response
;
215 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
216 response
.headers
->GetNormalizedHeaders(response_headers
);
219 void RunTransactionTestWithResponseAndGetTiming(
220 net::HttpCache
* cache
,
221 const MockTransaction
& trans_info
,
222 std::string
* response_headers
,
223 const net::BoundNetLog
& log
,
224 net::LoadTimingInfo
* load_timing_info
) {
225 net::HttpResponseInfo response
;
226 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
227 &response
, log
, load_timing_info
, NULL
);
228 response
.headers
->GetNormalizedHeaders(response_headers
);
231 // This class provides a handler for kFastNoStoreGET_Transaction so that the
232 // no-store header can be included on demand.
233 class FastTransactionServer
{
235 FastTransactionServer() {
238 ~FastTransactionServer() {}
240 void set_no_store(bool value
) { no_store
= value
; }
242 static void FastNoStoreHandler(const net::HttpRequestInfo
* request
,
243 std::string
* response_status
,
244 std::string
* response_headers
,
245 std::string
* response_data
) {
247 *response_headers
= "Cache-Control: no-store\n";
251 static bool no_store
;
252 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
254 bool FastTransactionServer::no_store
;
256 const MockTransaction kFastNoStoreGET_Transaction
= {
257 "http://www.google.com/nostore",
261 net::LOAD_VALIDATE_CACHE
,
263 "Cache-Control: max-age=10000\n",
265 "<html><body>Google Blah Blah</body></html>",
266 TEST_MODE_SYNC_NET_START
,
267 &FastTransactionServer::FastNoStoreHandler
,
272 // This class provides a handler for kRangeGET_TransactionOK so that the range
273 // request can be served on demand.
274 class RangeTransactionServer
{
276 RangeTransactionServer() {
277 not_modified_
= false;
281 ~RangeTransactionServer() {
282 not_modified_
= false;
287 // Returns only 416 or 304 when set.
288 void set_not_modified(bool value
) { not_modified_
= value
; }
290 // Returns 206 when revalidating a range (instead of 304).
291 void set_modified(bool value
) { modified_
= value
; }
293 // Returns 200 instead of 206 (a malformed response overall).
294 void set_bad_200(bool value
) { bad_200_
= value
; }
296 // Other than regular range related behavior (and the flags mentioned above),
297 // the server reacts to requests headers like so:
298 // X-Require-Mock-Auth -> return 401.
299 // X-Return-Default-Range -> assume 40-49 was requested.
300 static void RangeHandler(const net::HttpRequestInfo
* request
,
301 std::string
* response_status
,
302 std::string
* response_headers
,
303 std::string
* response_data
);
306 static bool not_modified_
;
307 static bool modified_
;
308 static bool bad_200_
;
309 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
311 bool RangeTransactionServer::not_modified_
= false;
312 bool RangeTransactionServer::modified_
= false;
313 bool RangeTransactionServer::bad_200_
= false;
315 // A dummy extra header that must be preserved on a given request.
317 // EXTRA_HEADER_LINE doesn't include a line terminator because it
318 // will be passed to AddHeaderFromString() which doesn't accept them.
319 #define EXTRA_HEADER_LINE "Extra: header"
321 // EXTRA_HEADER contains a line terminator, as expected by
322 // AddHeadersFromString() (_not_ AddHeaderFromString()).
323 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
325 static const char kExtraHeaderKey
[] = "Extra";
328 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo
* request
,
329 std::string
* response_status
,
330 std::string
* response_headers
,
331 std::string
* response_data
) {
332 if (request
->extra_headers
.IsEmpty()) {
333 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
334 response_data
->clear();
338 // We want to make sure we don't delete extra headers.
339 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
341 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
342 !request
->extra_headers
.HasHeader("Authorization")) {
343 response_status
->assign("HTTP/1.1 401 Unauthorized");
344 response_data
->assign("WWW-Authenticate: Foo\n");
349 response_status
->assign("HTTP/1.1 304 Not Modified");
350 response_data
->clear();
354 std::vector
<net::HttpByteRange
> ranges
;
355 std::string range_header
;
356 if (!request
->extra_headers
.GetHeader(
357 net::HttpRequestHeaders::kRange
, &range_header
) ||
358 !net::HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
359 ranges
.size() != 1) {
360 // This is not a byte range request. We return 200.
361 response_status
->assign("HTTP/1.1 200 OK");
362 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
363 response_data
->assign("Not a range");
367 // We can handle this range request.
368 net::HttpByteRange byte_range
= ranges
[0];
370 if (request
->extra_headers
.HasHeader("X-Return-Default-Range")) {
371 byte_range
.set_first_byte_position(40);
372 byte_range
.set_last_byte_position(49);
375 if (byte_range
.first_byte_position() > 79) {
376 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
377 response_data
->clear();
381 EXPECT_TRUE(byte_range
.ComputeBounds(80));
382 int start
= static_cast<int>(byte_range
.first_byte_position());
383 int end
= static_cast<int>(byte_range
.last_byte_position());
387 std::string content_range
= base::StringPrintf(
388 "Content-Range: bytes %d-%d/80\n", start
, end
);
389 response_headers
->append(content_range
);
391 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
394 EXPECT_EQ(0, end
% 10);
397 EXPECT_EQ(9, (end
- start
) % 10);
398 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
399 base::StringAppendF(&data
, "rg: %02d-%02d ",
400 block_start
, block_start
+ 9);
403 *response_data
= data
;
405 if (end
- start
!= 9) {
406 // We also have to fix content-length.
407 int len
= end
- start
+ 1;
408 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
410 response_headers
->replace(response_headers
->find("Content-Length:"),
411 content_length
.size(), content_length
);
414 response_status
->assign("HTTP/1.1 304 Not Modified");
415 response_data
->clear();
419 const MockTransaction kRangeGET_TransactionOK
= {
420 "http://www.google.com/range",
423 "Range: bytes = 40-49\r\n"
426 "HTTP/1.1 206 Partial Content",
427 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
429 "Accept-Ranges: bytes\n"
430 "Content-Length: 10\n",
434 &RangeTransactionServer::RangeHandler
,
439 const char kFullRangeData
[] =
440 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
441 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
443 // Verifies the response headers (|response|) match a partial content
444 // response for the range starting at |start| and ending at |end|.
445 void Verify206Response(std::string response
, int start
, int end
) {
446 std::string
raw_headers(net::HttpUtil::AssembleRawHeaders(response
.data(),
448 scoped_refptr
<net::HttpResponseHeaders
> headers(
449 new net::HttpResponseHeaders(raw_headers
));
451 ASSERT_EQ(206, headers
->response_code());
453 int64 range_start
, range_end
, object_size
;
455 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
456 int64 content_length
= headers
->GetContentLength();
458 int length
= end
- start
+ 1;
459 ASSERT_EQ(length
, content_length
);
460 ASSERT_EQ(start
, range_start
);
461 ASSERT_EQ(end
, range_end
);
464 // Creates a truncated entry that can be resumed using byte ranges.
465 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
466 // Create a disk cache entry that stores an incomplete resource.
467 disk_cache::Entry
* entry
;
468 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
471 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
474 net::HttpResponseInfo response
;
475 response
.response_time
= base::Time::Now();
476 response
.request_time
= base::Time::Now();
477 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
478 // Set the last argument for this to be an incomplete request.
479 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
481 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
482 int len
= static_cast<int>(base::strlcpy(buf
->data(),
483 "rg: 00-09 rg: 10-19 ", 100));
484 net::TestCompletionCallback cb
;
485 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
486 EXPECT_EQ(len
, cb
.GetResult(rv
));
490 // Helper to represent a network HTTP response.
492 // Set this response into |trans|.
493 void AssignTo(MockTransaction
* trans
) const {
494 trans
->status
= status
;
495 trans
->response_headers
= headers
;
499 std::string
status_and_headers() const {
500 return std::string(status
) + "\n" + std::string(headers
);
509 Context() : result(net::ERR_IO_PENDING
) {}
512 net::TestCompletionCallback callback
;
513 scoped_ptr
<net::HttpTransaction
> trans
;
516 class FakeWebSocketHandshakeStreamCreateHelper
517 : public net::WebSocketHandshakeStreamBase::CreateHelper
{
519 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
520 net::WebSocketHandshakeStreamBase
* CreateBasicStream(
521 scoped_ptr
<net::ClientSocketHandle
> connect
,
522 bool using_proxy
) override
{
525 net::WebSocketHandshakeStreamBase
* CreateSpdyStream(
526 const base::WeakPtr
<net::SpdySession
>& session
,
527 bool use_relative_url
) override
{
532 // Returns true if |entry| is not one of the log types paid attention to in this
533 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
535 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry
& entry
) {
536 switch (entry
.type
) {
537 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
538 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
539 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
540 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
541 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
542 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO
:
549 // Modifies |entries| to only include log entries created by the cache layer and
550 // asserted on in these tests.
551 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList
* entries
) {
552 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
553 &ShouldIgnoreLogEntry
),
557 bool LogContainsEventType(const net::CapturingBoundNetLog
& log
,
558 net::NetLog::EventType expected
) {
559 net::CapturingNetLog::CapturedEntryList entries
;
560 log
.GetEntries(&entries
);
561 for (size_t i
= 0; i
< entries
.size(); i
++) {
562 if (entries
[i
].type
== expected
)
571 //-----------------------------------------------------------------------------
574 TEST(HttpCache
, CreateThenDestroy
) {
577 scoped_ptr
<net::HttpTransaction
> trans
;
578 EXPECT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
579 ASSERT_TRUE(trans
.get());
582 TEST(HttpCache
, GetBackend
) {
583 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(0));
585 disk_cache::Backend
* backend
;
586 net::TestCompletionCallback cb
;
587 // This will lazily initialize the backend.
588 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
589 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
592 TEST(HttpCache
, SimpleGET
) {
594 net::CapturingBoundNetLog log
;
595 net::LoadTimingInfo load_timing_info
;
597 // Write to the cache.
598 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
599 log
.bound(), &load_timing_info
);
601 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
602 EXPECT_EQ(0, cache
.disk_cache()->open_count());
603 EXPECT_EQ(1, cache
.disk_cache()->create_count());
604 TestLoadTimingNetworkRequest(load_timing_info
);
607 TEST(HttpCache
, SimpleGETNoDiskCache
) {
610 cache
.disk_cache()->set_fail_requests();
612 net::CapturingBoundNetLog log
;
613 net::LoadTimingInfo load_timing_info
;
615 // Read from the network, and don't use the cache.
616 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
617 log
.bound(), &load_timing_info
);
619 // Check that the NetLog was filled as expected.
620 // (We attempted to both Open and Create entries, but both failed).
621 net::CapturingNetLog::CapturedEntryList entries
;
622 log
.GetEntries(&entries
);
623 FilterLogEntries(&entries
);
625 EXPECT_EQ(6u, entries
.size());
626 EXPECT_TRUE(net::LogContainsBeginEvent(
627 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
628 EXPECT_TRUE(net::LogContainsEndEvent(
629 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
630 EXPECT_TRUE(net::LogContainsBeginEvent(
631 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
632 EXPECT_TRUE(net::LogContainsEndEvent(
633 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
634 EXPECT_TRUE(net::LogContainsBeginEvent(
635 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
636 EXPECT_TRUE(net::LogContainsEndEvent(
637 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
639 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
640 EXPECT_EQ(0, cache
.disk_cache()->open_count());
641 EXPECT_EQ(0, cache
.disk_cache()->create_count());
642 TestLoadTimingNetworkRequest(load_timing_info
);
645 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
646 // This will initialize a cache object with NULL backend.
647 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
648 factory
->set_fail(true);
649 factory
->FinishCreation(); // We'll complete synchronously.
650 MockHttpCache
cache(factory
);
652 // Read from the network, and don't use the cache.
653 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
655 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
656 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
659 // Tests that IOBuffers are not referenced after IO completes.
660 TEST(HttpCache
, ReleaseBuffer
) {
663 // Write to the cache.
664 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
666 MockHttpRequest
request(kSimpleGET_Transaction
);
667 scoped_ptr
<net::HttpTransaction
> trans
;
668 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
670 const int kBufferSize
= 10;
671 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(kBufferSize
));
672 net::ReleaseBufferCompletionCallback
cb(buffer
.get());
674 int rv
= trans
->Start(&request
, cb
.callback(), net::BoundNetLog());
675 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
677 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
678 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
681 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
684 cache
.disk_cache()->set_soft_failures(true);
686 // Read from the network, and fail to write to the cache.
687 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
689 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
690 EXPECT_EQ(0, cache
.disk_cache()->open_count());
691 EXPECT_EQ(1, cache
.disk_cache()->create_count());
693 // This one should see an empty cache again.
694 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
696 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
697 EXPECT_EQ(0, cache
.disk_cache()->open_count());
698 EXPECT_EQ(2, cache
.disk_cache()->create_count());
701 // Tests that disk failures after the transaction has started don't cause the
703 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
706 MockHttpRequest
request(kSimpleGET_Transaction
);
708 scoped_ptr
<Context
> c(new Context());
709 int rv
= cache
.CreateTransaction(&c
->trans
);
710 ASSERT_EQ(net::OK
, rv
);
712 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
713 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
714 rv
= c
->callback
.WaitForResult();
716 // Start failing request now.
717 cache
.disk_cache()->set_soft_failures(true);
719 // We have to open the entry again to propagate the failure flag.
720 disk_cache::Entry
* en
;
721 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
724 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
727 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
728 EXPECT_EQ(1, cache
.disk_cache()->open_count());
729 EXPECT_EQ(1, cache
.disk_cache()->create_count());
731 // This one should see an empty cache again.
732 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
734 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
735 EXPECT_EQ(1, cache
.disk_cache()->open_count());
736 EXPECT_EQ(2, cache
.disk_cache()->create_count());
739 // Tests that we handle failures to read from the cache.
740 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
743 // Read from the network, and write to the cache.
744 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
746 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
747 EXPECT_EQ(0, cache
.disk_cache()->open_count());
748 EXPECT_EQ(1, cache
.disk_cache()->create_count());
750 cache
.disk_cache()->set_soft_failures(true);
752 // Now fail to read from the cache.
753 scoped_ptr
<Context
> c(new Context());
754 int rv
= cache
.CreateTransaction(&c
->trans
);
755 ASSERT_EQ(net::OK
, rv
);
757 MockHttpRequest
request(kSimpleGET_Transaction
);
758 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
759 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
761 // Now verify that the entry was removed from the cache.
762 cache
.disk_cache()->set_soft_failures(false);
764 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
765 EXPECT_EQ(1, cache
.disk_cache()->open_count());
766 EXPECT_EQ(2, cache
.disk_cache()->create_count());
768 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
770 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
771 EXPECT_EQ(1, cache
.disk_cache()->open_count());
772 EXPECT_EQ(3, cache
.disk_cache()->create_count());
775 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
778 net::CapturingBoundNetLog log
;
779 net::LoadTimingInfo load_timing_info
;
781 // Write to the cache.
782 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
783 log
.bound(), &load_timing_info
);
785 // Check that the NetLog was filled as expected.
786 net::CapturingNetLog::CapturedEntryList entries
;
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_CREATE_ENTRY
));
801 EXPECT_TRUE(net::LogContainsEndEvent(
802 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
803 EXPECT_TRUE(net::LogContainsBeginEvent(
804 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
805 EXPECT_TRUE(net::LogContainsEndEvent(
806 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
808 TestLoadTimingNetworkRequest(load_timing_info
);
810 // Force this transaction to read from the cache.
811 MockTransaction
transaction(kSimpleGET_Transaction
);
812 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
816 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
819 // Check that the NetLog was filled as expected.
820 log
.GetEntries(&entries
);
821 FilterLogEntries(&entries
);
823 EXPECT_EQ(8u, entries
.size());
824 EXPECT_TRUE(net::LogContainsBeginEvent(
825 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
826 EXPECT_TRUE(net::LogContainsEndEvent(
827 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
828 EXPECT_TRUE(net::LogContainsBeginEvent(
829 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
830 EXPECT_TRUE(net::LogContainsEndEvent(
831 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
832 EXPECT_TRUE(net::LogContainsBeginEvent(
833 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
834 EXPECT_TRUE(net::LogContainsEndEvent(
835 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
836 EXPECT_TRUE(net::LogContainsBeginEvent(
837 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
838 EXPECT_TRUE(net::LogContainsEndEvent(
839 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
841 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
842 EXPECT_EQ(1, cache
.disk_cache()->open_count());
843 EXPECT_EQ(1, cache
.disk_cache()->create_count());
844 TestLoadTimingCachedResponse(load_timing_info
);
847 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
850 // force this transaction to read from the cache
851 MockTransaction
transaction(kSimpleGET_Transaction
);
852 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
854 MockHttpRequest
request(transaction
);
855 net::TestCompletionCallback callback
;
857 scoped_ptr
<net::HttpTransaction
> trans
;
858 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
860 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
861 if (rv
== net::ERR_IO_PENDING
)
862 rv
= callback
.WaitForResult();
863 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
867 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
868 EXPECT_EQ(0, cache
.disk_cache()->open_count());
869 EXPECT_EQ(0, cache
.disk_cache()->create_count());
872 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
875 // write to the cache
876 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
878 // force this transaction to read from the cache if valid
879 MockTransaction
transaction(kSimpleGET_Transaction
);
880 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
882 RunTransactionTest(cache
.http_cache(), transaction
);
884 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
885 EXPECT_EQ(1, cache
.disk_cache()->open_count());
886 EXPECT_EQ(1, cache
.disk_cache()->create_count());
889 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
892 // force this transaction to read from the cache if valid
893 MockTransaction
transaction(kSimpleGET_Transaction
);
894 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
896 RunTransactionTest(cache
.http_cache(), transaction
);
898 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
899 EXPECT_EQ(0, cache
.disk_cache()->open_count());
900 EXPECT_EQ(1, cache
.disk_cache()->create_count());
903 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
904 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
907 // Write to the cache.
908 MockTransaction
transaction(kSimpleGET_Transaction
);
909 transaction
.request_headers
= "Foo: bar\r\n";
910 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
912 AddMockTransaction(&transaction
);
913 RunTransactionTest(cache
.http_cache(), transaction
);
915 // Read from the cache.
916 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
917 RunTransactionTest(cache
.http_cache(), transaction
);
919 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
920 EXPECT_EQ(1, cache
.disk_cache()->open_count());
921 EXPECT_EQ(1, cache
.disk_cache()->create_count());
922 RemoveMockTransaction(&transaction
);
925 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
926 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
929 // Write to the cache.
930 MockTransaction
transaction(kSimpleGET_Transaction
);
931 transaction
.request_headers
= "Foo: bar\r\n";
932 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
934 AddMockTransaction(&transaction
);
935 RunTransactionTest(cache
.http_cache(), transaction
);
937 // Attempt to read from the cache... this is a vary mismatch that must reach
938 // the network again.
939 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
940 transaction
.request_headers
= "Foo: none\r\n";
941 net::CapturingBoundNetLog log
;
942 net::LoadTimingInfo load_timing_info
;
943 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
946 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
947 EXPECT_EQ(1, cache
.disk_cache()->open_count());
948 EXPECT_EQ(1, cache
.disk_cache()->create_count());
949 TestLoadTimingNetworkRequest(load_timing_info
);
950 RemoveMockTransaction(&transaction
);
953 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
955 TEST(HttpCache
, SimpleGET_CacheOverride_Network
) {
959 MockTransaction
transaction(kSimpleGET_Transaction
);
960 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
961 transaction
.response_headers
= "Cache-Control: no-cache\n";
963 AddMockTransaction(&transaction
);
964 RunTransactionTest(cache
.http_cache(), transaction
);
965 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
966 EXPECT_EQ(1, cache
.disk_cache()->create_count());
967 RemoveMockTransaction(&transaction
);
969 // Re-run transaction; make sure the result came from the network,
971 transaction
.data
= "Changed data.";
972 AddMockTransaction(&transaction
);
973 net::HttpResponseInfo response_info
;
974 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
977 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
978 EXPECT_FALSE(response_info
.server_data_unavailable
);
979 EXPECT_TRUE(response_info
.network_accessed
);
981 RemoveMockTransaction(&transaction
);
984 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
986 TEST(HttpCache
, SimpleGET_CacheOverride_Offline
) {
990 MockTransaction
transaction(kSimpleGET_Transaction
);
991 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
992 transaction
.response_headers
= "Cache-Control: no-cache\n";
994 AddMockTransaction(&transaction
);
995 RunTransactionTest(cache
.http_cache(), transaction
);
996 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
997 EXPECT_EQ(1, cache
.disk_cache()->create_count());
998 RemoveMockTransaction(&transaction
);
1000 // Network failure with offline error; should return cache entry above +
1001 // flag signalling stale data.
1002 transaction
.return_code
= net::ERR_NAME_NOT_RESOLVED
;
1003 AddMockTransaction(&transaction
);
1005 MockHttpRequest
request(transaction
);
1006 net::TestCompletionCallback callback
;
1007 scoped_ptr
<net::HttpTransaction
> trans
;
1008 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1009 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1010 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
1012 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1013 ASSERT_TRUE(response_info
);
1014 EXPECT_TRUE(response_info
->server_data_unavailable
);
1015 EXPECT_TRUE(response_info
->was_cached
);
1016 EXPECT_FALSE(response_info
->network_accessed
);
1017 ReadAndVerifyTransaction(trans
.get(), transaction
);
1018 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1020 RemoveMockTransaction(&transaction
);
1023 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1024 // non-offline failure.
1025 TEST(HttpCache
, SimpleGET_CacheOverride_NonOffline
) {
1026 MockHttpCache cache
;
1029 MockTransaction
transaction(kSimpleGET_Transaction
);
1030 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
1031 transaction
.response_headers
= "Cache-Control: no-cache\n";
1033 AddMockTransaction(&transaction
);
1034 RunTransactionTest(cache
.http_cache(), transaction
);
1035 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1036 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1037 RemoveMockTransaction(&transaction
);
1039 // Network failure with non-offline error; should fail with that error.
1040 transaction
.return_code
= net::ERR_PROXY_CONNECTION_FAILED
;
1041 AddMockTransaction(&transaction
);
1043 net::HttpResponseInfo response_info2
;
1044 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1047 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1048 EXPECT_FALSE(response_info2
.server_data_unavailable
);
1050 RemoveMockTransaction(&transaction
);
1053 // Tests that was_cached was set properly on a failure, even if the cached
1054 // response wasn't returned.
1055 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
1056 MockHttpCache cache
;
1059 MockTransaction
transaction(kSimpleGET_Transaction
);
1060 transaction
.response_headers
= "Cache-Control: no-cache\n";
1062 AddMockTransaction(&transaction
);
1063 RunTransactionTest(cache
.http_cache(), transaction
);
1064 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1065 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1066 RemoveMockTransaction(&transaction
);
1068 // Network failure with error; should fail but have was_cached set.
1069 transaction
.return_code
= net::ERR_FAILED
;
1070 AddMockTransaction(&transaction
);
1072 MockHttpRequest
request(transaction
);
1073 net::TestCompletionCallback callback
;
1074 scoped_ptr
<net::HttpTransaction
> trans
;
1075 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
1076 EXPECT_EQ(net::OK
, rv
);
1077 ASSERT_TRUE(trans
.get());
1078 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1079 EXPECT_EQ(net::ERR_FAILED
, callback
.GetResult(rv
));
1081 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1082 ASSERT_TRUE(response_info
);
1083 EXPECT_TRUE(response_info
->was_cached
);
1084 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1086 RemoveMockTransaction(&transaction
);
1089 // Confirm if we have an empty cache, a read is marked as network verified.
1090 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1091 MockHttpCache cache
;
1093 // write to the cache
1094 net::HttpResponseInfo response_info
;
1095 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1098 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1099 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1100 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1101 EXPECT_TRUE(response_info
.network_accessed
);
1104 // Confirm if we have a fresh entry in cache, it isn't marked as
1105 // network verified.
1106 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1107 MockHttpCache cache
;
1110 MockTransaction
transaction(kSimpleGET_Transaction
);
1112 RunTransactionTest(cache
.http_cache(), transaction
);
1113 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1114 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1116 // Re-run transaction; make sure we don't mark the network as accessed.
1117 net::HttpResponseInfo response_info
;
1118 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1121 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1122 EXPECT_FALSE(response_info
.server_data_unavailable
);
1123 EXPECT_FALSE(response_info
.network_accessed
);
1126 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1127 MockHttpCache cache
;
1129 // Write to the cache.
1130 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1132 // Force this transaction to write to the cache again.
1133 MockTransaction
transaction(kSimpleGET_Transaction
);
1134 transaction
.load_flags
|= net::LOAD_BYPASS_CACHE
;
1136 net::CapturingBoundNetLog log
;
1137 net::LoadTimingInfo load_timing_info
;
1139 // Write to the cache.
1140 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1143 // Check that the NetLog was filled as expected.
1144 net::CapturingNetLog::CapturedEntryList entries
;
1145 log
.GetEntries(&entries
);
1146 FilterLogEntries(&entries
);
1148 EXPECT_EQ(8u, entries
.size());
1149 EXPECT_TRUE(net::LogContainsBeginEvent(
1150 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1151 EXPECT_TRUE(net::LogContainsEndEvent(
1152 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1153 EXPECT_TRUE(net::LogContainsBeginEvent(
1154 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1155 EXPECT_TRUE(net::LogContainsEndEvent(
1156 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1157 EXPECT_TRUE(net::LogContainsBeginEvent(
1158 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1159 EXPECT_TRUE(net::LogContainsEndEvent(
1160 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1161 EXPECT_TRUE(net::LogContainsBeginEvent(
1162 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1163 EXPECT_TRUE(net::LogContainsEndEvent(
1164 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1166 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1167 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1168 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1169 TestLoadTimingNetworkRequest(load_timing_info
);
1172 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1173 MockHttpCache cache
;
1175 // write to the cache
1176 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1178 // force this transaction to write to the cache again
1179 MockTransaction
transaction(kSimpleGET_Transaction
);
1180 transaction
.request_headers
= "pragma: no-cache\r\n";
1182 RunTransactionTest(cache
.http_cache(), transaction
);
1184 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1185 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1186 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1189 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1190 MockHttpCache cache
;
1192 // write to the cache
1193 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1195 // force this transaction to write to the cache again
1196 MockTransaction
transaction(kSimpleGET_Transaction
);
1197 transaction
.request_headers
= "cache-control: no-cache\r\n";
1199 RunTransactionTest(cache
.http_cache(), transaction
);
1201 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1202 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1203 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1206 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1207 MockHttpCache cache
;
1209 // Write to the cache.
1210 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1212 // Read from the cache.
1213 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1215 // Force this transaction to validate the cache.
1216 MockTransaction
transaction(kSimpleGET_Transaction
);
1217 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
1219 net::HttpResponseInfo response_info
;
1220 net::CapturingBoundNetLog log
;
1221 net::LoadTimingInfo load_timing_info
;
1222 RunTransactionTestWithResponseInfoAndGetTiming(
1223 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1226 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1227 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1228 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1229 EXPECT_TRUE(response_info
.network_accessed
);
1230 TestLoadTimingNetworkRequest(load_timing_info
);
1233 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1234 MockHttpCache cache
;
1236 // write to the cache
1237 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1239 // read from the cache
1240 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1242 // force this transaction to validate the cache
1243 MockTransaction
transaction(kSimpleGET_Transaction
);
1244 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1246 RunTransactionTest(cache
.http_cache(), transaction
);
1248 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1249 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1250 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1253 static void PreserveRequestHeaders_Handler(
1254 const net::HttpRequestInfo
* request
,
1255 std::string
* response_status
,
1256 std::string
* response_headers
,
1257 std::string
* response_data
) {
1258 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1261 // Tests that we don't remove extra headers for simple requests.
1262 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1263 MockHttpCache cache
;
1265 MockTransaction
transaction(kSimpleGET_Transaction
);
1266 transaction
.handler
= PreserveRequestHeaders_Handler
;
1267 transaction
.request_headers
= EXTRA_HEADER
;
1268 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1269 AddMockTransaction(&transaction
);
1271 // Write, then revalidate the entry.
1272 RunTransactionTest(cache
.http_cache(), transaction
);
1273 RunTransactionTest(cache
.http_cache(), transaction
);
1275 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1276 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1277 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1278 RemoveMockTransaction(&transaction
);
1281 // Tests that we don't remove extra headers for conditionalized requests.
1282 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1283 MockHttpCache cache
;
1285 // Write to the cache.
1286 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1288 MockTransaction
transaction(kETagGET_Transaction
);
1289 transaction
.handler
= PreserveRequestHeaders_Handler
;
1290 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1292 AddMockTransaction(&transaction
);
1294 RunTransactionTest(cache
.http_cache(), transaction
);
1296 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1297 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1298 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1299 RemoveMockTransaction(&transaction
);
1302 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1303 MockHttpCache cache
;
1305 MockHttpRequest
request(kSimpleGET_Transaction
);
1307 std::vector
<Context
*> context_list
;
1308 const int kNumTransactions
= 5;
1310 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1311 context_list
.push_back(new Context());
1312 Context
* c
= context_list
[i
];
1314 c
->result
= cache
.CreateTransaction(&c
->trans
);
1315 ASSERT_EQ(net::OK
, c
->result
);
1316 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1318 c
->result
= c
->trans
->Start(
1319 &request
, c
->callback
.callback(), net::BoundNetLog());
1322 // All requests are waiting for the active entry.
1323 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1324 Context
* c
= context_list
[i
];
1325 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1328 // Allow all requests to move from the Create queue to the active entry.
1329 base::MessageLoop::current()->RunUntilIdle();
1331 // The first request should be a writer at this point, and the subsequent
1332 // requests should be pending.
1334 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1335 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1336 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1338 // All requests depend on the writer, and the writer is between Start and
1340 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1341 Context
* c
= context_list
[i
];
1342 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1345 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1346 Context
* c
= context_list
[i
];
1347 if (c
->result
== net::ERR_IO_PENDING
)
1348 c
->result
= c
->callback
.WaitForResult();
1349 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1352 // We should not have had to re-open the disk entry
1354 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1355 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1356 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1358 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1359 Context
* c
= context_list
[i
];
1364 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1365 // If cancelling a request is racing with another request for the same resource
1366 // finishing, we have to make sure that we remove both transactions from the
1368 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1369 MockHttpCache cache
;
1371 MockHttpRequest
request(kSimpleGET_Transaction
);
1372 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1373 reader_request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
1375 std::vector
<Context
*> context_list
;
1376 const int kNumTransactions
= 5;
1378 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1379 context_list
.push_back(new Context());
1380 Context
* c
= context_list
[i
];
1382 c
->result
= cache
.CreateTransaction(&c
->trans
);
1383 ASSERT_EQ(net::OK
, c
->result
);
1385 MockHttpRequest
* this_request
= &request
;
1386 if (i
== 1 || i
== 2)
1387 this_request
= &reader_request
;
1389 c
->result
= c
->trans
->Start(
1390 this_request
, c
->callback
.callback(), net::BoundNetLog());
1393 // Allow all requests to move from the Create queue to the active entry.
1394 base::MessageLoop::current()->RunUntilIdle();
1396 // The first request should be a writer at this point, and the subsequent
1397 // requests should be pending.
1399 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1400 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1401 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1403 Context
* c
= context_list
[0];
1404 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1405 c
->result
= c
->callback
.WaitForResult();
1406 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1408 // Now we have 2 active readers and two queued transactions.
1410 EXPECT_EQ(net::LOAD_STATE_IDLE
,
1411 context_list
[2]->trans
->GetLoadState());
1412 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
,
1413 context_list
[3]->trans
->GetLoadState());
1415 c
= context_list
[1];
1416 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1417 c
->result
= c
->callback
.WaitForResult();
1418 if (c
->result
== net::OK
)
1419 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1421 // At this point we have one reader, two pending transactions and a task on
1422 // the queue to move to the next transaction. Now we cancel the request that
1423 // is the current reader, and expect the queued task to be able to start the
1426 c
= context_list
[2];
1429 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1430 Context
* c
= context_list
[i
];
1431 if (c
->result
== net::ERR_IO_PENDING
)
1432 c
->result
= c
->callback
.WaitForResult();
1433 if (c
->result
== net::OK
)
1434 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1437 // We should not have had to re-open the disk entry.
1439 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1440 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1441 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1443 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1444 Context
* c
= context_list
[i
];
1449 // Tests that we can doom an entry with pending transactions and delete one of
1450 // the pending transactions before the first one completes.
1451 // See http://code.google.com/p/chromium/issues/detail?id=25588
1452 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1453 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1454 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1456 MockHttpRequest
request(kSimpleGET_Transaction
);
1457 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1458 writer_request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1460 ScopedVector
<Context
> context_list
;
1461 const int kNumTransactions
= 4;
1463 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1464 context_list
.push_back(new Context());
1465 Context
* c
= context_list
[i
];
1467 c
->result
= cache
.CreateTransaction(&c
->trans
);
1468 ASSERT_EQ(net::OK
, c
->result
);
1470 MockHttpRequest
* this_request
= &request
;
1472 this_request
= &writer_request
;
1474 c
->result
= c
->trans
->Start(
1475 this_request
, c
->callback
.callback(), net::BoundNetLog());
1478 // The first request should be a writer at this point, and the two subsequent
1479 // requests should be pending. The last request doomed the first entry.
1481 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1483 // Cancel the first queued transaction.
1484 delete context_list
[1];
1485 context_list
.get()[1] = NULL
;
1487 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1490 Context
* c
= context_list
[i
];
1491 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1492 c
->result
= c
->callback
.WaitForResult();
1493 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1497 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1498 // We may attempt to delete an entry synchronously with the act of adding a new
1499 // transaction to said entry.
1500 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1501 MockHttpCache cache
;
1503 // The headers will be served right from the call to Start() the request.
1504 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1505 FastTransactionServer request_handler
;
1506 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1508 std::vector
<Context
*> context_list
;
1509 const int kNumTransactions
= 3;
1511 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1512 context_list
.push_back(new Context());
1513 Context
* c
= context_list
[i
];
1515 c
->result
= cache
.CreateTransaction(&c
->trans
);
1516 ASSERT_EQ(net::OK
, c
->result
);
1518 c
->result
= c
->trans
->Start(
1519 &request
, c
->callback
.callback(), net::BoundNetLog());
1522 // Allow all requests to move from the Create queue to the active entry.
1523 base::MessageLoop::current()->RunUntilIdle();
1525 // The first request should be a writer at this point, and the subsequent
1526 // requests should be pending.
1528 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1529 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1530 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1532 // Now, make sure that the second request asks for the entry not to be stored.
1533 request_handler
.set_no_store(true);
1535 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1536 Context
* c
= context_list
[i
];
1537 if (c
->result
== net::ERR_IO_PENDING
)
1538 c
->result
= c
->callback
.WaitForResult();
1539 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1543 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1544 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1545 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1547 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1550 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1551 MockHttpCache cache
;
1553 MockHttpRequest
request(kSimpleGET_Transaction
);
1555 std::vector
<Context
*> context_list
;
1556 const int kNumTransactions
= 2;
1558 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1559 context_list
.push_back(new Context());
1560 Context
* c
= context_list
[i
];
1562 c
->result
= cache
.CreateTransaction(&c
->trans
);
1563 ASSERT_EQ(net::OK
, c
->result
);
1565 c
->result
= c
->trans
->Start(
1566 &request
, c
->callback
.callback(), net::BoundNetLog());
1569 // Allow all requests to move from the Create queue to the active entry.
1570 base::MessageLoop::current()->RunUntilIdle();
1572 // The first request should be a writer at this point, and the subsequent
1573 // requests should be pending.
1575 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1576 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1577 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1579 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1580 Context
* c
= context_list
[i
];
1581 if (c
->result
== net::ERR_IO_PENDING
)
1582 c
->result
= c
->callback
.WaitForResult();
1583 // Destroy only the first transaction.
1586 context_list
[i
] = NULL
;
1590 // Complete the rest of the transactions.
1591 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1592 Context
* c
= context_list
[i
];
1593 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1596 // We should have had to re-open the disk entry.
1598 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1599 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1600 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1602 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1603 Context
* c
= context_list
[i
];
1608 // Tests that we can cancel requests that are queued waiting to open the disk
1610 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1611 MockHttpCache cache
;
1613 MockHttpRequest
request(kSimpleGET_Transaction
);
1615 std::vector
<Context
*> context_list
;
1616 const int kNumTransactions
= 5;
1618 for (int i
= 0; i
< kNumTransactions
; i
++) {
1619 context_list
.push_back(new Context());
1620 Context
* c
= context_list
[i
];
1622 c
->result
= cache
.CreateTransaction(&c
->trans
);
1623 ASSERT_EQ(net::OK
, c
->result
);
1625 c
->result
= c
->trans
->Start(
1626 &request
, c
->callback
.callback(), net::BoundNetLog());
1629 // The first request should be creating the disk cache entry and the others
1630 // should be pending.
1632 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1633 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1634 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1636 // Cancel a request from the pending queue.
1637 delete context_list
[3];
1638 context_list
[3] = NULL
;
1640 // Cancel the request that is creating the entry. This will force the pending
1641 // operations to restart.
1642 delete context_list
[0];
1643 context_list
[0] = NULL
;
1645 // Complete the rest of the transactions.
1646 for (int i
= 1; i
< kNumTransactions
; i
++) {
1647 Context
* c
= context_list
[i
];
1649 c
->result
= c
->callback
.GetResult(c
->result
);
1650 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1654 // We should have had to re-create the disk entry.
1656 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1657 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1658 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1660 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1661 delete context_list
[i
];
1665 // Tests that we can cancel a single request to open a disk cache entry.
1666 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1667 MockHttpCache cache
;
1669 MockHttpRequest
request(kSimpleGET_Transaction
);
1671 Context
* c
= new Context();
1673 c
->result
= cache
.CreateTransaction(&c
->trans
);
1674 ASSERT_EQ(net::OK
, c
->result
);
1676 c
->result
= c
->trans
->Start(
1677 &request
, c
->callback
.callback(), net::BoundNetLog());
1678 EXPECT_EQ(net::ERR_IO_PENDING
, c
->result
);
1680 // Release the reference that the mock disk cache keeps for this entry, so
1681 // that we test that the http cache handles the cancellation correctly.
1682 cache
.disk_cache()->ReleaseAll();
1685 base::MessageLoop::current()->RunUntilIdle();
1686 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1689 // Tests that we delete/create entries even if multiple requests are queued.
1690 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1691 MockHttpCache cache
;
1693 MockHttpRequest
request(kSimpleGET_Transaction
);
1694 request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1696 std::vector
<Context
*> context_list
;
1697 const int kNumTransactions
= 5;
1699 for (int i
= 0; i
< kNumTransactions
; i
++) {
1700 context_list
.push_back(new Context());
1701 Context
* c
= context_list
[i
];
1703 c
->result
= cache
.CreateTransaction(&c
->trans
);
1704 ASSERT_EQ(net::OK
, c
->result
);
1706 c
->result
= c
->trans
->Start(
1707 &request
, c
->callback
.callback(), net::BoundNetLog());
1710 // The first request should be deleting the disk cache entry and the others
1711 // should be pending.
1713 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1714 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1715 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1717 // Complete the transactions.
1718 for (int i
= 0; i
< kNumTransactions
; i
++) {
1719 Context
* c
= context_list
[i
];
1720 c
->result
= c
->callback
.GetResult(c
->result
);
1721 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1724 // We should have had to re-create the disk entry multiple times.
1726 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1727 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1728 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1730 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1731 delete context_list
[i
];
1735 // Tests that a (simulated) timeout allows transactions waiting on the cache
1736 // lock to continue.
1737 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1738 MockHttpCache cache
;
1739 cache
.BypassCacheLock();
1741 MockHttpRequest
request(kSimpleGET_Transaction
);
1743 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c1
.trans
));
1744 ASSERT_EQ(net::ERR_IO_PENDING
,
1745 c1
.trans
->Start(&request
, c1
.callback
.callback(),
1746 net::BoundNetLog()));
1747 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c2
.trans
));
1748 ASSERT_EQ(net::ERR_IO_PENDING
,
1749 c2
.trans
->Start(&request
, c2
.callback
.callback(),
1750 net::BoundNetLog()));
1752 // The second request is queued after the first one.
1754 c2
.callback
.WaitForResult();
1755 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1757 // Complete the first transaction.
1758 c1
.callback
.WaitForResult();
1759 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1762 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1763 MockHttpCache cache
;
1765 // write to the cache
1766 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1768 MockHttpRequest
request(kSimpleGET_Transaction
);
1769 net::TestCompletionCallback callback
;
1771 scoped_ptr
<net::HttpTransaction
> trans
;
1772 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1773 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1774 if (rv
== net::ERR_IO_PENDING
)
1775 rv
= callback
.WaitForResult();
1776 ASSERT_EQ(net::OK
, rv
);
1778 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
1779 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1780 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1782 // Test that destroying the transaction while it is reading from the cache
1786 // Make sure we pump any pending events, which should include a call to
1787 // HttpCache::Transaction::OnCacheReadCompleted.
1788 base::MessageLoop::current()->RunUntilIdle();
1791 // Tests that we can delete the HttpCache and deal with queued transactions
1792 // ("waiting for the backend" as opposed to Active or Doomed entries).
1793 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1794 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1795 new MockBackendNoCbFactory()));
1797 MockHttpRequest
request(kSimpleGET_Transaction
);
1799 std::vector
<Context
*> context_list
;
1800 const int kNumTransactions
= 5;
1802 for (int i
= 0; i
< kNumTransactions
; i
++) {
1803 context_list
.push_back(new Context());
1804 Context
* c
= context_list
[i
];
1806 c
->result
= cache
->CreateTransaction(&c
->trans
);
1807 ASSERT_EQ(net::OK
, c
->result
);
1809 c
->result
= c
->trans
->Start(
1810 &request
, c
->callback
.callback(), net::BoundNetLog());
1813 // The first request should be creating the disk cache entry and the others
1814 // should be pending.
1816 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1817 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1818 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1822 // There is not much to do with the transactions at this point... they are
1823 // waiting for a callback that will not fire.
1824 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1825 delete context_list
[i
];
1829 // Tests that we queue requests when initializing the backend.
1830 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1831 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1832 MockHttpCache
cache(factory
);
1834 MockHttpRequest
request0(kSimpleGET_Transaction
);
1835 MockHttpRequest
request1(kTypicalGET_Transaction
);
1836 MockHttpRequest
request2(kETagGET_Transaction
);
1838 std::vector
<Context
*> context_list
;
1839 const int kNumTransactions
= 3;
1841 for (int i
= 0; i
< kNumTransactions
; i
++) {
1842 context_list
.push_back(new Context());
1843 Context
* c
= context_list
[i
];
1845 c
->result
= cache
.CreateTransaction(&c
->trans
);
1846 ASSERT_EQ(net::OK
, c
->result
);
1849 context_list
[0]->result
= context_list
[0]->trans
->Start(
1850 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1851 context_list
[1]->result
= context_list
[1]->trans
->Start(
1852 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1853 context_list
[2]->result
= context_list
[2]->trans
->Start(
1854 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1856 // Just to make sure that everything is still pending.
1857 base::MessageLoop::current()->RunUntilIdle();
1859 // The first request should be creating the disk cache.
1860 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1862 factory
->FinishCreation();
1864 base::MessageLoop::current()->RunUntilIdle();
1865 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1866 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1868 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1869 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1870 delete context_list
[i
];
1874 // Tests that we can cancel requests that are queued waiting for the backend
1875 // to be initialized.
1876 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1877 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1878 MockHttpCache
cache(factory
);
1880 MockHttpRequest
request0(kSimpleGET_Transaction
);
1881 MockHttpRequest
request1(kTypicalGET_Transaction
);
1882 MockHttpRequest
request2(kETagGET_Transaction
);
1884 std::vector
<Context
*> context_list
;
1885 const int kNumTransactions
= 3;
1887 for (int i
= 0; i
< kNumTransactions
; i
++) {
1888 context_list
.push_back(new Context());
1889 Context
* c
= context_list
[i
];
1891 c
->result
= cache
.CreateTransaction(&c
->trans
);
1892 ASSERT_EQ(net::OK
, c
->result
);
1895 context_list
[0]->result
= context_list
[0]->trans
->Start(
1896 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1897 context_list
[1]->result
= context_list
[1]->trans
->Start(
1898 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1899 context_list
[2]->result
= context_list
[2]->trans
->Start(
1900 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1902 // Just to make sure that everything is still pending.
1903 base::MessageLoop::current()->RunUntilIdle();
1905 // The first request should be creating the disk cache.
1906 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1908 // Cancel a request from the pending queue.
1909 delete context_list
[1];
1910 context_list
[1] = NULL
;
1912 // Cancel the request that is creating the entry.
1913 delete context_list
[0];
1914 context_list
[0] = NULL
;
1916 // Complete the last transaction.
1917 factory
->FinishCreation();
1919 context_list
[2]->result
=
1920 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1921 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1923 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1924 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1926 delete context_list
[2];
1929 // Tests that we can delete the cache while creating the backend.
1930 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1931 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1932 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1934 MockHttpRequest
request(kSimpleGET_Transaction
);
1936 scoped_ptr
<Context
> c(new Context());
1937 c
->result
= cache
->CreateTransaction(&c
->trans
);
1938 ASSERT_EQ(net::OK
, c
->result
);
1940 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1942 // Just to make sure that everything is still pending.
1943 base::MessageLoop::current()->RunUntilIdle();
1945 // The request should be creating the disk cache.
1946 EXPECT_FALSE(c
->callback
.have_result());
1948 // We cannot call FinishCreation because the factory itself will go away with
1949 // the cache, so grab the callback and attempt to use it.
1950 net::CompletionCallback callback
= factory
->callback();
1951 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1954 base::MessageLoop::current()->RunUntilIdle();
1957 callback
.Run(net::ERR_ABORTED
);
1960 // Tests that we can delete the cache while creating the backend, from within
1961 // one of the callbacks.
1962 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1963 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1964 MockHttpCache
* cache
= new MockHttpCache(factory
);
1966 DeleteCacheCompletionCallback
cb(cache
);
1967 disk_cache::Backend
* backend
;
1968 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1969 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1971 // Now let's queue a regular transaction
1972 MockHttpRequest
request(kSimpleGET_Transaction
);
1974 scoped_ptr
<Context
> c(new Context());
1975 c
->result
= cache
->CreateTransaction(&c
->trans
);
1976 ASSERT_EQ(net::OK
, c
->result
);
1978 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1980 // And another direct backend request.
1981 net::TestCompletionCallback cb2
;
1982 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1983 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1985 // Just to make sure that everything is still pending.
1986 base::MessageLoop::current()->RunUntilIdle();
1988 // The request should be queued.
1989 EXPECT_FALSE(c
->callback
.have_result());
1991 // Generate the callback.
1992 factory
->FinishCreation();
1993 rv
= cb
.WaitForResult();
1995 // The cache should be gone by now.
1996 base::MessageLoop::current()->RunUntilIdle();
1997 EXPECT_EQ(net::OK
, c
->callback
.GetResult(c
->result
));
1998 EXPECT_FALSE(cb2
.have_result());
2001 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
2002 MockHttpCache cache
;
2004 // write to the cache
2005 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
2007 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2008 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2009 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2011 // Get the same URL again, but this time we expect it to result
2012 // in a conditional request.
2013 net::CapturingBoundNetLog log
;
2014 net::LoadTimingInfo load_timing_info
;
2015 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
2016 log
.bound(), &load_timing_info
);
2018 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2019 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2020 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2021 TestLoadTimingNetworkRequest(load_timing_info
);
2024 static void ETagGet_ConditionalRequest_Handler(
2025 const net::HttpRequestInfo
* request
,
2026 std::string
* response_status
,
2027 std::string
* response_headers
,
2028 std::string
* response_data
) {
2030 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2031 response_status
->assign("HTTP/1.1 304 Not Modified");
2032 response_headers
->assign(kETagGET_Transaction
.response_headers
);
2033 response_data
->clear();
2036 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
2037 MockHttpCache cache
;
2039 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2041 // write to the cache
2042 RunTransactionTest(cache
.http_cache(), transaction
);
2044 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2045 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2046 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2048 // Get the same URL again, but this time we expect it to result
2049 // in a conditional request.
2050 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2051 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
2052 net::CapturingBoundNetLog log
;
2053 net::LoadTimingInfo load_timing_info
;
2054 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2057 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2058 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2059 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2060 TestLoadTimingNetworkRequest(load_timing_info
);
2063 class RevalidationServer
{
2065 RevalidationServer() {
2066 s_etag_used_
= false;
2067 s_last_modified_used_
= false;
2070 bool EtagUsed() { return s_etag_used_
; }
2071 bool LastModifiedUsed() { return s_last_modified_used_
; }
2073 static void Handler(const net::HttpRequestInfo
* request
,
2074 std::string
* response_status
,
2075 std::string
* response_headers
,
2076 std::string
* response_data
);
2079 static bool s_etag_used_
;
2080 static bool s_last_modified_used_
;
2082 bool RevalidationServer::s_etag_used_
= false;
2083 bool RevalidationServer::s_last_modified_used_
= false;
2085 void RevalidationServer::Handler(const net::HttpRequestInfo
* request
,
2086 std::string
* response_status
,
2087 std::string
* response_headers
,
2088 std::string
* response_data
) {
2089 if (request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
))
2090 s_etag_used_
= true;
2092 if (request
->extra_headers
.HasHeader(
2093 net::HttpRequestHeaders::kIfModifiedSince
)) {
2094 s_last_modified_used_
= true;
2097 if (s_etag_used_
|| s_last_modified_used_
) {
2098 response_status
->assign("HTTP/1.1 304 Not Modified");
2099 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2100 response_data
->clear();
2102 response_status
->assign(kTypicalGET_Transaction
.status
);
2103 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2104 response_data
->assign(kTypicalGET_Transaction
.data
);
2108 // Tests revalidation after a vary match.
2109 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMatch
) {
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.
2125 RevalidationServer server
;
2126 transaction
.handler
= server
.Handler
;
2127 net::CapturingBoundNetLog log
;
2128 net::LoadTimingInfo load_timing_info
;
2129 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2132 EXPECT_TRUE(server
.EtagUsed());
2133 EXPECT_TRUE(server
.LastModifiedUsed());
2134 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2135 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2136 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2137 TestLoadTimingNetworkRequest(load_timing_info
);
2138 RemoveMockTransaction(&transaction
);
2141 // Tests revalidation after a vary mismatch if etag is present.
2142 TEST(HttpCache
, SimpleGET_LoadValidateCache_VaryMismatch
) {
2143 MockHttpCache cache
;
2145 // Write to the cache.
2146 MockTransaction
transaction(kTypicalGET_Transaction
);
2147 transaction
.request_headers
= "Foo: bar\r\n";
2148 transaction
.response_headers
=
2149 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2150 "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 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_TRUE(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 // Tests lack of revalidation after a vary mismatch and no etag.
2176 TEST(HttpCache
, SimpleGET_LoadDontValidateCache_VaryMismatch
) {
2177 MockHttpCache cache
;
2179 // Write to the cache.
2180 MockTransaction
transaction(kTypicalGET_Transaction
);
2181 transaction
.request_headers
= "Foo: bar\r\n";
2182 transaction
.response_headers
=
2183 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2184 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2185 "Cache-Control: max-age=0\n"
2187 AddMockTransaction(&transaction
);
2188 RunTransactionTest(cache
.http_cache(), transaction
);
2190 // Read from the cache and don't revalidate the entry.
2191 RevalidationServer server
;
2192 transaction
.handler
= server
.Handler
;
2193 transaction
.request_headers
= "Foo: none\r\n";
2194 net::CapturingBoundNetLog log
;
2195 net::LoadTimingInfo load_timing_info
;
2196 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2199 EXPECT_FALSE(server
.EtagUsed());
2200 EXPECT_FALSE(server
.LastModifiedUsed());
2201 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2202 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2203 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2204 TestLoadTimingNetworkRequest(load_timing_info
);
2205 RemoveMockTransaction(&transaction
);
2208 static void ETagGet_UnconditionalRequest_Handler(
2209 const net::HttpRequestInfo
* request
,
2210 std::string
* response_status
,
2211 std::string
* response_headers
,
2212 std::string
* response_data
) {
2214 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2217 TEST(HttpCache
, ETagGET_Http10
) {
2218 MockHttpCache cache
;
2220 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2221 transaction
.status
= "HTTP/1.0 200 OK";
2223 // Write to the cache.
2224 RunTransactionTest(cache
.http_cache(), transaction
);
2226 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2227 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2228 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2230 // Get the same URL again, without generating a conditional request.
2231 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2232 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2233 RunTransactionTest(cache
.http_cache(), transaction
);
2235 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2236 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2237 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2240 TEST(HttpCache
, ETagGET_Http10_Range
) {
2241 MockHttpCache cache
;
2243 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2244 transaction
.status
= "HTTP/1.0 200 OK";
2246 // Write to the cache.
2247 RunTransactionTest(cache
.http_cache(), transaction
);
2249 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2250 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2251 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2253 // Get the same URL again, but use a byte range request.
2254 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2255 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2256 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2257 RunTransactionTest(cache
.http_cache(), transaction
);
2259 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2260 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2261 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2264 static void ETagGet_ConditionalRequest_NoStore_Handler(
2265 const net::HttpRequestInfo
* request
,
2266 std::string
* response_status
,
2267 std::string
* response_headers
,
2268 std::string
* response_data
) {
2270 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2271 response_status
->assign("HTTP/1.1 304 Not Modified");
2272 response_headers
->assign("Cache-Control: no-store\n");
2273 response_data
->clear();
2276 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2277 MockHttpCache cache
;
2279 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2281 // Write to the cache.
2282 RunTransactionTest(cache
.http_cache(), transaction
);
2284 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2285 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2286 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2288 // Get the same URL again, but this time we expect it to result
2289 // in a conditional request.
2290 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2291 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2292 RunTransactionTest(cache
.http_cache(), transaction
);
2294 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2295 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2296 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2298 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2300 // Write to the cache again. This should create a new entry.
2301 RunTransactionTest(cache
.http_cache(), transaction2
);
2303 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2304 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2305 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2308 // Helper that does 4 requests using HttpCache:
2310 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2311 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2312 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2314 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2316 static void ConditionalizedRequestUpdatesCacheHelper(
2317 const Response
& net_response_1
,
2318 const Response
& net_response_2
,
2319 const Response
& cached_response_2
,
2320 const char* extra_request_headers
) {
2321 MockHttpCache cache
;
2323 // The URL we will be requesting.
2324 const char* kUrl
= "http://foobar.com/main.css";
2326 // Junk network response.
2327 static const Response kUnexpectedResponse
= {
2328 "HTTP/1.1 500 Unexpected",
2329 "Server: unexpected_header",
2333 // We will control the network layer's responses for |kUrl| using
2334 // |mock_network_response|.
2335 MockTransaction mock_network_response
= { 0 };
2336 mock_network_response
.url
= kUrl
;
2337 AddMockTransaction(&mock_network_response
);
2339 // Request |kUrl| for the first time. It should hit the network and
2340 // receive |kNetResponse1|, which it saves into the HTTP cache.
2342 MockTransaction request
= { 0 };
2344 request
.method
= "GET";
2345 request
.request_headers
= "";
2347 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2348 net_response_1
.AssignTo(&request
); // Expected result.
2350 std::string response_headers
;
2351 RunTransactionTestWithResponse(
2352 cache
.http_cache(), request
, &response_headers
);
2354 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2355 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2356 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2357 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2359 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2360 // cache, so we don't hit the network.
2362 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2364 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2365 net_response_1
.AssignTo(&request
); // Expected result.
2367 RunTransactionTestWithResponse(
2368 cache
.http_cache(), request
, &response_headers
);
2370 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2371 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2372 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2373 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2375 // Request |kUrl| yet again, but this time give the request an
2376 // "If-Modified-Since" header. This will cause the request to re-hit the
2377 // network. However now the network response is going to be
2378 // different -- this simulates a change made to the CSS file.
2380 request
.request_headers
= extra_request_headers
;
2381 request
.load_flags
= net::LOAD_NORMAL
;
2383 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2384 net_response_2
.AssignTo(&request
); // Expected result.
2386 RunTransactionTestWithResponse(
2387 cache
.http_cache(), request
, &response_headers
);
2389 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2390 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2391 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2392 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2394 // Finally, request |kUrl| again. This request should be serviced from
2395 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2396 // and NOT |kNetResponse1|. The previous step should have replaced the
2397 // value in the cache with the modified response.
2399 request
.request_headers
= "";
2400 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2402 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2403 cached_response_2
.AssignTo(&request
); // Expected result.
2405 RunTransactionTestWithResponse(
2406 cache
.http_cache(), request
, &response_headers
);
2408 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2409 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2410 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2411 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2413 RemoveMockTransaction(&mock_network_response
);
2416 // Check that when an "if-modified-since" header is attached
2417 // to the request, the result still updates the cached entry.
2418 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2419 // First network response for |kUrl|.
2420 static const Response kNetResponse1
= {
2422 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2423 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2427 // Second network response for |kUrl|.
2428 static const Response kNetResponse2
= {
2430 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2431 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2435 const char* extra_headers
=
2436 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2438 ConditionalizedRequestUpdatesCacheHelper(
2439 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2442 // Check that when an "if-none-match" header is attached
2443 // to the request, the result updates the cached entry.
2444 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2445 // First network response for |kUrl|.
2446 static const Response kNetResponse1
= {
2448 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2450 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2454 // Second network response for |kUrl|.
2455 static const Response kNetResponse2
= {
2457 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2459 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2463 const char* extra_headers
= "If-None-Match: \"ETAG1\"\r\n";
2465 ConditionalizedRequestUpdatesCacheHelper(
2466 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2469 // Check that when an "if-modified-since" header is attached
2470 // to a request, the 304 (not modified result) result updates the cached
2471 // headers, and the 304 response is returned rather than the cached response.
2472 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2473 // First network response for |kUrl|.
2474 static const Response kNetResponse1
= {
2476 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2478 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2482 // Second network response for |kUrl|.
2483 static const Response kNetResponse2
= {
2484 "HTTP/1.1 304 Not Modified",
2485 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2487 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2491 static const Response kCachedResponse2
= {
2493 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2495 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2499 const char* extra_headers
=
2500 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2502 ConditionalizedRequestUpdatesCacheHelper(
2503 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2506 // Test that when doing an externally conditionalized if-modified-since
2507 // and there is no corresponding cache entry, a new cache entry is NOT
2508 // created (304 response).
2509 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2510 MockHttpCache cache
;
2512 const char* kUrl
= "http://foobar.com/main.css";
2514 static const Response kNetResponse
= {
2515 "HTTP/1.1 304 Not Modified",
2516 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2517 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2521 const char* kExtraRequestHeaders
=
2522 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2524 // We will control the network layer's responses for |kUrl| using
2525 // |mock_network_response|.
2526 MockTransaction mock_network_response
= { 0 };
2527 mock_network_response
.url
= kUrl
;
2528 AddMockTransaction(&mock_network_response
);
2530 MockTransaction request
= { 0 };
2532 request
.method
= "GET";
2533 request
.request_headers
= kExtraRequestHeaders
;
2535 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2536 kNetResponse
.AssignTo(&request
); // Expected result.
2538 std::string response_headers
;
2539 RunTransactionTestWithResponse(
2540 cache
.http_cache(), request
, &response_headers
);
2542 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2543 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2544 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2545 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2547 RemoveMockTransaction(&mock_network_response
);
2550 // Test that when doing an externally conditionalized if-modified-since
2551 // and there is no corresponding cache entry, a new cache entry is NOT
2552 // created (200 response).
2553 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2554 MockHttpCache cache
;
2556 const char* kUrl
= "http://foobar.com/main.css";
2558 static const Response kNetResponse
= {
2560 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2561 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2565 const char* kExtraRequestHeaders
=
2566 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2568 // We will control the network layer's responses for |kUrl| using
2569 // |mock_network_response|.
2570 MockTransaction mock_network_response
= { 0 };
2571 mock_network_response
.url
= kUrl
;
2572 AddMockTransaction(&mock_network_response
);
2574 MockTransaction request
= { 0 };
2576 request
.method
= "GET";
2577 request
.request_headers
= kExtraRequestHeaders
;
2579 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2580 kNetResponse
.AssignTo(&request
); // Expected result.
2582 std::string response_headers
;
2583 RunTransactionTestWithResponse(
2584 cache
.http_cache(), request
, &response_headers
);
2586 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2587 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2588 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2589 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2591 RemoveMockTransaction(&mock_network_response
);
2594 // Test that when doing an externally conditionalized if-modified-since
2595 // if the date does not match the cache entry's last-modified date,
2596 // then we do NOT use the response (304) to update the cache.
2597 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2598 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2599 static const Response kNetResponse1
= {
2601 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2603 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2607 // Second network response for |kUrl|.
2608 static const Response kNetResponse2
= {
2609 "HTTP/1.1 304 Not Modified",
2610 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2612 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2616 // This is two days in the future from the original response's last-modified
2618 const char* kExtraRequestHeaders
=
2619 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2621 ConditionalizedRequestUpdatesCacheHelper(
2622 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2625 // Test that when doing an externally conditionalized if-none-match
2626 // if the etag does not match the cache entry's etag, then we do not use the
2627 // response (304) to update the cache.
2628 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2629 static const Response kNetResponse1
= {
2631 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2633 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2637 // Second network response for |kUrl|.
2638 static const Response kNetResponse2
= {
2639 "HTTP/1.1 304 Not Modified",
2640 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2642 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2646 // Different etag from original response.
2647 const char* kExtraRequestHeaders
= "If-None-Match: \"Foo2\"\r\n";
2649 ConditionalizedRequestUpdatesCacheHelper(
2650 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2653 // Test that doing an externally conditionalized request with both if-none-match
2654 // and if-modified-since updates the cache.
2655 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2656 static const Response kNetResponse1
= {
2658 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2660 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2664 // Second network response for |kUrl|.
2665 static const Response kNetResponse2
= {
2667 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2669 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2673 const char* kExtraRequestHeaders
=
2674 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2675 "If-None-Match: \"Foo1\"\r\n";
2677 ConditionalizedRequestUpdatesCacheHelper(
2678 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2681 // Test that doing an externally conditionalized request with both if-none-match
2682 // and if-modified-since does not update the cache with only one match.
2683 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2684 static const Response kNetResponse1
= {
2686 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2688 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2692 // Second network response for |kUrl|.
2693 static const Response kNetResponse2
= {
2695 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2697 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2701 // The etag doesn't match what we have stored.
2702 const char* kExtraRequestHeaders
=
2703 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2704 "If-None-Match: \"Foo2\"\r\n";
2706 ConditionalizedRequestUpdatesCacheHelper(
2707 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2710 // Test that doing an externally conditionalized request with both if-none-match
2711 // and if-modified-since does not update the cache with only one match.
2712 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2713 static const Response kNetResponse1
= {
2715 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2717 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2721 // Second network response for |kUrl|.
2722 static const Response kNetResponse2
= {
2724 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2726 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2730 // The modification date doesn't match what we have stored.
2731 const char* kExtraRequestHeaders
=
2732 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2733 "If-None-Match: \"Foo1\"\r\n";
2735 ConditionalizedRequestUpdatesCacheHelper(
2736 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2739 TEST(HttpCache
, UrlContainingHash
) {
2740 MockHttpCache cache
;
2742 // Do a typical GET request -- should write an entry into our cache.
2743 MockTransaction
trans(kTypicalGET_Transaction
);
2744 RunTransactionTest(cache
.http_cache(), trans
);
2746 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2747 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2748 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2750 // Request the same URL, but this time with a reference section (hash).
2751 // Since the cache key strips the hash sections, this should be a cache hit.
2752 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2753 trans
.url
= url_with_hash
.c_str();
2754 trans
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2756 RunTransactionTest(cache
.http_cache(), trans
);
2758 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2759 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2760 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2763 // Tests that we skip the cache for POST requests that do not have an upload
2765 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2766 MockHttpCache cache
;
2768 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2770 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2771 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2772 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2775 // Tests POST handling with a disabled cache (no DCHECK).
2776 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2777 MockHttpCache cache
;
2778 cache
.http_cache()->set_mode(net::HttpCache::Mode::DISABLE
);
2780 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2782 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2783 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2784 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2787 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2788 MockHttpCache cache
;
2790 MockTransaction
transaction(kSimplePOST_Transaction
);
2791 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2793 MockHttpRequest
request(transaction
);
2794 net::TestCompletionCallback callback
;
2796 scoped_ptr
<net::HttpTransaction
> trans
;
2797 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
2798 ASSERT_TRUE(trans
.get());
2800 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
2801 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
2805 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2806 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2807 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2810 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2811 MockHttpCache cache
;
2813 // Test that we hit the cache for POST requests.
2815 MockTransaction
transaction(kSimplePOST_Transaction
);
2817 const int64 kUploadId
= 1; // Just a dummy value.
2819 ScopedVector
<net::UploadElementReader
> element_readers
;
2820 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2821 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2823 MockHttpRequest
request(transaction
);
2824 request
.upload_data_stream
= &upload_data_stream
;
2826 // Populate the cache.
2827 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2829 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2830 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2831 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2834 request
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2835 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2837 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2838 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2839 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2842 // Test that we don't hit the cache for POST requests if there is a byte range.
2843 TEST(HttpCache
, SimplePOST_WithRanges
) {
2844 MockHttpCache cache
;
2846 MockTransaction
transaction(kSimplePOST_Transaction
);
2847 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2849 const int64 kUploadId
= 1; // Just a dummy value.
2851 ScopedVector
<net::UploadElementReader
> element_readers
;
2852 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2853 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2856 MockHttpRequest
request(transaction
);
2857 request
.upload_data_stream
= &upload_data_stream
;
2859 // Attempt to populate the cache.
2860 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2862 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2863 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2864 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2867 // Tests that a POST is cached separately from a previously cached GET.
2868 TEST(HttpCache
, SimplePOST_SeparateCache
) {
2869 MockHttpCache cache
;
2871 ScopedVector
<net::UploadElementReader
> element_readers
;
2872 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2873 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2875 MockTransaction
transaction(kSimplePOST_Transaction
);
2876 MockHttpRequest
req1(transaction
);
2877 req1
.upload_data_stream
= &upload_data_stream
;
2879 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2881 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2882 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2883 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2885 transaction
.method
= "GET";
2886 MockHttpRequest
req2(transaction
);
2888 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2890 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2891 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2892 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2895 // Tests that a successful POST invalidates a previously cached GET.
2896 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
2897 MockHttpCache cache
;
2899 MockTransaction
transaction(kSimpleGET_Transaction
);
2900 AddMockTransaction(&transaction
);
2901 MockHttpRequest
req1(transaction
);
2903 // Attempt to populate the cache.
2904 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2906 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2907 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2908 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2910 ScopedVector
<net::UploadElementReader
> element_readers
;
2911 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2912 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
2914 transaction
.method
= "POST";
2915 transaction
.status
= "HTTP/1.1 205 No Content";
2916 MockHttpRequest
req2(transaction
);
2917 req2
.upload_data_stream
= &upload_data_stream
;
2919 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2921 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2922 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2923 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2925 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2927 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2928 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2929 EXPECT_EQ(3, cache
.disk_cache()->create_count());
2930 RemoveMockTransaction(&transaction
);
2933 // Tests that a successful POST invalidates a previously cached GET, even when
2934 // there is no upload identifier.
2935 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
2936 MockHttpCache cache
;
2938 MockTransaction
transaction(kSimpleGET_Transaction
);
2939 AddMockTransaction(&transaction
);
2940 MockHttpRequest
req1(transaction
);
2942 // Attempt to populate the cache.
2943 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2945 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2946 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2947 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2949 ScopedVector
<net::UploadElementReader
> element_readers
;
2950 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2951 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2953 transaction
.method
= "POST";
2954 transaction
.status
= "HTTP/1.1 205 No Content";
2955 MockHttpRequest
req2(transaction
);
2956 req2
.upload_data_stream
= &upload_data_stream
;
2958 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
2960 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2961 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2962 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2964 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
2966 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2967 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2968 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2969 RemoveMockTransaction(&transaction
);
2972 // Tests that processing a POST before creating the backend doesn't crash.
2973 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
2974 // This will initialize a cache object with NULL backend.
2975 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
2976 factory
->set_fail(true);
2977 factory
->FinishCreation();
2978 MockHttpCache
cache(factory
);
2980 ScopedVector
<net::UploadElementReader
> element_readers
;
2981 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2982 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
2984 MockTransaction
transaction(kSimplePOST_Transaction
);
2985 AddMockTransaction(&transaction
);
2986 MockHttpRequest
req(transaction
);
2987 req
.upload_data_stream
= &upload_data_stream
;
2989 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
2991 RemoveMockTransaction(&transaction
);
2994 // Tests that we don't invalidate entries as a result of a failed POST.
2995 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
2996 MockHttpCache cache
;
2998 MockTransaction
transaction(kSimpleGET_Transaction
);
2999 AddMockTransaction(&transaction
);
3000 MockHttpRequest
req1(transaction
);
3002 // Attempt to populate the cache.
3003 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3005 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3006 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3007 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3009 ScopedVector
<net::UploadElementReader
> element_readers
;
3010 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3011 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3013 transaction
.method
= "POST";
3014 transaction
.status
= "HTTP/1.1 100 Continue";
3015 MockHttpRequest
req2(transaction
);
3016 req2
.upload_data_stream
= &upload_data_stream
;
3018 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3020 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3021 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3022 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3024 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3026 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3027 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3028 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3029 RemoveMockTransaction(&transaction
);
3032 // Tests that a HEAD request is not cached by itself.
3033 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3034 MockHttpCache cache
;
3035 MockTransaction
transaction(kSimplePOST_Transaction
);
3036 AddMockTransaction(&transaction
);
3037 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3038 transaction
.method
= "HEAD";
3040 MockHttpRequest
request(transaction
);
3041 net::TestCompletionCallback callback
;
3043 scoped_ptr
<net::HttpTransaction
> trans
;
3044 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
3045 ASSERT_TRUE(trans
.get());
3047 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
3048 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
3052 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3053 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3054 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3055 RemoveMockTransaction(&transaction
);
3058 // Tests that a HEAD request is served from a cached GET.
3059 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3060 MockHttpCache cache
;
3061 MockTransaction
transaction(kSimpleGET_Transaction
);
3062 AddMockTransaction(&transaction
);
3064 // Populate the cache.
3065 RunTransactionTest(cache
.http_cache(), transaction
);
3067 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3068 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3069 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3072 transaction
.method
= "HEAD";
3073 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3074 transaction
.data
= "";
3075 RunTransactionTest(cache
.http_cache(), transaction
);
3077 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3078 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3079 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3080 RemoveMockTransaction(&transaction
);
3083 // Tests that a read-only request served from the cache preserves CL.
3084 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3085 MockHttpCache cache
;
3086 MockTransaction
transaction(kSimpleGET_Transaction
);
3087 AddMockTransaction(&transaction
);
3088 transaction
.response_headers
= "Content-Length: 42\n";
3090 // Populate the cache.
3091 RunTransactionTest(cache
.http_cache(), transaction
);
3094 transaction
.method
= "HEAD";
3095 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3096 transaction
.data
= "";
3097 std::string headers
;
3099 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3101 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3102 RemoveMockTransaction(&transaction
);
3105 // Tests that a read-write request served from the cache preserves CL.
3106 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3107 MockHttpCache cache
;
3108 MockTransaction
transaction(kETagGET_Transaction
);
3109 AddMockTransaction(&transaction
);
3110 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3111 server_headers
.append("Content-Length: 42\n");
3112 transaction
.response_headers
= server_headers
.data();
3114 // Populate the cache.
3115 RunTransactionTest(cache
.http_cache(), transaction
);
3118 transaction
.method
= "HEAD";
3119 transaction
.data
= "";
3120 std::string headers
;
3122 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3124 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3125 RemoveMockTransaction(&transaction
);
3128 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3129 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3130 MockHttpCache cache
;
3131 MockTransaction
transaction(kSimpleGET_Transaction
);
3132 AddMockTransaction(&transaction
);
3134 // Populate the cache.
3135 RunTransactionTest(cache
.http_cache(), transaction
);
3138 transaction
.method
= "HEAD";
3139 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3140 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3141 transaction
.return_code
= net::ERR_CACHE_MISS
;
3142 RunTransactionTest(cache
.http_cache(), transaction
);
3144 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3145 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3146 RemoveMockTransaction(&transaction
);
3149 // Tests that a HEAD request can be served from a partialy cached resource.
3150 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3151 MockHttpCache cache
;
3152 AddMockTransaction(&kRangeGET_TransactionOK
);
3154 // Write to the cache (40-49).
3155 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3156 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3158 MockTransaction
transaction(kSimpleGET_Transaction
);
3160 transaction
.url
= kRangeGET_TransactionOK
.url
;
3161 transaction
.method
= "HEAD";
3162 transaction
.data
= "";
3163 AddMockTransaction(&transaction
);
3164 std::string headers
;
3167 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3169 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3170 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length"));
3171 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3172 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3173 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3174 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3175 RemoveMockTransaction(&transaction
);
3178 // Tests that a HEAD request can be served from a truncated resource.
3179 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3180 MockHttpCache cache
;
3181 AddMockTransaction(&kRangeGET_TransactionOK
);
3183 std::string
raw_headers("HTTP/1.1 200 OK\n"
3184 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3186 "Accept-Ranges: bytes\n"
3187 "Content-Length: 80\n");
3188 CreateTruncatedEntry(raw_headers
, &cache
);
3189 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3191 MockTransaction
transaction(kSimpleGET_Transaction
);
3193 transaction
.url
= kRangeGET_TransactionOK
.url
;
3194 transaction
.method
= "HEAD";
3195 transaction
.data
= "";
3196 AddMockTransaction(&transaction
);
3197 std::string headers
;
3200 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3202 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3203 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3204 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3205 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3206 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3207 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3208 RemoveMockTransaction(&transaction
);
3211 // Tests that a HEAD request updates the cached response.
3212 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3213 MockHttpCache cache
;
3214 MockTransaction
transaction(kTypicalGET_Transaction
);
3215 AddMockTransaction(&transaction
);
3217 // Populate the cache.
3218 RunTransactionTest(cache
.http_cache(), transaction
);
3220 // Update the cache.
3221 transaction
.method
= "HEAD";
3222 transaction
.response_headers
= "Foo: bar\n";
3223 transaction
.data
= "";
3224 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3225 std::string headers
;
3226 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3227 RemoveMockTransaction(&transaction
);
3229 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3230 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3232 MockTransaction
transaction2(kTypicalGET_Transaction
);
3233 AddMockTransaction(&transaction2
);
3235 // Make sure we are done with the previous transaction.
3236 base::MessageLoop::current()->RunUntilIdle();
3238 // Load from the cache.
3239 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3240 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3242 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3243 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3244 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3246 RemoveMockTransaction(&transaction2
);
3249 // Tests that an externally conditionalized HEAD request updates the cache.
3250 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3251 MockHttpCache cache
;
3252 MockTransaction
transaction(kTypicalGET_Transaction
);
3253 AddMockTransaction(&transaction
);
3255 // Populate the cache.
3256 RunTransactionTest(cache
.http_cache(), transaction
);
3258 // Update the cache.
3259 transaction
.method
= "HEAD";
3260 transaction
.request_headers
=
3261 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3262 transaction
.response_headers
= "Foo: bar\n";
3263 transaction
.data
= "";
3264 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3265 std::string headers
;
3266 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3267 RemoveMockTransaction(&transaction
);
3269 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3270 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3272 MockTransaction
transaction2(kTypicalGET_Transaction
);
3273 AddMockTransaction(&transaction2
);
3275 // Make sure we are done with the previous transaction.
3276 base::MessageLoop::current()->RunUntilIdle();
3278 // Load from the cache.
3279 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3280 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3282 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3283 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3284 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3285 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3286 RemoveMockTransaction(&transaction2
);
3289 // Tests that a HEAD request invalidates an old cached entry.
3290 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3291 MockHttpCache cache
;
3292 MockTransaction
transaction(kTypicalGET_Transaction
);
3293 AddMockTransaction(&transaction
);
3295 // Populate the cache.
3296 RunTransactionTest(cache
.http_cache(), transaction
);
3298 // Update the cache.
3299 transaction
.method
= "HEAD";
3300 transaction
.data
= "";
3301 RunTransactionTest(cache
.http_cache(), transaction
);
3302 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3304 // Load from the cache.
3305 transaction
.method
= "GET";
3306 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3307 transaction
.return_code
= net::ERR_CACHE_MISS
;
3308 RunTransactionTest(cache
.http_cache(), transaction
);
3310 RemoveMockTransaction(&transaction
);
3313 // Tests that we do not cache the response of a PUT.
3314 TEST(HttpCache
, SimplePUT_Miss
) {
3315 MockHttpCache cache
;
3317 MockTransaction
transaction(kSimplePOST_Transaction
);
3318 transaction
.method
= "PUT";
3320 ScopedVector
<net::UploadElementReader
> element_readers
;
3321 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3322 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3324 MockHttpRequest
request(transaction
);
3325 request
.upload_data_stream
= &upload_data_stream
;
3327 // Attempt to populate the cache.
3328 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3330 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3331 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3332 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3335 // Tests that we invalidate entries as a result of a PUT.
3336 TEST(HttpCache
, SimplePUT_Invalidate
) {
3337 MockHttpCache cache
;
3339 MockTransaction
transaction(kSimpleGET_Transaction
);
3340 MockHttpRequest
req1(transaction
);
3342 // Attempt to populate the cache.
3343 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3345 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3346 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3347 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3349 ScopedVector
<net::UploadElementReader
> element_readers
;
3350 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3351 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3353 transaction
.method
= "PUT";
3354 MockHttpRequest
req2(transaction
);
3355 req2
.upload_data_stream
= &upload_data_stream
;
3357 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3359 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3360 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3361 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3363 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3365 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3366 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3367 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3370 // Tests that we invalidate entries as a result of a PUT.
3371 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3372 MockHttpCache cache
;
3374 MockTransaction
transaction(kSimpleGET_Transaction
);
3375 AddMockTransaction(&transaction
);
3376 MockHttpRequest
req1(transaction
);
3378 // Attempt to populate the cache.
3379 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3381 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3382 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3383 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3385 ScopedVector
<net::UploadElementReader
> element_readers
;
3386 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3387 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3389 transaction
.method
= "PUT";
3390 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3391 MockHttpRequest
req2(transaction
);
3392 req2
.upload_data_stream
= &upload_data_stream
;
3394 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3396 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3397 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3398 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3400 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3402 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3403 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3404 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3405 RemoveMockTransaction(&transaction
);
3408 // Tests that we don't invalidate entries as a result of a failed PUT.
3409 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3410 MockHttpCache cache
;
3412 MockTransaction
transaction(kSimpleGET_Transaction
);
3413 AddMockTransaction(&transaction
);
3414 MockHttpRequest
req1(transaction
);
3416 // Attempt to populate the cache.
3417 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3419 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3420 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3421 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3423 ScopedVector
<net::UploadElementReader
> element_readers
;
3424 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3425 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3427 transaction
.method
= "PUT";
3428 transaction
.status
= "HTTP/1.1 404 Not Found";
3429 MockHttpRequest
req2(transaction
);
3430 req2
.upload_data_stream
= &upload_data_stream
;
3432 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3434 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3435 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3436 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3438 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3440 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3441 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3442 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3443 RemoveMockTransaction(&transaction
);
3446 // Tests that we do not cache the response of a DELETE.
3447 TEST(HttpCache
, SimpleDELETE_Miss
) {
3448 MockHttpCache cache
;
3450 MockTransaction
transaction(kSimplePOST_Transaction
);
3451 transaction
.method
= "DELETE";
3453 ScopedVector
<net::UploadElementReader
> element_readers
;
3454 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3455 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3457 MockHttpRequest
request(transaction
);
3458 request
.upload_data_stream
= &upload_data_stream
;
3460 // Attempt to populate the cache.
3461 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3463 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3464 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3465 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3468 // Tests that we invalidate entries as a result of a DELETE.
3469 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3470 MockHttpCache cache
;
3472 MockTransaction
transaction(kSimpleGET_Transaction
);
3473 MockHttpRequest
req1(transaction
);
3475 // Attempt to populate the cache.
3476 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3478 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3479 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3480 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3482 ScopedVector
<net::UploadElementReader
> element_readers
;
3483 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3484 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3486 transaction
.method
= "DELETE";
3487 MockHttpRequest
req2(transaction
);
3488 req2
.upload_data_stream
= &upload_data_stream
;
3490 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3492 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3493 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3494 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3496 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3498 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3499 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3500 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3503 // Tests that we invalidate entries as a result of a DELETE.
3504 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3505 MockHttpCache cache
;
3507 MockTransaction
transaction(kSimpleGET_Transaction
);
3508 AddMockTransaction(&transaction
);
3510 // Attempt to populate the cache.
3511 RunTransactionTest(cache
.http_cache(), transaction
);
3513 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3514 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3515 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3517 transaction
.method
= "DELETE";
3518 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3520 RunTransactionTest(cache
.http_cache(), transaction
);
3522 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3523 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3524 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3526 transaction
.method
= "GET";
3527 RunTransactionTest(cache
.http_cache(), transaction
);
3529 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3530 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3531 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3532 RemoveMockTransaction(&transaction
);
3535 // Tests that we don't invalidate entries as a result of a failed DELETE.
3536 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3537 MockHttpCache cache
;
3539 MockTransaction
transaction(kSimpleGET_Transaction
);
3540 AddMockTransaction(&transaction
);
3542 // Attempt to populate the cache.
3543 RunTransactionTest(cache
.http_cache(), transaction
);
3545 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3546 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3547 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3549 transaction
.method
= "DELETE";
3550 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3552 RunTransactionTest(cache
.http_cache(), transaction
);
3554 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3555 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3556 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3558 transaction
.method
= "GET";
3559 transaction
.status
= "HTTP/1.1 200 OK";
3560 RunTransactionTest(cache
.http_cache(), transaction
);
3562 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3563 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3564 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3565 RemoveMockTransaction(&transaction
);
3568 // Tests that we don't invalidate entries after a failed network transaction.
3569 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3570 MockHttpCache cache
;
3572 // Populate the cache.
3573 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3574 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3576 // Fail the network request.
3577 MockTransaction
transaction(kSimpleGET_Transaction
);
3578 transaction
.return_code
= net::ERR_FAILED
;
3579 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3581 AddMockTransaction(&transaction
);
3582 RunTransactionTest(cache
.http_cache(), transaction
);
3583 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3584 RemoveMockTransaction(&transaction
);
3586 transaction
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
3587 transaction
.return_code
= net::OK
;
3588 AddMockTransaction(&transaction
);
3589 RunTransactionTest(cache
.http_cache(), transaction
);
3591 // Make sure the transaction didn't reach the network.
3592 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3593 RemoveMockTransaction(&transaction
);
3596 TEST(HttpCache
, RangeGET_SkipsCache
) {
3597 MockHttpCache cache
;
3599 // Test that we skip the cache for range GET requests. Eventually, we will
3600 // want to cache these, but we'll still have cases where skipping the cache
3601 // makes sense, so we want to make sure that it works properly.
3603 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3605 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3606 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3607 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3609 MockTransaction
transaction(kSimpleGET_Transaction
);
3610 transaction
.request_headers
= "If-None-Match: foo\r\n";
3611 RunTransactionTest(cache
.http_cache(), transaction
);
3613 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3614 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3615 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3617 transaction
.request_headers
=
3618 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3619 RunTransactionTest(cache
.http_cache(), transaction
);
3621 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3622 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3623 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3626 // Test that we skip the cache for range requests that include a validation
3628 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3629 MockHttpCache cache
;
3631 MockTransaction
transaction(kRangeGET_Transaction
);
3632 transaction
.request_headers
= "If-None-Match: foo\r\n"
3634 "Range: bytes = 40-49\r\n";
3635 RunTransactionTest(cache
.http_cache(), transaction
);
3637 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3638 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3639 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3641 transaction
.request_headers
=
3642 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3644 "Range: bytes = 40-49\r\n";
3645 RunTransactionTest(cache
.http_cache(), transaction
);
3647 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3648 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3649 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3651 transaction
.request_headers
= "If-Range: bla\r\n"
3653 "Range: bytes = 40-49\r\n";
3654 RunTransactionTest(cache
.http_cache(), transaction
);
3656 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3657 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3658 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3661 TEST(HttpCache
, SimpleGET_DoesntLogHeaders
) {
3662 MockHttpCache cache
;
3664 net::CapturingBoundNetLog log
;
3665 RunTransactionTestWithLog(cache
.http_cache(), kSimpleGET_Transaction
,
3668 EXPECT_FALSE(LogContainsEventType(
3669 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3672 TEST(HttpCache
, RangeGET_LogsHeaders
) {
3673 MockHttpCache cache
;
3675 net::CapturingBoundNetLog log
;
3676 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_Transaction
,
3679 EXPECT_TRUE(LogContainsEventType(
3680 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3683 TEST(HttpCache
, ExternalValidation_LogsHeaders
) {
3684 MockHttpCache cache
;
3686 net::CapturingBoundNetLog log
;
3687 MockTransaction
transaction(kSimpleGET_Transaction
);
3688 transaction
.request_headers
= "If-None-Match: foo\r\n" EXTRA_HEADER
;
3689 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3691 EXPECT_TRUE(LogContainsEventType(
3692 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3695 TEST(HttpCache
, SpecialHeaders_LogsHeaders
) {
3696 MockHttpCache cache
;
3698 net::CapturingBoundNetLog log
;
3699 MockTransaction
transaction(kSimpleGET_Transaction
);
3700 transaction
.request_headers
= "cache-control: no-cache\r\n" EXTRA_HEADER
;
3701 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3703 EXPECT_TRUE(LogContainsEventType(
3704 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3707 // Tests that receiving 206 for a regular request is handled correctly.
3708 TEST(HttpCache
, GET_Crazy206
) {
3709 MockHttpCache cache
;
3711 // Write to the cache.
3712 MockTransaction
transaction(kRangeGET_TransactionOK
);
3713 AddMockTransaction(&transaction
);
3714 transaction
.request_headers
= EXTRA_HEADER
;
3715 transaction
.handler
= NULL
;
3716 RunTransactionTest(cache
.http_cache(), transaction
);
3718 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3719 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3720 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3722 // This should read again from the net.
3723 RunTransactionTest(cache
.http_cache(), transaction
);
3725 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3726 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3727 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3728 RemoveMockTransaction(&transaction
);
3731 // Tests that receiving 416 for a regular request is handled correctly.
3732 TEST(HttpCache
, GET_Crazy416
) {
3733 MockHttpCache cache
;
3735 // Write to the cache.
3736 MockTransaction
transaction(kSimpleGET_Transaction
);
3737 AddMockTransaction(&transaction
);
3738 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3739 RunTransactionTest(cache
.http_cache(), transaction
);
3741 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3742 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3743 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3745 RemoveMockTransaction(&transaction
);
3748 // Tests that we don't store partial responses that can't be validated.
3749 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3750 MockHttpCache cache
;
3751 std::string headers
;
3753 // Attempt to write to the cache (40-49).
3754 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3755 transaction
.response_headers
= "Content-Length: 10\n"
3756 "Cache-Control: max-age=3600\n"
3757 "ETag: w/\"foo\"\n";
3758 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3760 Verify206Response(headers
, 40, 49);
3761 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3762 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3763 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3765 // Now verify that there's no cached data.
3766 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3769 Verify206Response(headers
, 40, 49);
3770 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3771 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3772 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3775 // Tests failures to conditionalize byte range requests.
3776 TEST(HttpCache
, RangeGET_NoConditionalization
) {
3777 MockHttpCache cache
;
3778 cache
.FailConditionalizations();
3779 std::string headers
;
3781 // Write to the cache (40-49).
3782 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3783 transaction
.response_headers
= "Content-Length: 10\n"
3785 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3787 Verify206Response(headers
, 40, 49);
3788 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3789 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3790 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3792 // Now verify that the cached data is not used.
3793 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3796 Verify206Response(headers
, 40, 49);
3797 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3798 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3799 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3802 // Tests that restarting a partial request when the cached data cannot be
3803 // revalidated logs an event.
3804 TEST(HttpCache
, RangeGET_NoValidation_LogsRestart
) {
3805 MockHttpCache cache
;
3806 cache
.FailConditionalizations();
3808 // Write to the cache (40-49).
3809 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3810 transaction
.response_headers
= "Content-Length: 10\n"
3812 RunTransactionTest(cache
.http_cache(), transaction
);
3814 // Now verify that the cached data is not used.
3815 net::CapturingBoundNetLog log
;
3816 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_TransactionOK
,
3819 EXPECT_TRUE(LogContainsEventType(
3820 log
, net::NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST
));
3823 // Tests that a failure to conditionalize a regular request (no range) with a
3824 // sparse entry results in a full response.
3825 TEST(HttpCache
, GET_NoConditionalization
) {
3826 MockHttpCache cache
;
3827 cache
.FailConditionalizations();
3828 std::string headers
;
3830 // Write to the cache (40-49).
3831 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3832 transaction
.response_headers
= "Content-Length: 10\n"
3834 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3836 Verify206Response(headers
, 40, 49);
3837 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3838 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3839 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3841 // Now verify that the cached data is not used.
3842 // Don't ask for a range. The cache will attempt to use the cached data but
3843 // should discard it as it cannot be validated. A regular request should go
3844 // to the server and a new entry should be created.
3845 transaction
.request_headers
= EXTRA_HEADER
;
3846 transaction
.data
= "Not a range";
3847 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3849 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
3850 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3851 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3852 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3854 // The last response was saved.
3855 RunTransactionTest(cache
.http_cache(), transaction
);
3856 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3857 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3858 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3861 // Verifies that conditionalization failures when asking for a range that would
3862 // require the cache to modify the range to ask, result in a network request
3863 // that matches the user's one.
3864 TEST(HttpCache
, RangeGET_NoConditionalization2
) {
3865 MockHttpCache cache
;
3866 cache
.FailConditionalizations();
3867 std::string headers
;
3869 // Write to the cache (40-49).
3870 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3871 transaction
.response_headers
= "Content-Length: 10\n"
3873 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3875 Verify206Response(headers
, 40, 49);
3876 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3877 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3878 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3880 // Now verify that the cached data is not used.
3881 // Ask for a range that extends before and after the cached data so that the
3882 // cache would normally mix data from three sources. After deleting the entry,
3883 // the response will come from a single network request.
3884 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3885 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3886 transaction
.response_headers
= kRangeGET_TransactionOK
.response_headers
;
3887 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3889 Verify206Response(headers
, 20, 59);
3890 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3891 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3892 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3894 // The last response was saved.
3895 RunTransactionTest(cache
.http_cache(), transaction
);
3896 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3897 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3898 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3901 // Tests that we cache partial responses that lack content-length.
3902 TEST(HttpCache
, RangeGET_NoContentLength
) {
3903 MockHttpCache cache
;
3904 std::string headers
;
3906 // Attempt to write to the cache (40-49).
3907 MockTransaction
transaction(kRangeGET_TransactionOK
);
3908 AddMockTransaction(&transaction
);
3909 transaction
.response_headers
= "ETag: \"foo\"\n"
3910 "Accept-Ranges: bytes\n"
3911 "Content-Range: bytes 40-49/80\n";
3912 transaction
.handler
= NULL
;
3913 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3915 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3916 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3917 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3919 // Now verify that there's no cached data.
3920 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
3921 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3924 Verify206Response(headers
, 40, 49);
3925 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3926 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3927 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3929 RemoveMockTransaction(&transaction
);
3932 // Tests that we can cache range requests and fetch random blocks from the
3933 // cache and the network.
3934 TEST(HttpCache
, RangeGET_OK
) {
3935 MockHttpCache cache
;
3936 AddMockTransaction(&kRangeGET_TransactionOK
);
3937 std::string headers
;
3939 // Write to the cache (40-49).
3940 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3943 Verify206Response(headers
, 40, 49);
3944 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3945 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3946 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3948 // Read from the cache (40-49).
3949 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3952 Verify206Response(headers
, 40, 49);
3953 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3954 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3955 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3957 // Make sure we are done with the previous transaction.
3958 base::MessageLoop::current()->RunUntilIdle();
3960 // Write to the cache (30-39).
3961 MockTransaction
transaction(kRangeGET_TransactionOK
);
3962 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
3963 transaction
.data
= "rg: 30-39 ";
3964 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3966 Verify206Response(headers
, 30, 39);
3967 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3968 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3969 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3971 // Make sure we are done with the previous transaction.
3972 base::MessageLoop::current()->RunUntilIdle();
3974 // Write and read from the cache (20-59).
3975 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
3976 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3977 net::CapturingBoundNetLog log
;
3978 net::LoadTimingInfo load_timing_info
;
3979 RunTransactionTestWithResponseAndGetTiming(
3980 cache
.http_cache(), transaction
, &headers
, log
.bound(),
3983 Verify206Response(headers
, 20, 59);
3984 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
3985 EXPECT_EQ(3, cache
.disk_cache()->open_count());
3986 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3987 TestLoadTimingNetworkRequest(load_timing_info
);
3989 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3992 // Tests that we can cache range requests and fetch random blocks from the
3993 // cache and the network, with synchronous responses.
3994 TEST(HttpCache
, RangeGET_SyncOK
) {
3995 MockHttpCache cache
;
3997 MockTransaction
transaction(kRangeGET_TransactionOK
);
3998 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
3999 AddMockTransaction(&transaction
);
4001 // Write to the cache (40-49).
4002 std::string headers
;
4003 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4005 Verify206Response(headers
, 40, 49);
4006 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4007 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4008 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4010 // Read from the cache (40-49).
4011 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4013 Verify206Response(headers
, 40, 49);
4014 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4015 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4016 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4018 // Make sure we are done with the previous transaction.
4019 base::MessageLoop::current()->RunUntilIdle();
4021 // Write to the cache (30-39).
4022 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4023 transaction
.data
= "rg: 30-39 ";
4024 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4026 Verify206Response(headers
, 30, 39);
4027 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4028 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4029 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4031 // Make sure we are done with the previous transaction.
4032 base::MessageLoop::current()->RunUntilIdle();
4034 // Write and read from the cache (20-59).
4035 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4036 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4037 net::CapturingBoundNetLog log
;
4038 net::LoadTimingInfo load_timing_info
;
4039 RunTransactionTestWithResponseAndGetTiming(
4040 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4043 Verify206Response(headers
, 20, 59);
4044 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4045 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4046 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4047 TestLoadTimingNetworkRequest(load_timing_info
);
4049 RemoveMockTransaction(&transaction
);
4052 // Tests that we don't revalidate an entry unless we are required to do so.
4053 TEST(HttpCache
, RangeGET_Revalidate1
) {
4054 MockHttpCache cache
;
4055 std::string headers
;
4057 // Write to the cache (40-49).
4058 MockTransaction
transaction(kRangeGET_TransactionOK
);
4059 transaction
.response_headers
=
4060 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4061 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4063 "Accept-Ranges: bytes\n"
4064 "Content-Length: 10\n";
4065 AddMockTransaction(&transaction
);
4066 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4068 Verify206Response(headers
, 40, 49);
4069 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4070 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4071 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4073 // Read from the cache (40-49).
4074 net::CapturingBoundNetLog log
;
4075 net::LoadTimingInfo load_timing_info
;
4076 RunTransactionTestWithResponseAndGetTiming(
4077 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4080 Verify206Response(headers
, 40, 49);
4081 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4082 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4083 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4084 TestLoadTimingCachedResponse(load_timing_info
);
4086 // Read again forcing the revalidation.
4087 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4088 RunTransactionTestWithResponseAndGetTiming(
4089 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4092 Verify206Response(headers
, 40, 49);
4093 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4094 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4095 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4096 TestLoadTimingNetworkRequest(load_timing_info
);
4098 RemoveMockTransaction(&transaction
);
4101 // Checks that we revalidate an entry when the headers say so.
4102 TEST(HttpCache
, RangeGET_Revalidate2
) {
4103 MockHttpCache cache
;
4104 std::string headers
;
4106 // Write to the cache (40-49).
4107 MockTransaction
transaction(kRangeGET_TransactionOK
);
4108 transaction
.response_headers
=
4109 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4110 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4112 "Accept-Ranges: bytes\n"
4113 "Content-Length: 10\n";
4114 AddMockTransaction(&transaction
);
4115 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4117 Verify206Response(headers
, 40, 49);
4118 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4119 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4120 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4122 // Read from the cache (40-49).
4123 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4124 Verify206Response(headers
, 40, 49);
4126 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4127 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4128 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4130 RemoveMockTransaction(&transaction
);
4133 // Tests that we deal with 304s for range requests.
4134 TEST(HttpCache
, RangeGET_304
) {
4135 MockHttpCache cache
;
4136 AddMockTransaction(&kRangeGET_TransactionOK
);
4137 std::string headers
;
4139 // Write to the cache (40-49).
4140 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4143 Verify206Response(headers
, 40, 49);
4144 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4145 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4146 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4148 // Read from the cache (40-49).
4149 RangeTransactionServer handler
;
4150 handler
.set_not_modified(true);
4151 MockTransaction
transaction(kRangeGET_TransactionOK
);
4152 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4153 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4155 Verify206Response(headers
, 40, 49);
4156 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4157 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4158 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4160 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4163 // Tests that we deal with 206s when revalidating range requests.
4164 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4165 MockHttpCache cache
;
4166 AddMockTransaction(&kRangeGET_TransactionOK
);
4167 std::string headers
;
4169 // Write to the cache (40-49).
4170 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4173 Verify206Response(headers
, 40, 49);
4174 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4175 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4176 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4178 // Attempt to read from the cache (40-49).
4179 RangeTransactionServer handler
;
4180 handler
.set_modified(true);
4181 MockTransaction
transaction(kRangeGET_TransactionOK
);
4182 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4183 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4185 Verify206Response(headers
, 40, 49);
4186 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4187 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4188 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4190 // And the entry should be gone.
4191 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4192 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4193 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4194 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4196 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4199 // Tests that when a server returns 206 with a sub-range of the requested range,
4200 // and there is nothing stored in the cache, the returned response is passed to
4201 // the caller as is. In this context, a subrange means a response that starts
4202 // with the same byte that was requested, but that is not the whole range that
4204 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_NoCachedContent
) {
4205 MockHttpCache cache
;
4206 std::string headers
;
4208 // Request a large range (40-59). The server sends 40-49.
4209 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4210 transaction
.request_headers
= "Range: bytes = 40-59\r\n" EXTRA_HEADER
;
4211 transaction
.response_headers
=
4212 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4214 "Accept-Ranges: bytes\n"
4215 "Content-Length: 10\n"
4216 "Content-Range: bytes 40-49/80\n";
4217 transaction
.handler
= nullptr;
4218 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4220 Verify206Response(headers
, 40, 49);
4221 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4222 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4223 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4226 // Tests that when a server returns 206 with a sub-range of the requested range,
4227 // and there was an entry stored in the cache, the cache gets out of the way.
4228 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_CachedContent
) {
4229 MockHttpCache cache
;
4230 std::string headers
;
4232 // Write to the cache (70-79).
4233 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4234 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4235 transaction
.data
= "rg: 70-79 ";
4236 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4237 Verify206Response(headers
, 70, 79);
4239 // Request a large range (40-79). The cache will ask the server for 40-59.
4240 // The server returns 40-49. The cache should consider the server confused and
4241 // abort caching, restarting the request without caching.
4242 transaction
.request_headers
= "Range: bytes = 40-79\r\n" EXTRA_HEADER
;
4243 transaction
.response_headers
=
4244 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4246 "Accept-Ranges: bytes\n"
4247 "Content-Length: 10\n"
4248 "Content-Range: bytes 40-49/80\n";
4249 transaction
.handler
= nullptr;
4250 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4252 // Two new network requests were issued, one from the cache and another after
4253 // deleting the entry.
4254 Verify206Response(headers
, 40, 49);
4255 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4256 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4257 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4259 // The entry was deleted.
4260 RunTransactionTest(cache
.http_cache(), transaction
);
4261 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4262 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4263 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4266 // Tests that when a server returns 206 with a sub-range of the requested range,
4267 // and there was an entry stored in the cache, the cache gets out of the way,
4268 // when the caller is not using ranges.
4269 TEST(HttpCache
, GET_206ReturnsSubrangeRange_CachedContent
) {
4270 MockHttpCache cache
;
4271 std::string headers
;
4273 // Write to the cache (70-79).
4274 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4275 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4276 transaction
.data
= "rg: 70-79 ";
4277 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4278 Verify206Response(headers
, 70, 79);
4280 // Don't ask for a range. The cache will ask the server for 0-69.
4281 // The server returns 40-49. The cache should consider the server confused and
4282 // abort caching, restarting the request.
4283 // The second network request should not be a byte range request so the server
4284 // should return 200 + "Not a range"
4285 transaction
.request_headers
= "X-Return-Default-Range:\r\n" EXTRA_HEADER
;
4286 transaction
.data
= "Not a range";
4287 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4289 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4290 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4291 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4292 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4294 // The entry was deleted.
4295 RunTransactionTest(cache
.http_cache(), transaction
);
4296 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4297 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4298 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4301 // Tests that when a server returns 206 with a random range and there is
4302 // nothing stored in the cache, the returned response is passed to the caller
4303 // as is. In this context, a WrongRange means that the returned range may or may
4304 // not have any relationship with the requested range (may or may not be
4305 // contained). The important part is that the first byte doesn't match the first
4307 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_NoCachedContent
) {
4308 MockHttpCache cache
;
4309 std::string headers
;
4311 // Request a large range (30-59). The server sends (40-49).
4312 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4313 transaction
.request_headers
= "Range: bytes = 30-59\r\n" EXTRA_HEADER
;
4314 transaction
.response_headers
=
4315 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4317 "Accept-Ranges: bytes\n"
4318 "Content-Length: 10\n"
4319 "Content-Range: bytes 40-49/80\n";
4320 transaction
.handler
= nullptr;
4321 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4323 Verify206Response(headers
, 40, 49);
4324 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4325 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4326 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4328 // The entry was deleted.
4329 RunTransactionTest(cache
.http_cache(), transaction
);
4330 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4331 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4332 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4335 // Tests that when a server returns 206 with a random range and there is
4336 // an entry stored in the cache, the cache gets out of the way.
4337 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_CachedContent
) {
4338 MockHttpCache cache
;
4339 std::string headers
;
4341 // Write to the cache (70-79).
4342 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4343 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4344 transaction
.data
= "rg: 70-79 ";
4345 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4346 Verify206Response(headers
, 70, 79);
4348 // Request a large range (30-79). The cache will ask the server for 30-69.
4349 // The server returns 40-49. The cache should consider the server confused and
4350 // abort caching, returning the weird range to the caller.
4351 transaction
.request_headers
= "Range: bytes = 30-79\r\n" EXTRA_HEADER
;
4352 transaction
.response_headers
=
4353 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4355 "Accept-Ranges: bytes\n"
4356 "Content-Length: 10\n"
4357 "Content-Range: bytes 40-49/80\n";
4358 transaction
.handler
= nullptr;
4359 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4361 Verify206Response(headers
, 40, 49);
4362 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4363 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4364 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4366 // The entry was deleted.
4367 RunTransactionTest(cache
.http_cache(), transaction
);
4368 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4369 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4370 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4373 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4374 // the response matches the one provided by the server.
4375 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_NoCachedContent
) {
4376 MockHttpCache cache
;
4377 std::string headers
;
4379 // Request a large range (70-99). The server sends 70-79.
4380 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4381 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4382 transaction
.data
= "rg: 70-79 ";
4383 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4385 Verify206Response(headers
, 70, 79);
4386 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4387 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4388 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4390 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4391 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4394 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4395 // the cache automatically fixes the request.
4396 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_CachedContent
) {
4397 MockHttpCache cache
;
4398 std::string headers
;
4400 // Write to the cache (40-49).
4401 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4402 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4404 // Request a large range (70-99). The server sends 70-79.
4405 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4406 transaction
.data
= "rg: 70-79 ";
4407 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4409 Verify206Response(headers
, 70, 79);
4410 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4411 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4412 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4414 // The entry was not deleted (the range was automatically fixed).
4415 RunTransactionTest(cache
.http_cache(), transaction
);
4416 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4417 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4418 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4421 // Tests that when a caller asks for a not-satisfiable range, the server's
4422 // response is forwarded to the caller.
4423 TEST(HttpCache
, RangeGET_416_NoCachedContent
) {
4424 MockHttpCache cache
;
4425 std::string headers
;
4427 // Request a range beyond EOF (80-99).
4428 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4429 transaction
.request_headers
= "Range: bytes = 80-99\r\n" EXTRA_HEADER
;
4430 transaction
.data
= "";
4431 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
4432 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4434 EXPECT_EQ(0U, headers
.find(transaction
.status
));
4435 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4436 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4437 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4439 // The entry was deleted.
4440 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4441 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4444 // Tests that we cache 301s for range requests.
4445 TEST(HttpCache
, RangeGET_301
) {
4446 MockHttpCache cache
;
4447 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4448 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4449 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4450 transaction
.data
= "";
4451 transaction
.handler
= NULL
;
4453 // Write to the cache.
4454 RunTransactionTest(cache
.http_cache(), transaction
);
4455 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4456 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4457 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4459 // Read from the cache.
4460 RunTransactionTest(cache
.http_cache(), transaction
);
4461 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4462 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4463 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4466 // Tests that we can cache range requests when the start or end is unknown.
4467 // We start with one suffix request, followed by a request from a given point.
4468 TEST(HttpCache
, UnknownRangeGET_1
) {
4469 MockHttpCache cache
;
4470 AddMockTransaction(&kRangeGET_TransactionOK
);
4471 std::string headers
;
4473 // Write to the cache (70-79).
4474 MockTransaction
transaction(kRangeGET_TransactionOK
);
4475 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4476 transaction
.data
= "rg: 70-79 ";
4477 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4479 Verify206Response(headers
, 70, 79);
4480 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4481 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4482 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4484 // Make sure we are done with the previous transaction.
4485 base::MessageLoop::current()->RunUntilIdle();
4487 // Write and read from the cache (60-79).
4488 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4489 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4490 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4492 Verify206Response(headers
, 60, 79);
4493 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4494 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4495 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4497 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4500 // Tests that we can cache range requests when the start or end is unknown.
4501 // We start with one request from a given point, followed by a suffix request.
4502 // We'll also verify that synchronous cache responses work as intended.
4503 TEST(HttpCache
, UnknownRangeGET_2
) {
4504 MockHttpCache cache
;
4505 std::string headers
;
4507 MockTransaction
transaction(kRangeGET_TransactionOK
);
4508 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4509 TEST_MODE_SYNC_CACHE_READ
|
4510 TEST_MODE_SYNC_CACHE_WRITE
;
4511 AddMockTransaction(&transaction
);
4513 // Write to the cache (70-79).
4514 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4515 transaction
.data
= "rg: 70-79 ";
4516 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4518 Verify206Response(headers
, 70, 79);
4519 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4520 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4521 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4523 // Make sure we are done with the previous transaction.
4524 base::MessageLoop::current()->RunUntilIdle();
4526 // Write and read from the cache (60-79).
4527 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4528 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4529 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4531 Verify206Response(headers
, 60, 79);
4532 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4533 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4534 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4536 RemoveMockTransaction(&transaction
);
4539 // Tests that receiving Not Modified when asking for an open range doesn't mess
4541 TEST(HttpCache
, UnknownRangeGET_304
) {
4542 MockHttpCache cache
;
4543 std::string headers
;
4545 MockTransaction
transaction(kRangeGET_TransactionOK
);
4546 AddMockTransaction(&transaction
);
4548 RangeTransactionServer handler
;
4549 handler
.set_not_modified(true);
4551 // Ask for the end of the file, without knowing the length.
4552 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4553 transaction
.data
= "";
4554 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4556 // We just bypass the cache.
4557 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4558 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4559 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4560 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4562 RunTransactionTest(cache
.http_cache(), transaction
);
4563 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4565 RemoveMockTransaction(&transaction
);
4568 // Tests that we can handle non-range requests when we have cached a range.
4569 TEST(HttpCache
, GET_Previous206
) {
4570 MockHttpCache cache
;
4571 AddMockTransaction(&kRangeGET_TransactionOK
);
4572 std::string headers
;
4573 net::CapturingBoundNetLog log
;
4574 net::LoadTimingInfo load_timing_info
;
4576 // Write to the cache (40-49).
4577 RunTransactionTestWithResponseAndGetTiming(
4578 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4581 Verify206Response(headers
, 40, 49);
4582 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4583 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4584 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4585 TestLoadTimingNetworkRequest(load_timing_info
);
4587 // Write and read from the cache (0-79), when not asked for a range.
4588 MockTransaction
transaction(kRangeGET_TransactionOK
);
4589 transaction
.request_headers
= EXTRA_HEADER
;
4590 transaction
.data
= kFullRangeData
;
4591 RunTransactionTestWithResponseAndGetTiming(
4592 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4595 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4596 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4597 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4598 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4599 TestLoadTimingNetworkRequest(load_timing_info
);
4601 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4604 // Tests that we can handle non-range requests when we have cached the first
4605 // part of the object and the server replies with 304 (Not Modified).
4606 TEST(HttpCache
, GET_Previous206_NotModified
) {
4607 MockHttpCache cache
;
4609 MockTransaction
transaction(kRangeGET_TransactionOK
);
4610 AddMockTransaction(&transaction
);
4611 std::string headers
;
4612 net::CapturingBoundNetLog log
;
4613 net::LoadTimingInfo load_timing_info
;
4615 // Write to the cache (0-9).
4616 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4617 transaction
.data
= "rg: 00-09 ";
4618 RunTransactionTestWithResponseAndGetTiming(
4619 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4621 Verify206Response(headers
, 0, 9);
4622 TestLoadTimingNetworkRequest(load_timing_info
);
4624 // Write to the cache (70-79).
4625 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4626 transaction
.data
= "rg: 70-79 ";
4627 RunTransactionTestWithResponseAndGetTiming(
4628 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4630 Verify206Response(headers
, 70, 79);
4632 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4633 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4634 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4635 TestLoadTimingNetworkRequest(load_timing_info
);
4637 // Read from the cache (0-9), write and read from cache (10 - 79).
4638 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4639 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4640 transaction
.data
= kFullRangeData
;
4641 RunTransactionTestWithResponseAndGetTiming(
4642 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4645 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4646 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4647 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4648 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4649 TestLoadTimingNetworkRequest(load_timing_info
);
4651 RemoveMockTransaction(&transaction
);
4654 // Tests that we can handle a regular request to a sparse entry, that results in
4655 // new content provided by the server (206).
4656 TEST(HttpCache
, GET_Previous206_NewContent
) {
4657 MockHttpCache cache
;
4658 AddMockTransaction(&kRangeGET_TransactionOK
);
4659 std::string headers
;
4661 // Write to the cache (0-9).
4662 MockTransaction
transaction(kRangeGET_TransactionOK
);
4663 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4664 transaction
.data
= "rg: 00-09 ";
4665 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4667 Verify206Response(headers
, 0, 9);
4668 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4669 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4670 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4672 // Now we'll issue a request without any range that should result first in a
4673 // 206 (when revalidating), and then in a weird standard answer: the test
4674 // server will not modify the response so we'll get the default range... a
4675 // real server will answer with 200.
4676 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4677 transaction2
.request_headers
= EXTRA_HEADER
;
4678 transaction2
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4679 transaction2
.data
= "Not a range";
4680 RangeTransactionServer handler
;
4681 handler
.set_modified(true);
4682 net::CapturingBoundNetLog log
;
4683 net::LoadTimingInfo load_timing_info
;
4684 RunTransactionTestWithResponseAndGetTiming(
4685 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4688 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4689 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4690 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4691 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4692 TestLoadTimingNetworkRequest(load_timing_info
);
4694 // Verify that the previous request deleted the entry.
4695 RunTransactionTest(cache
.http_cache(), transaction
);
4696 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4698 RemoveMockTransaction(&transaction
);
4701 // Tests that we can handle cached 206 responses that are not sparse.
4702 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4703 MockHttpCache cache
;
4705 // Create a disk cache entry that stores 206 headers while not being sparse.
4706 disk_cache::Entry
* entry
;
4707 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4710 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4711 raw_headers
.append("\n");
4712 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4713 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4714 raw_headers
.size());
4716 net::HttpResponseInfo response
;
4717 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4718 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4720 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4721 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4722 kRangeGET_TransactionOK
.data
, 500));
4723 net::TestCompletionCallback cb
;
4724 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4725 EXPECT_EQ(len
, cb
.GetResult(rv
));
4728 // Now see that we don't use the stored entry.
4729 std::string headers
;
4730 net::CapturingBoundNetLog log
;
4731 net::LoadTimingInfo load_timing_info
;
4732 RunTransactionTestWithResponseAndGetTiming(
4733 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4736 // We are expecting a 200.
4737 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4738 expected_headers
.append("\n");
4739 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4740 EXPECT_EQ(expected_headers
, headers
);
4741 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4742 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4743 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4744 TestLoadTimingNetworkRequest(load_timing_info
);
4747 // Tests that we can handle cached 206 responses that are not sparse. This time
4748 // we issue a range request and expect to receive a range.
4749 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4750 MockHttpCache cache
;
4751 AddMockTransaction(&kRangeGET_TransactionOK
);
4753 // Create a disk cache entry that stores 206 headers while not being sparse.
4754 disk_cache::Entry
* entry
;
4755 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4758 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4759 raw_headers
.append("\n");
4760 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4761 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4762 raw_headers
.size());
4764 net::HttpResponseInfo response
;
4765 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4766 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4768 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4769 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4770 kRangeGET_TransactionOK
.data
, 500));
4771 net::TestCompletionCallback cb
;
4772 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4773 EXPECT_EQ(len
, cb
.GetResult(rv
));
4776 // Now see that we don't use the stored entry.
4777 std::string headers
;
4778 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4781 // We are expecting a 206.
4782 Verify206Response(headers
, 40, 49);
4783 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4784 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4785 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4787 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4790 // Tests that we can handle cached 206 responses that can't be validated.
4791 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4792 MockHttpCache cache
;
4794 // Create a disk cache entry that stores 206 headers.
4795 disk_cache::Entry
* entry
;
4796 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4799 // Make sure that the headers cannot be validated with the server.
4800 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4801 raw_headers
.append("\n");
4802 raw_headers
.append("Content-Length: 80\n");
4803 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4804 raw_headers
.size());
4806 net::HttpResponseInfo response
;
4807 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4808 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4810 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4811 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4812 kRangeGET_TransactionOK
.data
, 500));
4813 net::TestCompletionCallback cb
;
4814 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4815 EXPECT_EQ(len
, cb
.GetResult(rv
));
4818 // Now see that we don't use the stored entry.
4819 std::string headers
;
4820 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4823 // We are expecting a 200.
4824 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4825 expected_headers
.append("\n");
4826 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4827 EXPECT_EQ(expected_headers
, headers
);
4828 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4829 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4830 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4833 // Tests that we can handle range requests with cached 200 responses.
4834 TEST(HttpCache
, RangeGET_Previous200
) {
4835 MockHttpCache cache
;
4837 // Store the whole thing with status 200.
4838 MockTransaction
transaction(kTypicalGET_Transaction
);
4839 transaction
.url
= kRangeGET_TransactionOK
.url
;
4840 transaction
.data
= kFullRangeData
;
4841 AddMockTransaction(&transaction
);
4842 RunTransactionTest(cache
.http_cache(), transaction
);
4843 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4844 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4845 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4847 RemoveMockTransaction(&transaction
);
4848 AddMockTransaction(&kRangeGET_TransactionOK
);
4850 // Now see that we use the stored entry.
4851 std::string headers
;
4852 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4853 RangeTransactionServer handler
;
4854 handler
.set_not_modified(true);
4855 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4857 // We are expecting a 206.
4858 Verify206Response(headers
, 40, 49);
4859 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4860 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4861 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4863 // The last transaction has finished so make sure the entry is deactivated.
4864 base::MessageLoop::current()->RunUntilIdle();
4866 // Make a request for an invalid range.
4867 MockTransaction
transaction3(kRangeGET_TransactionOK
);
4868 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
4869 transaction3
.data
= transaction
.data
;
4870 transaction3
.load_flags
= net::LOAD_PREFERRING_CACHE
;
4871 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
4872 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4873 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
4874 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
4875 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
4877 // Make sure the entry is deactivated.
4878 base::MessageLoop::current()->RunUntilIdle();
4880 // Even though the request was invalid, we should have the entry.
4881 RunTransactionTest(cache
.http_cache(), transaction2
);
4882 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4884 // Make sure the entry is deactivated.
4885 base::MessageLoop::current()->RunUntilIdle();
4887 // Now we should receive a range from the server and drop the stored entry.
4888 handler
.set_not_modified(false);
4889 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4890 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4891 Verify206Response(headers
, 40, 49);
4892 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4893 EXPECT_EQ(4, cache
.disk_cache()->open_count());
4894 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4896 RunTransactionTest(cache
.http_cache(), transaction2
);
4897 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4899 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4902 // Tests that we can handle a 200 response when dealing with sparse entries.
4903 TEST(HttpCache
, RangeRequestResultsIn200
) {
4904 MockHttpCache cache
;
4905 AddMockTransaction(&kRangeGET_TransactionOK
);
4906 std::string headers
;
4908 // Write to the cache (70-79).
4909 MockTransaction
transaction(kRangeGET_TransactionOK
);
4910 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4911 transaction
.data
= "rg: 70-79 ";
4912 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4914 Verify206Response(headers
, 70, 79);
4915 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4916 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4917 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4919 // Now we'll issue a request that results in a plain 200 response, but to
4920 // the to the same URL that we used to store sparse data, and making sure
4921 // that we ask for a range.
4922 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4923 MockTransaction
transaction2(kSimpleGET_Transaction
);
4924 transaction2
.url
= kRangeGET_TransactionOK
.url
;
4925 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
4926 AddMockTransaction(&transaction2
);
4928 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
4930 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4931 expected_headers
.append("\n");
4932 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4933 EXPECT_EQ(expected_headers
, headers
);
4934 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4935 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4936 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4938 RemoveMockTransaction(&transaction2
);
4941 // Tests that a range request that falls outside of the size that we know about
4942 // only deletes the entry if the resource has indeed changed.
4943 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
4944 MockHttpCache cache
;
4945 AddMockTransaction(&kRangeGET_TransactionOK
);
4946 std::string headers
;
4948 // Write to the cache (40-49).
4949 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4952 Verify206Response(headers
, 40, 49);
4953 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4954 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4955 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4957 // A weird request should not delete this entry. Ask for bytes 120-.
4958 MockTransaction
transaction(kRangeGET_TransactionOK
);
4959 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
4960 transaction
.data
= "";
4961 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4963 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
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 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4969 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4970 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4972 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4975 // Tests that we don't delete a sparse entry when we cancel a request.
4976 TEST(HttpCache
, RangeGET_Cancel
) {
4977 MockHttpCache cache
;
4978 AddMockTransaction(&kRangeGET_TransactionOK
);
4980 MockHttpRequest
request(kRangeGET_TransactionOK
);
4982 Context
* c
= new Context();
4983 int rv
= cache
.CreateTransaction(&c
->trans
);
4984 ASSERT_EQ(net::OK
, rv
);
4986 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
4987 if (rv
== net::ERR_IO_PENDING
)
4988 rv
= c
->callback
.WaitForResult();
4990 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4991 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4992 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4994 // Make sure that the entry has some data stored.
4995 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
4996 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
4997 if (rv
== net::ERR_IO_PENDING
)
4998 rv
= c
->callback
.WaitForResult();
4999 EXPECT_EQ(buf
->size(), rv
);
5001 // Destroy the transaction.
5004 // Verify that the entry has not been deleted.
5005 disk_cache::Entry
* entry
;
5006 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5008 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5011 // Tests that we don't delete a sparse entry when we start a new request after
5012 // cancelling the previous one.
5013 TEST(HttpCache
, RangeGET_Cancel2
) {
5014 MockHttpCache cache
;
5015 AddMockTransaction(&kRangeGET_TransactionOK
);
5017 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5018 MockHttpRequest
request(kRangeGET_TransactionOK
);
5019 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5021 Context
* c
= new Context();
5022 int rv
= cache
.CreateTransaction(&c
->trans
);
5023 ASSERT_EQ(net::OK
, rv
);
5025 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5026 if (rv
== net::ERR_IO_PENDING
)
5027 rv
= c
->callback
.WaitForResult();
5029 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5030 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5031 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5033 // Make sure that we revalidate the entry and read from the cache (a single
5034 // read will return while waiting for the network).
5035 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5036 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5037 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5038 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5039 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5041 // Destroy the transaction before completing the read.
5044 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5045 // message loop. This means that a new transaction will just reuse the same
5046 // active entry (no open or create).
5048 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5050 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5051 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5052 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5053 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5056 // A slight variation of the previous test, this time we cancel two requests in
5057 // a row, making sure that the second is waiting for the entry to be ready.
5058 TEST(HttpCache
, RangeGET_Cancel3
) {
5059 MockHttpCache cache
;
5060 AddMockTransaction(&kRangeGET_TransactionOK
);
5062 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5063 MockHttpRequest
request(kRangeGET_TransactionOK
);
5064 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5066 Context
* c
= new Context();
5067 int rv
= cache
.CreateTransaction(&c
->trans
);
5068 ASSERT_EQ(net::OK
, rv
);
5070 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5071 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5072 rv
= c
->callback
.WaitForResult();
5074 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5075 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5076 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5078 // Make sure that we revalidate the entry and read from the cache (a single
5079 // read will return while waiting for the network).
5080 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5081 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5082 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5083 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5084 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5086 // Destroy the transaction before completing the read.
5089 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5090 // message loop. This means that a new transaction will just reuse the same
5091 // active entry (no open or create).
5094 rv
= cache
.CreateTransaction(&c
->trans
);
5095 ASSERT_EQ(net::OK
, rv
);
5097 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5098 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5100 MockDiskEntry::IgnoreCallbacks(true);
5101 base::MessageLoop::current()->RunUntilIdle();
5102 MockDiskEntry::IgnoreCallbacks(false);
5104 // The new transaction is waiting for the query range callback.
5107 // And we should not crash when the callback is delivered.
5108 base::MessageLoop::current()->RunUntilIdle();
5110 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5111 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5112 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5113 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5116 // Tests that an invalid range response results in no cached entry.
5117 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
5118 MockHttpCache cache
;
5119 std::string headers
;
5121 MockTransaction
transaction(kRangeGET_TransactionOK
);
5122 transaction
.handler
= NULL
;
5123 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
5124 "Content-Length: 10\n";
5125 AddMockTransaction(&transaction
);
5126 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5128 std::string
expected(transaction
.status
);
5129 expected
.append("\n");
5130 expected
.append(transaction
.response_headers
);
5131 EXPECT_EQ(expected
, headers
);
5133 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5134 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5135 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5137 // Verify that we don't have a cached entry.
5138 disk_cache::Entry
* entry
;
5139 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5141 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5144 // Tests that we reject a range that doesn't match the content-length.
5145 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
5146 MockHttpCache cache
;
5147 std::string headers
;
5149 MockTransaction
transaction(kRangeGET_TransactionOK
);
5150 transaction
.handler
= NULL
;
5151 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
5152 "Content-Length: 20\n";
5153 AddMockTransaction(&transaction
);
5154 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5156 std::string
expected(transaction
.status
);
5157 expected
.append("\n");
5158 expected
.append(transaction
.response_headers
);
5159 EXPECT_EQ(expected
, headers
);
5161 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5162 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5163 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5165 // Verify that we don't have a cached entry.
5166 disk_cache::Entry
* entry
;
5167 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5169 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5172 // Tests that if a server tells us conflicting information about a resource we
5174 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
5175 MockHttpCache cache
;
5176 std::string headers
;
5178 MockTransaction
transaction(kRangeGET_TransactionOK
);
5179 transaction
.handler
= NULL
;
5180 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
5181 std::string
response_headers(transaction
.response_headers
);
5182 response_headers
.append("Content-Range: bytes 50-59/160\n");
5183 transaction
.response_headers
= response_headers
.c_str();
5184 AddMockTransaction(&transaction
);
5185 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5187 Verify206Response(headers
, 50, 59);
5188 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5189 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5190 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5192 RemoveMockTransaction(&transaction
);
5193 AddMockTransaction(&kRangeGET_TransactionOK
);
5195 // This transaction will report a resource size of 80 bytes, and we think it's
5196 // 160 so we should ignore the response.
5197 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5200 Verify206Response(headers
, 40, 49);
5201 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5202 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5203 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5205 // Verify that the entry is gone.
5206 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5207 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5208 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5209 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5212 // Tests that we handle large range values properly.
5213 TEST(HttpCache
, RangeGET_LargeValues
) {
5214 // We need a real sparse cache for this test.
5215 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
5216 std::string headers
;
5218 MockTransaction
transaction(kRangeGET_TransactionOK
);
5219 transaction
.handler
= NULL
;
5220 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
5222 transaction
.response_headers
=
5224 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5225 "Content-Length: 10\n";
5226 AddMockTransaction(&transaction
);
5227 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5229 std::string
expected(transaction
.status
);
5230 expected
.append("\n");
5231 expected
.append(transaction
.response_headers
);
5232 EXPECT_EQ(expected
, headers
);
5234 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5236 // Verify that we have a cached entry.
5237 disk_cache::Entry
* en
;
5238 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
5241 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5244 // Tests that we don't crash with a range request if the disk cache was not
5245 // initialized properly.
5246 TEST(HttpCache
, RangeGET_NoDiskCache
) {
5247 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
5248 factory
->set_fail(true);
5249 factory
->FinishCreation(); // We'll complete synchronously.
5250 MockHttpCache
cache(factory
);
5252 AddMockTransaction(&kRangeGET_TransactionOK
);
5254 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5255 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5257 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5260 // Tests that we handle byte range requests that skip the cache.
5261 TEST(HttpCache
, RangeHEAD
) {
5262 MockHttpCache cache
;
5263 AddMockTransaction(&kRangeGET_TransactionOK
);
5265 MockTransaction
transaction(kRangeGET_TransactionOK
);
5266 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5267 transaction
.method
= "HEAD";
5268 transaction
.data
= "rg: 70-79 ";
5270 std::string headers
;
5271 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5273 Verify206Response(headers
, 70, 79);
5274 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5275 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5276 EXPECT_EQ(0, cache
.disk_cache()->create_count());
5278 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5281 // Tests that we don't crash when after reading from the cache we issue a
5282 // request for the next range and the server gives us a 200 synchronously.
5283 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
5284 MockHttpCache cache
;
5286 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5287 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
5288 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
5289 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5291 // Write to the cache.
5292 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5294 // And now read from the cache and the network.
5295 RangeTransactionServer handler
;
5296 handler
.set_bad_200(true);
5297 transaction
.data
= "Not a range";
5298 net::CapturingBoundNetLog log
;
5299 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
5301 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
5302 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5303 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5304 EXPECT_TRUE(LogContainsEventType(
5305 log
, net::NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST
));
5308 // Tests that when the server gives us less data than expected, we don't keep
5309 // asking for more data.
5310 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
5311 MockHttpCache cache
;
5313 // First, check with an empty cache (WRITE mode).
5314 MockTransaction
transaction(kRangeGET_TransactionOK
);
5315 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
5316 transaction
.data
= "rg: 40-"; // Less than expected.
5317 transaction
.handler
= NULL
;
5318 std::string
headers(transaction
.response_headers
);
5319 headers
.append("Content-Range: bytes 40-49/80\n");
5320 transaction
.response_headers
= headers
.c_str();
5322 AddMockTransaction(&transaction
);
5324 // Write to the cache.
5325 RunTransactionTest(cache
.http_cache(), transaction
);
5327 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5328 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5329 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5331 // Now verify that even in READ_WRITE mode, we forward the bad response to
5333 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5334 transaction
.data
= "rg: 60-"; // Less than expected.
5335 headers
= kRangeGET_TransactionOK
.response_headers
;
5336 headers
.append("Content-Range: bytes 60-69/80\n");
5337 transaction
.response_headers
= headers
.c_str();
5339 RunTransactionTest(cache
.http_cache(), transaction
);
5341 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5342 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5343 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5345 RemoveMockTransaction(&transaction
);
5348 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5349 // This test hits a NOTREACHED so it is a release mode only test.
5350 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5351 MockHttpCache cache
;
5352 AddMockTransaction(&kRangeGET_TransactionOK
);
5354 // Write to the cache (40-49).
5355 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5356 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5357 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5358 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5360 // Force this transaction to read from the cache.
5361 MockTransaction
transaction(kRangeGET_TransactionOK
);
5362 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5364 MockHttpRequest
request(transaction
);
5365 net::TestCompletionCallback callback
;
5367 scoped_ptr
<net::HttpTransaction
> trans
;
5368 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
5369 EXPECT_EQ(net::OK
, rv
);
5370 ASSERT_TRUE(trans
.get());
5372 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5373 if (rv
== net::ERR_IO_PENDING
)
5374 rv
= callback
.WaitForResult();
5375 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5379 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5380 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5381 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5383 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5387 // Tests the handling of the "truncation" flag.
5388 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5389 MockHttpCache cache
;
5390 disk_cache::Entry
* entry
;
5391 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5394 std::string
headers("HTTP/1.1 200 OK");
5395 headers
= net::HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5396 net::HttpResponseInfo response
;
5397 response
.headers
= new net::HttpResponseHeaders(headers
);
5399 // Set the last argument for this to be an incomplete request.
5400 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5401 bool truncated
= false;
5402 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5403 EXPECT_TRUE(truncated
);
5405 // And now test the opposite case.
5406 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5408 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5409 EXPECT_FALSE(truncated
);
5413 // Tests basic pickling/unpickling of HttpResponseInfo.
5414 TEST(HttpCache
, PersistHttpResponseInfo
) {
5415 // Set some fields (add more if needed.)
5416 net::HttpResponseInfo response1
;
5417 response1
.was_cached
= false;
5418 response1
.socket_address
= net::HostPortPair("1.2.3.4", 80);
5419 response1
.headers
= new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5423 response1
.Persist(&pickle
, false, false);
5426 net::HttpResponseInfo response2
;
5427 bool response_truncated
;
5428 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5429 EXPECT_FALSE(response_truncated
);
5432 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5433 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5434 EXPECT_EQ(80, response2
.socket_address
.port());
5435 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5438 // Tests that we delete an entry when the request is cancelled before starting
5439 // to read from the network.
5440 TEST(HttpCache
, DoomOnDestruction
) {
5441 MockHttpCache cache
;
5443 MockHttpRequest
request(kSimpleGET_Transaction
);
5445 Context
* c
= new Context();
5446 int rv
= cache
.CreateTransaction(&c
->trans
);
5447 ASSERT_EQ(net::OK
, rv
);
5449 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5450 if (rv
== net::ERR_IO_PENDING
)
5451 c
->result
= c
->callback
.WaitForResult();
5453 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5454 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5455 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5457 // Destroy the transaction. We only have the headers so we should delete this
5461 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5463 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5464 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5465 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5468 // Tests that we delete an entry when the request is cancelled if the response
5469 // does not have content-length and strong validators.
5470 TEST(HttpCache
, DoomOnDestruction2
) {
5471 MockHttpCache cache
;
5473 MockHttpRequest
request(kSimpleGET_Transaction
);
5475 Context
* c
= new Context();
5476 int rv
= cache
.CreateTransaction(&c
->trans
);
5477 ASSERT_EQ(net::OK
, rv
);
5479 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5480 if (rv
== net::ERR_IO_PENDING
)
5481 rv
= c
->callback
.WaitForResult();
5483 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5484 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5485 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5487 // Make sure that the entry has some data stored.
5488 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5489 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5490 if (rv
== net::ERR_IO_PENDING
)
5491 rv
= c
->callback
.WaitForResult();
5492 EXPECT_EQ(buf
->size(), rv
);
5494 // Destroy the transaction.
5497 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5499 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5500 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5501 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5504 // Tests that we delete an entry when the request is cancelled if the response
5505 // has an "Accept-Ranges: none" header.
5506 TEST(HttpCache
, DoomOnDestruction3
) {
5507 MockHttpCache cache
;
5509 MockTransaction
transaction(kSimpleGET_Transaction
);
5510 transaction
.response_headers
=
5511 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5512 "Content-Length: 22\n"
5513 "Accept-Ranges: none\n"
5514 "Etag: \"foopy\"\n";
5515 AddMockTransaction(&transaction
);
5516 MockHttpRequest
request(transaction
);
5518 Context
* c
= new Context();
5519 int rv
= cache
.CreateTransaction(&c
->trans
);
5520 ASSERT_EQ(net::OK
, rv
);
5522 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5523 if (rv
== net::ERR_IO_PENDING
)
5524 rv
= c
->callback
.WaitForResult();
5526 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5527 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5528 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5530 // Make sure that the entry has some data stored.
5531 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5532 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5533 if (rv
== net::ERR_IO_PENDING
)
5534 rv
= c
->callback
.WaitForResult();
5535 EXPECT_EQ(buf
->size(), rv
);
5537 // Destroy the transaction.
5540 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5542 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5543 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5544 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5546 RemoveMockTransaction(&transaction
);
5549 // Tests that we mark an entry as incomplete when the request is cancelled.
5550 TEST(HttpCache
, SetTruncatedFlag
) {
5551 MockHttpCache cache
;
5553 MockTransaction
transaction(kSimpleGET_Transaction
);
5554 transaction
.response_headers
=
5555 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5556 "Content-Length: 22\n"
5557 "Etag: \"foopy\"\n";
5558 AddMockTransaction(&transaction
);
5559 MockHttpRequest
request(transaction
);
5561 scoped_ptr
<Context
> c(new Context());
5563 int rv
= cache
.CreateTransaction(&c
->trans
);
5564 ASSERT_EQ(net::OK
, rv
);
5566 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5567 if (rv
== net::ERR_IO_PENDING
)
5568 rv
= c
->callback
.WaitForResult();
5570 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5571 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5572 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5574 // Make sure that the entry has some data stored.
5575 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5576 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5577 if (rv
== net::ERR_IO_PENDING
)
5578 rv
= c
->callback
.WaitForResult();
5579 EXPECT_EQ(buf
->size(), rv
);
5581 // We want to cancel the request when the transaction is busy.
5582 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5583 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5584 EXPECT_FALSE(c
->callback
.have_result());
5586 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5588 // Destroy the transaction.
5590 MockHttpCache::SetTestMode(0);
5593 // Make sure that we don't invoke the callback. We may have an issue if the
5594 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5595 // could end up with the transaction being deleted twice if we send any
5596 // notification from the transaction destructor (see http://crbug.com/31723).
5597 EXPECT_FALSE(c
->callback
.have_result());
5599 // Verify that the entry is marked as incomplete.
5600 disk_cache::Entry
* entry
;
5601 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5602 net::HttpResponseInfo response
;
5603 bool truncated
= false;
5604 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5605 EXPECT_TRUE(truncated
);
5608 RemoveMockTransaction(&transaction
);
5611 // Tests that we don't mark an entry as truncated when we read everything.
5612 TEST(HttpCache
, DontSetTruncatedFlag
) {
5613 MockHttpCache cache
;
5615 MockTransaction
transaction(kSimpleGET_Transaction
);
5616 transaction
.response_headers
=
5617 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5618 "Content-Length: 22\n"
5619 "Etag: \"foopy\"\n";
5620 AddMockTransaction(&transaction
);
5621 MockHttpRequest
request(transaction
);
5623 scoped_ptr
<Context
> c(new Context());
5624 int rv
= cache
.CreateTransaction(&c
->trans
);
5625 ASSERT_EQ(net::OK
, rv
);
5627 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5628 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5631 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(22));
5632 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5633 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5635 // Destroy the transaction.
5638 // Verify that the entry is not marked as truncated.
5639 disk_cache::Entry
* entry
;
5640 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5641 net::HttpResponseInfo response
;
5642 bool truncated
= true;
5643 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5644 EXPECT_FALSE(truncated
);
5647 RemoveMockTransaction(&transaction
);
5650 // Tests that we can continue with a request that was interrupted.
5651 TEST(HttpCache
, GET_IncompleteResource
) {
5652 MockHttpCache cache
;
5653 AddMockTransaction(&kRangeGET_TransactionOK
);
5655 std::string
raw_headers("HTTP/1.1 200 OK\n"
5656 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5658 "Accept-Ranges: bytes\n"
5659 "Content-Length: 80\n");
5660 CreateTruncatedEntry(raw_headers
, &cache
);
5662 // Now make a regular request.
5663 std::string headers
;
5664 MockTransaction
transaction(kRangeGET_TransactionOK
);
5665 transaction
.request_headers
= EXTRA_HEADER
;
5666 transaction
.data
= kFullRangeData
;
5667 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5669 // We update the headers with the ones received while revalidating.
5670 std::string
expected_headers(
5672 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5673 "Accept-Ranges: bytes\n"
5675 "Content-Length: 80\n");
5677 EXPECT_EQ(expected_headers
, headers
);
5678 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5679 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5680 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5682 // Verify that the disk entry was updated.
5683 disk_cache::Entry
* entry
;
5684 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5685 EXPECT_EQ(80, entry
->GetDataSize(1));
5686 bool truncated
= true;
5687 net::HttpResponseInfo response
;
5688 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5689 EXPECT_FALSE(truncated
);
5692 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5695 // Tests the handling of no-store when revalidating a truncated entry.
5696 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5697 MockHttpCache cache
;
5698 AddMockTransaction(&kRangeGET_TransactionOK
);
5700 std::string
raw_headers("HTTP/1.1 200 OK\n"
5701 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5703 "Accept-Ranges: bytes\n"
5704 "Content-Length: 80\n");
5705 CreateTruncatedEntry(raw_headers
, &cache
);
5706 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5708 // Now make a regular request.
5709 MockTransaction
transaction(kRangeGET_TransactionOK
);
5710 transaction
.request_headers
= EXTRA_HEADER
;
5711 std::string
response_headers(transaction
.response_headers
);
5712 response_headers
+= ("Cache-Control: no-store\n");
5713 transaction
.response_headers
= response_headers
.c_str();
5714 transaction
.data
= kFullRangeData
;
5715 AddMockTransaction(&transaction
);
5717 std::string headers
;
5718 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5720 // We update the headers with the ones received while revalidating.
5721 std::string
expected_headers(
5723 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5724 "Accept-Ranges: bytes\n"
5725 "Cache-Control: no-store\n"
5727 "Content-Length: 80\n");
5729 EXPECT_EQ(expected_headers
, headers
);
5730 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5731 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5732 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5734 // Verify that the disk entry was deleted.
5735 disk_cache::Entry
* entry
;
5736 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5737 RemoveMockTransaction(&transaction
);
5740 // Tests cancelling a request after the server sent no-store.
5741 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5742 MockHttpCache cache
;
5743 AddMockTransaction(&kRangeGET_TransactionOK
);
5745 std::string
raw_headers("HTTP/1.1 200 OK\n"
5746 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5748 "Accept-Ranges: bytes\n"
5749 "Content-Length: 80\n");
5750 CreateTruncatedEntry(raw_headers
, &cache
);
5751 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5753 // Now make a regular request.
5754 MockTransaction
transaction(kRangeGET_TransactionOK
);
5755 transaction
.request_headers
= EXTRA_HEADER
;
5756 std::string
response_headers(transaction
.response_headers
);
5757 response_headers
+= ("Cache-Control: no-store\n");
5758 transaction
.response_headers
= response_headers
.c_str();
5759 transaction
.data
= kFullRangeData
;
5760 AddMockTransaction(&transaction
);
5762 MockHttpRequest
request(transaction
);
5763 Context
* c
= new Context();
5765 int rv
= cache
.CreateTransaction(&c
->trans
);
5766 ASSERT_EQ(net::OK
, rv
);
5768 // Queue another request to this transaction. We have to start this request
5769 // before the first one gets the response from the server and dooms the entry,
5770 // otherwise it will just create a new entry without being queued to the first
5772 Context
* pending
= new Context();
5773 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&pending
->trans
));
5775 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5776 EXPECT_EQ(net::ERR_IO_PENDING
,
5777 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5778 net::BoundNetLog()));
5779 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5781 // Make sure that the entry has some data stored.
5782 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5783 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5784 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5786 // Cancel the requests.
5790 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5791 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5792 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5794 base::MessageLoop::current()->RunUntilIdle();
5795 RemoveMockTransaction(&transaction
);
5798 // Tests that we delete truncated entries if the server changes its mind midway.
5799 TEST(HttpCache
, GET_IncompleteResource2
) {
5800 MockHttpCache cache
;
5801 AddMockTransaction(&kRangeGET_TransactionOK
);
5803 // Content-length will be intentionally bad.
5804 std::string
raw_headers("HTTP/1.1 200 OK\n"
5805 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5807 "Accept-Ranges: bytes\n"
5808 "Content-Length: 50\n");
5809 CreateTruncatedEntry(raw_headers
, &cache
);
5811 // Now make a regular request. We expect the code to fail the validation and
5812 // retry the request without using byte ranges.
5813 std::string headers
;
5814 MockTransaction
transaction(kRangeGET_TransactionOK
);
5815 transaction
.request_headers
= EXTRA_HEADER
;
5816 transaction
.data
= "Not a range";
5817 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5819 // The server will return 200 instead of a byte range.
5820 std::string
expected_headers(
5822 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5824 EXPECT_EQ(expected_headers
, headers
);
5825 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5826 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5827 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5829 // Verify that the disk entry was deleted.
5830 disk_cache::Entry
* entry
;
5831 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5832 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5835 // Tests that we always validate a truncated request.
5836 TEST(HttpCache
, GET_IncompleteResource3
) {
5837 MockHttpCache cache
;
5838 AddMockTransaction(&kRangeGET_TransactionOK
);
5840 // This should not require validation for 10 hours.
5841 std::string
raw_headers("HTTP/1.1 200 OK\n"
5842 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5844 "Cache-Control: max-age= 36000\n"
5845 "Accept-Ranges: bytes\n"
5846 "Content-Length: 80\n");
5847 CreateTruncatedEntry(raw_headers
, &cache
);
5849 // Now make a regular request.
5850 std::string headers
;
5851 MockTransaction
transaction(kRangeGET_TransactionOK
);
5852 transaction
.request_headers
= EXTRA_HEADER
;
5853 transaction
.data
= kFullRangeData
;
5855 scoped_ptr
<Context
> c(new Context
);
5856 int rv
= cache
.CreateTransaction(&c
->trans
);
5857 ASSERT_EQ(net::OK
, rv
);
5859 MockHttpRequest
request(transaction
);
5860 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5861 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5863 // We should have checked with the server before finishing Start().
5864 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5865 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5866 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5868 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5871 // Tests that we handle 401s for truncated resources.
5872 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
5873 MockHttpCache cache
;
5874 AddMockTransaction(&kRangeGET_TransactionOK
);
5876 std::string
raw_headers("HTTP/1.1 200 OK\n"
5877 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5879 "Accept-Ranges: bytes\n"
5880 "Content-Length: 80\n");
5881 CreateTruncatedEntry(raw_headers
, &cache
);
5883 // Now make a regular request.
5884 MockTransaction
transaction(kRangeGET_TransactionOK
);
5885 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
5887 transaction
.data
= kFullRangeData
;
5888 RangeTransactionServer handler
;
5890 scoped_ptr
<Context
> c(new Context
);
5891 int rv
= cache
.CreateTransaction(&c
->trans
);
5892 ASSERT_EQ(net::OK
, rv
);
5894 MockHttpRequest
request(transaction
);
5895 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5896 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5898 const net::HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
5899 ASSERT_TRUE(response
);
5900 ASSERT_EQ(401, response
->headers
->response_code());
5901 rv
= c
->trans
->RestartWithAuth(net::AuthCredentials(),
5902 c
->callback
.callback());
5903 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5904 response
= c
->trans
->GetResponseInfo();
5905 ASSERT_TRUE(response
);
5906 ASSERT_EQ(200, response
->headers
->response_code());
5908 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
5909 c
.reset(); // The destructor could delete the entry.
5910 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5912 // Verify that the entry was not deleted.
5913 disk_cache::Entry
* entry
;
5914 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5917 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5920 // Tests that we cache a 200 response to the validation request.
5921 TEST(HttpCache
, GET_IncompleteResource4
) {
5922 MockHttpCache cache
;
5923 AddMockTransaction(&kRangeGET_TransactionOK
);
5925 std::string
raw_headers("HTTP/1.1 200 OK\n"
5926 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5928 "Accept-Ranges: bytes\n"
5929 "Content-Length: 80\n");
5930 CreateTruncatedEntry(raw_headers
, &cache
);
5932 // Now make a regular request.
5933 std::string headers
;
5934 MockTransaction
transaction(kRangeGET_TransactionOK
);
5935 transaction
.request_headers
= EXTRA_HEADER
;
5936 transaction
.data
= "Not a range";
5937 RangeTransactionServer handler
;
5938 handler
.set_bad_200(true);
5939 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5941 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5942 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5943 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5945 // Verify that the disk entry was updated.
5946 disk_cache::Entry
* entry
;
5947 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5948 EXPECT_EQ(11, entry
->GetDataSize(1));
5949 bool truncated
= true;
5950 net::HttpResponseInfo response
;
5951 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5952 EXPECT_FALSE(truncated
);
5955 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5958 // Tests that when we cancel a request that was interrupted, we mark it again
5960 TEST(HttpCache
, GET_CancelIncompleteResource
) {
5961 MockHttpCache cache
;
5962 AddMockTransaction(&kRangeGET_TransactionOK
);
5964 std::string
raw_headers("HTTP/1.1 200 OK\n"
5965 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5967 "Accept-Ranges: bytes\n"
5968 "Content-Length: 80\n");
5969 CreateTruncatedEntry(raw_headers
, &cache
);
5971 // Now make a regular request.
5972 MockTransaction
transaction(kRangeGET_TransactionOK
);
5973 transaction
.request_headers
= EXTRA_HEADER
;
5975 MockHttpRequest
request(transaction
);
5976 Context
* c
= new Context();
5977 int rv
= cache
.CreateTransaction(&c
->trans
);
5978 ASSERT_EQ(net::OK
, rv
);
5980 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5981 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5983 // Read 20 bytes from the cache, and 10 from the net.
5984 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
5985 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
5986 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
5987 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
5988 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
5990 // At this point, we are already reading so canceling the request should leave
5994 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5995 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5996 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5998 // Verify that the disk entry was updated: now we have 30 bytes.
5999 disk_cache::Entry
* entry
;
6000 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6001 EXPECT_EQ(30, entry
->GetDataSize(1));
6002 bool truncated
= false;
6003 net::HttpResponseInfo response
;
6004 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6005 EXPECT_TRUE(truncated
);
6007 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6010 // Tests that we can handle range requests when we have a truncated entry.
6011 TEST(HttpCache
, RangeGET_IncompleteResource
) {
6012 MockHttpCache cache
;
6013 AddMockTransaction(&kRangeGET_TransactionOK
);
6015 // Content-length will be intentionally bogus.
6016 std::string
raw_headers("HTTP/1.1 200 OK\n"
6017 "Last-Modified: something\n"
6019 "Accept-Ranges: bytes\n"
6020 "Content-Length: 10\n");
6021 CreateTruncatedEntry(raw_headers
, &cache
);
6023 // Now make a range request.
6024 std::string headers
;
6025 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
6028 Verify206Response(headers
, 40, 49);
6029 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6030 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6031 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6033 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6036 TEST(HttpCache
, SyncRead
) {
6037 MockHttpCache cache
;
6039 // This test ensures that a read that completes synchronously does not cause
6042 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6043 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
6044 TEST_MODE_SYNC_CACHE_READ
|
6045 TEST_MODE_SYNC_CACHE_WRITE
);
6047 MockHttpRequest
r1(transaction
),
6051 TestTransactionConsumer
c1(net::DEFAULT_PRIORITY
, cache
.http_cache()),
6052 c2(net::DEFAULT_PRIORITY
, cache
.http_cache()),
6053 c3(net::DEFAULT_PRIORITY
, cache
.http_cache());
6055 c1
.Start(&r1
, net::BoundNetLog());
6057 r2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
6058 c2
.Start(&r2
, net::BoundNetLog());
6060 r3
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
6061 c3
.Start(&r3
, net::BoundNetLog());
6063 base::MessageLoop::current()->Run();
6065 EXPECT_TRUE(c1
.is_done());
6066 EXPECT_TRUE(c2
.is_done());
6067 EXPECT_TRUE(c3
.is_done());
6069 EXPECT_EQ(net::OK
, c1
.error());
6070 EXPECT_EQ(net::OK
, c2
.error());
6071 EXPECT_EQ(net::OK
, c3
.error());
6074 TEST(HttpCache
, ValidationResultsIn200
) {
6075 MockHttpCache cache
;
6077 // This test ensures that a conditional request, which results in a 200
6078 // instead of a 304, properly truncates the existing response data.
6080 // write to the cache
6081 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6083 // force this transaction to validate the cache
6084 MockTransaction
transaction(kETagGET_Transaction
);
6085 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
6086 RunTransactionTest(cache
.http_cache(), transaction
);
6088 // read from the cache
6089 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6092 TEST(HttpCache
, CachedRedirect
) {
6093 MockHttpCache cache
;
6095 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
6096 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
6097 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
6099 MockHttpRequest
request(kTestTransaction
);
6100 net::TestCompletionCallback callback
;
6102 // Write to the cache.
6104 scoped_ptr
<net::HttpTransaction
> trans
;
6105 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6107 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6108 if (rv
== net::ERR_IO_PENDING
)
6109 rv
= callback
.WaitForResult();
6110 ASSERT_EQ(net::OK
, rv
);
6112 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
6115 EXPECT_EQ(info
->headers
->response_code(), 301);
6117 std::string location
;
6118 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6119 EXPECT_EQ(location
, "http://www.bar.com/");
6121 // Mark the transaction as completed so it is cached.
6122 trans
->DoneReading();
6124 // Destroy transaction when going out of scope. We have not actually
6125 // read the response body -- want to test that it is still getting cached.
6127 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6128 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6129 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6131 // Active entries in the cache are not retired synchronously. Make
6132 // sure the next run hits the MockHttpCache and open_count is
6134 base::MessageLoop::current()->RunUntilIdle();
6136 // Read from the cache.
6138 scoped_ptr
<net::HttpTransaction
> trans
;
6139 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6141 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6142 if (rv
== net::ERR_IO_PENDING
)
6143 rv
= callback
.WaitForResult();
6144 ASSERT_EQ(net::OK
, rv
);
6146 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
6149 EXPECT_EQ(info
->headers
->response_code(), 301);
6151 std::string location
;
6152 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6153 EXPECT_EQ(location
, "http://www.bar.com/");
6155 // Mark the transaction as completed so it is cached.
6156 trans
->DoneReading();
6158 // Destroy transaction when going out of scope. We have not actually
6159 // read the response body -- want to test that it is still getting cached.
6161 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6162 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6163 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6166 // Verify that no-cache resources are stored in cache, but are not fetched from
6167 // cache during normal loads.
6168 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
6169 MockHttpCache cache
;
6171 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6172 transaction
.response_headers
= "cache-control: no-cache\n";
6175 RunTransactionTest(cache
.http_cache(), transaction
);
6177 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6178 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6179 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6181 // Try loading again; it should result in a network fetch.
6182 RunTransactionTest(cache
.http_cache(), transaction
);
6184 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6185 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6186 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6188 disk_cache::Entry
* entry
;
6189 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6193 // Verify that no-cache resources are stored in cache and fetched from cache
6194 // when the LOAD_PREFERRING_CACHE flag is set.
6195 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
6196 MockHttpCache cache
;
6198 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6199 transaction
.response_headers
= "cache-control: no-cache\n";
6202 RunTransactionTest(cache
.http_cache(), transaction
);
6204 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6205 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6206 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6208 // Try loading again with LOAD_PREFERRING_CACHE.
6209 transaction
.load_flags
= net::LOAD_PREFERRING_CACHE
;
6210 RunTransactionTest(cache
.http_cache(), transaction
);
6212 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6213 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6214 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6216 disk_cache::Entry
* entry
;
6217 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6221 TEST(HttpCache
, CacheControlNoStore
) {
6222 MockHttpCache cache
;
6224 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6225 transaction
.response_headers
= "cache-control: no-store\n";
6228 RunTransactionTest(cache
.http_cache(), transaction
);
6230 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6231 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6232 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6234 // try loading again; it should result in a network fetch
6235 RunTransactionTest(cache
.http_cache(), transaction
);
6237 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6238 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6239 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6241 disk_cache::Entry
* entry
;
6242 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6245 TEST(HttpCache
, CacheControlNoStore2
) {
6246 // this test is similar to the above test, except that the initial response
6247 // is cachable, but when it is validated, no-store is received causing the
6248 // cached document to be deleted.
6249 MockHttpCache cache
;
6251 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6254 RunTransactionTest(cache
.http_cache(), transaction
);
6256 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6257 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6258 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6260 // try loading again; it should result in a network fetch
6261 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6262 transaction
.response_headers
= "cache-control: no-store\n";
6263 RunTransactionTest(cache
.http_cache(), transaction
);
6265 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6266 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6267 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6269 disk_cache::Entry
* entry
;
6270 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6273 TEST(HttpCache
, CacheControlNoStore3
) {
6274 // this test is similar to the above test, except that the response is a 304
6275 // instead of a 200. this should never happen in practice, but it seems like
6276 // a good thing to verify that we still destroy the cache entry.
6277 MockHttpCache cache
;
6279 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6282 RunTransactionTest(cache
.http_cache(), transaction
);
6284 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6285 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6286 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6288 // try loading again; it should result in a network fetch
6289 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6290 transaction
.response_headers
= "cache-control: no-store\n";
6291 transaction
.status
= "HTTP/1.1 304 Not Modified";
6292 RunTransactionTest(cache
.http_cache(), transaction
);
6294 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6295 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6296 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6298 disk_cache::Entry
* entry
;
6299 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6302 // Ensure that we don't cache requests served over bad HTTPS.
6303 TEST(HttpCache
, SimpleGET_SSLError
) {
6304 MockHttpCache cache
;
6306 MockTransaction transaction
= kSimpleGET_Transaction
;
6307 transaction
.cert_status
= net::CERT_STATUS_REVOKED
;
6308 ScopedMockTransaction
scoped_transaction(transaction
);
6310 // write to the cache
6311 RunTransactionTest(cache
.http_cache(), transaction
);
6313 // Test that it was not cached.
6314 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
6316 MockHttpRequest
request(transaction
);
6317 net::TestCompletionCallback callback
;
6319 scoped_ptr
<net::HttpTransaction
> trans
;
6320 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6322 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6323 if (rv
== net::ERR_IO_PENDING
)
6324 rv
= callback
.WaitForResult();
6325 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
6328 // Ensure that we don't crash by if left-behind transactions.
6329 TEST(HttpCache
, OutlivedTransactions
) {
6330 MockHttpCache
* cache
= new MockHttpCache
;
6332 scoped_ptr
<net::HttpTransaction
> trans
;
6333 EXPECT_EQ(net::OK
, cache
->CreateTransaction(&trans
));
6339 // Test that the disabled mode works.
6340 TEST(HttpCache
, CacheDisabledMode
) {
6341 MockHttpCache cache
;
6343 // write to the cache
6344 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6346 // go into disabled mode
6347 cache
.http_cache()->set_mode(net::HttpCache::DISABLE
);
6349 // force this transaction to write to the cache again
6350 MockTransaction
transaction(kSimpleGET_Transaction
);
6352 RunTransactionTest(cache
.http_cache(), transaction
);
6354 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6355 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6356 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6359 // Other tests check that the response headers of the cached response
6360 // get updated on 304. Here we specifically check that the
6361 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6362 // fields also gets updated.
6363 // http://crbug.com/20594.
6364 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6365 MockHttpCache cache
;
6367 const char* kUrl
= "http://foobar";
6368 const char* kData
= "body";
6370 MockTransaction mock_network_response
= { 0 };
6371 mock_network_response
.url
= kUrl
;
6373 AddMockTransaction(&mock_network_response
);
6375 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6377 MockTransaction request
= { 0 };
6379 request
.method
= "GET";
6380 request
.request_headers
= "\r\n";
6381 request
.data
= kData
;
6383 static const Response kNetResponse1
= {
6385 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6386 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6390 kNetResponse1
.AssignTo(&mock_network_response
);
6392 RunTransactionTest(cache
.http_cache(), request
);
6394 // Request |kUrl| again, this time validating the cache and getting
6397 request
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6399 static const Response kNetResponse2
= {
6400 "HTTP/1.1 304 Not Modified",
6401 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6405 kNetResponse2
.AssignTo(&mock_network_response
);
6407 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6408 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6410 mock_network_response
.request_time
= request_time
;
6411 mock_network_response
.response_time
= response_time
;
6413 net::HttpResponseInfo response
;
6414 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6416 // The request and response times should have been updated.
6417 EXPECT_EQ(request_time
.ToInternalValue(),
6418 response
.request_time
.ToInternalValue());
6419 EXPECT_EQ(response_time
.ToInternalValue(),
6420 response
.response_time
.ToInternalValue());
6422 std::string headers
;
6423 response
.headers
->GetNormalizedHeaders(&headers
);
6425 EXPECT_EQ("HTTP/1.1 200 OK\n"
6426 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6427 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6430 RemoveMockTransaction(&mock_network_response
);
6433 // Tests that we can write metadata to an entry.
6434 TEST(HttpCache
, WriteMetadata_OK
) {
6435 MockHttpCache cache
;
6437 // Write to the cache
6438 net::HttpResponseInfo response
;
6439 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6441 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6444 cache
.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY
,
6445 Time::Now(), NULL
, 0);
6447 // Write meta data to the same entry.
6448 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6449 memset(buf
->data(), 0, buf
->size());
6450 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6451 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6452 net::DEFAULT_PRIORITY
,
6453 response
.response_time
,
6457 // Release the buffer before the operation takes place.
6460 // Makes sure we finish pending operations.
6461 base::MessageLoop::current()->RunUntilIdle();
6463 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6465 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6466 EXPECT_EQ(50, response
.metadata
->size());
6467 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6469 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6470 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6471 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6474 // Tests that we only write metadata to an entry if the time stamp matches.
6475 TEST(HttpCache
, WriteMetadata_Fail
) {
6476 MockHttpCache cache
;
6478 // Write to the cache
6479 net::HttpResponseInfo response
;
6480 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6482 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6484 // Attempt to write meta data to the same entry.
6485 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6486 memset(buf
->data(), 0, buf
->size());
6487 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6488 base::Time expected_time
= response
.response_time
-
6489 base::TimeDelta::FromMilliseconds(20);
6490 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6491 net::DEFAULT_PRIORITY
,
6496 // Makes sure we finish pending operations.
6497 base::MessageLoop::current()->RunUntilIdle();
6499 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6501 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6503 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6504 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6505 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6508 // Tests that we can read metadata after validating the entry and with READ mode
6510 TEST(HttpCache
, ReadMetadata
) {
6511 MockHttpCache cache
;
6513 // Write to the cache
6514 net::HttpResponseInfo response
;
6515 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6516 kTypicalGET_Transaction
, &response
);
6517 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6519 // Write meta data to the same entry.
6520 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6521 memset(buf
->data(), 0, buf
->size());
6522 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6523 cache
.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction
.url
),
6524 net::DEFAULT_PRIORITY
,
6525 response
.response_time
,
6529 // Makes sure we finish pending operations.
6530 base::MessageLoop::current()->RunUntilIdle();
6532 // Start with a READ mode transaction.
6533 MockTransaction
trans1(kTypicalGET_Transaction
);
6534 trans1
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
6536 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6537 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6538 EXPECT_EQ(50, response
.metadata
->size());
6539 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6541 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6542 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6543 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6544 base::MessageLoop::current()->RunUntilIdle();
6546 // Now make sure that the entry is re-validated with the server.
6547 trans1
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6548 trans1
.status
= "HTTP/1.1 304 Not Modified";
6549 AddMockTransaction(&trans1
);
6551 response
.metadata
= NULL
;
6552 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6553 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6555 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6556 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6557 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6558 base::MessageLoop::current()->RunUntilIdle();
6559 RemoveMockTransaction(&trans1
);
6561 // Now return 200 when validating the entry so the metadata will be lost.
6562 MockTransaction
trans2(kTypicalGET_Transaction
);
6563 trans2
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6564 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6565 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6567 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6568 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6569 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6572 // Tests that we don't mark entries as truncated when a filter detects the end
6574 TEST(HttpCache
, FilterCompletion
) {
6575 MockHttpCache cache
;
6576 net::TestCompletionCallback callback
;
6579 scoped_ptr
<net::HttpTransaction
> trans
;
6580 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6582 MockHttpRequest
request(kSimpleGET_Transaction
);
6583 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6584 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6586 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6587 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6588 EXPECT_GT(callback
.GetResult(rv
), 0);
6590 // Now make sure that the entry is preserved.
6591 trans
->DoneReading();
6594 // Make sure that the ActiveEntry is gone.
6595 base::MessageLoop::current()->RunUntilIdle();
6597 // Read from the cache.
6598 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6600 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6601 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6602 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6605 // Tests that we don't mark entries as truncated and release the cache
6606 // entry when DoneReading() is called before any Read() calls, such as
6608 TEST(HttpCache
, DoneReading
) {
6609 MockHttpCache cache
;
6610 net::TestCompletionCallback callback
;
6612 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6613 transaction
.data
= "";
6615 scoped_ptr
<net::HttpTransaction
> trans
;
6616 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6618 MockHttpRequest
request(transaction
);
6619 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6620 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6622 trans
->DoneReading();
6623 // Leave the transaction around.
6625 // Make sure that the ActiveEntry is gone.
6626 base::MessageLoop::current()->RunUntilIdle();
6628 // Read from the cache. This should not deadlock.
6629 RunTransactionTest(cache
.http_cache(), transaction
);
6631 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6632 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6633 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6636 // Tests that we stop caching when told.
6637 TEST(HttpCache
, StopCachingDeletesEntry
) {
6638 MockHttpCache cache
;
6639 net::TestCompletionCallback callback
;
6640 MockHttpRequest
request(kSimpleGET_Transaction
);
6643 scoped_ptr
<net::HttpTransaction
> trans
;
6644 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6646 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6647 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6649 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6650 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6651 EXPECT_EQ(10, callback
.GetResult(rv
));
6653 trans
->StopCaching();
6655 // We should be able to keep reading.
6656 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6657 EXPECT_GT(callback
.GetResult(rv
), 0);
6658 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6659 EXPECT_EQ(0, callback
.GetResult(rv
));
6662 // Make sure that the ActiveEntry is gone.
6663 base::MessageLoop::current()->RunUntilIdle();
6665 // Verify that the entry is gone.
6666 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6668 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6669 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6670 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6673 // Tests that we stop caching when told, even if DoneReading is called
6674 // after StopCaching.
6675 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6676 MockHttpCache cache
;
6677 net::TestCompletionCallback callback
;
6678 MockHttpRequest
request(kSimpleGET_Transaction
);
6681 scoped_ptr
<net::HttpTransaction
> trans
;
6682 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6684 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6685 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6687 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6688 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6689 EXPECT_EQ(10, callback
.GetResult(rv
));
6691 trans
->StopCaching();
6693 // We should be able to keep reading.
6694 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6695 EXPECT_GT(callback
.GetResult(rv
), 0);
6696 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6697 EXPECT_EQ(0, callback
.GetResult(rv
));
6699 // We should be able to call DoneReading.
6700 trans
->DoneReading();
6703 // Make sure that the ActiveEntry is gone.
6704 base::MessageLoop::current()->RunUntilIdle();
6706 // Verify that the entry is gone.
6707 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6709 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6710 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6711 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6714 // Tests that we stop caching when told, when using auth.
6715 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6716 MockHttpCache cache
;
6717 net::TestCompletionCallback callback
;
6718 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6719 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6720 AddMockTransaction(&mock_transaction
);
6721 MockHttpRequest
request(mock_transaction
);
6724 scoped_ptr
<net::HttpTransaction
> trans
;
6725 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6727 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6728 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6730 trans
->StopCaching();
6732 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6733 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6734 EXPECT_EQ(callback
.GetResult(rv
), 10);
6736 RemoveMockTransaction(&mock_transaction
);
6738 // Make sure that the ActiveEntry is gone.
6739 base::MessageLoop::current()->RunUntilIdle();
6741 // Verify that the entry is gone.
6742 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6744 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6745 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6746 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6749 // Tests that when we are told to stop caching we don't throw away valid data.
6750 TEST(HttpCache
, StopCachingSavesEntry
) {
6751 MockHttpCache cache
;
6752 net::TestCompletionCallback callback
;
6753 MockHttpRequest
request(kSimpleGET_Transaction
);
6756 scoped_ptr
<net::HttpTransaction
> trans
;
6757 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6759 // Force a response that can be resumed.
6760 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6761 AddMockTransaction(&mock_transaction
);
6762 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6763 "Content-Length: 42\n"
6766 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6767 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6769 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6770 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6771 EXPECT_EQ(callback
.GetResult(rv
), 10);
6773 trans
->StopCaching();
6775 // We should be able to keep reading.
6776 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6777 EXPECT_GT(callback
.GetResult(rv
), 0);
6778 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6779 EXPECT_EQ(callback
.GetResult(rv
), 0);
6781 RemoveMockTransaction(&mock_transaction
);
6784 // Verify that the entry is marked as incomplete.
6785 disk_cache::Entry
* entry
;
6786 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6787 net::HttpResponseInfo response
;
6788 bool truncated
= false;
6789 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6790 EXPECT_TRUE(truncated
);
6794 // Tests that we handle truncated enries when StopCaching is called.
6795 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6796 MockHttpCache cache
;
6797 net::TestCompletionCallback callback
;
6798 MockHttpRequest
request(kRangeGET_TransactionOK
);
6799 request
.extra_headers
.Clear();
6800 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6801 AddMockTransaction(&kRangeGET_TransactionOK
);
6803 std::string
raw_headers("HTTP/1.1 200 OK\n"
6804 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6806 "Accept-Ranges: bytes\n"
6807 "Content-Length: 80\n");
6808 CreateTruncatedEntry(raw_headers
, &cache
);
6811 // Now make a regular request.
6812 scoped_ptr
<net::HttpTransaction
> trans
;
6813 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6815 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6816 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6818 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6819 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6820 EXPECT_EQ(callback
.GetResult(rv
), 10);
6822 // This is actually going to do nothing.
6823 trans
->StopCaching();
6825 // We should be able to keep reading.
6826 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6827 EXPECT_GT(callback
.GetResult(rv
), 0);
6828 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6829 EXPECT_GT(callback
.GetResult(rv
), 0);
6830 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6831 EXPECT_EQ(callback
.GetResult(rv
), 0);
6834 // Verify that the disk entry was updated.
6835 disk_cache::Entry
* entry
;
6836 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6837 EXPECT_EQ(80, entry
->GetDataSize(1));
6838 bool truncated
= true;
6839 net::HttpResponseInfo response
;
6840 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6841 EXPECT_FALSE(truncated
);
6844 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6847 // Tests that we detect truncated resources from the net when there is
6848 // a Content-Length header.
6849 TEST(HttpCache
, TruncatedByContentLength
) {
6850 MockHttpCache cache
;
6851 net::TestCompletionCallback callback
;
6853 MockTransaction
transaction(kSimpleGET_Transaction
);
6854 AddMockTransaction(&transaction
);
6855 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6856 "Content-Length: 100\n";
6857 RunTransactionTest(cache
.http_cache(), transaction
);
6858 RemoveMockTransaction(&transaction
);
6860 // Read from the cache.
6861 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6863 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6864 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6865 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6868 // Tests that we actually flag entries as truncated when we detect an error
6870 TEST(HttpCache
, TruncatedByContentLength2
) {
6871 MockHttpCache cache
;
6872 net::TestCompletionCallback callback
;
6874 MockTransaction
transaction(kSimpleGET_Transaction
);
6875 AddMockTransaction(&transaction
);
6876 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6877 "Content-Length: 100\n"
6879 RunTransactionTest(cache
.http_cache(), transaction
);
6880 RemoveMockTransaction(&transaction
);
6882 // Verify that the entry is marked as incomplete.
6883 disk_cache::Entry
* entry
;
6884 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6885 net::HttpResponseInfo response
;
6886 bool truncated
= false;
6887 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6888 EXPECT_TRUE(truncated
);
6892 // Make sure that calling SetPriority on a cache transaction passes on
6893 // its priority updates to its underlying network transaction.
6894 TEST(HttpCache
, SetPriority
) {
6895 MockHttpCache cache
;
6897 scoped_ptr
<net::HttpTransaction
> trans
;
6898 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6900 // Shouldn't crash, but doesn't do anything either.
6901 trans
->SetPriority(net::LOW
);
6903 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6904 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6905 cache
.network_layer()->last_create_transaction_priority());
6907 net::HttpRequestInfo info
;
6908 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6909 net::TestCompletionCallback callback
;
6910 EXPECT_EQ(net::ERR_IO_PENDING
,
6911 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6913 EXPECT_TRUE(cache
.network_layer()->last_transaction());
6914 if (cache
.network_layer()->last_transaction()) {
6916 cache
.network_layer()->last_create_transaction_priority());
6918 cache
.network_layer()->last_transaction()->priority());
6921 trans
->SetPriority(net::HIGHEST
);
6923 if (cache
.network_layer()->last_transaction()) {
6925 cache
.network_layer()->last_create_transaction_priority());
6926 EXPECT_EQ(net::HIGHEST
,
6927 cache
.network_layer()->last_transaction()->priority());
6930 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6933 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6934 // transaction passes on its argument to the underlying network transaction.
6935 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
6936 MockHttpCache cache
;
6938 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
6939 scoped_ptr
<net::HttpTransaction
> trans
;
6940 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
6942 EXPECT_FALSE(cache
.network_layer()->last_transaction());
6944 net::HttpRequestInfo info
;
6945 info
.url
= GURL(kSimpleGET_Transaction
.url
);
6946 net::TestCompletionCallback callback
;
6947 EXPECT_EQ(net::ERR_IO_PENDING
,
6948 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6950 ASSERT_TRUE(cache
.network_layer()->last_transaction());
6951 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
6952 websocket_handshake_stream_create_helper());
6953 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
6954 EXPECT_EQ(&create_helper
,
6955 cache
.network_layer()->last_transaction()->
6956 websocket_handshake_stream_create_helper());
6957 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6960 // Make sure that a cache transaction passes on its priority to
6961 // newly-created network transactions.
6962 TEST(HttpCache
, SetPriorityNewTransaction
) {
6963 MockHttpCache cache
;
6964 AddMockTransaction(&kRangeGET_TransactionOK
);
6966 std::string
raw_headers("HTTP/1.1 200 OK\n"
6967 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6969 "Accept-Ranges: bytes\n"
6970 "Content-Length: 80\n");
6971 CreateTruncatedEntry(raw_headers
, &cache
);
6973 // Now make a regular request.
6974 std::string headers
;
6975 MockTransaction
transaction(kRangeGET_TransactionOK
);
6976 transaction
.request_headers
= EXTRA_HEADER
;
6977 transaction
.data
= kFullRangeData
;
6979 scoped_ptr
<net::HttpTransaction
> trans
;
6981 cache
.http_cache()->CreateTransaction(net::MEDIUM
, &trans
));
6982 EXPECT_EQ(net::DEFAULT_PRIORITY
,
6983 cache
.network_layer()->last_create_transaction_priority());
6985 MockHttpRequest
info(transaction
);
6986 net::TestCompletionCallback callback
;
6987 EXPECT_EQ(net::ERR_IO_PENDING
,
6988 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
6989 EXPECT_EQ(net::OK
, callback
.WaitForResult());
6991 EXPECT_EQ(net::MEDIUM
,
6992 cache
.network_layer()->last_create_transaction_priority());
6994 trans
->SetPriority(net::HIGHEST
);
6995 // Should trigger a new network transaction and pick up the new
6997 ReadAndVerifyTransaction(trans
.get(), transaction
);
6999 EXPECT_EQ(net::HIGHEST
,
7000 cache
.network_layer()->last_create_transaction_priority());
7002 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7005 int64
RunTransactionAndGetReceivedBytes(
7006 MockHttpCache
& cache
,
7007 const MockTransaction
& trans_info
) {
7008 int64 received_bytes
= -1;
7009 RunTransactionTestBase(cache
.http_cache(), trans_info
,
7010 MockHttpRequest(trans_info
), NULL
, net::BoundNetLog(),
7011 NULL
, &received_bytes
);
7012 return received_bytes
;
7015 int64
TransactionSize(const MockTransaction
& transaction
) {
7016 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
7017 strlen(transaction
.data
);
7020 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
7021 MockHttpCache cache
;
7023 MockTransaction
transaction(kSimpleGET_Transaction
);
7024 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7025 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7027 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7028 EXPECT_EQ(0, received_bytes
);
7031 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
7032 MockHttpCache cache
;
7034 ScopedMockTransaction
transaction(kETagGET_Transaction
);
7035 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7036 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7038 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
7039 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
7040 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7041 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7044 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
7045 MockHttpCache cache
;
7047 MockTransaction
transaction(kTypicalGET_Transaction
);
7048 transaction
.request_headers
= "Foo: bar\r\n";
7049 transaction
.response_headers
=
7050 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7051 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7053 "Cache-Control: max-age=0\n"
7055 AddMockTransaction(&transaction
);
7056 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7057 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7059 RevalidationServer server
;
7060 transaction
.handler
= server
.Handler
;
7061 transaction
.request_headers
= "Foo: none\r\n";
7062 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7063 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7065 RemoveMockTransaction(&transaction
);
7068 TEST(HttpCache
, ReceivedBytesRange
) {
7069 MockHttpCache cache
;
7070 AddMockTransaction(&kRangeGET_TransactionOK
);
7071 MockTransaction
transaction(kRangeGET_TransactionOK
);
7073 // Read bytes 40-49 from the network.
7074 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7075 int64 range_response_size
= TransactionSize(transaction
);
7076 EXPECT_EQ(range_response_size
, received_bytes
);
7078 // Read bytes 40-49 from the cache.
7079 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7080 EXPECT_EQ(0, received_bytes
);
7081 base::MessageLoop::current()->RunUntilIdle();
7083 // Read bytes 30-39 from the network.
7084 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
7085 transaction
.data
= "rg: 30-39 ";
7086 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7087 EXPECT_EQ(range_response_size
, received_bytes
);
7088 base::MessageLoop::current()->RunUntilIdle();
7090 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7091 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
7092 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7093 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7094 EXPECT_EQ(range_response_size
* 2, received_bytes
);
7096 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7099 // Framework for tests of stale-while-revalidate related functionality. With
7100 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
7101 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
7102 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
7103 // synchronous revalidation.
7104 class HttpCacheStaleWhileRevalidateTest
: public ::testing::Test
{
7106 HttpCacheStaleWhileRevalidateTest()
7107 : transaction_(kSimpleGET_Transaction
),
7109 stale_while_revalidate_(7200),
7110 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
7111 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(true);
7114 // RunTransactionTest() with the arguments from this fixture.
7115 void RunFixtureTransactionTest() {
7116 std::string response_headers
= base::StringPrintf(
7119 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
7122 stale_while_revalidate_
);
7123 transaction_
.response_headers
= response_headers
.c_str();
7124 RunTransactionTest(cache_
.http_cache(), transaction_
);
7125 transaction_
.response_headers
= "";
7128 // How many times this test has sent requests to the (fake) origin
7129 // server. Every test case needs to make at least one request to initialise
7131 int transaction_count() {
7132 return cache_
.network_layer()->transaction_count();
7135 // How many times an existing cache entry was opened during the test case.
7136 int open_count() { return cache_
.disk_cache()->open_count(); }
7138 MockHttpCache cache_
;
7139 ScopedMockTransaction transaction_
;
7141 int stale_while_revalidate_
;
7142 std::string validator_
;
7145 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo
* request
,
7146 std::string
* response_status
,
7147 std::string
* response_headers
,
7148 std::string
* response_data
) {
7150 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
7151 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
7154 // Verify that the Resource-Freshness header is sent on a revalidation if the
7155 // stale-while-revalidate directive was on the response.
7156 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderSent
) {
7157 age_
= 10801; // Outside the stale-while-revalidate window.
7159 // Write to the cache.
7160 RunFixtureTransactionTest();
7162 EXPECT_EQ(1, transaction_count());
7164 // Send the request again and check that Resource-Freshness header is added.
7165 transaction_
.handler
= CheckResourceFreshnessHeader
;
7167 RunFixtureTransactionTest();
7169 EXPECT_EQ(2, transaction_count());
7172 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo
* request
,
7173 std::string
* response_status
,
7174 std::string
* response_headers
,
7175 std::string
* response_data
) {
7176 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7179 // Verify that the Resource-Freshness header is not sent when
7180 // stale-while-revalidate is 0.
7181 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderNotSent
) {
7183 stale_while_revalidate_
= 0;
7185 // Write to the cache.
7186 RunFixtureTransactionTest();
7188 EXPECT_EQ(1, transaction_count());
7190 // Send the request again and check that Resource-Freshness header is absent.
7191 transaction_
.handler
= CheckResourceFreshnessAbsent
;
7193 RunFixtureTransactionTest();
7195 EXPECT_EQ(2, transaction_count());
7198 // Verify that when stale-while-revalidate applies the response is read from
7200 TEST_F(HttpCacheStaleWhileRevalidateTest
, ReadFromCache
) {
7201 // Write to the cache.
7202 RunFixtureTransactionTest();
7204 EXPECT_EQ(0, open_count());
7205 EXPECT_EQ(1, transaction_count());
7207 // Read back from the cache.
7208 RunFixtureTransactionTest();
7210 EXPECT_EQ(1, open_count());
7211 EXPECT_EQ(1, transaction_count());
7214 // Verify that when stale-while-revalidate applies an asynchronous request is
7216 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestSent
) {
7217 // Write to the cache.
7218 RunFixtureTransactionTest();
7220 EXPECT_EQ(1, transaction_count());
7222 // Read back from the cache.
7223 RunFixtureTransactionTest();
7225 EXPECT_EQ(1, transaction_count());
7227 // Let the async request execute.
7228 base::RunLoop().RunUntilIdle();
7229 EXPECT_EQ(2, transaction_count());
7232 // Verify that tearing down the HttpCache with an async revalidation in progress
7233 // does not break anything (this test is most likely to find problems when run
7234 // with a memory checker such as AddressSanitizer).
7235 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncTearDown
) {
7236 // Write to the cache.
7237 RunFixtureTransactionTest();
7239 // Read back from the cache.
7240 RunFixtureTransactionTest();
7243 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo
* request
,
7244 std::string
* response_status
,
7245 std::string
* response_headers
,
7246 std::string
* response_data
) {
7248 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-Modified-Since", &value
));
7249 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value
);
7252 // Verify that the async revalidation contains an If-Modified-Since header.
7253 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfModifiedSince
) {
7254 // Write to the cache.
7255 RunFixtureTransactionTest();
7257 transaction_
.handler
= CheckIfModifiedSinceHeader
;
7259 // Read back from the cache.
7260 RunFixtureTransactionTest();
7263 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo
* request
,
7264 std::string
* response_status
,
7265 std::string
* response_headers
,
7266 std::string
* response_data
) {
7268 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-None-Match", &value
));
7269 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value
);
7272 // If the response had ETag rather than Last-Modified, then that is used to
7273 // conditionalise the response.
7274 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfNoneMatch
) {
7275 validator_
= "Etag: \"40a1-1320-4f6adefa22a40\"";
7277 // Write to the cache.
7278 RunFixtureTransactionTest();
7280 transaction_
.handler
= CheckIfNoneMatchHeader
;
7282 // Read back from the cache.
7283 RunFixtureTransactionTest();
7286 static void CheckResourceFreshnessHeaderPresent(
7287 const net::HttpRequestInfo
* request
,
7288 std::string
* response_status
,
7289 std::string
* response_headers
,
7290 std::string
* response_data
) {
7291 EXPECT_TRUE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7294 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestHasResourceFreshness
) {
7295 // Write to the cache.
7296 RunFixtureTransactionTest();
7298 transaction_
.handler
= CheckResourceFreshnessHeaderPresent
;
7300 // Read back from the cache.
7301 RunFixtureTransactionTest();
7304 // Verify that when age > max-age + stale-while-revalidate stale results are
7306 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedIfTooStale
) {
7309 // Write to the cache.
7310 RunFixtureTransactionTest();
7312 EXPECT_EQ(0, open_count());
7313 EXPECT_EQ(1, transaction_count());
7315 // Reading back reads from the network.
7316 RunFixtureTransactionTest();
7318 EXPECT_EQ(1, open_count());
7319 EXPECT_EQ(2, transaction_count());
7322 // HEAD requests should be able to take advantage of stale-while-revalidate.
7323 TEST_F(HttpCacheStaleWhileRevalidateTest
, WorksForHeadMethod
) {
7324 // Write to the cache. This has to be a GET request; HEAD requests don't
7325 // create new cache entries.
7326 RunFixtureTransactionTest();
7328 EXPECT_EQ(0, open_count());
7329 EXPECT_EQ(1, transaction_count());
7331 // Read back from the cache, and trigger an asynchronous HEAD request.
7332 transaction_
.method
= "HEAD";
7333 transaction_
.data
= "";
7335 RunFixtureTransactionTest();
7337 EXPECT_EQ(1, open_count());
7338 EXPECT_EQ(1, transaction_count());
7340 // Let the network request proceed.
7341 base::RunLoop().RunUntilIdle();
7343 EXPECT_EQ(2, transaction_count());
7346 // POST requests should not use stale-while-revalidate.
7347 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedToPost
) {
7348 transaction_
= ScopedMockTransaction(kSimplePOST_Transaction
);
7350 // Write to the cache.
7351 RunFixtureTransactionTest();
7353 EXPECT_EQ(0, open_count());
7354 EXPECT_EQ(1, transaction_count());
7356 // Reading back reads from the network.
7357 RunFixtureTransactionTest();
7359 EXPECT_EQ(0, open_count());
7360 EXPECT_EQ(2, transaction_count());
7363 static void CheckUrlMatches(const net::HttpRequestInfo
* request
,
7364 std::string
* response_status
,
7365 std::string
* response_headers
,
7366 std::string
* response_data
) {
7367 EXPECT_EQ("http://www.google.com/", request
->url
.spec());
7370 // Async revalidation is issued to the original URL.
7371 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestUrlMatches
) {
7372 transaction_
.url
= "http://www.google.com/";
7373 // Write to the cache.
7374 RunFixtureTransactionTest();
7376 // Read back from the cache.
7377 RunFixtureTransactionTest();
7379 EXPECT_EQ(1, transaction_count());
7381 transaction_
.handler
= CheckUrlMatches
;
7383 // Let the async request execute and perform the check.
7384 base::RunLoop().RunUntilIdle();
7385 EXPECT_EQ(2, transaction_count());
7388 class SyncLoadFlagTest
: public HttpCacheStaleWhileRevalidateTest
,
7389 public ::testing::WithParamInterface
<int> {};
7391 // Flags which should always cause the request to be synchronous.
7392 TEST_P(SyncLoadFlagTest
, MustBeSynchronous
) {
7393 transaction_
.load_flags
|= GetParam();
7394 // Write to the cache.
7395 RunFixtureTransactionTest();
7397 EXPECT_EQ(1, transaction_count());
7399 // Reading back reads from the network.
7400 RunFixtureTransactionTest();
7402 EXPECT_EQ(2, transaction_count());
7405 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate
,
7407 ::testing::Values(net::LOAD_VALIDATE_CACHE
,
7408 net::LOAD_BYPASS_CACHE
,
7409 net::LOAD_DISABLE_CACHE
));
7411 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7412 PreferringCacheDoesNotTriggerAsyncRequest
) {
7413 transaction_
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
7414 // Write to the cache.
7415 RunFixtureTransactionTest();
7417 EXPECT_EQ(1, transaction_count());
7419 // Reading back reads from the cache.
7420 RunFixtureTransactionTest();
7422 EXPECT_EQ(1, transaction_count());
7424 // If there was an async transaction created, it would run now.
7425 base::RunLoop().RunUntilIdle();
7427 // There was no async transaction.
7428 EXPECT_EQ(1, transaction_count());
7431 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotUsedWhenDisabled
) {
7432 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7433 // Write to the cache.
7434 RunFixtureTransactionTest();
7436 EXPECT_EQ(1, transaction_count());
7438 // A synchronous revalidation is performed.
7439 RunFixtureTransactionTest();
7441 EXPECT_EQ(2, transaction_count());
7444 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7445 OnlyFromCacheDoesNotTriggerAsyncRequest
) {
7446 transaction_
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
7447 transaction_
.return_code
= net::ERR_CACHE_MISS
;
7449 // Writing to the cache should fail, because we are avoiding the network.
7450 RunFixtureTransactionTest();
7452 EXPECT_EQ(0, transaction_count());
7454 base::RunLoop().RunUntilIdle();
7457 EXPECT_EQ(0, transaction_count());
7460 // A certificate error during an asynchronous fetch should cause the next fetch
7461 // to proceed synchronously.
7462 // TODO(ricea): In future, only certificate errors which require user
7463 // interaction should fail the asynchronous revalidation, and they should cause
7464 // the next revalidation to be synchronous rather than requiring a total
7465 // refetch. This test will need to be updated appropriately.
7466 TEST_F(HttpCacheStaleWhileRevalidateTest
, CertificateErrorCausesRefetch
) {
7467 // Write to the cache.
7468 RunFixtureTransactionTest();
7470 EXPECT_EQ(1, transaction_count());
7472 // Now read back. RunTransactionTestBase() expects to receive the network
7473 // error back from the HttpCache::Transaction, but since the cache request
7474 // will return OK we need to duplicate some of its implementation here.
7475 transaction_
.return_code
= net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
7476 net::TestCompletionCallback callback
;
7477 scoped_ptr
<net::HttpTransaction
> trans
;
7479 cache_
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7480 EXPECT_EQ(net::OK
, rv
);
7481 ASSERT_TRUE(trans
.get());
7483 MockHttpRequest
request(transaction_
);
7484 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7485 ASSERT_EQ(net::ERR_IO_PENDING
, rv
);
7486 ASSERT_EQ(net::OK
, callback
.WaitForResult());
7487 ReadAndVerifyTransaction(trans
.get(), transaction_
);
7489 EXPECT_EQ(1, transaction_count());
7491 // Allow the asynchronous fetch to run.
7492 base::RunLoop().RunUntilIdle();
7494 EXPECT_EQ(2, transaction_count());
7496 // Now run the transaction again. It should run synchronously.
7497 transaction_
.return_code
= net::OK
;
7498 RunFixtureTransactionTest();
7500 EXPECT_EQ(3, transaction_count());
7503 // Ensure that the response cached by the asynchronous request is not truncated,
7504 // even if the server is slow.
7505 TEST_F(HttpCacheStaleWhileRevalidateTest
, EntireResponseCached
) {
7506 transaction_
.test_mode
= TEST_MODE_SLOW_READ
;
7507 // Write to the cache.
7508 RunFixtureTransactionTest();
7510 // Read back from the cache.
7511 RunFixtureTransactionTest();
7513 // Let the async request execute.
7514 base::RunLoop().RunUntilIdle();
7516 // The cache entry should still be complete.
7517 transaction_
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
7518 RunFixtureTransactionTest();
7521 // Verify that there are no race conditions in the completely synchronous case.
7522 TEST_F(HttpCacheStaleWhileRevalidateTest
, SynchronousCaseWorks
) {
7523 transaction_
.test_mode
= TEST_MODE_SYNC_ALL
;
7524 // Write to the cache.
7525 RunFixtureTransactionTest();
7527 EXPECT_EQ(1, transaction_count());
7529 // Read back from the cache.
7530 RunFixtureTransactionTest();
7532 EXPECT_EQ(1, transaction_count());
7534 // Let the async request execute.
7535 base::RunLoop().RunUntilIdle();
7536 EXPECT_EQ(2, transaction_count());
7539 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo
* request
,
7540 std::string
* response_status
,
7541 std::string
* response_headers
,
7542 std::string
* response_data
) {
7543 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION
, request
->load_flags
);
7546 // Check that the load flags on the async request are the same as the load flags
7547 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7548 TEST_F(HttpCacheStaleWhileRevalidateTest
, LoadFlagsAsyncRevalidation
) {
7549 transaction_
.load_flags
= net::LOAD_NORMAL
;
7550 // Write to the cache.
7551 RunFixtureTransactionTest();
7553 EXPECT_EQ(1, transaction_count());
7555 // Read back from the cache.
7556 RunFixtureTransactionTest();
7558 EXPECT_EQ(1, transaction_count());
7560 transaction_
.handler
= CheckLoadFlagsAsyncRevalidation
;
7561 // Let the async request execute.
7562 base::RunLoop().RunUntilIdle();
7563 EXPECT_EQ(2, transaction_count());
7566 static void SimpleMockAuthHandler(const net::HttpRequestInfo
* request
,
7567 std::string
* response_status
,
7568 std::string
* response_headers
,
7569 std::string
* response_data
) {
7570 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
7571 !request
->extra_headers
.HasHeader("Authorization")) {
7572 response_status
->assign("HTTP/1.1 401 Unauthorized");
7573 response_headers
->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7576 response_status
->assign("HTTP/1.1 200 OK");
7579 TEST_F(HttpCacheStaleWhileRevalidateTest
, RestartForAuth
) {
7580 // Write to the cache.
7581 RunFixtureTransactionTest();
7583 EXPECT_EQ(1, transaction_count());
7585 // Now make the transaction require auth.
7586 transaction_
.request_headers
= "X-Require-Mock-Auth: dummy\r\n\r\n";
7587 transaction_
.handler
= SimpleMockAuthHandler
;
7589 // Read back from the cache.
7590 RunFixtureTransactionTest();
7592 EXPECT_EQ(1, transaction_count());
7594 // Let the async request execute.
7595 base::RunLoop().RunUntilIdle();
7597 EXPECT_EQ(2, transaction_count());
7600 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7601 // take place on a sparse entry.
7602 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7603 MockHttpCache cache
;
7605 // Create a transaction for bytes 0-9.
7606 MockHttpRequest
request(kRangeGET_TransactionOK
);
7607 MockTransaction
transaction(kRangeGET_TransactionOK
);
7608 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7609 transaction
.data
= "rg: 00-09 ";
7610 AddMockTransaction(&transaction
);
7612 net::TestCompletionCallback callback
;
7613 scoped_ptr
<net::HttpTransaction
> trans
;
7614 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7615 EXPECT_EQ(net::OK
, rv
);
7616 ASSERT_TRUE(trans
.get());
7618 // Start our transaction.
7619 trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7621 // A second transaction on a different part of the file (the default
7622 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7623 // the already pending transaction.
7624 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7626 // Let the first transaction complete.
7627 callback
.WaitForResult();
7629 RemoveMockTransaction(&transaction
);
7632 // Makes sure that a request stops using the cache when the response headers
7633 // with "Cache-Control: no-store" arrives. That means that another request for
7634 // the same URL can be processed before the response body of the original
7636 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7637 MockHttpCache cache
;
7638 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7639 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7640 MockHttpRequest
request(mock_transaction
);
7642 scoped_ptr
<Context
> first(new Context
);
7643 first
->result
= cache
.CreateTransaction(&first
->trans
);
7644 ASSERT_EQ(net::OK
, first
->result
);
7645 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7646 first
->result
= first
->trans
->Start(
7647 &request
, first
->callback
.callback(), net::BoundNetLog());
7648 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7650 base::MessageLoop::current()->RunUntilIdle();
7651 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7652 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7653 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7654 "Cache-Control", "no-store"));
7655 // Here we have read the response header but not read the response body yet.
7657 // Let us create the second (read) transaction.
7658 scoped_ptr
<Context
> second(new Context
);
7659 second
->result
= cache
.CreateTransaction(&second
->trans
);
7660 ASSERT_EQ(net::OK
, second
->result
);
7661 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7662 second
->result
= second
->trans
->Start(
7663 &request
, second
->callback
.callback(), net::BoundNetLog());
7665 // Here the second transaction proceeds without reading the first body.
7666 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7667 base::MessageLoop::current()->RunUntilIdle();
7668 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7669 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7670 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7671 "Cache-Control", "no-store"));
7672 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);