Pass CreateDirectory errors up to IndexedDB.
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blob14099c7bd684e61e34939fb62804de3aaf73c0ed
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"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/message_loop.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "net/base/cache_type.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/load_flags.h"
16 #include "net/base/load_timing_info.h"
17 #include "net/base/load_timing_info_test_util.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/net_log_unittest.h"
20 #include "net/base/upload_bytes_element_reader.h"
21 #include "net/base/upload_data_stream.h"
22 #include "net/cert/cert_status_flags.h"
23 #include "net/disk_cache/disk_cache.h"
24 #include "net/http/http_byte_range.h"
25 #include "net/http/http_request_headers.h"
26 #include "net/http/http_request_info.h"
27 #include "net/http/http_response_headers.h"
28 #include "net/http/http_response_info.h"
29 #include "net/http/http_transaction.h"
30 #include "net/http/http_transaction_delegate.h"
31 #include "net/http/http_transaction_unittest.h"
32 #include "net/http/http_util.h"
33 #include "net/http/mock_http_cache.h"
34 #include "net/ssl/ssl_cert_request_info.h"
35 #include "testing/gtest/include/gtest/gtest.h"
37 using base::Time;
39 namespace {
41 // Tests the load timing values of a request that goes through a
42 // MockNetworkTransaction.
43 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) {
44 EXPECT_FALSE(load_timing_info.socket_reused);
45 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
47 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
48 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
50 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
51 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
52 EXPECT_LE(load_timing_info.connect_timing.connect_end,
53 load_timing_info.send_start);
55 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
57 // Set by URLRequest / URLRequestHttpJob, at a higher level.
58 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
59 EXPECT_TRUE(load_timing_info.request_start.is_null());
60 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
63 // Tests the load timing values of a request that receives a cached response.
64 void TestLoadTimingCachedResponse(const net::LoadTimingInfo& load_timing_info) {
65 EXPECT_FALSE(load_timing_info.socket_reused);
66 EXPECT_EQ(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
68 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
69 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
71 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
73 // Only the send start / end times should be sent, and they should have the
74 // same value.
75 EXPECT_FALSE(load_timing_info.send_start.is_null());
76 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
78 // Set by URLRequest / URLRequestHttpJob, at a higher level.
79 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
80 EXPECT_TRUE(load_timing_info.request_start.is_null());
81 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
84 class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
85 public:
86 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
87 : cache_(cache),
88 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
89 base::Unretained(this))) {
92 const net::CompletionCallback& callback() const { return callback_; }
94 private:
95 void OnComplete(int result) {
96 delete cache_;
97 SetResult(result);
100 MockHttpCache* cache_;
101 net::CompletionCallback callback_;
103 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
106 //-----------------------------------------------------------------------------
107 // helpers
109 class TestHttpTransactionDelegate : public net::HttpTransactionDelegate {
110 public:
111 TestHttpTransactionDelegate(int num_cache_actions_to_observe,
112 int num_network_actions_to_observe)
113 : num_callbacks_observed_(0),
114 num_remaining_cache_actions_to_observe_(num_cache_actions_to_observe),
115 num_remaining_network_actions_to_observe_(
116 num_network_actions_to_observe),
117 cache_action_in_progress_(false),
118 network_action_in_progress_(false) {
120 virtual ~TestHttpTransactionDelegate() {
121 EXPECT_EQ(0, num_remaining_cache_actions_to_observe_);
122 EXPECT_EQ(0, num_remaining_network_actions_to_observe_);
123 EXPECT_FALSE(cache_action_in_progress_);
124 EXPECT_FALSE(network_action_in_progress_);
126 virtual void OnCacheActionStart() OVERRIDE {
127 num_callbacks_observed_++;
128 EXPECT_FALSE(cache_action_in_progress_);
129 EXPECT_FALSE(network_action_in_progress_);
130 EXPECT_GT(num_remaining_cache_actions_to_observe_, 0);
131 num_remaining_cache_actions_to_observe_--;
132 cache_action_in_progress_ = true;
134 virtual void OnCacheActionFinish() OVERRIDE {
135 num_callbacks_observed_++;
136 EXPECT_TRUE(cache_action_in_progress_);
137 cache_action_in_progress_ = false;
139 virtual void OnNetworkActionStart() OVERRIDE {
140 num_callbacks_observed_++;
141 EXPECT_FALSE(cache_action_in_progress_);
142 EXPECT_FALSE(network_action_in_progress_);
143 EXPECT_GT(num_remaining_network_actions_to_observe_, 0);
144 num_remaining_network_actions_to_observe_--;
145 network_action_in_progress_ = true;
147 virtual void OnNetworkActionFinish() OVERRIDE {
148 num_callbacks_observed_++;
149 EXPECT_TRUE(network_action_in_progress_);
150 network_action_in_progress_ = false;
153 int num_callbacks_observed() { return num_callbacks_observed_; }
155 private:
156 int num_callbacks_observed_;
157 int num_remaining_cache_actions_to_observe_;
158 int num_remaining_network_actions_to_observe_;
159 bool cache_action_in_progress_;
160 bool network_action_in_progress_;
163 void ReadAndVerifyTransaction(net::HttpTransaction* trans,
164 const MockTransaction& trans_info) {
165 std::string content;
166 int rv = ReadTransaction(trans, &content);
168 EXPECT_EQ(net::OK, rv);
169 std::string expected(trans_info.data);
170 EXPECT_EQ(expected, content);
173 const int kNoDelegateTransactionCheck = -1;
175 void RunTransactionTestWithRequestAndDelegateAndGetTiming(
176 net::HttpCache* cache,
177 const MockTransaction& trans_info,
178 const MockHttpRequest& request,
179 net::HttpResponseInfo* response_info,
180 int num_cache_delegate_actions,
181 int num_network_delegate_actions,
182 const net::BoundNetLog& net_log,
183 net::LoadTimingInfo* load_timing_info) {
184 net::TestCompletionCallback callback;
186 // write to the cache
188 scoped_ptr<TestHttpTransactionDelegate> delegate;
189 if (num_cache_delegate_actions != kNoDelegateTransactionCheck &&
190 num_network_delegate_actions != kNoDelegateTransactionCheck) {
191 delegate.reset(
192 new TestHttpTransactionDelegate(num_cache_delegate_actions,
193 num_network_delegate_actions));
195 scoped_ptr<net::HttpTransaction> trans;
196 int rv = cache->CreateTransaction(
197 net::DEFAULT_PRIORITY, &trans, delegate.get());
198 EXPECT_EQ(net::OK, rv);
199 ASSERT_TRUE(trans.get());
201 rv = trans->Start(&request, callback.callback(), net_log);
202 if (rv == net::ERR_IO_PENDING)
203 rv = callback.WaitForResult();
204 ASSERT_EQ(trans_info.return_code, rv);
206 if (net::OK != rv)
207 return;
209 const net::HttpResponseInfo* response = trans->GetResponseInfo();
210 ASSERT_TRUE(response);
212 if (response_info)
213 *response_info = *response;
215 if (load_timing_info) {
216 // If a fake network connection is used, need a NetLog to get a fake socket
217 // ID.
218 EXPECT_TRUE(net_log.net_log());
219 *load_timing_info = net::LoadTimingInfo();
220 trans->GetLoadTimingInfo(load_timing_info);
223 ReadAndVerifyTransaction(trans.get(), trans_info);
226 void RunTransactionTestWithRequestAndDelegate(
227 net::HttpCache* cache,
228 const MockTransaction& trans_info,
229 const MockHttpRequest& request,
230 net::HttpResponseInfo* response_info,
231 int num_cache_delegate_actions,
232 int num_network_delegate_actions) {
233 RunTransactionTestWithRequestAndDelegateAndGetTiming(
234 cache, trans_info, request, response_info, num_cache_delegate_actions,
235 num_network_delegate_actions, net::BoundNetLog(), NULL);
238 void RunTransactionTestWithRequest(net::HttpCache* cache,
239 const MockTransaction& trans_info,
240 const MockHttpRequest& request,
241 net::HttpResponseInfo* response_info) {
242 RunTransactionTestWithRequestAndDelegate(
243 cache, trans_info, request, response_info, kNoDelegateTransactionCheck,
244 kNoDelegateTransactionCheck);
247 void RunTransactionTestAndGetTiming(
248 net::HttpCache* cache,
249 const MockTransaction& trans_info,
250 const net::BoundNetLog& log,
251 net::LoadTimingInfo* load_timing_info) {
252 RunTransactionTestWithRequestAndDelegateAndGetTiming(
253 cache, trans_info, MockHttpRequest(trans_info), NULL,
254 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log,
255 load_timing_info);
258 void RunTransactionTestWithDelegate(net::HttpCache* cache,
259 const MockTransaction& trans_info,
260 int num_cache_delegate_actions,
261 int num_network_delegate_actions) {
262 RunTransactionTestWithRequestAndDelegate(
263 cache, trans_info, MockHttpRequest(trans_info), NULL,
264 num_cache_delegate_actions, num_network_delegate_actions);
267 void RunTransactionTest(net::HttpCache* cache,
268 const MockTransaction& trans_info) {
269 RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL);
272 void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
273 const MockTransaction& trans_info,
274 net::HttpResponseInfo* response) {
275 RunTransactionTestWithRequest(
276 cache, trans_info, MockHttpRequest(trans_info), response);
279 void RunTransactionTestWithResponseInfoAndGetTiming(
280 net::HttpCache* cache,
281 const MockTransaction& trans_info,
282 net::HttpResponseInfo* response,
283 const net::BoundNetLog& log,
284 net::LoadTimingInfo* load_timing_info) {
285 RunTransactionTestWithRequestAndDelegateAndGetTiming(
286 cache, trans_info, MockHttpRequest(trans_info), response,
287 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log,
288 load_timing_info);
291 void RunTransactionTestWithResponse(net::HttpCache* cache,
292 const MockTransaction& trans_info,
293 std::string* response_headers) {
294 net::HttpResponseInfo response;
295 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
296 response.headers->GetNormalizedHeaders(response_headers);
299 void RunTransactionTestWithResponseAndGetTiming(
300 net::HttpCache* cache,
301 const MockTransaction& trans_info,
302 std::string* response_headers,
303 const net::BoundNetLog& log,
304 net::LoadTimingInfo* load_timing_info) {
305 net::HttpResponseInfo response;
306 RunTransactionTestWithRequestAndDelegateAndGetTiming(
307 cache, trans_info, MockHttpRequest(trans_info), &response,
308 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck,
309 log, load_timing_info);
310 response.headers->GetNormalizedHeaders(response_headers);
313 // This class provides a handler for kFastNoStoreGET_Transaction so that the
314 // no-store header can be included on demand.
315 class FastTransactionServer {
316 public:
317 FastTransactionServer() {
318 no_store = false;
320 ~FastTransactionServer() {}
322 void set_no_store(bool value) { no_store = value; }
324 static void FastNoStoreHandler(const net::HttpRequestInfo* request,
325 std::string* response_status,
326 std::string* response_headers,
327 std::string* response_data) {
328 if (no_store)
329 *response_headers = "Cache-Control: no-store\n";
332 private:
333 static bool no_store;
334 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
336 bool FastTransactionServer::no_store;
338 const MockTransaction kFastNoStoreGET_Transaction = {
339 "http://www.google.com/nostore",
340 "GET",
341 base::Time(),
343 net::LOAD_VALIDATE_CACHE,
344 "HTTP/1.1 200 OK",
345 "Cache-Control: max-age=10000\n",
346 base::Time(),
347 "<html><body>Google Blah Blah</body></html>",
348 TEST_MODE_SYNC_NET_START,
349 &FastTransactionServer::FastNoStoreHandler,
351 net::OK
354 // This class provides a handler for kRangeGET_TransactionOK so that the range
355 // request can be served on demand.
356 class RangeTransactionServer {
357 public:
358 RangeTransactionServer() {
359 not_modified_ = false;
360 modified_ = false;
361 bad_200_ = false;
363 ~RangeTransactionServer() {
364 not_modified_ = false;
365 modified_ = false;
366 bad_200_ = false;
369 // Returns only 416 or 304 when set.
370 void set_not_modified(bool value) { not_modified_ = value; }
372 // Returns 206 when revalidating a range (instead of 304).
373 void set_modified(bool value) { modified_ = value; }
375 // Returns 200 instead of 206 (a malformed response overall).
376 void set_bad_200(bool value) { bad_200_ = value; }
378 static void RangeHandler(const net::HttpRequestInfo* request,
379 std::string* response_status,
380 std::string* response_headers,
381 std::string* response_data);
383 private:
384 static bool not_modified_;
385 static bool modified_;
386 static bool bad_200_;
387 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
389 bool RangeTransactionServer::not_modified_ = false;
390 bool RangeTransactionServer::modified_ = false;
391 bool RangeTransactionServer::bad_200_ = false;
393 // A dummy extra header that must be preserved on a given request.
395 // EXTRA_HEADER_LINE doesn't include a line terminator because it
396 // will be passed to AddHeaderFromString() which doesn't accept them.
397 #define EXTRA_HEADER_LINE "Extra: header"
399 // EXTRA_HEADER contains a line terminator, as expected by
400 // AddHeadersFromString() (_not_ AddHeaderFromString()).
401 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
403 static const char kExtraHeaderKey[] = "Extra";
405 // Static.
406 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
407 std::string* response_status,
408 std::string* response_headers,
409 std::string* response_data) {
410 if (request->extra_headers.IsEmpty()) {
411 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
412 response_data->clear();
413 return;
416 // We want to make sure we don't delete extra headers.
417 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
419 if (not_modified_) {
420 response_status->assign("HTTP/1.1 304 Not Modified");
421 response_data->clear();
422 return;
425 std::vector<net::HttpByteRange> ranges;
426 std::string range_header;
427 if (!request->extra_headers.GetHeader(
428 net::HttpRequestHeaders::kRange, &range_header) ||
429 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
430 ranges.size() != 1) {
431 // This is not a byte range request. We return 200.
432 response_status->assign("HTTP/1.1 200 OK");
433 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
434 response_data->assign("Not a range");
435 return;
438 // We can handle this range request.
439 net::HttpByteRange byte_range = ranges[0];
440 if (byte_range.first_byte_position() > 79) {
441 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
442 response_data->clear();
443 return;
446 EXPECT_TRUE(byte_range.ComputeBounds(80));
447 int start = static_cast<int>(byte_range.first_byte_position());
448 int end = static_cast<int>(byte_range.last_byte_position());
450 EXPECT_LT(end, 80);
452 std::string content_range = base::StringPrintf(
453 "Content-Range: bytes %d-%d/80\n", start, end);
454 response_headers->append(content_range);
456 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
457 std::string data;
458 if (end == start) {
459 EXPECT_EQ(0, end % 10);
460 data = "r";
461 } else {
462 EXPECT_EQ(9, (end - start) % 10);
463 for (int block_start = start; block_start < end; block_start += 10) {
464 base::StringAppendF(&data, "rg: %02d-%02d ",
465 block_start, block_start + 9);
468 *response_data = data;
470 if (end - start != 9) {
471 // We also have to fix content-length.
472 int len = end - start + 1;
473 std::string content_length = base::StringPrintf("Content-Length: %d\n",
474 len);
475 response_headers->replace(response_headers->find("Content-Length:"),
476 content_length.size(), content_length);
478 } else {
479 response_status->assign("HTTP/1.1 304 Not Modified");
480 response_data->clear();
484 const MockTransaction kRangeGET_TransactionOK = {
485 "http://www.google.com/range",
486 "GET",
487 base::Time(),
488 "Range: bytes = 40-49\r\n"
489 EXTRA_HEADER,
490 net::LOAD_NORMAL,
491 "HTTP/1.1 206 Partial Content",
492 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
493 "ETag: \"foo\"\n"
494 "Accept-Ranges: bytes\n"
495 "Content-Length: 10\n",
496 base::Time(),
497 "rg: 40-49 ",
498 TEST_MODE_NORMAL,
499 &RangeTransactionServer::RangeHandler,
501 net::OK
504 // Verifies the response headers (|response|) match a partial content
505 // response for the range starting at |start| and ending at |end|.
506 void Verify206Response(std::string response, int start, int end) {
507 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
508 response.size()));
509 scoped_refptr<net::HttpResponseHeaders> headers(
510 new net::HttpResponseHeaders(raw_headers));
512 ASSERT_EQ(206, headers->response_code());
514 int64 range_start, range_end, object_size;
515 ASSERT_TRUE(
516 headers->GetContentRange(&range_start, &range_end, &object_size));
517 int64 content_length = headers->GetContentLength();
519 int length = end - start + 1;
520 ASSERT_EQ(length, content_length);
521 ASSERT_EQ(start, range_start);
522 ASSERT_EQ(end, range_end);
525 // Creates a truncated entry that can be resumed using byte ranges.
526 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
527 // Create a disk cache entry that stores an incomplete resource.
528 disk_cache::Entry* entry;
529 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
530 NULL));
532 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
533 raw_headers.size());
535 net::HttpResponseInfo response;
536 response.response_time = base::Time::Now();
537 response.request_time = base::Time::Now();
538 response.headers = new net::HttpResponseHeaders(raw_headers);
539 // Set the last argument for this to be an incomplete request.
540 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
542 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
543 int len = static_cast<int>(base::strlcpy(buf->data(),
544 "rg: 00-09 rg: 10-19 ", 100));
545 net::TestCompletionCallback cb;
546 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
547 EXPECT_EQ(len, cb.GetResult(rv));
548 entry->Close();
551 // Helper to represent a network HTTP response.
552 struct Response {
553 // Set this response into |trans|.
554 void AssignTo(MockTransaction* trans) const {
555 trans->status = status;
556 trans->response_headers = headers;
557 trans->data = body;
560 std::string status_and_headers() const {
561 return std::string(status) + "\n" + std::string(headers);
564 const char* status;
565 const char* headers;
566 const char* body;
569 struct Context {
570 Context() : result(net::ERR_IO_PENDING) {}
572 int result;
573 net::TestCompletionCallback callback;
574 scoped_ptr<net::HttpTransaction> trans;
577 } // namespace
580 //-----------------------------------------------------------------------------
581 // Tests.
583 TEST(HttpCache, CreateThenDestroy) {
584 MockHttpCache cache;
586 scoped_ptr<net::HttpTransaction> trans;
587 int rv = cache.http_cache()->CreateTransaction(
588 net::DEFAULT_PRIORITY, &trans, NULL);
589 EXPECT_EQ(net::OK, rv);
590 ASSERT_TRUE(trans.get());
593 TEST(HttpCache, GetBackend) {
594 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
596 disk_cache::Backend* backend;
597 net::TestCompletionCallback cb;
598 // This will lazily initialize the backend.
599 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
600 EXPECT_EQ(net::OK, cb.GetResult(rv));
603 TEST(HttpCache, SimpleGET) {
604 MockHttpCache cache;
605 net::CapturingBoundNetLog log;
606 net::LoadTimingInfo load_timing_info;
608 // Write to the cache.
609 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
610 log.bound(), &load_timing_info);
612 EXPECT_EQ(1, cache.network_layer()->transaction_count());
613 EXPECT_EQ(0, cache.disk_cache()->open_count());
614 EXPECT_EQ(1, cache.disk_cache()->create_count());
615 TestLoadTimingNetworkRequest(load_timing_info);
618 TEST(HttpCache, SimpleGETNoDiskCache) {
619 MockHttpCache cache;
621 cache.disk_cache()->set_fail_requests();
623 net::CapturingBoundNetLog log;
624 log.SetLogLevel(net::NetLog::LOG_BASIC);
625 net::LoadTimingInfo load_timing_info;
627 // Read from the network, and don't use the cache.
628 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
629 log.bound(), &load_timing_info);
631 // Check that the NetLog was filled as expected.
632 // (We attempted to both Open and Create entries, but both failed).
633 net::CapturingNetLog::CapturedEntryList entries;
634 log.GetEntries(&entries);
636 EXPECT_EQ(6u, entries.size());
637 EXPECT_TRUE(net::LogContainsBeginEvent(
638 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
639 EXPECT_TRUE(net::LogContainsEndEvent(
640 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
641 EXPECT_TRUE(net::LogContainsBeginEvent(
642 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
643 EXPECT_TRUE(net::LogContainsEndEvent(
644 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
645 EXPECT_TRUE(net::LogContainsBeginEvent(
646 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
647 EXPECT_TRUE(net::LogContainsEndEvent(
648 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
650 EXPECT_EQ(1, cache.network_layer()->transaction_count());
651 EXPECT_EQ(0, cache.disk_cache()->open_count());
652 EXPECT_EQ(0, cache.disk_cache()->create_count());
653 TestLoadTimingNetworkRequest(load_timing_info);
656 TEST(HttpCache, SimpleGETNoDiskCache2) {
657 // This will initialize a cache object with NULL backend.
658 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
659 factory->set_fail(true);
660 factory->FinishCreation(); // We'll complete synchronously.
661 MockHttpCache cache(factory);
663 // Read from the network, and don't use the cache.
664 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
666 EXPECT_EQ(1, cache.network_layer()->transaction_count());
667 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
670 // Tests that IOBuffers are not referenced after IO completes.
671 TEST(HttpCache, ReleaseBuffer) {
672 MockHttpCache cache;
674 // Write to the cache.
675 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
677 MockHttpRequest request(kSimpleGET_Transaction);
678 scoped_ptr<net::HttpTransaction> trans;
679 int rv = cache.http_cache()->CreateTransaction(
680 net::DEFAULT_PRIORITY, &trans, NULL);
681 ASSERT_EQ(net::OK, rv);
683 const int kBufferSize = 10;
684 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
685 net::ReleaseBufferCompletionCallback cb(buffer.get());
687 rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
688 EXPECT_EQ(net::OK, cb.GetResult(rv));
690 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
691 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
694 TEST(HttpCache, SimpleGETWithDiskFailures) {
695 MockHttpCache cache;
697 cache.disk_cache()->set_soft_failures(true);
699 // Read from the network, and fail to write to the cache.
700 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
702 EXPECT_EQ(1, cache.network_layer()->transaction_count());
703 EXPECT_EQ(0, cache.disk_cache()->open_count());
704 EXPECT_EQ(1, cache.disk_cache()->create_count());
706 // This one should see an empty cache again.
707 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
709 EXPECT_EQ(2, cache.network_layer()->transaction_count());
710 EXPECT_EQ(0, cache.disk_cache()->open_count());
711 EXPECT_EQ(2, cache.disk_cache()->create_count());
714 // Tests that disk failures after the transaction has started don't cause the
715 // request to fail.
716 TEST(HttpCache, SimpleGETWithDiskFailures2) {
717 MockHttpCache cache;
719 MockHttpRequest request(kSimpleGET_Transaction);
721 scoped_ptr<Context> c(new Context());
722 int rv = cache.http_cache()->CreateTransaction(
723 net::DEFAULT_PRIORITY, &c->trans, NULL);
724 EXPECT_EQ(net::OK, rv);
726 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
727 EXPECT_EQ(net::ERR_IO_PENDING, rv);
728 rv = c->callback.WaitForResult();
730 // Start failing request now.
731 cache.disk_cache()->set_soft_failures(true);
733 // We have to open the entry again to propagate the failure flag.
734 disk_cache::Entry* en;
735 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
736 en->Close();
738 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
739 c.reset();
741 EXPECT_EQ(1, cache.network_layer()->transaction_count());
742 EXPECT_EQ(1, cache.disk_cache()->open_count());
743 EXPECT_EQ(1, cache.disk_cache()->create_count());
745 // This one should see an empty cache again.
746 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
748 EXPECT_EQ(2, cache.network_layer()->transaction_count());
749 EXPECT_EQ(1, cache.disk_cache()->open_count());
750 EXPECT_EQ(2, cache.disk_cache()->create_count());
753 // Tests that we handle failures to read from the cache.
754 TEST(HttpCache, SimpleGETWithDiskFailures3) {
755 MockHttpCache cache;
757 // Read from the network, and write to the cache.
758 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
760 EXPECT_EQ(1, cache.network_layer()->transaction_count());
761 EXPECT_EQ(0, cache.disk_cache()->open_count());
762 EXPECT_EQ(1, cache.disk_cache()->create_count());
764 cache.disk_cache()->set_soft_failures(true);
766 // Now fail to read from the cache.
767 scoped_ptr<Context> c(new Context());
768 int rv = cache.http_cache()->CreateTransaction(
769 net::DEFAULT_PRIORITY, &c->trans, NULL);
770 EXPECT_EQ(net::OK, rv);
772 MockHttpRequest request(kSimpleGET_Transaction);
773 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
774 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
776 // Now verify that the entry was removed from the cache.
777 cache.disk_cache()->set_soft_failures(false);
779 EXPECT_EQ(2, cache.network_layer()->transaction_count());
780 EXPECT_EQ(1, cache.disk_cache()->open_count());
781 EXPECT_EQ(2, cache.disk_cache()->create_count());
783 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
785 EXPECT_EQ(3, cache.network_layer()->transaction_count());
786 EXPECT_EQ(1, cache.disk_cache()->open_count());
787 EXPECT_EQ(3, cache.disk_cache()->create_count());
790 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
791 MockHttpCache cache;
793 net::CapturingBoundNetLog log;
795 // This prevents a number of write events from being logged.
796 log.SetLogLevel(net::NetLog::LOG_BASIC);
798 net::LoadTimingInfo load_timing_info;
800 // Write to the cache.
801 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
802 log.bound(), &load_timing_info);
804 // Check that the NetLog was filled as expected.
805 net::CapturingNetLog::CapturedEntryList entries;
806 log.GetEntries(&entries);
808 EXPECT_EQ(8u, entries.size());
809 EXPECT_TRUE(net::LogContainsBeginEvent(
810 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
811 EXPECT_TRUE(net::LogContainsEndEvent(
812 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
813 EXPECT_TRUE(net::LogContainsBeginEvent(
814 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
815 EXPECT_TRUE(net::LogContainsEndEvent(
816 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
817 EXPECT_TRUE(net::LogContainsBeginEvent(
818 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
819 EXPECT_TRUE(net::LogContainsEndEvent(
820 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
821 EXPECT_TRUE(net::LogContainsBeginEvent(
822 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
823 EXPECT_TRUE(net::LogContainsEndEvent(
824 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
826 TestLoadTimingNetworkRequest(load_timing_info);
828 // Force this transaction to read from the cache.
829 MockTransaction transaction(kSimpleGET_Transaction);
830 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
832 log.Clear();
834 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
835 &load_timing_info);
837 // Check that the NetLog was filled as expected.
838 log.GetEntries(&entries);
840 EXPECT_EQ(8u, entries.size());
841 EXPECT_TRUE(net::LogContainsBeginEvent(
842 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
843 EXPECT_TRUE(net::LogContainsEndEvent(
844 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
845 EXPECT_TRUE(net::LogContainsBeginEvent(
846 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
847 EXPECT_TRUE(net::LogContainsEndEvent(
848 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
849 EXPECT_TRUE(net::LogContainsBeginEvent(
850 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
851 EXPECT_TRUE(net::LogContainsEndEvent(
852 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
853 EXPECT_TRUE(net::LogContainsBeginEvent(
854 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
855 EXPECT_TRUE(net::LogContainsEndEvent(
856 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
858 EXPECT_EQ(1, cache.network_layer()->transaction_count());
859 EXPECT_EQ(1, cache.disk_cache()->open_count());
860 EXPECT_EQ(1, cache.disk_cache()->create_count());
861 TestLoadTimingCachedResponse(load_timing_info);
864 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
865 MockHttpCache cache;
867 // force this transaction to read from the cache
868 MockTransaction transaction(kSimpleGET_Transaction);
869 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
871 MockHttpRequest request(transaction);
872 net::TestCompletionCallback callback;
874 scoped_ptr<net::HttpTransaction> trans;
875 int rv = cache.http_cache()->CreateTransaction(
876 net::DEFAULT_PRIORITY, &trans, NULL);
877 EXPECT_EQ(net::OK, rv);
878 ASSERT_TRUE(trans.get());
880 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
881 if (rv == net::ERR_IO_PENDING)
882 rv = callback.WaitForResult();
883 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
885 trans.reset();
887 EXPECT_EQ(0, cache.network_layer()->transaction_count());
888 EXPECT_EQ(0, cache.disk_cache()->open_count());
889 EXPECT_EQ(0, cache.disk_cache()->create_count());
892 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
893 MockHttpCache cache;
895 // write to the cache
896 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
898 // force this transaction to read from the cache if valid
899 MockTransaction transaction(kSimpleGET_Transaction);
900 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
902 RunTransactionTest(cache.http_cache(), transaction);
904 EXPECT_EQ(1, cache.network_layer()->transaction_count());
905 EXPECT_EQ(1, cache.disk_cache()->open_count());
906 EXPECT_EQ(1, cache.disk_cache()->create_count());
909 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
910 MockHttpCache cache;
912 // force this transaction to read from the cache if valid
913 MockTransaction transaction(kSimpleGET_Transaction);
914 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
916 RunTransactionTest(cache.http_cache(), transaction);
918 EXPECT_EQ(1, cache.network_layer()->transaction_count());
919 EXPECT_EQ(0, cache.disk_cache()->open_count());
920 EXPECT_EQ(1, cache.disk_cache()->create_count());
923 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
924 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
925 MockHttpCache cache;
927 // Write to the cache.
928 MockTransaction transaction(kSimpleGET_Transaction);
929 transaction.request_headers = "Foo: bar\r\n";
930 transaction.response_headers = "Cache-Control: max-age=10000\n"
931 "Vary: Foo\n";
932 AddMockTransaction(&transaction);
933 RunTransactionTest(cache.http_cache(), transaction);
935 // Read from the cache.
936 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
937 RunTransactionTest(cache.http_cache(), transaction);
939 EXPECT_EQ(1, cache.network_layer()->transaction_count());
940 EXPECT_EQ(1, cache.disk_cache()->open_count());
941 EXPECT_EQ(1, cache.disk_cache()->create_count());
942 RemoveMockTransaction(&transaction);
945 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
946 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
947 MockHttpCache cache;
949 // Write to the cache.
950 MockTransaction transaction(kSimpleGET_Transaction);
951 transaction.request_headers = "Foo: bar\r\n";
952 transaction.response_headers = "Cache-Control: max-age=10000\n"
953 "Vary: Foo\n";
954 AddMockTransaction(&transaction);
955 RunTransactionTest(cache.http_cache(), transaction);
957 // Attempt to read from the cache... this is a vary mismatch that must reach
958 // the network again.
959 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
960 transaction.request_headers = "Foo: none\r\n";
961 net::CapturingBoundNetLog log;
962 net::LoadTimingInfo load_timing_info;
963 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
964 &load_timing_info);
966 EXPECT_EQ(2, cache.network_layer()->transaction_count());
967 EXPECT_EQ(1, cache.disk_cache()->open_count());
968 EXPECT_EQ(1, cache.disk_cache()->create_count());
969 TestLoadTimingNetworkRequest(load_timing_info);
970 RemoveMockTransaction(&transaction);
973 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
974 // network success
975 TEST(HttpCache, SimpleGET_CacheOverride_Network) {
976 MockHttpCache cache;
978 // Prime cache.
979 MockTransaction transaction(kSimpleGET_Transaction);
980 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
981 transaction.response_headers = "Cache-Control: no-cache\n";
983 AddMockTransaction(&transaction);
984 RunTransactionTest(cache.http_cache(), transaction);
985 EXPECT_EQ(1, cache.network_layer()->transaction_count());
986 EXPECT_EQ(1, cache.disk_cache()->create_count());
987 RemoveMockTransaction(&transaction);
989 // Re-run transaction; make sure the result came from the network,
990 // not the cache.
991 transaction.data = "Changed data.";
992 AddMockTransaction(&transaction);
993 net::HttpResponseInfo response_info;
994 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
995 &response_info);
997 EXPECT_EQ(2, cache.network_layer()->transaction_count());
998 EXPECT_FALSE(response_info.server_data_unavailable);
999 EXPECT_TRUE(response_info.network_accessed);
1001 RemoveMockTransaction(&transaction);
1004 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1005 // offline failure
1006 TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
1007 MockHttpCache cache;
1009 // Prime cache.
1010 MockTransaction transaction(kSimpleGET_Transaction);
1011 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1012 transaction.response_headers = "Cache-Control: no-cache\n";
1014 AddMockTransaction(&transaction);
1015 RunTransactionTest(cache.http_cache(), transaction);
1016 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1017 EXPECT_EQ(1, cache.disk_cache()->create_count());
1018 RemoveMockTransaction(&transaction);
1020 // Network failure with offline error; should return cache entry above +
1021 // flag signalling stale data.
1022 transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
1023 AddMockTransaction(&transaction);
1025 MockHttpRequest request(transaction);
1026 net::TestCompletionCallback callback;
1027 scoped_ptr<net::HttpTransaction> trans;
1028 int rv = cache.http_cache()->CreateTransaction(
1029 net::DEFAULT_PRIORITY, &trans, NULL);
1030 EXPECT_EQ(net::OK, rv);
1031 ASSERT_TRUE(trans.get());
1032 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1033 EXPECT_EQ(net::OK, callback.GetResult(rv));
1035 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1036 ASSERT_TRUE(response_info);
1037 EXPECT_TRUE(response_info->server_data_unavailable);
1038 EXPECT_TRUE(response_info->was_cached);
1039 EXPECT_FALSE(response_info->network_accessed);
1040 ReadAndVerifyTransaction(trans.get(), transaction);
1041 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1043 RemoveMockTransaction(&transaction);
1046 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1047 // non-offline failure.
1048 TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
1049 MockHttpCache cache;
1051 // Prime cache.
1052 MockTransaction transaction(kSimpleGET_Transaction);
1053 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1054 transaction.response_headers = "Cache-Control: no-cache\n";
1056 AddMockTransaction(&transaction);
1057 RunTransactionTest(cache.http_cache(), transaction);
1058 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1059 EXPECT_EQ(1, cache.disk_cache()->create_count());
1060 RemoveMockTransaction(&transaction);
1062 // Network failure with non-offline error; should fail with that error.
1063 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1064 AddMockTransaction(&transaction);
1066 net::HttpResponseInfo response_info2;
1067 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1068 &response_info2);
1070 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1071 EXPECT_FALSE(response_info2.server_data_unavailable);
1073 RemoveMockTransaction(&transaction);
1076 // Confirm if we have an empty cache, a read is marked as network verified.
1077 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1078 MockHttpCache cache;
1080 // write to the cache
1081 net::HttpResponseInfo response_info;
1082 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1083 &response_info);
1085 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1086 EXPECT_EQ(0, cache.disk_cache()->open_count());
1087 EXPECT_EQ(1, cache.disk_cache()->create_count());
1088 EXPECT_TRUE(response_info.network_accessed);
1091 // Confirm if we have a fresh entry in cache, it isn't marked as
1092 // network verified.
1093 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1094 MockHttpCache cache;
1096 // Prime cache.
1097 MockTransaction transaction(kSimpleGET_Transaction);
1099 RunTransactionTest(cache.http_cache(), transaction);
1100 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1101 EXPECT_EQ(1, cache.disk_cache()->create_count());
1103 // Re-run transaction; make sure we don't mark the network as accessed.
1104 net::HttpResponseInfo response_info;
1105 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1106 &response_info);
1108 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1109 EXPECT_FALSE(response_info.server_data_unavailable);
1110 EXPECT_FALSE(response_info.network_accessed);
1113 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1114 MockHttpCache cache;
1116 // Write to the cache.
1117 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1119 // Force this transaction to write to the cache again.
1120 MockTransaction transaction(kSimpleGET_Transaction);
1121 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1123 net::CapturingBoundNetLog log;
1125 // This prevents a number of write events from being logged.
1126 log.SetLogLevel(net::NetLog::LOG_BASIC);
1127 net::LoadTimingInfo load_timing_info;
1129 // Write to the cache.
1130 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1131 &load_timing_info);
1133 // Check that the NetLog was filled as expected.
1134 net::CapturingNetLog::CapturedEntryList entries;
1135 log.GetEntries(&entries);
1137 EXPECT_EQ(8u, entries.size());
1138 EXPECT_TRUE(net::LogContainsBeginEvent(
1139 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1140 EXPECT_TRUE(net::LogContainsEndEvent(
1141 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1142 EXPECT_TRUE(net::LogContainsBeginEvent(
1143 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1144 EXPECT_TRUE(net::LogContainsEndEvent(
1145 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1146 EXPECT_TRUE(net::LogContainsBeginEvent(
1147 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1148 EXPECT_TRUE(net::LogContainsEndEvent(
1149 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1150 EXPECT_TRUE(net::LogContainsBeginEvent(
1151 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1152 EXPECT_TRUE(net::LogContainsEndEvent(
1153 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1155 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1156 EXPECT_EQ(0, cache.disk_cache()->open_count());
1157 EXPECT_EQ(2, cache.disk_cache()->create_count());
1158 TestLoadTimingNetworkRequest(load_timing_info);
1161 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1162 MockHttpCache cache;
1164 // write to the cache
1165 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1167 // force this transaction to write to the cache again
1168 MockTransaction transaction(kSimpleGET_Transaction);
1169 transaction.request_headers = "pragma: no-cache\r\n";
1171 RunTransactionTest(cache.http_cache(), transaction);
1173 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1174 EXPECT_EQ(0, cache.disk_cache()->open_count());
1175 EXPECT_EQ(2, cache.disk_cache()->create_count());
1178 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1179 MockHttpCache cache;
1181 // write to the cache
1182 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1184 // force this transaction to write to the cache again
1185 MockTransaction transaction(kSimpleGET_Transaction);
1186 transaction.request_headers = "cache-control: no-cache\r\n";
1188 RunTransactionTest(cache.http_cache(), transaction);
1190 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1191 EXPECT_EQ(0, cache.disk_cache()->open_count());
1192 EXPECT_EQ(2, cache.disk_cache()->create_count());
1195 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1196 MockHttpCache cache;
1198 // Write to the cache.
1199 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1201 // Read from the cache.
1202 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1204 // Force this transaction to validate the cache.
1205 MockTransaction transaction(kSimpleGET_Transaction);
1206 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1208 net::HttpResponseInfo response_info;
1209 net::CapturingBoundNetLog log;
1210 net::LoadTimingInfo load_timing_info;
1211 RunTransactionTestWithResponseInfoAndGetTiming(
1212 cache.http_cache(), transaction, &response_info, log.bound(),
1213 &load_timing_info);
1215 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1216 EXPECT_EQ(1, cache.disk_cache()->open_count());
1217 EXPECT_EQ(1, cache.disk_cache()->create_count());
1218 EXPECT_TRUE(response_info.network_accessed);
1219 TestLoadTimingNetworkRequest(load_timing_info);
1222 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1223 MockHttpCache cache;
1225 // write to the cache
1226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1228 // read from the cache
1229 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1231 // force this transaction to validate the cache
1232 MockTransaction transaction(kSimpleGET_Transaction);
1233 transaction.request_headers = "cache-control: max-age=0\r\n";
1235 RunTransactionTest(cache.http_cache(), transaction);
1237 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1238 EXPECT_EQ(1, cache.disk_cache()->open_count());
1239 EXPECT_EQ(1, cache.disk_cache()->create_count());
1242 static void PreserveRequestHeaders_Handler(
1243 const net::HttpRequestInfo* request,
1244 std::string* response_status,
1245 std::string* response_headers,
1246 std::string* response_data) {
1247 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1250 // Tests that we don't remove extra headers for simple requests.
1251 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1252 MockHttpCache cache;
1254 MockTransaction transaction(kSimpleGET_Transaction);
1255 transaction.handler = PreserveRequestHeaders_Handler;
1256 transaction.request_headers = EXTRA_HEADER;
1257 transaction.response_headers = "Cache-Control: max-age=0\n";
1258 AddMockTransaction(&transaction);
1260 // Write, then revalidate the entry.
1261 RunTransactionTest(cache.http_cache(), transaction);
1262 RunTransactionTest(cache.http_cache(), transaction);
1264 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1265 EXPECT_EQ(1, cache.disk_cache()->open_count());
1266 EXPECT_EQ(1, cache.disk_cache()->create_count());
1267 RemoveMockTransaction(&transaction);
1270 // Tests that we don't remove extra headers for conditionalized requests.
1271 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1272 MockHttpCache cache;
1274 // Write to the cache.
1275 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1277 MockTransaction transaction(kETagGET_Transaction);
1278 transaction.handler = PreserveRequestHeaders_Handler;
1279 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1280 EXTRA_HEADER;
1281 AddMockTransaction(&transaction);
1283 RunTransactionTest(cache.http_cache(), transaction);
1285 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1286 EXPECT_EQ(1, cache.disk_cache()->open_count());
1287 EXPECT_EQ(1, cache.disk_cache()->create_count());
1288 RemoveMockTransaction(&transaction);
1291 TEST(HttpCache, SimpleGET_ManyReaders) {
1292 MockHttpCache cache;
1294 MockHttpRequest request(kSimpleGET_Transaction);
1296 std::vector<Context*> context_list;
1297 const int kNumTransactions = 5;
1299 for (int i = 0; i < kNumTransactions; ++i) {
1300 context_list.push_back(new Context());
1301 Context* c = context_list[i];
1303 c->result = cache.http_cache()->CreateTransaction(
1304 net::DEFAULT_PRIORITY, &c->trans, NULL);
1305 EXPECT_EQ(net::OK, c->result);
1306 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1308 c->result = c->trans->Start(
1309 &request, c->callback.callback(), net::BoundNetLog());
1312 // All requests are waiting for the active entry.
1313 for (int i = 0; i < kNumTransactions; ++i) {
1314 Context* c = context_list[i];
1315 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1318 // Allow all requests to move from the Create queue to the active entry.
1319 base::MessageLoop::current()->RunUntilIdle();
1321 // The first request should be a writer at this point, and the subsequent
1322 // requests should be pending.
1324 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1325 EXPECT_EQ(0, cache.disk_cache()->open_count());
1326 EXPECT_EQ(1, cache.disk_cache()->create_count());
1328 // All requests depend on the writer, and the writer is between Start and
1329 // Read, i.e. idle.
1330 for (int i = 0; i < kNumTransactions; ++i) {
1331 Context* c = context_list[i];
1332 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1335 for (int i = 0; i < kNumTransactions; ++i) {
1336 Context* c = context_list[i];
1337 if (c->result == net::ERR_IO_PENDING)
1338 c->result = c->callback.WaitForResult();
1339 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1342 // We should not have had to re-open the disk entry
1344 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1345 EXPECT_EQ(0, cache.disk_cache()->open_count());
1346 EXPECT_EQ(1, cache.disk_cache()->create_count());
1348 for (int i = 0; i < kNumTransactions; ++i) {
1349 Context* c = context_list[i];
1350 delete c;
1354 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1355 // If cancelling a request is racing with another request for the same resource
1356 // finishing, we have to make sure that we remove both transactions from the
1357 // entry.
1358 TEST(HttpCache, SimpleGET_RacingReaders) {
1359 MockHttpCache cache;
1361 MockHttpRequest request(kSimpleGET_Transaction);
1362 MockHttpRequest reader_request(kSimpleGET_Transaction);
1363 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1365 std::vector<Context*> context_list;
1366 const int kNumTransactions = 5;
1368 for (int i = 0; i < kNumTransactions; ++i) {
1369 context_list.push_back(new Context());
1370 Context* c = context_list[i];
1372 c->result = cache.http_cache()->CreateTransaction(
1373 net::DEFAULT_PRIORITY, &c->trans, NULL);
1374 EXPECT_EQ(net::OK, c->result);
1376 MockHttpRequest* this_request = &request;
1377 if (i == 1 || i == 2)
1378 this_request = &reader_request;
1380 c->result = c->trans->Start(
1381 this_request, c->callback.callback(), net::BoundNetLog());
1384 // Allow all requests to move from the Create queue to the active entry.
1385 base::MessageLoop::current()->RunUntilIdle();
1387 // The first request should be a writer at this point, and the subsequent
1388 // requests should be pending.
1390 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1391 EXPECT_EQ(0, cache.disk_cache()->open_count());
1392 EXPECT_EQ(1, cache.disk_cache()->create_count());
1394 Context* c = context_list[0];
1395 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1396 c->result = c->callback.WaitForResult();
1397 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1399 // Now we have 2 active readers and two queued transactions.
1401 EXPECT_EQ(net::LOAD_STATE_IDLE,
1402 context_list[2]->trans->GetLoadState());
1403 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1404 context_list[3]->trans->GetLoadState());
1406 c = context_list[1];
1407 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1408 c->result = c->callback.WaitForResult();
1409 if (c->result == net::OK)
1410 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1412 // At this point we have one reader, two pending transactions and a task on
1413 // the queue to move to the next transaction. Now we cancel the request that
1414 // is the current reader, and expect the queued task to be able to start the
1415 // next request.
1417 c = context_list[2];
1418 c->trans.reset();
1420 for (int i = 3; i < kNumTransactions; ++i) {
1421 Context* c = context_list[i];
1422 if (c->result == net::ERR_IO_PENDING)
1423 c->result = c->callback.WaitForResult();
1424 if (c->result == net::OK)
1425 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1428 // We should not have had to re-open the disk entry.
1430 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1431 EXPECT_EQ(0, cache.disk_cache()->open_count());
1432 EXPECT_EQ(1, cache.disk_cache()->create_count());
1434 for (int i = 0; i < kNumTransactions; ++i) {
1435 Context* c = context_list[i];
1436 delete c;
1440 // Tests that we can doom an entry with pending transactions and delete one of
1441 // the pending transactions before the first one completes.
1442 // See http://code.google.com/p/chromium/issues/detail?id=25588
1443 TEST(HttpCache, SimpleGET_DoomWithPending) {
1444 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1445 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1447 MockHttpRequest request(kSimpleGET_Transaction);
1448 MockHttpRequest writer_request(kSimpleGET_Transaction);
1449 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1451 ScopedVector<Context> context_list;
1452 const int kNumTransactions = 4;
1454 for (int i = 0; i < kNumTransactions; ++i) {
1455 context_list.push_back(new Context());
1456 Context* c = context_list[i];
1458 c->result = cache.http_cache()->CreateTransaction(
1459 net::DEFAULT_PRIORITY, &c->trans, NULL);
1460 EXPECT_EQ(net::OK, c->result);
1462 MockHttpRequest* this_request = &request;
1463 if (i == 3)
1464 this_request = &writer_request;
1466 c->result = c->trans->Start(
1467 this_request, c->callback.callback(), net::BoundNetLog());
1470 // The first request should be a writer at this point, and the two subsequent
1471 // requests should be pending. The last request doomed the first entry.
1473 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1475 // Cancel the first queued transaction.
1476 delete context_list[1];
1477 context_list.get()[1] = NULL;
1479 for (int i = 0; i < kNumTransactions; ++i) {
1480 if (i == 1)
1481 continue;
1482 Context* c = context_list[i];
1483 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1484 c->result = c->callback.WaitForResult();
1485 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1489 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1490 // We may attempt to delete an entry synchronously with the act of adding a new
1491 // transaction to said entry.
1492 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1493 MockHttpCache cache;
1495 // The headers will be served right from the call to Start() the request.
1496 MockHttpRequest request(kFastNoStoreGET_Transaction);
1497 FastTransactionServer request_handler;
1498 AddMockTransaction(&kFastNoStoreGET_Transaction);
1500 std::vector<Context*> context_list;
1501 const int kNumTransactions = 3;
1503 for (int i = 0; i < kNumTransactions; ++i) {
1504 context_list.push_back(new Context());
1505 Context* c = context_list[i];
1507 c->result = cache.http_cache()->CreateTransaction(
1508 net::DEFAULT_PRIORITY, &c->trans, NULL);
1509 EXPECT_EQ(net::OK, c->result);
1511 c->result = c->trans->Start(
1512 &request, c->callback.callback(), net::BoundNetLog());
1515 // Allow all requests to move from the Create queue to the active entry.
1516 base::MessageLoop::current()->RunUntilIdle();
1518 // The first request should be a writer at this point, and the subsequent
1519 // requests should be pending.
1521 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1522 EXPECT_EQ(0, cache.disk_cache()->open_count());
1523 EXPECT_EQ(1, cache.disk_cache()->create_count());
1525 // Now, make sure that the second request asks for the entry not to be stored.
1526 request_handler.set_no_store(true);
1528 for (int i = 0; i < kNumTransactions; ++i) {
1529 Context* c = context_list[i];
1530 if (c->result == net::ERR_IO_PENDING)
1531 c->result = c->callback.WaitForResult();
1532 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1533 delete c;
1536 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1537 EXPECT_EQ(0, cache.disk_cache()->open_count());
1538 EXPECT_EQ(2, cache.disk_cache()->create_count());
1540 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1543 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1544 MockHttpCache cache;
1546 MockHttpRequest request(kSimpleGET_Transaction);
1548 std::vector<Context*> context_list;
1549 const int kNumTransactions = 2;
1551 for (int i = 0; i < kNumTransactions; ++i) {
1552 context_list.push_back(new Context());
1553 Context* c = context_list[i];
1555 c->result = cache.http_cache()->CreateTransaction(
1556 net::DEFAULT_PRIORITY, &c->trans, NULL);
1557 EXPECT_EQ(net::OK, c->result);
1559 c->result = c->trans->Start(
1560 &request, c->callback.callback(), net::BoundNetLog());
1563 // Allow all requests to move from the Create queue to the active entry.
1564 base::MessageLoop::current()->RunUntilIdle();
1566 // The first request should be a writer at this point, and the subsequent
1567 // requests should be pending.
1569 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1570 EXPECT_EQ(0, cache.disk_cache()->open_count());
1571 EXPECT_EQ(1, cache.disk_cache()->create_count());
1573 for (int i = 0; i < kNumTransactions; ++i) {
1574 Context* c = context_list[i];
1575 if (c->result == net::ERR_IO_PENDING)
1576 c->result = c->callback.WaitForResult();
1577 // Destroy only the first transaction.
1578 if (i == 0) {
1579 delete c;
1580 context_list[i] = NULL;
1584 // Complete the rest of the transactions.
1585 for (int i = 1; i < kNumTransactions; ++i) {
1586 Context* c = context_list[i];
1587 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1590 // We should have had to re-open the disk entry.
1592 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1593 EXPECT_EQ(0, cache.disk_cache()->open_count());
1594 EXPECT_EQ(2, cache.disk_cache()->create_count());
1596 for (int i = 1; i < kNumTransactions; ++i) {
1597 Context* c = context_list[i];
1598 delete c;
1602 // Tests that we can cancel requests that are queued waiting to open the disk
1603 // cache entry.
1604 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1605 MockHttpCache cache;
1607 MockHttpRequest request(kSimpleGET_Transaction);
1609 std::vector<Context*> context_list;
1610 const int kNumTransactions = 5;
1612 for (int i = 0; i < kNumTransactions; i++) {
1613 context_list.push_back(new Context());
1614 Context* c = context_list[i];
1616 c->result = cache.http_cache()->CreateTransaction(
1617 net::DEFAULT_PRIORITY, &c->trans, NULL);
1618 EXPECT_EQ(net::OK, c->result);
1620 c->result = c->trans->Start(
1621 &request, c->callback.callback(), net::BoundNetLog());
1624 // The first request should be creating the disk cache entry and the others
1625 // should be pending.
1627 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1628 EXPECT_EQ(0, cache.disk_cache()->open_count());
1629 EXPECT_EQ(1, cache.disk_cache()->create_count());
1631 // Cancel a request from the pending queue.
1632 delete context_list[3];
1633 context_list[3] = NULL;
1635 // Cancel the request that is creating the entry. This will force the pending
1636 // operations to restart.
1637 delete context_list[0];
1638 context_list[0] = NULL;
1640 // Complete the rest of the transactions.
1641 for (int i = 1; i < kNumTransactions; i++) {
1642 Context* c = context_list[i];
1643 if (c) {
1644 c->result = c->callback.GetResult(c->result);
1645 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1649 // We should have had to re-create the disk entry.
1651 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1652 EXPECT_EQ(0, cache.disk_cache()->open_count());
1653 EXPECT_EQ(2, cache.disk_cache()->create_count());
1655 for (int i = 1; i < kNumTransactions; ++i) {
1656 delete context_list[i];
1660 // Tests that we can cancel a single request to open a disk cache entry.
1661 TEST(HttpCache, SimpleGET_CancelCreate) {
1662 MockHttpCache cache;
1664 MockHttpRequest request(kSimpleGET_Transaction);
1666 Context* c = new Context();
1668 c->result = cache.http_cache()->CreateTransaction(
1669 net::DEFAULT_PRIORITY, &c->trans, NULL);
1670 EXPECT_EQ(net::OK, c->result);
1672 c->result = c->trans->Start(
1673 &request, c->callback.callback(), net::BoundNetLog());
1674 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1676 // Release the reference that the mock disk cache keeps for this entry, so
1677 // that we test that the http cache handles the cancellation correctly.
1678 cache.disk_cache()->ReleaseAll();
1679 delete c;
1681 base::MessageLoop::current()->RunUntilIdle();
1682 EXPECT_EQ(1, cache.disk_cache()->create_count());
1685 // Tests that we delete/create entries even if multiple requests are queued.
1686 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1687 MockHttpCache cache;
1689 MockHttpRequest request(kSimpleGET_Transaction);
1690 request.load_flags = net::LOAD_BYPASS_CACHE;
1692 std::vector<Context*> context_list;
1693 const int kNumTransactions = 5;
1695 for (int i = 0; i < kNumTransactions; i++) {
1696 context_list.push_back(new Context());
1697 Context* c = context_list[i];
1699 c->result = cache.http_cache()->CreateTransaction(
1700 net::DEFAULT_PRIORITY, &c->trans, NULL);
1701 EXPECT_EQ(net::OK, c->result);
1703 c->result = c->trans->Start(
1704 &request, c->callback.callback(), net::BoundNetLog());
1707 // The first request should be deleting the disk cache entry and the others
1708 // should be pending.
1710 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1711 EXPECT_EQ(0, cache.disk_cache()->open_count());
1712 EXPECT_EQ(0, cache.disk_cache()->create_count());
1714 // Complete the transactions.
1715 for (int i = 0; i < kNumTransactions; i++) {
1716 Context* c = context_list[i];
1717 c->result = c->callback.GetResult(c->result);
1718 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1721 // We should have had to re-create the disk entry multiple times.
1723 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1724 EXPECT_EQ(0, cache.disk_cache()->open_count());
1725 EXPECT_EQ(5, cache.disk_cache()->create_count());
1727 for (int i = 0; i < kNumTransactions; ++i) {
1728 delete context_list[i];
1732 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1733 MockHttpCache cache;
1735 // write to the cache
1736 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1738 MockHttpRequest request(kSimpleGET_Transaction);
1739 net::TestCompletionCallback callback;
1741 scoped_ptr<net::HttpTransaction> trans;
1742 int rv = cache.http_cache()->CreateTransaction(
1743 net::DEFAULT_PRIORITY, &trans, NULL);
1744 EXPECT_EQ(net::OK, rv);
1745 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1746 if (rv == net::ERR_IO_PENDING)
1747 rv = callback.WaitForResult();
1748 ASSERT_EQ(net::OK, rv);
1750 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1751 rv = trans->Read(buf.get(), 256, callback.callback());
1752 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1754 // Test that destroying the transaction while it is reading from the cache
1755 // works properly.
1756 trans.reset();
1758 // Make sure we pump any pending events, which should include a call to
1759 // HttpCache::Transaction::OnCacheReadCompleted.
1760 base::MessageLoop::current()->RunUntilIdle();
1763 // Tests that we can delete the HttpCache and deal with queued transactions
1764 // ("waiting for the backend" as opposed to Active or Doomed entries).
1765 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1766 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1767 new MockBackendNoCbFactory()));
1769 MockHttpRequest request(kSimpleGET_Transaction);
1771 std::vector<Context*> context_list;
1772 const int kNumTransactions = 5;
1774 for (int i = 0; i < kNumTransactions; i++) {
1775 context_list.push_back(new Context());
1776 Context* c = context_list[i];
1778 c->result = cache->http_cache()->CreateTransaction(
1779 net::DEFAULT_PRIORITY, &c->trans, NULL);
1780 EXPECT_EQ(net::OK, c->result);
1782 c->result = c->trans->Start(
1783 &request, c->callback.callback(), net::BoundNetLog());
1786 // The first request should be creating the disk cache entry and the others
1787 // should be pending.
1789 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1790 EXPECT_EQ(0, cache->disk_cache()->open_count());
1791 EXPECT_EQ(0, cache->disk_cache()->create_count());
1793 cache.reset();
1795 // There is not much to do with the transactions at this point... they are
1796 // waiting for a callback that will not fire.
1797 for (int i = 0; i < kNumTransactions; ++i) {
1798 delete context_list[i];
1802 // Tests that we queue requests when initializing the backend.
1803 TEST(HttpCache, SimpleGET_WaitForBackend) {
1804 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1805 MockHttpCache cache(factory);
1807 MockHttpRequest request0(kSimpleGET_Transaction);
1808 MockHttpRequest request1(kTypicalGET_Transaction);
1809 MockHttpRequest request2(kETagGET_Transaction);
1811 std::vector<Context*> context_list;
1812 const int kNumTransactions = 3;
1814 for (int i = 0; i < kNumTransactions; i++) {
1815 context_list.push_back(new Context());
1816 Context* c = context_list[i];
1818 c->result = cache.http_cache()->CreateTransaction(
1819 net::DEFAULT_PRIORITY, &c->trans, NULL);
1820 EXPECT_EQ(net::OK, c->result);
1823 context_list[0]->result = context_list[0]->trans->Start(
1824 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1825 context_list[1]->result = context_list[1]->trans->Start(
1826 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1827 context_list[2]->result = context_list[2]->trans->Start(
1828 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1830 // Just to make sure that everything is still pending.
1831 base::MessageLoop::current()->RunUntilIdle();
1833 // The first request should be creating the disk cache.
1834 EXPECT_FALSE(context_list[0]->callback.have_result());
1836 factory->FinishCreation();
1838 base::MessageLoop::current()->RunUntilIdle();
1839 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1840 EXPECT_EQ(3, cache.disk_cache()->create_count());
1842 for (int i = 0; i < kNumTransactions; ++i) {
1843 EXPECT_TRUE(context_list[i]->callback.have_result());
1844 delete context_list[i];
1848 // Tests that we can cancel requests that are queued waiting for the backend
1849 // to be initialized.
1850 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1851 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1852 MockHttpCache cache(factory);
1854 MockHttpRequest request0(kSimpleGET_Transaction);
1855 MockHttpRequest request1(kTypicalGET_Transaction);
1856 MockHttpRequest request2(kETagGET_Transaction);
1858 std::vector<Context*> context_list;
1859 const int kNumTransactions = 3;
1861 for (int i = 0; i < kNumTransactions; i++) {
1862 context_list.push_back(new Context());
1863 Context* c = context_list[i];
1865 c->result = cache.http_cache()->CreateTransaction(
1866 net::DEFAULT_PRIORITY, &c->trans, NULL);
1867 EXPECT_EQ(net::OK, c->result);
1870 context_list[0]->result = context_list[0]->trans->Start(
1871 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1872 context_list[1]->result = context_list[1]->trans->Start(
1873 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1874 context_list[2]->result = context_list[2]->trans->Start(
1875 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1877 // Just to make sure that everything is still pending.
1878 base::MessageLoop::current()->RunUntilIdle();
1880 // The first request should be creating the disk cache.
1881 EXPECT_FALSE(context_list[0]->callback.have_result());
1883 // Cancel a request from the pending queue.
1884 delete context_list[1];
1885 context_list[1] = NULL;
1887 // Cancel the request that is creating the entry.
1888 delete context_list[0];
1889 context_list[0] = NULL;
1891 // Complete the last transaction.
1892 factory->FinishCreation();
1894 context_list[2]->result =
1895 context_list[2]->callback.GetResult(context_list[2]->result);
1896 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1899 EXPECT_EQ(1, cache.disk_cache()->create_count());
1901 delete context_list[2];
1904 // Tests that we can delete the cache while creating the backend.
1905 TEST(HttpCache, DeleteCacheWaitingForBackend) {
1906 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1907 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1909 MockHttpRequest request(kSimpleGET_Transaction);
1911 scoped_ptr<Context> c(new Context());
1912 c->result = cache->http_cache()->CreateTransaction(
1913 net::DEFAULT_PRIORITY, &c->trans, NULL);
1914 EXPECT_EQ(net::OK, c->result);
1916 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1918 // Just to make sure that everything is still pending.
1919 base::MessageLoop::current()->RunUntilIdle();
1921 // The request should be creating the disk cache.
1922 EXPECT_FALSE(c->callback.have_result());
1924 // We cannot call FinishCreation because the factory itself will go away with
1925 // the cache, so grab the callback and attempt to use it.
1926 net::CompletionCallback callback = factory->callback();
1927 disk_cache::Backend** backend = factory->backend();
1929 cache.reset();
1930 base::MessageLoop::current()->RunUntilIdle();
1932 *backend = NULL;
1933 callback.Run(net::ERR_ABORTED);
1936 // Tests that we can delete the cache while creating the backend, from within
1937 // one of the callbacks.
1938 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1939 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1940 MockHttpCache* cache = new MockHttpCache(factory);
1942 DeleteCacheCompletionCallback cb(cache);
1943 disk_cache::Backend* backend;
1944 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1945 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1947 // Now let's queue a regular transaction
1948 MockHttpRequest request(kSimpleGET_Transaction);
1950 scoped_ptr<Context> c(new Context());
1951 c->result = cache->http_cache()->CreateTransaction(
1952 net::DEFAULT_PRIORITY, &c->trans, NULL);
1953 EXPECT_EQ(net::OK, c->result);
1955 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1957 // And another direct backend request.
1958 net::TestCompletionCallback cb2;
1959 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1960 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1962 // Just to make sure that everything is still pending.
1963 base::MessageLoop::current()->RunUntilIdle();
1965 // The request should be queued.
1966 EXPECT_FALSE(c->callback.have_result());
1968 // Generate the callback.
1969 factory->FinishCreation();
1970 rv = cb.WaitForResult();
1972 // The cache should be gone by now.
1973 base::MessageLoop::current()->RunUntilIdle();
1974 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1975 EXPECT_FALSE(cb2.have_result());
1978 TEST(HttpCache, TypicalGET_ConditionalRequest) {
1979 MockHttpCache cache;
1981 // write to the cache
1982 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1984 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1985 EXPECT_EQ(0, cache.disk_cache()->open_count());
1986 EXPECT_EQ(1, cache.disk_cache()->create_count());
1988 // Get the same URL again, but this time we expect it to result
1989 // in a conditional request.
1990 net::CapturingBoundNetLog log;
1991 net::LoadTimingInfo load_timing_info;
1992 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1993 log.bound(), &load_timing_info);
1995 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1996 EXPECT_EQ(1, cache.disk_cache()->open_count());
1997 EXPECT_EQ(1, cache.disk_cache()->create_count());
1998 TestLoadTimingNetworkRequest(load_timing_info);
2001 static void ETagGet_ConditionalRequest_Handler(
2002 const net::HttpRequestInfo* request,
2003 std::string* response_status,
2004 std::string* response_headers,
2005 std::string* response_data) {
2006 EXPECT_TRUE(
2007 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2008 response_status->assign("HTTP/1.1 304 Not Modified");
2009 response_headers->assign(kETagGET_Transaction.response_headers);
2010 response_data->clear();
2013 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2014 MockHttpCache cache;
2016 ScopedMockTransaction transaction(kETagGET_Transaction);
2018 // write to the cache
2019 RunTransactionTest(cache.http_cache(), transaction);
2021 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2022 EXPECT_EQ(0, cache.disk_cache()->open_count());
2023 EXPECT_EQ(1, cache.disk_cache()->create_count());
2025 // Get the same URL again, but this time we expect it to result
2026 // in a conditional request.
2027 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2028 transaction.handler = ETagGet_ConditionalRequest_Handler;
2029 net::CapturingBoundNetLog log;
2030 net::LoadTimingInfo load_timing_info;
2031 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2032 &load_timing_info);
2034 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2035 EXPECT_EQ(1, cache.disk_cache()->open_count());
2036 EXPECT_EQ(1, cache.disk_cache()->create_count());
2037 TestLoadTimingNetworkRequest(load_timing_info);
2040 class RevalidationServer {
2041 public:
2042 RevalidationServer() {
2043 s_etag_used_ = false;
2044 s_last_modified_used_ = false;
2047 bool EtagUsed() { return s_etag_used_; }
2048 bool LastModifiedUsed() { return s_last_modified_used_; }
2050 static void Handler(const net::HttpRequestInfo* request,
2051 std::string* response_status,
2052 std::string* response_headers,
2053 std::string* response_data);
2055 private:
2056 static bool s_etag_used_;
2057 static bool s_last_modified_used_;
2059 bool RevalidationServer::s_etag_used_ = false;
2060 bool RevalidationServer::s_last_modified_used_ = false;
2062 void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2063 std::string* response_status,
2064 std::string* response_headers,
2065 std::string* response_data) {
2066 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2067 s_etag_used_ = true;
2069 if (request->extra_headers.HasHeader(
2070 net::HttpRequestHeaders::kIfModifiedSince)) {
2071 s_last_modified_used_ = true;
2074 if (s_etag_used_ || s_last_modified_used_) {
2075 response_status->assign("HTTP/1.1 304 Not Modified");
2076 response_headers->assign(kTypicalGET_Transaction.response_headers);
2077 response_data->clear();
2078 } else {
2079 response_status->assign(kTypicalGET_Transaction.status);
2080 response_headers->assign(kTypicalGET_Transaction.response_headers);
2081 response_data->assign(kTypicalGET_Transaction.data);
2085 // Tests revalidation after a vary match.
2086 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2087 MockHttpCache cache;
2089 // Write to the cache.
2090 MockTransaction transaction(kTypicalGET_Transaction);
2091 transaction.request_headers = "Foo: bar\r\n";
2092 transaction.response_headers =
2093 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2094 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2095 "Etag: \"foopy\"\n"
2096 "Cache-Control: max-age=0\n"
2097 "Vary: Foo\n";
2098 AddMockTransaction(&transaction);
2099 RunTransactionTest(cache.http_cache(), transaction);
2101 // Read from the cache.
2102 RevalidationServer server;
2103 transaction.handler = server.Handler;
2104 net::CapturingBoundNetLog log;
2105 net::LoadTimingInfo load_timing_info;
2106 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2107 &load_timing_info);
2109 EXPECT_TRUE(server.EtagUsed());
2110 EXPECT_TRUE(server.LastModifiedUsed());
2111 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2112 EXPECT_EQ(1, cache.disk_cache()->open_count());
2113 EXPECT_EQ(1, cache.disk_cache()->create_count());
2114 TestLoadTimingNetworkRequest(load_timing_info);
2115 RemoveMockTransaction(&transaction);
2118 // Tests revalidation after a vary mismatch if etag is present.
2119 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2120 MockHttpCache cache;
2122 // Write to the cache.
2123 MockTransaction transaction(kTypicalGET_Transaction);
2124 transaction.request_headers = "Foo: bar\r\n";
2125 transaction.response_headers =
2126 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2127 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2128 "Etag: \"foopy\"\n"
2129 "Cache-Control: max-age=0\n"
2130 "Vary: Foo\n";
2131 AddMockTransaction(&transaction);
2132 RunTransactionTest(cache.http_cache(), transaction);
2134 // Read from the cache and revalidate the entry.
2135 RevalidationServer server;
2136 transaction.handler = server.Handler;
2137 transaction.request_headers = "Foo: none\r\n";
2138 net::CapturingBoundNetLog log;
2139 net::LoadTimingInfo load_timing_info;
2140 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2141 &load_timing_info);
2143 EXPECT_TRUE(server.EtagUsed());
2144 EXPECT_FALSE(server.LastModifiedUsed());
2145 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2146 EXPECT_EQ(1, cache.disk_cache()->open_count());
2147 EXPECT_EQ(1, cache.disk_cache()->create_count());
2148 TestLoadTimingNetworkRequest(load_timing_info);
2149 RemoveMockTransaction(&transaction);
2152 // Tests lack of revalidation after a vary mismatch and no etag.
2153 TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2154 MockHttpCache cache;
2156 // Write to the cache.
2157 MockTransaction transaction(kTypicalGET_Transaction);
2158 transaction.request_headers = "Foo: bar\r\n";
2159 transaction.response_headers =
2160 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2161 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2162 "Cache-Control: max-age=0\n"
2163 "Vary: Foo\n";
2164 AddMockTransaction(&transaction);
2165 RunTransactionTest(cache.http_cache(), transaction);
2167 // Read from the cache and don't revalidate the entry.
2168 RevalidationServer server;
2169 transaction.handler = server.Handler;
2170 transaction.request_headers = "Foo: none\r\n";
2171 net::CapturingBoundNetLog log;
2172 net::LoadTimingInfo load_timing_info;
2173 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2174 &load_timing_info);
2176 EXPECT_FALSE(server.EtagUsed());
2177 EXPECT_FALSE(server.LastModifiedUsed());
2178 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2179 EXPECT_EQ(1, cache.disk_cache()->open_count());
2180 EXPECT_EQ(1, cache.disk_cache()->create_count());
2181 TestLoadTimingNetworkRequest(load_timing_info);
2182 RemoveMockTransaction(&transaction);
2185 static void ETagGet_UnconditionalRequest_Handler(
2186 const net::HttpRequestInfo* request,
2187 std::string* response_status,
2188 std::string* response_headers,
2189 std::string* response_data) {
2190 EXPECT_FALSE(
2191 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2194 TEST(HttpCache, ETagGET_Http10) {
2195 MockHttpCache cache;
2197 ScopedMockTransaction transaction(kETagGET_Transaction);
2198 transaction.status = "HTTP/1.0 200 OK";
2200 // Write to the cache.
2201 RunTransactionTest(cache.http_cache(), transaction);
2203 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2204 EXPECT_EQ(0, cache.disk_cache()->open_count());
2205 EXPECT_EQ(1, cache.disk_cache()->create_count());
2207 // Get the same URL again, without generating a conditional request.
2208 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2209 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2210 RunTransactionTest(cache.http_cache(), transaction);
2212 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2213 EXPECT_EQ(1, cache.disk_cache()->open_count());
2214 EXPECT_EQ(1, cache.disk_cache()->create_count());
2217 TEST(HttpCache, ETagGET_Http10_Range) {
2218 MockHttpCache cache;
2220 ScopedMockTransaction transaction(kETagGET_Transaction);
2221 transaction.status = "HTTP/1.0 200 OK";
2223 // Write to the cache.
2224 RunTransactionTest(cache.http_cache(), transaction);
2226 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2227 EXPECT_EQ(0, cache.disk_cache()->open_count());
2228 EXPECT_EQ(1, cache.disk_cache()->create_count());
2230 // Get the same URL again, but use a byte range request.
2231 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2232 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2233 transaction.request_headers = "Range: bytes = 5-\r\n";
2234 RunTransactionTest(cache.http_cache(), transaction);
2236 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2237 EXPECT_EQ(1, cache.disk_cache()->open_count());
2238 EXPECT_EQ(2, cache.disk_cache()->create_count());
2241 static void ETagGet_ConditionalRequest_NoStore_Handler(
2242 const net::HttpRequestInfo* request,
2243 std::string* response_status,
2244 std::string* response_headers,
2245 std::string* response_data) {
2246 EXPECT_TRUE(
2247 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2248 response_status->assign("HTTP/1.1 304 Not Modified");
2249 response_headers->assign("Cache-Control: no-store\n");
2250 response_data->clear();
2253 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2254 MockHttpCache cache;
2256 ScopedMockTransaction transaction(kETagGET_Transaction);
2258 // Write to the cache.
2259 RunTransactionTest(cache.http_cache(), transaction);
2261 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2262 EXPECT_EQ(0, cache.disk_cache()->open_count());
2263 EXPECT_EQ(1, cache.disk_cache()->create_count());
2265 // Get the same URL again, but this time we expect it to result
2266 // in a conditional request.
2267 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2268 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2269 RunTransactionTest(cache.http_cache(), transaction);
2271 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2272 EXPECT_EQ(1, cache.disk_cache()->open_count());
2273 EXPECT_EQ(1, cache.disk_cache()->create_count());
2275 ScopedMockTransaction transaction2(kETagGET_Transaction);
2277 // Write to the cache again. This should create a new entry.
2278 RunTransactionTest(cache.http_cache(), transaction2);
2280 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2281 EXPECT_EQ(1, cache.disk_cache()->open_count());
2282 EXPECT_EQ(2, cache.disk_cache()->create_count());
2285 // Helper that does 4 requests using HttpCache:
2287 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2288 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2289 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2290 // be returned.
2291 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2292 // returned.
2293 static void ConditionalizedRequestUpdatesCacheHelper(
2294 const Response& net_response_1,
2295 const Response& net_response_2,
2296 const Response& cached_response_2,
2297 const char* extra_request_headers) {
2298 MockHttpCache cache;
2300 // The URL we will be requesting.
2301 const char* kUrl = "http://foobar.com/main.css";
2303 // Junk network response.
2304 static const Response kUnexpectedResponse = {
2305 "HTTP/1.1 500 Unexpected",
2306 "Server: unexpected_header",
2307 "unexpected body"
2310 // We will control the network layer's responses for |kUrl| using
2311 // |mock_network_response|.
2312 MockTransaction mock_network_response = { 0 };
2313 mock_network_response.url = kUrl;
2314 AddMockTransaction(&mock_network_response);
2316 // Request |kUrl| for the first time. It should hit the network and
2317 // receive |kNetResponse1|, which it saves into the HTTP cache.
2319 MockTransaction request = { 0 };
2320 request.url = kUrl;
2321 request.method = "GET";
2322 request.request_headers = "";
2324 net_response_1.AssignTo(&mock_network_response); // Network mock.
2325 net_response_1.AssignTo(&request); // Expected result.
2327 std::string response_headers;
2328 RunTransactionTestWithResponse(
2329 cache.http_cache(), request, &response_headers);
2331 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2332 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2333 EXPECT_EQ(0, cache.disk_cache()->open_count());
2334 EXPECT_EQ(1, cache.disk_cache()->create_count());
2336 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2337 // cache, so we don't hit the network.
2339 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2341 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2342 net_response_1.AssignTo(&request); // Expected result.
2344 RunTransactionTestWithResponse(
2345 cache.http_cache(), request, &response_headers);
2347 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2348 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2349 EXPECT_EQ(1, cache.disk_cache()->open_count());
2350 EXPECT_EQ(1, cache.disk_cache()->create_count());
2352 // Request |kUrl| yet again, but this time give the request an
2353 // "If-Modified-Since" header. This will cause the request to re-hit the
2354 // network. However now the network response is going to be
2355 // different -- this simulates a change made to the CSS file.
2357 request.request_headers = extra_request_headers;
2358 request.load_flags = net::LOAD_NORMAL;
2360 net_response_2.AssignTo(&mock_network_response); // Network mock.
2361 net_response_2.AssignTo(&request); // Expected result.
2363 RunTransactionTestWithResponse(
2364 cache.http_cache(), request, &response_headers);
2366 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2367 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2368 EXPECT_EQ(1, cache.disk_cache()->open_count());
2369 EXPECT_EQ(1, cache.disk_cache()->create_count());
2371 // Finally, request |kUrl| again. This request should be serviced from
2372 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2373 // and NOT |kNetResponse1|. The previous step should have replaced the
2374 // value in the cache with the modified response.
2376 request.request_headers = "";
2377 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2379 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2380 cached_response_2.AssignTo(&request); // Expected result.
2382 RunTransactionTestWithResponse(
2383 cache.http_cache(), request, &response_headers);
2385 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2386 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2387 EXPECT_EQ(2, cache.disk_cache()->open_count());
2388 EXPECT_EQ(1, cache.disk_cache()->create_count());
2390 RemoveMockTransaction(&mock_network_response);
2393 // Check that when an "if-modified-since" header is attached
2394 // to the request, the result still updates the cached entry.
2395 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2396 // First network response for |kUrl|.
2397 static const Response kNetResponse1 = {
2398 "HTTP/1.1 200 OK",
2399 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2400 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2401 "body1"
2404 // Second network response for |kUrl|.
2405 static const Response kNetResponse2 = {
2406 "HTTP/1.1 200 OK",
2407 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2408 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2409 "body2"
2412 const char* extra_headers =
2413 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2415 ConditionalizedRequestUpdatesCacheHelper(
2416 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2419 // Check that when an "if-none-match" header is attached
2420 // to the request, the result updates the cached entry.
2421 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2422 // First network response for |kUrl|.
2423 static const Response kNetResponse1 = {
2424 "HTTP/1.1 200 OK",
2425 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2426 "Etag: \"ETAG1\"\n"
2427 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2428 "body1"
2431 // Second network response for |kUrl|.
2432 static const Response kNetResponse2 = {
2433 "HTTP/1.1 200 OK",
2434 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2435 "Etag: \"ETAG2\"\n"
2436 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2437 "body2"
2440 const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
2442 ConditionalizedRequestUpdatesCacheHelper(
2443 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2446 // Check that when an "if-modified-since" header is attached
2447 // to a request, the 304 (not modified result) result updates the cached
2448 // headers, and the 304 response is returned rather than the cached response.
2449 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2450 // First network response for |kUrl|.
2451 static const Response kNetResponse1 = {
2452 "HTTP/1.1 200 OK",
2453 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2454 "Server: server1\n"
2455 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2456 "body1"
2459 // Second network response for |kUrl|.
2460 static const Response kNetResponse2 = {
2461 "HTTP/1.1 304 Not Modified",
2462 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2463 "Server: server2\n"
2464 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2468 static const Response kCachedResponse2 = {
2469 "HTTP/1.1 200 OK",
2470 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2471 "Server: server2\n"
2472 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2473 "body1"
2476 const char* extra_headers =
2477 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2479 ConditionalizedRequestUpdatesCacheHelper(
2480 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2483 // Test that when doing an externally conditionalized if-modified-since
2484 // and there is no corresponding cache entry, a new cache entry is NOT
2485 // created (304 response).
2486 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2487 MockHttpCache cache;
2489 const char* kUrl = "http://foobar.com/main.css";
2491 static const Response kNetResponse = {
2492 "HTTP/1.1 304 Not Modified",
2493 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2494 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2498 const char* kExtraRequestHeaders =
2499 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2501 // We will control the network layer's responses for |kUrl| using
2502 // |mock_network_response|.
2503 MockTransaction mock_network_response = { 0 };
2504 mock_network_response.url = kUrl;
2505 AddMockTransaction(&mock_network_response);
2507 MockTransaction request = { 0 };
2508 request.url = kUrl;
2509 request.method = "GET";
2510 request.request_headers = kExtraRequestHeaders;
2512 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2513 kNetResponse.AssignTo(&request); // Expected result.
2515 std::string response_headers;
2516 RunTransactionTestWithResponse(
2517 cache.http_cache(), request, &response_headers);
2519 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2520 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2521 EXPECT_EQ(0, cache.disk_cache()->open_count());
2522 EXPECT_EQ(0, cache.disk_cache()->create_count());
2524 RemoveMockTransaction(&mock_network_response);
2527 // Test that when doing an externally conditionalized if-modified-since
2528 // and there is no corresponding cache entry, a new cache entry is NOT
2529 // created (200 response).
2530 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2531 MockHttpCache cache;
2533 const char* kUrl = "http://foobar.com/main.css";
2535 static const Response kNetResponse = {
2536 "HTTP/1.1 200 OK",
2537 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2538 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2539 "foobar!!!"
2542 const char* kExtraRequestHeaders =
2543 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2545 // We will control the network layer's responses for |kUrl| using
2546 // |mock_network_response|.
2547 MockTransaction mock_network_response = { 0 };
2548 mock_network_response.url = kUrl;
2549 AddMockTransaction(&mock_network_response);
2551 MockTransaction request = { 0 };
2552 request.url = kUrl;
2553 request.method = "GET";
2554 request.request_headers = kExtraRequestHeaders;
2556 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2557 kNetResponse.AssignTo(&request); // Expected result.
2559 std::string response_headers;
2560 RunTransactionTestWithResponse(
2561 cache.http_cache(), request, &response_headers);
2563 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2564 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2565 EXPECT_EQ(0, cache.disk_cache()->open_count());
2566 EXPECT_EQ(0, cache.disk_cache()->create_count());
2568 RemoveMockTransaction(&mock_network_response);
2571 // Test that when doing an externally conditionalized if-modified-since
2572 // if the date does not match the cache entry's last-modified date,
2573 // then we do NOT use the response (304) to update the cache.
2574 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2575 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2576 static const Response kNetResponse1 = {
2577 "HTTP/1.1 200 OK",
2578 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2579 "Server: server1\n"
2580 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2581 "body1"
2584 // Second network response for |kUrl|.
2585 static const Response kNetResponse2 = {
2586 "HTTP/1.1 304 Not Modified",
2587 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2588 "Server: server2\n"
2589 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2593 // This is two days in the future from the original response's last-modified
2594 // date!
2595 const char* kExtraRequestHeaders =
2596 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2598 ConditionalizedRequestUpdatesCacheHelper(
2599 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2602 // Test that when doing an externally conditionalized if-none-match
2603 // if the etag does not match the cache entry's etag, then we do not use the
2604 // response (304) to update the cache.
2605 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2606 static const Response kNetResponse1 = {
2607 "HTTP/1.1 200 OK",
2608 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2609 "Etag: \"Foo1\"\n"
2610 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2611 "body1"
2614 // Second network response for |kUrl|.
2615 static const Response kNetResponse2 = {
2616 "HTTP/1.1 304 Not Modified",
2617 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2618 "Etag: \"Foo2\"\n"
2619 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2623 // Different etag from original response.
2624 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
2626 ConditionalizedRequestUpdatesCacheHelper(
2627 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2630 // Test that doing an externally conditionalized request with both if-none-match
2631 // and if-modified-since updates the cache.
2632 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2633 static const Response kNetResponse1 = {
2634 "HTTP/1.1 200 OK",
2635 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2636 "Etag: \"Foo1\"\n"
2637 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2638 "body1"
2641 // Second network response for |kUrl|.
2642 static const Response kNetResponse2 = {
2643 "HTTP/1.1 200 OK",
2644 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2645 "Etag: \"Foo2\"\n"
2646 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2647 "body2"
2650 const char* kExtraRequestHeaders =
2651 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2652 "If-None-Match: \"Foo1\"\r\n";
2654 ConditionalizedRequestUpdatesCacheHelper(
2655 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2658 // Test that doing an externally conditionalized request with both if-none-match
2659 // and if-modified-since does not update the cache with only one match.
2660 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2661 static const Response kNetResponse1 = {
2662 "HTTP/1.1 200 OK",
2663 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2664 "Etag: \"Foo1\"\n"
2665 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2666 "body1"
2669 // Second network response for |kUrl|.
2670 static const Response kNetResponse2 = {
2671 "HTTP/1.1 200 OK",
2672 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2673 "Etag: \"Foo2\"\n"
2674 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2675 "body2"
2678 // The etag doesn't match what we have stored.
2679 const char* kExtraRequestHeaders =
2680 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2681 "If-None-Match: \"Foo2\"\r\n";
2683 ConditionalizedRequestUpdatesCacheHelper(
2684 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2687 // Test that doing an externally conditionalized request with both if-none-match
2688 // and if-modified-since does not update the cache with only one match.
2689 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2690 static const Response kNetResponse1 = {
2691 "HTTP/1.1 200 OK",
2692 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2693 "Etag: \"Foo1\"\n"
2694 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2695 "body1"
2698 // Second network response for |kUrl|.
2699 static const Response kNetResponse2 = {
2700 "HTTP/1.1 200 OK",
2701 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2702 "Etag: \"Foo2\"\n"
2703 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2704 "body2"
2707 // The modification date doesn't match what we have stored.
2708 const char* kExtraRequestHeaders =
2709 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2710 "If-None-Match: \"Foo1\"\r\n";
2712 ConditionalizedRequestUpdatesCacheHelper(
2713 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2716 TEST(HttpCache, UrlContainingHash) {
2717 MockHttpCache cache;
2719 // Do a typical GET request -- should write an entry into our cache.
2720 MockTransaction trans(kTypicalGET_Transaction);
2721 RunTransactionTest(cache.http_cache(), trans);
2723 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2724 EXPECT_EQ(0, cache.disk_cache()->open_count());
2725 EXPECT_EQ(1, cache.disk_cache()->create_count());
2727 // Request the same URL, but this time with a reference section (hash).
2728 // Since the cache key strips the hash sections, this should be a cache hit.
2729 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2730 trans.url = url_with_hash.c_str();
2731 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2733 RunTransactionTest(cache.http_cache(), trans);
2735 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2736 EXPECT_EQ(1, cache.disk_cache()->open_count());
2737 EXPECT_EQ(1, cache.disk_cache()->create_count());
2740 // Tests that we skip the cache for POST requests that do not have an upload
2741 // identifier.
2742 TEST(HttpCache, SimplePOST_SkipsCache) {
2743 MockHttpCache cache;
2745 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2747 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2748 EXPECT_EQ(0, cache.disk_cache()->open_count());
2749 EXPECT_EQ(0, cache.disk_cache()->create_count());
2752 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2753 MockHttpCache cache;
2755 MockTransaction transaction(kSimplePOST_Transaction);
2756 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2758 MockHttpRequest request(transaction);
2759 net::TestCompletionCallback callback;
2761 scoped_ptr<net::HttpTransaction> trans;
2762 int rv = cache.http_cache()->CreateTransaction(
2763 net::DEFAULT_PRIORITY, &trans, NULL);
2764 EXPECT_EQ(net::OK, rv);
2765 ASSERT_TRUE(trans.get());
2767 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
2768 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
2770 trans.reset();
2772 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2773 EXPECT_EQ(0, cache.disk_cache()->open_count());
2774 EXPECT_EQ(0, cache.disk_cache()->create_count());
2777 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2778 MockHttpCache cache;
2780 // Test that we hit the cache for POST requests.
2782 MockTransaction transaction(kSimplePOST_Transaction);
2784 const int64 kUploadId = 1; // Just a dummy value.
2786 ScopedVector<net::UploadElementReader> element_readers;
2787 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2788 net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
2789 MockHttpRequest request(transaction);
2790 request.upload_data_stream = &upload_data_stream;
2792 // Populate the cache.
2793 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2795 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2796 EXPECT_EQ(0, cache.disk_cache()->open_count());
2797 EXPECT_EQ(1, cache.disk_cache()->create_count());
2799 // Load from cache.
2800 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2801 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2803 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2804 EXPECT_EQ(1, cache.disk_cache()->open_count());
2805 EXPECT_EQ(1, cache.disk_cache()->create_count());
2808 // Test that we don't hit the cache for POST requests if there is a byte range.
2809 TEST(HttpCache, SimplePOST_WithRanges) {
2810 MockHttpCache cache;
2812 MockTransaction transaction(kSimplePOST_Transaction);
2813 transaction.request_headers = "Range: bytes = 0-4\r\n";
2815 const int64 kUploadId = 1; // Just a dummy value.
2817 ScopedVector<net::UploadElementReader> element_readers;
2818 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2819 net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
2821 MockHttpRequest request(transaction);
2822 request.upload_data_stream = &upload_data_stream;
2824 // Attempt to populate the cache.
2825 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2827 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2828 EXPECT_EQ(0, cache.disk_cache()->open_count());
2829 EXPECT_EQ(0, cache.disk_cache()->create_count());
2832 // Tests that a POST is cached separately from a previously cached GET.
2833 TEST(HttpCache, SimplePOST_SeparateCache) {
2834 MockHttpCache cache;
2836 ScopedVector<net::UploadElementReader> element_readers;
2837 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2838 net::UploadDataStream upload_data_stream(&element_readers, 1);
2840 MockTransaction transaction(kSimplePOST_Transaction);
2841 MockHttpRequest req1(transaction);
2842 req1.upload_data_stream = &upload_data_stream;
2844 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2846 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2847 EXPECT_EQ(0, cache.disk_cache()->open_count());
2848 EXPECT_EQ(1, cache.disk_cache()->create_count());
2850 transaction.method = "GET";
2851 MockHttpRequest req2(transaction);
2853 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2855 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2856 EXPECT_EQ(0, cache.disk_cache()->open_count());
2857 EXPECT_EQ(2, cache.disk_cache()->create_count());
2860 // Tests that a successful POST invalidates a previously cached GET.
2861 TEST(HttpCache, SimplePOST_Invalidate_205) {
2862 MockHttpCache cache;
2864 MockTransaction transaction(kSimpleGET_Transaction);
2865 AddMockTransaction(&transaction);
2866 MockHttpRequest req1(transaction);
2868 // Attempt to populate the cache.
2869 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2871 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2872 EXPECT_EQ(0, cache.disk_cache()->open_count());
2873 EXPECT_EQ(1, cache.disk_cache()->create_count());
2875 ScopedVector<net::UploadElementReader> element_readers;
2876 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2877 net::UploadDataStream upload_data_stream(&element_readers, 1);
2879 transaction.method = "POST";
2880 transaction.status = "HTTP/1.1 205 No Content";
2881 MockHttpRequest req2(transaction);
2882 req2.upload_data_stream = &upload_data_stream;
2884 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2886 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2887 EXPECT_EQ(0, cache.disk_cache()->open_count());
2888 EXPECT_EQ(2, cache.disk_cache()->create_count());
2890 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2892 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2893 EXPECT_EQ(0, cache.disk_cache()->open_count());
2894 EXPECT_EQ(3, cache.disk_cache()->create_count());
2895 RemoveMockTransaction(&transaction);
2898 // Tests that we don't invalidate entries as a result of a failed POST.
2899 TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2900 MockHttpCache cache;
2902 MockTransaction transaction(kSimpleGET_Transaction);
2903 AddMockTransaction(&transaction);
2904 MockHttpRequest req1(transaction);
2906 // Attempt to populate the cache.
2907 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2909 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2910 EXPECT_EQ(0, cache.disk_cache()->open_count());
2911 EXPECT_EQ(1, cache.disk_cache()->create_count());
2913 ScopedVector<net::UploadElementReader> element_readers;
2914 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2915 net::UploadDataStream upload_data_stream(&element_readers, 1);
2917 transaction.method = "POST";
2918 transaction.status = "HTTP/1.1 100 Continue";
2919 MockHttpRequest req2(transaction);
2920 req2.upload_data_stream = &upload_data_stream;
2922 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2924 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2925 EXPECT_EQ(0, cache.disk_cache()->open_count());
2926 EXPECT_EQ(2, cache.disk_cache()->create_count());
2928 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2930 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2931 EXPECT_EQ(1, cache.disk_cache()->open_count());
2932 EXPECT_EQ(2, cache.disk_cache()->create_count());
2933 RemoveMockTransaction(&transaction);
2936 // Tests that we do not cache the response of a PUT.
2937 TEST(HttpCache, SimplePUT_Miss) {
2938 MockHttpCache cache;
2940 MockTransaction transaction(kSimplePOST_Transaction);
2941 transaction.method = "PUT";
2943 ScopedVector<net::UploadElementReader> element_readers;
2944 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2945 net::UploadDataStream upload_data_stream(&element_readers, 0);
2947 MockHttpRequest request(transaction);
2948 request.upload_data_stream = &upload_data_stream;
2950 // Attempt to populate the cache.
2951 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2953 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2954 EXPECT_EQ(0, cache.disk_cache()->open_count());
2955 EXPECT_EQ(0, cache.disk_cache()->create_count());
2958 // Tests that we invalidate entries as a result of a PUT.
2959 TEST(HttpCache, SimplePUT_Invalidate) {
2960 MockHttpCache cache;
2962 MockTransaction transaction(kSimpleGET_Transaction);
2963 MockHttpRequest req1(transaction);
2965 // Attempt to populate the cache.
2966 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2968 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2969 EXPECT_EQ(0, cache.disk_cache()->open_count());
2970 EXPECT_EQ(1, cache.disk_cache()->create_count());
2972 ScopedVector<net::UploadElementReader> element_readers;
2973 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2974 net::UploadDataStream upload_data_stream(&element_readers, 0);
2976 transaction.method = "PUT";
2977 MockHttpRequest req2(transaction);
2978 req2.upload_data_stream = &upload_data_stream;
2980 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2982 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2983 EXPECT_EQ(1, cache.disk_cache()->open_count());
2984 EXPECT_EQ(1, cache.disk_cache()->create_count());
2986 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2988 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2989 EXPECT_EQ(1, cache.disk_cache()->open_count());
2990 EXPECT_EQ(2, cache.disk_cache()->create_count());
2993 // Tests that we invalidate entries as a result of a PUT.
2994 TEST(HttpCache, SimplePUT_Invalidate_305) {
2995 MockHttpCache cache;
2997 MockTransaction transaction(kSimpleGET_Transaction);
2998 AddMockTransaction(&transaction);
2999 MockHttpRequest req1(transaction);
3001 // Attempt to populate the cache.
3002 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3004 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3005 EXPECT_EQ(0, cache.disk_cache()->open_count());
3006 EXPECT_EQ(1, cache.disk_cache()->create_count());
3008 ScopedVector<net::UploadElementReader> element_readers;
3009 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3010 net::UploadDataStream upload_data_stream(&element_readers, 0);
3012 transaction.method = "PUT";
3013 transaction.status = "HTTP/1.1 305 Use Proxy";
3014 MockHttpRequest req2(transaction);
3015 req2.upload_data_stream = &upload_data_stream;
3017 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3019 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3020 EXPECT_EQ(1, cache.disk_cache()->open_count());
3021 EXPECT_EQ(1, cache.disk_cache()->create_count());
3023 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3025 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3026 EXPECT_EQ(1, cache.disk_cache()->open_count());
3027 EXPECT_EQ(2, cache.disk_cache()->create_count());
3028 RemoveMockTransaction(&transaction);
3031 // Tests that we don't invalidate entries as a result of a failed PUT.
3032 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3033 MockHttpCache cache;
3035 MockTransaction transaction(kSimpleGET_Transaction);
3036 AddMockTransaction(&transaction);
3037 MockHttpRequest req1(transaction);
3039 // Attempt to populate the cache.
3040 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3042 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3043 EXPECT_EQ(0, cache.disk_cache()->open_count());
3044 EXPECT_EQ(1, cache.disk_cache()->create_count());
3046 ScopedVector<net::UploadElementReader> element_readers;
3047 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3048 net::UploadDataStream upload_data_stream(&element_readers, 0);
3050 transaction.method = "PUT";
3051 transaction.status = "HTTP/1.1 404 Not Found";
3052 MockHttpRequest req2(transaction);
3053 req2.upload_data_stream = &upload_data_stream;
3055 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3057 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3058 EXPECT_EQ(1, cache.disk_cache()->open_count());
3059 EXPECT_EQ(1, cache.disk_cache()->create_count());
3061 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3063 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3064 EXPECT_EQ(2, cache.disk_cache()->open_count());
3065 EXPECT_EQ(1, cache.disk_cache()->create_count());
3066 RemoveMockTransaction(&transaction);
3069 // Tests that we do not cache the response of a DELETE.
3070 TEST(HttpCache, SimpleDELETE_Miss) {
3071 MockHttpCache cache;
3073 MockTransaction transaction(kSimplePOST_Transaction);
3074 transaction.method = "DELETE";
3076 ScopedVector<net::UploadElementReader> element_readers;
3077 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3078 net::UploadDataStream upload_data_stream(&element_readers, 0);
3080 MockHttpRequest request(transaction);
3081 request.upload_data_stream = &upload_data_stream;
3083 // Attempt to populate the cache.
3084 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3086 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3087 EXPECT_EQ(0, cache.disk_cache()->open_count());
3088 EXPECT_EQ(0, cache.disk_cache()->create_count());
3091 // Tests that we invalidate entries as a result of a DELETE.
3092 TEST(HttpCache, SimpleDELETE_Invalidate) {
3093 MockHttpCache cache;
3095 MockTransaction transaction(kSimpleGET_Transaction);
3096 MockHttpRequest req1(transaction);
3098 // Attempt to populate the cache.
3099 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3101 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3102 EXPECT_EQ(0, cache.disk_cache()->open_count());
3103 EXPECT_EQ(1, cache.disk_cache()->create_count());
3105 ScopedVector<net::UploadElementReader> element_readers;
3106 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3107 net::UploadDataStream upload_data_stream(&element_readers, 0);
3109 transaction.method = "DELETE";
3110 MockHttpRequest req2(transaction);
3111 req2.upload_data_stream = &upload_data_stream;
3113 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3115 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3116 EXPECT_EQ(1, cache.disk_cache()->open_count());
3117 EXPECT_EQ(1, cache.disk_cache()->create_count());
3119 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3121 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3122 EXPECT_EQ(1, cache.disk_cache()->open_count());
3123 EXPECT_EQ(2, cache.disk_cache()->create_count());
3126 // Tests that we invalidate entries as a result of a DELETE.
3127 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3128 MockHttpCache cache;
3130 MockTransaction transaction(kSimpleGET_Transaction);
3131 AddMockTransaction(&transaction);
3133 // Attempt to populate the cache.
3134 RunTransactionTest(cache.http_cache(), transaction);
3136 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3137 EXPECT_EQ(0, cache.disk_cache()->open_count());
3138 EXPECT_EQ(1, cache.disk_cache()->create_count());
3140 transaction.method = "DELETE";
3141 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3143 RunTransactionTest(cache.http_cache(), transaction);
3145 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3146 EXPECT_EQ(1, cache.disk_cache()->open_count());
3147 EXPECT_EQ(1, cache.disk_cache()->create_count());
3149 transaction.method = "GET";
3150 RunTransactionTest(cache.http_cache(), transaction);
3152 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3153 EXPECT_EQ(1, cache.disk_cache()->open_count());
3154 EXPECT_EQ(2, cache.disk_cache()->create_count());
3155 RemoveMockTransaction(&transaction);
3158 // Tests that we don't invalidate entries as a result of a failed DELETE.
3159 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3160 MockHttpCache cache;
3162 MockTransaction transaction(kSimpleGET_Transaction);
3163 AddMockTransaction(&transaction);
3165 // Attempt to populate the cache.
3166 RunTransactionTest(cache.http_cache(), transaction);
3168 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3169 EXPECT_EQ(0, cache.disk_cache()->open_count());
3170 EXPECT_EQ(1, cache.disk_cache()->create_count());
3172 transaction.method = "DELETE";
3173 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3175 RunTransactionTest(cache.http_cache(), transaction);
3177 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3178 EXPECT_EQ(1, cache.disk_cache()->open_count());
3179 EXPECT_EQ(1, cache.disk_cache()->create_count());
3181 transaction.method = "GET";
3182 transaction.status = "HTTP/1.1 200 OK";
3183 RunTransactionTest(cache.http_cache(), transaction);
3185 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3186 EXPECT_EQ(2, cache.disk_cache()->open_count());
3187 EXPECT_EQ(1, cache.disk_cache()->create_count());
3188 RemoveMockTransaction(&transaction);
3191 // Tests that we don't invalidate entries after a failed network transaction.
3192 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3193 MockHttpCache cache;
3195 // Populate the cache.
3196 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3197 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3199 // Fail the network request.
3200 MockTransaction transaction(kSimpleGET_Transaction);
3201 transaction.return_code = net::ERR_FAILED;
3202 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3204 AddMockTransaction(&transaction);
3205 RunTransactionTest(cache.http_cache(), transaction);
3206 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3207 RemoveMockTransaction(&transaction);
3209 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3210 transaction.return_code = net::OK;
3211 AddMockTransaction(&transaction);
3212 RunTransactionTest(cache.http_cache(), transaction);
3214 // Make sure the transaction didn't reach the network.
3215 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3216 RemoveMockTransaction(&transaction);
3219 TEST(HttpCache, RangeGET_SkipsCache) {
3220 MockHttpCache cache;
3222 // Test that we skip the cache for range GET requests. Eventually, we will
3223 // want to cache these, but we'll still have cases where skipping the cache
3224 // makes sense, so we want to make sure that it works properly.
3226 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3228 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3229 EXPECT_EQ(0, cache.disk_cache()->open_count());
3230 EXPECT_EQ(0, cache.disk_cache()->create_count());
3232 MockTransaction transaction(kSimpleGET_Transaction);
3233 transaction.request_headers = "If-None-Match: foo\r\n";
3234 RunTransactionTest(cache.http_cache(), transaction);
3236 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3237 EXPECT_EQ(0, cache.disk_cache()->open_count());
3238 EXPECT_EQ(0, cache.disk_cache()->create_count());
3240 transaction.request_headers =
3241 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3242 RunTransactionTest(cache.http_cache(), transaction);
3244 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3245 EXPECT_EQ(0, cache.disk_cache()->open_count());
3246 EXPECT_EQ(0, cache.disk_cache()->create_count());
3249 // Test that we skip the cache for range requests that include a validation
3250 // header.
3251 TEST(HttpCache, RangeGET_SkipsCache2) {
3252 MockHttpCache cache;
3254 MockTransaction transaction(kRangeGET_Transaction);
3255 transaction.request_headers = "If-None-Match: foo\r\n"
3256 EXTRA_HEADER
3257 "Range: bytes = 40-49\r\n";
3258 RunTransactionTest(cache.http_cache(), transaction);
3260 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3261 EXPECT_EQ(0, cache.disk_cache()->open_count());
3262 EXPECT_EQ(0, cache.disk_cache()->create_count());
3264 transaction.request_headers =
3265 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3266 EXTRA_HEADER
3267 "Range: bytes = 40-49\r\n";
3268 RunTransactionTest(cache.http_cache(), transaction);
3270 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3271 EXPECT_EQ(0, cache.disk_cache()->open_count());
3272 EXPECT_EQ(0, cache.disk_cache()->create_count());
3274 transaction.request_headers = "If-Range: bla\r\n"
3275 EXTRA_HEADER
3276 "Range: bytes = 40-49\r\n";
3277 RunTransactionTest(cache.http_cache(), transaction);
3279 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3280 EXPECT_EQ(0, cache.disk_cache()->open_count());
3281 EXPECT_EQ(0, cache.disk_cache()->create_count());
3284 // Tests that receiving 206 for a regular request is handled correctly.
3285 TEST(HttpCache, GET_Crazy206) {
3286 MockHttpCache cache;
3288 // Write to the cache.
3289 MockTransaction transaction(kRangeGET_TransactionOK);
3290 AddMockTransaction(&transaction);
3291 transaction.request_headers = EXTRA_HEADER;
3292 transaction.handler = NULL;
3293 RunTransactionTest(cache.http_cache(), transaction);
3295 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3296 EXPECT_EQ(0, cache.disk_cache()->open_count());
3297 EXPECT_EQ(1, cache.disk_cache()->create_count());
3299 // This should read again from the net.
3300 RunTransactionTest(cache.http_cache(), transaction);
3302 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3303 EXPECT_EQ(0, cache.disk_cache()->open_count());
3304 EXPECT_EQ(2, cache.disk_cache()->create_count());
3305 RemoveMockTransaction(&transaction);
3308 // Tests that we don't cache partial responses that can't be validated.
3309 TEST(HttpCache, RangeGET_NoStrongValidators) {
3310 MockHttpCache cache;
3311 std::string headers;
3313 // Attempt to write to the cache (40-49).
3314 MockTransaction transaction(kRangeGET_TransactionOK);
3315 AddMockTransaction(&transaction);
3316 transaction.response_headers = "Content-Length: 10\n"
3317 "ETag: w/\"foo\"\n";
3318 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3320 Verify206Response(headers, 40, 49);
3321 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3322 EXPECT_EQ(0, cache.disk_cache()->open_count());
3323 EXPECT_EQ(1, cache.disk_cache()->create_count());
3325 // Now verify that there's no cached data.
3326 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3327 &headers);
3329 Verify206Response(headers, 40, 49);
3330 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3331 EXPECT_EQ(0, cache.disk_cache()->open_count());
3332 EXPECT_EQ(2, cache.disk_cache()->create_count());
3334 RemoveMockTransaction(&transaction);
3337 // Tests that we can cache range requests and fetch random blocks from the
3338 // cache and the network.
3339 TEST(HttpCache, RangeGET_OK) {
3340 MockHttpCache cache;
3341 AddMockTransaction(&kRangeGET_TransactionOK);
3342 std::string headers;
3344 // Write to the cache (40-49).
3345 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3346 &headers);
3348 Verify206Response(headers, 40, 49);
3349 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3350 EXPECT_EQ(0, cache.disk_cache()->open_count());
3351 EXPECT_EQ(1, cache.disk_cache()->create_count());
3353 // Read from the cache (40-49).
3354 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3355 &headers);
3357 Verify206Response(headers, 40, 49);
3358 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3359 EXPECT_EQ(1, cache.disk_cache()->open_count());
3360 EXPECT_EQ(1, cache.disk_cache()->create_count());
3362 // Make sure we are done with the previous transaction.
3363 base::MessageLoop::current()->RunUntilIdle();
3365 // Write to the cache (30-39).
3366 MockTransaction transaction(kRangeGET_TransactionOK);
3367 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3368 transaction.data = "rg: 30-39 ";
3369 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3371 Verify206Response(headers, 30, 39);
3372 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3373 EXPECT_EQ(2, cache.disk_cache()->open_count());
3374 EXPECT_EQ(1, cache.disk_cache()->create_count());
3376 // Make sure we are done with the previous transaction.
3377 base::MessageLoop::current()->RunUntilIdle();
3379 // Write and read from the cache (20-59).
3380 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3381 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3382 net::CapturingBoundNetLog log;
3383 net::LoadTimingInfo load_timing_info;
3384 RunTransactionTestWithResponseAndGetTiming(
3385 cache.http_cache(), transaction, &headers, log.bound(),
3386 &load_timing_info);
3388 Verify206Response(headers, 20, 59);
3389 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3390 EXPECT_EQ(3, cache.disk_cache()->open_count());
3391 EXPECT_EQ(1, cache.disk_cache()->create_count());
3392 TestLoadTimingNetworkRequest(load_timing_info);
3394 RemoveMockTransaction(&kRangeGET_TransactionOK);
3397 // Tests that we can cache range requests and fetch random blocks from the
3398 // cache and the network, with synchronous responses.
3399 TEST(HttpCache, RangeGET_SyncOK) {
3400 MockHttpCache cache;
3402 MockTransaction transaction(kRangeGET_TransactionOK);
3403 transaction.test_mode = TEST_MODE_SYNC_ALL;
3404 AddMockTransaction(&transaction);
3406 // Write to the cache (40-49).
3407 std::string headers;
3408 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3410 Verify206Response(headers, 40, 49);
3411 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3412 EXPECT_EQ(0, cache.disk_cache()->open_count());
3413 EXPECT_EQ(1, cache.disk_cache()->create_count());
3415 // Read from the cache (40-49).
3416 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3418 Verify206Response(headers, 40, 49);
3419 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3420 EXPECT_EQ(0, cache.disk_cache()->open_count());
3421 EXPECT_EQ(1, cache.disk_cache()->create_count());
3423 // Make sure we are done with the previous transaction.
3424 base::MessageLoop::current()->RunUntilIdle();
3426 // Write to the cache (30-39).
3427 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3428 transaction.data = "rg: 30-39 ";
3429 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3431 Verify206Response(headers, 30, 39);
3432 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3433 EXPECT_EQ(1, cache.disk_cache()->open_count());
3434 EXPECT_EQ(1, cache.disk_cache()->create_count());
3436 // Make sure we are done with the previous transaction.
3437 base::MessageLoop::current()->RunUntilIdle();
3439 // Write and read from the cache (20-59).
3440 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3441 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3442 net::CapturingBoundNetLog log;
3443 net::LoadTimingInfo load_timing_info;
3444 RunTransactionTestWithResponseAndGetTiming(
3445 cache.http_cache(), transaction, &headers, log.bound(),
3446 &load_timing_info);
3448 Verify206Response(headers, 20, 59);
3449 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3450 EXPECT_EQ(2, cache.disk_cache()->open_count());
3451 EXPECT_EQ(1, cache.disk_cache()->create_count());
3452 TestLoadTimingNetworkRequest(load_timing_info);
3454 RemoveMockTransaction(&transaction);
3457 // Tests that we don't revalidate an entry unless we are required to do so.
3458 TEST(HttpCache, RangeGET_Revalidate1) {
3459 MockHttpCache cache;
3460 std::string headers;
3462 // Write to the cache (40-49).
3463 MockTransaction transaction(kRangeGET_TransactionOK);
3464 transaction.response_headers =
3465 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3466 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3467 "ETag: \"foo\"\n"
3468 "Accept-Ranges: bytes\n"
3469 "Content-Length: 10\n";
3470 AddMockTransaction(&transaction);
3471 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3473 Verify206Response(headers, 40, 49);
3474 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3475 EXPECT_EQ(0, cache.disk_cache()->open_count());
3476 EXPECT_EQ(1, cache.disk_cache()->create_count());
3478 // Read from the cache (40-49).
3479 net::CapturingBoundNetLog log;
3480 net::LoadTimingInfo load_timing_info;
3481 RunTransactionTestWithResponseAndGetTiming(
3482 cache.http_cache(), transaction, &headers, log.bound(),
3483 &load_timing_info);
3485 Verify206Response(headers, 40, 49);
3486 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3487 EXPECT_EQ(1, cache.disk_cache()->open_count());
3488 EXPECT_EQ(1, cache.disk_cache()->create_count());
3489 TestLoadTimingCachedResponse(load_timing_info);
3491 // Read again forcing the revalidation.
3492 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3493 RunTransactionTestWithResponseAndGetTiming(
3494 cache.http_cache(), transaction, &headers, log.bound(),
3495 &load_timing_info);
3497 Verify206Response(headers, 40, 49);
3498 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3499 EXPECT_EQ(1, cache.disk_cache()->open_count());
3500 EXPECT_EQ(1, cache.disk_cache()->create_count());
3501 TestLoadTimingNetworkRequest(load_timing_info);
3503 RemoveMockTransaction(&transaction);
3506 // Checks that we revalidate an entry when the headers say so.
3507 TEST(HttpCache, RangeGET_Revalidate2) {
3508 MockHttpCache cache;
3509 std::string headers;
3511 // Write to the cache (40-49).
3512 MockTransaction transaction(kRangeGET_TransactionOK);
3513 transaction.response_headers =
3514 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3515 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
3516 "ETag: \"foo\"\n"
3517 "Accept-Ranges: bytes\n"
3518 "Content-Length: 10\n";
3519 AddMockTransaction(&transaction);
3520 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3522 Verify206Response(headers, 40, 49);
3523 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3524 EXPECT_EQ(0, cache.disk_cache()->open_count());
3525 EXPECT_EQ(1, cache.disk_cache()->create_count());
3527 // Read from the cache (40-49).
3528 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3529 Verify206Response(headers, 40, 49);
3531 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3532 EXPECT_EQ(1, cache.disk_cache()->open_count());
3533 EXPECT_EQ(1, cache.disk_cache()->create_count());
3535 RemoveMockTransaction(&transaction);
3538 // Tests that we deal with 304s for range requests.
3539 TEST(HttpCache, RangeGET_304) {
3540 MockHttpCache cache;
3541 AddMockTransaction(&kRangeGET_TransactionOK);
3542 std::string headers;
3544 // Write to the cache (40-49).
3545 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3546 &headers);
3548 Verify206Response(headers, 40, 49);
3549 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3550 EXPECT_EQ(0, cache.disk_cache()->open_count());
3551 EXPECT_EQ(1, cache.disk_cache()->create_count());
3553 // Read from the cache (40-49).
3554 RangeTransactionServer handler;
3555 handler.set_not_modified(true);
3556 MockTransaction transaction(kRangeGET_TransactionOK);
3557 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3558 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3560 Verify206Response(headers, 40, 49);
3561 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3562 EXPECT_EQ(1, cache.disk_cache()->open_count());
3563 EXPECT_EQ(1, cache.disk_cache()->create_count());
3565 RemoveMockTransaction(&kRangeGET_TransactionOK);
3568 // Tests that we deal with 206s when revalidating range requests.
3569 TEST(HttpCache, RangeGET_ModifiedResult) {
3570 MockHttpCache cache;
3571 AddMockTransaction(&kRangeGET_TransactionOK);
3572 std::string headers;
3574 // Write to the cache (40-49).
3575 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3576 &headers);
3578 Verify206Response(headers, 40, 49);
3579 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3580 EXPECT_EQ(0, cache.disk_cache()->open_count());
3581 EXPECT_EQ(1, cache.disk_cache()->create_count());
3583 // Attempt to read from the cache (40-49).
3584 RangeTransactionServer handler;
3585 handler.set_modified(true);
3586 MockTransaction transaction(kRangeGET_TransactionOK);
3587 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3588 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3590 Verify206Response(headers, 40, 49);
3591 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3592 EXPECT_EQ(1, cache.disk_cache()->open_count());
3593 EXPECT_EQ(1, cache.disk_cache()->create_count());
3595 // And the entry should be gone.
3596 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3597 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3598 EXPECT_EQ(1, cache.disk_cache()->open_count());
3599 EXPECT_EQ(2, cache.disk_cache()->create_count());
3601 RemoveMockTransaction(&kRangeGET_TransactionOK);
3604 // Tests that we cache 301s for range requests.
3605 TEST(HttpCache, RangeGET_301) {
3606 MockHttpCache cache;
3607 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3608 transaction.status = "HTTP/1.1 301 Moved Permanently";
3609 transaction.response_headers = "Location: http://www.bar.com/\n";
3610 transaction.data = "";
3611 transaction.handler = NULL;
3612 AddMockTransaction(&transaction);
3614 // Write to the cache.
3615 RunTransactionTest(cache.http_cache(), transaction);
3616 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3617 EXPECT_EQ(0, cache.disk_cache()->open_count());
3618 EXPECT_EQ(1, cache.disk_cache()->create_count());
3620 // Read from the cache.
3621 RunTransactionTest(cache.http_cache(), transaction);
3622 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3623 EXPECT_EQ(1, cache.disk_cache()->open_count());
3624 EXPECT_EQ(1, cache.disk_cache()->create_count());
3626 RemoveMockTransaction(&transaction);
3629 // Tests that we can cache range requests when the start or end is unknown.
3630 // We start with one suffix request, followed by a request from a given point.
3631 TEST(HttpCache, UnknownRangeGET_1) {
3632 MockHttpCache cache;
3633 AddMockTransaction(&kRangeGET_TransactionOK);
3634 std::string headers;
3636 // Write to the cache (70-79).
3637 MockTransaction transaction(kRangeGET_TransactionOK);
3638 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3639 transaction.data = "rg: 70-79 ";
3640 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3642 Verify206Response(headers, 70, 79);
3643 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3644 EXPECT_EQ(0, cache.disk_cache()->open_count());
3645 EXPECT_EQ(1, cache.disk_cache()->create_count());
3647 // Make sure we are done with the previous transaction.
3648 base::MessageLoop::current()->RunUntilIdle();
3650 // Write and read from the cache (60-79).
3651 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
3652 transaction.data = "rg: 60-69 rg: 70-79 ";
3653 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3655 Verify206Response(headers, 60, 79);
3656 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3657 EXPECT_EQ(1, cache.disk_cache()->open_count());
3658 EXPECT_EQ(1, cache.disk_cache()->create_count());
3660 RemoveMockTransaction(&kRangeGET_TransactionOK);
3663 // Tests that we can cache range requests when the start or end is unknown.
3664 // We start with one request from a given point, followed by a suffix request.
3665 // We'll also verify that synchronous cache responses work as intended.
3666 TEST(HttpCache, UnknownRangeGET_2) {
3667 MockHttpCache cache;
3668 std::string headers;
3670 MockTransaction transaction(kRangeGET_TransactionOK);
3671 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
3672 TEST_MODE_SYNC_CACHE_READ |
3673 TEST_MODE_SYNC_CACHE_WRITE;
3674 AddMockTransaction(&transaction);
3676 // Write to the cache (70-79).
3677 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3678 transaction.data = "rg: 70-79 ";
3679 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3681 Verify206Response(headers, 70, 79);
3682 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3683 EXPECT_EQ(0, cache.disk_cache()->open_count());
3684 EXPECT_EQ(1, cache.disk_cache()->create_count());
3686 // Make sure we are done with the previous transaction.
3687 base::MessageLoop::current()->RunUntilIdle();
3689 // Write and read from the cache (60-79).
3690 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
3691 transaction.data = "rg: 60-69 rg: 70-79 ";
3692 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3694 Verify206Response(headers, 60, 79);
3695 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3696 EXPECT_EQ(1, cache.disk_cache()->open_count());
3697 EXPECT_EQ(1, cache.disk_cache()->create_count());
3699 RemoveMockTransaction(&transaction);
3702 // Tests that receiving Not Modified when asking for an open range doesn't mess
3703 // up things.
3704 TEST(HttpCache, UnknownRangeGET_304) {
3705 MockHttpCache cache;
3706 std::string headers;
3708 MockTransaction transaction(kRangeGET_TransactionOK);
3709 AddMockTransaction(&transaction);
3711 RangeTransactionServer handler;
3712 handler.set_not_modified(true);
3714 // Ask for the end of the file, without knowing the length.
3715 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3716 transaction.data = "";
3717 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3719 // We just bypass the cache.
3720 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3721 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3722 EXPECT_EQ(0, cache.disk_cache()->open_count());
3723 EXPECT_EQ(1, cache.disk_cache()->create_count());
3725 RunTransactionTest(cache.http_cache(), transaction);
3726 EXPECT_EQ(2, cache.disk_cache()->create_count());
3728 RemoveMockTransaction(&transaction);
3731 // Tests that we can handle non-range requests when we have cached a range.
3732 TEST(HttpCache, GET_Previous206) {
3733 MockHttpCache cache;
3734 AddMockTransaction(&kRangeGET_TransactionOK);
3735 std::string headers;
3736 net::CapturingBoundNetLog log;
3737 net::LoadTimingInfo load_timing_info;
3739 // Write to the cache (40-49).
3740 RunTransactionTestWithResponseAndGetTiming(
3741 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
3742 &load_timing_info);
3744 Verify206Response(headers, 40, 49);
3745 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3746 EXPECT_EQ(0, cache.disk_cache()->open_count());
3747 EXPECT_EQ(1, cache.disk_cache()->create_count());
3748 TestLoadTimingNetworkRequest(load_timing_info);
3750 // Write and read from the cache (0-79), when not asked for a range.
3751 MockTransaction transaction(kRangeGET_TransactionOK);
3752 transaction.request_headers = EXTRA_HEADER;
3753 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3754 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3755 RunTransactionTestWithResponseAndGetTiming(
3756 cache.http_cache(), transaction, &headers, log.bound(),
3757 &load_timing_info);
3759 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3760 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3761 EXPECT_EQ(1, cache.disk_cache()->open_count());
3762 EXPECT_EQ(1, cache.disk_cache()->create_count());
3763 TestLoadTimingNetworkRequest(load_timing_info);
3765 RemoveMockTransaction(&kRangeGET_TransactionOK);
3768 // Tests that we can handle non-range requests when we have cached the first
3769 // part of the object and the server replies with 304 (Not Modified).
3770 TEST(HttpCache, GET_Previous206_NotModified) {
3771 MockHttpCache cache;
3773 MockTransaction transaction(kRangeGET_TransactionOK);
3774 AddMockTransaction(&transaction);
3775 std::string headers;
3776 net::CapturingBoundNetLog log;
3777 net::LoadTimingInfo load_timing_info;
3779 // Write to the cache (0-9).
3780 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3781 transaction.data = "rg: 00-09 ";
3782 RunTransactionTestWithResponseAndGetTiming(
3783 cache.http_cache(), transaction, &headers, log.bound(),
3784 &load_timing_info);
3785 Verify206Response(headers, 0, 9);
3786 TestLoadTimingNetworkRequest(load_timing_info);
3788 // Write to the cache (70-79).
3789 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3790 transaction.data = "rg: 70-79 ";
3791 RunTransactionTestWithResponseAndGetTiming(
3792 cache.http_cache(), transaction, &headers, log.bound(),
3793 &load_timing_info);
3794 Verify206Response(headers, 70, 79);
3796 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3797 EXPECT_EQ(1, cache.disk_cache()->open_count());
3798 EXPECT_EQ(1, cache.disk_cache()->create_count());
3799 TestLoadTimingNetworkRequest(load_timing_info);
3801 // Read from the cache (0-9), write and read from cache (10 - 79).
3802 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3803 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3804 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3805 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3806 RunTransactionTestWithResponseAndGetTiming(
3807 cache.http_cache(), transaction, &headers, log.bound(),
3808 &load_timing_info);
3810 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3811 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3812 EXPECT_EQ(2, cache.disk_cache()->open_count());
3813 EXPECT_EQ(1, cache.disk_cache()->create_count());
3814 TestLoadTimingNetworkRequest(load_timing_info);
3816 RemoveMockTransaction(&transaction);
3819 // Tests that we can handle a regular request to a sparse entry, that results in
3820 // new content provided by the server (206).
3821 TEST(HttpCache, GET_Previous206_NewContent) {
3822 MockHttpCache cache;
3823 AddMockTransaction(&kRangeGET_TransactionOK);
3824 std::string headers;
3826 // Write to the cache (0-9).
3827 MockTransaction transaction(kRangeGET_TransactionOK);
3828 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3829 transaction.data = "rg: 00-09 ";
3830 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3832 Verify206Response(headers, 0, 9);
3833 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3834 EXPECT_EQ(0, cache.disk_cache()->open_count());
3835 EXPECT_EQ(1, cache.disk_cache()->create_count());
3837 // Now we'll issue a request without any range that should result first in a
3838 // 206 (when revalidating), and then in a weird standard answer: the test
3839 // server will not modify the response so we'll get the default range... a
3840 // real server will answer with 200.
3841 MockTransaction transaction2(kRangeGET_TransactionOK);
3842 transaction2.request_headers = EXTRA_HEADER;
3843 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
3844 transaction2.data = "Not a range";
3845 RangeTransactionServer handler;
3846 handler.set_modified(true);
3847 net::CapturingBoundNetLog log;
3848 net::LoadTimingInfo load_timing_info;
3849 RunTransactionTestWithResponseAndGetTiming(
3850 cache.http_cache(), transaction2, &headers, log.bound(),
3851 &load_timing_info);
3853 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3854 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3855 EXPECT_EQ(1, cache.disk_cache()->open_count());
3856 EXPECT_EQ(1, cache.disk_cache()->create_count());
3857 TestLoadTimingNetworkRequest(load_timing_info);
3859 // Verify that the previous request deleted the entry.
3860 RunTransactionTest(cache.http_cache(), transaction);
3861 EXPECT_EQ(2, cache.disk_cache()->create_count());
3863 RemoveMockTransaction(&transaction);
3866 // Tests that we can handle cached 206 responses that are not sparse.
3867 TEST(HttpCache, GET_Previous206_NotSparse) {
3868 MockHttpCache cache;
3870 // Create a disk cache entry that stores 206 headers while not being sparse.
3871 disk_cache::Entry* entry;
3872 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3873 NULL));
3875 std::string raw_headers(kRangeGET_TransactionOK.status);
3876 raw_headers.append("\n");
3877 raw_headers.append(kRangeGET_TransactionOK.response_headers);
3878 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3879 raw_headers.size());
3881 net::HttpResponseInfo response;
3882 response.headers = new net::HttpResponseHeaders(raw_headers);
3883 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3885 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3886 int len = static_cast<int>(base::strlcpy(buf->data(),
3887 kRangeGET_TransactionOK.data, 500));
3888 net::TestCompletionCallback cb;
3889 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
3890 EXPECT_EQ(len, cb.GetResult(rv));
3891 entry->Close();
3893 // Now see that we don't use the stored entry.
3894 std::string headers;
3895 net::CapturingBoundNetLog log;
3896 net::LoadTimingInfo load_timing_info;
3897 RunTransactionTestWithResponseAndGetTiming(
3898 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
3899 &load_timing_info);
3901 // We are expecting a 200.
3902 std::string expected_headers(kSimpleGET_Transaction.status);
3903 expected_headers.append("\n");
3904 expected_headers.append(kSimpleGET_Transaction.response_headers);
3905 EXPECT_EQ(expected_headers, headers);
3906 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3907 EXPECT_EQ(1, cache.disk_cache()->open_count());
3908 EXPECT_EQ(2, cache.disk_cache()->create_count());
3909 TestLoadTimingNetworkRequest(load_timing_info);
3912 // Tests that we can handle cached 206 responses that are not sparse. This time
3913 // we issue a range request and expect to receive a range.
3914 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
3915 MockHttpCache cache;
3916 AddMockTransaction(&kRangeGET_TransactionOK);
3918 // Create a disk cache entry that stores 206 headers while not being sparse.
3919 disk_cache::Entry* entry;
3920 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
3921 NULL));
3923 std::string raw_headers(kRangeGET_TransactionOK.status);
3924 raw_headers.append("\n");
3925 raw_headers.append(kRangeGET_TransactionOK.response_headers);
3926 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3927 raw_headers.size());
3929 net::HttpResponseInfo response;
3930 response.headers = new net::HttpResponseHeaders(raw_headers);
3931 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3933 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3934 int len = static_cast<int>(base::strlcpy(buf->data(),
3935 kRangeGET_TransactionOK.data, 500));
3936 net::TestCompletionCallback cb;
3937 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
3938 EXPECT_EQ(len, cb.GetResult(rv));
3939 entry->Close();
3941 // Now see that we don't use the stored entry.
3942 std::string headers;
3943 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3944 &headers);
3946 // We are expecting a 206.
3947 Verify206Response(headers, 40, 49);
3948 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3949 EXPECT_EQ(1, cache.disk_cache()->open_count());
3950 EXPECT_EQ(2, cache.disk_cache()->create_count());
3952 RemoveMockTransaction(&kRangeGET_TransactionOK);
3955 // Tests that we can handle cached 206 responses that can't be validated.
3956 TEST(HttpCache, GET_Previous206_NotValidation) {
3957 MockHttpCache cache;
3959 // Create a disk cache entry that stores 206 headers.
3960 disk_cache::Entry* entry;
3961 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3962 NULL));
3964 // Make sure that the headers cannot be validated with the server.
3965 std::string raw_headers(kRangeGET_TransactionOK.status);
3966 raw_headers.append("\n");
3967 raw_headers.append("Content-Length: 80\n");
3968 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3969 raw_headers.size());
3971 net::HttpResponseInfo response;
3972 response.headers = new net::HttpResponseHeaders(raw_headers);
3973 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3975 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3976 int len = static_cast<int>(base::strlcpy(buf->data(),
3977 kRangeGET_TransactionOK.data, 500));
3978 net::TestCompletionCallback cb;
3979 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
3980 EXPECT_EQ(len, cb.GetResult(rv));
3981 entry->Close();
3983 // Now see that we don't use the stored entry.
3984 std::string headers;
3985 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3986 &headers);
3988 // We are expecting a 200.
3989 std::string expected_headers(kSimpleGET_Transaction.status);
3990 expected_headers.append("\n");
3991 expected_headers.append(kSimpleGET_Transaction.response_headers);
3992 EXPECT_EQ(expected_headers, headers);
3993 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3994 EXPECT_EQ(1, cache.disk_cache()->open_count());
3995 EXPECT_EQ(2, cache.disk_cache()->create_count());
3998 // Tests that we can handle range requests with cached 200 responses.
3999 TEST(HttpCache, RangeGET_Previous200) {
4000 MockHttpCache cache;
4002 // Store the whole thing with status 200.
4003 MockTransaction transaction(kTypicalGET_Transaction);
4004 transaction.url = kRangeGET_TransactionOK.url;
4005 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4006 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4007 AddMockTransaction(&transaction);
4008 RunTransactionTest(cache.http_cache(), transaction);
4009 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4010 EXPECT_EQ(0, cache.disk_cache()->open_count());
4011 EXPECT_EQ(1, cache.disk_cache()->create_count());
4013 RemoveMockTransaction(&transaction);
4014 AddMockTransaction(&kRangeGET_TransactionOK);
4016 // Now see that we use the stored entry.
4017 std::string headers;
4018 MockTransaction transaction2(kRangeGET_TransactionOK);
4019 RangeTransactionServer handler;
4020 handler.set_not_modified(true);
4021 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4023 // We are expecting a 206.
4024 Verify206Response(headers, 40, 49);
4025 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4026 EXPECT_EQ(1, cache.disk_cache()->open_count());
4027 EXPECT_EQ(1, cache.disk_cache()->create_count());
4029 // The last transaction has finished so make sure the entry is deactivated.
4030 base::MessageLoop::current()->RunUntilIdle();
4032 // Make a request for an invalid range.
4033 MockTransaction transaction3(kRangeGET_TransactionOK);
4034 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4035 transaction3.data = transaction.data;
4036 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4037 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4038 EXPECT_EQ(2, cache.disk_cache()->open_count());
4039 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4040 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4041 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4043 // Make sure the entry is deactivated.
4044 base::MessageLoop::current()->RunUntilIdle();
4046 // Even though the request was invalid, we should have the entry.
4047 RunTransactionTest(cache.http_cache(), transaction2);
4048 EXPECT_EQ(3, cache.disk_cache()->open_count());
4050 // Make sure the entry is deactivated.
4051 base::MessageLoop::current()->RunUntilIdle();
4053 // Now we should receive a range from the server and drop the stored entry.
4054 handler.set_not_modified(false);
4055 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4056 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4057 Verify206Response(headers, 40, 49);
4058 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4059 EXPECT_EQ(4, cache.disk_cache()->open_count());
4060 EXPECT_EQ(1, cache.disk_cache()->create_count());
4062 RunTransactionTest(cache.http_cache(), transaction2);
4063 EXPECT_EQ(2, cache.disk_cache()->create_count());
4065 RemoveMockTransaction(&kRangeGET_TransactionOK);
4068 // Tests that we can handle a 200 response when dealing with sparse entries.
4069 TEST(HttpCache, RangeRequestResultsIn200) {
4070 MockHttpCache cache;
4071 AddMockTransaction(&kRangeGET_TransactionOK);
4072 std::string headers;
4074 // Write to the cache (70-79).
4075 MockTransaction transaction(kRangeGET_TransactionOK);
4076 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4077 transaction.data = "rg: 70-79 ";
4078 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4080 Verify206Response(headers, 70, 79);
4081 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4082 EXPECT_EQ(0, cache.disk_cache()->open_count());
4083 EXPECT_EQ(1, cache.disk_cache()->create_count());
4085 // Now we'll issue a request that results in a plain 200 response, but to
4086 // the to the same URL that we used to store sparse data, and making sure
4087 // that we ask for a range.
4088 RemoveMockTransaction(&kRangeGET_TransactionOK);
4089 MockTransaction transaction2(kSimpleGET_Transaction);
4090 transaction2.url = kRangeGET_TransactionOK.url;
4091 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4092 AddMockTransaction(&transaction2);
4094 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4096 std::string expected_headers(kSimpleGET_Transaction.status);
4097 expected_headers.append("\n");
4098 expected_headers.append(kSimpleGET_Transaction.response_headers);
4099 EXPECT_EQ(expected_headers, headers);
4100 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4101 EXPECT_EQ(1, cache.disk_cache()->open_count());
4102 EXPECT_EQ(1, cache.disk_cache()->create_count());
4104 RemoveMockTransaction(&transaction2);
4107 // Tests that a range request that falls outside of the size that we know about
4108 // only deletes the entry if the resource has indeed changed.
4109 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4110 MockHttpCache cache;
4111 AddMockTransaction(&kRangeGET_TransactionOK);
4112 std::string headers;
4114 // Write to the cache (40-49).
4115 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4116 &headers);
4118 Verify206Response(headers, 40, 49);
4119 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4120 EXPECT_EQ(0, cache.disk_cache()->open_count());
4121 EXPECT_EQ(1, cache.disk_cache()->create_count());
4123 // A weird request should not delete this entry. Ask for bytes 120-.
4124 MockTransaction transaction(kRangeGET_TransactionOK);
4125 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4126 transaction.data = "";
4127 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4129 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4130 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4131 EXPECT_EQ(1, cache.disk_cache()->open_count());
4132 EXPECT_EQ(1, cache.disk_cache()->create_count());
4134 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4135 EXPECT_EQ(2, cache.disk_cache()->open_count());
4136 EXPECT_EQ(1, cache.disk_cache()->create_count());
4138 RemoveMockTransaction(&kRangeGET_TransactionOK);
4141 // Tests that we don't delete a sparse entry when we cancel a request.
4142 TEST(HttpCache, RangeGET_Cancel) {
4143 MockHttpCache cache;
4144 AddMockTransaction(&kRangeGET_TransactionOK);
4146 MockHttpRequest request(kRangeGET_TransactionOK);
4148 Context* c = new Context();
4149 int rv = cache.http_cache()->CreateTransaction(
4150 net::DEFAULT_PRIORITY, &c->trans, NULL);
4151 EXPECT_EQ(net::OK, rv);
4153 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4154 if (rv == net::ERR_IO_PENDING)
4155 rv = c->callback.WaitForResult();
4157 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4158 EXPECT_EQ(0, cache.disk_cache()->open_count());
4159 EXPECT_EQ(1, cache.disk_cache()->create_count());
4161 // Make sure that the entry has some data stored.
4162 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4163 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4164 if (rv == net::ERR_IO_PENDING)
4165 rv = c->callback.WaitForResult();
4166 EXPECT_EQ(buf->size(), rv);
4168 // Destroy the transaction.
4169 delete c;
4171 // Verify that the entry has not been deleted.
4172 disk_cache::Entry* entry;
4173 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4174 entry->Close();
4175 RemoveMockTransaction(&kRangeGET_TransactionOK);
4178 // Tests that we don't delete a sparse entry when we start a new request after
4179 // cancelling the previous one.
4180 TEST(HttpCache, RangeGET_Cancel2) {
4181 MockHttpCache cache;
4182 AddMockTransaction(&kRangeGET_TransactionOK);
4184 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4185 MockHttpRequest request(kRangeGET_TransactionOK);
4186 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4188 Context* c = new Context();
4189 int rv = cache.http_cache()->CreateTransaction(
4190 net::DEFAULT_PRIORITY, &c->trans, NULL);
4191 EXPECT_EQ(net::OK, rv);
4193 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4194 if (rv == net::ERR_IO_PENDING)
4195 rv = c->callback.WaitForResult();
4197 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4198 EXPECT_EQ(1, cache.disk_cache()->open_count());
4199 EXPECT_EQ(1, cache.disk_cache()->create_count());
4201 // Make sure that we revalidate the entry and read from the cache (a single
4202 // read will return while waiting for the network).
4203 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4204 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4205 EXPECT_EQ(5, c->callback.GetResult(rv));
4206 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4207 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4209 // Destroy the transaction before completing the read.
4210 delete c;
4212 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4213 // message loop. This means that a new transaction will just reuse the same
4214 // active entry (no open or create).
4216 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4218 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4219 EXPECT_EQ(1, cache.disk_cache()->open_count());
4220 EXPECT_EQ(1, cache.disk_cache()->create_count());
4221 RemoveMockTransaction(&kRangeGET_TransactionOK);
4224 // A slight variation of the previous test, this time we cancel two requests in
4225 // a row, making sure that the second is waiting for the entry to be ready.
4226 TEST(HttpCache, RangeGET_Cancel3) {
4227 MockHttpCache cache;
4228 AddMockTransaction(&kRangeGET_TransactionOK);
4230 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4231 MockHttpRequest request(kRangeGET_TransactionOK);
4232 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4234 Context* c = new Context();
4235 int rv = cache.http_cache()->CreateTransaction(
4236 net::DEFAULT_PRIORITY, &c->trans, NULL);
4237 EXPECT_EQ(net::OK, rv);
4239 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4240 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4241 rv = c->callback.WaitForResult();
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());
4247 // Make sure that we revalidate the entry and read from the cache (a single
4248 // read will return while waiting for the network).
4249 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4250 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4251 EXPECT_EQ(5, c->callback.GetResult(rv));
4252 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4253 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4255 // Destroy the transaction before completing the read.
4256 delete c;
4258 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4259 // message loop. This means that a new transaction will just reuse the same
4260 // active entry (no open or create).
4262 c = new Context();
4263 rv = cache.http_cache()->CreateTransaction(
4264 net::DEFAULT_PRIORITY, &c->trans, NULL);
4265 EXPECT_EQ(net::OK, rv);
4267 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4268 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4270 MockDiskEntry::IgnoreCallbacks(true);
4271 base::MessageLoop::current()->RunUntilIdle();
4272 MockDiskEntry::IgnoreCallbacks(false);
4274 // The new transaction is waiting for the query range callback.
4275 delete c;
4277 // And we should not crash when the callback is delivered.
4278 base::MessageLoop::current()->RunUntilIdle();
4280 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4281 EXPECT_EQ(1, cache.disk_cache()->open_count());
4282 EXPECT_EQ(1, cache.disk_cache()->create_count());
4283 RemoveMockTransaction(&kRangeGET_TransactionOK);
4286 // Tests that an invalid range response results in no cached entry.
4287 TEST(HttpCache, RangeGET_InvalidResponse1) {
4288 MockHttpCache cache;
4289 std::string headers;
4291 MockTransaction transaction(kRangeGET_TransactionOK);
4292 transaction.handler = NULL;
4293 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4294 "Content-Length: 10\n";
4295 AddMockTransaction(&transaction);
4296 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4298 std::string expected(transaction.status);
4299 expected.append("\n");
4300 expected.append(transaction.response_headers);
4301 EXPECT_EQ(expected, headers);
4303 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4304 EXPECT_EQ(0, cache.disk_cache()->open_count());
4305 EXPECT_EQ(1, cache.disk_cache()->create_count());
4307 // Verify that we don't have a cached entry.
4308 disk_cache::Entry* entry;
4309 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4311 RemoveMockTransaction(&kRangeGET_TransactionOK);
4314 // Tests that we reject a range that doesn't match the content-length.
4315 TEST(HttpCache, RangeGET_InvalidResponse2) {
4316 MockHttpCache cache;
4317 std::string headers;
4319 MockTransaction transaction(kRangeGET_TransactionOK);
4320 transaction.handler = NULL;
4321 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4322 "Content-Length: 20\n";
4323 AddMockTransaction(&transaction);
4324 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4326 std::string expected(transaction.status);
4327 expected.append("\n");
4328 expected.append(transaction.response_headers);
4329 EXPECT_EQ(expected, headers);
4331 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4332 EXPECT_EQ(0, cache.disk_cache()->open_count());
4333 EXPECT_EQ(1, cache.disk_cache()->create_count());
4335 // Verify that we don't have a cached entry.
4336 disk_cache::Entry* entry;
4337 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4339 RemoveMockTransaction(&kRangeGET_TransactionOK);
4342 // Tests that if a server tells us conflicting information about a resource we
4343 // ignore the response.
4344 TEST(HttpCache, RangeGET_InvalidResponse3) {
4345 MockHttpCache cache;
4346 std::string headers;
4348 MockTransaction transaction(kRangeGET_TransactionOK);
4349 transaction.handler = NULL;
4350 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4351 std::string response_headers(transaction.response_headers);
4352 response_headers.append("Content-Range: bytes 50-59/160\n");
4353 transaction.response_headers = response_headers.c_str();
4354 AddMockTransaction(&transaction);
4355 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4357 Verify206Response(headers, 50, 59);
4358 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4359 EXPECT_EQ(0, cache.disk_cache()->open_count());
4360 EXPECT_EQ(1, cache.disk_cache()->create_count());
4362 RemoveMockTransaction(&transaction);
4363 AddMockTransaction(&kRangeGET_TransactionOK);
4365 // This transaction will report a resource size of 80 bytes, and we think it's
4366 // 160 so we should ignore the response.
4367 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4368 &headers);
4370 Verify206Response(headers, 40, 49);
4371 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4372 EXPECT_EQ(1, cache.disk_cache()->open_count());
4373 EXPECT_EQ(1, cache.disk_cache()->create_count());
4375 // Verify that we cached the first response but not the second one.
4376 disk_cache::Entry* en;
4377 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4379 int64 cached_start = 0;
4380 net::TestCompletionCallback cb;
4381 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4382 EXPECT_EQ(10, cb.GetResult(rv));
4383 EXPECT_EQ(50, cached_start);
4384 en->Close();
4386 RemoveMockTransaction(&kRangeGET_TransactionOK);
4389 // Tests that we handle large range values properly.
4390 TEST(HttpCache, RangeGET_LargeValues) {
4391 // We need a real sparse cache for this test.
4392 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4393 std::string headers;
4395 MockTransaction transaction(kRangeGET_TransactionOK);
4396 transaction.handler = NULL;
4397 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4398 EXTRA_HEADER;
4399 transaction.response_headers =
4400 "ETag: \"foo\"\n"
4401 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4402 "Content-Length: 10\n";
4403 AddMockTransaction(&transaction);
4404 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4406 std::string expected(transaction.status);
4407 expected.append("\n");
4408 expected.append(transaction.response_headers);
4409 EXPECT_EQ(expected, headers);
4411 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4413 // Verify that we have a cached entry.
4414 disk_cache::Entry* en;
4415 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4416 en->Close();
4418 RemoveMockTransaction(&kRangeGET_TransactionOK);
4421 // Tests that we don't crash with a range request if the disk cache was not
4422 // initialized properly.
4423 TEST(HttpCache, RangeGET_NoDiskCache) {
4424 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4425 factory->set_fail(true);
4426 factory->FinishCreation(); // We'll complete synchronously.
4427 MockHttpCache cache(factory);
4429 AddMockTransaction(&kRangeGET_TransactionOK);
4431 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4432 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4434 RemoveMockTransaction(&kRangeGET_TransactionOK);
4437 // Tests that we handle byte range requests that skip the cache.
4438 TEST(HttpCache, RangeHEAD) {
4439 MockHttpCache cache;
4440 AddMockTransaction(&kRangeGET_TransactionOK);
4442 MockTransaction transaction(kRangeGET_TransactionOK);
4443 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4444 transaction.method = "HEAD";
4445 transaction.data = "rg: 70-79 ";
4447 std::string headers;
4448 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4450 Verify206Response(headers, 70, 79);
4451 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4452 EXPECT_EQ(0, cache.disk_cache()->open_count());
4453 EXPECT_EQ(0, cache.disk_cache()->create_count());
4455 RemoveMockTransaction(&kRangeGET_TransactionOK);
4458 // Tests that we don't crash when after reading from the cache we issue a
4459 // request for the next range and the server gives us a 200 synchronously.
4460 TEST(HttpCache, RangeGET_FastFlakyServer) {
4461 MockHttpCache cache;
4463 MockTransaction transaction(kRangeGET_TransactionOK);
4464 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4465 transaction.test_mode = TEST_MODE_SYNC_NET_START;
4466 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4467 AddMockTransaction(&transaction);
4469 // Write to the cache.
4470 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4472 // And now read from the cache and the network.
4473 RangeTransactionServer handler;
4474 handler.set_bad_200(true);
4475 transaction.data = "Not a range";
4476 RunTransactionTest(cache.http_cache(), transaction);
4478 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4479 EXPECT_EQ(1, cache.disk_cache()->open_count());
4480 EXPECT_EQ(1, cache.disk_cache()->create_count());
4482 RemoveMockTransaction(&transaction);
4485 // Tests that when the server gives us less data than expected, we don't keep
4486 // asking for more data.
4487 TEST(HttpCache, RangeGET_FastFlakyServer2) {
4488 MockHttpCache cache;
4490 // First, check with an empty cache (WRITE mode).
4491 MockTransaction transaction(kRangeGET_TransactionOK);
4492 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4493 transaction.data = "rg: 40-"; // Less than expected.
4494 transaction.handler = NULL;
4495 std::string headers(transaction.response_headers);
4496 headers.append("Content-Range: bytes 40-49/80\n");
4497 transaction.response_headers = headers.c_str();
4499 AddMockTransaction(&transaction);
4501 // Write to the cache.
4502 RunTransactionTest(cache.http_cache(), transaction);
4504 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4505 EXPECT_EQ(0, cache.disk_cache()->open_count());
4506 EXPECT_EQ(1, cache.disk_cache()->create_count());
4508 // Now verify that even in READ_WRITE mode, we forward the bad response to
4509 // the caller.
4510 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4511 transaction.data = "rg: 60-"; // Less than expected.
4512 headers = kRangeGET_TransactionOK.response_headers;
4513 headers.append("Content-Range: bytes 60-69/80\n");
4514 transaction.response_headers = headers.c_str();
4516 RunTransactionTest(cache.http_cache(), transaction);
4518 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4519 EXPECT_EQ(1, cache.disk_cache()->open_count());
4520 EXPECT_EQ(1, cache.disk_cache()->create_count());
4522 RemoveMockTransaction(&transaction);
4525 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
4526 // This test hits a NOTREACHED so it is a release mode only test.
4527 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
4528 MockHttpCache cache;
4529 AddMockTransaction(&kRangeGET_TransactionOK);
4531 // Write to the cache (40-49).
4532 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4533 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4534 EXPECT_EQ(0, cache.disk_cache()->open_count());
4535 EXPECT_EQ(1, cache.disk_cache()->create_count());
4537 // Force this transaction to read from the cache.
4538 MockTransaction transaction(kRangeGET_TransactionOK);
4539 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4541 MockHttpRequest request(transaction);
4542 net::TestCompletionCallback callback;
4544 scoped_ptr<net::HttpTransaction> trans;
4545 int rv = cache.http_cache()->CreateTransaction(
4546 net::DEFAULT_PRIORITY, &trans, NULL);
4547 EXPECT_EQ(net::OK, rv);
4548 ASSERT_TRUE(trans.get());
4550 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
4551 if (rv == net::ERR_IO_PENDING)
4552 rv = callback.WaitForResult();
4553 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4555 trans.reset();
4557 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4558 EXPECT_EQ(1, cache.disk_cache()->open_count());
4559 EXPECT_EQ(1, cache.disk_cache()->create_count());
4561 RemoveMockTransaction(&kRangeGET_TransactionOK);
4563 #endif
4565 // Tests the handling of the "truncation" flag.
4566 TEST(HttpCache, WriteResponseInfo_Truncated) {
4567 MockHttpCache cache;
4568 disk_cache::Entry* entry;
4569 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
4570 NULL));
4572 std::string headers("HTTP/1.1 200 OK");
4573 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4574 net::HttpResponseInfo response;
4575 response.headers = new net::HttpResponseHeaders(headers);
4577 // Set the last argument for this to be an incomplete request.
4578 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
4579 bool truncated = false;
4580 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4581 EXPECT_TRUE(truncated);
4583 // And now test the opposite case.
4584 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4585 truncated = true;
4586 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4587 EXPECT_FALSE(truncated);
4588 entry->Close();
4591 // Tests basic pickling/unpickling of HttpResponseInfo.
4592 TEST(HttpCache, PersistHttpResponseInfo) {
4593 // Set some fields (add more if needed.)
4594 net::HttpResponseInfo response1;
4595 response1.was_cached = false;
4596 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4597 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4599 // Pickle.
4600 Pickle pickle;
4601 response1.Persist(&pickle, false, false);
4603 // Unpickle.
4604 net::HttpResponseInfo response2;
4605 bool response_truncated;
4606 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4607 EXPECT_FALSE(response_truncated);
4609 // Verify fields.
4610 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
4611 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4612 EXPECT_EQ(80, response2.socket_address.port());
4613 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4616 // Tests that we delete an entry when the request is cancelled before starting
4617 // to read from the network.
4618 TEST(HttpCache, DoomOnDestruction) {
4619 MockHttpCache cache;
4621 MockHttpRequest request(kSimpleGET_Transaction);
4623 Context* c = new Context();
4624 int rv = cache.http_cache()->CreateTransaction(
4625 net::DEFAULT_PRIORITY, &c->trans, NULL);
4626 EXPECT_EQ(net::OK, rv);
4628 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4629 if (rv == net::ERR_IO_PENDING)
4630 c->result = c->callback.WaitForResult();
4632 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4633 EXPECT_EQ(0, cache.disk_cache()->open_count());
4634 EXPECT_EQ(1, cache.disk_cache()->create_count());
4636 // Destroy the transaction. We only have the headers so we should delete this
4637 // entry.
4638 delete c;
4640 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4642 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4643 EXPECT_EQ(0, cache.disk_cache()->open_count());
4644 EXPECT_EQ(2, cache.disk_cache()->create_count());
4647 // Tests that we delete an entry when the request is cancelled if the response
4648 // does not have content-length and strong validators.
4649 TEST(HttpCache, DoomOnDestruction2) {
4650 MockHttpCache cache;
4652 MockHttpRequest request(kSimpleGET_Transaction);
4654 Context* c = new Context();
4655 int rv = cache.http_cache()->CreateTransaction(
4656 net::DEFAULT_PRIORITY, &c->trans, NULL);
4657 EXPECT_EQ(net::OK, rv);
4659 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4660 if (rv == net::ERR_IO_PENDING)
4661 rv = c->callback.WaitForResult();
4663 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4664 EXPECT_EQ(0, cache.disk_cache()->open_count());
4665 EXPECT_EQ(1, cache.disk_cache()->create_count());
4667 // Make sure that the entry has some data stored.
4668 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4669 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4670 if (rv == net::ERR_IO_PENDING)
4671 rv = c->callback.WaitForResult();
4672 EXPECT_EQ(buf->size(), rv);
4674 // Destroy the transaction.
4675 delete c;
4677 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4679 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4680 EXPECT_EQ(0, cache.disk_cache()->open_count());
4681 EXPECT_EQ(2, cache.disk_cache()->create_count());
4684 // Tests that we delete an entry when the request is cancelled if the response
4685 // has an "Accept-Ranges: none" header.
4686 TEST(HttpCache, DoomOnDestruction3) {
4687 MockHttpCache cache;
4689 MockTransaction transaction(kSimpleGET_Transaction);
4690 transaction.response_headers =
4691 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4692 "Content-Length: 22\n"
4693 "Accept-Ranges: none\n"
4694 "Etag: \"foopy\"\n";
4695 AddMockTransaction(&transaction);
4696 MockHttpRequest request(transaction);
4698 Context* c = new Context();
4699 int rv = cache.http_cache()->CreateTransaction(
4700 net::DEFAULT_PRIORITY, &c->trans, NULL);
4701 EXPECT_EQ(net::OK, rv);
4703 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4704 if (rv == net::ERR_IO_PENDING)
4705 rv = c->callback.WaitForResult();
4707 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4708 EXPECT_EQ(0, cache.disk_cache()->open_count());
4709 EXPECT_EQ(1, cache.disk_cache()->create_count());
4711 // Make sure that the entry has some data stored.
4712 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4713 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4714 if (rv == net::ERR_IO_PENDING)
4715 rv = c->callback.WaitForResult();
4716 EXPECT_EQ(buf->size(), rv);
4718 // Destroy the transaction.
4719 delete c;
4721 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4723 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4724 EXPECT_EQ(0, cache.disk_cache()->open_count());
4725 EXPECT_EQ(2, cache.disk_cache()->create_count());
4727 RemoveMockTransaction(&transaction);
4730 // Tests that we mark an entry as incomplete when the request is cancelled.
4731 TEST(HttpCache, SetTruncatedFlag) {
4732 MockHttpCache cache;
4734 MockTransaction transaction(kSimpleGET_Transaction);
4735 transaction.response_headers =
4736 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4737 "Content-Length: 22\n"
4738 "Etag: \"foopy\"\n";
4739 AddMockTransaction(&transaction);
4740 MockHttpRequest request(transaction);
4742 scoped_ptr<Context> c(new Context());
4743 // We use a test delegate to ensure that after initiating destruction
4744 // of the transaction, no further delegate callbacks happen.
4745 // We initialize the TestHttpTransactionDelegate with the correct number of
4746 // cache actions and network actions to be reported.
4747 scoped_ptr<TestHttpTransactionDelegate> delegate(
4748 new TestHttpTransactionDelegate(7, 3));
4749 int rv = cache.http_cache()->CreateTransaction(
4750 net::DEFAULT_PRIORITY, &c->trans, delegate.get());
4751 EXPECT_EQ(net::OK, rv);
4753 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4754 if (rv == net::ERR_IO_PENDING)
4755 rv = c->callback.WaitForResult();
4757 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4758 EXPECT_EQ(0, cache.disk_cache()->open_count());
4759 EXPECT_EQ(1, cache.disk_cache()->create_count());
4761 // Make sure that the entry has some data stored.
4762 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4763 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4764 if (rv == net::ERR_IO_PENDING)
4765 rv = c->callback.WaitForResult();
4766 EXPECT_EQ(buf->size(), rv);
4768 // We want to cancel the request when the transaction is busy.
4769 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4770 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4771 EXPECT_FALSE(c->callback.have_result());
4773 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
4774 int num_delegate_callbacks_before_destruction =
4775 delegate->num_callbacks_observed();
4777 // Destroy the transaction.
4778 c->trans.reset();
4779 MockHttpCache::SetTestMode(0);
4781 // Ensure the delegate received no callbacks during destruction.
4782 EXPECT_EQ(num_delegate_callbacks_before_destruction,
4783 delegate->num_callbacks_observed());
4785 // Since the transaction was aborted in the middle of network I/O, we will
4786 // manually call the delegate so that its pending I/O operation will be
4787 // closed (which is what the test delegate is expecting).
4788 delegate->OnNetworkActionFinish();
4790 // Make sure that we don't invoke the callback. We may have an issue if the
4791 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4792 // could end up with the transaction being deleted twice if we send any
4793 // notification from the transaction destructor (see http://crbug.com/31723).
4794 EXPECT_FALSE(c->callback.have_result());
4796 // Verify that the entry is marked as incomplete.
4797 disk_cache::Entry* entry;
4798 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4799 net::HttpResponseInfo response;
4800 bool truncated = false;
4801 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4802 EXPECT_TRUE(truncated);
4803 entry->Close();
4805 RemoveMockTransaction(&transaction);
4808 // Tests that we don't mark an entry as truncated when we read everything.
4809 TEST(HttpCache, DontSetTruncatedFlag) {
4810 MockHttpCache cache;
4812 MockTransaction transaction(kSimpleGET_Transaction);
4813 transaction.response_headers =
4814 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4815 "Content-Length: 22\n"
4816 "Etag: \"foopy\"\n";
4817 AddMockTransaction(&transaction);
4818 MockHttpRequest request(transaction);
4820 scoped_ptr<Context> c(new Context());
4821 int rv = cache.http_cache()->CreateTransaction(
4822 net::DEFAULT_PRIORITY, &c->trans, NULL);
4823 EXPECT_EQ(net::OK, rv);
4825 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4826 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4828 // Read everything.
4829 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
4830 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4831 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
4833 // Destroy the transaction.
4834 c->trans.reset();
4836 // Verify that the entry is not marked as truncated.
4837 disk_cache::Entry* entry;
4838 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4839 net::HttpResponseInfo response;
4840 bool truncated = true;
4841 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4842 EXPECT_FALSE(truncated);
4843 entry->Close();
4845 RemoveMockTransaction(&transaction);
4848 // Tests that we can continue with a request that was interrupted.
4849 TEST(HttpCache, GET_IncompleteResource) {
4850 MockHttpCache cache;
4851 AddMockTransaction(&kRangeGET_TransactionOK);
4853 std::string raw_headers("HTTP/1.1 200 OK\n"
4854 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4855 "ETag: \"foo\"\n"
4856 "Accept-Ranges: bytes\n"
4857 "Content-Length: 80\n");
4858 CreateTruncatedEntry(raw_headers, &cache);
4860 // Now make a regular request.
4861 std::string headers;
4862 MockTransaction transaction(kRangeGET_TransactionOK);
4863 transaction.request_headers = EXTRA_HEADER;
4864 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4865 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4866 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4868 // We update the headers with the ones received while revalidating.
4869 std::string expected_headers(
4870 "HTTP/1.1 200 OK\n"
4871 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4872 "Accept-Ranges: bytes\n"
4873 "ETag: \"foo\"\n"
4874 "Content-Length: 80\n");
4876 EXPECT_EQ(expected_headers, headers);
4877 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4878 EXPECT_EQ(1, cache.disk_cache()->open_count());
4879 EXPECT_EQ(1, cache.disk_cache()->create_count());
4881 // Verify that the disk entry was updated.
4882 disk_cache::Entry* entry;
4883 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4884 EXPECT_EQ(80, entry->GetDataSize(1));
4885 bool truncated = true;
4886 net::HttpResponseInfo response;
4887 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4888 EXPECT_FALSE(truncated);
4889 entry->Close();
4891 RemoveMockTransaction(&kRangeGET_TransactionOK);
4894 // Tests the handling of no-store when revalidating a truncated entry.
4895 TEST(HttpCache, GET_IncompleteResource_NoStore) {
4896 MockHttpCache cache;
4897 AddMockTransaction(&kRangeGET_TransactionOK);
4899 std::string raw_headers("HTTP/1.1 200 OK\n"
4900 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4901 "ETag: \"foo\"\n"
4902 "Accept-Ranges: bytes\n"
4903 "Content-Length: 80\n");
4904 CreateTruncatedEntry(raw_headers, &cache);
4905 RemoveMockTransaction(&kRangeGET_TransactionOK);
4907 // Now make a regular request.
4908 MockTransaction transaction(kRangeGET_TransactionOK);
4909 transaction.request_headers = EXTRA_HEADER;
4910 std::string response_headers(transaction.response_headers);
4911 response_headers += ("Cache-Control: no-store\n");
4912 transaction.response_headers = response_headers.c_str();
4913 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4914 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4915 AddMockTransaction(&transaction);
4917 std::string headers;
4918 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4920 // We update the headers with the ones received while revalidating.
4921 std::string expected_headers(
4922 "HTTP/1.1 200 OK\n"
4923 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4924 "Accept-Ranges: bytes\n"
4925 "Cache-Control: no-store\n"
4926 "ETag: \"foo\"\n"
4927 "Content-Length: 80\n");
4929 EXPECT_EQ(expected_headers, headers);
4930 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4931 EXPECT_EQ(1, cache.disk_cache()->open_count());
4932 EXPECT_EQ(1, cache.disk_cache()->create_count());
4934 // Verify that the disk entry was deleted.
4935 disk_cache::Entry* entry;
4936 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4937 RemoveMockTransaction(&transaction);
4940 // Tests cancelling a request after the server sent no-store.
4941 TEST(HttpCache, GET_IncompleteResource_Cancel) {
4942 MockHttpCache cache;
4943 AddMockTransaction(&kRangeGET_TransactionOK);
4945 std::string raw_headers("HTTP/1.1 200 OK\n"
4946 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4947 "ETag: \"foo\"\n"
4948 "Accept-Ranges: bytes\n"
4949 "Content-Length: 80\n");
4950 CreateTruncatedEntry(raw_headers, &cache);
4951 RemoveMockTransaction(&kRangeGET_TransactionOK);
4953 // Now make a regular request.
4954 MockTransaction transaction(kRangeGET_TransactionOK);
4955 transaction.request_headers = EXTRA_HEADER;
4956 std::string response_headers(transaction.response_headers);
4957 response_headers += ("Cache-Control: no-store\n");
4958 transaction.response_headers = response_headers.c_str();
4959 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4960 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4961 AddMockTransaction(&transaction);
4963 MockHttpRequest request(transaction);
4964 Context* c = new Context();
4966 int rv = cache.http_cache()->CreateTransaction(
4967 net::DEFAULT_PRIORITY, &c->trans, NULL);
4968 EXPECT_EQ(net::OK, rv);
4970 // Queue another request to this transaction. We have to start this request
4971 // before the first one gets the response from the server and dooms the entry,
4972 // otherwise it will just create a new entry without being queued to the first
4973 // request.
4974 Context* pending = new Context();
4975 EXPECT_EQ(net::OK,
4976 cache.http_cache()->CreateTransaction(
4977 net::DEFAULT_PRIORITY, &pending->trans, NULL));
4979 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4980 EXPECT_EQ(net::ERR_IO_PENDING,
4981 pending->trans->Start(&request, pending->callback.callback(),
4982 net::BoundNetLog()));
4983 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4985 // Make sure that the entry has some data stored.
4986 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4987 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4988 EXPECT_EQ(5, c->callback.GetResult(rv));
4990 // Cancel the requests.
4991 delete c;
4992 delete pending;
4994 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4995 EXPECT_EQ(1, cache.disk_cache()->open_count());
4996 EXPECT_EQ(2, cache.disk_cache()->create_count());
4998 base::MessageLoop::current()->RunUntilIdle();
4999 RemoveMockTransaction(&transaction);
5002 // Tests that we delete truncated entries if the server changes its mind midway.
5003 TEST(HttpCache, GET_IncompleteResource2) {
5004 MockHttpCache cache;
5005 AddMockTransaction(&kRangeGET_TransactionOK);
5007 // Content-length will be intentionally bad.
5008 std::string raw_headers("HTTP/1.1 200 OK\n"
5009 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5010 "ETag: \"foo\"\n"
5011 "Accept-Ranges: bytes\n"
5012 "Content-Length: 50\n");
5013 CreateTruncatedEntry(raw_headers, &cache);
5015 // Now make a regular request. We expect the code to fail the validation and
5016 // retry the request without using byte ranges.
5017 std::string headers;
5018 MockTransaction transaction(kRangeGET_TransactionOK);
5019 transaction.request_headers = EXTRA_HEADER;
5020 transaction.data = "Not a range";
5021 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5023 // The server will return 200 instead of a byte range.
5024 std::string expected_headers(
5025 "HTTP/1.1 200 OK\n"
5026 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5028 EXPECT_EQ(expected_headers, headers);
5029 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5030 EXPECT_EQ(1, cache.disk_cache()->open_count());
5031 EXPECT_EQ(1, cache.disk_cache()->create_count());
5033 // Verify that the disk entry was deleted.
5034 disk_cache::Entry* entry;
5035 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5036 RemoveMockTransaction(&kRangeGET_TransactionOK);
5039 // Tests that we always validate a truncated request.
5040 TEST(HttpCache, GET_IncompleteResource3) {
5041 MockHttpCache cache;
5042 AddMockTransaction(&kRangeGET_TransactionOK);
5044 // This should not require validation for 10 hours.
5045 std::string raw_headers("HTTP/1.1 200 OK\n"
5046 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5047 "ETag: \"foo\"\n"
5048 "Cache-Control: max-age= 36000\n"
5049 "Accept-Ranges: bytes\n"
5050 "Content-Length: 80\n");
5051 CreateTruncatedEntry(raw_headers, &cache);
5053 // Now make a regular request.
5054 std::string headers;
5055 MockTransaction transaction(kRangeGET_TransactionOK);
5056 transaction.request_headers = EXTRA_HEADER;
5057 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5058 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5060 scoped_ptr<Context> c(new Context);
5061 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5062 net::DEFAULT_PRIORITY, &c->trans, NULL));
5064 MockHttpRequest request(transaction);
5065 int rv = c->trans->Start(
5066 &request, c->callback.callback(), net::BoundNetLog());
5067 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5069 // We should have checked with the server before finishing Start().
5070 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5071 EXPECT_EQ(1, cache.disk_cache()->open_count());
5072 EXPECT_EQ(1, cache.disk_cache()->create_count());
5074 RemoveMockTransaction(&kRangeGET_TransactionOK);
5077 // Tests that we cache a 200 response to the validation request.
5078 TEST(HttpCache, GET_IncompleteResource4) {
5079 MockHttpCache cache;
5080 AddMockTransaction(&kRangeGET_TransactionOK);
5082 std::string raw_headers("HTTP/1.1 200 OK\n"
5083 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5084 "ETag: \"foo\"\n"
5085 "Accept-Ranges: bytes\n"
5086 "Content-Length: 80\n");
5087 CreateTruncatedEntry(raw_headers, &cache);
5089 // Now make a regular request.
5090 std::string headers;
5091 MockTransaction transaction(kRangeGET_TransactionOK);
5092 transaction.request_headers = EXTRA_HEADER;
5093 transaction.data = "Not a range";
5094 RangeTransactionServer handler;
5095 handler.set_bad_200(true);
5096 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5098 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5099 EXPECT_EQ(1, cache.disk_cache()->open_count());
5100 EXPECT_EQ(1, cache.disk_cache()->create_count());
5102 // Verify that the disk entry was updated.
5103 disk_cache::Entry* entry;
5104 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5105 EXPECT_EQ(11, entry->GetDataSize(1));
5106 bool truncated = true;
5107 net::HttpResponseInfo response;
5108 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5109 EXPECT_FALSE(truncated);
5110 entry->Close();
5112 RemoveMockTransaction(&kRangeGET_TransactionOK);
5115 // Tests that when we cancel a request that was interrupted, we mark it again
5116 // as truncated.
5117 TEST(HttpCache, GET_CancelIncompleteResource) {
5118 MockHttpCache cache;
5119 AddMockTransaction(&kRangeGET_TransactionOK);
5121 std::string raw_headers("HTTP/1.1 200 OK\n"
5122 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5123 "ETag: \"foo\"\n"
5124 "Accept-Ranges: bytes\n"
5125 "Content-Length: 80\n");
5126 CreateTruncatedEntry(raw_headers, &cache);
5128 // Now make a regular request.
5129 MockTransaction transaction(kRangeGET_TransactionOK);
5130 transaction.request_headers = EXTRA_HEADER;
5132 MockHttpRequest request(transaction);
5133 Context* c = new Context();
5134 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5135 net::DEFAULT_PRIORITY, &c->trans, NULL));
5137 int rv = c->trans->Start(
5138 &request, c->callback.callback(), net::BoundNetLog());
5139 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5141 // Read 20 bytes from the cache, and 10 from the net.
5142 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5143 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5144 EXPECT_EQ(20, c->callback.GetResult(rv));
5145 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5146 EXPECT_EQ(10, c->callback.GetResult(rv));
5148 // At this point, we are already reading so canceling the request should leave
5149 // a truncated one.
5150 delete c;
5152 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5153 EXPECT_EQ(1, cache.disk_cache()->open_count());
5154 EXPECT_EQ(1, cache.disk_cache()->create_count());
5156 // Verify that the disk entry was updated: now we have 30 bytes.
5157 disk_cache::Entry* entry;
5158 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5159 EXPECT_EQ(30, entry->GetDataSize(1));
5160 bool truncated = false;
5161 net::HttpResponseInfo response;
5162 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5163 EXPECT_TRUE(truncated);
5164 entry->Close();
5165 RemoveMockTransaction(&kRangeGET_TransactionOK);
5168 // Tests that we can handle range requests when we have a truncated entry.
5169 TEST(HttpCache, RangeGET_IncompleteResource) {
5170 MockHttpCache cache;
5171 AddMockTransaction(&kRangeGET_TransactionOK);
5173 // Content-length will be intentionally bogus.
5174 std::string raw_headers("HTTP/1.1 200 OK\n"
5175 "Last-Modified: something\n"
5176 "ETag: \"foo\"\n"
5177 "Accept-Ranges: bytes\n"
5178 "Content-Length: 10\n");
5179 CreateTruncatedEntry(raw_headers, &cache);
5181 // Now make a range request.
5182 std::string headers;
5183 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5184 &headers);
5186 Verify206Response(headers, 40, 49);
5187 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5188 EXPECT_EQ(1, cache.disk_cache()->open_count());
5189 EXPECT_EQ(2, cache.disk_cache()->create_count());
5191 RemoveMockTransaction(&kRangeGET_TransactionOK);
5194 TEST(HttpCache, SyncRead) {
5195 MockHttpCache cache;
5197 // This test ensures that a read that completes synchronously does not cause
5198 // any problems.
5200 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5201 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5202 TEST_MODE_SYNC_CACHE_READ |
5203 TEST_MODE_SYNC_CACHE_WRITE);
5205 MockHttpRequest r1(transaction),
5206 r2(transaction),
5207 r3(transaction);
5209 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5210 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5211 c3(net::DEFAULT_PRIORITY, cache.http_cache());
5213 c1.Start(&r1, net::BoundNetLog());
5215 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5216 c2.Start(&r2, net::BoundNetLog());
5218 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5219 c3.Start(&r3, net::BoundNetLog());
5221 base::MessageLoop::current()->Run();
5223 EXPECT_TRUE(c1.is_done());
5224 EXPECT_TRUE(c2.is_done());
5225 EXPECT_TRUE(c3.is_done());
5227 EXPECT_EQ(net::OK, c1.error());
5228 EXPECT_EQ(net::OK, c2.error());
5229 EXPECT_EQ(net::OK, c3.error());
5232 TEST(HttpCache, ValidationResultsIn200) {
5233 MockHttpCache cache;
5235 // This test ensures that a conditional request, which results in a 200
5236 // instead of a 304, properly truncates the existing response data.
5238 // write to the cache
5239 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5241 // force this transaction to validate the cache
5242 MockTransaction transaction(kETagGET_Transaction);
5243 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5244 RunTransactionTest(cache.http_cache(), transaction);
5246 // read from the cache
5247 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5250 TEST(HttpCache, CachedRedirect) {
5251 MockHttpCache cache;
5253 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5254 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5255 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5257 MockHttpRequest request(kTestTransaction);
5258 net::TestCompletionCallback callback;
5260 // write to the cache
5262 scoped_ptr<net::HttpTransaction> trans;
5263 int rv = cache.http_cache()->CreateTransaction(
5264 net::DEFAULT_PRIORITY, &trans, NULL);
5265 EXPECT_EQ(net::OK, rv);
5266 ASSERT_TRUE(trans.get());
5268 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5269 if (rv == net::ERR_IO_PENDING)
5270 rv = callback.WaitForResult();
5271 ASSERT_EQ(net::OK, rv);
5273 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5274 ASSERT_TRUE(info);
5276 EXPECT_EQ(info->headers->response_code(), 301);
5278 std::string location;
5279 info->headers->EnumerateHeader(NULL, "Location", &location);
5280 EXPECT_EQ(location, "http://www.bar.com/");
5282 // Destroy transaction when going out of scope. We have not actually
5283 // read the response body -- want to test that it is still getting cached.
5285 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5286 EXPECT_EQ(0, cache.disk_cache()->open_count());
5287 EXPECT_EQ(1, cache.disk_cache()->create_count());
5289 // read from the cache
5291 scoped_ptr<net::HttpTransaction> trans;
5292 int rv = cache.http_cache()->CreateTransaction(
5293 net::DEFAULT_PRIORITY, &trans, NULL);
5294 EXPECT_EQ(net::OK, rv);
5295 ASSERT_TRUE(trans.get());
5297 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5298 if (rv == net::ERR_IO_PENDING)
5299 rv = callback.WaitForResult();
5300 ASSERT_EQ(net::OK, rv);
5302 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5303 ASSERT_TRUE(info);
5305 EXPECT_EQ(info->headers->response_code(), 301);
5307 std::string location;
5308 info->headers->EnumerateHeader(NULL, "Location", &location);
5309 EXPECT_EQ(location, "http://www.bar.com/");
5311 // Destroy transaction when going out of scope. We have not actually
5312 // read the response body -- want to test that it is still getting cached.
5314 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5315 EXPECT_EQ(1, cache.disk_cache()->open_count());
5316 EXPECT_EQ(1, cache.disk_cache()->create_count());
5319 TEST(HttpCache, CacheControlNoStore) {
5320 MockHttpCache cache;
5322 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5323 transaction.response_headers = "cache-control: no-store\n";
5325 // initial load
5326 RunTransactionTest(cache.http_cache(), transaction);
5328 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5329 EXPECT_EQ(0, cache.disk_cache()->open_count());
5330 EXPECT_EQ(1, cache.disk_cache()->create_count());
5332 // try loading again; it should result in a network fetch
5333 RunTransactionTest(cache.http_cache(), transaction);
5335 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5336 EXPECT_EQ(0, cache.disk_cache()->open_count());
5337 EXPECT_EQ(2, cache.disk_cache()->create_count());
5339 disk_cache::Entry* entry;
5340 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5343 TEST(HttpCache, CacheControlNoStore2) {
5344 // this test is similar to the above test, except that the initial response
5345 // is cachable, but when it is validated, no-store is received causing the
5346 // cached document to be deleted.
5347 MockHttpCache cache;
5349 ScopedMockTransaction transaction(kETagGET_Transaction);
5351 // initial load
5352 RunTransactionTest(cache.http_cache(), transaction);
5354 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5355 EXPECT_EQ(0, cache.disk_cache()->open_count());
5356 EXPECT_EQ(1, cache.disk_cache()->create_count());
5358 // try loading again; it should result in a network fetch
5359 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5360 transaction.response_headers = "cache-control: no-store\n";
5361 RunTransactionTest(cache.http_cache(), transaction);
5363 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5364 EXPECT_EQ(1, cache.disk_cache()->open_count());
5365 EXPECT_EQ(1, cache.disk_cache()->create_count());
5367 disk_cache::Entry* entry;
5368 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5371 TEST(HttpCache, CacheControlNoStore3) {
5372 // this test is similar to the above test, except that the response is a 304
5373 // instead of a 200. this should never happen in practice, but it seems like
5374 // a good thing to verify that we still destroy the cache entry.
5375 MockHttpCache cache;
5377 ScopedMockTransaction transaction(kETagGET_Transaction);
5379 // initial load
5380 RunTransactionTest(cache.http_cache(), transaction);
5382 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5383 EXPECT_EQ(0, cache.disk_cache()->open_count());
5384 EXPECT_EQ(1, cache.disk_cache()->create_count());
5386 // try loading again; it should result in a network fetch
5387 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5388 transaction.response_headers = "cache-control: no-store\n";
5389 transaction.status = "HTTP/1.1 304 Not Modified";
5390 RunTransactionTest(cache.http_cache(), transaction);
5392 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5393 EXPECT_EQ(1, cache.disk_cache()->open_count());
5394 EXPECT_EQ(1, cache.disk_cache()->create_count());
5396 disk_cache::Entry* entry;
5397 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5400 // Ensure that we don't cache requests served over bad HTTPS.
5401 TEST(HttpCache, SimpleGET_SSLError) {
5402 MockHttpCache cache;
5404 MockTransaction transaction = kSimpleGET_Transaction;
5405 transaction.cert_status = net::CERT_STATUS_REVOKED;
5406 ScopedMockTransaction scoped_transaction(transaction);
5408 // write to the cache
5409 RunTransactionTest(cache.http_cache(), transaction);
5411 // Test that it was not cached.
5412 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5414 MockHttpRequest request(transaction);
5415 net::TestCompletionCallback callback;
5417 scoped_ptr<net::HttpTransaction> trans;
5418 int rv = cache.http_cache()->CreateTransaction(
5419 net::DEFAULT_PRIORITY, &trans, NULL);
5420 EXPECT_EQ(net::OK, rv);
5421 ASSERT_TRUE(trans.get());
5423 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5424 if (rv == net::ERR_IO_PENDING)
5425 rv = callback.WaitForResult();
5426 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5429 // Ensure that we don't crash by if left-behind transactions.
5430 TEST(HttpCache, OutlivedTransactions) {
5431 MockHttpCache* cache = new MockHttpCache;
5433 scoped_ptr<net::HttpTransaction> trans;
5434 int rv = cache->http_cache()->CreateTransaction(
5435 net::DEFAULT_PRIORITY, &trans, NULL);
5436 EXPECT_EQ(net::OK, rv);
5438 delete cache;
5439 trans.reset();
5442 // Test that the disabled mode works.
5443 TEST(HttpCache, CacheDisabledMode) {
5444 MockHttpCache cache;
5446 // write to the cache
5447 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5449 // go into disabled mode
5450 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
5452 // force this transaction to write to the cache again
5453 MockTransaction transaction(kSimpleGET_Transaction);
5455 RunTransactionTest(cache.http_cache(), transaction);
5457 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5458 EXPECT_EQ(0, cache.disk_cache()->open_count());
5459 EXPECT_EQ(1, cache.disk_cache()->create_count());
5462 // Other tests check that the response headers of the cached response
5463 // get updated on 304. Here we specifically check that the
5464 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5465 // fields also gets updated.
5466 // http://crbug.com/20594.
5467 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
5468 MockHttpCache cache;
5470 const char* kUrl = "http://foobar";
5471 const char* kData = "body";
5473 MockTransaction mock_network_response = { 0 };
5474 mock_network_response.url = kUrl;
5476 AddMockTransaction(&mock_network_response);
5478 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
5480 MockTransaction request = { 0 };
5481 request.url = kUrl;
5482 request.method = "GET";
5483 request.request_headers = "\r\n";
5484 request.data = kData;
5486 static const Response kNetResponse1 = {
5487 "HTTP/1.1 200 OK",
5488 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
5489 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5490 kData
5493 kNetResponse1.AssignTo(&mock_network_response);
5495 RunTransactionTest(cache.http_cache(), request);
5497 // Request |kUrl| again, this time validating the cache and getting
5498 // a 304 back.
5500 request.load_flags = net::LOAD_VALIDATE_CACHE;
5502 static const Response kNetResponse2 = {
5503 "HTTP/1.1 304 Not Modified",
5504 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
5508 kNetResponse2.AssignTo(&mock_network_response);
5510 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
5511 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
5513 mock_network_response.request_time = request_time;
5514 mock_network_response.response_time = response_time;
5516 net::HttpResponseInfo response;
5517 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
5519 // The request and response times should have been updated.
5520 EXPECT_EQ(request_time.ToInternalValue(),
5521 response.request_time.ToInternalValue());
5522 EXPECT_EQ(response_time.ToInternalValue(),
5523 response.response_time.ToInternalValue());
5525 std::string headers;
5526 response.headers->GetNormalizedHeaders(&headers);
5528 EXPECT_EQ("HTTP/1.1 200 OK\n"
5529 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
5530 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5531 headers);
5533 RemoveMockTransaction(&mock_network_response);
5536 // Tests that we can write metadata to an entry.
5537 TEST(HttpCache, WriteMetadata_OK) {
5538 MockHttpCache cache;
5540 // Write to the cache
5541 net::HttpResponseInfo response;
5542 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5543 &response);
5544 EXPECT_TRUE(response.metadata.get() == NULL);
5546 // Trivial call.
5547 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
5548 Time::Now(), NULL, 0);
5550 // Write meta data to the same entry.
5551 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5552 memset(buf->data(), 0, buf->size());
5553 base::strlcpy(buf->data(), "Hi there", buf->size());
5554 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
5555 net::DEFAULT_PRIORITY,
5556 response.response_time,
5557 buf.get(),
5558 buf->size());
5560 // Release the buffer before the operation takes place.
5561 buf = NULL;
5563 // Makes sure we finish pending operations.
5564 base::MessageLoop::current()->RunUntilIdle();
5566 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5567 &response);
5568 ASSERT_TRUE(response.metadata.get() != NULL);
5569 EXPECT_EQ(50, response.metadata->size());
5570 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5572 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5573 EXPECT_EQ(2, cache.disk_cache()->open_count());
5574 EXPECT_EQ(1, cache.disk_cache()->create_count());
5577 // Tests that we only write metadata to an entry if the time stamp matches.
5578 TEST(HttpCache, WriteMetadata_Fail) {
5579 MockHttpCache cache;
5581 // Write to the cache
5582 net::HttpResponseInfo response;
5583 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5584 &response);
5585 EXPECT_TRUE(response.metadata.get() == NULL);
5587 // Attempt to write meta data to the same entry.
5588 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5589 memset(buf->data(), 0, buf->size());
5590 base::strlcpy(buf->data(), "Hi there", buf->size());
5591 base::Time expected_time = response.response_time -
5592 base::TimeDelta::FromMilliseconds(20);
5593 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
5594 net::DEFAULT_PRIORITY,
5595 expected_time,
5596 buf.get(),
5597 buf->size());
5599 // Makes sure we finish pending operations.
5600 base::MessageLoop::current()->RunUntilIdle();
5602 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5603 &response);
5604 EXPECT_TRUE(response.metadata.get() == NULL);
5606 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5607 EXPECT_EQ(2, cache.disk_cache()->open_count());
5608 EXPECT_EQ(1, cache.disk_cache()->create_count());
5611 // Tests that we can read metadata after validating the entry and with READ mode
5612 // transactions.
5613 TEST(HttpCache, ReadMetadata) {
5614 MockHttpCache cache;
5616 // Write to the cache
5617 net::HttpResponseInfo response;
5618 RunTransactionTestWithResponseInfo(cache.http_cache(),
5619 kTypicalGET_Transaction, &response);
5620 EXPECT_TRUE(response.metadata.get() == NULL);
5622 // Write meta data to the same entry.
5623 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5624 memset(buf->data(), 0, buf->size());
5625 base::strlcpy(buf->data(), "Hi there", buf->size());
5626 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
5627 net::DEFAULT_PRIORITY,
5628 response.response_time,
5629 buf.get(),
5630 buf->size());
5632 // Makes sure we finish pending operations.
5633 base::MessageLoop::current()->RunUntilIdle();
5635 // Start with a READ mode transaction.
5636 MockTransaction trans1(kTypicalGET_Transaction);
5637 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
5639 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5640 ASSERT_TRUE(response.metadata.get() != NULL);
5641 EXPECT_EQ(50, response.metadata->size());
5642 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5644 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5645 EXPECT_EQ(2, cache.disk_cache()->open_count());
5646 EXPECT_EQ(1, cache.disk_cache()->create_count());
5647 base::MessageLoop::current()->RunUntilIdle();
5649 // Now make sure that the entry is re-validated with the server.
5650 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
5651 trans1.status = "HTTP/1.1 304 Not Modified";
5652 AddMockTransaction(&trans1);
5654 response.metadata = NULL;
5655 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5656 EXPECT_TRUE(response.metadata.get() != NULL);
5658 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5659 EXPECT_EQ(3, cache.disk_cache()->open_count());
5660 EXPECT_EQ(1, cache.disk_cache()->create_count());
5661 base::MessageLoop::current()->RunUntilIdle();
5662 RemoveMockTransaction(&trans1);
5664 // Now return 200 when validating the entry so the metadata will be lost.
5665 MockTransaction trans2(kTypicalGET_Transaction);
5666 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5667 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5668 EXPECT_TRUE(response.metadata.get() == NULL);
5670 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5671 EXPECT_EQ(4, cache.disk_cache()->open_count());
5672 EXPECT_EQ(1, cache.disk_cache()->create_count());
5675 // Tests that we don't mark entries as truncated when a filter detects the end
5676 // of the stream.
5677 TEST(HttpCache, FilterCompletion) {
5678 MockHttpCache cache;
5679 net::TestCompletionCallback callback;
5682 scoped_ptr<net::HttpTransaction> trans;
5683 int rv = cache.http_cache()->CreateTransaction(
5684 net::DEFAULT_PRIORITY, &trans, NULL);
5685 EXPECT_EQ(net::OK, rv);
5687 MockHttpRequest request(kSimpleGET_Transaction);
5688 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5689 EXPECT_EQ(net::OK, callback.GetResult(rv));
5691 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5692 rv = trans->Read(buf.get(), 256, callback.callback());
5693 EXPECT_GT(callback.GetResult(rv), 0);
5695 // Now make sure that the entry is preserved.
5696 trans->DoneReading();
5699 // Make sure that the ActiveEntry is gone.
5700 base::MessageLoop::current()->RunUntilIdle();
5702 // Read from the cache.
5703 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5705 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5706 EXPECT_EQ(1, cache.disk_cache()->open_count());
5707 EXPECT_EQ(1, cache.disk_cache()->create_count());
5710 // Tests that we stop cachining when told.
5711 TEST(HttpCache, StopCachingDeletesEntry) {
5712 MockHttpCache cache;
5713 net::TestCompletionCallback callback;
5714 MockHttpRequest request(kSimpleGET_Transaction);
5717 scoped_ptr<net::HttpTransaction> trans;
5718 int rv = cache.http_cache()->CreateTransaction(
5719 net::DEFAULT_PRIORITY, &trans, NULL);
5720 EXPECT_EQ(net::OK, rv);
5722 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5723 EXPECT_EQ(net::OK, callback.GetResult(rv));
5725 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5726 rv = trans->Read(buf.get(), 10, callback.callback());
5727 EXPECT_EQ(callback.GetResult(rv), 10);
5729 trans->StopCaching();
5731 // We should be able to keep reading.
5732 rv = trans->Read(buf.get(), 256, callback.callback());
5733 EXPECT_GT(callback.GetResult(rv), 0);
5734 rv = trans->Read(buf.get(), 256, callback.callback());
5735 EXPECT_EQ(callback.GetResult(rv), 0);
5738 // Make sure that the ActiveEntry is gone.
5739 base::MessageLoop::current()->RunUntilIdle();
5741 // Verify that the entry is gone.
5742 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5744 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5745 EXPECT_EQ(0, cache.disk_cache()->open_count());
5746 EXPECT_EQ(2, cache.disk_cache()->create_count());
5749 // Tests that when we are told to stop caching we don't throw away valid data.
5750 TEST(HttpCache, StopCachingSavesEntry) {
5751 MockHttpCache cache;
5752 net::TestCompletionCallback callback;
5753 MockHttpRequest request(kSimpleGET_Transaction);
5756 scoped_ptr<net::HttpTransaction> trans;
5757 int rv = cache.http_cache()->CreateTransaction(
5758 net::DEFAULT_PRIORITY, &trans, NULL);
5759 EXPECT_EQ(net::OK, rv);
5761 // Force a response that can be resumed.
5762 MockTransaction mock_transaction(kSimpleGET_Transaction);
5763 AddMockTransaction(&mock_transaction);
5764 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
5765 "Content-Length: 42\n"
5766 "Etag: \"foo\"\n";
5768 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5769 EXPECT_EQ(net::OK, callback.GetResult(rv));
5771 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5772 rv = trans->Read(buf.get(), 10, callback.callback());
5773 EXPECT_EQ(callback.GetResult(rv), 10);
5775 trans->StopCaching();
5777 // We should be able to keep reading.
5778 rv = trans->Read(buf.get(), 256, callback.callback());
5779 EXPECT_GT(callback.GetResult(rv), 0);
5780 rv = trans->Read(buf.get(), 256, callback.callback());
5781 EXPECT_EQ(callback.GetResult(rv), 0);
5783 RemoveMockTransaction(&mock_transaction);
5786 // Verify that the entry is marked as incomplete.
5787 disk_cache::Entry* entry;
5788 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5789 net::HttpResponseInfo response;
5790 bool truncated = false;
5791 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5792 EXPECT_TRUE(truncated);
5793 entry->Close();
5796 // Tests that we handle truncated enries when StopCaching is called.
5797 TEST(HttpCache, StopCachingTruncatedEntry) {
5798 MockHttpCache cache;
5799 net::TestCompletionCallback callback;
5800 MockHttpRequest request(kRangeGET_TransactionOK);
5801 request.extra_headers.Clear();
5802 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
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"
5807 "ETag: \"foo\"\n"
5808 "Accept-Ranges: bytes\n"
5809 "Content-Length: 80\n");
5810 CreateTruncatedEntry(raw_headers, &cache);
5813 // Now make a regular request.
5814 scoped_ptr<net::HttpTransaction> trans;
5815 int rv = cache.http_cache()->CreateTransaction(
5816 net::DEFAULT_PRIORITY, &trans, NULL);
5817 EXPECT_EQ(net::OK, rv);
5819 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5820 EXPECT_EQ(net::OK, callback.GetResult(rv));
5822 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5823 rv = trans->Read(buf.get(), 10, callback.callback());
5824 EXPECT_EQ(callback.GetResult(rv), 10);
5826 // This is actually going to do nothing.
5827 trans->StopCaching();
5829 // We should be able to keep reading.
5830 rv = trans->Read(buf.get(), 256, callback.callback());
5831 EXPECT_GT(callback.GetResult(rv), 0);
5832 rv = trans->Read(buf.get(), 256, callback.callback());
5833 EXPECT_GT(callback.GetResult(rv), 0);
5834 rv = trans->Read(buf.get(), 256, callback.callback());
5835 EXPECT_EQ(callback.GetResult(rv), 0);
5838 // Verify that the disk entry was updated.
5839 disk_cache::Entry* entry;
5840 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5841 EXPECT_EQ(80, entry->GetDataSize(1));
5842 bool truncated = true;
5843 net::HttpResponseInfo response;
5844 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5845 EXPECT_FALSE(truncated);
5846 entry->Close();
5848 RemoveMockTransaction(&kRangeGET_TransactionOK);
5851 // Tests that we detect truncated resources from the net when there is
5852 // a Content-Length header.
5853 TEST(HttpCache, TruncatedByContentLength) {
5854 MockHttpCache cache;
5855 net::TestCompletionCallback callback;
5857 MockTransaction transaction(kSimpleGET_Transaction);
5858 AddMockTransaction(&transaction);
5859 transaction.response_headers = "Cache-Control: max-age=10000\n"
5860 "Content-Length: 100\n";
5861 RunTransactionTest(cache.http_cache(), transaction);
5862 RemoveMockTransaction(&transaction);
5864 // Read from the cache.
5865 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5867 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5868 EXPECT_EQ(0, cache.disk_cache()->open_count());
5869 EXPECT_EQ(2, cache.disk_cache()->create_count());
5872 // Tests that we actually flag entries as truncated when we detect an error
5873 // from the net.
5874 TEST(HttpCache, TruncatedByContentLength2) {
5875 MockHttpCache cache;
5876 net::TestCompletionCallback callback;
5878 MockTransaction transaction(kSimpleGET_Transaction);
5879 AddMockTransaction(&transaction);
5880 transaction.response_headers = "Cache-Control: max-age=10000\n"
5881 "Content-Length: 100\n"
5882 "Etag: \"foo\"\n";
5883 RunTransactionTest(cache.http_cache(), transaction);
5884 RemoveMockTransaction(&transaction);
5886 // Verify that the entry is marked as incomplete.
5887 disk_cache::Entry* entry;
5888 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5889 net::HttpResponseInfo response;
5890 bool truncated = false;
5891 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5892 EXPECT_TRUE(truncated);
5893 entry->Close();
5896 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit_TransactionDelegate) {
5897 MockHttpCache cache;
5899 // Write to the cache.
5900 RunTransactionTestWithDelegate(cache.http_cache(),
5901 kSimpleGET_Transaction,
5905 // Force this transaction to read from the cache.
5906 MockTransaction transaction(kSimpleGET_Transaction);
5907 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5909 RunTransactionTestWithDelegate(cache.http_cache(),
5910 kSimpleGET_Transaction,
5915 // Make sure that calling SetPriority on a cache transaction passes on
5916 // its priority updates to its underlying network transaction.
5917 TEST(HttpCache, SetPriority) {
5918 MockHttpCache cache;
5920 scoped_ptr<net::HttpTransaction> trans;
5921 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5922 net::IDLE, &trans, NULL));
5923 ASSERT_TRUE(trans.get());
5925 // Shouldn't crash, but doesn't do anything either.
5926 trans->SetPriority(net::LOW);
5928 EXPECT_FALSE(cache.network_layer()->last_transaction());
5929 EXPECT_EQ(net::DEFAULT_PRIORITY,
5930 cache.network_layer()->last_create_transaction_priority());
5932 net::HttpRequestInfo info;
5933 info.url = GURL(kSimpleGET_Transaction.url);
5934 net::TestCompletionCallback callback;
5935 EXPECT_EQ(net::ERR_IO_PENDING,
5936 trans->Start(&info, callback.callback(), net::BoundNetLog()));
5938 ASSERT_TRUE(cache.network_layer()->last_transaction());
5939 EXPECT_EQ(net::LOW,
5940 cache.network_layer()->last_create_transaction_priority());
5941 EXPECT_EQ(net::LOW,
5942 cache.network_layer()->last_transaction()->priority());
5944 trans->SetPriority(net::HIGHEST);
5945 EXPECT_EQ(net::LOW,
5946 cache.network_layer()->last_create_transaction_priority());
5947 EXPECT_EQ(net::HIGHEST,
5948 cache.network_layer()->last_transaction()->priority());
5950 EXPECT_EQ(net::OK, callback.WaitForResult());
5953 // Make sure that a cache transaction passes on its priority to
5954 // newly-created network transactions.
5955 TEST(HttpCache, SetPriorityNewTransaction) {
5956 MockHttpCache cache;
5957 AddMockTransaction(&kRangeGET_TransactionOK);
5959 std::string raw_headers("HTTP/1.1 200 OK\n"
5960 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5961 "ETag: \"foo\"\n"
5962 "Accept-Ranges: bytes\n"
5963 "Content-Length: 80\n");
5964 CreateTruncatedEntry(raw_headers, &cache);
5966 // Now make a regular request.
5967 std::string headers;
5968 MockTransaction transaction(kRangeGET_TransactionOK);
5969 transaction.request_headers = EXTRA_HEADER;
5970 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5971 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5973 scoped_ptr<net::HttpTransaction> trans;
5974 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5975 net::MEDIUM, &trans, NULL));
5976 ASSERT_TRUE(trans.get());
5977 EXPECT_EQ(net::DEFAULT_PRIORITY,
5978 cache.network_layer()->last_create_transaction_priority());
5980 MockHttpRequest info(transaction);
5981 net::TestCompletionCallback callback;
5982 EXPECT_EQ(net::ERR_IO_PENDING,
5983 trans->Start(&info, callback.callback(), net::BoundNetLog()));
5984 EXPECT_EQ(net::OK, callback.WaitForResult());
5986 EXPECT_EQ(net::MEDIUM,
5987 cache.network_layer()->last_create_transaction_priority());
5989 trans->SetPriority(net::HIGHEST);
5990 // Should trigger a new network transaction and pick up the new
5991 // priority.
5992 ReadAndVerifyTransaction(trans.get(), transaction);
5994 EXPECT_EQ(net::HIGHEST,
5995 cache.network_layer()->last_create_transaction_priority());
5997 RemoveMockTransaction(&kRangeGET_TransactionOK);