1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/http_cache.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/test/simple_test_clock.h"
17 #include "net/base/cache_type.h"
18 #include "net/base/elements_upload_data_stream.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/load_flags.h"
21 #include "net/base/load_timing_info.h"
22 #include "net/base/load_timing_info_test_util.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/net_log_unittest.h"
25 #include "net/base/upload_bytes_element_reader.h"
26 #include "net/cert/cert_status_flags.h"
27 #include "net/disk_cache/disk_cache.h"
28 #include "net/http/http_byte_range.h"
29 #include "net/http/http_cache_transaction.h"
30 #include "net/http/http_request_headers.h"
31 #include "net/http/http_request_info.h"
32 #include "net/http/http_response_headers.h"
33 #include "net/http/http_response_info.h"
34 #include "net/http/http_transaction.h"
35 #include "net/http/http_transaction_test_util.h"
36 #include "net/http/http_util.h"
37 #include "net/http/mock_http_cache.h"
38 #include "net/socket/client_socket_handle.h"
39 #include "net/ssl/ssl_cert_request_info.h"
40 #include "net/websockets/websocket_handshake_stream_base.h"
41 #include "testing/gtest/include/gtest/gtest.h"
47 // Tests the load timing values of a request that goes through a
48 // MockNetworkTransaction.
49 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo
& load_timing_info
) {
50 EXPECT_FALSE(load_timing_info
.socket_reused
);
51 EXPECT_NE(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
53 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
54 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
56 net::ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
57 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY
);
58 EXPECT_LE(load_timing_info
.connect_timing
.connect_end
,
59 load_timing_info
.send_start
);
61 EXPECT_LE(load_timing_info
.send_start
, load_timing_info
.send_end
);
63 // Set by URLRequest / URLRequestHttpJob, at a higher level.
64 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
65 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
66 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
69 // Tests the load timing values of a request that receives a cached response.
70 void TestLoadTimingCachedResponse(const net::LoadTimingInfo
& load_timing_info
) {
71 EXPECT_FALSE(load_timing_info
.socket_reused
);
72 EXPECT_EQ(net::NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
74 EXPECT_TRUE(load_timing_info
.proxy_resolve_start
.is_null());
75 EXPECT_TRUE(load_timing_info
.proxy_resolve_end
.is_null());
77 net::ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
79 // Only the send start / end times should be sent, and they should have the
81 EXPECT_FALSE(load_timing_info
.send_start
.is_null());
82 EXPECT_EQ(load_timing_info
.send_start
, load_timing_info
.send_end
);
84 // Set by URLRequest / URLRequestHttpJob, at a higher level.
85 EXPECT_TRUE(load_timing_info
.request_start_time
.is_null());
86 EXPECT_TRUE(load_timing_info
.request_start
.is_null());
87 EXPECT_TRUE(load_timing_info
.receive_headers_end
.is_null());
90 class DeleteCacheCompletionCallback
: public net::TestCompletionCallbackBase
{
92 explicit DeleteCacheCompletionCallback(MockHttpCache
* cache
)
94 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete
,
95 base::Unretained(this))) {
98 const net::CompletionCallback
& callback() const { return callback_
; }
101 void OnComplete(int result
) {
106 MockHttpCache
* cache_
;
107 net::CompletionCallback callback_
;
109 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback
);
112 //-----------------------------------------------------------------------------
115 void ReadAndVerifyTransaction(net::HttpTransaction
* trans
,
116 const MockTransaction
& trans_info
) {
118 int rv
= ReadTransaction(trans
, &content
);
120 EXPECT_EQ(net::OK
, rv
);
121 std::string
expected(trans_info
.data
);
122 EXPECT_EQ(expected
, content
);
125 void RunTransactionTestBase(net::HttpCache
* cache
,
126 const MockTransaction
& trans_info
,
127 const MockHttpRequest
& request
,
128 net::HttpResponseInfo
* response_info
,
129 const net::BoundNetLog
& net_log
,
130 net::LoadTimingInfo
* load_timing_info
,
131 int64
* received_bytes
) {
132 net::TestCompletionCallback callback
;
134 // write to the cache
136 scoped_ptr
<net::HttpTransaction
> trans
;
137 int rv
= cache
->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
138 EXPECT_EQ(net::OK
, rv
);
139 ASSERT_TRUE(trans
.get());
141 rv
= trans
->Start(&request
, callback
.callback(), net_log
);
142 if (rv
== net::ERR_IO_PENDING
)
143 rv
= callback
.WaitForResult();
144 ASSERT_EQ(trans_info
.return_code
, rv
);
149 const net::HttpResponseInfo
* response
= trans
->GetResponseInfo();
150 ASSERT_TRUE(response
);
153 *response_info
= *response
;
155 if (load_timing_info
) {
156 // If a fake network connection is used, need a NetLog to get a fake socket
158 EXPECT_TRUE(net_log
.net_log());
159 *load_timing_info
= net::LoadTimingInfo();
160 trans
->GetLoadTimingInfo(load_timing_info
);
163 ReadAndVerifyTransaction(trans
.get(), trans_info
);
166 *received_bytes
= trans
->GetTotalReceivedBytes();
169 void RunTransactionTestWithRequest(net::HttpCache
* cache
,
170 const MockTransaction
& trans_info
,
171 const MockHttpRequest
& request
,
172 net::HttpResponseInfo
* response_info
) {
173 RunTransactionTestBase(cache
, trans_info
, request
, response_info
,
174 net::BoundNetLog(), NULL
, NULL
);
177 void RunTransactionTestAndGetTiming(net::HttpCache
* cache
,
178 const MockTransaction
& trans_info
,
179 const net::BoundNetLog
& log
,
180 net::LoadTimingInfo
* load_timing_info
) {
181 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
182 NULL
, log
, load_timing_info
, NULL
);
185 void RunTransactionTest(net::HttpCache
* cache
,
186 const MockTransaction
& trans_info
) {
187 RunTransactionTestAndGetTiming(cache
, trans_info
, net::BoundNetLog(), NULL
);
190 void RunTransactionTestWithLog(net::HttpCache
* cache
,
191 const MockTransaction
& trans_info
,
192 const net::BoundNetLog
& log
) {
193 RunTransactionTestAndGetTiming(cache
, trans_info
, log
, NULL
);
196 void RunTransactionTestWithResponseInfo(net::HttpCache
* cache
,
197 const MockTransaction
& trans_info
,
198 net::HttpResponseInfo
* response
) {
199 RunTransactionTestWithRequest(cache
, trans_info
, MockHttpRequest(trans_info
),
203 void RunTransactionTestWithResponseInfoAndGetTiming(
204 net::HttpCache
* cache
,
205 const MockTransaction
& trans_info
,
206 net::HttpResponseInfo
* response
,
207 const net::BoundNetLog
& log
,
208 net::LoadTimingInfo
* load_timing_info
) {
209 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
210 response
, log
, load_timing_info
, NULL
);
213 void RunTransactionTestWithResponse(net::HttpCache
* cache
,
214 const MockTransaction
& trans_info
,
215 std::string
* response_headers
) {
216 net::HttpResponseInfo response
;
217 RunTransactionTestWithResponseInfo(cache
, trans_info
, &response
);
218 response
.headers
->GetNormalizedHeaders(response_headers
);
221 void RunTransactionTestWithResponseAndGetTiming(
222 net::HttpCache
* cache
,
223 const MockTransaction
& trans_info
,
224 std::string
* response_headers
,
225 const net::BoundNetLog
& log
,
226 net::LoadTimingInfo
* load_timing_info
) {
227 net::HttpResponseInfo response
;
228 RunTransactionTestBase(cache
, trans_info
, MockHttpRequest(trans_info
),
229 &response
, log
, load_timing_info
, NULL
);
230 response
.headers
->GetNormalizedHeaders(response_headers
);
233 // This class provides a handler for kFastNoStoreGET_Transaction so that the
234 // no-store header can be included on demand.
235 class FastTransactionServer
{
237 FastTransactionServer() {
240 ~FastTransactionServer() {}
242 void set_no_store(bool value
) { no_store
= value
; }
244 static void FastNoStoreHandler(const net::HttpRequestInfo
* request
,
245 std::string
* response_status
,
246 std::string
* response_headers
,
247 std::string
* response_data
) {
249 *response_headers
= "Cache-Control: no-store\n";
253 static bool no_store
;
254 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer
);
256 bool FastTransactionServer::no_store
;
258 const MockTransaction kFastNoStoreGET_Transaction
= {
259 "http://www.google.com/nostore",
263 net::LOAD_VALIDATE_CACHE
,
265 "Cache-Control: max-age=10000\n",
267 "<html><body>Google Blah Blah</body></html>",
268 TEST_MODE_SYNC_NET_START
,
269 &FastTransactionServer::FastNoStoreHandler
,
274 // This class provides a handler for kRangeGET_TransactionOK so that the range
275 // request can be served on demand.
276 class RangeTransactionServer
{
278 RangeTransactionServer() {
279 not_modified_
= false;
283 ~RangeTransactionServer() {
284 not_modified_
= false;
289 // Returns only 416 or 304 when set.
290 void set_not_modified(bool value
) { not_modified_
= value
; }
292 // Returns 206 when revalidating a range (instead of 304).
293 void set_modified(bool value
) { modified_
= value
; }
295 // Returns 200 instead of 206 (a malformed response overall).
296 void set_bad_200(bool value
) { bad_200_
= value
; }
298 // Other than regular range related behavior (and the flags mentioned above),
299 // the server reacts to requests headers like so:
300 // X-Require-Mock-Auth -> return 401.
301 // X-Return-Default-Range -> assume 40-49 was requested.
302 static void RangeHandler(const net::HttpRequestInfo
* request
,
303 std::string
* response_status
,
304 std::string
* response_headers
,
305 std::string
* response_data
);
308 static bool not_modified_
;
309 static bool modified_
;
310 static bool bad_200_
;
311 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer
);
313 bool RangeTransactionServer::not_modified_
= false;
314 bool RangeTransactionServer::modified_
= false;
315 bool RangeTransactionServer::bad_200_
= false;
317 // A dummy extra header that must be preserved on a given request.
319 // EXTRA_HEADER_LINE doesn't include a line terminator because it
320 // will be passed to AddHeaderFromString() which doesn't accept them.
321 #define EXTRA_HEADER_LINE "Extra: header"
323 // EXTRA_HEADER contains a line terminator, as expected by
324 // AddHeadersFromString() (_not_ AddHeaderFromString()).
325 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
327 static const char kExtraHeaderKey
[] = "Extra";
330 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo
* request
,
331 std::string
* response_status
,
332 std::string
* response_headers
,
333 std::string
* response_data
) {
334 if (request
->extra_headers
.IsEmpty()) {
335 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
336 response_data
->clear();
340 // We want to make sure we don't delete extra headers.
341 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
343 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
344 !request
->extra_headers
.HasHeader("Authorization")) {
345 response_status
->assign("HTTP/1.1 401 Unauthorized");
346 response_data
->assign("WWW-Authenticate: Foo\n");
351 response_status
->assign("HTTP/1.1 304 Not Modified");
352 response_data
->clear();
356 std::vector
<net::HttpByteRange
> ranges
;
357 std::string range_header
;
358 if (!request
->extra_headers
.GetHeader(
359 net::HttpRequestHeaders::kRange
, &range_header
) ||
360 !net::HttpUtil::ParseRangeHeader(range_header
, &ranges
) || bad_200_
||
361 ranges
.size() != 1) {
362 // This is not a byte range request. We return 200.
363 response_status
->assign("HTTP/1.1 200 OK");
364 response_headers
->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
365 response_data
->assign("Not a range");
369 // We can handle this range request.
370 net::HttpByteRange byte_range
= ranges
[0];
372 if (request
->extra_headers
.HasHeader("X-Return-Default-Range")) {
373 byte_range
.set_first_byte_position(40);
374 byte_range
.set_last_byte_position(49);
377 if (byte_range
.first_byte_position() > 79) {
378 response_status
->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
379 response_data
->clear();
383 EXPECT_TRUE(byte_range
.ComputeBounds(80));
384 int start
= static_cast<int>(byte_range
.first_byte_position());
385 int end
= static_cast<int>(byte_range
.last_byte_position());
389 std::string content_range
= base::StringPrintf(
390 "Content-Range: bytes %d-%d/80\n", start
, end
);
391 response_headers
->append(content_range
);
393 if (!request
->extra_headers
.HasHeader("If-None-Match") || modified_
) {
396 EXPECT_EQ(0, end
% 10);
399 EXPECT_EQ(9, (end
- start
) % 10);
400 for (int block_start
= start
; block_start
< end
; block_start
+= 10) {
401 base::StringAppendF(&data
, "rg: %02d-%02d ",
402 block_start
, block_start
+ 9);
405 *response_data
= data
;
407 if (end
- start
!= 9) {
408 // We also have to fix content-length.
409 int len
= end
- start
+ 1;
410 std::string content_length
= base::StringPrintf("Content-Length: %d\n",
412 response_headers
->replace(response_headers
->find("Content-Length:"),
413 content_length
.size(), content_length
);
416 response_status
->assign("HTTP/1.1 304 Not Modified");
417 response_data
->clear();
421 const MockTransaction kRangeGET_TransactionOK
= {
422 "http://www.google.com/range",
425 "Range: bytes = 40-49\r\n"
428 "HTTP/1.1 206 Partial Content",
429 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
431 "Accept-Ranges: bytes\n"
432 "Content-Length: 10\n",
436 &RangeTransactionServer::RangeHandler
,
441 const char kFullRangeData
[] =
442 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
443 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
445 // Verifies the response headers (|response|) match a partial content
446 // response for the range starting at |start| and ending at |end|.
447 void Verify206Response(std::string response
, int start
, int end
) {
448 std::string
raw_headers(net::HttpUtil::AssembleRawHeaders(response
.data(),
450 scoped_refptr
<net::HttpResponseHeaders
> headers(
451 new net::HttpResponseHeaders(raw_headers
));
453 ASSERT_EQ(206, headers
->response_code());
455 int64 range_start
, range_end
, object_size
;
457 headers
->GetContentRange(&range_start
, &range_end
, &object_size
));
458 int64 content_length
= headers
->GetContentLength();
460 int length
= end
- start
+ 1;
461 ASSERT_EQ(length
, content_length
);
462 ASSERT_EQ(start
, range_start
);
463 ASSERT_EQ(end
, range_end
);
466 // Creates a truncated entry that can be resumed using byte ranges.
467 void CreateTruncatedEntry(std::string raw_headers
, MockHttpCache
* cache
) {
468 // Create a disk cache entry that stores an incomplete resource.
469 disk_cache::Entry
* entry
;
470 ASSERT_TRUE(cache
->CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
473 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
476 net::HttpResponseInfo response
;
477 response
.response_time
= base::Time::Now();
478 response
.request_time
= base::Time::Now();
479 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
480 // Set the last argument for this to be an incomplete request.
481 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
483 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
484 int len
= static_cast<int>(base::strlcpy(buf
->data(),
485 "rg: 00-09 rg: 10-19 ", 100));
486 net::TestCompletionCallback cb
;
487 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
488 EXPECT_EQ(len
, cb
.GetResult(rv
));
492 // Helper to represent a network HTTP response.
494 // Set this response into |trans|.
495 void AssignTo(MockTransaction
* trans
) const {
496 trans
->status
= status
;
497 trans
->response_headers
= headers
;
501 std::string
status_and_headers() const {
502 return std::string(status
) + "\n" + std::string(headers
);
511 Context() : result(net::ERR_IO_PENDING
) {}
514 net::TestCompletionCallback callback
;
515 scoped_ptr
<net::HttpTransaction
> trans
;
518 class FakeWebSocketHandshakeStreamCreateHelper
519 : public net::WebSocketHandshakeStreamBase::CreateHelper
{
521 ~FakeWebSocketHandshakeStreamCreateHelper() override
{}
522 net::WebSocketHandshakeStreamBase
* CreateBasicStream(
523 scoped_ptr
<net::ClientSocketHandle
> connect
,
524 bool using_proxy
) override
{
527 net::WebSocketHandshakeStreamBase
* CreateSpdyStream(
528 const base::WeakPtr
<net::SpdySession
>& session
,
529 bool use_relative_url
) override
{
534 // Returns true if |entry| is not one of the log types paid attention to in this
535 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
537 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry
& entry
) {
538 switch (entry
.type
) {
539 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
:
540 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
:
541 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
:
542 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
:
543 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
:
544 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO
:
551 // Modifies |entries| to only include log entries created by the cache layer and
552 // asserted on in these tests.
553 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList
* entries
) {
554 entries
->erase(std::remove_if(entries
->begin(), entries
->end(),
555 &ShouldIgnoreLogEntry
),
559 bool LogContainsEventType(const net::CapturingBoundNetLog
& log
,
560 net::NetLog::EventType expected
) {
561 net::CapturingNetLog::CapturedEntryList entries
;
562 log
.GetEntries(&entries
);
563 for (size_t i
= 0; i
< entries
.size(); i
++) {
564 if (entries
[i
].type
== expected
)
573 //-----------------------------------------------------------------------------
576 TEST(HttpCache
, CreateThenDestroy
) {
579 scoped_ptr
<net::HttpTransaction
> trans
;
580 EXPECT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
581 ASSERT_TRUE(trans
.get());
584 TEST(HttpCache
, GetBackend
) {
585 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(0));
587 disk_cache::Backend
* backend
;
588 net::TestCompletionCallback cb
;
589 // This will lazily initialize the backend.
590 int rv
= cache
.http_cache()->GetBackend(&backend
, cb
.callback());
591 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
594 TEST(HttpCache
, SimpleGET
) {
596 net::CapturingBoundNetLog log
;
597 net::LoadTimingInfo load_timing_info
;
599 // Write to the cache.
600 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
601 log
.bound(), &load_timing_info
);
603 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
605 EXPECT_EQ(1, cache
.disk_cache()->create_count());
606 TestLoadTimingNetworkRequest(load_timing_info
);
609 TEST(HttpCache
, SimpleGETNoDiskCache
) {
612 cache
.disk_cache()->set_fail_requests();
614 net::CapturingBoundNetLog log
;
615 net::LoadTimingInfo load_timing_info
;
617 // Read from the network, and don't use the cache.
618 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
619 log
.bound(), &load_timing_info
);
621 // Check that the NetLog was filled as expected.
622 // (We attempted to both Open and Create entries, but both failed).
623 net::CapturingNetLog::CapturedEntryList entries
;
624 log
.GetEntries(&entries
);
625 FilterLogEntries(&entries
);
627 EXPECT_EQ(6u, entries
.size());
628 EXPECT_TRUE(net::LogContainsBeginEvent(
629 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
630 EXPECT_TRUE(net::LogContainsEndEvent(
631 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
632 EXPECT_TRUE(net::LogContainsBeginEvent(
633 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
634 EXPECT_TRUE(net::LogContainsEndEvent(
635 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
636 EXPECT_TRUE(net::LogContainsBeginEvent(
637 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
638 EXPECT_TRUE(net::LogContainsEndEvent(
639 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
641 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
642 EXPECT_EQ(0, cache
.disk_cache()->open_count());
643 EXPECT_EQ(0, cache
.disk_cache()->create_count());
644 TestLoadTimingNetworkRequest(load_timing_info
);
647 TEST(HttpCache
, SimpleGETNoDiskCache2
) {
648 // This will initialize a cache object with NULL backend.
649 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
650 factory
->set_fail(true);
651 factory
->FinishCreation(); // We'll complete synchronously.
652 MockHttpCache
cache(factory
);
654 // Read from the network, and don't use the cache.
655 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
657 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
658 EXPECT_FALSE(cache
.http_cache()->GetCurrentBackend());
661 // Tests that IOBuffers are not referenced after IO completes.
662 TEST(HttpCache
, ReleaseBuffer
) {
665 // Write to the cache.
666 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
668 MockHttpRequest
request(kSimpleGET_Transaction
);
669 scoped_ptr
<net::HttpTransaction
> trans
;
670 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
672 const int kBufferSize
= 10;
673 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(kBufferSize
));
674 net::ReleaseBufferCompletionCallback
cb(buffer
.get());
676 int rv
= trans
->Start(&request
, cb
.callback(), net::BoundNetLog());
677 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
679 rv
= trans
->Read(buffer
.get(), kBufferSize
, cb
.callback());
680 EXPECT_EQ(kBufferSize
, cb
.GetResult(rv
));
683 TEST(HttpCache
, SimpleGETWithDiskFailures
) {
686 cache
.disk_cache()->set_soft_failures(true);
688 // Read from the network, and fail to write to the cache.
689 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
691 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
692 EXPECT_EQ(0, cache
.disk_cache()->open_count());
693 EXPECT_EQ(1, cache
.disk_cache()->create_count());
695 // This one should see an empty cache again.
696 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
698 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
699 EXPECT_EQ(0, cache
.disk_cache()->open_count());
700 EXPECT_EQ(2, cache
.disk_cache()->create_count());
703 // Tests that disk failures after the transaction has started don't cause the
705 TEST(HttpCache
, SimpleGETWithDiskFailures2
) {
708 MockHttpRequest
request(kSimpleGET_Transaction
);
710 scoped_ptr
<Context
> c(new Context());
711 int rv
= cache
.CreateTransaction(&c
->trans
);
712 ASSERT_EQ(net::OK
, rv
);
714 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
715 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
716 rv
= c
->callback
.WaitForResult();
718 // Start failing request now.
719 cache
.disk_cache()->set_soft_failures(true);
721 // We have to open the entry again to propagate the failure flag.
722 disk_cache::Entry
* en
;
723 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &en
));
726 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
729 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
730 EXPECT_EQ(1, cache
.disk_cache()->open_count());
731 EXPECT_EQ(1, cache
.disk_cache()->create_count());
733 // This one should see an empty cache again.
734 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
736 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
737 EXPECT_EQ(1, cache
.disk_cache()->open_count());
738 EXPECT_EQ(2, cache
.disk_cache()->create_count());
741 // Tests that we handle failures to read from the cache.
742 TEST(HttpCache
, SimpleGETWithDiskFailures3
) {
745 // Read from the network, and write to the cache.
746 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
748 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
749 EXPECT_EQ(0, cache
.disk_cache()->open_count());
750 EXPECT_EQ(1, cache
.disk_cache()->create_count());
752 cache
.disk_cache()->set_soft_failures(true);
754 // Now fail to read from the cache.
755 scoped_ptr
<Context
> c(new Context());
756 int rv
= cache
.CreateTransaction(&c
->trans
);
757 ASSERT_EQ(net::OK
, rv
);
759 MockHttpRequest
request(kSimpleGET_Transaction
);
760 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
761 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
763 // Now verify that the entry was removed from the cache.
764 cache
.disk_cache()->set_soft_failures(false);
766 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
767 EXPECT_EQ(1, cache
.disk_cache()->open_count());
768 EXPECT_EQ(2, cache
.disk_cache()->create_count());
770 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
772 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
773 EXPECT_EQ(1, cache
.disk_cache()->open_count());
774 EXPECT_EQ(3, cache
.disk_cache()->create_count());
777 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Hit
) {
780 net::CapturingBoundNetLog log
;
781 net::LoadTimingInfo load_timing_info
;
783 // Write to the cache.
784 RunTransactionTestAndGetTiming(cache
.http_cache(), kSimpleGET_Transaction
,
785 log
.bound(), &load_timing_info
);
787 // Check that the NetLog was filled as expected.
788 net::CapturingNetLog::CapturedEntryList entries
;
789 log
.GetEntries(&entries
);
790 FilterLogEntries(&entries
);
792 EXPECT_EQ(8u, entries
.size());
793 EXPECT_TRUE(net::LogContainsBeginEvent(
794 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
795 EXPECT_TRUE(net::LogContainsEndEvent(
796 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
797 EXPECT_TRUE(net::LogContainsBeginEvent(
798 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
799 EXPECT_TRUE(net::LogContainsEndEvent(
800 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
801 EXPECT_TRUE(net::LogContainsBeginEvent(
802 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
803 EXPECT_TRUE(net::LogContainsEndEvent(
804 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
805 EXPECT_TRUE(net::LogContainsBeginEvent(
806 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
807 EXPECT_TRUE(net::LogContainsEndEvent(
808 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
810 TestLoadTimingNetworkRequest(load_timing_info
);
812 // Force this transaction to read from the cache.
813 MockTransaction
transaction(kSimpleGET_Transaction
);
814 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
818 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
821 // Check that the NetLog was filled as expected.
822 log
.GetEntries(&entries
);
823 FilterLogEntries(&entries
);
825 EXPECT_EQ(8u, entries
.size());
826 EXPECT_TRUE(net::LogContainsBeginEvent(
827 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
828 EXPECT_TRUE(net::LogContainsEndEvent(
829 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
830 EXPECT_TRUE(net::LogContainsBeginEvent(
831 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
832 EXPECT_TRUE(net::LogContainsEndEvent(
833 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY
));
834 EXPECT_TRUE(net::LogContainsBeginEvent(
835 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
836 EXPECT_TRUE(net::LogContainsEndEvent(
837 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
838 EXPECT_TRUE(net::LogContainsBeginEvent(
839 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
840 EXPECT_TRUE(net::LogContainsEndEvent(
841 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO
));
843 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
844 EXPECT_EQ(1, cache
.disk_cache()->open_count());
845 EXPECT_EQ(1, cache
.disk_cache()->create_count());
846 TestLoadTimingCachedResponse(load_timing_info
);
849 TEST(HttpCache
, SimpleGET_LoadOnlyFromCache_Miss
) {
852 // force this transaction to read from the cache
853 MockTransaction
transaction(kSimpleGET_Transaction
);
854 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
856 MockHttpRequest
request(transaction
);
857 net::TestCompletionCallback callback
;
859 scoped_ptr
<net::HttpTransaction
> trans
;
860 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
862 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
863 if (rv
== net::ERR_IO_PENDING
)
864 rv
= callback
.WaitForResult();
865 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
869 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
870 EXPECT_EQ(0, cache
.disk_cache()->open_count());
871 EXPECT_EQ(0, cache
.disk_cache()->create_count());
874 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Hit
) {
877 // write to the cache
878 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
880 // force this transaction to read from the cache if valid
881 MockTransaction
transaction(kSimpleGET_Transaction
);
882 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
884 RunTransactionTest(cache
.http_cache(), transaction
);
886 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
887 EXPECT_EQ(1, cache
.disk_cache()->open_count());
888 EXPECT_EQ(1, cache
.disk_cache()->create_count());
891 TEST(HttpCache
, SimpleGET_LoadPreferringCache_Miss
) {
894 // force this transaction to read from the cache if valid
895 MockTransaction
transaction(kSimpleGET_Transaction
);
896 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
898 RunTransactionTest(cache
.http_cache(), transaction
);
900 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
901 EXPECT_EQ(0, cache
.disk_cache()->open_count());
902 EXPECT_EQ(1, cache
.disk_cache()->create_count());
905 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
906 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMatch
) {
909 // Write to the cache.
910 MockTransaction
transaction(kSimpleGET_Transaction
);
911 transaction
.request_headers
= "Foo: bar\r\n";
912 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
914 AddMockTransaction(&transaction
);
915 RunTransactionTest(cache
.http_cache(), transaction
);
917 // Read from the cache.
918 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
919 RunTransactionTest(cache
.http_cache(), transaction
);
921 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
922 EXPECT_EQ(1, cache
.disk_cache()->open_count());
923 EXPECT_EQ(1, cache
.disk_cache()->create_count());
924 RemoveMockTransaction(&transaction
);
927 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
928 TEST(HttpCache
, SimpleGET_LoadPreferringCache_VaryMismatch
) {
931 // Write to the cache.
932 MockTransaction
transaction(kSimpleGET_Transaction
);
933 transaction
.request_headers
= "Foo: bar\r\n";
934 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
936 AddMockTransaction(&transaction
);
937 RunTransactionTest(cache
.http_cache(), transaction
);
939 // Attempt to read from the cache... this is a vary mismatch that must reach
940 // the network again.
941 transaction
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
942 transaction
.request_headers
= "Foo: none\r\n";
943 net::CapturingBoundNetLog log
;
944 net::LoadTimingInfo load_timing_info
;
945 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
948 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
949 EXPECT_EQ(1, cache
.disk_cache()->open_count());
950 EXPECT_EQ(1, cache
.disk_cache()->create_count());
951 TestLoadTimingNetworkRequest(load_timing_info
);
952 RemoveMockTransaction(&transaction
);
955 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
957 TEST(HttpCache
, SimpleGET_CacheOverride_Network
) {
961 MockTransaction
transaction(kSimpleGET_Transaction
);
962 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
963 transaction
.response_headers
= "Cache-Control: no-cache\n";
965 AddMockTransaction(&transaction
);
966 RunTransactionTest(cache
.http_cache(), transaction
);
967 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
968 EXPECT_EQ(1, cache
.disk_cache()->create_count());
969 RemoveMockTransaction(&transaction
);
971 // Re-run transaction; make sure the result came from the network,
973 transaction
.data
= "Changed data.";
974 AddMockTransaction(&transaction
);
975 net::HttpResponseInfo response_info
;
976 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
979 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
980 EXPECT_FALSE(response_info
.server_data_unavailable
);
981 EXPECT_TRUE(response_info
.network_accessed
);
983 RemoveMockTransaction(&transaction
);
986 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
988 TEST(HttpCache
, SimpleGET_CacheOverride_Offline
) {
992 MockTransaction
transaction(kSimpleGET_Transaction
);
993 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
994 transaction
.response_headers
= "Cache-Control: no-cache\n";
996 AddMockTransaction(&transaction
);
997 RunTransactionTest(cache
.http_cache(), transaction
);
998 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
999 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1000 RemoveMockTransaction(&transaction
);
1002 // Network failure with offline error; should return cache entry above +
1003 // flag signalling stale data.
1004 transaction
.return_code
= net::ERR_NAME_NOT_RESOLVED
;
1005 AddMockTransaction(&transaction
);
1007 MockHttpRequest
request(transaction
);
1008 net::TestCompletionCallback callback
;
1009 scoped_ptr
<net::HttpTransaction
> trans
;
1010 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1011 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1012 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
1014 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1015 ASSERT_TRUE(response_info
);
1016 EXPECT_TRUE(response_info
->server_data_unavailable
);
1017 EXPECT_TRUE(response_info
->was_cached
);
1018 EXPECT_FALSE(response_info
->network_accessed
);
1019 ReadAndVerifyTransaction(trans
.get(), transaction
);
1020 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1022 RemoveMockTransaction(&transaction
);
1025 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1026 // non-offline failure.
1027 TEST(HttpCache
, SimpleGET_CacheOverride_NonOffline
) {
1028 MockHttpCache cache
;
1031 MockTransaction
transaction(kSimpleGET_Transaction
);
1032 transaction
.load_flags
|= net::LOAD_FROM_CACHE_IF_OFFLINE
;
1033 transaction
.response_headers
= "Cache-Control: no-cache\n";
1035 AddMockTransaction(&transaction
);
1036 RunTransactionTest(cache
.http_cache(), transaction
);
1037 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1038 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1039 RemoveMockTransaction(&transaction
);
1041 // Network failure with non-offline error; should fail with that error.
1042 transaction
.return_code
= net::ERR_PROXY_CONNECTION_FAILED
;
1043 AddMockTransaction(&transaction
);
1045 net::HttpResponseInfo response_info2
;
1046 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1049 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1050 EXPECT_FALSE(response_info2
.server_data_unavailable
);
1052 RemoveMockTransaction(&transaction
);
1055 // Tests that was_cached was set properly on a failure, even if the cached
1056 // response wasn't returned.
1057 TEST(HttpCache
, SimpleGET_CacheSignal_Failure
) {
1058 MockHttpCache cache
;
1061 MockTransaction
transaction(kSimpleGET_Transaction
);
1062 transaction
.response_headers
= "Cache-Control: no-cache\n";
1064 AddMockTransaction(&transaction
);
1065 RunTransactionTest(cache
.http_cache(), transaction
);
1066 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1067 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1068 RemoveMockTransaction(&transaction
);
1070 // Network failure with error; should fail but have was_cached set.
1071 transaction
.return_code
= net::ERR_FAILED
;
1072 AddMockTransaction(&transaction
);
1074 MockHttpRequest
request(transaction
);
1075 net::TestCompletionCallback callback
;
1076 scoped_ptr
<net::HttpTransaction
> trans
;
1077 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
1078 EXPECT_EQ(net::OK
, rv
);
1079 ASSERT_TRUE(trans
.get());
1080 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1081 EXPECT_EQ(net::ERR_FAILED
, callback
.GetResult(rv
));
1083 const net::HttpResponseInfo
* response_info
= trans
->GetResponseInfo();
1084 ASSERT_TRUE(response_info
);
1085 EXPECT_TRUE(response_info
->was_cached
);
1086 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1088 RemoveMockTransaction(&transaction
);
1091 // Confirm if we have an empty cache, a read is marked as network verified.
1092 TEST(HttpCache
, SimpleGET_NetworkAccessed_Network
) {
1093 MockHttpCache cache
;
1095 // write to the cache
1096 net::HttpResponseInfo response_info
;
1097 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
1100 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1101 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1102 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1103 EXPECT_TRUE(response_info
.network_accessed
);
1106 // Confirm if we have a fresh entry in cache, it isn't marked as
1107 // network verified.
1108 TEST(HttpCache
, SimpleGET_NetworkAccessed_Cache
) {
1109 MockHttpCache cache
;
1112 MockTransaction
transaction(kSimpleGET_Transaction
);
1114 RunTransactionTest(cache
.http_cache(), transaction
);
1115 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1116 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1118 // Re-run transaction; make sure we don't mark the network as accessed.
1119 net::HttpResponseInfo response_info
;
1120 RunTransactionTestWithResponseInfo(cache
.http_cache(), transaction
,
1123 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1124 EXPECT_FALSE(response_info
.server_data_unavailable
);
1125 EXPECT_FALSE(response_info
.network_accessed
);
1128 TEST(HttpCache
, SimpleGET_LoadBypassCache
) {
1129 MockHttpCache cache
;
1131 // Write to the cache.
1132 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1134 // Force this transaction to write to the cache again.
1135 MockTransaction
transaction(kSimpleGET_Transaction
);
1136 transaction
.load_flags
|= net::LOAD_BYPASS_CACHE
;
1138 net::CapturingBoundNetLog log
;
1139 net::LoadTimingInfo load_timing_info
;
1141 // Write to the cache.
1142 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
1145 // Check that the NetLog was filled as expected.
1146 net::CapturingNetLog::CapturedEntryList entries
;
1147 log
.GetEntries(&entries
);
1148 FilterLogEntries(&entries
);
1150 EXPECT_EQ(8u, entries
.size());
1151 EXPECT_TRUE(net::LogContainsBeginEvent(
1152 entries
, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1153 EXPECT_TRUE(net::LogContainsEndEvent(
1154 entries
, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND
));
1155 EXPECT_TRUE(net::LogContainsBeginEvent(
1156 entries
, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1157 EXPECT_TRUE(net::LogContainsEndEvent(
1158 entries
, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY
));
1159 EXPECT_TRUE(net::LogContainsBeginEvent(
1160 entries
, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1161 EXPECT_TRUE(net::LogContainsEndEvent(
1162 entries
, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY
));
1163 EXPECT_TRUE(net::LogContainsBeginEvent(
1164 entries
, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1165 EXPECT_TRUE(net::LogContainsEndEvent(
1166 entries
, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY
));
1168 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1169 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1170 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1171 TestLoadTimingNetworkRequest(load_timing_info
);
1174 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit
) {
1175 MockHttpCache cache
;
1177 // write to the cache
1178 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1180 // force this transaction to write to the cache again
1181 MockTransaction
transaction(kSimpleGET_Transaction
);
1182 transaction
.request_headers
= "pragma: no-cache\r\n";
1184 RunTransactionTest(cache
.http_cache(), transaction
);
1186 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1187 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1188 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1191 TEST(HttpCache
, SimpleGET_LoadBypassCache_Implicit2
) {
1192 MockHttpCache cache
;
1194 // write to the cache
1195 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1197 // force this transaction to write to the cache again
1198 MockTransaction
transaction(kSimpleGET_Transaction
);
1199 transaction
.request_headers
= "cache-control: no-cache\r\n";
1201 RunTransactionTest(cache
.http_cache(), transaction
);
1203 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1204 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1205 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1208 TEST(HttpCache
, SimpleGET_LoadValidateCache
) {
1209 MockHttpCache cache
;
1211 // Write to the cache.
1212 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1214 // Read from the cache.
1215 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1217 // Force this transaction to validate the cache.
1218 MockTransaction
transaction(kSimpleGET_Transaction
);
1219 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
1221 net::HttpResponseInfo response_info
;
1222 net::CapturingBoundNetLog log
;
1223 net::LoadTimingInfo load_timing_info
;
1224 RunTransactionTestWithResponseInfoAndGetTiming(
1225 cache
.http_cache(), transaction
, &response_info
, log
.bound(),
1228 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1229 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1230 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1231 EXPECT_TRUE(response_info
.network_accessed
);
1232 TestLoadTimingNetworkRequest(load_timing_info
);
1235 TEST(HttpCache
, SimpleGET_LoadValidateCache_Implicit
) {
1236 MockHttpCache cache
;
1238 // write to the cache
1239 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1241 // read from the cache
1242 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1244 // force this transaction to validate the cache
1245 MockTransaction
transaction(kSimpleGET_Transaction
);
1246 transaction
.request_headers
= "cache-control: max-age=0\r\n";
1248 RunTransactionTest(cache
.http_cache(), transaction
);
1250 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1251 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1252 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1255 static void PreserveRequestHeaders_Handler(
1256 const net::HttpRequestInfo
* request
,
1257 std::string
* response_status
,
1258 std::string
* response_headers
,
1259 std::string
* response_data
) {
1260 EXPECT_TRUE(request
->extra_headers
.HasHeader(kExtraHeaderKey
));
1263 // Tests that we don't remove extra headers for simple requests.
1264 TEST(HttpCache
, SimpleGET_PreserveRequestHeaders
) {
1265 MockHttpCache cache
;
1267 MockTransaction
transaction(kSimpleGET_Transaction
);
1268 transaction
.handler
= PreserveRequestHeaders_Handler
;
1269 transaction
.request_headers
= EXTRA_HEADER
;
1270 transaction
.response_headers
= "Cache-Control: max-age=0\n";
1271 AddMockTransaction(&transaction
);
1273 // Write, then revalidate the entry.
1274 RunTransactionTest(cache
.http_cache(), transaction
);
1275 RunTransactionTest(cache
.http_cache(), transaction
);
1277 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1278 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1279 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1280 RemoveMockTransaction(&transaction
);
1283 // Tests that we don't remove extra headers for conditionalized requests.
1284 TEST(HttpCache
, ConditionalizedGET_PreserveRequestHeaders
) {
1285 MockHttpCache cache
;
1287 // Write to the cache.
1288 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
1290 MockTransaction
transaction(kETagGET_Transaction
);
1291 transaction
.handler
= PreserveRequestHeaders_Handler
;
1292 transaction
.request_headers
= "If-None-Match: \"foopy\"\r\n"
1294 AddMockTransaction(&transaction
);
1296 RunTransactionTest(cache
.http_cache(), transaction
);
1298 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1299 EXPECT_EQ(1, cache
.disk_cache()->open_count());
1300 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1301 RemoveMockTransaction(&transaction
);
1304 TEST(HttpCache
, SimpleGET_ManyReaders
) {
1305 MockHttpCache cache
;
1307 MockHttpRequest
request(kSimpleGET_Transaction
);
1309 std::vector
<Context
*> context_list
;
1310 const int kNumTransactions
= 5;
1312 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1313 context_list
.push_back(new Context());
1314 Context
* c
= context_list
[i
];
1316 c
->result
= cache
.CreateTransaction(&c
->trans
);
1317 ASSERT_EQ(net::OK
, c
->result
);
1318 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1320 c
->result
= c
->trans
->Start(
1321 &request
, c
->callback
.callback(), net::BoundNetLog());
1324 // All requests are waiting for the active entry.
1325 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1326 Context
* c
= context_list
[i
];
1327 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, c
->trans
->GetLoadState());
1330 // Allow all requests to move from the Create queue to the active entry.
1331 base::MessageLoop::current()->RunUntilIdle();
1333 // The first request should be a writer at this point, and the subsequent
1334 // requests should be pending.
1336 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1337 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1338 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1340 // All requests depend on the writer, and the writer is between Start and
1342 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1343 Context
* c
= context_list
[i
];
1344 EXPECT_EQ(net::LOAD_STATE_IDLE
, c
->trans
->GetLoadState());
1347 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1348 Context
* c
= context_list
[i
];
1349 if (c
->result
== net::ERR_IO_PENDING
)
1350 c
->result
= c
->callback
.WaitForResult();
1351 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1354 // We should not have had to re-open the disk entry
1356 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1357 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1358 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1360 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1361 Context
* c
= context_list
[i
];
1366 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1367 // If cancelling a request is racing with another request for the same resource
1368 // finishing, we have to make sure that we remove both transactions from the
1370 TEST(HttpCache
, SimpleGET_RacingReaders
) {
1371 MockHttpCache cache
;
1373 MockHttpRequest
request(kSimpleGET_Transaction
);
1374 MockHttpRequest
reader_request(kSimpleGET_Transaction
);
1375 reader_request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
1377 std::vector
<Context
*> context_list
;
1378 const int kNumTransactions
= 5;
1380 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1381 context_list
.push_back(new Context());
1382 Context
* c
= context_list
[i
];
1384 c
->result
= cache
.CreateTransaction(&c
->trans
);
1385 ASSERT_EQ(net::OK
, c
->result
);
1387 MockHttpRequest
* this_request
= &request
;
1388 if (i
== 1 || i
== 2)
1389 this_request
= &reader_request
;
1391 c
->result
= c
->trans
->Start(
1392 this_request
, c
->callback
.callback(), net::BoundNetLog());
1395 // Allow all requests to move from the Create queue to the active entry.
1396 base::MessageLoop::current()->RunUntilIdle();
1398 // The first request should be a writer at this point, and the subsequent
1399 // requests should be pending.
1401 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1402 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1403 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1405 Context
* c
= context_list
[0];
1406 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1407 c
->result
= c
->callback
.WaitForResult();
1408 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1410 // Now we have 2 active readers and two queued transactions.
1412 EXPECT_EQ(net::LOAD_STATE_IDLE
,
1413 context_list
[2]->trans
->GetLoadState());
1414 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
,
1415 context_list
[3]->trans
->GetLoadState());
1417 c
= context_list
[1];
1418 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1419 c
->result
= c
->callback
.WaitForResult();
1420 if (c
->result
== net::OK
)
1421 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1423 // At this point we have one reader, two pending transactions and a task on
1424 // the queue to move to the next transaction. Now we cancel the request that
1425 // is the current reader, and expect the queued task to be able to start the
1428 c
= context_list
[2];
1431 for (int i
= 3; i
< kNumTransactions
; ++i
) {
1432 Context
* c
= context_list
[i
];
1433 if (c
->result
== net::ERR_IO_PENDING
)
1434 c
->result
= c
->callback
.WaitForResult();
1435 if (c
->result
== net::OK
)
1436 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1439 // We should not have had to re-open the disk entry.
1441 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1442 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1443 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1445 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1446 Context
* c
= context_list
[i
];
1451 // Tests that we can doom an entry with pending transactions and delete one of
1452 // the pending transactions before the first one completes.
1453 // See http://code.google.com/p/chromium/issues/detail?id=25588
1454 TEST(HttpCache
, SimpleGET_DoomWithPending
) {
1455 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1456 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1458 MockHttpRequest
request(kSimpleGET_Transaction
);
1459 MockHttpRequest
writer_request(kSimpleGET_Transaction
);
1460 writer_request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1462 ScopedVector
<Context
> context_list
;
1463 const int kNumTransactions
= 4;
1465 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1466 context_list
.push_back(new Context());
1467 Context
* c
= context_list
[i
];
1469 c
->result
= cache
.CreateTransaction(&c
->trans
);
1470 ASSERT_EQ(net::OK
, c
->result
);
1472 MockHttpRequest
* this_request
= &request
;
1474 this_request
= &writer_request
;
1476 c
->result
= c
->trans
->Start(
1477 this_request
, c
->callback
.callback(), net::BoundNetLog());
1480 // The first request should be a writer at this point, and the two subsequent
1481 // requests should be pending. The last request doomed the first entry.
1483 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1485 // Cancel the first queued transaction.
1486 delete context_list
[1];
1487 context_list
.get()[1] = NULL
;
1489 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1492 Context
* c
= context_list
[i
];
1493 ASSERT_EQ(net::ERR_IO_PENDING
, c
->result
);
1494 c
->result
= c
->callback
.WaitForResult();
1495 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1499 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1500 // We may attempt to delete an entry synchronously with the act of adding a new
1501 // transaction to said entry.
1502 TEST(HttpCache
, FastNoStoreGET_DoneWithPending
) {
1503 MockHttpCache cache
;
1505 // The headers will be served right from the call to Start() the request.
1506 MockHttpRequest
request(kFastNoStoreGET_Transaction
);
1507 FastTransactionServer request_handler
;
1508 AddMockTransaction(&kFastNoStoreGET_Transaction
);
1510 std::vector
<Context
*> context_list
;
1511 const int kNumTransactions
= 3;
1513 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1514 context_list
.push_back(new Context());
1515 Context
* c
= context_list
[i
];
1517 c
->result
= cache
.CreateTransaction(&c
->trans
);
1518 ASSERT_EQ(net::OK
, c
->result
);
1520 c
->result
= c
->trans
->Start(
1521 &request
, c
->callback
.callback(), net::BoundNetLog());
1524 // Allow all requests to move from the Create queue to the active entry.
1525 base::MessageLoop::current()->RunUntilIdle();
1527 // The first request should be a writer at this point, and the subsequent
1528 // requests should be pending.
1530 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1531 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1532 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1534 // Now, make sure that the second request asks for the entry not to be stored.
1535 request_handler
.set_no_store(true);
1537 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1538 Context
* c
= context_list
[i
];
1539 if (c
->result
== net::ERR_IO_PENDING
)
1540 c
->result
= c
->callback
.WaitForResult();
1541 ReadAndVerifyTransaction(c
->trans
.get(), kFastNoStoreGET_Transaction
);
1545 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1546 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1547 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1549 RemoveMockTransaction(&kFastNoStoreGET_Transaction
);
1552 TEST(HttpCache
, SimpleGET_ManyWriters_CancelFirst
) {
1553 MockHttpCache cache
;
1555 MockHttpRequest
request(kSimpleGET_Transaction
);
1557 std::vector
<Context
*> context_list
;
1558 const int kNumTransactions
= 2;
1560 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1561 context_list
.push_back(new Context());
1562 Context
* c
= context_list
[i
];
1564 c
->result
= cache
.CreateTransaction(&c
->trans
);
1565 ASSERT_EQ(net::OK
, c
->result
);
1567 c
->result
= c
->trans
->Start(
1568 &request
, c
->callback
.callback(), net::BoundNetLog());
1571 // Allow all requests to move from the Create queue to the active entry.
1572 base::MessageLoop::current()->RunUntilIdle();
1574 // The first request should be a writer at this point, and the subsequent
1575 // requests should be pending.
1577 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1578 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1579 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1581 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1582 Context
* c
= context_list
[i
];
1583 if (c
->result
== net::ERR_IO_PENDING
)
1584 c
->result
= c
->callback
.WaitForResult();
1585 // Destroy only the first transaction.
1588 context_list
[i
] = NULL
;
1592 // Complete the rest of the transactions.
1593 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1594 Context
* c
= context_list
[i
];
1595 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1598 // We should have had to re-open the disk entry.
1600 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
1601 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1602 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1604 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1605 Context
* c
= context_list
[i
];
1610 // Tests that we can cancel requests that are queued waiting to open the disk
1612 TEST(HttpCache
, SimpleGET_ManyWriters_CancelCreate
) {
1613 MockHttpCache cache
;
1615 MockHttpRequest
request(kSimpleGET_Transaction
);
1617 std::vector
<Context
*> context_list
;
1618 const int kNumTransactions
= 5;
1620 for (int i
= 0; i
< kNumTransactions
; i
++) {
1621 context_list
.push_back(new Context());
1622 Context
* c
= context_list
[i
];
1624 c
->result
= cache
.CreateTransaction(&c
->trans
);
1625 ASSERT_EQ(net::OK
, c
->result
);
1627 c
->result
= c
->trans
->Start(
1628 &request
, c
->callback
.callback(), net::BoundNetLog());
1631 // The first request should be creating the disk cache entry and the others
1632 // should be pending.
1634 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1635 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1636 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1638 // Cancel a request from the pending queue.
1639 delete context_list
[3];
1640 context_list
[3] = NULL
;
1642 // Cancel the request that is creating the entry. This will force the pending
1643 // operations to restart.
1644 delete context_list
[0];
1645 context_list
[0] = NULL
;
1647 // Complete the rest of the transactions.
1648 for (int i
= 1; i
< kNumTransactions
; i
++) {
1649 Context
* c
= context_list
[i
];
1651 c
->result
= c
->callback
.GetResult(c
->result
);
1652 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1656 // We should have had to re-create the disk entry.
1658 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1659 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1660 EXPECT_EQ(2, cache
.disk_cache()->create_count());
1662 for (int i
= 1; i
< kNumTransactions
; ++i
) {
1663 delete context_list
[i
];
1667 // Tests that we can cancel a single request to open a disk cache entry.
1668 TEST(HttpCache
, SimpleGET_CancelCreate
) {
1669 MockHttpCache cache
;
1671 MockHttpRequest
request(kSimpleGET_Transaction
);
1673 Context
* c
= new Context();
1675 c
->result
= cache
.CreateTransaction(&c
->trans
);
1676 ASSERT_EQ(net::OK
, c
->result
);
1678 c
->result
= c
->trans
->Start(
1679 &request
, c
->callback
.callback(), net::BoundNetLog());
1680 EXPECT_EQ(net::ERR_IO_PENDING
, c
->result
);
1682 // Release the reference that the mock disk cache keeps for this entry, so
1683 // that we test that the http cache handles the cancellation correctly.
1684 cache
.disk_cache()->ReleaseAll();
1687 base::MessageLoop::current()->RunUntilIdle();
1688 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1691 // Tests that we delete/create entries even if multiple requests are queued.
1692 TEST(HttpCache
, SimpleGET_ManyWriters_BypassCache
) {
1693 MockHttpCache cache
;
1695 MockHttpRequest
request(kSimpleGET_Transaction
);
1696 request
.load_flags
= net::LOAD_BYPASS_CACHE
;
1698 std::vector
<Context
*> context_list
;
1699 const int kNumTransactions
= 5;
1701 for (int i
= 0; i
< kNumTransactions
; i
++) {
1702 context_list
.push_back(new Context());
1703 Context
* c
= context_list
[i
];
1705 c
->result
= cache
.CreateTransaction(&c
->trans
);
1706 ASSERT_EQ(net::OK
, c
->result
);
1708 c
->result
= c
->trans
->Start(
1709 &request
, c
->callback
.callback(), net::BoundNetLog());
1712 // The first request should be deleting the disk cache entry and the others
1713 // should be pending.
1715 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
1716 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1717 EXPECT_EQ(0, cache
.disk_cache()->create_count());
1719 // Complete the transactions.
1720 for (int i
= 0; i
< kNumTransactions
; i
++) {
1721 Context
* c
= context_list
[i
];
1722 c
->result
= c
->callback
.GetResult(c
->result
);
1723 ReadAndVerifyTransaction(c
->trans
.get(), kSimpleGET_Transaction
);
1726 // We should have had to re-create the disk entry multiple times.
1728 EXPECT_EQ(5, cache
.network_layer()->transaction_count());
1729 EXPECT_EQ(0, cache
.disk_cache()->open_count());
1730 EXPECT_EQ(5, cache
.disk_cache()->create_count());
1732 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1733 delete context_list
[i
];
1737 // Tests that a (simulated) timeout allows transactions waiting on the cache
1738 // lock to continue.
1739 TEST(HttpCache
, SimpleGET_WriterTimeout
) {
1740 MockHttpCache cache
;
1741 cache
.BypassCacheLock();
1743 MockHttpRequest
request(kSimpleGET_Transaction
);
1745 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c1
.trans
));
1746 ASSERT_EQ(net::ERR_IO_PENDING
,
1747 c1
.trans
->Start(&request
, c1
.callback
.callback(),
1748 net::BoundNetLog()));
1749 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&c2
.trans
));
1750 ASSERT_EQ(net::ERR_IO_PENDING
,
1751 c2
.trans
->Start(&request
, c2
.callback
.callback(),
1752 net::BoundNetLog()));
1754 // The second request is queued after the first one.
1756 c2
.callback
.WaitForResult();
1757 ReadAndVerifyTransaction(c2
.trans
.get(), kSimpleGET_Transaction
);
1759 // Complete the first transaction.
1760 c1
.callback
.WaitForResult();
1761 ReadAndVerifyTransaction(c1
.trans
.get(), kSimpleGET_Transaction
);
1764 TEST(HttpCache
, SimpleGET_AbandonedCacheRead
) {
1765 MockHttpCache cache
;
1767 // write to the cache
1768 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
1770 MockHttpRequest
request(kSimpleGET_Transaction
);
1771 net::TestCompletionCallback callback
;
1773 scoped_ptr
<net::HttpTransaction
> trans
;
1774 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
1775 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
1776 if (rv
== net::ERR_IO_PENDING
)
1777 rv
= callback
.WaitForResult();
1778 ASSERT_EQ(net::OK
, rv
);
1780 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
1781 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
1782 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1784 // Test that destroying the transaction while it is reading from the cache
1788 // Make sure we pump any pending events, which should include a call to
1789 // HttpCache::Transaction::OnCacheReadCompleted.
1790 base::MessageLoop::current()->RunUntilIdle();
1793 // Tests that we can delete the HttpCache and deal with queued transactions
1794 // ("waiting for the backend" as opposed to Active or Doomed entries).
1795 TEST(HttpCache
, SimpleGET_ManyWriters_DeleteCache
) {
1796 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(
1797 new MockBackendNoCbFactory()));
1799 MockHttpRequest
request(kSimpleGET_Transaction
);
1801 std::vector
<Context
*> context_list
;
1802 const int kNumTransactions
= 5;
1804 for (int i
= 0; i
< kNumTransactions
; i
++) {
1805 context_list
.push_back(new Context());
1806 Context
* c
= context_list
[i
];
1808 c
->result
= cache
->CreateTransaction(&c
->trans
);
1809 ASSERT_EQ(net::OK
, c
->result
);
1811 c
->result
= c
->trans
->Start(
1812 &request
, c
->callback
.callback(), net::BoundNetLog());
1815 // The first request should be creating the disk cache entry and the others
1816 // should be pending.
1818 EXPECT_EQ(0, cache
->network_layer()->transaction_count());
1819 EXPECT_EQ(0, cache
->disk_cache()->open_count());
1820 EXPECT_EQ(0, cache
->disk_cache()->create_count());
1824 // There is not much to do with the transactions at this point... they are
1825 // waiting for a callback that will not fire.
1826 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1827 delete context_list
[i
];
1831 // Tests that we queue requests when initializing the backend.
1832 TEST(HttpCache
, SimpleGET_WaitForBackend
) {
1833 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1834 MockHttpCache
cache(factory
);
1836 MockHttpRequest
request0(kSimpleGET_Transaction
);
1837 MockHttpRequest
request1(kTypicalGET_Transaction
);
1838 MockHttpRequest
request2(kETagGET_Transaction
);
1840 std::vector
<Context
*> context_list
;
1841 const int kNumTransactions
= 3;
1843 for (int i
= 0; i
< kNumTransactions
; i
++) {
1844 context_list
.push_back(new Context());
1845 Context
* c
= context_list
[i
];
1847 c
->result
= cache
.CreateTransaction(&c
->trans
);
1848 ASSERT_EQ(net::OK
, c
->result
);
1851 context_list
[0]->result
= context_list
[0]->trans
->Start(
1852 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1853 context_list
[1]->result
= context_list
[1]->trans
->Start(
1854 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1855 context_list
[2]->result
= context_list
[2]->trans
->Start(
1856 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1858 // Just to make sure that everything is still pending.
1859 base::MessageLoop::current()->RunUntilIdle();
1861 // The first request should be creating the disk cache.
1862 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1864 factory
->FinishCreation();
1866 base::MessageLoop::current()->RunUntilIdle();
1867 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
1868 EXPECT_EQ(3, cache
.disk_cache()->create_count());
1870 for (int i
= 0; i
< kNumTransactions
; ++i
) {
1871 EXPECT_TRUE(context_list
[i
]->callback
.have_result());
1872 delete context_list
[i
];
1876 // Tests that we can cancel requests that are queued waiting for the backend
1877 // to be initialized.
1878 TEST(HttpCache
, SimpleGET_WaitForBackend_CancelCreate
) {
1879 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1880 MockHttpCache
cache(factory
);
1882 MockHttpRequest
request0(kSimpleGET_Transaction
);
1883 MockHttpRequest
request1(kTypicalGET_Transaction
);
1884 MockHttpRequest
request2(kETagGET_Transaction
);
1886 std::vector
<Context
*> context_list
;
1887 const int kNumTransactions
= 3;
1889 for (int i
= 0; i
< kNumTransactions
; i
++) {
1890 context_list
.push_back(new Context());
1891 Context
* c
= context_list
[i
];
1893 c
->result
= cache
.CreateTransaction(&c
->trans
);
1894 ASSERT_EQ(net::OK
, c
->result
);
1897 context_list
[0]->result
= context_list
[0]->trans
->Start(
1898 &request0
, context_list
[0]->callback
.callback(), net::BoundNetLog());
1899 context_list
[1]->result
= context_list
[1]->trans
->Start(
1900 &request1
, context_list
[1]->callback
.callback(), net::BoundNetLog());
1901 context_list
[2]->result
= context_list
[2]->trans
->Start(
1902 &request2
, context_list
[2]->callback
.callback(), net::BoundNetLog());
1904 // Just to make sure that everything is still pending.
1905 base::MessageLoop::current()->RunUntilIdle();
1907 // The first request should be creating the disk cache.
1908 EXPECT_FALSE(context_list
[0]->callback
.have_result());
1910 // Cancel a request from the pending queue.
1911 delete context_list
[1];
1912 context_list
[1] = NULL
;
1914 // Cancel the request that is creating the entry.
1915 delete context_list
[0];
1916 context_list
[0] = NULL
;
1918 // Complete the last transaction.
1919 factory
->FinishCreation();
1921 context_list
[2]->result
=
1922 context_list
[2]->callback
.GetResult(context_list
[2]->result
);
1923 ReadAndVerifyTransaction(context_list
[2]->trans
.get(), kETagGET_Transaction
);
1925 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
1926 EXPECT_EQ(1, cache
.disk_cache()->create_count());
1928 delete context_list
[2];
1931 // Tests that we can delete the cache while creating the backend.
1932 TEST(HttpCache
, DeleteCacheWaitingForBackend
) {
1933 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1934 scoped_ptr
<MockHttpCache
> cache(new MockHttpCache(factory
));
1936 MockHttpRequest
request(kSimpleGET_Transaction
);
1938 scoped_ptr
<Context
> c(new Context());
1939 c
->result
= cache
->CreateTransaction(&c
->trans
);
1940 ASSERT_EQ(net::OK
, c
->result
);
1942 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1944 // Just to make sure that everything is still pending.
1945 base::MessageLoop::current()->RunUntilIdle();
1947 // The request should be creating the disk cache.
1948 EXPECT_FALSE(c
->callback
.have_result());
1950 // We cannot call FinishCreation because the factory itself will go away with
1951 // the cache, so grab the callback and attempt to use it.
1952 net::CompletionCallback callback
= factory
->callback();
1953 scoped_ptr
<disk_cache::Backend
>* backend
= factory
->backend();
1956 base::MessageLoop::current()->RunUntilIdle();
1959 callback
.Run(net::ERR_ABORTED
);
1962 // Tests that we can delete the cache while creating the backend, from within
1963 // one of the callbacks.
1964 TEST(HttpCache
, DeleteCacheWaitingForBackend2
) {
1965 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
1966 MockHttpCache
* cache
= new MockHttpCache(factory
);
1968 DeleteCacheCompletionCallback
cb(cache
);
1969 disk_cache::Backend
* backend
;
1970 int rv
= cache
->http_cache()->GetBackend(&backend
, cb
.callback());
1971 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1973 // Now let's queue a regular transaction
1974 MockHttpRequest
request(kSimpleGET_Transaction
);
1976 scoped_ptr
<Context
> c(new Context());
1977 c
->result
= cache
->CreateTransaction(&c
->trans
);
1978 ASSERT_EQ(net::OK
, c
->result
);
1980 c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
1982 // And another direct backend request.
1983 net::TestCompletionCallback cb2
;
1984 rv
= cache
->http_cache()->GetBackend(&backend
, cb2
.callback());
1985 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
1987 // Just to make sure that everything is still pending.
1988 base::MessageLoop::current()->RunUntilIdle();
1990 // The request should be queued.
1991 EXPECT_FALSE(c
->callback
.have_result());
1993 // Generate the callback.
1994 factory
->FinishCreation();
1995 rv
= cb
.WaitForResult();
1997 // The cache should be gone by now.
1998 base::MessageLoop::current()->RunUntilIdle();
1999 EXPECT_EQ(net::OK
, c
->callback
.GetResult(c
->result
));
2000 EXPECT_FALSE(cb2
.have_result());
2003 TEST(HttpCache
, TypicalGET_ConditionalRequest
) {
2004 MockHttpCache cache
;
2006 // write to the cache
2007 RunTransactionTest(cache
.http_cache(), kTypicalGET_Transaction
);
2009 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2010 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2011 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2013 // Get the same URL again, but this time we expect it to result
2014 // in a conditional request.
2015 net::CapturingBoundNetLog log
;
2016 net::LoadTimingInfo load_timing_info
;
2017 RunTransactionTestAndGetTiming(cache
.http_cache(), kTypicalGET_Transaction
,
2018 log
.bound(), &load_timing_info
);
2020 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2021 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2022 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2023 TestLoadTimingNetworkRequest(load_timing_info
);
2026 static void ETagGet_ConditionalRequest_Handler(
2027 const net::HttpRequestInfo
* request
,
2028 std::string
* response_status
,
2029 std::string
* response_headers
,
2030 std::string
* response_data
) {
2032 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2033 response_status
->assign("HTTP/1.1 304 Not Modified");
2034 response_headers
->assign(kETagGET_Transaction
.response_headers
);
2035 response_data
->clear();
2038 TEST(HttpCache
, ETagGET_ConditionalRequest_304
) {
2039 MockHttpCache cache
;
2041 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2043 // write to the cache
2044 RunTransactionTest(cache
.http_cache(), transaction
);
2046 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2047 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2048 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2050 // Get the same URL again, but this time we expect it to result
2051 // in a conditional request.
2052 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2053 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
2054 net::CapturingBoundNetLog log
;
2055 net::LoadTimingInfo load_timing_info
;
2056 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2059 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2060 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2061 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2062 TestLoadTimingNetworkRequest(load_timing_info
);
2065 class RevalidationServer
{
2067 RevalidationServer() {
2068 s_etag_used_
= false;
2069 s_last_modified_used_
= false;
2072 bool EtagUsed() { return s_etag_used_
; }
2073 bool LastModifiedUsed() { return s_last_modified_used_
; }
2075 static void Handler(const net::HttpRequestInfo
* request
,
2076 std::string
* response_status
,
2077 std::string
* response_headers
,
2078 std::string
* response_data
);
2081 static bool s_etag_used_
;
2082 static bool s_last_modified_used_
;
2084 bool RevalidationServer::s_etag_used_
= false;
2085 bool RevalidationServer::s_last_modified_used_
= false;
2087 void RevalidationServer::Handler(const net::HttpRequestInfo
* request
,
2088 std::string
* response_status
,
2089 std::string
* response_headers
,
2090 std::string
* response_data
) {
2091 if (request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
))
2092 s_etag_used_
= true;
2094 if (request
->extra_headers
.HasHeader(
2095 net::HttpRequestHeaders::kIfModifiedSince
)) {
2096 s_last_modified_used_
= true;
2099 if (s_etag_used_
|| s_last_modified_used_
) {
2100 response_status
->assign("HTTP/1.1 304 Not Modified");
2101 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2102 response_data
->clear();
2104 response_status
->assign(kTypicalGET_Transaction
.status
);
2105 response_headers
->assign(kTypicalGET_Transaction
.response_headers
);
2106 response_data
->assign(kTypicalGET_Transaction
.data
);
2110 // Tests revalidation after a vary match.
2111 TEST(HttpCache
, GET_ValidateCache_VaryMatch
) {
2112 MockHttpCache cache
;
2114 // Write to the cache.
2115 MockTransaction
transaction(kTypicalGET_Transaction
);
2116 transaction
.request_headers
= "Foo: bar\r\n";
2117 transaction
.response_headers
=
2118 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2119 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2121 "Cache-Control: max-age=0\n"
2123 AddMockTransaction(&transaction
);
2124 RunTransactionTest(cache
.http_cache(), transaction
);
2126 // Read from the cache.
2127 RevalidationServer server
;
2128 transaction
.handler
= server
.Handler
;
2129 net::CapturingBoundNetLog log
;
2130 net::LoadTimingInfo load_timing_info
;
2131 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2134 EXPECT_TRUE(server
.EtagUsed());
2135 EXPECT_TRUE(server
.LastModifiedUsed());
2136 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2137 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2138 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2139 TestLoadTimingNetworkRequest(load_timing_info
);
2140 RemoveMockTransaction(&transaction
);
2143 // Tests revalidation after a vary mismatch if etag is present.
2144 TEST(HttpCache
, GET_ValidateCache_VaryMismatch
) {
2145 MockHttpCache cache
;
2147 // Write to the cache.
2148 MockTransaction
transaction(kTypicalGET_Transaction
);
2149 transaction
.request_headers
= "Foo: bar\r\n";
2150 transaction
.response_headers
=
2151 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2152 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2154 "Cache-Control: max-age=0\n"
2156 AddMockTransaction(&transaction
);
2157 RunTransactionTest(cache
.http_cache(), transaction
);
2159 // Read from the cache and revalidate the entry.
2160 RevalidationServer server
;
2161 transaction
.handler
= server
.Handler
;
2162 transaction
.request_headers
= "Foo: none\r\n";
2163 net::CapturingBoundNetLog log
;
2164 net::LoadTimingInfo load_timing_info
;
2165 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2168 EXPECT_TRUE(server
.EtagUsed());
2169 EXPECT_FALSE(server
.LastModifiedUsed());
2170 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2171 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2172 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2173 TestLoadTimingNetworkRequest(load_timing_info
);
2174 RemoveMockTransaction(&transaction
);
2177 // Tests lack of revalidation after a vary mismatch and no etag.
2178 TEST(HttpCache
, GET_DontValidateCache_VaryMismatch
) {
2179 MockHttpCache cache
;
2181 // Write to the cache.
2182 MockTransaction
transaction(kTypicalGET_Transaction
);
2183 transaction
.request_headers
= "Foo: bar\r\n";
2184 transaction
.response_headers
=
2185 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2186 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2187 "Cache-Control: max-age=0\n"
2189 AddMockTransaction(&transaction
);
2190 RunTransactionTest(cache
.http_cache(), transaction
);
2192 // Read from the cache and don't revalidate the entry.
2193 RevalidationServer server
;
2194 transaction
.handler
= server
.Handler
;
2195 transaction
.request_headers
= "Foo: none\r\n";
2196 net::CapturingBoundNetLog log
;
2197 net::LoadTimingInfo load_timing_info
;
2198 RunTransactionTestAndGetTiming(cache
.http_cache(), transaction
, log
.bound(),
2201 EXPECT_FALSE(server
.EtagUsed());
2202 EXPECT_FALSE(server
.LastModifiedUsed());
2203 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2204 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2205 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2206 TestLoadTimingNetworkRequest(load_timing_info
);
2207 RemoveMockTransaction(&transaction
);
2210 // Tests that a new vary header provided when revalidating an entry is saved.
2211 TEST(HttpCache
, GET_ValidateCache_VaryMatch_UpdateVary
) {
2212 MockHttpCache cache
;
2214 // Write to the cache.
2215 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2216 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2217 transaction
.response_headers
=
2219 "Cache-Control: max-age=0\n"
2221 RunTransactionTest(cache
.http_cache(), transaction
);
2223 // Validate the entry and change the vary field in the response.
2224 transaction
.request_headers
= "Foo: bar\r\n Name: none\r\n";
2225 transaction
.status
= "HTTP/1.1 304 Not Modified";
2226 transaction
.response_headers
=
2228 "Cache-Control: max-age=3600\n"
2230 RunTransactionTest(cache
.http_cache(), transaction
);
2232 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2233 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2234 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2236 // Make sure that the ActiveEntry is gone.
2237 base::RunLoop().RunUntilIdle();
2239 // Generate a vary mismatch.
2240 transaction
.request_headers
= "Foo: bar\r\n Name: bar\r\n";
2241 RunTransactionTest(cache
.http_cache(), transaction
);
2243 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2244 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2248 // Tests that new request headers causing a vary mismatch are paired with the
2249 // new response when the server says the old response can be used.
2250 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_UpdateRequestHeader
) {
2251 MockHttpCache cache
;
2253 // Write to the cache.
2254 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2255 transaction
.request_headers
= "Foo: bar\r\n";
2256 transaction
.response_headers
=
2258 "Cache-Control: max-age=3600\n"
2260 RunTransactionTest(cache
.http_cache(), transaction
);
2262 // Vary-mismatch validation receives 304.
2263 transaction
.request_headers
= "Foo: none\r\n";
2264 transaction
.status
= "HTTP/1.1 304 Not Modified";
2265 RunTransactionTest(cache
.http_cache(), transaction
);
2267 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2268 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2269 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2271 // Make sure that the ActiveEntry is gone.
2272 base::RunLoop().RunUntilIdle();
2274 // Generate a vary mismatch.
2275 transaction
.request_headers
= "Foo: bar\r\n";
2276 RunTransactionTest(cache
.http_cache(), transaction
);
2278 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2279 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2280 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2283 // Tests that a 304 without vary headers doesn't delete the previously stored
2284 // vary data after a vary match revalidation.
2285 TEST(HttpCache
, GET_ValidateCache_VaryMatch_DontDeleteVary
) {
2286 MockHttpCache cache
;
2288 // Write to the cache.
2289 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2290 transaction
.request_headers
= "Foo: bar\r\n";
2291 transaction
.response_headers
=
2293 "Cache-Control: max-age=0\n"
2295 RunTransactionTest(cache
.http_cache(), transaction
);
2297 // Validate the entry and remove the vary field in the response.
2298 transaction
.status
= "HTTP/1.1 304 Not Modified";
2299 transaction
.response_headers
=
2301 "Cache-Control: max-age=3600\n";
2302 RunTransactionTest(cache
.http_cache(), transaction
);
2304 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2305 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2306 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2308 // Make sure that the ActiveEntry is gone.
2309 base::RunLoop().RunUntilIdle();
2311 // Generate a vary mismatch.
2312 transaction
.request_headers
= "Foo: none\r\n";
2313 RunTransactionTest(cache
.http_cache(), transaction
);
2315 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2316 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2317 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2320 // Tests that a 304 without vary headers doesn't delete the previously stored
2321 // vary data after a vary mismatch.
2322 TEST(HttpCache
, GET_ValidateCache_VaryMismatch_DontDeleteVary
) {
2323 MockHttpCache cache
;
2325 // Write to the cache.
2326 ScopedMockTransaction
transaction(kTypicalGET_Transaction
);
2327 transaction
.request_headers
= "Foo: bar\r\n";
2328 transaction
.response_headers
=
2330 "Cache-Control: max-age=3600\n"
2332 RunTransactionTest(cache
.http_cache(), transaction
);
2334 // Vary-mismatch validation receives 304 and no vary header.
2335 transaction
.request_headers
= "Foo: none\r\n";
2336 transaction
.status
= "HTTP/1.1 304 Not Modified";
2337 transaction
.response_headers
=
2339 "Cache-Control: max-age=3600\n";
2340 RunTransactionTest(cache
.http_cache(), transaction
);
2342 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2343 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2344 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2346 // Make sure that the ActiveEntry is gone.
2347 base::RunLoop().RunUntilIdle();
2349 // Generate a vary mismatch.
2350 transaction
.request_headers
= "Foo: bar\r\n";
2351 RunTransactionTest(cache
.http_cache(), transaction
);
2353 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2354 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2355 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2358 static void ETagGet_UnconditionalRequest_Handler(
2359 const net::HttpRequestInfo
* request
,
2360 std::string
* response_status
,
2361 std::string
* response_headers
,
2362 std::string
* response_data
) {
2364 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2367 TEST(HttpCache
, ETagGET_Http10
) {
2368 MockHttpCache cache
;
2370 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2371 transaction
.status
= "HTTP/1.0 200 OK";
2373 // Write to the cache.
2374 RunTransactionTest(cache
.http_cache(), transaction
);
2376 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2377 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2378 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2380 // Get the same URL again, without generating a conditional request.
2381 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2382 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2383 RunTransactionTest(cache
.http_cache(), transaction
);
2385 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2386 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2387 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2390 TEST(HttpCache
, ETagGET_Http10_Range
) {
2391 MockHttpCache cache
;
2393 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2394 transaction
.status
= "HTTP/1.0 200 OK";
2396 // Write to the cache.
2397 RunTransactionTest(cache
.http_cache(), transaction
);
2399 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2400 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2401 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2403 // Get the same URL again, but use a byte range request.
2404 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2405 transaction
.handler
= ETagGet_UnconditionalRequest_Handler
;
2406 transaction
.request_headers
= "Range: bytes = 5-\r\n";
2407 RunTransactionTest(cache
.http_cache(), transaction
);
2409 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2410 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2411 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2414 static void ETagGet_ConditionalRequest_NoStore_Handler(
2415 const net::HttpRequestInfo
* request
,
2416 std::string
* response_status
,
2417 std::string
* response_headers
,
2418 std::string
* response_data
) {
2420 request
->extra_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
));
2421 response_status
->assign("HTTP/1.1 304 Not Modified");
2422 response_headers
->assign("Cache-Control: no-store\n");
2423 response_data
->clear();
2426 TEST(HttpCache
, ETagGET_ConditionalRequest_304_NoStore
) {
2427 MockHttpCache cache
;
2429 ScopedMockTransaction
transaction(kETagGET_Transaction
);
2431 // Write to the cache.
2432 RunTransactionTest(cache
.http_cache(), transaction
);
2434 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2435 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2436 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2438 // Get the same URL again, but this time we expect it to result
2439 // in a conditional request.
2440 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
2441 transaction
.handler
= ETagGet_ConditionalRequest_NoStore_Handler
;
2442 RunTransactionTest(cache
.http_cache(), transaction
);
2444 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2445 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2446 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2448 ScopedMockTransaction
transaction2(kETagGET_Transaction
);
2450 // Write to the cache again. This should create a new entry.
2451 RunTransactionTest(cache
.http_cache(), transaction2
);
2453 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
2454 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2455 EXPECT_EQ(2, cache
.disk_cache()->create_count());
2458 // Helper that does 4 requests using HttpCache:
2460 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2461 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2462 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2464 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2466 static void ConditionalizedRequestUpdatesCacheHelper(
2467 const Response
& net_response_1
,
2468 const Response
& net_response_2
,
2469 const Response
& cached_response_2
,
2470 const char* extra_request_headers
) {
2471 MockHttpCache cache
;
2473 // The URL we will be requesting.
2474 const char kUrl
[] = "http://foobar.com/main.css";
2476 // Junk network response.
2477 static const Response kUnexpectedResponse
= {
2478 "HTTP/1.1 500 Unexpected",
2479 "Server: unexpected_header",
2483 // We will control the network layer's responses for |kUrl| using
2484 // |mock_network_response|.
2485 MockTransaction mock_network_response
= { 0 };
2486 mock_network_response
.url
= kUrl
;
2487 AddMockTransaction(&mock_network_response
);
2489 // Request |kUrl| for the first time. It should hit the network and
2490 // receive |kNetResponse1|, which it saves into the HTTP cache.
2492 MockTransaction request
= { 0 };
2494 request
.method
= "GET";
2495 request
.request_headers
= "";
2497 net_response_1
.AssignTo(&mock_network_response
); // Network mock.
2498 net_response_1
.AssignTo(&request
); // Expected result.
2500 std::string response_headers
;
2501 RunTransactionTestWithResponse(
2502 cache
.http_cache(), request
, &response_headers
);
2504 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2505 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2506 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2507 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2509 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2510 // cache, so we don't hit the network.
2512 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2514 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2515 net_response_1
.AssignTo(&request
); // Expected result.
2517 RunTransactionTestWithResponse(
2518 cache
.http_cache(), request
, &response_headers
);
2520 EXPECT_EQ(net_response_1
.status_and_headers(), response_headers
);
2521 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2522 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2523 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2525 // Request |kUrl| yet again, but this time give the request an
2526 // "If-Modified-Since" header. This will cause the request to re-hit the
2527 // network. However now the network response is going to be
2528 // different -- this simulates a change made to the CSS file.
2530 request
.request_headers
= extra_request_headers
;
2531 request
.load_flags
= net::LOAD_NORMAL
;
2533 net_response_2
.AssignTo(&mock_network_response
); // Network mock.
2534 net_response_2
.AssignTo(&request
); // Expected result.
2536 RunTransactionTestWithResponse(
2537 cache
.http_cache(), request
, &response_headers
);
2539 EXPECT_EQ(net_response_2
.status_and_headers(), response_headers
);
2540 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2541 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2542 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2544 // Finally, request |kUrl| again. This request should be serviced from
2545 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2546 // and NOT |kNetResponse1|. The previous step should have replaced the
2547 // value in the cache with the modified response.
2549 request
.request_headers
= "";
2550 request
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2552 kUnexpectedResponse
.AssignTo(&mock_network_response
); // Network mock.
2553 cached_response_2
.AssignTo(&request
); // Expected result.
2555 RunTransactionTestWithResponse(
2556 cache
.http_cache(), request
, &response_headers
);
2558 EXPECT_EQ(cached_response_2
.status_and_headers(), response_headers
);
2559 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
2560 EXPECT_EQ(2, cache
.disk_cache()->open_count());
2561 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2563 RemoveMockTransaction(&mock_network_response
);
2566 // Check that when an "if-modified-since" header is attached
2567 // to the request, the result still updates the cached entry.
2568 TEST(HttpCache
, ConditionalizedRequestUpdatesCache1
) {
2569 // First network response for |kUrl|.
2570 static const Response kNetResponse1
= {
2572 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2573 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2577 // Second network response for |kUrl|.
2578 static const Response kNetResponse2
= {
2580 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2581 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2585 const char extra_headers
[] =
2586 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2588 ConditionalizedRequestUpdatesCacheHelper(
2589 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2592 // Check that when an "if-none-match" header is attached
2593 // to the request, the result updates the cached entry.
2594 TEST(HttpCache
, ConditionalizedRequestUpdatesCache2
) {
2595 // First network response for |kUrl|.
2596 static const Response kNetResponse1
= {
2598 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2600 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2604 // Second network response for |kUrl|.
2605 static const Response kNetResponse2
= {
2607 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2609 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2613 const char extra_headers
[] = "If-None-Match: \"ETAG1\"\r\n";
2615 ConditionalizedRequestUpdatesCacheHelper(
2616 kNetResponse1
, kNetResponse2
, kNetResponse2
, extra_headers
);
2619 // Check that when an "if-modified-since" header is attached
2620 // to a request, the 304 (not modified result) result updates the cached
2621 // headers, and the 304 response is returned rather than the cached response.
2622 TEST(HttpCache
, ConditionalizedRequestUpdatesCache3
) {
2623 // First network response for |kUrl|.
2624 static const Response kNetResponse1
= {
2626 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2628 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2632 // Second network response for |kUrl|.
2633 static const Response kNetResponse2
= {
2634 "HTTP/1.1 304 Not Modified",
2635 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2637 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2641 static const Response kCachedResponse2
= {
2643 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2645 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2649 const char extra_headers
[] =
2650 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2652 ConditionalizedRequestUpdatesCacheHelper(
2653 kNetResponse1
, kNetResponse2
, kCachedResponse2
, extra_headers
);
2656 // Test that when doing an externally conditionalized if-modified-since
2657 // and there is no corresponding cache entry, a new cache entry is NOT
2658 // created (304 response).
2659 TEST(HttpCache
, ConditionalizedRequestUpdatesCache4
) {
2660 MockHttpCache cache
;
2662 const char kUrl
[] = "http://foobar.com/main.css";
2664 static const Response kNetResponse
= {
2665 "HTTP/1.1 304 Not Modified",
2666 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2667 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2671 const char kExtraRequestHeaders
[] =
2672 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2674 // We will control the network layer's responses for |kUrl| using
2675 // |mock_network_response|.
2676 MockTransaction mock_network_response
= { 0 };
2677 mock_network_response
.url
= kUrl
;
2678 AddMockTransaction(&mock_network_response
);
2680 MockTransaction request
= { 0 };
2682 request
.method
= "GET";
2683 request
.request_headers
= kExtraRequestHeaders
;
2685 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2686 kNetResponse
.AssignTo(&request
); // Expected result.
2688 std::string response_headers
;
2689 RunTransactionTestWithResponse(
2690 cache
.http_cache(), request
, &response_headers
);
2692 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2693 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2694 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2695 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2697 RemoveMockTransaction(&mock_network_response
);
2700 // Test that when doing an externally conditionalized if-modified-since
2701 // and there is no corresponding cache entry, a new cache entry is NOT
2702 // created (200 response).
2703 TEST(HttpCache
, ConditionalizedRequestUpdatesCache5
) {
2704 MockHttpCache cache
;
2706 const char kUrl
[] = "http://foobar.com/main.css";
2708 static const Response kNetResponse
= {
2710 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2711 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2715 const char kExtraRequestHeaders
[] =
2716 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2718 // We will control the network layer's responses for |kUrl| using
2719 // |mock_network_response|.
2720 MockTransaction mock_network_response
= { 0 };
2721 mock_network_response
.url
= kUrl
;
2722 AddMockTransaction(&mock_network_response
);
2724 MockTransaction request
= { 0 };
2726 request
.method
= "GET";
2727 request
.request_headers
= kExtraRequestHeaders
;
2729 kNetResponse
.AssignTo(&mock_network_response
); // Network mock.
2730 kNetResponse
.AssignTo(&request
); // Expected result.
2732 std::string response_headers
;
2733 RunTransactionTestWithResponse(
2734 cache
.http_cache(), request
, &response_headers
);
2736 EXPECT_EQ(kNetResponse
.status_and_headers(), response_headers
);
2737 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2738 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2739 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2741 RemoveMockTransaction(&mock_network_response
);
2744 // Test that when doing an externally conditionalized if-modified-since
2745 // if the date does not match the cache entry's last-modified date,
2746 // then we do NOT use the response (304) to update the cache.
2747 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2748 TEST(HttpCache
, ConditionalizedRequestUpdatesCache6
) {
2749 static const Response kNetResponse1
= {
2751 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2753 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2757 // Second network response for |kUrl|.
2758 static const Response kNetResponse2
= {
2759 "HTTP/1.1 304 Not Modified",
2760 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2762 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2766 // This is two days in the future from the original response's last-modified
2768 const char kExtraRequestHeaders
[] =
2769 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2771 ConditionalizedRequestUpdatesCacheHelper(
2772 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2775 // Test that when doing an externally conditionalized if-none-match
2776 // if the etag does not match the cache entry's etag, then we do not use the
2777 // response (304) to update the cache.
2778 TEST(HttpCache
, ConditionalizedRequestUpdatesCache7
) {
2779 static const Response kNetResponse1
= {
2781 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2783 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2787 // Second network response for |kUrl|.
2788 static const Response kNetResponse2
= {
2789 "HTTP/1.1 304 Not Modified",
2790 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2792 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2796 // Different etag from original response.
2797 const char kExtraRequestHeaders
[] = "If-None-Match: \"Foo2\"\r\n";
2799 ConditionalizedRequestUpdatesCacheHelper(
2800 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2803 // Test that doing an externally conditionalized request with both if-none-match
2804 // and if-modified-since updates the cache.
2805 TEST(HttpCache
, ConditionalizedRequestUpdatesCache8
) {
2806 static const Response kNetResponse1
= {
2808 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2810 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2814 // Second network response for |kUrl|.
2815 static const Response kNetResponse2
= {
2817 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2819 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2823 const char kExtraRequestHeaders
[] =
2824 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2825 "If-None-Match: \"Foo1\"\r\n";
2827 ConditionalizedRequestUpdatesCacheHelper(
2828 kNetResponse1
, kNetResponse2
, kNetResponse2
, kExtraRequestHeaders
);
2831 // Test that doing an externally conditionalized request with both if-none-match
2832 // and if-modified-since does not update the cache with only one match.
2833 TEST(HttpCache
, ConditionalizedRequestUpdatesCache9
) {
2834 static const Response kNetResponse1
= {
2836 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2838 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2842 // Second network response for |kUrl|.
2843 static const Response kNetResponse2
= {
2845 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2847 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2851 // The etag doesn't match what we have stored.
2852 const char kExtraRequestHeaders
[] =
2853 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2854 "If-None-Match: \"Foo2\"\r\n";
2856 ConditionalizedRequestUpdatesCacheHelper(
2857 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2860 // Test that doing an externally conditionalized request with both if-none-match
2861 // and if-modified-since does not update the cache with only one match.
2862 TEST(HttpCache
, ConditionalizedRequestUpdatesCache10
) {
2863 static const Response kNetResponse1
= {
2865 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2867 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2871 // Second network response for |kUrl|.
2872 static const Response kNetResponse2
= {
2874 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2876 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2880 // The modification date doesn't match what we have stored.
2881 const char kExtraRequestHeaders
[] =
2882 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2883 "If-None-Match: \"Foo1\"\r\n";
2885 ConditionalizedRequestUpdatesCacheHelper(
2886 kNetResponse1
, kNetResponse2
, kNetResponse1
, kExtraRequestHeaders
);
2889 TEST(HttpCache
, UrlContainingHash
) {
2890 MockHttpCache cache
;
2892 // Do a typical GET request -- should write an entry into our cache.
2893 MockTransaction
trans(kTypicalGET_Transaction
);
2894 RunTransactionTest(cache
.http_cache(), trans
);
2896 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2897 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2898 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2900 // Request the same URL, but this time with a reference section (hash).
2901 // Since the cache key strips the hash sections, this should be a cache hit.
2902 std::string url_with_hash
= std::string(trans
.url
) + "#multiple#hashes";
2903 trans
.url
= url_with_hash
.c_str();
2904 trans
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
2906 RunTransactionTest(cache
.http_cache(), trans
);
2908 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2909 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2910 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2913 // Tests that we skip the cache for POST requests that do not have an upload
2915 TEST(HttpCache
, SimplePOST_SkipsCache
) {
2916 MockHttpCache cache
;
2918 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2920 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2921 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2922 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2925 // Tests POST handling with a disabled cache (no DCHECK).
2926 TEST(HttpCache
, SimplePOST_DisabledCache
) {
2927 MockHttpCache cache
;
2928 cache
.http_cache()->set_mode(net::HttpCache::Mode::DISABLE
);
2930 RunTransactionTest(cache
.http_cache(), kSimplePOST_Transaction
);
2932 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2933 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2934 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2937 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Miss
) {
2938 MockHttpCache cache
;
2940 MockTransaction
transaction(kSimplePOST_Transaction
);
2941 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2943 MockHttpRequest
request(transaction
);
2944 net::TestCompletionCallback callback
;
2946 scoped_ptr
<net::HttpTransaction
> trans
;
2947 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
2948 ASSERT_TRUE(trans
.get());
2950 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
2951 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
2955 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
2956 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2957 EXPECT_EQ(0, cache
.disk_cache()->create_count());
2960 TEST(HttpCache
, SimplePOST_LoadOnlyFromCache_Hit
) {
2961 MockHttpCache cache
;
2963 // Test that we hit the cache for POST requests.
2965 MockTransaction
transaction(kSimplePOST_Transaction
);
2967 const int64 kUploadId
= 1; // Just a dummy value.
2969 ScopedVector
<net::UploadElementReader
> element_readers
;
2970 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
2971 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
2973 MockHttpRequest
request(transaction
);
2974 request
.upload_data_stream
= &upload_data_stream
;
2976 // Populate the cache.
2977 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2979 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2980 EXPECT_EQ(0, cache
.disk_cache()->open_count());
2981 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2984 request
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
2985 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
2987 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
2988 EXPECT_EQ(1, cache
.disk_cache()->open_count());
2989 EXPECT_EQ(1, cache
.disk_cache()->create_count());
2992 // Test that we don't hit the cache for POST requests if there is a byte range.
2993 TEST(HttpCache
, SimplePOST_WithRanges
) {
2994 MockHttpCache cache
;
2996 MockTransaction
transaction(kSimplePOST_Transaction
);
2997 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
2999 const int64 kUploadId
= 1; // Just a dummy value.
3001 ScopedVector
<net::UploadElementReader
> element_readers
;
3002 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3003 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(),
3006 MockHttpRequest
request(transaction
);
3007 request
.upload_data_stream
= &upload_data_stream
;
3009 // Attempt to populate the cache.
3010 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3012 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3013 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3014 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3017 // Tests that a POST is cached separately from a previously cached GET.
3018 TEST(HttpCache
, SimplePOST_SeparateCache
) {
3019 MockHttpCache cache
;
3021 ScopedVector
<net::UploadElementReader
> element_readers
;
3022 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3023 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3025 MockTransaction
transaction(kSimplePOST_Transaction
);
3026 MockHttpRequest
req1(transaction
);
3027 req1
.upload_data_stream
= &upload_data_stream
;
3029 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3031 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3032 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3033 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3035 transaction
.method
= "GET";
3036 MockHttpRequest
req2(transaction
);
3038 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3040 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3041 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3042 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3045 // Tests that a successful POST invalidates a previously cached GET.
3046 TEST(HttpCache
, SimplePOST_Invalidate_205
) {
3047 MockHttpCache cache
;
3049 MockTransaction
transaction(kSimpleGET_Transaction
);
3050 AddMockTransaction(&transaction
);
3051 MockHttpRequest
req1(transaction
);
3053 // Attempt to populate the cache.
3054 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3056 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3057 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3058 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3060 ScopedVector
<net::UploadElementReader
> element_readers
;
3061 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3062 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3064 transaction
.method
= "POST";
3065 transaction
.status
= "HTTP/1.1 205 No Content";
3066 MockHttpRequest
req2(transaction
);
3067 req2
.upload_data_stream
= &upload_data_stream
;
3069 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3071 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3072 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3073 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3075 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3077 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3078 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3079 EXPECT_EQ(3, cache
.disk_cache()->create_count());
3080 RemoveMockTransaction(&transaction
);
3083 // Tests that a successful POST invalidates a previously cached GET, even when
3084 // there is no upload identifier.
3085 TEST(HttpCache
, SimplePOST_NoUploadId_Invalidate_205
) {
3086 MockHttpCache cache
;
3088 MockTransaction
transaction(kSimpleGET_Transaction
);
3089 AddMockTransaction(&transaction
);
3090 MockHttpRequest
req1(transaction
);
3092 // Attempt to populate the cache.
3093 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3095 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3096 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3097 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3099 ScopedVector
<net::UploadElementReader
> element_readers
;
3100 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3101 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3103 transaction
.method
= "POST";
3104 transaction
.status
= "HTTP/1.1 205 No Content";
3105 MockHttpRequest
req2(transaction
);
3106 req2
.upload_data_stream
= &upload_data_stream
;
3108 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3110 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3111 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3112 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3114 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3116 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3117 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3118 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3119 RemoveMockTransaction(&transaction
);
3122 // Tests that processing a POST before creating the backend doesn't crash.
3123 TEST(HttpCache
, SimplePOST_NoUploadId_NoBackend
) {
3124 // This will initialize a cache object with NULL backend.
3125 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
3126 factory
->set_fail(true);
3127 factory
->FinishCreation();
3128 MockHttpCache
cache(factory
);
3130 ScopedVector
<net::UploadElementReader
> element_readers
;
3131 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3132 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3134 MockTransaction
transaction(kSimplePOST_Transaction
);
3135 AddMockTransaction(&transaction
);
3136 MockHttpRequest
req(transaction
);
3137 req
.upload_data_stream
= &upload_data_stream
;
3139 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req
, NULL
);
3141 RemoveMockTransaction(&transaction
);
3144 // Tests that we don't invalidate entries as a result of a failed POST.
3145 TEST(HttpCache
, SimplePOST_DontInvalidate_100
) {
3146 MockHttpCache cache
;
3148 MockTransaction
transaction(kSimpleGET_Transaction
);
3149 AddMockTransaction(&transaction
);
3150 MockHttpRequest
req1(transaction
);
3152 // Attempt to populate the cache.
3153 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3155 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3156 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3157 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3159 ScopedVector
<net::UploadElementReader
> element_readers
;
3160 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3161 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 1);
3163 transaction
.method
= "POST";
3164 transaction
.status
= "HTTP/1.1 100 Continue";
3165 MockHttpRequest
req2(transaction
);
3166 req2
.upload_data_stream
= &upload_data_stream
;
3168 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3170 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3171 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3172 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3174 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3176 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3177 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3178 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3179 RemoveMockTransaction(&transaction
);
3182 // Tests that a HEAD request is not cached by itself.
3183 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Miss
) {
3184 MockHttpCache cache
;
3185 MockTransaction
transaction(kSimplePOST_Transaction
);
3186 AddMockTransaction(&transaction
);
3187 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3188 transaction
.method
= "HEAD";
3190 MockHttpRequest
request(transaction
);
3191 net::TestCompletionCallback callback
;
3193 scoped_ptr
<net::HttpTransaction
> trans
;
3194 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
3195 ASSERT_TRUE(trans
.get());
3197 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
3198 ASSERT_EQ(net::ERR_CACHE_MISS
, callback
.GetResult(rv
));
3202 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3203 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3204 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3205 RemoveMockTransaction(&transaction
);
3208 // Tests that a HEAD request is served from a cached GET.
3209 TEST(HttpCache
, SimpleHEAD_LoadOnlyFromCache_Hit
) {
3210 MockHttpCache cache
;
3211 MockTransaction
transaction(kSimpleGET_Transaction
);
3212 AddMockTransaction(&transaction
);
3214 // Populate the cache.
3215 RunTransactionTest(cache
.http_cache(), transaction
);
3217 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3218 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3219 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3222 transaction
.method
= "HEAD";
3223 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3224 transaction
.data
= "";
3225 RunTransactionTest(cache
.http_cache(), transaction
);
3227 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3228 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3229 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3230 RemoveMockTransaction(&transaction
);
3233 // Tests that a read-only request served from the cache preserves CL.
3234 TEST(HttpCache
, SimpleHEAD_ContentLengthOnHit_Read
) {
3235 MockHttpCache cache
;
3236 MockTransaction
transaction(kSimpleGET_Transaction
);
3237 AddMockTransaction(&transaction
);
3238 transaction
.response_headers
= "Content-Length: 42\n";
3240 // Populate the cache.
3241 RunTransactionTest(cache
.http_cache(), transaction
);
3244 transaction
.method
= "HEAD";
3245 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3246 transaction
.data
= "";
3247 std::string headers
;
3249 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3251 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers
);
3252 RemoveMockTransaction(&transaction
);
3255 // Tests that a read-write request served from the cache preserves CL.
3256 TEST(HttpCache
, ETagHEAD_ContentLengthOnHit_ReadWrite
) {
3257 MockHttpCache cache
;
3258 MockTransaction
transaction(kETagGET_Transaction
);
3259 AddMockTransaction(&transaction
);
3260 std::string
server_headers(kETagGET_Transaction
.response_headers
);
3261 server_headers
.append("Content-Length: 42\n");
3262 transaction
.response_headers
= server_headers
.data();
3264 // Populate the cache.
3265 RunTransactionTest(cache
.http_cache(), transaction
);
3268 transaction
.method
= "HEAD";
3269 transaction
.data
= "";
3270 std::string headers
;
3272 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3274 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 42\n"));
3275 RemoveMockTransaction(&transaction
);
3278 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3279 TEST(HttpCache
, SimpleHEAD_WithRanges
) {
3280 MockHttpCache cache
;
3281 MockTransaction
transaction(kSimpleGET_Transaction
);
3282 AddMockTransaction(&transaction
);
3284 // Populate the cache.
3285 RunTransactionTest(cache
.http_cache(), transaction
);
3288 transaction
.method
= "HEAD";
3289 transaction
.request_headers
= "Range: bytes = 0-4\r\n";
3290 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3291 transaction
.return_code
= net::ERR_CACHE_MISS
;
3292 RunTransactionTest(cache
.http_cache(), transaction
);
3294 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3295 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3296 RemoveMockTransaction(&transaction
);
3299 // Tests that a HEAD request can be served from a partialy cached resource.
3300 TEST(HttpCache
, SimpleHEAD_WithCachedRanges
) {
3301 MockHttpCache cache
;
3302 AddMockTransaction(&kRangeGET_TransactionOK
);
3304 // Write to the cache (40-49).
3305 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
3306 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3308 MockTransaction
transaction(kSimpleGET_Transaction
);
3310 transaction
.url
= kRangeGET_TransactionOK
.url
;
3311 transaction
.method
= "HEAD";
3312 transaction
.data
= "";
3313 AddMockTransaction(&transaction
);
3314 std::string headers
;
3317 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3319 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3320 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3321 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3322 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3323 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3324 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3325 RemoveMockTransaction(&transaction
);
3328 // Tests that a HEAD request can be served from a truncated resource.
3329 TEST(HttpCache
, SimpleHEAD_WithTruncatedEntry
) {
3330 MockHttpCache cache
;
3331 AddMockTransaction(&kRangeGET_TransactionOK
);
3333 std::string
raw_headers("HTTP/1.1 200 OK\n"
3334 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3336 "Accept-Ranges: bytes\n"
3337 "Content-Length: 80\n");
3338 CreateTruncatedEntry(raw_headers
, &cache
);
3339 RemoveMockTransaction(&kRangeGET_TransactionOK
);
3341 MockTransaction
transaction(kSimpleGET_Transaction
);
3343 transaction
.url
= kRangeGET_TransactionOK
.url
;
3344 transaction
.method
= "HEAD";
3345 transaction
.data
= "";
3346 AddMockTransaction(&transaction
);
3347 std::string headers
;
3350 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3352 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3353 EXPECT_NE(std::string::npos
, headers
.find("Content-Length: 80\n"));
3354 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range"));
3355 EXPECT_EQ(0, cache
.network_layer()->transaction_count());
3356 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3357 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3358 RemoveMockTransaction(&transaction
);
3361 // Tests that a HEAD request updates the cached response.
3362 TEST(HttpCache
, TypicalHEAD_UpdatesResponse
) {
3363 MockHttpCache cache
;
3364 MockTransaction
transaction(kTypicalGET_Transaction
);
3365 AddMockTransaction(&transaction
);
3367 // Populate the cache.
3368 RunTransactionTest(cache
.http_cache(), transaction
);
3370 // Update the cache.
3371 transaction
.method
= "HEAD";
3372 transaction
.response_headers
= "Foo: bar\n";
3373 transaction
.data
= "";
3374 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3375 std::string headers
;
3376 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3377 RemoveMockTransaction(&transaction
);
3379 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 200 OK\n"));
3380 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3382 MockTransaction
transaction2(kTypicalGET_Transaction
);
3383 AddMockTransaction(&transaction2
);
3385 // Make sure we are done with the previous transaction.
3386 base::MessageLoop::current()->RunUntilIdle();
3388 // Load from the cache.
3389 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3390 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3392 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3393 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3394 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3395 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3396 RemoveMockTransaction(&transaction2
);
3399 // Tests that an externally conditionalized HEAD request updates the cache.
3400 TEST(HttpCache
, TypicalHEAD_ConditionalizedRequestUpdatesResponse
) {
3401 MockHttpCache cache
;
3402 MockTransaction
transaction(kTypicalGET_Transaction
);
3403 AddMockTransaction(&transaction
);
3405 // Populate the cache.
3406 RunTransactionTest(cache
.http_cache(), transaction
);
3408 // Update the cache.
3409 transaction
.method
= "HEAD";
3410 transaction
.request_headers
=
3411 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3412 transaction
.response_headers
= "Foo: bar\n";
3413 transaction
.data
= "";
3414 transaction
.status
= "HTTP/1.1 304 Not Modified\n";
3415 std::string headers
;
3416 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3417 RemoveMockTransaction(&transaction
);
3419 EXPECT_NE(std::string::npos
, headers
.find("HTTP/1.1 304 Not Modified\n"));
3420 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3422 MockTransaction
transaction2(kTypicalGET_Transaction
);
3423 AddMockTransaction(&transaction2
);
3425 // Make sure we are done with the previous transaction.
3426 base::MessageLoop::current()->RunUntilIdle();
3428 // Load from the cache.
3429 transaction2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3430 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
3432 EXPECT_NE(std::string::npos
, headers
.find("Foo: bar\n"));
3433 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3434 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3435 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3436 RemoveMockTransaction(&transaction2
);
3439 // Tests that a HEAD request invalidates an old cached entry.
3440 TEST(HttpCache
, SimpleHEAD_InvalidatesEntry
) {
3441 MockHttpCache cache
;
3442 MockTransaction
transaction(kTypicalGET_Transaction
);
3443 AddMockTransaction(&transaction
);
3445 // Populate the cache.
3446 RunTransactionTest(cache
.http_cache(), transaction
);
3448 // Update the cache.
3449 transaction
.method
= "HEAD";
3450 transaction
.data
= "";
3451 RunTransactionTest(cache
.http_cache(), transaction
);
3452 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3454 // Load from the cache.
3455 transaction
.method
= "GET";
3456 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
3457 transaction
.return_code
= net::ERR_CACHE_MISS
;
3458 RunTransactionTest(cache
.http_cache(), transaction
);
3460 RemoveMockTransaction(&transaction
);
3463 // Tests that we do not cache the response of a PUT.
3464 TEST(HttpCache
, SimplePUT_Miss
) {
3465 MockHttpCache cache
;
3467 MockTransaction
transaction(kSimplePOST_Transaction
);
3468 transaction
.method
= "PUT";
3470 ScopedVector
<net::UploadElementReader
> element_readers
;
3471 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3472 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3474 MockHttpRequest
request(transaction
);
3475 request
.upload_data_stream
= &upload_data_stream
;
3477 // Attempt to populate the cache.
3478 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3480 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3481 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3482 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3485 // Tests that we invalidate entries as a result of a PUT.
3486 TEST(HttpCache
, SimplePUT_Invalidate
) {
3487 MockHttpCache cache
;
3489 MockTransaction
transaction(kSimpleGET_Transaction
);
3490 MockHttpRequest
req1(transaction
);
3492 // Attempt to populate the cache.
3493 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3495 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3496 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3497 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3499 ScopedVector
<net::UploadElementReader
> element_readers
;
3500 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3501 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3503 transaction
.method
= "PUT";
3504 MockHttpRequest
req2(transaction
);
3505 req2
.upload_data_stream
= &upload_data_stream
;
3507 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3509 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3510 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3511 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3513 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3515 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3516 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3517 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3520 // Tests that we invalidate entries as a result of a PUT.
3521 TEST(HttpCache
, SimplePUT_Invalidate_305
) {
3522 MockHttpCache cache
;
3524 MockTransaction
transaction(kSimpleGET_Transaction
);
3525 AddMockTransaction(&transaction
);
3526 MockHttpRequest
req1(transaction
);
3528 // Attempt to populate the cache.
3529 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3531 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3532 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3533 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3535 ScopedVector
<net::UploadElementReader
> element_readers
;
3536 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3537 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3539 transaction
.method
= "PUT";
3540 transaction
.status
= "HTTP/1.1 305 Use Proxy";
3541 MockHttpRequest
req2(transaction
);
3542 req2
.upload_data_stream
= &upload_data_stream
;
3544 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3546 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3547 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3548 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3550 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3552 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3553 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3554 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3555 RemoveMockTransaction(&transaction
);
3558 // Tests that we don't invalidate entries as a result of a failed PUT.
3559 TEST(HttpCache
, SimplePUT_DontInvalidate_404
) {
3560 MockHttpCache cache
;
3562 MockTransaction
transaction(kSimpleGET_Transaction
);
3563 AddMockTransaction(&transaction
);
3564 MockHttpRequest
req1(transaction
);
3566 // Attempt to populate the cache.
3567 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3569 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3570 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3571 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3573 ScopedVector
<net::UploadElementReader
> element_readers
;
3574 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3575 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3577 transaction
.method
= "PUT";
3578 transaction
.status
= "HTTP/1.1 404 Not Found";
3579 MockHttpRequest
req2(transaction
);
3580 req2
.upload_data_stream
= &upload_data_stream
;
3582 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3584 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3585 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3586 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3588 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3590 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3591 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3592 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3593 RemoveMockTransaction(&transaction
);
3596 // Tests that we do not cache the response of a DELETE.
3597 TEST(HttpCache
, SimpleDELETE_Miss
) {
3598 MockHttpCache cache
;
3600 MockTransaction
transaction(kSimplePOST_Transaction
);
3601 transaction
.method
= "DELETE";
3603 ScopedVector
<net::UploadElementReader
> element_readers
;
3604 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3605 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3607 MockHttpRequest
request(transaction
);
3608 request
.upload_data_stream
= &upload_data_stream
;
3610 // Attempt to populate the cache.
3611 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, request
, NULL
);
3613 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3614 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3615 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3618 // Tests that we invalidate entries as a result of a DELETE.
3619 TEST(HttpCache
, SimpleDELETE_Invalidate
) {
3620 MockHttpCache cache
;
3622 MockTransaction
transaction(kSimpleGET_Transaction
);
3623 MockHttpRequest
req1(transaction
);
3625 // Attempt to populate the cache.
3626 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3628 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3629 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3630 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3632 ScopedVector
<net::UploadElementReader
> element_readers
;
3633 element_readers
.push_back(new net::UploadBytesElementReader("hello", 5));
3634 net::ElementsUploadDataStream
upload_data_stream(element_readers
.Pass(), 0);
3636 transaction
.method
= "DELETE";
3637 MockHttpRequest
req2(transaction
);
3638 req2
.upload_data_stream
= &upload_data_stream
;
3640 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req2
, NULL
);
3642 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3643 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3644 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3646 RunTransactionTestWithRequest(cache
.http_cache(), transaction
, req1
, NULL
);
3648 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3649 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3650 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3653 // Tests that we invalidate entries as a result of a DELETE.
3654 TEST(HttpCache
, SimpleDELETE_Invalidate_301
) {
3655 MockHttpCache cache
;
3657 MockTransaction
transaction(kSimpleGET_Transaction
);
3658 AddMockTransaction(&transaction
);
3660 // Attempt to populate the cache.
3661 RunTransactionTest(cache
.http_cache(), transaction
);
3663 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3664 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3665 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3667 transaction
.method
= "DELETE";
3668 transaction
.status
= "HTTP/1.1 301 Moved Permanently ";
3670 RunTransactionTest(cache
.http_cache(), transaction
);
3672 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3673 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3674 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3676 transaction
.method
= "GET";
3677 RunTransactionTest(cache
.http_cache(), transaction
);
3679 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3680 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3681 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3682 RemoveMockTransaction(&transaction
);
3685 // Tests that we don't invalidate entries as a result of a failed DELETE.
3686 TEST(HttpCache
, SimpleDELETE_DontInvalidate_416
) {
3687 MockHttpCache cache
;
3689 MockTransaction
transaction(kSimpleGET_Transaction
);
3690 AddMockTransaction(&transaction
);
3692 // Attempt to populate the cache.
3693 RunTransactionTest(cache
.http_cache(), transaction
);
3695 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3696 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3697 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3699 transaction
.method
= "DELETE";
3700 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3702 RunTransactionTest(cache
.http_cache(), transaction
);
3704 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3705 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3706 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3708 transaction
.method
= "GET";
3709 transaction
.status
= "HTTP/1.1 200 OK";
3710 RunTransactionTest(cache
.http_cache(), transaction
);
3712 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3713 EXPECT_EQ(2, cache
.disk_cache()->open_count());
3714 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3715 RemoveMockTransaction(&transaction
);
3718 // Tests that we don't invalidate entries after a failed network transaction.
3719 TEST(HttpCache
, SimpleGET_DontInvalidateOnFailure
) {
3720 MockHttpCache cache
;
3722 // Populate the cache.
3723 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
3724 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3726 // Fail the network request.
3727 MockTransaction
transaction(kSimpleGET_Transaction
);
3728 transaction
.return_code
= net::ERR_FAILED
;
3729 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
3731 AddMockTransaction(&transaction
);
3732 RunTransactionTest(cache
.http_cache(), transaction
);
3733 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3734 RemoveMockTransaction(&transaction
);
3736 transaction
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
3737 transaction
.return_code
= net::OK
;
3738 AddMockTransaction(&transaction
);
3739 RunTransactionTest(cache
.http_cache(), transaction
);
3741 // Make sure the transaction didn't reach the network.
3742 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3743 RemoveMockTransaction(&transaction
);
3746 TEST(HttpCache
, RangeGET_SkipsCache
) {
3747 MockHttpCache cache
;
3749 // Test that we skip the cache for range GET requests. Eventually, we will
3750 // want to cache these, but we'll still have cases where skipping the cache
3751 // makes sense, so we want to make sure that it works properly.
3753 RunTransactionTest(cache
.http_cache(), kRangeGET_Transaction
);
3755 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3756 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3757 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3759 MockTransaction
transaction(kSimpleGET_Transaction
);
3760 transaction
.request_headers
= "If-None-Match: foo\r\n";
3761 RunTransactionTest(cache
.http_cache(), transaction
);
3763 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3764 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3765 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3767 transaction
.request_headers
=
3768 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3769 RunTransactionTest(cache
.http_cache(), transaction
);
3771 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3772 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3773 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3776 // Test that we skip the cache for range requests that include a validation
3778 TEST(HttpCache
, RangeGET_SkipsCache2
) {
3779 MockHttpCache cache
;
3781 MockTransaction
transaction(kRangeGET_Transaction
);
3782 transaction
.request_headers
= "If-None-Match: foo\r\n"
3784 "Range: bytes = 40-49\r\n";
3785 RunTransactionTest(cache
.http_cache(), transaction
);
3787 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3788 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3789 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3791 transaction
.request_headers
=
3792 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3794 "Range: bytes = 40-49\r\n";
3795 RunTransactionTest(cache
.http_cache(), transaction
);
3797 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3798 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3799 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3801 transaction
.request_headers
= "If-Range: bla\r\n"
3803 "Range: bytes = 40-49\r\n";
3804 RunTransactionTest(cache
.http_cache(), transaction
);
3806 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
3807 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3808 EXPECT_EQ(0, cache
.disk_cache()->create_count());
3811 TEST(HttpCache
, SimpleGET_DoesntLogHeaders
) {
3812 MockHttpCache cache
;
3814 net::CapturingBoundNetLog log
;
3815 RunTransactionTestWithLog(cache
.http_cache(), kSimpleGET_Transaction
,
3818 EXPECT_FALSE(LogContainsEventType(
3819 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3822 TEST(HttpCache
, RangeGET_LogsHeaders
) {
3823 MockHttpCache cache
;
3825 net::CapturingBoundNetLog log
;
3826 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_Transaction
,
3829 EXPECT_TRUE(LogContainsEventType(
3830 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3833 TEST(HttpCache
, ExternalValidation_LogsHeaders
) {
3834 MockHttpCache cache
;
3836 net::CapturingBoundNetLog log
;
3837 MockTransaction
transaction(kSimpleGET_Transaction
);
3838 transaction
.request_headers
= "If-None-Match: foo\r\n" EXTRA_HEADER
;
3839 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3841 EXPECT_TRUE(LogContainsEventType(
3842 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3845 TEST(HttpCache
, SpecialHeaders_LogsHeaders
) {
3846 MockHttpCache cache
;
3848 net::CapturingBoundNetLog log
;
3849 MockTransaction
transaction(kSimpleGET_Transaction
);
3850 transaction
.request_headers
= "cache-control: no-cache\r\n" EXTRA_HEADER
;
3851 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
3853 EXPECT_TRUE(LogContainsEventType(
3854 log
, net::NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS
));
3857 // Tests that receiving 206 for a regular request is handled correctly.
3858 TEST(HttpCache
, GET_Crazy206
) {
3859 MockHttpCache cache
;
3861 // Write to the cache.
3862 MockTransaction
transaction(kRangeGET_TransactionOK
);
3863 AddMockTransaction(&transaction
);
3864 transaction
.request_headers
= EXTRA_HEADER
;
3865 transaction
.handler
= NULL
;
3866 RunTransactionTest(cache
.http_cache(), transaction
);
3868 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3869 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3870 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3872 // This should read again from the net.
3873 RunTransactionTest(cache
.http_cache(), transaction
);
3875 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3876 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3877 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3878 RemoveMockTransaction(&transaction
);
3881 // Tests that receiving 416 for a regular request is handled correctly.
3882 TEST(HttpCache
, GET_Crazy416
) {
3883 MockHttpCache cache
;
3885 // Write to the cache.
3886 MockTransaction
transaction(kSimpleGET_Transaction
);
3887 AddMockTransaction(&transaction
);
3888 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
3889 RunTransactionTest(cache
.http_cache(), transaction
);
3891 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3892 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3893 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3895 RemoveMockTransaction(&transaction
);
3898 // Tests that we don't store partial responses that can't be validated.
3899 TEST(HttpCache
, RangeGET_NoStrongValidators
) {
3900 MockHttpCache cache
;
3901 std::string headers
;
3903 // Attempt to write to the cache (40-49).
3904 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3905 transaction
.response_headers
= "Content-Length: 10\n"
3906 "Cache-Control: max-age=3600\n"
3907 "ETag: w/\"foo\"\n";
3908 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3910 Verify206Response(headers
, 40, 49);
3911 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3912 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3913 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3915 // Now verify that there's no cached data.
3916 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3919 Verify206Response(headers
, 40, 49);
3920 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3921 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3922 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3925 // Tests failures to conditionalize byte range requests.
3926 TEST(HttpCache
, RangeGET_NoConditionalization
) {
3927 MockHttpCache cache
;
3928 cache
.FailConditionalizations();
3929 std::string headers
;
3931 // Write to the cache (40-49).
3932 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3933 transaction
.response_headers
= "Content-Length: 10\n"
3935 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3937 Verify206Response(headers
, 40, 49);
3938 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3939 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3940 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3942 // Now verify that the cached data is not used.
3943 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
3946 Verify206Response(headers
, 40, 49);
3947 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
3948 EXPECT_EQ(1, cache
.disk_cache()->open_count());
3949 EXPECT_EQ(2, cache
.disk_cache()->create_count());
3952 // Tests that restarting a partial request when the cached data cannot be
3953 // revalidated logs an event.
3954 TEST(HttpCache
, RangeGET_NoValidation_LogsRestart
) {
3955 MockHttpCache cache
;
3956 cache
.FailConditionalizations();
3958 // Write to the cache (40-49).
3959 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3960 transaction
.response_headers
= "Content-Length: 10\n"
3962 RunTransactionTest(cache
.http_cache(), transaction
);
3964 // Now verify that the cached data is not used.
3965 net::CapturingBoundNetLog log
;
3966 RunTransactionTestWithLog(cache
.http_cache(), kRangeGET_TransactionOK
,
3969 EXPECT_TRUE(LogContainsEventType(
3970 log
, net::NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST
));
3973 // Tests that a failure to conditionalize a regular request (no range) with a
3974 // sparse entry results in a full response.
3975 TEST(HttpCache
, GET_NoConditionalization
) {
3976 MockHttpCache cache
;
3977 cache
.FailConditionalizations();
3978 std::string headers
;
3980 // Write to the cache (40-49).
3981 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
3982 transaction
.response_headers
= "Content-Length: 10\n"
3984 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3986 Verify206Response(headers
, 40, 49);
3987 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
3988 EXPECT_EQ(0, cache
.disk_cache()->open_count());
3989 EXPECT_EQ(1, cache
.disk_cache()->create_count());
3991 // Now verify that the cached data is not used.
3992 // Don't ask for a range. The cache will attempt to use the cached data but
3993 // should discard it as it cannot be validated. A regular request should go
3994 // to the server and a new entry should be created.
3995 transaction
.request_headers
= EXTRA_HEADER
;
3996 transaction
.data
= "Not a range";
3997 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
3999 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4000 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4001 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4002 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4004 // The last response was saved.
4005 RunTransactionTest(cache
.http_cache(), transaction
);
4006 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4007 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4008 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4011 // Verifies that conditionalization failures when asking for a range that would
4012 // require the cache to modify the range to ask, result in a network request
4013 // that matches the user's one.
4014 TEST(HttpCache
, RangeGET_NoConditionalization2
) {
4015 MockHttpCache cache
;
4016 cache
.FailConditionalizations();
4017 std::string headers
;
4019 // Write to the cache (40-49).
4020 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4021 transaction
.response_headers
= "Content-Length: 10\n"
4023 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4025 Verify206Response(headers
, 40, 49);
4026 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4027 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4028 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4030 // Now verify that the cached data is not used.
4031 // Ask for a range that extends before and after the cached data so that the
4032 // cache would normally mix data from three sources. After deleting the entry,
4033 // the response will come from a single network request.
4034 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4035 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4036 transaction
.response_headers
= kRangeGET_TransactionOK
.response_headers
;
4037 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4039 Verify206Response(headers
, 20, 59);
4040 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4041 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4042 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4044 // The last response was saved.
4045 RunTransactionTest(cache
.http_cache(), transaction
);
4046 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4047 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4048 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4051 // Tests that we cache partial responses that lack content-length.
4052 TEST(HttpCache
, RangeGET_NoContentLength
) {
4053 MockHttpCache cache
;
4054 std::string headers
;
4056 // Attempt to write to the cache (40-49).
4057 MockTransaction
transaction(kRangeGET_TransactionOK
);
4058 AddMockTransaction(&transaction
);
4059 transaction
.response_headers
= "ETag: \"foo\"\n"
4060 "Accept-Ranges: bytes\n"
4061 "Content-Range: bytes 40-49/80\n";
4062 transaction
.handler
= NULL
;
4063 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4065 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4066 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4067 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4069 // Now verify that there's no cached data.
4070 transaction
.handler
= &RangeTransactionServer::RangeHandler
;
4071 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4074 Verify206Response(headers
, 40, 49);
4075 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4076 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4077 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4079 RemoveMockTransaction(&transaction
);
4082 // Tests that we can cache range requests and fetch random blocks from the
4083 // cache and the network.
4084 TEST(HttpCache
, RangeGET_OK
) {
4085 MockHttpCache cache
;
4086 AddMockTransaction(&kRangeGET_TransactionOK
);
4087 std::string headers
;
4089 // Write to the cache (40-49).
4090 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4093 Verify206Response(headers
, 40, 49);
4094 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4095 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4096 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4098 // Read from the cache (40-49).
4099 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4102 Verify206Response(headers
, 40, 49);
4103 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4104 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4105 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4107 // Make sure we are done with the previous transaction.
4108 base::MessageLoop::current()->RunUntilIdle();
4110 // Write to the cache (30-39).
4111 MockTransaction
transaction(kRangeGET_TransactionOK
);
4112 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4113 transaction
.data
= "rg: 30-39 ";
4114 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4116 Verify206Response(headers
, 30, 39);
4117 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4118 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4119 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4121 // Make sure we are done with the previous transaction.
4122 base::MessageLoop::current()->RunUntilIdle();
4124 // Write and read from the cache (20-59).
4125 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4126 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4127 net::CapturingBoundNetLog log
;
4128 net::LoadTimingInfo load_timing_info
;
4129 RunTransactionTestWithResponseAndGetTiming(
4130 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4133 Verify206Response(headers
, 20, 59);
4134 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4135 EXPECT_EQ(3, cache
.disk_cache()->open_count());
4136 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4137 TestLoadTimingNetworkRequest(load_timing_info
);
4139 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4142 // Tests that we can cache range requests and fetch random blocks from the
4143 // cache and the network, with synchronous responses.
4144 TEST(HttpCache
, RangeGET_SyncOK
) {
4145 MockHttpCache cache
;
4147 MockTransaction
transaction(kRangeGET_TransactionOK
);
4148 transaction
.test_mode
= TEST_MODE_SYNC_ALL
;
4149 AddMockTransaction(&transaction
);
4151 // Write to the cache (40-49).
4152 std::string headers
;
4153 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4155 Verify206Response(headers
, 40, 49);
4156 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4157 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4158 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4160 // Read from the cache (40-49).
4161 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4163 Verify206Response(headers
, 40, 49);
4164 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4165 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4166 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4168 // Make sure we are done with the previous transaction.
4169 base::MessageLoop::current()->RunUntilIdle();
4171 // Write to the cache (30-39).
4172 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
4173 transaction
.data
= "rg: 30-39 ";
4174 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4176 Verify206Response(headers
, 30, 39);
4177 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4178 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4179 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4181 // Make sure we are done with the previous transaction.
4182 base::MessageLoop::current()->RunUntilIdle();
4184 // Write and read from the cache (20-59).
4185 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
4186 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4187 net::CapturingBoundNetLog log
;
4188 net::LoadTimingInfo load_timing_info
;
4189 RunTransactionTestWithResponseAndGetTiming(
4190 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4193 Verify206Response(headers
, 20, 59);
4194 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4195 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4196 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4197 TestLoadTimingNetworkRequest(load_timing_info
);
4199 RemoveMockTransaction(&transaction
);
4202 // Tests that we don't revalidate an entry unless we are required to do so.
4203 TEST(HttpCache
, RangeGET_Revalidate1
) {
4204 MockHttpCache cache
;
4205 std::string headers
;
4207 // Write to the cache (40-49).
4208 MockTransaction
transaction(kRangeGET_TransactionOK
);
4209 transaction
.response_headers
=
4210 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4211 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4213 "Accept-Ranges: bytes\n"
4214 "Content-Length: 10\n";
4215 AddMockTransaction(&transaction
);
4216 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4218 Verify206Response(headers
, 40, 49);
4219 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4220 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4221 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4223 // Read from the cache (40-49).
4224 net::CapturingBoundNetLog log
;
4225 net::LoadTimingInfo load_timing_info
;
4226 RunTransactionTestWithResponseAndGetTiming(
4227 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4230 Verify206Response(headers
, 40, 49);
4231 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4232 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4233 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4234 TestLoadTimingCachedResponse(load_timing_info
);
4236 // Read again forcing the revalidation.
4237 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4238 RunTransactionTestWithResponseAndGetTiming(
4239 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4242 Verify206Response(headers
, 40, 49);
4243 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4244 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4245 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4246 TestLoadTimingNetworkRequest(load_timing_info
);
4248 RemoveMockTransaction(&transaction
);
4251 // Checks that we revalidate an entry when the headers say so.
4252 TEST(HttpCache
, RangeGET_Revalidate2
) {
4253 MockHttpCache cache
;
4254 std::string headers
;
4256 // Write to the cache (40-49).
4257 MockTransaction
transaction(kRangeGET_TransactionOK
);
4258 transaction
.response_headers
=
4259 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4260 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4262 "Accept-Ranges: bytes\n"
4263 "Content-Length: 10\n";
4264 AddMockTransaction(&transaction
);
4265 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4267 Verify206Response(headers
, 40, 49);
4268 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4269 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4270 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4272 // Read from the cache (40-49).
4273 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4274 Verify206Response(headers
, 40, 49);
4276 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4277 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4278 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4280 RemoveMockTransaction(&transaction
);
4283 // Tests that we deal with 304s for range requests.
4284 TEST(HttpCache
, RangeGET_304
) {
4285 MockHttpCache cache
;
4286 AddMockTransaction(&kRangeGET_TransactionOK
);
4287 std::string headers
;
4289 // Write to the cache (40-49).
4290 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4293 Verify206Response(headers
, 40, 49);
4294 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4295 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4296 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4298 // Read from the cache (40-49).
4299 RangeTransactionServer handler
;
4300 handler
.set_not_modified(true);
4301 MockTransaction
transaction(kRangeGET_TransactionOK
);
4302 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4303 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4305 Verify206Response(headers
, 40, 49);
4306 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4307 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4308 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4310 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4313 // Tests that we deal with 206s when revalidating range requests.
4314 TEST(HttpCache
, RangeGET_ModifiedResult
) {
4315 MockHttpCache cache
;
4316 AddMockTransaction(&kRangeGET_TransactionOK
);
4317 std::string headers
;
4319 // Write to the cache (40-49).
4320 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
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 // Attempt to read from the cache (40-49).
4329 RangeTransactionServer handler
;
4330 handler
.set_modified(true);
4331 MockTransaction
transaction(kRangeGET_TransactionOK
);
4332 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4333 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4335 Verify206Response(headers
, 40, 49);
4336 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4337 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4338 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4340 // And the entry should be gone.
4341 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4342 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4343 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4344 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4346 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4349 // Tests that when a server returns 206 with a sub-range of the requested range,
4350 // and there is nothing stored in the cache, the returned response is passed to
4351 // the caller as is. In this context, a subrange means a response that starts
4352 // with the same byte that was requested, but that is not the whole range that
4354 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_NoCachedContent
) {
4355 MockHttpCache cache
;
4356 std::string headers
;
4358 // Request a large range (40-59). The server sends 40-49.
4359 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4360 transaction
.request_headers
= "Range: bytes = 40-59\r\n" EXTRA_HEADER
;
4361 transaction
.response_headers
=
4362 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4364 "Accept-Ranges: bytes\n"
4365 "Content-Length: 10\n"
4366 "Content-Range: bytes 40-49/80\n";
4367 transaction
.handler
= nullptr;
4368 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4370 Verify206Response(headers
, 40, 49);
4371 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4372 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4373 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4376 // Tests that when a server returns 206 with a sub-range of the requested range,
4377 // and there was an entry stored in the cache, the cache gets out of the way.
4378 TEST(HttpCache
, RangeGET_206ReturnsSubrangeRange_CachedContent
) {
4379 MockHttpCache cache
;
4380 std::string headers
;
4382 // Write to the cache (70-79).
4383 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4384 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4385 transaction
.data
= "rg: 70-79 ";
4386 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4387 Verify206Response(headers
, 70, 79);
4389 // Request a large range (40-79). The cache will ask the server for 40-59.
4390 // The server returns 40-49. The cache should consider the server confused and
4391 // abort caching, restarting the request without caching.
4392 transaction
.request_headers
= "Range: bytes = 40-79\r\n" EXTRA_HEADER
;
4393 transaction
.response_headers
=
4394 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4396 "Accept-Ranges: bytes\n"
4397 "Content-Length: 10\n"
4398 "Content-Range: bytes 40-49/80\n";
4399 transaction
.handler
= nullptr;
4400 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4402 // Two new network requests were issued, one from the cache and another after
4403 // deleting the entry.
4404 Verify206Response(headers
, 40, 49);
4405 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4406 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4407 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4409 // The entry was deleted.
4410 RunTransactionTest(cache
.http_cache(), transaction
);
4411 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4412 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4413 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4416 // Tests that when a server returns 206 with a sub-range of the requested range,
4417 // and there was an entry stored in the cache, the cache gets out of the way,
4418 // when the caller is not using ranges.
4419 TEST(HttpCache
, GET_206ReturnsSubrangeRange_CachedContent
) {
4420 MockHttpCache cache
;
4421 std::string headers
;
4423 // Write to the cache (70-79).
4424 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4425 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4426 transaction
.data
= "rg: 70-79 ";
4427 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4428 Verify206Response(headers
, 70, 79);
4430 // Don't ask for a range. The cache will ask the server for 0-69.
4431 // The server returns 40-49. The cache should consider the server confused and
4432 // abort caching, restarting the request.
4433 // The second network request should not be a byte range request so the server
4434 // should return 200 + "Not a range"
4435 transaction
.request_headers
= "X-Return-Default-Range:\r\n" EXTRA_HEADER
;
4436 transaction
.data
= "Not a range";
4437 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4439 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4440 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4441 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4442 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4444 // The entry was deleted.
4445 RunTransactionTest(cache
.http_cache(), transaction
);
4446 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4447 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4448 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4451 // Tests that when a server returns 206 with a random range and there is
4452 // nothing stored in the cache, the returned response is passed to the caller
4453 // as is. In this context, a WrongRange means that the returned range may or may
4454 // not have any relationship with the requested range (may or may not be
4455 // contained). The important part is that the first byte doesn't match the first
4457 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_NoCachedContent
) {
4458 MockHttpCache cache
;
4459 std::string headers
;
4461 // Request a large range (30-59). The server sends (40-49).
4462 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4463 transaction
.request_headers
= "Range: bytes = 30-59\r\n" EXTRA_HEADER
;
4464 transaction
.response_headers
=
4465 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4467 "Accept-Ranges: bytes\n"
4468 "Content-Length: 10\n"
4469 "Content-Range: bytes 40-49/80\n";
4470 transaction
.handler
= nullptr;
4471 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4473 Verify206Response(headers
, 40, 49);
4474 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4475 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4476 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4478 // The entry was deleted.
4479 RunTransactionTest(cache
.http_cache(), transaction
);
4480 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4481 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4482 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4485 // Tests that when a server returns 206 with a random range and there is
4486 // an entry stored in the cache, the cache gets out of the way.
4487 TEST(HttpCache
, RangeGET_206ReturnsWrongRange_CachedContent
) {
4488 MockHttpCache cache
;
4489 std::string headers
;
4491 // Write to the cache (70-79).
4492 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4493 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4494 transaction
.data
= "rg: 70-79 ";
4495 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4496 Verify206Response(headers
, 70, 79);
4498 // Request a large range (30-79). The cache will ask the server for 30-69.
4499 // The server returns 40-49. The cache should consider the server confused and
4500 // abort caching, returning the weird range to the caller.
4501 transaction
.request_headers
= "Range: bytes = 30-79\r\n" EXTRA_HEADER
;
4502 transaction
.response_headers
=
4503 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4505 "Accept-Ranges: bytes\n"
4506 "Content-Length: 10\n"
4507 "Content-Range: bytes 40-49/80\n";
4508 transaction
.handler
= nullptr;
4509 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4511 Verify206Response(headers
, 40, 49);
4512 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4513 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4514 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4516 // The entry was deleted.
4517 RunTransactionTest(cache
.http_cache(), transaction
);
4518 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4519 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4520 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4523 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4524 // the response matches the one provided by the server.
4525 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_NoCachedContent
) {
4526 MockHttpCache cache
;
4527 std::string headers
;
4529 // Request a large range (70-99). The server sends 70-79.
4530 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4531 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4532 transaction
.data
= "rg: 70-79 ";
4533 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4535 Verify206Response(headers
, 70, 79);
4536 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4537 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4538 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4540 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4541 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4544 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4545 // the cache automatically fixes the request.
4546 TEST(HttpCache
, RangeGET_206ReturnsSmallerFile_CachedContent
) {
4547 MockHttpCache cache
;
4548 std::string headers
;
4550 // Write to the cache (40-49).
4551 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4552 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4554 // Request a large range (70-99). The server sends 70-79.
4555 transaction
.request_headers
= "Range: bytes = 70-99\r\n" EXTRA_HEADER
;
4556 transaction
.data
= "rg: 70-79 ";
4557 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4559 Verify206Response(headers
, 70, 79);
4560 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4561 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4562 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4564 // The entry was not deleted (the range was automatically fixed).
4565 RunTransactionTest(cache
.http_cache(), transaction
);
4566 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4567 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4568 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4571 // Tests that when a caller asks for a not-satisfiable range, the server's
4572 // response is forwarded to the caller.
4573 TEST(HttpCache
, RangeGET_416_NoCachedContent
) {
4574 MockHttpCache cache
;
4575 std::string headers
;
4577 // Request a range beyond EOF (80-99).
4578 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4579 transaction
.request_headers
= "Range: bytes = 80-99\r\n" EXTRA_HEADER
;
4580 transaction
.data
= "";
4581 transaction
.status
= "HTTP/1.1 416 Requested Range Not Satisfiable";
4582 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4584 EXPECT_EQ(0U, headers
.find(transaction
.status
));
4585 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4586 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4587 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4589 // The entry was deleted.
4590 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
4591 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4594 // Tests that we cache 301s for range requests.
4595 TEST(HttpCache
, RangeGET_301
) {
4596 MockHttpCache cache
;
4597 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
4598 transaction
.status
= "HTTP/1.1 301 Moved Permanently";
4599 transaction
.response_headers
= "Location: http://www.bar.com/\n";
4600 transaction
.data
= "";
4601 transaction
.handler
= NULL
;
4603 // Write to the cache.
4604 RunTransactionTest(cache
.http_cache(), transaction
);
4605 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4606 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4607 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4609 // Read from the cache.
4610 RunTransactionTest(cache
.http_cache(), transaction
);
4611 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4612 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4613 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4616 // Tests that we can cache range requests when the start or end is unknown.
4617 // We start with one suffix request, followed by a request from a given point.
4618 TEST(HttpCache
, UnknownRangeGET_1
) {
4619 MockHttpCache cache
;
4620 AddMockTransaction(&kRangeGET_TransactionOK
);
4621 std::string headers
;
4623 // Write to the cache (70-79).
4624 MockTransaction
transaction(kRangeGET_TransactionOK
);
4625 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
4626 transaction
.data
= "rg: 70-79 ";
4627 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4629 Verify206Response(headers
, 70, 79);
4630 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4631 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4632 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4634 // Make sure we are done with the previous transaction.
4635 base::MessageLoop::current()->RunUntilIdle();
4637 // Write and read from the cache (60-79).
4638 transaction
.request_headers
= "Range: bytes = 60-\r\n" EXTRA_HEADER
;
4639 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4640 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4642 Verify206Response(headers
, 60, 79);
4643 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4644 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4645 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4647 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4650 // Tests that we can cache range requests when the start or end is unknown.
4651 // We start with one request from a given point, followed by a suffix request.
4652 // We'll also verify that synchronous cache responses work as intended.
4653 TEST(HttpCache
, UnknownRangeGET_2
) {
4654 MockHttpCache cache
;
4655 std::string headers
;
4657 MockTransaction
transaction(kRangeGET_TransactionOK
);
4658 transaction
.test_mode
= TEST_MODE_SYNC_CACHE_START
|
4659 TEST_MODE_SYNC_CACHE_READ
|
4660 TEST_MODE_SYNC_CACHE_WRITE
;
4661 AddMockTransaction(&transaction
);
4663 // Write to the cache (70-79).
4664 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4665 transaction
.data
= "rg: 70-79 ";
4666 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4668 Verify206Response(headers
, 70, 79);
4669 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4670 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4671 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4673 // Make sure we are done with the previous transaction.
4674 base::MessageLoop::current()->RunUntilIdle();
4676 // Write and read from the cache (60-79).
4677 transaction
.request_headers
= "Range: bytes = -20\r\n" EXTRA_HEADER
;
4678 transaction
.data
= "rg: 60-69 rg: 70-79 ";
4679 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4681 Verify206Response(headers
, 60, 79);
4682 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4683 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4684 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4686 RemoveMockTransaction(&transaction
);
4689 // Tests that receiving Not Modified when asking for an open range doesn't mess
4691 TEST(HttpCache
, UnknownRangeGET_304
) {
4692 MockHttpCache cache
;
4693 std::string headers
;
4695 MockTransaction
transaction(kRangeGET_TransactionOK
);
4696 AddMockTransaction(&transaction
);
4698 RangeTransactionServer handler
;
4699 handler
.set_not_modified(true);
4701 // Ask for the end of the file, without knowing the length.
4702 transaction
.request_headers
= "Range: bytes = 70-\r\n" EXTRA_HEADER
;
4703 transaction
.data
= "";
4704 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4706 // We just bypass the cache.
4707 EXPECT_EQ(0U, headers
.find("HTTP/1.1 304 Not Modified\n"));
4708 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4709 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4710 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4712 RunTransactionTest(cache
.http_cache(), transaction
);
4713 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4715 RemoveMockTransaction(&transaction
);
4718 // Tests that we can handle non-range requests when we have cached a range.
4719 TEST(HttpCache
, GET_Previous206
) {
4720 MockHttpCache cache
;
4721 AddMockTransaction(&kRangeGET_TransactionOK
);
4722 std::string headers
;
4723 net::CapturingBoundNetLog log
;
4724 net::LoadTimingInfo load_timing_info
;
4726 // Write to the cache (40-49).
4727 RunTransactionTestWithResponseAndGetTiming(
4728 cache
.http_cache(), kRangeGET_TransactionOK
, &headers
, log
.bound(),
4731 Verify206Response(headers
, 40, 49);
4732 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4733 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4734 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4735 TestLoadTimingNetworkRequest(load_timing_info
);
4737 // Write and read from the cache (0-79), when not asked for a range.
4738 MockTransaction
transaction(kRangeGET_TransactionOK
);
4739 transaction
.request_headers
= EXTRA_HEADER
;
4740 transaction
.data
= kFullRangeData
;
4741 RunTransactionTestWithResponseAndGetTiming(
4742 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4745 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4746 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4747 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4748 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4749 TestLoadTimingNetworkRequest(load_timing_info
);
4751 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4754 // Tests that we can handle non-range requests when we have cached the first
4755 // part of the object and the server replies with 304 (Not Modified).
4756 TEST(HttpCache
, GET_Previous206_NotModified
) {
4757 MockHttpCache cache
;
4759 MockTransaction
transaction(kRangeGET_TransactionOK
);
4760 AddMockTransaction(&transaction
);
4761 std::string headers
;
4762 net::CapturingBoundNetLog log
;
4763 net::LoadTimingInfo load_timing_info
;
4765 // Write to the cache (0-9).
4766 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4767 transaction
.data
= "rg: 00-09 ";
4768 RunTransactionTestWithResponseAndGetTiming(
4769 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4771 Verify206Response(headers
, 0, 9);
4772 TestLoadTimingNetworkRequest(load_timing_info
);
4774 // Write to the cache (70-79).
4775 transaction
.request_headers
= "Range: bytes = 70-79\r\n" EXTRA_HEADER
;
4776 transaction
.data
= "rg: 70-79 ";
4777 RunTransactionTestWithResponseAndGetTiming(
4778 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4780 Verify206Response(headers
, 70, 79);
4782 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
4783 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4784 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4785 TestLoadTimingNetworkRequest(load_timing_info
);
4787 // Read from the cache (0-9), write and read from cache (10 - 79).
4788 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4789 transaction
.request_headers
= "Foo: bar\r\n" EXTRA_HEADER
;
4790 transaction
.data
= kFullRangeData
;
4791 RunTransactionTestWithResponseAndGetTiming(
4792 cache
.http_cache(), transaction
, &headers
, log
.bound(),
4795 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4796 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
4797 EXPECT_EQ(2, cache
.disk_cache()->open_count());
4798 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4799 TestLoadTimingNetworkRequest(load_timing_info
);
4801 RemoveMockTransaction(&transaction
);
4804 // Tests that we can handle a regular request to a sparse entry, that results in
4805 // new content provided by the server (206).
4806 TEST(HttpCache
, GET_Previous206_NewContent
) {
4807 MockHttpCache cache
;
4808 AddMockTransaction(&kRangeGET_TransactionOK
);
4809 std::string headers
;
4811 // Write to the cache (0-9).
4812 MockTransaction
transaction(kRangeGET_TransactionOK
);
4813 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
4814 transaction
.data
= "rg: 00-09 ";
4815 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
4817 Verify206Response(headers
, 0, 9);
4818 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4819 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4820 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4822 // Now we'll issue a request without any range that should result first in a
4823 // 206 (when revalidating), and then in a weird standard answer: the test
4824 // server will not modify the response so we'll get the default range... a
4825 // real server will answer with 200.
4826 MockTransaction
transaction2(kRangeGET_TransactionOK
);
4827 transaction2
.request_headers
= EXTRA_HEADER
;
4828 transaction2
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
4829 transaction2
.data
= "Not a range";
4830 RangeTransactionServer handler
;
4831 handler
.set_modified(true);
4832 net::CapturingBoundNetLog log
;
4833 net::LoadTimingInfo load_timing_info
;
4834 RunTransactionTestWithResponseAndGetTiming(
4835 cache
.http_cache(), transaction2
, &headers
, log
.bound(),
4838 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 OK\n"));
4839 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
4840 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4841 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4842 TestLoadTimingNetworkRequest(load_timing_info
);
4844 // Verify that the previous request deleted the entry.
4845 RunTransactionTest(cache
.http_cache(), transaction
);
4846 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4848 RemoveMockTransaction(&transaction
);
4851 // Tests that we can handle cached 206 responses that are not sparse.
4852 TEST(HttpCache
, GET_Previous206_NotSparse
) {
4853 MockHttpCache cache
;
4855 // Create a disk cache entry that stores 206 headers while not being sparse.
4856 disk_cache::Entry
* entry
;
4857 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4860 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4861 raw_headers
.append("\n");
4862 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4863 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4864 raw_headers
.size());
4866 net::HttpResponseInfo response
;
4867 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4868 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4870 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4871 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4872 kRangeGET_TransactionOK
.data
, 500));
4873 net::TestCompletionCallback cb
;
4874 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4875 EXPECT_EQ(len
, cb
.GetResult(rv
));
4878 // Now see that we don't use the stored entry.
4879 std::string headers
;
4880 net::CapturingBoundNetLog log
;
4881 net::LoadTimingInfo load_timing_info
;
4882 RunTransactionTestWithResponseAndGetTiming(
4883 cache
.http_cache(), kSimpleGET_Transaction
, &headers
, log
.bound(),
4886 // We are expecting a 200.
4887 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4888 expected_headers
.append("\n");
4889 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4890 EXPECT_EQ(expected_headers
, headers
);
4891 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4892 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4893 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4894 TestLoadTimingNetworkRequest(load_timing_info
);
4897 // Tests that we can handle cached 206 responses that are not sparse. This time
4898 // we issue a range request and expect to receive a range.
4899 TEST(HttpCache
, RangeGET_Previous206_NotSparse_2
) {
4900 MockHttpCache cache
;
4901 AddMockTransaction(&kRangeGET_TransactionOK
);
4903 // Create a disk cache entry that stores 206 headers while not being sparse.
4904 disk_cache::Entry
* entry
;
4905 ASSERT_TRUE(cache
.CreateBackendEntry(kRangeGET_TransactionOK
.url
, &entry
,
4908 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4909 raw_headers
.append("\n");
4910 raw_headers
.append(kRangeGET_TransactionOK
.response_headers
);
4911 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4912 raw_headers
.size());
4914 net::HttpResponseInfo response
;
4915 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4916 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4918 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4919 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4920 kRangeGET_TransactionOK
.data
, 500));
4921 net::TestCompletionCallback cb
;
4922 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4923 EXPECT_EQ(len
, cb
.GetResult(rv
));
4926 // Now see that we don't use the stored entry.
4927 std::string headers
;
4928 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
4931 // We are expecting a 206.
4932 Verify206Response(headers
, 40, 49);
4933 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4934 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4935 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4937 RemoveMockTransaction(&kRangeGET_TransactionOK
);
4940 // Tests that we can handle cached 206 responses that can't be validated.
4941 TEST(HttpCache
, GET_Previous206_NotValidation
) {
4942 MockHttpCache cache
;
4944 // Create a disk cache entry that stores 206 headers.
4945 disk_cache::Entry
* entry
;
4946 ASSERT_TRUE(cache
.CreateBackendEntry(kSimpleGET_Transaction
.url
, &entry
,
4949 // Make sure that the headers cannot be validated with the server.
4950 std::string
raw_headers(kRangeGET_TransactionOK
.status
);
4951 raw_headers
.append("\n");
4952 raw_headers
.append("Content-Length: 80\n");
4953 raw_headers
= net::HttpUtil::AssembleRawHeaders(raw_headers
.data(),
4954 raw_headers
.size());
4956 net::HttpResponseInfo response
;
4957 response
.headers
= new net::HttpResponseHeaders(raw_headers
);
4958 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
4960 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(500));
4961 int len
= static_cast<int>(base::strlcpy(buf
->data(),
4962 kRangeGET_TransactionOK
.data
, 500));
4963 net::TestCompletionCallback cb
;
4964 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
4965 EXPECT_EQ(len
, cb
.GetResult(rv
));
4968 // Now see that we don't use the stored entry.
4969 std::string headers
;
4970 RunTransactionTestWithResponse(cache
.http_cache(), kSimpleGET_Transaction
,
4973 // We are expecting a 200.
4974 std::string
expected_headers(kSimpleGET_Transaction
.status
);
4975 expected_headers
.append("\n");
4976 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
4977 EXPECT_EQ(expected_headers
, headers
);
4978 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4979 EXPECT_EQ(1, cache
.disk_cache()->open_count());
4980 EXPECT_EQ(2, cache
.disk_cache()->create_count());
4983 // Tests that we can handle range requests with cached 200 responses.
4984 TEST(HttpCache
, RangeGET_Previous200
) {
4985 MockHttpCache cache
;
4987 // Store the whole thing with status 200.
4988 MockTransaction
transaction(kTypicalGET_Transaction
);
4989 transaction
.url
= kRangeGET_TransactionOK
.url
;
4990 transaction
.data
= kFullRangeData
;
4991 AddMockTransaction(&transaction
);
4992 RunTransactionTest(cache
.http_cache(), transaction
);
4993 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
4994 EXPECT_EQ(0, cache
.disk_cache()->open_count());
4995 EXPECT_EQ(1, cache
.disk_cache()->create_count());
4997 RemoveMockTransaction(&transaction
);
4998 AddMockTransaction(&kRangeGET_TransactionOK
);
5000 // Now see that we use the stored entry.
5001 std::string headers
;
5002 MockTransaction
transaction2(kRangeGET_TransactionOK
);
5003 RangeTransactionServer handler
;
5004 handler
.set_not_modified(true);
5005 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5007 // We are expecting a 206.
5008 Verify206Response(headers
, 40, 49);
5009 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5010 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5011 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5013 // The last transaction has finished so make sure the entry is deactivated.
5014 base::MessageLoop::current()->RunUntilIdle();
5016 // Make a request for an invalid range.
5017 MockTransaction
transaction3(kRangeGET_TransactionOK
);
5018 transaction3
.request_headers
= "Range: bytes = 80-90\r\n" EXTRA_HEADER
;
5019 transaction3
.data
= transaction
.data
;
5020 transaction3
.load_flags
= net::LOAD_PREFERRING_CACHE
;
5021 RunTransactionTestWithResponse(cache
.http_cache(), transaction3
, &headers
);
5022 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5023 EXPECT_EQ(0U, headers
.find("HTTP/1.1 200 "));
5024 EXPECT_EQ(std::string::npos
, headers
.find("Content-Range:"));
5025 EXPECT_EQ(std::string::npos
, headers
.find("Content-Length: 80"));
5027 // Make sure the entry is deactivated.
5028 base::MessageLoop::current()->RunUntilIdle();
5030 // Even though the request was invalid, we should have the entry.
5031 RunTransactionTest(cache
.http_cache(), transaction2
);
5032 EXPECT_EQ(3, cache
.disk_cache()->open_count());
5034 // Make sure the entry is deactivated.
5035 base::MessageLoop::current()->RunUntilIdle();
5037 // Now we should receive a range from the server and drop the stored entry.
5038 handler
.set_not_modified(false);
5039 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5040 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5041 Verify206Response(headers
, 40, 49);
5042 EXPECT_EQ(4, cache
.network_layer()->transaction_count());
5043 EXPECT_EQ(4, cache
.disk_cache()->open_count());
5044 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5046 RunTransactionTest(cache
.http_cache(), transaction2
);
5047 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5049 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5052 // Tests that we can handle a 200 response when dealing with sparse entries.
5053 TEST(HttpCache
, RangeRequestResultsIn200
) {
5054 MockHttpCache cache
;
5055 AddMockTransaction(&kRangeGET_TransactionOK
);
5056 std::string headers
;
5058 // Write to the cache (70-79).
5059 MockTransaction
transaction(kRangeGET_TransactionOK
);
5060 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5061 transaction
.data
= "rg: 70-79 ";
5062 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5064 Verify206Response(headers
, 70, 79);
5065 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5066 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5067 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5069 // Now we'll issue a request that results in a plain 200 response, but to
5070 // the to the same URL that we used to store sparse data, and making sure
5071 // that we ask for a range.
5072 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5073 MockTransaction
transaction2(kSimpleGET_Transaction
);
5074 transaction2
.url
= kRangeGET_TransactionOK
.url
;
5075 transaction2
.request_headers
= kRangeGET_TransactionOK
.request_headers
;
5076 AddMockTransaction(&transaction2
);
5078 RunTransactionTestWithResponse(cache
.http_cache(), transaction2
, &headers
);
5080 std::string
expected_headers(kSimpleGET_Transaction
.status
);
5081 expected_headers
.append("\n");
5082 expected_headers
.append(kSimpleGET_Transaction
.response_headers
);
5083 EXPECT_EQ(expected_headers
, headers
);
5084 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5085 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5086 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5088 RemoveMockTransaction(&transaction2
);
5091 // Tests that a range request that falls outside of the size that we know about
5092 // only deletes the entry if the resource has indeed changed.
5093 TEST(HttpCache
, RangeGET_MoreThanCurrentSize
) {
5094 MockHttpCache cache
;
5095 AddMockTransaction(&kRangeGET_TransactionOK
);
5096 std::string headers
;
5098 // Write to the cache (40-49).
5099 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5102 Verify206Response(headers
, 40, 49);
5103 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5104 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5105 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5107 // A weird request should not delete this entry. Ask for bytes 120-.
5108 MockTransaction
transaction(kRangeGET_TransactionOK
);
5109 transaction
.request_headers
= "Range: bytes = 120-\r\n" EXTRA_HEADER
;
5110 transaction
.data
= "";
5111 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5113 EXPECT_EQ(0U, headers
.find("HTTP/1.1 416 "));
5114 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5115 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5116 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5118 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5119 EXPECT_EQ(2, cache
.disk_cache()->open_count());
5120 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5122 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5125 // Tests that we don't delete a sparse entry when we cancel a request.
5126 TEST(HttpCache
, RangeGET_Cancel
) {
5127 MockHttpCache cache
;
5128 AddMockTransaction(&kRangeGET_TransactionOK
);
5130 MockHttpRequest
request(kRangeGET_TransactionOK
);
5132 Context
* c
= new Context();
5133 int rv
= cache
.CreateTransaction(&c
->trans
);
5134 ASSERT_EQ(net::OK
, rv
);
5136 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5137 if (rv
== net::ERR_IO_PENDING
)
5138 rv
= c
->callback
.WaitForResult();
5140 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5141 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5142 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5144 // Make sure that the entry has some data stored.
5145 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5146 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5147 if (rv
== net::ERR_IO_PENDING
)
5148 rv
= c
->callback
.WaitForResult();
5149 EXPECT_EQ(buf
->size(), rv
);
5151 // Destroy the transaction.
5154 // Verify that the entry has not been deleted.
5155 disk_cache::Entry
* entry
;
5156 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5158 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5161 // Tests that we don't delete a sparse entry when we start a new request after
5162 // cancelling the previous one.
5163 TEST(HttpCache
, RangeGET_Cancel2
) {
5164 MockHttpCache cache
;
5165 AddMockTransaction(&kRangeGET_TransactionOK
);
5167 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5168 MockHttpRequest
request(kRangeGET_TransactionOK
);
5169 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5171 Context
* c
= new Context();
5172 int rv
= cache
.CreateTransaction(&c
->trans
);
5173 ASSERT_EQ(net::OK
, rv
);
5175 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5176 if (rv
== net::ERR_IO_PENDING
)
5177 rv
= c
->callback
.WaitForResult();
5179 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5180 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5181 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5183 // Make sure that we revalidate the entry and read from the cache (a single
5184 // read will return while waiting for the network).
5185 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5186 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5187 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5188 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5189 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5191 // Destroy the transaction before completing the read.
5194 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5195 // message loop. This means that a new transaction will just reuse the same
5196 // active entry (no open or create).
5198 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5200 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5201 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5202 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5203 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5206 // A slight variation of the previous test, this time we cancel two requests in
5207 // a row, making sure that the second is waiting for the entry to be ready.
5208 TEST(HttpCache
, RangeGET_Cancel3
) {
5209 MockHttpCache cache
;
5210 AddMockTransaction(&kRangeGET_TransactionOK
);
5212 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5213 MockHttpRequest
request(kRangeGET_TransactionOK
);
5214 request
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5216 Context
* c
= new Context();
5217 int rv
= cache
.CreateTransaction(&c
->trans
);
5218 ASSERT_EQ(net::OK
, rv
);
5220 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5221 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5222 rv
= c
->callback
.WaitForResult();
5224 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5225 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5226 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5228 // Make sure that we revalidate the entry and read from the cache (a single
5229 // read will return while waiting for the network).
5230 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5231 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5232 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5233 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5234 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5236 // Destroy the transaction before completing the read.
5239 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5240 // message loop. This means that a new transaction will just reuse the same
5241 // active entry (no open or create).
5244 rv
= cache
.CreateTransaction(&c
->trans
);
5245 ASSERT_EQ(net::OK
, rv
);
5247 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5248 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5250 MockDiskEntry::IgnoreCallbacks(true);
5251 base::MessageLoop::current()->RunUntilIdle();
5252 MockDiskEntry::IgnoreCallbacks(false);
5254 // The new transaction is waiting for the query range callback.
5257 // And we should not crash when the callback is delivered.
5258 base::MessageLoop::current()->RunUntilIdle();
5260 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5261 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5262 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5263 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5266 // Tests that an invalid range response results in no cached entry.
5267 TEST(HttpCache
, RangeGET_InvalidResponse1
) {
5268 MockHttpCache cache
;
5269 std::string headers
;
5271 MockTransaction
transaction(kRangeGET_TransactionOK
);
5272 transaction
.handler
= NULL
;
5273 transaction
.response_headers
= "Content-Range: bytes 40-49/45\n"
5274 "Content-Length: 10\n";
5275 AddMockTransaction(&transaction
);
5276 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5278 std::string
expected(transaction
.status
);
5279 expected
.append("\n");
5280 expected
.append(transaction
.response_headers
);
5281 EXPECT_EQ(expected
, headers
);
5283 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5284 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5285 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5287 // Verify that we don't have a cached entry.
5288 disk_cache::Entry
* entry
;
5289 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5291 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5294 // Tests that we reject a range that doesn't match the content-length.
5295 TEST(HttpCache
, RangeGET_InvalidResponse2
) {
5296 MockHttpCache cache
;
5297 std::string headers
;
5299 MockTransaction
transaction(kRangeGET_TransactionOK
);
5300 transaction
.handler
= NULL
;
5301 transaction
.response_headers
= "Content-Range: bytes 40-49/80\n"
5302 "Content-Length: 20\n";
5303 AddMockTransaction(&transaction
);
5304 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5306 std::string
expected(transaction
.status
);
5307 expected
.append("\n");
5308 expected
.append(transaction
.response_headers
);
5309 EXPECT_EQ(expected
, headers
);
5311 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5312 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5313 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5315 // Verify that we don't have a cached entry.
5316 disk_cache::Entry
* entry
;
5317 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5319 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5322 // Tests that if a server tells us conflicting information about a resource we
5324 TEST(HttpCache
, RangeGET_InvalidResponse3
) {
5325 MockHttpCache cache
;
5326 std::string headers
;
5328 MockTransaction
transaction(kRangeGET_TransactionOK
);
5329 transaction
.handler
= NULL
;
5330 transaction
.request_headers
= "Range: bytes = 50-59\r\n" EXTRA_HEADER
;
5331 std::string
response_headers(transaction
.response_headers
);
5332 response_headers
.append("Content-Range: bytes 50-59/160\n");
5333 transaction
.response_headers
= response_headers
.c_str();
5334 AddMockTransaction(&transaction
);
5335 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5337 Verify206Response(headers
, 50, 59);
5338 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5339 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5340 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5342 RemoveMockTransaction(&transaction
);
5343 AddMockTransaction(&kRangeGET_TransactionOK
);
5345 // This transaction will report a resource size of 80 bytes, and we think it's
5346 // 160 so we should ignore the response.
5347 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
5350 Verify206Response(headers
, 40, 49);
5351 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5352 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5353 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5355 // Verify that the entry is gone.
5356 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5357 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5358 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5359 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5362 // Tests that we handle large range values properly.
5363 TEST(HttpCache
, RangeGET_LargeValues
) {
5364 // We need a real sparse cache for this test.
5365 MockHttpCache
cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
5366 std::string headers
;
5368 MockTransaction
transaction(kRangeGET_TransactionOK
);
5369 transaction
.handler
= NULL
;
5370 transaction
.request_headers
= "Range: bytes = 4294967288-4294967297\r\n"
5372 transaction
.response_headers
=
5374 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5375 "Content-Length: 10\n";
5376 AddMockTransaction(&transaction
);
5377 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5379 std::string
expected(transaction
.status
);
5380 expected
.append("\n");
5381 expected
.append(transaction
.response_headers
);
5382 EXPECT_EQ(expected
, headers
);
5384 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5386 // Verify that we have a cached entry.
5387 disk_cache::Entry
* en
;
5388 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &en
));
5391 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5394 // Tests that we don't crash with a range request if the disk cache was not
5395 // initialized properly.
5396 TEST(HttpCache
, RangeGET_NoDiskCache
) {
5397 MockBlockingBackendFactory
* factory
= new MockBlockingBackendFactory();
5398 factory
->set_fail(true);
5399 factory
->FinishCreation(); // We'll complete synchronously.
5400 MockHttpCache
cache(factory
);
5402 AddMockTransaction(&kRangeGET_TransactionOK
);
5404 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5405 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5407 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5410 // Tests that we handle byte range requests that skip the cache.
5411 TEST(HttpCache
, RangeHEAD
) {
5412 MockHttpCache cache
;
5413 AddMockTransaction(&kRangeGET_TransactionOK
);
5415 MockTransaction
transaction(kRangeGET_TransactionOK
);
5416 transaction
.request_headers
= "Range: bytes = -10\r\n" EXTRA_HEADER
;
5417 transaction
.method
= "HEAD";
5418 transaction
.data
= "rg: 70-79 ";
5420 std::string headers
;
5421 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5423 Verify206Response(headers
, 70, 79);
5424 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5425 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5426 EXPECT_EQ(0, cache
.disk_cache()->create_count());
5428 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5431 // Tests that we don't crash when after reading from the cache we issue a
5432 // request for the next range and the server gives us a 200 synchronously.
5433 TEST(HttpCache
, RangeGET_FastFlakyServer
) {
5434 MockHttpCache cache
;
5436 ScopedMockTransaction
transaction(kRangeGET_TransactionOK
);
5437 transaction
.request_headers
= "Range: bytes = 40-\r\n" EXTRA_HEADER
;
5438 transaction
.test_mode
= TEST_MODE_SYNC_NET_START
;
5439 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
5441 // Write to the cache.
5442 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5444 // And now read from the cache and the network.
5445 RangeTransactionServer handler
;
5446 handler
.set_bad_200(true);
5447 transaction
.data
= "Not a range";
5448 net::CapturingBoundNetLog log
;
5449 RunTransactionTestWithLog(cache
.http_cache(), transaction
, log
.bound());
5451 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5453 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5454 EXPECT_TRUE(LogContainsEventType(
5455 log
, net::NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST
));
5458 // Tests that when the server gives us less data than expected, we don't keep
5459 // asking for more data.
5460 TEST(HttpCache
, RangeGET_FastFlakyServer2
) {
5461 MockHttpCache cache
;
5463 // First, check with an empty cache (WRITE mode).
5464 MockTransaction
transaction(kRangeGET_TransactionOK
);
5465 transaction
.request_headers
= "Range: bytes = 40-49\r\n" EXTRA_HEADER
;
5466 transaction
.data
= "rg: 40-"; // Less than expected.
5467 transaction
.handler
= NULL
;
5468 std::string
headers(transaction
.response_headers
);
5469 headers
.append("Content-Range: bytes 40-49/80\n");
5470 transaction
.response_headers
= headers
.c_str();
5472 AddMockTransaction(&transaction
);
5474 // Write to the cache.
5475 RunTransactionTest(cache
.http_cache(), transaction
);
5477 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5478 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5479 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5481 // Now verify that even in READ_WRITE mode, we forward the bad response to
5483 transaction
.request_headers
= "Range: bytes = 60-69\r\n" EXTRA_HEADER
;
5484 transaction
.data
= "rg: 60-"; // Less than expected.
5485 headers
= kRangeGET_TransactionOK
.response_headers
;
5486 headers
.append("Content-Range: bytes 60-69/80\n");
5487 transaction
.response_headers
= headers
.c_str();
5489 RunTransactionTest(cache
.http_cache(), transaction
);
5491 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5492 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5493 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5495 RemoveMockTransaction(&transaction
);
5498 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5499 // This test hits a NOTREACHED so it is a release mode only test.
5500 TEST(HttpCache
, RangeGET_OK_LoadOnlyFromCache
) {
5501 MockHttpCache cache
;
5502 AddMockTransaction(&kRangeGET_TransactionOK
);
5504 // Write to the cache (40-49).
5505 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
5506 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5507 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5508 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5510 // Force this transaction to read from the cache.
5511 MockTransaction
transaction(kRangeGET_TransactionOK
);
5512 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
5514 MockHttpRequest
request(transaction
);
5515 net::TestCompletionCallback callback
;
5517 scoped_ptr
<net::HttpTransaction
> trans
;
5518 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
5519 EXPECT_EQ(net::OK
, rv
);
5520 ASSERT_TRUE(trans
.get());
5522 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
5523 if (rv
== net::ERR_IO_PENDING
)
5524 rv
= callback
.WaitForResult();
5525 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
5529 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5530 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5531 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5533 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5537 // Tests the handling of the "truncation" flag.
5538 TEST(HttpCache
, WriteResponseInfo_Truncated
) {
5539 MockHttpCache cache
;
5540 disk_cache::Entry
* entry
;
5541 ASSERT_TRUE(cache
.CreateBackendEntry("http://www.google.com", &entry
,
5544 std::string
headers("HTTP/1.1 200 OK");
5545 headers
= net::HttpUtil::AssembleRawHeaders(headers
.data(), headers
.size());
5546 net::HttpResponseInfo response
;
5547 response
.headers
= new net::HttpResponseHeaders(headers
);
5549 // Set the last argument for this to be an incomplete request.
5550 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, true));
5551 bool truncated
= false;
5552 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5553 EXPECT_TRUE(truncated
);
5555 // And now test the opposite case.
5556 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry
, &response
, true, false));
5558 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5559 EXPECT_FALSE(truncated
);
5563 // Tests basic pickling/unpickling of HttpResponseInfo.
5564 TEST(HttpCache
, PersistHttpResponseInfo
) {
5565 // Set some fields (add more if needed.)
5566 net::HttpResponseInfo response1
;
5567 response1
.was_cached
= false;
5568 response1
.socket_address
= net::HostPortPair("1.2.3.4", 80);
5569 response1
.headers
= new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5573 response1
.Persist(&pickle
, false, false);
5576 net::HttpResponseInfo response2
;
5577 bool response_truncated
;
5578 EXPECT_TRUE(response2
.InitFromPickle(pickle
, &response_truncated
));
5579 EXPECT_FALSE(response_truncated
);
5582 EXPECT_TRUE(response2
.was_cached
); // InitFromPickle sets this flag.
5583 EXPECT_EQ("1.2.3.4", response2
.socket_address
.host());
5584 EXPECT_EQ(80, response2
.socket_address
.port());
5585 EXPECT_EQ("HTTP/1.1 200 OK", response2
.headers
->GetStatusLine());
5588 // Tests that we delete an entry when the request is cancelled before starting
5589 // to read from the network.
5590 TEST(HttpCache
, DoomOnDestruction
) {
5591 MockHttpCache cache
;
5593 MockHttpRequest
request(kSimpleGET_Transaction
);
5595 Context
* c
= new Context();
5596 int rv
= cache
.CreateTransaction(&c
->trans
);
5597 ASSERT_EQ(net::OK
, rv
);
5599 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5600 if (rv
== net::ERR_IO_PENDING
)
5601 c
->result
= c
->callback
.WaitForResult();
5603 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5604 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5605 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5607 // Destroy the transaction. We only have the headers so we should delete this
5611 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5613 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5614 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5615 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5618 // Tests that we delete an entry when the request is cancelled if the response
5619 // does not have content-length and strong validators.
5620 TEST(HttpCache
, DoomOnDestruction2
) {
5621 MockHttpCache cache
;
5623 MockHttpRequest
request(kSimpleGET_Transaction
);
5625 Context
* c
= new Context();
5626 int rv
= cache
.CreateTransaction(&c
->trans
);
5627 ASSERT_EQ(net::OK
, rv
);
5629 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5630 if (rv
== net::ERR_IO_PENDING
)
5631 rv
= c
->callback
.WaitForResult();
5633 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5634 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5635 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5637 // Make sure that the entry has some data stored.
5638 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5639 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5640 if (rv
== net::ERR_IO_PENDING
)
5641 rv
= c
->callback
.WaitForResult();
5642 EXPECT_EQ(buf
->size(), rv
);
5644 // Destroy the transaction.
5647 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5649 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5650 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5651 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5654 // Tests that we delete an entry when the request is cancelled if the response
5655 // has an "Accept-Ranges: none" header.
5656 TEST(HttpCache
, DoomOnDestruction3
) {
5657 MockHttpCache cache
;
5659 MockTransaction
transaction(kSimpleGET_Transaction
);
5660 transaction
.response_headers
=
5661 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5662 "Content-Length: 22\n"
5663 "Accept-Ranges: none\n"
5664 "Etag: \"foopy\"\n";
5665 AddMockTransaction(&transaction
);
5666 MockHttpRequest
request(transaction
);
5668 Context
* c
= new Context();
5669 int rv
= cache
.CreateTransaction(&c
->trans
);
5670 ASSERT_EQ(net::OK
, rv
);
5672 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5673 if (rv
== net::ERR_IO_PENDING
)
5674 rv
= c
->callback
.WaitForResult();
5676 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5677 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5678 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5680 // Make sure that the entry has some data stored.
5681 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5682 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5683 if (rv
== net::ERR_IO_PENDING
)
5684 rv
= c
->callback
.WaitForResult();
5685 EXPECT_EQ(buf
->size(), rv
);
5687 // Destroy the transaction.
5690 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
5692 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5693 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5694 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5696 RemoveMockTransaction(&transaction
);
5699 // Tests that we mark an entry as incomplete when the request is cancelled.
5700 TEST(HttpCache
, SetTruncatedFlag
) {
5701 MockHttpCache cache
;
5703 MockTransaction
transaction(kSimpleGET_Transaction
);
5704 transaction
.response_headers
=
5705 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5706 "Content-Length: 22\n"
5707 "Etag: \"foopy\"\n";
5708 AddMockTransaction(&transaction
);
5709 MockHttpRequest
request(transaction
);
5711 scoped_ptr
<Context
> c(new Context());
5713 int rv
= cache
.CreateTransaction(&c
->trans
);
5714 ASSERT_EQ(net::OK
, rv
);
5716 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5717 if (rv
== net::ERR_IO_PENDING
)
5718 rv
= c
->callback
.WaitForResult();
5720 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5721 EXPECT_EQ(0, cache
.disk_cache()->open_count());
5722 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5724 // Make sure that the entry has some data stored.
5725 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(10));
5726 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5727 if (rv
== net::ERR_IO_PENDING
)
5728 rv
= c
->callback
.WaitForResult();
5729 EXPECT_EQ(buf
->size(), rv
);
5731 // We want to cancel the request when the transaction is busy.
5732 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5733 EXPECT_EQ(net::ERR_IO_PENDING
, rv
);
5734 EXPECT_FALSE(c
->callback
.have_result());
5736 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL
);
5738 // Destroy the transaction.
5740 MockHttpCache::SetTestMode(0);
5743 // Make sure that we don't invoke the callback. We may have an issue if the
5744 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5745 // could end up with the transaction being deleted twice if we send any
5746 // notification from the transaction destructor (see http://crbug.com/31723).
5747 EXPECT_FALSE(c
->callback
.have_result());
5749 // Verify that the entry is marked as incomplete.
5750 disk_cache::Entry
* entry
;
5751 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5752 net::HttpResponseInfo response
;
5753 bool truncated
= false;
5754 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5755 EXPECT_TRUE(truncated
);
5758 RemoveMockTransaction(&transaction
);
5761 // Tests that we don't mark an entry as truncated when we read everything.
5762 TEST(HttpCache
, DontSetTruncatedFlag
) {
5763 MockHttpCache cache
;
5765 MockTransaction
transaction(kSimpleGET_Transaction
);
5766 transaction
.response_headers
=
5767 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5768 "Content-Length: 22\n"
5769 "Etag: \"foopy\"\n";
5770 AddMockTransaction(&transaction
);
5771 MockHttpRequest
request(transaction
);
5773 scoped_ptr
<Context
> c(new Context());
5774 int rv
= cache
.CreateTransaction(&c
->trans
);
5775 ASSERT_EQ(net::OK
, rv
);
5777 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5778 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5781 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(22));
5782 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5783 EXPECT_EQ(buf
->size(), c
->callback
.GetResult(rv
));
5785 // Destroy the transaction.
5788 // Verify that the entry is not marked as truncated.
5789 disk_cache::Entry
* entry
;
5790 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
5791 net::HttpResponseInfo response
;
5792 bool truncated
= true;
5793 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5794 EXPECT_FALSE(truncated
);
5797 RemoveMockTransaction(&transaction
);
5800 // Tests that we can continue with a request that was interrupted.
5801 TEST(HttpCache
, GET_IncompleteResource
) {
5802 MockHttpCache cache
;
5803 AddMockTransaction(&kRangeGET_TransactionOK
);
5805 std::string
raw_headers("HTTP/1.1 200 OK\n"
5806 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5808 "Accept-Ranges: bytes\n"
5809 "Content-Length: 80\n");
5810 CreateTruncatedEntry(raw_headers
, &cache
);
5812 // Now make a regular request.
5813 std::string headers
;
5814 MockTransaction
transaction(kRangeGET_TransactionOK
);
5815 transaction
.request_headers
= EXTRA_HEADER
;
5816 transaction
.data
= kFullRangeData
;
5817 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5819 // We update the headers with the ones received while revalidating.
5820 std::string
expected_headers(
5822 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5823 "Accept-Ranges: bytes\n"
5825 "Content-Length: 80\n");
5827 EXPECT_EQ(expected_headers
, headers
);
5828 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5829 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5830 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5832 // Verify that the disk entry was updated.
5833 disk_cache::Entry
* entry
;
5834 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5835 EXPECT_EQ(80, entry
->GetDataSize(1));
5836 bool truncated
= true;
5837 net::HttpResponseInfo response
;
5838 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
5839 EXPECT_FALSE(truncated
);
5842 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5845 // Tests the handling of no-store when revalidating a truncated entry.
5846 TEST(HttpCache
, GET_IncompleteResource_NoStore
) {
5847 MockHttpCache cache
;
5848 AddMockTransaction(&kRangeGET_TransactionOK
);
5850 std::string
raw_headers("HTTP/1.1 200 OK\n"
5851 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5853 "Accept-Ranges: bytes\n"
5854 "Content-Length: 80\n");
5855 CreateTruncatedEntry(raw_headers
, &cache
);
5856 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5858 // Now make a regular request.
5859 MockTransaction
transaction(kRangeGET_TransactionOK
);
5860 transaction
.request_headers
= EXTRA_HEADER
;
5861 std::string
response_headers(transaction
.response_headers
);
5862 response_headers
+= ("Cache-Control: no-store\n");
5863 transaction
.response_headers
= response_headers
.c_str();
5864 transaction
.data
= kFullRangeData
;
5865 AddMockTransaction(&transaction
);
5867 std::string headers
;
5868 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5870 // We update the headers with the ones received while revalidating.
5871 std::string
expected_headers(
5873 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5874 "Accept-Ranges: bytes\n"
5875 "Cache-Control: no-store\n"
5877 "Content-Length: 80\n");
5879 EXPECT_EQ(expected_headers
, headers
);
5880 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5881 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5882 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5884 // Verify that the disk entry was deleted.
5885 disk_cache::Entry
* entry
;
5886 EXPECT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5887 RemoveMockTransaction(&transaction
);
5890 // Tests cancelling a request after the server sent no-store.
5891 TEST(HttpCache
, GET_IncompleteResource_Cancel
) {
5892 MockHttpCache cache
;
5893 AddMockTransaction(&kRangeGET_TransactionOK
);
5895 std::string
raw_headers("HTTP/1.1 200 OK\n"
5896 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5898 "Accept-Ranges: bytes\n"
5899 "Content-Length: 80\n");
5900 CreateTruncatedEntry(raw_headers
, &cache
);
5901 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5903 // Now make a regular request.
5904 MockTransaction
transaction(kRangeGET_TransactionOK
);
5905 transaction
.request_headers
= EXTRA_HEADER
;
5906 std::string
response_headers(transaction
.response_headers
);
5907 response_headers
+= ("Cache-Control: no-store\n");
5908 transaction
.response_headers
= response_headers
.c_str();
5909 transaction
.data
= kFullRangeData
;
5910 AddMockTransaction(&transaction
);
5912 MockHttpRequest
request(transaction
);
5913 Context
* c
= new Context();
5915 int rv
= cache
.CreateTransaction(&c
->trans
);
5916 ASSERT_EQ(net::OK
, rv
);
5918 // Queue another request to this transaction. We have to start this request
5919 // before the first one gets the response from the server and dooms the entry,
5920 // otherwise it will just create a new entry without being queued to the first
5922 Context
* pending
= new Context();
5923 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&pending
->trans
));
5925 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
5926 EXPECT_EQ(net::ERR_IO_PENDING
,
5927 pending
->trans
->Start(&request
, pending
->callback
.callback(),
5928 net::BoundNetLog()));
5929 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
5931 // Make sure that the entry has some data stored.
5932 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(5));
5933 rv
= c
->trans
->Read(buf
.get(), buf
->size(), c
->callback
.callback());
5934 EXPECT_EQ(5, c
->callback
.GetResult(rv
));
5936 // Cancel the requests.
5940 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
5941 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5942 EXPECT_EQ(2, cache
.disk_cache()->create_count());
5944 base::MessageLoop::current()->RunUntilIdle();
5945 RemoveMockTransaction(&transaction
);
5948 // Tests that we delete truncated entries if the server changes its mind midway.
5949 TEST(HttpCache
, GET_IncompleteResource2
) {
5950 MockHttpCache cache
;
5951 AddMockTransaction(&kRangeGET_TransactionOK
);
5953 // Content-length will be intentionally bad.
5954 std::string
raw_headers("HTTP/1.1 200 OK\n"
5955 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5957 "Accept-Ranges: bytes\n"
5958 "Content-Length: 50\n");
5959 CreateTruncatedEntry(raw_headers
, &cache
);
5961 // Now make a regular request. We expect the code to fail the validation and
5962 // retry the request without using byte ranges.
5963 std::string headers
;
5964 MockTransaction
transaction(kRangeGET_TransactionOK
);
5965 transaction
.request_headers
= EXTRA_HEADER
;
5966 transaction
.data
= "Not a range";
5967 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
5969 // The server will return 200 instead of a byte range.
5970 std::string
expected_headers(
5972 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5974 EXPECT_EQ(expected_headers
, headers
);
5975 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
5976 EXPECT_EQ(1, cache
.disk_cache()->open_count());
5977 EXPECT_EQ(1, cache
.disk_cache()->create_count());
5979 // Verify that the disk entry was deleted.
5980 disk_cache::Entry
* entry
;
5981 ASSERT_FALSE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
5982 RemoveMockTransaction(&kRangeGET_TransactionOK
);
5985 // Tests that we always validate a truncated request.
5986 TEST(HttpCache
, GET_IncompleteResource3
) {
5987 MockHttpCache cache
;
5988 AddMockTransaction(&kRangeGET_TransactionOK
);
5990 // This should not require validation for 10 hours.
5991 std::string
raw_headers("HTTP/1.1 200 OK\n"
5992 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5994 "Cache-Control: max-age= 36000\n"
5995 "Accept-Ranges: bytes\n"
5996 "Content-Length: 80\n");
5997 CreateTruncatedEntry(raw_headers
, &cache
);
5999 // Now make a regular request.
6000 std::string headers
;
6001 MockTransaction
transaction(kRangeGET_TransactionOK
);
6002 transaction
.request_headers
= EXTRA_HEADER
;
6003 transaction
.data
= kFullRangeData
;
6005 scoped_ptr
<Context
> c(new Context
);
6006 int rv
= cache
.CreateTransaction(&c
->trans
);
6007 ASSERT_EQ(net::OK
, rv
);
6009 MockHttpRequest
request(transaction
);
6010 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
6011 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
6013 // We should have checked with the server before finishing Start().
6014 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6015 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6016 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6018 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6021 // Tests that we handle 401s for truncated resources.
6022 TEST(HttpCache
, GET_IncompleteResourceWithAuth
) {
6023 MockHttpCache cache
;
6024 AddMockTransaction(&kRangeGET_TransactionOK
);
6026 std::string
raw_headers("HTTP/1.1 200 OK\n"
6027 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6029 "Accept-Ranges: bytes\n"
6030 "Content-Length: 80\n");
6031 CreateTruncatedEntry(raw_headers
, &cache
);
6033 // Now make a regular request.
6034 MockTransaction
transaction(kRangeGET_TransactionOK
);
6035 transaction
.request_headers
= "X-Require-Mock-Auth: dummy\r\n"
6037 transaction
.data
= kFullRangeData
;
6038 RangeTransactionServer handler
;
6040 scoped_ptr
<Context
> c(new Context
);
6041 int rv
= cache
.CreateTransaction(&c
->trans
);
6042 ASSERT_EQ(net::OK
, rv
);
6044 MockHttpRequest
request(transaction
);
6045 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
6046 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
6048 const net::HttpResponseInfo
* response
= c
->trans
->GetResponseInfo();
6049 ASSERT_TRUE(response
);
6050 ASSERT_EQ(401, response
->headers
->response_code());
6051 rv
= c
->trans
->RestartWithAuth(net::AuthCredentials(),
6052 c
->callback
.callback());
6053 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
6054 response
= c
->trans
->GetResponseInfo();
6055 ASSERT_TRUE(response
);
6056 ASSERT_EQ(200, response
->headers
->response_code());
6058 ReadAndVerifyTransaction(c
->trans
.get(), transaction
);
6059 c
.reset(); // The destructor could delete the entry.
6060 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6062 // Verify that the entry was not deleted.
6063 disk_cache::Entry
* entry
;
6064 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6067 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6070 // Tests that we cache a 200 response to the validation request.
6071 TEST(HttpCache
, GET_IncompleteResource4
) {
6072 MockHttpCache cache
;
6073 AddMockTransaction(&kRangeGET_TransactionOK
);
6075 std::string
raw_headers("HTTP/1.1 200 OK\n"
6076 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6078 "Accept-Ranges: bytes\n"
6079 "Content-Length: 80\n");
6080 CreateTruncatedEntry(raw_headers
, &cache
);
6082 // Now make a regular request.
6083 std::string headers
;
6084 MockTransaction
transaction(kRangeGET_TransactionOK
);
6085 transaction
.request_headers
= EXTRA_HEADER
;
6086 transaction
.data
= "Not a range";
6087 RangeTransactionServer handler
;
6088 handler
.set_bad_200(true);
6089 RunTransactionTestWithResponse(cache
.http_cache(), transaction
, &headers
);
6091 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6092 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6093 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6095 // Verify that the disk entry was updated.
6096 disk_cache::Entry
* entry
;
6097 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6098 EXPECT_EQ(11, entry
->GetDataSize(1));
6099 bool truncated
= true;
6100 net::HttpResponseInfo response
;
6101 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6102 EXPECT_FALSE(truncated
);
6105 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6108 // Tests that when we cancel a request that was interrupted, we mark it again
6110 TEST(HttpCache
, GET_CancelIncompleteResource
) {
6111 MockHttpCache cache
;
6112 AddMockTransaction(&kRangeGET_TransactionOK
);
6114 std::string
raw_headers("HTTP/1.1 200 OK\n"
6115 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6117 "Accept-Ranges: bytes\n"
6118 "Content-Length: 80\n");
6119 CreateTruncatedEntry(raw_headers
, &cache
);
6121 // Now make a regular request.
6122 MockTransaction
transaction(kRangeGET_TransactionOK
);
6123 transaction
.request_headers
= EXTRA_HEADER
;
6125 MockHttpRequest
request(transaction
);
6126 Context
* c
= new Context();
6127 int rv
= cache
.CreateTransaction(&c
->trans
);
6128 ASSERT_EQ(net::OK
, rv
);
6130 rv
= c
->trans
->Start(&request
, c
->callback
.callback(), net::BoundNetLog());
6131 EXPECT_EQ(net::OK
, c
->callback
.GetResult(rv
));
6133 // Read 20 bytes from the cache, and 10 from the net.
6134 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(100));
6135 rv
= c
->trans
->Read(buf
.get(), 20, c
->callback
.callback());
6136 EXPECT_EQ(20, c
->callback
.GetResult(rv
));
6137 rv
= c
->trans
->Read(buf
.get(), 10, c
->callback
.callback());
6138 EXPECT_EQ(10, c
->callback
.GetResult(rv
));
6140 // At this point, we are already reading so canceling the request should leave
6144 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6145 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6146 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6148 // Verify that the disk entry was updated: now we have 30 bytes.
6149 disk_cache::Entry
* entry
;
6150 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6151 EXPECT_EQ(30, entry
->GetDataSize(1));
6152 bool truncated
= false;
6153 net::HttpResponseInfo response
;
6154 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6155 EXPECT_TRUE(truncated
);
6157 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6160 // Tests that we can handle range requests when we have a truncated entry.
6161 TEST(HttpCache
, RangeGET_IncompleteResource
) {
6162 MockHttpCache cache
;
6163 AddMockTransaction(&kRangeGET_TransactionOK
);
6165 // Content-length will be intentionally bogus.
6166 std::string
raw_headers("HTTP/1.1 200 OK\n"
6167 "Last-Modified: something\n"
6169 "Accept-Ranges: bytes\n"
6170 "Content-Length: 10\n");
6171 CreateTruncatedEntry(raw_headers
, &cache
);
6173 // Now make a range request.
6174 std::string headers
;
6175 RunTransactionTestWithResponse(cache
.http_cache(), kRangeGET_TransactionOK
,
6178 Verify206Response(headers
, 40, 49);
6179 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6180 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6181 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6183 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6186 TEST(HttpCache
, SyncRead
) {
6187 MockHttpCache cache
;
6189 // This test ensures that a read that completes synchronously does not cause
6192 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6193 transaction
.test_mode
|= (TEST_MODE_SYNC_CACHE_START
|
6194 TEST_MODE_SYNC_CACHE_READ
|
6195 TEST_MODE_SYNC_CACHE_WRITE
);
6197 MockHttpRequest
r1(transaction
),
6201 TestTransactionConsumer
c1(net::DEFAULT_PRIORITY
, cache
.http_cache()),
6202 c2(net::DEFAULT_PRIORITY
, cache
.http_cache()),
6203 c3(net::DEFAULT_PRIORITY
, cache
.http_cache());
6205 c1
.Start(&r1
, net::BoundNetLog());
6207 r2
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
6208 c2
.Start(&r2
, net::BoundNetLog());
6210 r3
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
6211 c3
.Start(&r3
, net::BoundNetLog());
6213 base::MessageLoop::current()->Run();
6215 EXPECT_TRUE(c1
.is_done());
6216 EXPECT_TRUE(c2
.is_done());
6217 EXPECT_TRUE(c3
.is_done());
6219 EXPECT_EQ(net::OK
, c1
.error());
6220 EXPECT_EQ(net::OK
, c2
.error());
6221 EXPECT_EQ(net::OK
, c3
.error());
6224 TEST(HttpCache
, ValidationResultsIn200
) {
6225 MockHttpCache cache
;
6227 // This test ensures that a conditional request, which results in a 200
6228 // instead of a 304, properly truncates the existing response data.
6230 // write to the cache
6231 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6233 // force this transaction to validate the cache
6234 MockTransaction
transaction(kETagGET_Transaction
);
6235 transaction
.load_flags
|= net::LOAD_VALIDATE_CACHE
;
6236 RunTransactionTest(cache
.http_cache(), transaction
);
6238 // read from the cache
6239 RunTransactionTest(cache
.http_cache(), kETagGET_Transaction
);
6242 TEST(HttpCache
, CachedRedirect
) {
6243 MockHttpCache cache
;
6245 ScopedMockTransaction
kTestTransaction(kSimpleGET_Transaction
);
6246 kTestTransaction
.status
= "HTTP/1.1 301 Moved Permanently";
6247 kTestTransaction
.response_headers
= "Location: http://www.bar.com/\n";
6249 MockHttpRequest
request(kTestTransaction
);
6250 net::TestCompletionCallback callback
;
6252 // Write to the cache.
6254 scoped_ptr
<net::HttpTransaction
> trans
;
6255 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6257 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6258 if (rv
== net::ERR_IO_PENDING
)
6259 rv
= callback
.WaitForResult();
6260 ASSERT_EQ(net::OK
, rv
);
6262 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
6265 EXPECT_EQ(info
->headers
->response_code(), 301);
6267 std::string location
;
6268 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6269 EXPECT_EQ(location
, "http://www.bar.com/");
6271 // Mark the transaction as completed so it is cached.
6272 trans
->DoneReading();
6274 // Destroy transaction when going out of scope. We have not actually
6275 // read the response body -- want to test that it is still getting cached.
6277 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6278 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6279 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6281 // Active entries in the cache are not retired synchronously. Make
6282 // sure the next run hits the MockHttpCache and open_count is
6284 base::MessageLoop::current()->RunUntilIdle();
6286 // Read from the cache.
6288 scoped_ptr
<net::HttpTransaction
> trans
;
6289 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6291 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6292 if (rv
== net::ERR_IO_PENDING
)
6293 rv
= callback
.WaitForResult();
6294 ASSERT_EQ(net::OK
, rv
);
6296 const net::HttpResponseInfo
* info
= trans
->GetResponseInfo();
6299 EXPECT_EQ(info
->headers
->response_code(), 301);
6301 std::string location
;
6302 info
->headers
->EnumerateHeader(NULL
, "Location", &location
);
6303 EXPECT_EQ(location
, "http://www.bar.com/");
6305 // Mark the transaction as completed so it is cached.
6306 trans
->DoneReading();
6308 // Destroy transaction when going out of scope. We have not actually
6309 // read the response body -- want to test that it is still getting cached.
6311 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6312 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6313 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6316 // Verify that no-cache resources are stored in cache, but are not fetched from
6317 // cache during normal loads.
6318 TEST(HttpCache
, CacheControlNoCacheNormalLoad
) {
6319 MockHttpCache cache
;
6321 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6322 transaction
.response_headers
= "cache-control: no-cache\n";
6325 RunTransactionTest(cache
.http_cache(), transaction
);
6327 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6328 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6329 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6331 // Try loading again; it should result in a network fetch.
6332 RunTransactionTest(cache
.http_cache(), transaction
);
6334 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6335 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6336 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6338 disk_cache::Entry
* entry
;
6339 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6343 // Verify that no-cache resources are stored in cache and fetched from cache
6344 // when the LOAD_PREFERRING_CACHE flag is set.
6345 TEST(HttpCache
, CacheControlNoCacheHistoryLoad
) {
6346 MockHttpCache cache
;
6348 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6349 transaction
.response_headers
= "cache-control: no-cache\n";
6352 RunTransactionTest(cache
.http_cache(), transaction
);
6354 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6355 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6356 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6358 // Try loading again with LOAD_PREFERRING_CACHE.
6359 transaction
.load_flags
= net::LOAD_PREFERRING_CACHE
;
6360 RunTransactionTest(cache
.http_cache(), transaction
);
6362 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6363 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6364 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6366 disk_cache::Entry
* entry
;
6367 EXPECT_TRUE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6371 TEST(HttpCache
, CacheControlNoStore
) {
6372 MockHttpCache cache
;
6374 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6375 transaction
.response_headers
= "cache-control: no-store\n";
6378 RunTransactionTest(cache
.http_cache(), transaction
);
6380 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6381 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6382 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6384 // try loading again; it should result in a network fetch
6385 RunTransactionTest(cache
.http_cache(), transaction
);
6387 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6388 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6389 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6391 disk_cache::Entry
* entry
;
6392 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6395 TEST(HttpCache
, CacheControlNoStore2
) {
6396 // this test is similar to the above test, except that the initial response
6397 // is cachable, but when it is validated, no-store is received causing the
6398 // cached document to be deleted.
6399 MockHttpCache cache
;
6401 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6404 RunTransactionTest(cache
.http_cache(), transaction
);
6406 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6407 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6408 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6410 // try loading again; it should result in a network fetch
6411 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6412 transaction
.response_headers
= "cache-control: no-store\n";
6413 RunTransactionTest(cache
.http_cache(), transaction
);
6415 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6416 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6417 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6419 disk_cache::Entry
* entry
;
6420 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6423 TEST(HttpCache
, CacheControlNoStore3
) {
6424 // this test is similar to the above test, except that the response is a 304
6425 // instead of a 200. this should never happen in practice, but it seems like
6426 // a good thing to verify that we still destroy the cache entry.
6427 MockHttpCache cache
;
6429 ScopedMockTransaction
transaction(kETagGET_Transaction
);
6432 RunTransactionTest(cache
.http_cache(), transaction
);
6434 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6435 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6436 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6438 // try loading again; it should result in a network fetch
6439 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6440 transaction
.response_headers
= "cache-control: no-store\n";
6441 transaction
.status
= "HTTP/1.1 304 Not Modified";
6442 RunTransactionTest(cache
.http_cache(), transaction
);
6444 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6445 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6446 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6448 disk_cache::Entry
* entry
;
6449 EXPECT_FALSE(cache
.OpenBackendEntry(transaction
.url
, &entry
));
6452 // Ensure that we don't cache requests served over bad HTTPS.
6453 TEST(HttpCache
, SimpleGET_SSLError
) {
6454 MockHttpCache cache
;
6456 MockTransaction transaction
= kSimpleGET_Transaction
;
6457 transaction
.cert_status
= net::CERT_STATUS_REVOKED
;
6458 ScopedMockTransaction
scoped_transaction(transaction
);
6460 // write to the cache
6461 RunTransactionTest(cache
.http_cache(), transaction
);
6463 // Test that it was not cached.
6464 transaction
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
6466 MockHttpRequest
request(transaction
);
6467 net::TestCompletionCallback callback
;
6469 scoped_ptr
<net::HttpTransaction
> trans
;
6470 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6472 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6473 if (rv
== net::ERR_IO_PENDING
)
6474 rv
= callback
.WaitForResult();
6475 ASSERT_EQ(net::ERR_CACHE_MISS
, rv
);
6478 // Ensure that we don't crash by if left-behind transactions.
6479 TEST(HttpCache
, OutlivedTransactions
) {
6480 MockHttpCache
* cache
= new MockHttpCache
;
6482 scoped_ptr
<net::HttpTransaction
> trans
;
6483 EXPECT_EQ(net::OK
, cache
->CreateTransaction(&trans
));
6489 // Test that the disabled mode works.
6490 TEST(HttpCache
, CacheDisabledMode
) {
6491 MockHttpCache cache
;
6493 // write to the cache
6494 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6496 // go into disabled mode
6497 cache
.http_cache()->set_mode(net::HttpCache::DISABLE
);
6499 // force this transaction to write to the cache again
6500 MockTransaction
transaction(kSimpleGET_Transaction
);
6502 RunTransactionTest(cache
.http_cache(), transaction
);
6504 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6505 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6506 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6509 // Other tests check that the response headers of the cached response
6510 // get updated on 304. Here we specifically check that the
6511 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6512 // fields also gets updated.
6513 // http://crbug.com/20594.
6514 TEST(HttpCache
, UpdatesRequestResponseTimeOn304
) {
6515 MockHttpCache cache
;
6517 const char kUrl
[] = "http://foobar";
6518 const char kData
[] = "body";
6520 MockTransaction mock_network_response
= { 0 };
6521 mock_network_response
.url
= kUrl
;
6523 AddMockTransaction(&mock_network_response
);
6525 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6527 MockTransaction request
= { 0 };
6529 request
.method
= "GET";
6530 request
.request_headers
= "\r\n";
6531 request
.data
= kData
;
6533 static const Response kNetResponse1
= {
6535 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6536 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6540 kNetResponse1
.AssignTo(&mock_network_response
);
6542 RunTransactionTest(cache
.http_cache(), request
);
6544 // Request |kUrl| again, this time validating the cache and getting
6547 request
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6549 static const Response kNetResponse2
= {
6550 "HTTP/1.1 304 Not Modified",
6551 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6555 kNetResponse2
.AssignTo(&mock_network_response
);
6557 base::Time request_time
= base::Time() + base::TimeDelta::FromHours(1234);
6558 base::Time response_time
= base::Time() + base::TimeDelta::FromHours(1235);
6560 mock_network_response
.request_time
= request_time
;
6561 mock_network_response
.response_time
= response_time
;
6563 net::HttpResponseInfo response
;
6564 RunTransactionTestWithResponseInfo(cache
.http_cache(), request
, &response
);
6566 // The request and response times should have been updated.
6567 EXPECT_EQ(request_time
.ToInternalValue(),
6568 response
.request_time
.ToInternalValue());
6569 EXPECT_EQ(response_time
.ToInternalValue(),
6570 response
.response_time
.ToInternalValue());
6572 std::string headers
;
6573 response
.headers
->GetNormalizedHeaders(&headers
);
6575 EXPECT_EQ("HTTP/1.1 200 OK\n"
6576 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6577 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6580 RemoveMockTransaction(&mock_network_response
);
6583 // Tests that we can write metadata to an entry.
6584 TEST(HttpCache
, WriteMetadata_OK
) {
6585 MockHttpCache cache
;
6587 // Write to the cache
6588 net::HttpResponseInfo response
;
6589 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6591 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6594 cache
.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY
,
6595 Time::Now(), NULL
, 0);
6597 // Write meta data to the same entry.
6598 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6599 memset(buf
->data(), 0, buf
->size());
6600 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6601 cache
.http_cache()->WriteMetadata(
6602 GURL(kSimpleGET_Transaction
.url
), net::DEFAULT_PRIORITY
,
6603 response
.response_time
, buf
.get(), buf
->size());
6605 // Release the buffer before the operation takes place.
6608 // Makes sure we finish pending operations.
6609 base::MessageLoop::current()->RunUntilIdle();
6611 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6613 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6614 EXPECT_EQ(50, response
.metadata
->size());
6615 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6617 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6618 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6619 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6622 // Tests that we only write metadata to an entry if the time stamp matches.
6623 TEST(HttpCache
, WriteMetadata_Fail
) {
6624 MockHttpCache cache
;
6626 // Write to the cache
6627 net::HttpResponseInfo response
;
6628 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6630 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6632 // Attempt to write meta data to the same entry.
6633 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6634 memset(buf
->data(), 0, buf
->size());
6635 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6636 base::Time expected_time
= response
.response_time
-
6637 base::TimeDelta::FromMilliseconds(20);
6638 cache
.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction
.url
),
6639 net::DEFAULT_PRIORITY
, expected_time
,
6640 buf
.get(), buf
->size());
6642 // Makes sure we finish pending operations.
6643 base::MessageLoop::current()->RunUntilIdle();
6645 RunTransactionTestWithResponseInfo(cache
.http_cache(), kSimpleGET_Transaction
,
6647 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6649 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6650 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6651 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6654 // Tests that we can read metadata after validating the entry and with READ mode
6656 TEST(HttpCache
, ReadMetadata
) {
6657 MockHttpCache cache
;
6659 // Write to the cache
6660 net::HttpResponseInfo response
;
6661 RunTransactionTestWithResponseInfo(cache
.http_cache(),
6662 kTypicalGET_Transaction
, &response
);
6663 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6665 // Write meta data to the same entry.
6666 scoped_refptr
<net::IOBufferWithSize
> buf(new net::IOBufferWithSize(50));
6667 memset(buf
->data(), 0, buf
->size());
6668 base::strlcpy(buf
->data(), "Hi there", buf
->size());
6669 cache
.http_cache()->WriteMetadata(
6670 GURL(kTypicalGET_Transaction
.url
), net::DEFAULT_PRIORITY
,
6671 response
.response_time
, buf
.get(), buf
->size());
6673 // Makes sure we finish pending operations.
6674 base::MessageLoop::current()->RunUntilIdle();
6676 // Start with a READ mode transaction.
6677 MockTransaction
trans1(kTypicalGET_Transaction
);
6678 trans1
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
6680 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6681 ASSERT_TRUE(response
.metadata
.get() != NULL
);
6682 EXPECT_EQ(50, response
.metadata
->size());
6683 EXPECT_EQ(0, strcmp(response
.metadata
->data(), "Hi there"));
6685 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6686 EXPECT_EQ(2, cache
.disk_cache()->open_count());
6687 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6688 base::MessageLoop::current()->RunUntilIdle();
6690 // Now make sure that the entry is re-validated with the server.
6691 trans1
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6692 trans1
.status
= "HTTP/1.1 304 Not Modified";
6693 AddMockTransaction(&trans1
);
6695 response
.metadata
= NULL
;
6696 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans1
, &response
);
6697 EXPECT_TRUE(response
.metadata
.get() != NULL
);
6699 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6700 EXPECT_EQ(3, cache
.disk_cache()->open_count());
6701 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6702 base::MessageLoop::current()->RunUntilIdle();
6703 RemoveMockTransaction(&trans1
);
6705 // Now return 200 when validating the entry so the metadata will be lost.
6706 MockTransaction
trans2(kTypicalGET_Transaction
);
6707 trans2
.load_flags
= net::LOAD_VALIDATE_CACHE
;
6708 RunTransactionTestWithResponseInfo(cache
.http_cache(), trans2
, &response
);
6709 EXPECT_TRUE(response
.metadata
.get() == NULL
);
6711 EXPECT_EQ(3, cache
.network_layer()->transaction_count());
6712 EXPECT_EQ(4, cache
.disk_cache()->open_count());
6713 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6716 // Tests that we don't mark entries as truncated when a filter detects the end
6718 TEST(HttpCache
, FilterCompletion
) {
6719 MockHttpCache cache
;
6720 net::TestCompletionCallback callback
;
6723 scoped_ptr
<net::HttpTransaction
> trans
;
6724 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6726 MockHttpRequest
request(kSimpleGET_Transaction
);
6727 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6728 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6730 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6731 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6732 EXPECT_GT(callback
.GetResult(rv
), 0);
6734 // Now make sure that the entry is preserved.
6735 trans
->DoneReading();
6738 // Make sure that the ActiveEntry is gone.
6739 base::MessageLoop::current()->RunUntilIdle();
6741 // Read from the cache.
6742 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6744 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6745 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6746 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6749 // Tests that we don't mark entries as truncated and release the cache
6750 // entry when DoneReading() is called before any Read() calls, such as
6752 TEST(HttpCache
, DoneReading
) {
6753 MockHttpCache cache
;
6754 net::TestCompletionCallback callback
;
6756 ScopedMockTransaction
transaction(kSimpleGET_Transaction
);
6757 transaction
.data
= "";
6759 scoped_ptr
<net::HttpTransaction
> trans
;
6760 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6762 MockHttpRequest
request(transaction
);
6763 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6764 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6766 trans
->DoneReading();
6767 // Leave the transaction around.
6769 // Make sure that the ActiveEntry is gone.
6770 base::MessageLoop::current()->RunUntilIdle();
6772 // Read from the cache. This should not deadlock.
6773 RunTransactionTest(cache
.http_cache(), transaction
);
6775 EXPECT_EQ(1, cache
.network_layer()->transaction_count());
6776 EXPECT_EQ(1, cache
.disk_cache()->open_count());
6777 EXPECT_EQ(1, cache
.disk_cache()->create_count());
6780 // Tests that we stop caching when told.
6781 TEST(HttpCache
, StopCachingDeletesEntry
) {
6782 MockHttpCache cache
;
6783 net::TestCompletionCallback callback
;
6784 MockHttpRequest
request(kSimpleGET_Transaction
);
6787 scoped_ptr
<net::HttpTransaction
> trans
;
6788 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6790 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6791 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6793 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6794 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6795 EXPECT_EQ(10, callback
.GetResult(rv
));
6797 trans
->StopCaching();
6799 // We should be able to keep reading.
6800 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6801 EXPECT_GT(callback
.GetResult(rv
), 0);
6802 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6803 EXPECT_EQ(0, callback
.GetResult(rv
));
6806 // Make sure that the ActiveEntry is gone.
6807 base::MessageLoop::current()->RunUntilIdle();
6809 // Verify that the entry is gone.
6810 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6812 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6813 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6814 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6817 // Tests that we stop caching when told, even if DoneReading is called
6818 // after StopCaching.
6819 TEST(HttpCache
, StopCachingThenDoneReadingDeletesEntry
) {
6820 MockHttpCache cache
;
6821 net::TestCompletionCallback callback
;
6822 MockHttpRequest
request(kSimpleGET_Transaction
);
6825 scoped_ptr
<net::HttpTransaction
> trans
;
6826 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6828 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6829 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6831 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6832 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6833 EXPECT_EQ(10, callback
.GetResult(rv
));
6835 trans
->StopCaching();
6837 // We should be able to keep reading.
6838 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6839 EXPECT_GT(callback
.GetResult(rv
), 0);
6840 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6841 EXPECT_EQ(0, callback
.GetResult(rv
));
6843 // We should be able to call DoneReading.
6844 trans
->DoneReading();
6847 // Make sure that the ActiveEntry is gone.
6848 base::MessageLoop::current()->RunUntilIdle();
6850 // Verify that the entry is gone.
6851 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6853 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6854 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6855 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6858 // Tests that we stop caching when told, when using auth.
6859 TEST(HttpCache
, StopCachingWithAuthDeletesEntry
) {
6860 MockHttpCache cache
;
6861 net::TestCompletionCallback callback
;
6862 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6863 mock_transaction
.status
= "HTTP/1.1 401 Unauthorized";
6864 AddMockTransaction(&mock_transaction
);
6865 MockHttpRequest
request(mock_transaction
);
6868 scoped_ptr
<net::HttpTransaction
> trans
;
6869 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6871 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6872 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6874 trans
->StopCaching();
6876 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6877 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6878 EXPECT_EQ(callback
.GetResult(rv
), 10);
6880 RemoveMockTransaction(&mock_transaction
);
6882 // Make sure that the ActiveEntry is gone.
6883 base::MessageLoop::current()->RunUntilIdle();
6885 // Verify that the entry is gone.
6886 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
6888 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
6889 EXPECT_EQ(0, cache
.disk_cache()->open_count());
6890 EXPECT_EQ(2, cache
.disk_cache()->create_count());
6893 // Tests that when we are told to stop caching we don't throw away valid data.
6894 TEST(HttpCache
, StopCachingSavesEntry
) {
6895 MockHttpCache cache
;
6896 net::TestCompletionCallback callback
;
6897 MockHttpRequest
request(kSimpleGET_Transaction
);
6900 scoped_ptr
<net::HttpTransaction
> trans
;
6901 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6903 // Force a response that can be resumed.
6904 MockTransaction
mock_transaction(kSimpleGET_Transaction
);
6905 AddMockTransaction(&mock_transaction
);
6906 mock_transaction
.response_headers
= "Cache-Control: max-age=10000\n"
6907 "Content-Length: 42\n"
6910 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6911 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6913 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6914 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6915 EXPECT_EQ(callback
.GetResult(rv
), 10);
6917 trans
->StopCaching();
6919 // We should be able to keep reading.
6920 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6921 EXPECT_GT(callback
.GetResult(rv
), 0);
6922 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6923 EXPECT_EQ(callback
.GetResult(rv
), 0);
6925 RemoveMockTransaction(&mock_transaction
);
6928 // Verify that the entry is marked as incomplete.
6929 disk_cache::Entry
* entry
;
6930 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
6931 net::HttpResponseInfo response
;
6932 bool truncated
= false;
6933 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6934 EXPECT_TRUE(truncated
);
6938 // Tests that we handle truncated enries when StopCaching is called.
6939 TEST(HttpCache
, StopCachingTruncatedEntry
) {
6940 MockHttpCache cache
;
6941 net::TestCompletionCallback callback
;
6942 MockHttpRequest
request(kRangeGET_TransactionOK
);
6943 request
.extra_headers
.Clear();
6944 request
.extra_headers
.AddHeaderFromString(EXTRA_HEADER_LINE
);
6945 AddMockTransaction(&kRangeGET_TransactionOK
);
6947 std::string
raw_headers("HTTP/1.1 200 OK\n"
6948 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6950 "Accept-Ranges: bytes\n"
6951 "Content-Length: 80\n");
6952 CreateTruncatedEntry(raw_headers
, &cache
);
6955 // Now make a regular request.
6956 scoped_ptr
<net::HttpTransaction
> trans
;
6957 ASSERT_EQ(net::OK
, cache
.CreateTransaction(&trans
));
6959 int rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
6960 EXPECT_EQ(net::OK
, callback
.GetResult(rv
));
6962 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(256));
6963 rv
= trans
->Read(buf
.get(), 10, callback
.callback());
6964 EXPECT_EQ(callback
.GetResult(rv
), 10);
6966 // This is actually going to do nothing.
6967 trans
->StopCaching();
6969 // We should be able to keep reading.
6970 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6971 EXPECT_GT(callback
.GetResult(rv
), 0);
6972 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6973 EXPECT_GT(callback
.GetResult(rv
), 0);
6974 rv
= trans
->Read(buf
.get(), 256, callback
.callback());
6975 EXPECT_EQ(callback
.GetResult(rv
), 0);
6978 // Verify that the disk entry was updated.
6979 disk_cache::Entry
* entry
;
6980 ASSERT_TRUE(cache
.OpenBackendEntry(kRangeGET_TransactionOK
.url
, &entry
));
6981 EXPECT_EQ(80, entry
->GetDataSize(1));
6982 bool truncated
= true;
6983 net::HttpResponseInfo response
;
6984 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
6985 EXPECT_FALSE(truncated
);
6988 RemoveMockTransaction(&kRangeGET_TransactionOK
);
6991 // Tests that we detect truncated resources from the net when there is
6992 // a Content-Length header.
6993 TEST(HttpCache
, TruncatedByContentLength
) {
6994 MockHttpCache cache
;
6995 net::TestCompletionCallback callback
;
6997 MockTransaction
transaction(kSimpleGET_Transaction
);
6998 AddMockTransaction(&transaction
);
6999 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
7000 "Content-Length: 100\n";
7001 RunTransactionTest(cache
.http_cache(), transaction
);
7002 RemoveMockTransaction(&transaction
);
7004 // Read from the cache.
7005 RunTransactionTest(cache
.http_cache(), kSimpleGET_Transaction
);
7007 EXPECT_EQ(2, cache
.network_layer()->transaction_count());
7008 EXPECT_EQ(0, cache
.disk_cache()->open_count());
7009 EXPECT_EQ(2, cache
.disk_cache()->create_count());
7012 // Tests that we actually flag entries as truncated when we detect an error
7014 TEST(HttpCache
, TruncatedByContentLength2
) {
7015 MockHttpCache cache
;
7016 net::TestCompletionCallback callback
;
7018 MockTransaction
transaction(kSimpleGET_Transaction
);
7019 AddMockTransaction(&transaction
);
7020 transaction
.response_headers
= "Cache-Control: max-age=10000\n"
7021 "Content-Length: 100\n"
7023 RunTransactionTest(cache
.http_cache(), transaction
);
7024 RemoveMockTransaction(&transaction
);
7026 // Verify that the entry is marked as incomplete.
7027 disk_cache::Entry
* entry
;
7028 ASSERT_TRUE(cache
.OpenBackendEntry(kSimpleGET_Transaction
.url
, &entry
));
7029 net::HttpResponseInfo response
;
7030 bool truncated
= false;
7031 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry
, &response
, &truncated
));
7032 EXPECT_TRUE(truncated
);
7036 // Make sure that calling SetPriority on a cache transaction passes on
7037 // its priority updates to its underlying network transaction.
7038 TEST(HttpCache
, SetPriority
) {
7039 MockHttpCache cache
;
7041 scoped_ptr
<net::HttpTransaction
> trans
;
7042 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
7044 // Shouldn't crash, but doesn't do anything either.
7045 trans
->SetPriority(net::LOW
);
7047 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7048 EXPECT_EQ(net::DEFAULT_PRIORITY
,
7049 cache
.network_layer()->last_create_transaction_priority());
7051 net::HttpRequestInfo info
;
7052 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7053 net::TestCompletionCallback callback
;
7054 EXPECT_EQ(net::ERR_IO_PENDING
,
7055 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
7057 EXPECT_TRUE(cache
.network_layer()->last_transaction());
7058 if (cache
.network_layer()->last_transaction()) {
7060 cache
.network_layer()->last_create_transaction_priority());
7062 cache
.network_layer()->last_transaction()->priority());
7065 trans
->SetPriority(net::HIGHEST
);
7067 if (cache
.network_layer()->last_transaction()) {
7069 cache
.network_layer()->last_create_transaction_priority());
7070 EXPECT_EQ(net::HIGHEST
,
7071 cache
.network_layer()->last_transaction()->priority());
7074 EXPECT_EQ(net::OK
, callback
.WaitForResult());
7077 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7078 // transaction passes on its argument to the underlying network transaction.
7079 TEST(HttpCache
, SetWebSocketHandshakeStreamCreateHelper
) {
7080 MockHttpCache cache
;
7082 FakeWebSocketHandshakeStreamCreateHelper create_helper
;
7083 scoped_ptr
<net::HttpTransaction
> trans
;
7084 ASSERT_EQ(net::OK
, cache
.http_cache()->CreateTransaction(net::IDLE
, &trans
));
7086 EXPECT_FALSE(cache
.network_layer()->last_transaction());
7088 net::HttpRequestInfo info
;
7089 info
.url
= GURL(kSimpleGET_Transaction
.url
);
7090 net::TestCompletionCallback callback
;
7091 EXPECT_EQ(net::ERR_IO_PENDING
,
7092 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
7094 ASSERT_TRUE(cache
.network_layer()->last_transaction());
7095 EXPECT_FALSE(cache
.network_layer()->last_transaction()->
7096 websocket_handshake_stream_create_helper());
7097 trans
->SetWebSocketHandshakeStreamCreateHelper(&create_helper
);
7098 EXPECT_EQ(&create_helper
,
7099 cache
.network_layer()->last_transaction()->
7100 websocket_handshake_stream_create_helper());
7101 EXPECT_EQ(net::OK
, callback
.WaitForResult());
7104 // Make sure that a cache transaction passes on its priority to
7105 // newly-created network transactions.
7106 TEST(HttpCache
, SetPriorityNewTransaction
) {
7107 MockHttpCache cache
;
7108 AddMockTransaction(&kRangeGET_TransactionOK
);
7110 std::string
raw_headers("HTTP/1.1 200 OK\n"
7111 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7113 "Accept-Ranges: bytes\n"
7114 "Content-Length: 80\n");
7115 CreateTruncatedEntry(raw_headers
, &cache
);
7117 // Now make a regular request.
7118 std::string headers
;
7119 MockTransaction
transaction(kRangeGET_TransactionOK
);
7120 transaction
.request_headers
= EXTRA_HEADER
;
7121 transaction
.data
= kFullRangeData
;
7123 scoped_ptr
<net::HttpTransaction
> trans
;
7125 cache
.http_cache()->CreateTransaction(net::MEDIUM
, &trans
));
7126 EXPECT_EQ(net::DEFAULT_PRIORITY
,
7127 cache
.network_layer()->last_create_transaction_priority());
7129 MockHttpRequest
info(transaction
);
7130 net::TestCompletionCallback callback
;
7131 EXPECT_EQ(net::ERR_IO_PENDING
,
7132 trans
->Start(&info
, callback
.callback(), net::BoundNetLog()));
7133 EXPECT_EQ(net::OK
, callback
.WaitForResult());
7135 EXPECT_EQ(net::MEDIUM
,
7136 cache
.network_layer()->last_create_transaction_priority());
7138 trans
->SetPriority(net::HIGHEST
);
7139 // Should trigger a new network transaction and pick up the new
7141 ReadAndVerifyTransaction(trans
.get(), transaction
);
7143 EXPECT_EQ(net::HIGHEST
,
7144 cache
.network_layer()->last_create_transaction_priority());
7146 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7149 int64
RunTransactionAndGetReceivedBytes(
7150 MockHttpCache
& cache
,
7151 const MockTransaction
& trans_info
) {
7152 int64 received_bytes
= -1;
7153 RunTransactionTestBase(cache
.http_cache(), trans_info
,
7154 MockHttpRequest(trans_info
), NULL
, net::BoundNetLog(),
7155 NULL
, &received_bytes
);
7156 return received_bytes
;
7159 int64
TransactionSize(const MockTransaction
& transaction
) {
7160 return strlen(transaction
.status
) + strlen(transaction
.response_headers
) +
7161 strlen(transaction
.data
);
7164 TEST(HttpCache
, ReceivedBytesCacheMissAndThenHit
) {
7165 MockHttpCache cache
;
7167 MockTransaction
transaction(kSimpleGET_Transaction
);
7168 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7169 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7171 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7172 EXPECT_EQ(0, received_bytes
);
7175 TEST(HttpCache
, ReceivedBytesConditionalRequest304
) {
7176 MockHttpCache cache
;
7178 ScopedMockTransaction
transaction(kETagGET_Transaction
);
7179 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7180 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7182 transaction
.load_flags
= net::LOAD_VALIDATE_CACHE
;
7183 transaction
.handler
= ETagGet_ConditionalRequest_Handler
;
7184 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7185 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7188 TEST(HttpCache
, ReceivedBytesConditionalRequest200
) {
7189 MockHttpCache cache
;
7191 MockTransaction
transaction(kTypicalGET_Transaction
);
7192 transaction
.request_headers
= "Foo: bar\r\n";
7193 transaction
.response_headers
=
7194 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7195 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7197 "Cache-Control: max-age=0\n"
7199 AddMockTransaction(&transaction
);
7200 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7201 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7203 RevalidationServer server
;
7204 transaction
.handler
= server
.Handler
;
7205 transaction
.request_headers
= "Foo: none\r\n";
7206 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7207 EXPECT_EQ(TransactionSize(transaction
), received_bytes
);
7209 RemoveMockTransaction(&transaction
);
7212 TEST(HttpCache
, ReceivedBytesRange
) {
7213 MockHttpCache cache
;
7214 AddMockTransaction(&kRangeGET_TransactionOK
);
7215 MockTransaction
transaction(kRangeGET_TransactionOK
);
7217 // Read bytes 40-49 from the network.
7218 int64 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7219 int64 range_response_size
= TransactionSize(transaction
);
7220 EXPECT_EQ(range_response_size
, received_bytes
);
7222 // Read bytes 40-49 from the cache.
7223 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7224 EXPECT_EQ(0, received_bytes
);
7225 base::MessageLoop::current()->RunUntilIdle();
7227 // Read bytes 30-39 from the network.
7228 transaction
.request_headers
= "Range: bytes = 30-39\r\n" EXTRA_HEADER
;
7229 transaction
.data
= "rg: 30-39 ";
7230 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7231 EXPECT_EQ(range_response_size
, received_bytes
);
7232 base::MessageLoop::current()->RunUntilIdle();
7234 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7235 transaction
.request_headers
= "Range: bytes = 20-59\r\n" EXTRA_HEADER
;
7236 transaction
.data
= "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7237 received_bytes
= RunTransactionAndGetReceivedBytes(cache
, transaction
);
7238 EXPECT_EQ(range_response_size
* 2, received_bytes
);
7240 RemoveMockTransaction(&kRangeGET_TransactionOK
);
7243 class HttpCachePrefetchValidationTest
: public ::testing::Test
{
7245 static const int kMaxAgeSecs
= 100;
7246 static const int kRequireValidationSecs
= kMaxAgeSecs
+ 1;
7248 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction
) {
7249 DCHECK_LT(kMaxAgeSecs
, prefetch_reuse_mins() * net::kNumSecondsPerMinute
);
7251 clock_
= new base::SimpleTestClock();
7252 cache_
.http_cache()->SetClockForTesting(make_scoped_ptr(clock_
));
7253 cache_
.network_layer()->SetClock(clock_
);
7255 transaction_
.response_headers
= "Cache-Control: max-age=100\n";
7258 bool TransactionRequiredNetwork(int load_flags
) {
7259 int pre_transaction_count
= transaction_count();
7260 transaction_
.load_flags
= load_flags
;
7261 RunTransactionTest(cache_
.http_cache(), transaction_
);
7262 return pre_transaction_count
!= transaction_count();
7265 void AdvanceTime(int seconds
) {
7266 clock_
->Advance(base::TimeDelta::FromSeconds(seconds
));
7269 int prefetch_reuse_mins() { return net::HttpCache::kPrefetchReuseMins
; }
7271 // How many times this test has sent requests to the (fake) origin
7272 // server. Every test case needs to make at least one request to initialise
7274 int transaction_count() {
7275 return cache_
.network_layer()->transaction_count();
7278 MockHttpCache cache_
;
7279 ScopedMockTransaction transaction_
;
7280 std::string response_headers_
;
7281 base::SimpleTestClock
* clock_
;
7284 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationShortlyAfterPrefetch
) {
7285 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7286 AdvanceTime(kRequireValidationSecs
);
7287 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7290 TEST_F(HttpCachePrefetchValidationTest
, ValidateLongAfterPrefetch
) {
7291 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7292 AdvanceTime(prefetch_reuse_mins() * net::kNumSecondsPerMinute
);
7293 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7296 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceOnly
) {
7297 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7298 AdvanceTime(kRequireValidationSecs
);
7299 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7300 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7303 TEST_F(HttpCachePrefetchValidationTest
, SkipValidationOnceReadOnly
) {
7304 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7305 AdvanceTime(kRequireValidationSecs
);
7306 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_ONLY_FROM_CACHE
));
7307 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7310 TEST_F(HttpCachePrefetchValidationTest
, BypassCacheOverwritesPrefetch
) {
7311 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7312 AdvanceTime(kRequireValidationSecs
);
7313 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_BYPASS_CACHE
));
7314 AdvanceTime(kRequireValidationSecs
);
7315 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7318 TEST_F(HttpCachePrefetchValidationTest
,
7319 SkipValidationOnExistingEntryThatNeedsValidation
) {
7320 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7321 AdvanceTime(kRequireValidationSecs
);
7322 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7323 AdvanceTime(kRequireValidationSecs
);
7324 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7325 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7328 TEST_F(HttpCachePrefetchValidationTest
,
7329 SkipValidationOnExistingEntryThatDoesNotNeedValidation
) {
7330 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7331 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7332 AdvanceTime(kRequireValidationSecs
);
7333 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7334 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7337 TEST_F(HttpCachePrefetchValidationTest
, PrefetchMultipleTimes
) {
7338 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7339 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7340 AdvanceTime(kRequireValidationSecs
);
7341 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7344 TEST_F(HttpCachePrefetchValidationTest
, ValidateOnDelayedSecondPrefetch
) {
7345 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7346 AdvanceTime(kRequireValidationSecs
);
7347 EXPECT_TRUE(TransactionRequiredNetwork(net::LOAD_PREFETCH
));
7348 AdvanceTime(kRequireValidationSecs
);
7349 EXPECT_FALSE(TransactionRequiredNetwork(net::LOAD_NORMAL
));
7352 // Framework for tests of stale-while-revalidate related functionality. With
7353 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
7354 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
7355 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
7356 // synchronous revalidation.
7357 class HttpCacheStaleWhileRevalidateTest
: public ::testing::Test
{
7359 HttpCacheStaleWhileRevalidateTest()
7360 : transaction_(kSimpleGET_Transaction
),
7362 stale_while_revalidate_(7200),
7363 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
7364 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(true);
7367 // RunTransactionTest() with the arguments from this fixture.
7368 void RunFixtureTransactionTest() {
7369 std::string response_headers
= base::StringPrintf(
7372 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
7375 stale_while_revalidate_
);
7376 transaction_
.response_headers
= response_headers
.c_str();
7377 RunTransactionTest(cache_
.http_cache(), transaction_
);
7378 transaction_
.response_headers
= "";
7381 // How many times this test has sent requests to the (fake) origin
7382 // server. Every test case needs to make at least one request to initialise
7384 int transaction_count() {
7385 return cache_
.network_layer()->transaction_count();
7388 // How many times an existing cache entry was opened during the test case.
7389 int open_count() { return cache_
.disk_cache()->open_count(); }
7391 MockHttpCache cache_
;
7392 ScopedMockTransaction transaction_
;
7394 int stale_while_revalidate_
;
7395 std::string validator_
;
7398 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo
* request
,
7399 std::string
* response_status
,
7400 std::string
* response_headers
,
7401 std::string
* response_data
) {
7403 EXPECT_TRUE(request
->extra_headers
.GetHeader("Resource-Freshness", &value
));
7404 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value
);
7407 // Verify that the Resource-Freshness header is sent on a revalidation if the
7408 // stale-while-revalidate directive was on the response.
7409 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderSent
) {
7410 age_
= 10801; // Outside the stale-while-revalidate window.
7412 // Write to the cache.
7413 RunFixtureTransactionTest();
7415 EXPECT_EQ(1, transaction_count());
7417 // Send the request again and check that Resource-Freshness header is added.
7418 transaction_
.handler
= CheckResourceFreshnessHeader
;
7420 RunFixtureTransactionTest();
7422 EXPECT_EQ(2, transaction_count());
7425 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo
* request
,
7426 std::string
* response_status
,
7427 std::string
* response_headers
,
7428 std::string
* response_data
) {
7429 EXPECT_FALSE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7432 // Verify that the Resource-Freshness header is not sent when
7433 // stale-while-revalidate is 0.
7434 TEST_F(HttpCacheStaleWhileRevalidateTest
, ResourceFreshnessHeaderNotSent
) {
7436 stale_while_revalidate_
= 0;
7438 // Write to the cache.
7439 RunFixtureTransactionTest();
7441 EXPECT_EQ(1, transaction_count());
7443 // Send the request again and check that Resource-Freshness header is absent.
7444 transaction_
.handler
= CheckResourceFreshnessAbsent
;
7446 RunFixtureTransactionTest();
7448 EXPECT_EQ(2, transaction_count());
7451 // Verify that when stale-while-revalidate applies the response is read from
7453 TEST_F(HttpCacheStaleWhileRevalidateTest
, ReadFromCache
) {
7454 // Write to the cache.
7455 RunFixtureTransactionTest();
7457 EXPECT_EQ(0, open_count());
7458 EXPECT_EQ(1, transaction_count());
7460 // Read back from the cache.
7461 RunFixtureTransactionTest();
7463 EXPECT_EQ(1, open_count());
7464 EXPECT_EQ(1, transaction_count());
7467 // Verify that when stale-while-revalidate applies an asynchronous request is
7469 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestSent
) {
7470 // Write to the cache.
7471 RunFixtureTransactionTest();
7473 EXPECT_EQ(1, transaction_count());
7475 // Read back from the cache.
7476 RunFixtureTransactionTest();
7478 EXPECT_EQ(1, transaction_count());
7480 // Let the async request execute.
7481 base::RunLoop().RunUntilIdle();
7482 EXPECT_EQ(2, transaction_count());
7485 // Verify that tearing down the HttpCache with an async revalidation in progress
7486 // does not break anything (this test is most likely to find problems when run
7487 // with a memory checker such as AddressSanitizer).
7488 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncTearDown
) {
7489 // Write to the cache.
7490 RunFixtureTransactionTest();
7492 // Read back from the cache.
7493 RunFixtureTransactionTest();
7496 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo
* request
,
7497 std::string
* response_status
,
7498 std::string
* response_headers
,
7499 std::string
* response_data
) {
7501 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-Modified-Since", &value
));
7502 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value
);
7505 // Verify that the async revalidation contains an If-Modified-Since header.
7506 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfModifiedSince
) {
7507 // Write to the cache.
7508 RunFixtureTransactionTest();
7510 transaction_
.handler
= CheckIfModifiedSinceHeader
;
7512 // Read back from the cache.
7513 RunFixtureTransactionTest();
7516 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo
* request
,
7517 std::string
* response_status
,
7518 std::string
* response_headers
,
7519 std::string
* response_data
) {
7521 EXPECT_TRUE(request
->extra_headers
.GetHeader("If-None-Match", &value
));
7522 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value
);
7525 // If the response had ETag rather than Last-Modified, then that is used to
7526 // conditionalise the response.
7527 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestIfNoneMatch
) {
7528 validator_
= "Etag: \"40a1-1320-4f6adefa22a40\"";
7530 // Write to the cache.
7531 RunFixtureTransactionTest();
7533 transaction_
.handler
= CheckIfNoneMatchHeader
;
7535 // Read back from the cache.
7536 RunFixtureTransactionTest();
7539 static void CheckResourceFreshnessHeaderPresent(
7540 const net::HttpRequestInfo
* request
,
7541 std::string
* response_status
,
7542 std::string
* response_headers
,
7543 std::string
* response_data
) {
7544 EXPECT_TRUE(request
->extra_headers
.HasHeader("Resource-Freshness"));
7547 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestHasResourceFreshness
) {
7548 // Write to the cache.
7549 RunFixtureTransactionTest();
7551 transaction_
.handler
= CheckResourceFreshnessHeaderPresent
;
7553 // Read back from the cache.
7554 RunFixtureTransactionTest();
7557 // Verify that when age > max-age + stale-while-revalidate stale results are
7559 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedIfTooStale
) {
7562 // Write to the cache.
7563 RunFixtureTransactionTest();
7565 EXPECT_EQ(0, open_count());
7566 EXPECT_EQ(1, transaction_count());
7568 // Reading back reads from the network.
7569 RunFixtureTransactionTest();
7571 EXPECT_EQ(1, open_count());
7572 EXPECT_EQ(2, transaction_count());
7575 // HEAD requests should be able to take advantage of stale-while-revalidate.
7576 TEST_F(HttpCacheStaleWhileRevalidateTest
, WorksForHeadMethod
) {
7577 // Write to the cache. This has to be a GET request; HEAD requests don't
7578 // create new cache entries.
7579 RunFixtureTransactionTest();
7581 EXPECT_EQ(0, open_count());
7582 EXPECT_EQ(1, transaction_count());
7584 // Read back from the cache, and trigger an asynchronous HEAD request.
7585 transaction_
.method
= "HEAD";
7586 transaction_
.data
= "";
7588 RunFixtureTransactionTest();
7590 EXPECT_EQ(1, open_count());
7591 EXPECT_EQ(1, transaction_count());
7593 // Let the network request proceed.
7594 base::RunLoop().RunUntilIdle();
7596 EXPECT_EQ(2, transaction_count());
7599 // POST requests should not use stale-while-revalidate.
7600 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotAppliedToPost
) {
7601 transaction_
= ScopedMockTransaction(kSimplePOST_Transaction
);
7603 // Write to the cache.
7604 RunFixtureTransactionTest();
7606 EXPECT_EQ(0, open_count());
7607 EXPECT_EQ(1, transaction_count());
7609 // Reading back reads from the network.
7610 RunFixtureTransactionTest();
7612 EXPECT_EQ(0, open_count());
7613 EXPECT_EQ(2, transaction_count());
7616 static void CheckUrlMatches(const net::HttpRequestInfo
* request
,
7617 std::string
* response_status
,
7618 std::string
* response_headers
,
7619 std::string
* response_data
) {
7620 EXPECT_EQ("http://www.google.com/", request
->url
.spec());
7623 // Async revalidation is issued to the original URL.
7624 TEST_F(HttpCacheStaleWhileRevalidateTest
, AsyncRequestUrlMatches
) {
7625 transaction_
.url
= "http://www.google.com/";
7626 // Write to the cache.
7627 RunFixtureTransactionTest();
7629 // Read back from the cache.
7630 RunFixtureTransactionTest();
7632 EXPECT_EQ(1, transaction_count());
7634 transaction_
.handler
= CheckUrlMatches
;
7636 // Let the async request execute and perform the check.
7637 base::RunLoop().RunUntilIdle();
7638 EXPECT_EQ(2, transaction_count());
7641 class SyncLoadFlagTest
: public HttpCacheStaleWhileRevalidateTest
,
7642 public ::testing::WithParamInterface
<int> {};
7644 // Flags which should always cause the request to be synchronous.
7645 TEST_P(SyncLoadFlagTest
, MustBeSynchronous
) {
7646 transaction_
.load_flags
|= GetParam();
7647 // Write to the cache.
7648 RunFixtureTransactionTest();
7650 EXPECT_EQ(1, transaction_count());
7652 // Reading back reads from the network.
7653 RunFixtureTransactionTest();
7655 EXPECT_EQ(2, transaction_count());
7658 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate
,
7660 ::testing::Values(net::LOAD_VALIDATE_CACHE
,
7661 net::LOAD_BYPASS_CACHE
,
7662 net::LOAD_DISABLE_CACHE
));
7664 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7665 PreferringCacheDoesNotTriggerAsyncRequest
) {
7666 transaction_
.load_flags
|= net::LOAD_PREFERRING_CACHE
;
7667 // Write to the cache.
7668 RunFixtureTransactionTest();
7670 EXPECT_EQ(1, transaction_count());
7672 // Reading back reads from the cache.
7673 RunFixtureTransactionTest();
7675 EXPECT_EQ(1, transaction_count());
7677 // If there was an async transaction created, it would run now.
7678 base::RunLoop().RunUntilIdle();
7680 // There was no async transaction.
7681 EXPECT_EQ(1, transaction_count());
7684 TEST_F(HttpCacheStaleWhileRevalidateTest
, NotUsedWhenDisabled
) {
7685 cache_
.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7686 // Write to the cache.
7687 RunFixtureTransactionTest();
7689 EXPECT_EQ(1, transaction_count());
7691 // A synchronous revalidation is performed.
7692 RunFixtureTransactionTest();
7694 EXPECT_EQ(2, transaction_count());
7697 TEST_F(HttpCacheStaleWhileRevalidateTest
,
7698 OnlyFromCacheDoesNotTriggerAsyncRequest
) {
7699 transaction_
.load_flags
|= net::LOAD_ONLY_FROM_CACHE
;
7700 transaction_
.return_code
= net::ERR_CACHE_MISS
;
7702 // Writing to the cache should fail, because we are avoiding the network.
7703 RunFixtureTransactionTest();
7705 EXPECT_EQ(0, transaction_count());
7707 base::RunLoop().RunUntilIdle();
7710 EXPECT_EQ(0, transaction_count());
7713 // A certificate error during an asynchronous fetch should cause the next fetch
7714 // to proceed synchronously.
7715 // TODO(ricea): In future, only certificate errors which require user
7716 // interaction should fail the asynchronous revalidation, and they should cause
7717 // the next revalidation to be synchronous rather than requiring a total
7718 // refetch. This test will need to be updated appropriately.
7719 TEST_F(HttpCacheStaleWhileRevalidateTest
, CertificateErrorCausesRefetch
) {
7720 // Write to the cache.
7721 RunFixtureTransactionTest();
7723 EXPECT_EQ(1, transaction_count());
7725 // Now read back. RunTransactionTestBase() expects to receive the network
7726 // error back from the HttpCache::Transaction, but since the cache request
7727 // will return OK we need to duplicate some of its implementation here.
7728 transaction_
.return_code
= net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
7729 net::TestCompletionCallback callback
;
7730 scoped_ptr
<net::HttpTransaction
> trans
;
7732 cache_
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7733 EXPECT_EQ(net::OK
, rv
);
7734 ASSERT_TRUE(trans
.get());
7736 MockHttpRequest
request(transaction_
);
7737 rv
= trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7738 ASSERT_EQ(net::ERR_IO_PENDING
, rv
);
7739 ASSERT_EQ(net::OK
, callback
.WaitForResult());
7740 ReadAndVerifyTransaction(trans
.get(), transaction_
);
7742 EXPECT_EQ(1, transaction_count());
7744 // Allow the asynchronous fetch to run.
7745 base::RunLoop().RunUntilIdle();
7747 EXPECT_EQ(2, transaction_count());
7749 // Now run the transaction again. It should run synchronously.
7750 transaction_
.return_code
= net::OK
;
7751 RunFixtureTransactionTest();
7753 EXPECT_EQ(3, transaction_count());
7756 // Ensure that the response cached by the asynchronous request is not truncated,
7757 // even if the server is slow.
7758 TEST_F(HttpCacheStaleWhileRevalidateTest
, EntireResponseCached
) {
7759 transaction_
.test_mode
= TEST_MODE_SLOW_READ
;
7760 // Write to the cache.
7761 RunFixtureTransactionTest();
7763 // Read back from the cache.
7764 RunFixtureTransactionTest();
7766 // Let the async request execute.
7767 base::RunLoop().RunUntilIdle();
7769 // The cache entry should still be complete.
7770 transaction_
.load_flags
= net::LOAD_ONLY_FROM_CACHE
;
7771 RunFixtureTransactionTest();
7774 // Verify that there are no race conditions in the completely synchronous case.
7775 TEST_F(HttpCacheStaleWhileRevalidateTest
, SynchronousCaseWorks
) {
7776 transaction_
.test_mode
= TEST_MODE_SYNC_ALL
;
7777 // Write to the cache.
7778 RunFixtureTransactionTest();
7780 EXPECT_EQ(1, transaction_count());
7782 // Read back from the cache.
7783 RunFixtureTransactionTest();
7785 EXPECT_EQ(1, transaction_count());
7787 // Let the async request execute.
7788 base::RunLoop().RunUntilIdle();
7789 EXPECT_EQ(2, transaction_count());
7792 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo
* request
,
7793 std::string
* response_status
,
7794 std::string
* response_headers
,
7795 std::string
* response_data
) {
7796 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION
, request
->load_flags
);
7799 // Check that the load flags on the async request are the same as the load flags
7800 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7801 TEST_F(HttpCacheStaleWhileRevalidateTest
, LoadFlagsAsyncRevalidation
) {
7802 transaction_
.load_flags
= net::LOAD_NORMAL
;
7803 // Write to the cache.
7804 RunFixtureTransactionTest();
7806 EXPECT_EQ(1, transaction_count());
7808 // Read back from the cache.
7809 RunFixtureTransactionTest();
7811 EXPECT_EQ(1, transaction_count());
7813 transaction_
.handler
= CheckLoadFlagsAsyncRevalidation
;
7814 // Let the async request execute.
7815 base::RunLoop().RunUntilIdle();
7816 EXPECT_EQ(2, transaction_count());
7819 static void SimpleMockAuthHandler(const net::HttpRequestInfo
* request
,
7820 std::string
* response_status
,
7821 std::string
* response_headers
,
7822 std::string
* response_data
) {
7823 if (request
->extra_headers
.HasHeader("X-Require-Mock-Auth") &&
7824 !request
->extra_headers
.HasHeader("Authorization")) {
7825 response_status
->assign("HTTP/1.1 401 Unauthorized");
7826 response_headers
->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7829 response_status
->assign("HTTP/1.1 200 OK");
7832 TEST_F(HttpCacheStaleWhileRevalidateTest
, RestartForAuth
) {
7833 // Write to the cache.
7834 RunFixtureTransactionTest();
7836 EXPECT_EQ(1, transaction_count());
7838 // Now make the transaction require auth.
7839 transaction_
.request_headers
= "X-Require-Mock-Auth: dummy\r\n\r\n";
7840 transaction_
.handler
= SimpleMockAuthHandler
;
7842 // Read back from the cache.
7843 RunFixtureTransactionTest();
7845 EXPECT_EQ(1, transaction_count());
7847 // Let the async request execute.
7848 base::RunLoop().RunUntilIdle();
7850 EXPECT_EQ(2, transaction_count());
7853 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7854 // take place on a sparse entry.
7855 TEST(HttpCache
, RangeGET_MultipleRequests
) {
7856 MockHttpCache cache
;
7858 // Create a transaction for bytes 0-9.
7859 MockHttpRequest
request(kRangeGET_TransactionOK
);
7860 MockTransaction
transaction(kRangeGET_TransactionOK
);
7861 transaction
.request_headers
= "Range: bytes = 0-9\r\n" EXTRA_HEADER
;
7862 transaction
.data
= "rg: 00-09 ";
7863 AddMockTransaction(&transaction
);
7865 net::TestCompletionCallback callback
;
7866 scoped_ptr
<net::HttpTransaction
> trans
;
7867 int rv
= cache
.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY
, &trans
);
7868 EXPECT_EQ(net::OK
, rv
);
7869 ASSERT_TRUE(trans
.get());
7871 // Start our transaction.
7872 trans
->Start(&request
, callback
.callback(), net::BoundNetLog());
7874 // A second transaction on a different part of the file (the default
7875 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7876 // the already pending transaction.
7877 RunTransactionTest(cache
.http_cache(), kRangeGET_TransactionOK
);
7879 // Let the first transaction complete.
7880 callback
.WaitForResult();
7882 RemoveMockTransaction(&transaction
);
7885 // Makes sure that a request stops using the cache when the response headers
7886 // with "Cache-Control: no-store" arrives. That means that another request for
7887 // the same URL can be processed before the response body of the original
7889 TEST(HttpCache
, NoStoreResponseShouldNotBlockFollowingRequests
) {
7890 MockHttpCache cache
;
7891 ScopedMockTransaction
mock_transaction(kSimpleGET_Transaction
);
7892 mock_transaction
.response_headers
= "Cache-Control: no-store\n";
7893 MockHttpRequest
request(mock_transaction
);
7895 scoped_ptr
<Context
> first(new Context
);
7896 first
->result
= cache
.CreateTransaction(&first
->trans
);
7897 ASSERT_EQ(net::OK
, first
->result
);
7898 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7899 first
->result
= first
->trans
->Start(
7900 &request
, first
->callback
.callback(), net::BoundNetLog());
7901 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, first
->trans
->GetLoadState());
7903 base::MessageLoop::current()->RunUntilIdle();
7904 EXPECT_EQ(net::LOAD_STATE_IDLE
, first
->trans
->GetLoadState());
7905 ASSERT_TRUE(first
->trans
->GetResponseInfo());
7906 EXPECT_TRUE(first
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7907 "Cache-Control", "no-store"));
7908 // Here we have read the response header but not read the response body yet.
7910 // Let us create the second (read) transaction.
7911 scoped_ptr
<Context
> second(new Context
);
7912 second
->result
= cache
.CreateTransaction(&second
->trans
);
7913 ASSERT_EQ(net::OK
, second
->result
);
7914 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7915 second
->result
= second
->trans
->Start(
7916 &request
, second
->callback
.callback(), net::BoundNetLog());
7918 // Here the second transaction proceeds without reading the first body.
7919 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE
, second
->trans
->GetLoadState());
7920 base::MessageLoop::current()->RunUntilIdle();
7921 EXPECT_EQ(net::LOAD_STATE_IDLE
, second
->trans
->GetLoadState());
7922 ASSERT_TRUE(second
->trans
->GetResponseInfo());
7923 EXPECT_TRUE(second
->trans
->GetResponseInfo()->headers
->HasHeaderValue(
7924 "Cache-Control", "no-store"));
7925 ReadAndVerifyTransaction(second
->trans
.get(), kSimpleGET_Transaction
);