Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blobd318e9180b6380369f02a42910b327ad0268df9d
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 <algorithm>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/test/simple_test_clock.h"
17 #include "net/base/cache_type.h"
18 #include "net/base/elements_upload_data_stream.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/load_flags.h"
21 #include "net/base/load_timing_info.h"
22 #include "net/base/load_timing_info_test_util.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/upload_bytes_element_reader.h"
25 #include "net/cert/cert_status_flags.h"
26 #include "net/disk_cache/disk_cache.h"
27 #include "net/http/http_byte_range.h"
28 #include "net/http/http_cache_transaction.h"
29 #include "net/http/http_request_headers.h"
30 #include "net/http/http_request_info.h"
31 #include "net/http/http_response_headers.h"
32 #include "net/http/http_response_info.h"
33 #include "net/http/http_transaction.h"
34 #include "net/http/http_transaction_test_util.h"
35 #include "net/http/http_util.h"
36 #include "net/http/mock_http_cache.h"
37 #include "net/log/net_log_unittest.h"
38 #include "net/socket/client_socket_handle.h"
39 #include "net/ssl/ssl_cert_request_info.h"
40 #include "net/websockets/websocket_handshake_stream_base.h"
41 #include "testing/gtest/include/gtest/gtest.h"
43 using base::Time;
45 namespace net {
47 namespace {
49 // Tests the load timing values of a request that goes through a
50 // MockNetworkTransaction.
51 void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
52 EXPECT_FALSE(load_timing_info.socket_reused);
53 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
55 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
56 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
58 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
59 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
60 EXPECT_LE(load_timing_info.connect_timing.connect_end,
61 load_timing_info.send_start);
63 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
65 // Set by URLRequest / URLRequestHttpJob, at a higher level.
66 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
67 EXPECT_TRUE(load_timing_info.request_start.is_null());
68 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
71 // Tests the load timing values of a request that receives a cached response.
72 void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
73 EXPECT_FALSE(load_timing_info.socket_reused);
74 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
76 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
77 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
79 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
81 // Only the send start / end times should be sent, and they should have the
82 // same value.
83 EXPECT_FALSE(load_timing_info.send_start.is_null());
84 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
86 // Set by URLRequest / URLRequestHttpJob, at a higher level.
87 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
88 EXPECT_TRUE(load_timing_info.request_start.is_null());
89 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
92 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
93 public:
94 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
95 : cache_(cache),
96 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
97 base::Unretained(this))) {
100 const CompletionCallback& callback() const { return callback_; }
102 private:
103 void OnComplete(int result) {
104 delete cache_;
105 SetResult(result);
108 MockHttpCache* cache_;
109 CompletionCallback callback_;
111 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
114 //-----------------------------------------------------------------------------
115 // helpers
117 void ReadAndVerifyTransaction(HttpTransaction* trans,
118 const MockTransaction& trans_info) {
119 std::string content;
120 int rv = ReadTransaction(trans, &content);
122 EXPECT_EQ(OK, rv);
123 std::string expected(trans_info.data);
124 EXPECT_EQ(expected, content);
127 void RunTransactionTestBase(HttpCache* cache,
128 const MockTransaction& trans_info,
129 const MockHttpRequest& request,
130 HttpResponseInfo* response_info,
131 const BoundNetLog& net_log,
132 LoadTimingInfo* load_timing_info,
133 int64* received_bytes) {
134 TestCompletionCallback callback;
136 // write to the cache
138 scoped_ptr<HttpTransaction> trans;
139 int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
140 EXPECT_EQ(OK, rv);
141 ASSERT_TRUE(trans.get());
143 rv = trans->Start(&request, callback.callback(), net_log);
144 if (rv == ERR_IO_PENDING)
145 rv = callback.WaitForResult();
146 ASSERT_EQ(trans_info.return_code, rv);
148 if (OK != rv)
149 return;
151 const HttpResponseInfo* response = trans->GetResponseInfo();
152 ASSERT_TRUE(response);
154 if (response_info)
155 *response_info = *response;
157 if (load_timing_info) {
158 // If a fake network connection is used, need a NetLog to get a fake socket
159 // ID.
160 EXPECT_TRUE(net_log.net_log());
161 *load_timing_info = LoadTimingInfo();
162 trans->GetLoadTimingInfo(load_timing_info);
165 ReadAndVerifyTransaction(trans.get(), trans_info);
167 if (received_bytes)
168 *received_bytes = trans->GetTotalReceivedBytes();
171 void RunTransactionTestWithRequest(HttpCache* cache,
172 const MockTransaction& trans_info,
173 const MockHttpRequest& request,
174 HttpResponseInfo* response_info) {
175 RunTransactionTestBase(cache, trans_info, request, response_info,
176 BoundNetLog(), NULL, NULL);
179 void RunTransactionTestAndGetTiming(HttpCache* cache,
180 const MockTransaction& trans_info,
181 const BoundNetLog& log,
182 LoadTimingInfo* load_timing_info) {
183 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
184 NULL, log, load_timing_info, NULL);
187 void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
188 RunTransactionTestAndGetTiming(cache, trans_info, BoundNetLog(), NULL);
191 void RunTransactionTestWithLog(HttpCache* cache,
192 const MockTransaction& trans_info,
193 const BoundNetLog& log) {
194 RunTransactionTestAndGetTiming(cache, trans_info, log, NULL);
197 void RunTransactionTestWithResponseInfo(HttpCache* cache,
198 const MockTransaction& trans_info,
199 HttpResponseInfo* response) {
200 RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
201 response);
204 void RunTransactionTestWithResponseInfoAndGetTiming(
205 HttpCache* cache,
206 const MockTransaction& trans_info,
207 HttpResponseInfo* response,
208 const BoundNetLog& log,
209 LoadTimingInfo* load_timing_info) {
210 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
211 response, log, load_timing_info, NULL);
214 void RunTransactionTestWithResponse(HttpCache* cache,
215 const MockTransaction& trans_info,
216 std::string* response_headers) {
217 HttpResponseInfo response;
218 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
219 response.headers->GetNormalizedHeaders(response_headers);
222 void RunTransactionTestWithResponseAndGetTiming(
223 HttpCache* cache,
224 const MockTransaction& trans_info,
225 std::string* response_headers,
226 const BoundNetLog& log,
227 LoadTimingInfo* load_timing_info) {
228 HttpResponseInfo response;
229 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
230 &response, log, load_timing_info, NULL);
231 response.headers->GetNormalizedHeaders(response_headers);
234 // This class provides a handler for kFastNoStoreGET_Transaction so that the
235 // no-store header can be included on demand.
236 class FastTransactionServer {
237 public:
238 FastTransactionServer() {
239 no_store = false;
241 ~FastTransactionServer() {}
243 void set_no_store(bool value) { no_store = value; }
245 static void FastNoStoreHandler(const HttpRequestInfo* request,
246 std::string* response_status,
247 std::string* response_headers,
248 std::string* response_data) {
249 if (no_store)
250 *response_headers = "Cache-Control: no-store\n";
253 private:
254 static bool no_store;
255 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
257 bool FastTransactionServer::no_store;
259 const MockTransaction kFastNoStoreGET_Transaction = {
260 "http://www.google.com/nostore",
261 "GET",
262 base::Time(),
264 LOAD_VALIDATE_CACHE,
265 "HTTP/1.1 200 OK",
266 "Cache-Control: max-age=10000\n",
267 base::Time(),
268 "<html><body>Google Blah Blah</body></html>",
269 TEST_MODE_SYNC_NET_START,
270 &FastTransactionServer::FastNoStoreHandler,
272 OK};
274 // This class provides a handler for kRangeGET_TransactionOK so that the range
275 // request can be served on demand.
276 class RangeTransactionServer {
277 public:
278 RangeTransactionServer() {
279 not_modified_ = false;
280 modified_ = false;
281 bad_200_ = false;
283 ~RangeTransactionServer() {
284 not_modified_ = false;
285 modified_ = false;
286 bad_200_ = false;
289 // Returns only 416 or 304 when set.
290 void set_not_modified(bool value) { not_modified_ = value; }
292 // Returns 206 when revalidating a range (instead of 304).
293 void set_modified(bool value) { modified_ = value; }
295 // Returns 200 instead of 206 (a malformed response overall).
296 void set_bad_200(bool value) { bad_200_ = value; }
298 // Other than regular range related behavior (and the flags mentioned above),
299 // the server reacts to requests headers like so:
300 // X-Require-Mock-Auth -> return 401.
301 // X-Return-Default-Range -> assume 40-49 was requested.
302 static void RangeHandler(const HttpRequestInfo* request,
303 std::string* response_status,
304 std::string* response_headers,
305 std::string* response_data);
307 private:
308 static bool not_modified_;
309 static bool modified_;
310 static bool bad_200_;
311 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
313 bool RangeTransactionServer::not_modified_ = false;
314 bool RangeTransactionServer::modified_ = false;
315 bool RangeTransactionServer::bad_200_ = false;
317 // A dummy extra header that must be preserved on a given request.
319 // EXTRA_HEADER_LINE doesn't include a line terminator because it
320 // will be passed to AddHeaderFromString() which doesn't accept them.
321 #define EXTRA_HEADER_LINE "Extra: header"
323 // EXTRA_HEADER contains a line terminator, as expected by
324 // AddHeadersFromString() (_not_ AddHeaderFromString()).
325 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
327 static const char kExtraHeaderKey[] = "Extra";
329 // Static.
330 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
331 std::string* response_status,
332 std::string* response_headers,
333 std::string* response_data) {
334 if (request->extra_headers.IsEmpty()) {
335 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
336 response_data->clear();
337 return;
340 // We want to make sure we don't delete extra headers.
341 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
343 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
344 !request->extra_headers.HasHeader("Authorization")) {
345 response_status->assign("HTTP/1.1 401 Unauthorized");
346 response_data->assign("WWW-Authenticate: Foo\n");
347 return;
350 if (not_modified_) {
351 response_status->assign("HTTP/1.1 304 Not Modified");
352 response_data->clear();
353 return;
356 std::vector<HttpByteRange> ranges;
357 std::string range_header;
358 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
359 &range_header) ||
360 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
361 ranges.size() != 1) {
362 // This is not a byte range request. We return 200.
363 response_status->assign("HTTP/1.1 200 OK");
364 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
365 response_data->assign("Not a range");
366 return;
369 // We can handle this range request.
370 HttpByteRange byte_range = ranges[0];
372 if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
373 byte_range.set_first_byte_position(40);
374 byte_range.set_last_byte_position(49);
377 if (byte_range.first_byte_position() > 79) {
378 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
379 response_data->clear();
380 return;
383 EXPECT_TRUE(byte_range.ComputeBounds(80));
384 int start = static_cast<int>(byte_range.first_byte_position());
385 int end = static_cast<int>(byte_range.last_byte_position());
387 EXPECT_LT(end, 80);
389 std::string content_range = base::StringPrintf(
390 "Content-Range: bytes %d-%d/80\n", start, end);
391 response_headers->append(content_range);
393 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
394 std::string data;
395 if (end == start) {
396 EXPECT_EQ(0, end % 10);
397 data = "r";
398 } else {
399 EXPECT_EQ(9, (end - start) % 10);
400 for (int block_start = start; block_start < end; block_start += 10) {
401 base::StringAppendF(&data, "rg: %02d-%02d ",
402 block_start, block_start + 9);
405 *response_data = data;
407 if (end - start != 9) {
408 // We also have to fix content-length.
409 int len = end - start + 1;
410 std::string content_length = base::StringPrintf("Content-Length: %d\n",
411 len);
412 response_headers->replace(response_headers->find("Content-Length:"),
413 content_length.size(), content_length);
415 } else {
416 response_status->assign("HTTP/1.1 304 Not Modified");
417 response_data->clear();
421 const MockTransaction kRangeGET_TransactionOK = {
422 "http://www.google.com/range",
423 "GET",
424 base::Time(),
425 "Range: bytes = 40-49\r\n" EXTRA_HEADER,
426 LOAD_NORMAL,
427 "HTTP/1.1 206 Partial Content",
428 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
429 "ETag: \"foo\"\n"
430 "Accept-Ranges: bytes\n"
431 "Content-Length: 10\n",
432 base::Time(),
433 "rg: 40-49 ",
434 TEST_MODE_NORMAL,
435 &RangeTransactionServer::RangeHandler,
437 OK};
439 const char kFullRangeData[] =
440 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
441 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
443 // Verifies the response headers (|response|) match a partial content
444 // response for the range starting at |start| and ending at |end|.
445 void Verify206Response(std::string response, int start, int end) {
446 std::string raw_headers(
447 HttpUtil::AssembleRawHeaders(response.data(), response.size()));
448 scoped_refptr<HttpResponseHeaders> headers(
449 new HttpResponseHeaders(raw_headers));
451 ASSERT_EQ(206, headers->response_code());
453 int64 range_start, range_end, object_size;
454 ASSERT_TRUE(
455 headers->GetContentRange(&range_start, &range_end, &object_size));
456 int64 content_length = headers->GetContentLength();
458 int length = end - start + 1;
459 ASSERT_EQ(length, content_length);
460 ASSERT_EQ(start, range_start);
461 ASSERT_EQ(end, range_end);
464 // Creates a truncated entry that can be resumed using byte ranges.
465 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
466 // Create a disk cache entry that stores an incomplete resource.
467 disk_cache::Entry* entry;
468 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
469 NULL));
471 raw_headers =
472 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
474 HttpResponseInfo response;
475 response.response_time = base::Time::Now();
476 response.request_time = base::Time::Now();
477 response.headers = new HttpResponseHeaders(raw_headers);
478 // Set the last argument for this to be an incomplete request.
479 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
481 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
482 int len = static_cast<int>(base::strlcpy(buf->data(),
483 "rg: 00-09 rg: 10-19 ", 100));
484 TestCompletionCallback cb;
485 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
486 EXPECT_EQ(len, cb.GetResult(rv));
487 entry->Close();
490 // Helper to represent a network HTTP response.
491 struct Response {
492 // Set this response into |trans|.
493 void AssignTo(MockTransaction* trans) const {
494 trans->status = status;
495 trans->response_headers = headers;
496 trans->data = body;
499 std::string status_and_headers() const {
500 return std::string(status) + "\n" + std::string(headers);
503 const char* status;
504 const char* headers;
505 const char* body;
508 struct Context {
509 Context() : result(ERR_IO_PENDING) {}
511 int result;
512 TestCompletionCallback callback;
513 scoped_ptr<HttpTransaction> trans;
516 class FakeWebSocketHandshakeStreamCreateHelper
517 : public WebSocketHandshakeStreamBase::CreateHelper {
518 public:
519 ~FakeWebSocketHandshakeStreamCreateHelper() override {}
520 WebSocketHandshakeStreamBase* CreateBasicStream(
521 scoped_ptr<ClientSocketHandle> connect,
522 bool using_proxy) override {
523 return NULL;
525 WebSocketHandshakeStreamBase* CreateSpdyStream(
526 const base::WeakPtr<SpdySession>& session,
527 bool use_relative_url) override {
528 return NULL;
532 // Returns true if |entry| is not one of the log types paid attention to in this
533 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
534 // ignored.
535 bool ShouldIgnoreLogEntry(const TestNetLog::CapturedEntry& entry) {
536 switch (entry.type) {
537 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
538 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
539 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
540 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
541 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
542 case NetLog::TYPE_HTTP_CACHE_READ_INFO:
543 return false;
544 default:
545 return true;
549 // Modifies |entries| to only include log entries created by the cache layer and
550 // asserted on in these tests.
551 void FilterLogEntries(TestNetLog::CapturedEntryList* entries) {
552 entries->erase(std::remove_if(entries->begin(), entries->end(),
553 &ShouldIgnoreLogEntry),
554 entries->end());
557 bool LogContainsEventType(const BoundTestNetLog& log,
558 NetLog::EventType expected) {
559 TestNetLog::CapturedEntryList entries;
560 log.GetEntries(&entries);
561 for (size_t i = 0; i < entries.size(); i++) {
562 if (entries[i].type == expected)
563 return true;
565 return false;
568 } // namespace
571 //-----------------------------------------------------------------------------
572 // Tests.
574 TEST(HttpCache, CreateThenDestroy) {
575 MockHttpCache cache;
577 scoped_ptr<HttpTransaction> trans;
578 EXPECT_EQ(OK, cache.CreateTransaction(&trans));
579 ASSERT_TRUE(trans.get());
582 TEST(HttpCache, GetBackend) {
583 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
585 disk_cache::Backend* backend;
586 TestCompletionCallback cb;
587 // This will lazily initialize the backend.
588 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
589 EXPECT_EQ(OK, cb.GetResult(rv));
592 TEST(HttpCache, SimpleGET) {
593 MockHttpCache cache;
594 BoundTestNetLog log;
595 LoadTimingInfo load_timing_info;
597 // Write to the cache.
598 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
599 log.bound(), &load_timing_info);
601 EXPECT_EQ(1, cache.network_layer()->transaction_count());
602 EXPECT_EQ(0, cache.disk_cache()->open_count());
603 EXPECT_EQ(1, cache.disk_cache()->create_count());
604 TestLoadTimingNetworkRequest(load_timing_info);
607 TEST(HttpCache, SimpleGETNoDiskCache) {
608 MockHttpCache cache;
610 cache.disk_cache()->set_fail_requests();
612 BoundTestNetLog log;
613 LoadTimingInfo load_timing_info;
615 // Read from the network, and don't use the cache.
616 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
617 log.bound(), &load_timing_info);
619 // Check that the NetLog was filled as expected.
620 // (We attempted to both Open and Create entries, but both failed).
621 TestNetLog::CapturedEntryList entries;
622 log.GetEntries(&entries);
623 FilterLogEntries(&entries);
625 EXPECT_EQ(6u, entries.size());
626 EXPECT_TRUE(
627 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
628 EXPECT_TRUE(
629 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
630 EXPECT_TRUE(
631 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
632 EXPECT_TRUE(
633 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
634 EXPECT_TRUE(
635 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
636 EXPECT_TRUE(
637 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
639 EXPECT_EQ(1, cache.network_layer()->transaction_count());
640 EXPECT_EQ(0, cache.disk_cache()->open_count());
641 EXPECT_EQ(0, cache.disk_cache()->create_count());
642 TestLoadTimingNetworkRequest(load_timing_info);
645 TEST(HttpCache, SimpleGETNoDiskCache2) {
646 // This will initialize a cache object with NULL backend.
647 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
648 factory->set_fail(true);
649 factory->FinishCreation(); // We'll complete synchronously.
650 MockHttpCache cache(factory);
652 // Read from the network, and don't use the cache.
653 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
655 EXPECT_EQ(1, cache.network_layer()->transaction_count());
656 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
659 // Tests that IOBuffers are not referenced after IO completes.
660 TEST(HttpCache, ReleaseBuffer) {
661 MockHttpCache cache;
663 // Write to the cache.
664 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
666 MockHttpRequest request(kSimpleGET_Transaction);
667 scoped_ptr<HttpTransaction> trans;
668 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
670 const int kBufferSize = 10;
671 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
672 ReleaseBufferCompletionCallback cb(buffer.get());
674 int rv = trans->Start(&request, cb.callback(), BoundNetLog());
675 EXPECT_EQ(OK, cb.GetResult(rv));
677 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
678 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
681 TEST(HttpCache, SimpleGETWithDiskFailures) {
682 MockHttpCache cache;
684 cache.disk_cache()->set_soft_failures(true);
686 // Read from the network, and fail to write to the cache.
687 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
689 EXPECT_EQ(1, cache.network_layer()->transaction_count());
690 EXPECT_EQ(0, cache.disk_cache()->open_count());
691 EXPECT_EQ(1, cache.disk_cache()->create_count());
693 // This one should see an empty cache again.
694 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
696 EXPECT_EQ(2, cache.network_layer()->transaction_count());
697 EXPECT_EQ(0, cache.disk_cache()->open_count());
698 EXPECT_EQ(2, cache.disk_cache()->create_count());
701 // Tests that disk failures after the transaction has started don't cause the
702 // request to fail.
703 TEST(HttpCache, SimpleGETWithDiskFailures2) {
704 MockHttpCache cache;
706 MockHttpRequest request(kSimpleGET_Transaction);
708 scoped_ptr<Context> c(new Context());
709 int rv = cache.CreateTransaction(&c->trans);
710 ASSERT_EQ(OK, rv);
712 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
713 EXPECT_EQ(ERR_IO_PENDING, rv);
714 rv = c->callback.WaitForResult();
716 // Start failing request now.
717 cache.disk_cache()->set_soft_failures(true);
719 // We have to open the entry again to propagate the failure flag.
720 disk_cache::Entry* en;
721 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
722 en->Close();
724 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
725 c.reset();
727 EXPECT_EQ(1, cache.network_layer()->transaction_count());
728 EXPECT_EQ(1, cache.disk_cache()->open_count());
729 EXPECT_EQ(1, cache.disk_cache()->create_count());
731 // This one should see an empty cache again.
732 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
734 EXPECT_EQ(2, cache.network_layer()->transaction_count());
735 EXPECT_EQ(1, cache.disk_cache()->open_count());
736 EXPECT_EQ(2, cache.disk_cache()->create_count());
739 // Tests that we handle failures to read from the cache.
740 TEST(HttpCache, SimpleGETWithDiskFailures3) {
741 MockHttpCache cache;
743 // Read from the network, and write to the cache.
744 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
746 EXPECT_EQ(1, cache.network_layer()->transaction_count());
747 EXPECT_EQ(0, cache.disk_cache()->open_count());
748 EXPECT_EQ(1, cache.disk_cache()->create_count());
750 cache.disk_cache()->set_soft_failures(true);
752 // Now fail to read from the cache.
753 scoped_ptr<Context> c(new Context());
754 int rv = cache.CreateTransaction(&c->trans);
755 ASSERT_EQ(OK, rv);
757 MockHttpRequest request(kSimpleGET_Transaction);
758 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
759 EXPECT_EQ(OK, c->callback.GetResult(rv));
761 // Now verify that the entry was removed from the cache.
762 cache.disk_cache()->set_soft_failures(false);
764 EXPECT_EQ(2, cache.network_layer()->transaction_count());
765 EXPECT_EQ(1, cache.disk_cache()->open_count());
766 EXPECT_EQ(2, cache.disk_cache()->create_count());
768 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
770 EXPECT_EQ(3, cache.network_layer()->transaction_count());
771 EXPECT_EQ(1, cache.disk_cache()->open_count());
772 EXPECT_EQ(3, cache.disk_cache()->create_count());
775 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
776 MockHttpCache cache;
778 BoundTestNetLog log;
779 LoadTimingInfo load_timing_info;
781 // Write to the cache.
782 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
783 log.bound(), &load_timing_info);
785 // Check that the NetLog was filled as expected.
786 TestNetLog::CapturedEntryList entries;
787 log.GetEntries(&entries);
788 FilterLogEntries(&entries);
790 EXPECT_EQ(8u, entries.size());
791 EXPECT_TRUE(
792 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
793 EXPECT_TRUE(
794 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
795 EXPECT_TRUE(
796 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
797 EXPECT_TRUE(
798 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
799 EXPECT_TRUE(
800 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
801 EXPECT_TRUE(
802 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
803 EXPECT_TRUE(
804 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
805 EXPECT_TRUE(
806 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
808 TestLoadTimingNetworkRequest(load_timing_info);
810 // Force this transaction to read from the cache.
811 MockTransaction transaction(kSimpleGET_Transaction);
812 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
814 log.Clear();
816 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
817 &load_timing_info);
819 // Check that the NetLog was filled as expected.
820 log.GetEntries(&entries);
821 FilterLogEntries(&entries);
823 EXPECT_EQ(8u, entries.size());
824 EXPECT_TRUE(
825 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
826 EXPECT_TRUE(
827 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
828 EXPECT_TRUE(
829 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
830 EXPECT_TRUE(
831 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
832 EXPECT_TRUE(
833 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
834 EXPECT_TRUE(
835 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
836 EXPECT_TRUE(
837 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO));
838 EXPECT_TRUE(
839 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO));
841 EXPECT_EQ(1, cache.network_layer()->transaction_count());
842 EXPECT_EQ(1, cache.disk_cache()->open_count());
843 EXPECT_EQ(1, cache.disk_cache()->create_count());
844 TestLoadTimingCachedResponse(load_timing_info);
847 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
848 MockHttpCache cache;
850 // force this transaction to read from the cache
851 MockTransaction transaction(kSimpleGET_Transaction);
852 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
854 MockHttpRequest request(transaction);
855 TestCompletionCallback callback;
857 scoped_ptr<HttpTransaction> trans;
858 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
860 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
861 if (rv == ERR_IO_PENDING)
862 rv = callback.WaitForResult();
863 ASSERT_EQ(ERR_CACHE_MISS, rv);
865 trans.reset();
867 EXPECT_EQ(0, cache.network_layer()->transaction_count());
868 EXPECT_EQ(0, cache.disk_cache()->open_count());
869 EXPECT_EQ(0, cache.disk_cache()->create_count());
872 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
873 MockHttpCache cache;
875 // write to the cache
876 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
878 // force this transaction to read from the cache if valid
879 MockTransaction transaction(kSimpleGET_Transaction);
880 transaction.load_flags |= LOAD_PREFERRING_CACHE;
882 RunTransactionTest(cache.http_cache(), transaction);
884 EXPECT_EQ(1, cache.network_layer()->transaction_count());
885 EXPECT_EQ(1, cache.disk_cache()->open_count());
886 EXPECT_EQ(1, cache.disk_cache()->create_count());
889 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
890 MockHttpCache cache;
892 // force this transaction to read from the cache if valid
893 MockTransaction transaction(kSimpleGET_Transaction);
894 transaction.load_flags |= LOAD_PREFERRING_CACHE;
896 RunTransactionTest(cache.http_cache(), transaction);
898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
899 EXPECT_EQ(0, cache.disk_cache()->open_count());
900 EXPECT_EQ(1, cache.disk_cache()->create_count());
903 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
904 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
905 MockHttpCache cache;
907 // Write to the cache.
908 MockTransaction transaction(kSimpleGET_Transaction);
909 transaction.request_headers = "Foo: bar\r\n";
910 transaction.response_headers = "Cache-Control: max-age=10000\n"
911 "Vary: Foo\n";
912 AddMockTransaction(&transaction);
913 RunTransactionTest(cache.http_cache(), transaction);
915 // Read from the cache.
916 transaction.load_flags |= LOAD_PREFERRING_CACHE;
917 RunTransactionTest(cache.http_cache(), transaction);
919 EXPECT_EQ(1, cache.network_layer()->transaction_count());
920 EXPECT_EQ(1, cache.disk_cache()->open_count());
921 EXPECT_EQ(1, cache.disk_cache()->create_count());
922 RemoveMockTransaction(&transaction);
925 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
926 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
927 MockHttpCache cache;
929 // Write to the cache.
930 MockTransaction transaction(kSimpleGET_Transaction);
931 transaction.request_headers = "Foo: bar\r\n";
932 transaction.response_headers = "Cache-Control: max-age=10000\n"
933 "Vary: Foo\n";
934 AddMockTransaction(&transaction);
935 RunTransactionTest(cache.http_cache(), transaction);
937 // Attempt to read from the cache... this is a vary mismatch that must reach
938 // the network again.
939 transaction.load_flags |= LOAD_PREFERRING_CACHE;
940 transaction.request_headers = "Foo: none\r\n";
941 BoundTestNetLog log;
942 LoadTimingInfo load_timing_info;
943 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
944 &load_timing_info);
946 EXPECT_EQ(2, cache.network_layer()->transaction_count());
947 EXPECT_EQ(1, cache.disk_cache()->open_count());
948 EXPECT_EQ(1, cache.disk_cache()->create_count());
949 TestLoadTimingNetworkRequest(load_timing_info);
950 RemoveMockTransaction(&transaction);
953 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
954 // network success
955 TEST(HttpCache, SimpleGET_CacheOverride_Network) {
956 MockHttpCache cache;
958 // Prime cache.
959 MockTransaction transaction(kSimpleGET_Transaction);
960 transaction.load_flags |= LOAD_FROM_CACHE_IF_OFFLINE;
961 transaction.response_headers = "Cache-Control: no-cache\n";
963 AddMockTransaction(&transaction);
964 RunTransactionTest(cache.http_cache(), transaction);
965 EXPECT_EQ(1, cache.network_layer()->transaction_count());
966 EXPECT_EQ(1, cache.disk_cache()->create_count());
967 RemoveMockTransaction(&transaction);
969 // Re-run transaction; make sure the result came from the network,
970 // not the cache.
971 transaction.data = "Changed data.";
972 AddMockTransaction(&transaction);
973 HttpResponseInfo response_info;
974 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
975 &response_info);
977 EXPECT_EQ(2, cache.network_layer()->transaction_count());
978 EXPECT_FALSE(response_info.server_data_unavailable);
979 EXPECT_TRUE(response_info.network_accessed);
981 RemoveMockTransaction(&transaction);
984 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
985 // offline failure
986 TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
987 MockHttpCache cache;
989 // Prime cache.
990 MockTransaction transaction(kSimpleGET_Transaction);
991 transaction.load_flags |= LOAD_FROM_CACHE_IF_OFFLINE;
992 transaction.response_headers = "Cache-Control: no-cache\n";
994 AddMockTransaction(&transaction);
995 RunTransactionTest(cache.http_cache(), transaction);
996 EXPECT_EQ(1, cache.network_layer()->transaction_count());
997 EXPECT_EQ(1, cache.disk_cache()->create_count());
998 RemoveMockTransaction(&transaction);
1000 // Network failure with offline error; should return cache entry above +
1001 // flag signalling stale data.
1002 transaction.return_code = ERR_NAME_NOT_RESOLVED;
1003 AddMockTransaction(&transaction);
1005 MockHttpRequest request(transaction);
1006 TestCompletionCallback callback;
1007 scoped_ptr<HttpTransaction> trans;
1008 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
1009 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1010 EXPECT_EQ(OK, callback.GetResult(rv));
1012 const HttpResponseInfo* response_info = trans->GetResponseInfo();
1013 ASSERT_TRUE(response_info);
1014 EXPECT_TRUE(response_info->server_data_unavailable);
1015 EXPECT_TRUE(response_info->was_cached);
1016 EXPECT_FALSE(response_info->network_accessed);
1017 ReadAndVerifyTransaction(trans.get(), transaction);
1018 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1020 RemoveMockTransaction(&transaction);
1023 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1024 // non-offline failure.
1025 TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
1026 MockHttpCache cache;
1028 // Prime cache.
1029 MockTransaction transaction(kSimpleGET_Transaction);
1030 transaction.load_flags |= LOAD_FROM_CACHE_IF_OFFLINE;
1031 transaction.response_headers = "Cache-Control: no-cache\n";
1033 AddMockTransaction(&transaction);
1034 RunTransactionTest(cache.http_cache(), transaction);
1035 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1036 EXPECT_EQ(1, cache.disk_cache()->create_count());
1037 RemoveMockTransaction(&transaction);
1039 // Network failure with non-offline error; should fail with that error.
1040 transaction.return_code = ERR_PROXY_CONNECTION_FAILED;
1041 AddMockTransaction(&transaction);
1043 HttpResponseInfo response_info2;
1044 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1045 &response_info2);
1047 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1048 EXPECT_FALSE(response_info2.server_data_unavailable);
1050 RemoveMockTransaction(&transaction);
1053 // Tests that was_cached was set properly on a failure, even if the cached
1054 // response wasn't returned.
1055 TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
1056 MockHttpCache cache;
1058 // Prime cache.
1059 MockTransaction transaction(kSimpleGET_Transaction);
1060 transaction.response_headers = "Cache-Control: no-cache\n";
1062 AddMockTransaction(&transaction);
1063 RunTransactionTest(cache.http_cache(), transaction);
1064 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1065 EXPECT_EQ(1, cache.disk_cache()->create_count());
1066 RemoveMockTransaction(&transaction);
1068 // Network failure with error; should fail but have was_cached set.
1069 transaction.return_code = ERR_FAILED;
1070 AddMockTransaction(&transaction);
1072 MockHttpRequest request(transaction);
1073 TestCompletionCallback callback;
1074 scoped_ptr<HttpTransaction> trans;
1075 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1076 EXPECT_EQ(OK, rv);
1077 ASSERT_TRUE(trans.get());
1078 rv = trans->Start(&request, callback.callback(), BoundNetLog());
1079 EXPECT_EQ(ERR_FAILED, callback.GetResult(rv));
1081 const HttpResponseInfo* response_info = trans->GetResponseInfo();
1082 ASSERT_TRUE(response_info);
1083 EXPECT_TRUE(response_info->was_cached);
1084 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1086 RemoveMockTransaction(&transaction);
1089 // Confirm if we have an empty cache, a read is marked as network verified.
1090 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1091 MockHttpCache cache;
1093 // write to the cache
1094 HttpResponseInfo response_info;
1095 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1096 &response_info);
1098 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1099 EXPECT_EQ(0, cache.disk_cache()->open_count());
1100 EXPECT_EQ(1, cache.disk_cache()->create_count());
1101 EXPECT_TRUE(response_info.network_accessed);
1104 // Confirm if we have a fresh entry in cache, it isn't marked as
1105 // network verified.
1106 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1107 MockHttpCache cache;
1109 // Prime cache.
1110 MockTransaction transaction(kSimpleGET_Transaction);
1112 RunTransactionTest(cache.http_cache(), transaction);
1113 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1114 EXPECT_EQ(1, cache.disk_cache()->create_count());
1116 // Re-run transaction; make sure we don't mark the network as accessed.
1117 HttpResponseInfo response_info;
1118 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1119 &response_info);
1121 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1122 EXPECT_FALSE(response_info.server_data_unavailable);
1123 EXPECT_FALSE(response_info.network_accessed);
1126 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1127 MockHttpCache cache;
1129 // Write to the cache.
1130 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1132 // Force this transaction to write to the cache again.
1133 MockTransaction transaction(kSimpleGET_Transaction);
1134 transaction.load_flags |= LOAD_BYPASS_CACHE;
1136 BoundTestNetLog log;
1137 LoadTimingInfo load_timing_info;
1139 // Write to the cache.
1140 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1141 &load_timing_info);
1143 // Check that the NetLog was filled as expected.
1144 TestNetLog::CapturedEntryList entries;
1145 log.GetEntries(&entries);
1146 FilterLogEntries(&entries);
1148 EXPECT_EQ(8u, entries.size());
1149 EXPECT_TRUE(
1150 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1151 EXPECT_TRUE(
1152 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1153 EXPECT_TRUE(
1154 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1155 EXPECT_TRUE(
1156 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1157 EXPECT_TRUE(
1158 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1159 EXPECT_TRUE(
1160 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1161 EXPECT_TRUE(
1162 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1163 EXPECT_TRUE(
1164 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1166 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1167 EXPECT_EQ(0, cache.disk_cache()->open_count());
1168 EXPECT_EQ(2, cache.disk_cache()->create_count());
1169 TestLoadTimingNetworkRequest(load_timing_info);
1172 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1173 MockHttpCache cache;
1175 // write to the cache
1176 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1178 // force this transaction to write to the cache again
1179 MockTransaction transaction(kSimpleGET_Transaction);
1180 transaction.request_headers = "pragma: no-cache\r\n";
1182 RunTransactionTest(cache.http_cache(), transaction);
1184 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1185 EXPECT_EQ(0, cache.disk_cache()->open_count());
1186 EXPECT_EQ(2, cache.disk_cache()->create_count());
1189 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1190 MockHttpCache cache;
1192 // write to the cache
1193 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1195 // force this transaction to write to the cache again
1196 MockTransaction transaction(kSimpleGET_Transaction);
1197 transaction.request_headers = "cache-control: no-cache\r\n";
1199 RunTransactionTest(cache.http_cache(), transaction);
1201 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1202 EXPECT_EQ(0, cache.disk_cache()->open_count());
1203 EXPECT_EQ(2, cache.disk_cache()->create_count());
1206 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1207 MockHttpCache cache;
1209 // Write to the cache.
1210 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1212 // Read from the cache.
1213 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1215 // Force this transaction to validate the cache.
1216 MockTransaction transaction(kSimpleGET_Transaction);
1217 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1219 HttpResponseInfo response_info;
1220 BoundTestNetLog log;
1221 LoadTimingInfo load_timing_info;
1222 RunTransactionTestWithResponseInfoAndGetTiming(
1223 cache.http_cache(), transaction, &response_info, log.bound(),
1224 &load_timing_info);
1226 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1227 EXPECT_EQ(1, cache.disk_cache()->open_count());
1228 EXPECT_EQ(1, cache.disk_cache()->create_count());
1229 EXPECT_TRUE(response_info.network_accessed);
1230 TestLoadTimingNetworkRequest(load_timing_info);
1233 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1234 MockHttpCache cache;
1236 // write to the cache
1237 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1239 // read from the cache
1240 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1242 // force this transaction to validate the cache
1243 MockTransaction transaction(kSimpleGET_Transaction);
1244 transaction.request_headers = "cache-control: max-age=0\r\n";
1246 RunTransactionTest(cache.http_cache(), transaction);
1248 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1249 EXPECT_EQ(1, cache.disk_cache()->open_count());
1250 EXPECT_EQ(1, cache.disk_cache()->create_count());
1253 static void PreserveRequestHeaders_Handler(const HttpRequestInfo* request,
1254 std::string* response_status,
1255 std::string* response_headers,
1256 std::string* response_data) {
1257 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1260 // Tests that we don't remove extra headers for simple requests.
1261 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1262 MockHttpCache cache;
1264 MockTransaction transaction(kSimpleGET_Transaction);
1265 transaction.handler = PreserveRequestHeaders_Handler;
1266 transaction.request_headers = EXTRA_HEADER;
1267 transaction.response_headers = "Cache-Control: max-age=0\n";
1268 AddMockTransaction(&transaction);
1270 // Write, then revalidate the entry.
1271 RunTransactionTest(cache.http_cache(), transaction);
1272 RunTransactionTest(cache.http_cache(), transaction);
1274 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1275 EXPECT_EQ(1, cache.disk_cache()->open_count());
1276 EXPECT_EQ(1, cache.disk_cache()->create_count());
1277 RemoveMockTransaction(&transaction);
1280 // Tests that we don't remove extra headers for conditionalized requests.
1281 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1282 MockHttpCache cache;
1284 // Write to the cache.
1285 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1287 MockTransaction transaction(kETagGET_Transaction);
1288 transaction.handler = PreserveRequestHeaders_Handler;
1289 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1290 EXTRA_HEADER;
1291 AddMockTransaction(&transaction);
1293 RunTransactionTest(cache.http_cache(), transaction);
1295 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1296 EXPECT_EQ(1, cache.disk_cache()->open_count());
1297 EXPECT_EQ(1, cache.disk_cache()->create_count());
1298 RemoveMockTransaction(&transaction);
1301 TEST(HttpCache, SimpleGET_ManyReaders) {
1302 MockHttpCache cache;
1304 MockHttpRequest request(kSimpleGET_Transaction);
1306 std::vector<Context*> context_list;
1307 const int kNumTransactions = 5;
1309 for (int i = 0; i < kNumTransactions; ++i) {
1310 context_list.push_back(new Context());
1311 Context* c = context_list[i];
1313 c->result = cache.CreateTransaction(&c->trans);
1314 ASSERT_EQ(OK, c->result);
1315 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1317 c->result =
1318 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1321 // All requests are waiting for the active entry.
1322 for (int i = 0; i < kNumTransactions; ++i) {
1323 Context* c = context_list[i];
1324 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1327 // Allow all requests to move from the Create queue to the active entry.
1328 base::MessageLoop::current()->RunUntilIdle();
1330 // The first request should be a writer at this point, and the subsequent
1331 // requests should be pending.
1333 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1334 EXPECT_EQ(0, cache.disk_cache()->open_count());
1335 EXPECT_EQ(1, cache.disk_cache()->create_count());
1337 // All requests depend on the writer, and the writer is between Start and
1338 // Read, i.e. idle.
1339 for (int i = 0; i < kNumTransactions; ++i) {
1340 Context* c = context_list[i];
1341 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1344 for (int i = 0; i < kNumTransactions; ++i) {
1345 Context* c = context_list[i];
1346 if (c->result == ERR_IO_PENDING)
1347 c->result = c->callback.WaitForResult();
1348 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1351 // We should not have had to re-open the disk entry
1353 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1354 EXPECT_EQ(0, cache.disk_cache()->open_count());
1355 EXPECT_EQ(1, cache.disk_cache()->create_count());
1357 for (int i = 0; i < kNumTransactions; ++i) {
1358 Context* c = context_list[i];
1359 delete c;
1363 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1364 // If cancelling a request is racing with another request for the same resource
1365 // finishing, we have to make sure that we remove both transactions from the
1366 // entry.
1367 TEST(HttpCache, SimpleGET_RacingReaders) {
1368 MockHttpCache cache;
1370 MockHttpRequest request(kSimpleGET_Transaction);
1371 MockHttpRequest reader_request(kSimpleGET_Transaction);
1372 reader_request.load_flags = LOAD_ONLY_FROM_CACHE;
1374 std::vector<Context*> context_list;
1375 const int kNumTransactions = 5;
1377 for (int i = 0; i < kNumTransactions; ++i) {
1378 context_list.push_back(new Context());
1379 Context* c = context_list[i];
1381 c->result = cache.CreateTransaction(&c->trans);
1382 ASSERT_EQ(OK, c->result);
1384 MockHttpRequest* this_request = &request;
1385 if (i == 1 || i == 2)
1386 this_request = &reader_request;
1388 c->result =
1389 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
1392 // Allow all requests to move from the Create queue to the active entry.
1393 base::MessageLoop::current()->RunUntilIdle();
1395 // The first request should be a writer at this point, and the subsequent
1396 // requests should be pending.
1398 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1399 EXPECT_EQ(0, cache.disk_cache()->open_count());
1400 EXPECT_EQ(1, cache.disk_cache()->create_count());
1402 Context* c = context_list[0];
1403 ASSERT_EQ(ERR_IO_PENDING, c->result);
1404 c->result = c->callback.WaitForResult();
1405 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1407 // Now we have 2 active readers and two queued transactions.
1409 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1410 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE,
1411 context_list[3]->trans->GetLoadState());
1413 c = context_list[1];
1414 ASSERT_EQ(ERR_IO_PENDING, c->result);
1415 c->result = c->callback.WaitForResult();
1416 if (c->result == OK)
1417 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1419 // At this point we have one reader, two pending transactions and a task on
1420 // the queue to move to the next transaction. Now we cancel the request that
1421 // is the current reader, and expect the queued task to be able to start the
1422 // next request.
1424 c = context_list[2];
1425 c->trans.reset();
1427 for (int i = 3; i < kNumTransactions; ++i) {
1428 Context* c = context_list[i];
1429 if (c->result == ERR_IO_PENDING)
1430 c->result = c->callback.WaitForResult();
1431 if (c->result == OK)
1432 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1435 // We should not have had to re-open the disk entry.
1437 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1438 EXPECT_EQ(0, cache.disk_cache()->open_count());
1439 EXPECT_EQ(1, cache.disk_cache()->create_count());
1441 for (int i = 0; i < kNumTransactions; ++i) {
1442 Context* c = context_list[i];
1443 delete c;
1447 // Tests that we can doom an entry with pending transactions and delete one of
1448 // the pending transactions before the first one completes.
1449 // See http://code.google.com/p/chromium/issues/detail?id=25588
1450 TEST(HttpCache, SimpleGET_DoomWithPending) {
1451 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1452 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
1454 MockHttpRequest request(kSimpleGET_Transaction);
1455 MockHttpRequest writer_request(kSimpleGET_Transaction);
1456 writer_request.load_flags = LOAD_BYPASS_CACHE;
1458 ScopedVector<Context> context_list;
1459 const int kNumTransactions = 4;
1461 for (int i = 0; i < kNumTransactions; ++i) {
1462 context_list.push_back(new Context());
1463 Context* c = context_list[i];
1465 c->result = cache.CreateTransaction(&c->trans);
1466 ASSERT_EQ(OK, c->result);
1468 MockHttpRequest* this_request = &request;
1469 if (i == 3)
1470 this_request = &writer_request;
1472 c->result =
1473 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
1476 // The first request should be a writer at this point, and the two subsequent
1477 // requests should be pending. The last request doomed the first entry.
1479 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1481 // Cancel the first queued transaction.
1482 delete context_list[1];
1483 context_list.get()[1] = NULL;
1485 for (int i = 0; i < kNumTransactions; ++i) {
1486 if (i == 1)
1487 continue;
1488 Context* c = context_list[i];
1489 ASSERT_EQ(ERR_IO_PENDING, c->result);
1490 c->result = c->callback.WaitForResult();
1491 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1495 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1496 // We may attempt to delete an entry synchronously with the act of adding a new
1497 // transaction to said entry.
1498 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1499 MockHttpCache cache;
1501 // The headers will be served right from the call to Start() the request.
1502 MockHttpRequest request(kFastNoStoreGET_Transaction);
1503 FastTransactionServer request_handler;
1504 AddMockTransaction(&kFastNoStoreGET_Transaction);
1506 std::vector<Context*> context_list;
1507 const int kNumTransactions = 3;
1509 for (int i = 0; i < kNumTransactions; ++i) {
1510 context_list.push_back(new Context());
1511 Context* c = context_list[i];
1513 c->result = cache.CreateTransaction(&c->trans);
1514 ASSERT_EQ(OK, c->result);
1516 c->result =
1517 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1520 // Allow all requests to move from the Create queue to the active entry.
1521 base::MessageLoop::current()->RunUntilIdle();
1523 // The first request should be a writer at this point, and the subsequent
1524 // requests should be pending.
1526 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1527 EXPECT_EQ(0, cache.disk_cache()->open_count());
1528 EXPECT_EQ(1, cache.disk_cache()->create_count());
1530 // Now, make sure that the second request asks for the entry not to be stored.
1531 request_handler.set_no_store(true);
1533 for (int i = 0; i < kNumTransactions; ++i) {
1534 Context* c = context_list[i];
1535 if (c->result == ERR_IO_PENDING)
1536 c->result = c->callback.WaitForResult();
1537 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1538 delete c;
1541 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1542 EXPECT_EQ(0, cache.disk_cache()->open_count());
1543 EXPECT_EQ(2, cache.disk_cache()->create_count());
1545 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1548 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1549 MockHttpCache cache;
1551 MockHttpRequest request(kSimpleGET_Transaction);
1553 std::vector<Context*> context_list;
1554 const int kNumTransactions = 2;
1556 for (int i = 0; i < kNumTransactions; ++i) {
1557 context_list.push_back(new Context());
1558 Context* c = context_list[i];
1560 c->result = cache.CreateTransaction(&c->trans);
1561 ASSERT_EQ(OK, c->result);
1563 c->result =
1564 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1567 // Allow all requests to move from the Create queue to the active entry.
1568 base::MessageLoop::current()->RunUntilIdle();
1570 // The first request should be a writer at this point, and the subsequent
1571 // requests should be pending.
1573 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1574 EXPECT_EQ(0, cache.disk_cache()->open_count());
1575 EXPECT_EQ(1, cache.disk_cache()->create_count());
1577 for (int i = 0; i < kNumTransactions; ++i) {
1578 Context* c = context_list[i];
1579 if (c->result == ERR_IO_PENDING)
1580 c->result = c->callback.WaitForResult();
1581 // Destroy only the first transaction.
1582 if (i == 0) {
1583 delete c;
1584 context_list[i] = NULL;
1588 // Complete the rest of the transactions.
1589 for (int i = 1; i < kNumTransactions; ++i) {
1590 Context* c = context_list[i];
1591 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1594 // We should have had to re-open the disk entry.
1596 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1597 EXPECT_EQ(0, cache.disk_cache()->open_count());
1598 EXPECT_EQ(2, cache.disk_cache()->create_count());
1600 for (int i = 1; i < kNumTransactions; ++i) {
1601 Context* c = context_list[i];
1602 delete c;
1606 // Tests that we can cancel requests that are queued waiting to open the disk
1607 // cache entry.
1608 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1609 MockHttpCache cache;
1611 MockHttpRequest request(kSimpleGET_Transaction);
1613 std::vector<Context*> context_list;
1614 const int kNumTransactions = 5;
1616 for (int i = 0; i < kNumTransactions; i++) {
1617 context_list.push_back(new Context());
1618 Context* c = context_list[i];
1620 c->result = cache.CreateTransaction(&c->trans);
1621 ASSERT_EQ(OK, c->result);
1623 c->result =
1624 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1627 // The first request should be creating the disk cache entry and the others
1628 // should be pending.
1630 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1631 EXPECT_EQ(0, cache.disk_cache()->open_count());
1632 EXPECT_EQ(1, cache.disk_cache()->create_count());
1634 // Cancel a request from the pending queue.
1635 delete context_list[3];
1636 context_list[3] = NULL;
1638 // Cancel the request that is creating the entry. This will force the pending
1639 // operations to restart.
1640 delete context_list[0];
1641 context_list[0] = NULL;
1643 // Complete the rest of the transactions.
1644 for (int i = 1; i < kNumTransactions; i++) {
1645 Context* c = context_list[i];
1646 if (c) {
1647 c->result = c->callback.GetResult(c->result);
1648 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1652 // We should have had to re-create the disk entry.
1654 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1655 EXPECT_EQ(0, cache.disk_cache()->open_count());
1656 EXPECT_EQ(2, cache.disk_cache()->create_count());
1658 for (int i = 1; i < kNumTransactions; ++i) {
1659 delete context_list[i];
1663 // Tests that we can cancel a single request to open a disk cache entry.
1664 TEST(HttpCache, SimpleGET_CancelCreate) {
1665 MockHttpCache cache;
1667 MockHttpRequest request(kSimpleGET_Transaction);
1669 Context* c = new Context();
1671 c->result = cache.CreateTransaction(&c->trans);
1672 ASSERT_EQ(OK, c->result);
1674 c->result = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1675 EXPECT_EQ(ERR_IO_PENDING, c->result);
1677 // Release the reference that the mock disk cache keeps for this entry, so
1678 // that we test that the http cache handles the cancellation correctly.
1679 cache.disk_cache()->ReleaseAll();
1680 delete c;
1682 base::MessageLoop::current()->RunUntilIdle();
1683 EXPECT_EQ(1, cache.disk_cache()->create_count());
1686 // Tests that we delete/create entries even if multiple requests are queued.
1687 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1688 MockHttpCache cache;
1690 MockHttpRequest request(kSimpleGET_Transaction);
1691 request.load_flags = LOAD_BYPASS_CACHE;
1693 std::vector<Context*> context_list;
1694 const int kNumTransactions = 5;
1696 for (int i = 0; i < kNumTransactions; i++) {
1697 context_list.push_back(new Context());
1698 Context* c = context_list[i];
1700 c->result = cache.CreateTransaction(&c->trans);
1701 ASSERT_EQ(OK, c->result);
1703 c->result =
1704 c->trans->Start(&request, c->callback.callback(), 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 // Tests that a (simulated) timeout allows transactions waiting on the cache
1733 // lock to continue.
1734 TEST(HttpCache, SimpleGET_WriterTimeout) {
1735 MockHttpCache cache;
1736 cache.BypassCacheLock();
1738 MockHttpRequest request(kSimpleGET_Transaction);
1739 Context c1, c2;
1740 ASSERT_EQ(OK, cache.CreateTransaction(&c1.trans));
1741 ASSERT_EQ(ERR_IO_PENDING,
1742 c1.trans->Start(&request, c1.callback.callback(), BoundNetLog()));
1743 ASSERT_EQ(OK, cache.CreateTransaction(&c2.trans));
1744 ASSERT_EQ(ERR_IO_PENDING,
1745 c2.trans->Start(&request, c2.callback.callback(), BoundNetLog()));
1747 // The second request is queued after the first one.
1749 c2.callback.WaitForResult();
1750 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1752 // Complete the first transaction.
1753 c1.callback.WaitForResult();
1754 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1757 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1758 MockHttpCache cache;
1760 // write to the cache
1761 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1763 MockHttpRequest request(kSimpleGET_Transaction);
1764 TestCompletionCallback callback;
1766 scoped_ptr<HttpTransaction> trans;
1767 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
1768 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1769 if (rv == ERR_IO_PENDING)
1770 rv = callback.WaitForResult();
1771 ASSERT_EQ(OK, rv);
1773 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
1774 rv = trans->Read(buf.get(), 256, callback.callback());
1775 EXPECT_EQ(ERR_IO_PENDING, rv);
1777 // Test that destroying the transaction while it is reading from the cache
1778 // works properly.
1779 trans.reset();
1781 // Make sure we pump any pending events, which should include a call to
1782 // HttpCache::Transaction::OnCacheReadCompleted.
1783 base::MessageLoop::current()->RunUntilIdle();
1786 // Tests that we can delete the HttpCache and deal with queued transactions
1787 // ("waiting for the backend" as opposed to Active or Doomed entries).
1788 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1789 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1790 new MockBackendNoCbFactory()));
1792 MockHttpRequest request(kSimpleGET_Transaction);
1794 std::vector<Context*> context_list;
1795 const int kNumTransactions = 5;
1797 for (int i = 0; i < kNumTransactions; i++) {
1798 context_list.push_back(new Context());
1799 Context* c = context_list[i];
1801 c->result = cache->CreateTransaction(&c->trans);
1802 ASSERT_EQ(OK, c->result);
1804 c->result =
1805 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1808 // The first request should be creating the disk cache entry and the others
1809 // should be pending.
1811 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1812 EXPECT_EQ(0, cache->disk_cache()->open_count());
1813 EXPECT_EQ(0, cache->disk_cache()->create_count());
1815 cache.reset();
1817 // There is not much to do with the transactions at this point... they are
1818 // waiting for a callback that will not fire.
1819 for (int i = 0; i < kNumTransactions; ++i) {
1820 delete context_list[i];
1824 // Tests that we queue requests when initializing the backend.
1825 TEST(HttpCache, SimpleGET_WaitForBackend) {
1826 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1827 MockHttpCache cache(factory);
1829 MockHttpRequest request0(kSimpleGET_Transaction);
1830 MockHttpRequest request1(kTypicalGET_Transaction);
1831 MockHttpRequest request2(kETagGET_Transaction);
1833 std::vector<Context*> context_list;
1834 const int kNumTransactions = 3;
1836 for (int i = 0; i < kNumTransactions; i++) {
1837 context_list.push_back(new Context());
1838 Context* c = context_list[i];
1840 c->result = cache.CreateTransaction(&c->trans);
1841 ASSERT_EQ(OK, c->result);
1844 context_list[0]->result = context_list[0]->trans->Start(
1845 &request0, context_list[0]->callback.callback(), BoundNetLog());
1846 context_list[1]->result = context_list[1]->trans->Start(
1847 &request1, context_list[1]->callback.callback(), BoundNetLog());
1848 context_list[2]->result = context_list[2]->trans->Start(
1849 &request2, context_list[2]->callback.callback(), BoundNetLog());
1851 // Just to make sure that everything is still pending.
1852 base::MessageLoop::current()->RunUntilIdle();
1854 // The first request should be creating the disk cache.
1855 EXPECT_FALSE(context_list[0]->callback.have_result());
1857 factory->FinishCreation();
1859 base::MessageLoop::current()->RunUntilIdle();
1860 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1861 EXPECT_EQ(3, cache.disk_cache()->create_count());
1863 for (int i = 0; i < kNumTransactions; ++i) {
1864 EXPECT_TRUE(context_list[i]->callback.have_result());
1865 delete context_list[i];
1869 // Tests that we can cancel requests that are queued waiting for the backend
1870 // to be initialized.
1871 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1872 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1873 MockHttpCache cache(factory);
1875 MockHttpRequest request0(kSimpleGET_Transaction);
1876 MockHttpRequest request1(kTypicalGET_Transaction);
1877 MockHttpRequest request2(kETagGET_Transaction);
1879 std::vector<Context*> context_list;
1880 const int kNumTransactions = 3;
1882 for (int i = 0; i < kNumTransactions; i++) {
1883 context_list.push_back(new Context());
1884 Context* c = context_list[i];
1886 c->result = cache.CreateTransaction(&c->trans);
1887 ASSERT_EQ(OK, c->result);
1890 context_list[0]->result = context_list[0]->trans->Start(
1891 &request0, context_list[0]->callback.callback(), BoundNetLog());
1892 context_list[1]->result = context_list[1]->trans->Start(
1893 &request1, context_list[1]->callback.callback(), BoundNetLog());
1894 context_list[2]->result = context_list[2]->trans->Start(
1895 &request2, context_list[2]->callback.callback(), BoundNetLog());
1897 // Just to make sure that everything is still pending.
1898 base::MessageLoop::current()->RunUntilIdle();
1900 // The first request should be creating the disk cache.
1901 EXPECT_FALSE(context_list[0]->callback.have_result());
1903 // Cancel a request from the pending queue.
1904 delete context_list[1];
1905 context_list[1] = NULL;
1907 // Cancel the request that is creating the entry.
1908 delete context_list[0];
1909 context_list[0] = NULL;
1911 // Complete the last transaction.
1912 factory->FinishCreation();
1914 context_list[2]->result =
1915 context_list[2]->callback.GetResult(context_list[2]->result);
1916 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1918 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1919 EXPECT_EQ(1, cache.disk_cache()->create_count());
1921 delete context_list[2];
1924 // Tests that we can delete the cache while creating the backend.
1925 TEST(HttpCache, DeleteCacheWaitingForBackend) {
1926 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1927 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1929 MockHttpRequest request(kSimpleGET_Transaction);
1931 scoped_ptr<Context> c(new Context());
1932 c->result = cache->CreateTransaction(&c->trans);
1933 ASSERT_EQ(OK, c->result);
1935 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1937 // Just to make sure that everything is still pending.
1938 base::MessageLoop::current()->RunUntilIdle();
1940 // The request should be creating the disk cache.
1941 EXPECT_FALSE(c->callback.have_result());
1943 // We cannot call FinishCreation because the factory itself will go away with
1944 // the cache, so grab the callback and attempt to use it.
1945 CompletionCallback callback = factory->callback();
1946 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1948 cache.reset();
1949 base::MessageLoop::current()->RunUntilIdle();
1951 backend->reset();
1952 callback.Run(ERR_ABORTED);
1955 // Tests that we can delete the cache while creating the backend, from within
1956 // one of the callbacks.
1957 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1958 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1959 MockHttpCache* cache = new MockHttpCache(factory);
1961 DeleteCacheCompletionCallback cb(cache);
1962 disk_cache::Backend* backend;
1963 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1964 EXPECT_EQ(ERR_IO_PENDING, rv);
1966 // Now let's queue a regular transaction
1967 MockHttpRequest request(kSimpleGET_Transaction);
1969 scoped_ptr<Context> c(new Context());
1970 c->result = cache->CreateTransaction(&c->trans);
1971 ASSERT_EQ(OK, c->result);
1973 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1975 // And another direct backend request.
1976 TestCompletionCallback cb2;
1977 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1978 EXPECT_EQ(ERR_IO_PENDING, rv);
1980 // Just to make sure that everything is still pending.
1981 base::MessageLoop::current()->RunUntilIdle();
1983 // The request should be queued.
1984 EXPECT_FALSE(c->callback.have_result());
1986 // Generate the callback.
1987 factory->FinishCreation();
1988 rv = cb.WaitForResult();
1990 // The cache should be gone by now.
1991 base::MessageLoop::current()->RunUntilIdle();
1992 EXPECT_EQ(OK, c->callback.GetResult(c->result));
1993 EXPECT_FALSE(cb2.have_result());
1996 TEST(HttpCache, TypicalGET_ConditionalRequest) {
1997 MockHttpCache cache;
1999 // write to the cache
2000 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
2002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2003 EXPECT_EQ(0, cache.disk_cache()->open_count());
2004 EXPECT_EQ(1, cache.disk_cache()->create_count());
2006 // Get the same URL again, but this time we expect it to result
2007 // in a conditional request.
2008 BoundTestNetLog log;
2009 LoadTimingInfo load_timing_info;
2010 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
2011 log.bound(), &load_timing_info);
2013 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2014 EXPECT_EQ(1, cache.disk_cache()->open_count());
2015 EXPECT_EQ(1, cache.disk_cache()->create_count());
2016 TestLoadTimingNetworkRequest(load_timing_info);
2019 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo* request,
2020 std::string* response_status,
2021 std::string* response_headers,
2022 std::string* response_data) {
2023 EXPECT_TRUE(
2024 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
2025 response_status->assign("HTTP/1.1 304 Not Modified");
2026 response_headers->assign(kETagGET_Transaction.response_headers);
2027 response_data->clear();
2030 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2031 MockHttpCache cache;
2033 ScopedMockTransaction transaction(kETagGET_Transaction);
2035 // write to the cache
2036 RunTransactionTest(cache.http_cache(), transaction);
2038 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2039 EXPECT_EQ(0, cache.disk_cache()->open_count());
2040 EXPECT_EQ(1, cache.disk_cache()->create_count());
2042 // Get the same URL again, but this time we expect it to result
2043 // in a conditional request.
2044 transaction.load_flags = LOAD_VALIDATE_CACHE;
2045 transaction.handler = ETagGet_ConditionalRequest_Handler;
2046 BoundTestNetLog log;
2047 LoadTimingInfo load_timing_info;
2048 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2049 &load_timing_info);
2051 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2052 EXPECT_EQ(1, cache.disk_cache()->open_count());
2053 EXPECT_EQ(1, cache.disk_cache()->create_count());
2054 TestLoadTimingNetworkRequest(load_timing_info);
2057 class RevalidationServer {
2058 public:
2059 RevalidationServer() {
2060 s_etag_used_ = false;
2061 s_last_modified_used_ = false;
2064 bool EtagUsed() { return s_etag_used_; }
2065 bool LastModifiedUsed() { return s_last_modified_used_; }
2067 static void Handler(const HttpRequestInfo* request,
2068 std::string* response_status,
2069 std::string* response_headers,
2070 std::string* response_data);
2072 private:
2073 static bool s_etag_used_;
2074 static bool s_last_modified_used_;
2076 bool RevalidationServer::s_etag_used_ = false;
2077 bool RevalidationServer::s_last_modified_used_ = false;
2079 void RevalidationServer::Handler(const HttpRequestInfo* request,
2080 std::string* response_status,
2081 std::string* response_headers,
2082 std::string* response_data) {
2083 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch))
2084 s_etag_used_ = true;
2086 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfModifiedSince)) {
2087 s_last_modified_used_ = true;
2090 if (s_etag_used_ || s_last_modified_used_) {
2091 response_status->assign("HTTP/1.1 304 Not Modified");
2092 response_headers->assign(kTypicalGET_Transaction.response_headers);
2093 response_data->clear();
2094 } else {
2095 response_status->assign(kTypicalGET_Transaction.status);
2096 response_headers->assign(kTypicalGET_Transaction.response_headers);
2097 response_data->assign(kTypicalGET_Transaction.data);
2101 // Tests revalidation after a vary match.
2102 TEST(HttpCache, GET_ValidateCache_VaryMatch) {
2103 MockHttpCache cache;
2105 // Write to the cache.
2106 MockTransaction transaction(kTypicalGET_Transaction);
2107 transaction.request_headers = "Foo: bar\r\n";
2108 transaction.response_headers =
2109 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2110 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2111 "Etag: \"foopy\"\n"
2112 "Cache-Control: max-age=0\n"
2113 "Vary: Foo\n";
2114 AddMockTransaction(&transaction);
2115 RunTransactionTest(cache.http_cache(), transaction);
2117 // Read from the cache.
2118 RevalidationServer server;
2119 transaction.handler = server.Handler;
2120 BoundTestNetLog log;
2121 LoadTimingInfo load_timing_info;
2122 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2123 &load_timing_info);
2125 EXPECT_TRUE(server.EtagUsed());
2126 EXPECT_TRUE(server.LastModifiedUsed());
2127 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2128 EXPECT_EQ(1, cache.disk_cache()->open_count());
2129 EXPECT_EQ(1, cache.disk_cache()->create_count());
2130 TestLoadTimingNetworkRequest(load_timing_info);
2131 RemoveMockTransaction(&transaction);
2134 // Tests revalidation after a vary mismatch if etag is present.
2135 TEST(HttpCache, GET_ValidateCache_VaryMismatch) {
2136 MockHttpCache cache;
2138 // Write to the cache.
2139 MockTransaction transaction(kTypicalGET_Transaction);
2140 transaction.request_headers = "Foo: bar\r\n";
2141 transaction.response_headers =
2142 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2143 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2144 "Etag: \"foopy\"\n"
2145 "Cache-Control: max-age=0\n"
2146 "Vary: Foo\n";
2147 AddMockTransaction(&transaction);
2148 RunTransactionTest(cache.http_cache(), transaction);
2150 // Read from the cache and revalidate the entry.
2151 RevalidationServer server;
2152 transaction.handler = server.Handler;
2153 transaction.request_headers = "Foo: none\r\n";
2154 BoundTestNetLog log;
2155 LoadTimingInfo load_timing_info;
2156 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2157 &load_timing_info);
2159 EXPECT_TRUE(server.EtagUsed());
2160 EXPECT_FALSE(server.LastModifiedUsed());
2161 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2162 EXPECT_EQ(1, cache.disk_cache()->open_count());
2163 EXPECT_EQ(1, cache.disk_cache()->create_count());
2164 TestLoadTimingNetworkRequest(load_timing_info);
2165 RemoveMockTransaction(&transaction);
2168 // Tests lack of revalidation after a vary mismatch and no etag.
2169 TEST(HttpCache, GET_DontValidateCache_VaryMismatch) {
2170 MockHttpCache cache;
2172 // Write to the cache.
2173 MockTransaction transaction(kTypicalGET_Transaction);
2174 transaction.request_headers = "Foo: bar\r\n";
2175 transaction.response_headers =
2176 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2177 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2178 "Cache-Control: max-age=0\n"
2179 "Vary: Foo\n";
2180 AddMockTransaction(&transaction);
2181 RunTransactionTest(cache.http_cache(), transaction);
2183 // Read from the cache and don't revalidate the entry.
2184 RevalidationServer server;
2185 transaction.handler = server.Handler;
2186 transaction.request_headers = "Foo: none\r\n";
2187 BoundTestNetLog log;
2188 LoadTimingInfo load_timing_info;
2189 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2190 &load_timing_info);
2192 EXPECT_FALSE(server.EtagUsed());
2193 EXPECT_FALSE(server.LastModifiedUsed());
2194 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2195 EXPECT_EQ(1, cache.disk_cache()->open_count());
2196 EXPECT_EQ(1, cache.disk_cache()->create_count());
2197 TestLoadTimingNetworkRequest(load_timing_info);
2198 RemoveMockTransaction(&transaction);
2201 // Tests that a new vary header provided when revalidating an entry is saved.
2202 TEST(HttpCache, GET_ValidateCache_VaryMatch_UpdateVary) {
2203 MockHttpCache cache;
2205 // Write to the cache.
2206 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2207 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2208 transaction.response_headers =
2209 "Etag: \"foopy\"\n"
2210 "Cache-Control: max-age=0\n"
2211 "Vary: Foo\n";
2212 RunTransactionTest(cache.http_cache(), transaction);
2214 // Validate the entry and change the vary field in the response.
2215 transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
2216 transaction.status = "HTTP/1.1 304 Not Modified";
2217 transaction.response_headers =
2218 "Etag: \"foopy\"\n"
2219 "Cache-Control: max-age=3600\n"
2220 "Vary: Name\n";
2221 RunTransactionTest(cache.http_cache(), transaction);
2223 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2224 EXPECT_EQ(1, cache.disk_cache()->open_count());
2225 EXPECT_EQ(1, cache.disk_cache()->create_count());
2227 // Make sure that the ActiveEntry is gone.
2228 base::RunLoop().RunUntilIdle();
2230 // Generate a vary mismatch.
2231 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2232 RunTransactionTest(cache.http_cache(), transaction);
2234 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2235 EXPECT_EQ(2, cache.disk_cache()->open_count());
2236 EXPECT_EQ(1, cache.disk_cache()->create_count());
2239 // Tests that new request headers causing a vary mismatch are paired with the
2240 // new response when the server says the old response can be used.
2241 TEST(HttpCache, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
2242 MockHttpCache cache;
2244 // Write to the cache.
2245 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2246 transaction.request_headers = "Foo: bar\r\n";
2247 transaction.response_headers =
2248 "Etag: \"foopy\"\n"
2249 "Cache-Control: max-age=3600\n"
2250 "Vary: Foo\n";
2251 RunTransactionTest(cache.http_cache(), transaction);
2253 // Vary-mismatch validation receives 304.
2254 transaction.request_headers = "Foo: none\r\n";
2255 transaction.status = "HTTP/1.1 304 Not Modified";
2256 RunTransactionTest(cache.http_cache(), transaction);
2258 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2259 EXPECT_EQ(1, cache.disk_cache()->open_count());
2260 EXPECT_EQ(1, cache.disk_cache()->create_count());
2262 // Make sure that the ActiveEntry is gone.
2263 base::RunLoop().RunUntilIdle();
2265 // Generate a vary mismatch.
2266 transaction.request_headers = "Foo: bar\r\n";
2267 RunTransactionTest(cache.http_cache(), transaction);
2269 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2270 EXPECT_EQ(2, cache.disk_cache()->open_count());
2271 EXPECT_EQ(1, cache.disk_cache()->create_count());
2274 // Tests that a 304 without vary headers doesn't delete the previously stored
2275 // vary data after a vary match revalidation.
2276 TEST(HttpCache, GET_ValidateCache_VaryMatch_DontDeleteVary) {
2277 MockHttpCache cache;
2279 // Write to the cache.
2280 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2281 transaction.request_headers = "Foo: bar\r\n";
2282 transaction.response_headers =
2283 "Etag: \"foopy\"\n"
2284 "Cache-Control: max-age=0\n"
2285 "Vary: Foo\n";
2286 RunTransactionTest(cache.http_cache(), transaction);
2288 // Validate the entry and remove the vary field in the response.
2289 transaction.status = "HTTP/1.1 304 Not Modified";
2290 transaction.response_headers =
2291 "Etag: \"foopy\"\n"
2292 "Cache-Control: max-age=3600\n";
2293 RunTransactionTest(cache.http_cache(), transaction);
2295 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2296 EXPECT_EQ(1, cache.disk_cache()->open_count());
2297 EXPECT_EQ(1, cache.disk_cache()->create_count());
2299 // Make sure that the ActiveEntry is gone.
2300 base::RunLoop().RunUntilIdle();
2302 // Generate a vary mismatch.
2303 transaction.request_headers = "Foo: none\r\n";
2304 RunTransactionTest(cache.http_cache(), transaction);
2306 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2307 EXPECT_EQ(2, cache.disk_cache()->open_count());
2308 EXPECT_EQ(1, cache.disk_cache()->create_count());
2311 // Tests that a 304 without vary headers doesn't delete the previously stored
2312 // vary data after a vary mismatch.
2313 TEST(HttpCache, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
2314 MockHttpCache cache;
2316 // Write to the cache.
2317 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2318 transaction.request_headers = "Foo: bar\r\n";
2319 transaction.response_headers =
2320 "Etag: \"foopy\"\n"
2321 "Cache-Control: max-age=3600\n"
2322 "Vary: Foo\n";
2323 RunTransactionTest(cache.http_cache(), transaction);
2325 // Vary-mismatch validation receives 304 and no vary header.
2326 transaction.request_headers = "Foo: none\r\n";
2327 transaction.status = "HTTP/1.1 304 Not Modified";
2328 transaction.response_headers =
2329 "Etag: \"foopy\"\n"
2330 "Cache-Control: max-age=3600\n";
2331 RunTransactionTest(cache.http_cache(), transaction);
2333 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2334 EXPECT_EQ(1, cache.disk_cache()->open_count());
2335 EXPECT_EQ(1, cache.disk_cache()->create_count());
2337 // Make sure that the ActiveEntry is gone.
2338 base::RunLoop().RunUntilIdle();
2340 // Generate a vary mismatch.
2341 transaction.request_headers = "Foo: bar\r\n";
2342 RunTransactionTest(cache.http_cache(), transaction);
2344 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2345 EXPECT_EQ(2, cache.disk_cache()->open_count());
2346 EXPECT_EQ(1, cache.disk_cache()->create_count());
2349 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
2350 std::string* response_status,
2351 std::string* response_headers,
2352 std::string* response_data) {
2353 EXPECT_FALSE(
2354 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
2357 TEST(HttpCache, ETagGET_Http10) {
2358 MockHttpCache cache;
2360 ScopedMockTransaction transaction(kETagGET_Transaction);
2361 transaction.status = "HTTP/1.0 200 OK";
2363 // Write to the cache.
2364 RunTransactionTest(cache.http_cache(), transaction);
2366 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2367 EXPECT_EQ(0, cache.disk_cache()->open_count());
2368 EXPECT_EQ(1, cache.disk_cache()->create_count());
2370 // Get the same URL again, without generating a conditional request.
2371 transaction.load_flags = LOAD_VALIDATE_CACHE;
2372 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2373 RunTransactionTest(cache.http_cache(), transaction);
2375 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2376 EXPECT_EQ(1, cache.disk_cache()->open_count());
2377 EXPECT_EQ(1, cache.disk_cache()->create_count());
2380 TEST(HttpCache, ETagGET_Http10_Range) {
2381 MockHttpCache cache;
2383 ScopedMockTransaction transaction(kETagGET_Transaction);
2384 transaction.status = "HTTP/1.0 200 OK";
2386 // Write to the cache.
2387 RunTransactionTest(cache.http_cache(), transaction);
2389 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2390 EXPECT_EQ(0, cache.disk_cache()->open_count());
2391 EXPECT_EQ(1, cache.disk_cache()->create_count());
2393 // Get the same URL again, but use a byte range request.
2394 transaction.load_flags = LOAD_VALIDATE_CACHE;
2395 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2396 transaction.request_headers = "Range: bytes = 5-\r\n";
2397 RunTransactionTest(cache.http_cache(), transaction);
2399 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2400 EXPECT_EQ(1, cache.disk_cache()->open_count());
2401 EXPECT_EQ(2, cache.disk_cache()->create_count());
2404 static void ETagGet_ConditionalRequest_NoStore_Handler(
2405 const HttpRequestInfo* request,
2406 std::string* response_status,
2407 std::string* response_headers,
2408 std::string* response_data) {
2409 EXPECT_TRUE(
2410 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
2411 response_status->assign("HTTP/1.1 304 Not Modified");
2412 response_headers->assign("Cache-Control: no-store\n");
2413 response_data->clear();
2416 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2417 MockHttpCache cache;
2419 ScopedMockTransaction transaction(kETagGET_Transaction);
2421 // Write to the cache.
2422 RunTransactionTest(cache.http_cache(), transaction);
2424 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2425 EXPECT_EQ(0, cache.disk_cache()->open_count());
2426 EXPECT_EQ(1, cache.disk_cache()->create_count());
2428 // Get the same URL again, but this time we expect it to result
2429 // in a conditional request.
2430 transaction.load_flags = LOAD_VALIDATE_CACHE;
2431 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2432 RunTransactionTest(cache.http_cache(), transaction);
2434 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2435 EXPECT_EQ(1, cache.disk_cache()->open_count());
2436 EXPECT_EQ(1, cache.disk_cache()->create_count());
2438 ScopedMockTransaction transaction2(kETagGET_Transaction);
2440 // Write to the cache again. This should create a new entry.
2441 RunTransactionTest(cache.http_cache(), transaction2);
2443 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2444 EXPECT_EQ(1, cache.disk_cache()->open_count());
2445 EXPECT_EQ(2, cache.disk_cache()->create_count());
2448 // Helper that does 4 requests using HttpCache:
2450 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2451 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2452 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2453 // be returned.
2454 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2455 // returned.
2456 static void ConditionalizedRequestUpdatesCacheHelper(
2457 const Response& net_response_1,
2458 const Response& net_response_2,
2459 const Response& cached_response_2,
2460 const char* extra_request_headers) {
2461 MockHttpCache cache;
2463 // The URL we will be requesting.
2464 const char kUrl[] = "http://foobar.com/main.css";
2466 // Junk network response.
2467 static const Response kUnexpectedResponse = {
2468 "HTTP/1.1 500 Unexpected",
2469 "Server: unexpected_header",
2470 "unexpected body"
2473 // We will control the network layer's responses for |kUrl| using
2474 // |mock_network_response|.
2475 MockTransaction mock_network_response = { 0 };
2476 mock_network_response.url = kUrl;
2477 AddMockTransaction(&mock_network_response);
2479 // Request |kUrl| for the first time. It should hit the network and
2480 // receive |kNetResponse1|, which it saves into the HTTP cache.
2482 MockTransaction request = { 0 };
2483 request.url = kUrl;
2484 request.method = "GET";
2485 request.request_headers = "";
2487 net_response_1.AssignTo(&mock_network_response); // Network mock.
2488 net_response_1.AssignTo(&request); // Expected result.
2490 std::string response_headers;
2491 RunTransactionTestWithResponse(
2492 cache.http_cache(), request, &response_headers);
2494 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2495 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2496 EXPECT_EQ(0, cache.disk_cache()->open_count());
2497 EXPECT_EQ(1, cache.disk_cache()->create_count());
2499 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2500 // cache, so we don't hit the network.
2502 request.load_flags = LOAD_ONLY_FROM_CACHE;
2504 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2505 net_response_1.AssignTo(&request); // Expected result.
2507 RunTransactionTestWithResponse(
2508 cache.http_cache(), request, &response_headers);
2510 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2511 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2512 EXPECT_EQ(1, cache.disk_cache()->open_count());
2513 EXPECT_EQ(1, cache.disk_cache()->create_count());
2515 // Request |kUrl| yet again, but this time give the request an
2516 // "If-Modified-Since" header. This will cause the request to re-hit the
2517 // network. However now the network response is going to be
2518 // different -- this simulates a change made to the CSS file.
2520 request.request_headers = extra_request_headers;
2521 request.load_flags = LOAD_NORMAL;
2523 net_response_2.AssignTo(&mock_network_response); // Network mock.
2524 net_response_2.AssignTo(&request); // Expected result.
2526 RunTransactionTestWithResponse(
2527 cache.http_cache(), request, &response_headers);
2529 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2530 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2531 EXPECT_EQ(1, cache.disk_cache()->open_count());
2532 EXPECT_EQ(1, cache.disk_cache()->create_count());
2534 // Finally, request |kUrl| again. This request should be serviced from
2535 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2536 // and NOT |kNetResponse1|. The previous step should have replaced the
2537 // value in the cache with the modified response.
2539 request.request_headers = "";
2540 request.load_flags = LOAD_ONLY_FROM_CACHE;
2542 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2543 cached_response_2.AssignTo(&request); // Expected result.
2545 RunTransactionTestWithResponse(
2546 cache.http_cache(), request, &response_headers);
2548 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2549 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2550 EXPECT_EQ(2, cache.disk_cache()->open_count());
2551 EXPECT_EQ(1, cache.disk_cache()->create_count());
2553 RemoveMockTransaction(&mock_network_response);
2556 // Check that when an "if-modified-since" header is attached
2557 // to the request, the result still updates the cached entry.
2558 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2559 // First network response for |kUrl|.
2560 static const Response kNetResponse1 = {
2561 "HTTP/1.1 200 OK",
2562 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2563 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2564 "body1"
2567 // Second network response for |kUrl|.
2568 static const Response kNetResponse2 = {
2569 "HTTP/1.1 200 OK",
2570 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2571 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2572 "body2"
2575 const char extra_headers[] =
2576 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2578 ConditionalizedRequestUpdatesCacheHelper(
2579 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2582 // Check that when an "if-none-match" header is attached
2583 // to the request, the result updates the cached entry.
2584 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2585 // First network response for |kUrl|.
2586 static const Response kNetResponse1 = {
2587 "HTTP/1.1 200 OK",
2588 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2589 "Etag: \"ETAG1\"\n"
2590 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2591 "body1"
2594 // Second network response for |kUrl|.
2595 static const Response kNetResponse2 = {
2596 "HTTP/1.1 200 OK",
2597 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2598 "Etag: \"ETAG2\"\n"
2599 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2600 "body2"
2603 const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
2605 ConditionalizedRequestUpdatesCacheHelper(
2606 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2609 // Check that when an "if-modified-since" header is attached
2610 // to a request, the 304 (not modified result) result updates the cached
2611 // headers, and the 304 response is returned rather than the cached response.
2612 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2613 // First network response for |kUrl|.
2614 static const Response kNetResponse1 = {
2615 "HTTP/1.1 200 OK",
2616 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2617 "Server: server1\n"
2618 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2619 "body1"
2622 // Second network response for |kUrl|.
2623 static const Response kNetResponse2 = {
2624 "HTTP/1.1 304 Not Modified",
2625 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2626 "Server: server2\n"
2627 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2631 static const Response kCachedResponse2 = {
2632 "HTTP/1.1 200 OK",
2633 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2634 "Server: server2\n"
2635 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2636 "body1"
2639 const char extra_headers[] =
2640 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2642 ConditionalizedRequestUpdatesCacheHelper(
2643 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2646 // Test that when doing an externally conditionalized if-modified-since
2647 // and there is no corresponding cache entry, a new cache entry is NOT
2648 // created (304 response).
2649 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2650 MockHttpCache cache;
2652 const char kUrl[] = "http://foobar.com/main.css";
2654 static const Response kNetResponse = {
2655 "HTTP/1.1 304 Not Modified",
2656 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2657 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2661 const char kExtraRequestHeaders[] =
2662 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2664 // We will control the network layer's responses for |kUrl| using
2665 // |mock_network_response|.
2666 MockTransaction mock_network_response = { 0 };
2667 mock_network_response.url = kUrl;
2668 AddMockTransaction(&mock_network_response);
2670 MockTransaction request = { 0 };
2671 request.url = kUrl;
2672 request.method = "GET";
2673 request.request_headers = kExtraRequestHeaders;
2675 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2676 kNetResponse.AssignTo(&request); // Expected result.
2678 std::string response_headers;
2679 RunTransactionTestWithResponse(
2680 cache.http_cache(), request, &response_headers);
2682 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2683 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2684 EXPECT_EQ(0, cache.disk_cache()->open_count());
2685 EXPECT_EQ(0, cache.disk_cache()->create_count());
2687 RemoveMockTransaction(&mock_network_response);
2690 // Test that when doing an externally conditionalized if-modified-since
2691 // and there is no corresponding cache entry, a new cache entry is NOT
2692 // created (200 response).
2693 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2694 MockHttpCache cache;
2696 const char kUrl[] = "http://foobar.com/main.css";
2698 static const Response kNetResponse = {
2699 "HTTP/1.1 200 OK",
2700 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2701 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2702 "foobar!!!"
2705 const char kExtraRequestHeaders[] =
2706 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2708 // We will control the network layer's responses for |kUrl| using
2709 // |mock_network_response|.
2710 MockTransaction mock_network_response = { 0 };
2711 mock_network_response.url = kUrl;
2712 AddMockTransaction(&mock_network_response);
2714 MockTransaction request = { 0 };
2715 request.url = kUrl;
2716 request.method = "GET";
2717 request.request_headers = kExtraRequestHeaders;
2719 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2720 kNetResponse.AssignTo(&request); // Expected result.
2722 std::string response_headers;
2723 RunTransactionTestWithResponse(
2724 cache.http_cache(), request, &response_headers);
2726 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2727 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2728 EXPECT_EQ(0, cache.disk_cache()->open_count());
2729 EXPECT_EQ(0, cache.disk_cache()->create_count());
2731 RemoveMockTransaction(&mock_network_response);
2734 // Test that when doing an externally conditionalized if-modified-since
2735 // if the date does not match the cache entry's last-modified date,
2736 // then we do NOT use the response (304) to update the cache.
2737 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2738 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2739 static const Response kNetResponse1 = {
2740 "HTTP/1.1 200 OK",
2741 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2742 "Server: server1\n"
2743 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2744 "body1"
2747 // Second network response for |kUrl|.
2748 static const Response kNetResponse2 = {
2749 "HTTP/1.1 304 Not Modified",
2750 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2751 "Server: server2\n"
2752 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2756 // This is two days in the future from the original response's last-modified
2757 // date!
2758 const char kExtraRequestHeaders[] =
2759 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2761 ConditionalizedRequestUpdatesCacheHelper(
2762 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2765 // Test that when doing an externally conditionalized if-none-match
2766 // if the etag does not match the cache entry's etag, then we do not use the
2767 // response (304) to update the cache.
2768 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2769 static const Response kNetResponse1 = {
2770 "HTTP/1.1 200 OK",
2771 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2772 "Etag: \"Foo1\"\n"
2773 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2774 "body1"
2777 // Second network response for |kUrl|.
2778 static const Response kNetResponse2 = {
2779 "HTTP/1.1 304 Not Modified",
2780 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2781 "Etag: \"Foo2\"\n"
2782 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2786 // Different etag from original response.
2787 const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
2789 ConditionalizedRequestUpdatesCacheHelper(
2790 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2793 // Test that doing an externally conditionalized request with both if-none-match
2794 // and if-modified-since updates the cache.
2795 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2796 static const Response kNetResponse1 = {
2797 "HTTP/1.1 200 OK",
2798 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2799 "Etag: \"Foo1\"\n"
2800 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2801 "body1"
2804 // Second network response for |kUrl|.
2805 static const Response kNetResponse2 = {
2806 "HTTP/1.1 200 OK",
2807 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2808 "Etag: \"Foo2\"\n"
2809 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2810 "body2"
2813 const char kExtraRequestHeaders[] =
2814 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2815 "If-None-Match: \"Foo1\"\r\n";
2817 ConditionalizedRequestUpdatesCacheHelper(
2818 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2821 // Test that doing an externally conditionalized request with both if-none-match
2822 // and if-modified-since does not update the cache with only one match.
2823 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2824 static const Response kNetResponse1 = {
2825 "HTTP/1.1 200 OK",
2826 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2827 "Etag: \"Foo1\"\n"
2828 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2829 "body1"
2832 // Second network response for |kUrl|.
2833 static const Response kNetResponse2 = {
2834 "HTTP/1.1 200 OK",
2835 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2836 "Etag: \"Foo2\"\n"
2837 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2838 "body2"
2841 // The etag doesn't match what we have stored.
2842 const char kExtraRequestHeaders[] =
2843 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2844 "If-None-Match: \"Foo2\"\r\n";
2846 ConditionalizedRequestUpdatesCacheHelper(
2847 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2850 // Test that doing an externally conditionalized request with both if-none-match
2851 // and if-modified-since does not update the cache with only one match.
2852 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2853 static const Response kNetResponse1 = {
2854 "HTTP/1.1 200 OK",
2855 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2856 "Etag: \"Foo1\"\n"
2857 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2858 "body1"
2861 // Second network response for |kUrl|.
2862 static const Response kNetResponse2 = {
2863 "HTTP/1.1 200 OK",
2864 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2865 "Etag: \"Foo2\"\n"
2866 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2867 "body2"
2870 // The modification date doesn't match what we have stored.
2871 const char kExtraRequestHeaders[] =
2872 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2873 "If-None-Match: \"Foo1\"\r\n";
2875 ConditionalizedRequestUpdatesCacheHelper(
2876 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2879 TEST(HttpCache, UrlContainingHash) {
2880 MockHttpCache cache;
2882 // Do a typical GET request -- should write an entry into our cache.
2883 MockTransaction trans(kTypicalGET_Transaction);
2884 RunTransactionTest(cache.http_cache(), trans);
2886 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2887 EXPECT_EQ(0, cache.disk_cache()->open_count());
2888 EXPECT_EQ(1, cache.disk_cache()->create_count());
2890 // Request the same URL, but this time with a reference section (hash).
2891 // Since the cache key strips the hash sections, this should be a cache hit.
2892 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2893 trans.url = url_with_hash.c_str();
2894 trans.load_flags = LOAD_ONLY_FROM_CACHE;
2896 RunTransactionTest(cache.http_cache(), trans);
2898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2899 EXPECT_EQ(1, cache.disk_cache()->open_count());
2900 EXPECT_EQ(1, cache.disk_cache()->create_count());
2903 // Tests that we skip the cache for POST requests that do not have an upload
2904 // identifier.
2905 TEST(HttpCache, SimplePOST_SkipsCache) {
2906 MockHttpCache cache;
2908 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2910 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2911 EXPECT_EQ(0, cache.disk_cache()->open_count());
2912 EXPECT_EQ(0, cache.disk_cache()->create_count());
2915 // Tests POST handling with a disabled cache (no DCHECK).
2916 TEST(HttpCache, SimplePOST_DisabledCache) {
2917 MockHttpCache cache;
2918 cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
2920 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2922 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2923 EXPECT_EQ(0, cache.disk_cache()->open_count());
2924 EXPECT_EQ(0, cache.disk_cache()->create_count());
2927 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2928 MockHttpCache cache;
2930 MockTransaction transaction(kSimplePOST_Transaction);
2931 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
2933 MockHttpRequest request(transaction);
2934 TestCompletionCallback callback;
2936 scoped_ptr<HttpTransaction> trans;
2937 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
2938 ASSERT_TRUE(trans.get());
2940 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2941 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
2943 trans.reset();
2945 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2946 EXPECT_EQ(0, cache.disk_cache()->open_count());
2947 EXPECT_EQ(0, cache.disk_cache()->create_count());
2950 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2951 MockHttpCache cache;
2953 // Test that we hit the cache for POST requests.
2955 MockTransaction transaction(kSimplePOST_Transaction);
2957 const int64 kUploadId = 1; // Just a dummy value.
2959 ScopedVector<UploadElementReader> element_readers;
2960 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2961 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2962 kUploadId);
2963 MockHttpRequest request(transaction);
2964 request.upload_data_stream = &upload_data_stream;
2966 // Populate the cache.
2967 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2969 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2970 EXPECT_EQ(0, cache.disk_cache()->open_count());
2971 EXPECT_EQ(1, cache.disk_cache()->create_count());
2973 // Load from cache.
2974 request.load_flags |= LOAD_ONLY_FROM_CACHE;
2975 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2977 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2978 EXPECT_EQ(1, cache.disk_cache()->open_count());
2979 EXPECT_EQ(1, cache.disk_cache()->create_count());
2982 // Test that we don't hit the cache for POST requests if there is a byte range.
2983 TEST(HttpCache, SimplePOST_WithRanges) {
2984 MockHttpCache cache;
2986 MockTransaction transaction(kSimplePOST_Transaction);
2987 transaction.request_headers = "Range: bytes = 0-4\r\n";
2989 const int64 kUploadId = 1; // Just a dummy value.
2991 ScopedVector<UploadElementReader> element_readers;
2992 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2993 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2994 kUploadId);
2996 MockHttpRequest request(transaction);
2997 request.upload_data_stream = &upload_data_stream;
2999 // Attempt to populate the cache.
3000 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3003 EXPECT_EQ(0, cache.disk_cache()->open_count());
3004 EXPECT_EQ(0, cache.disk_cache()->create_count());
3007 // Tests that a POST is cached separately from a previously cached GET.
3008 TEST(HttpCache, SimplePOST_SeparateCache) {
3009 MockHttpCache cache;
3011 ScopedVector<UploadElementReader> element_readers;
3012 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3013 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
3015 MockTransaction transaction(kSimplePOST_Transaction);
3016 MockHttpRequest req1(transaction);
3017 req1.upload_data_stream = &upload_data_stream;
3019 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3021 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3022 EXPECT_EQ(0, cache.disk_cache()->open_count());
3023 EXPECT_EQ(1, cache.disk_cache()->create_count());
3025 transaction.method = "GET";
3026 MockHttpRequest req2(transaction);
3028 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3030 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3031 EXPECT_EQ(0, cache.disk_cache()->open_count());
3032 EXPECT_EQ(2, cache.disk_cache()->create_count());
3035 // Tests that a successful POST invalidates a previously cached GET.
3036 TEST(HttpCache, SimplePOST_Invalidate_205) {
3037 MockHttpCache cache;
3039 MockTransaction transaction(kSimpleGET_Transaction);
3040 AddMockTransaction(&transaction);
3041 MockHttpRequest req1(transaction);
3043 // Attempt to populate the cache.
3044 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3046 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3047 EXPECT_EQ(0, cache.disk_cache()->open_count());
3048 EXPECT_EQ(1, cache.disk_cache()->create_count());
3050 ScopedVector<UploadElementReader> element_readers;
3051 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3052 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
3054 transaction.method = "POST";
3055 transaction.status = "HTTP/1.1 205 No Content";
3056 MockHttpRequest req2(transaction);
3057 req2.upload_data_stream = &upload_data_stream;
3059 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3061 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3062 EXPECT_EQ(0, cache.disk_cache()->open_count());
3063 EXPECT_EQ(2, cache.disk_cache()->create_count());
3065 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3067 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3068 EXPECT_EQ(0, cache.disk_cache()->open_count());
3069 EXPECT_EQ(3, cache.disk_cache()->create_count());
3070 RemoveMockTransaction(&transaction);
3073 // Tests that a successful POST invalidates a previously cached GET, even when
3074 // there is no upload identifier.
3075 TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
3076 MockHttpCache cache;
3078 MockTransaction transaction(kSimpleGET_Transaction);
3079 AddMockTransaction(&transaction);
3080 MockHttpRequest req1(transaction);
3082 // Attempt to populate the cache.
3083 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3085 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3086 EXPECT_EQ(0, cache.disk_cache()->open_count());
3087 EXPECT_EQ(1, cache.disk_cache()->create_count());
3089 ScopedVector<UploadElementReader> element_readers;
3090 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3091 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3093 transaction.method = "POST";
3094 transaction.status = "HTTP/1.1 205 No Content";
3095 MockHttpRequest req2(transaction);
3096 req2.upload_data_stream = &upload_data_stream;
3098 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3100 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3101 EXPECT_EQ(0, cache.disk_cache()->open_count());
3102 EXPECT_EQ(1, cache.disk_cache()->create_count());
3104 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3106 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3107 EXPECT_EQ(0, cache.disk_cache()->open_count());
3108 EXPECT_EQ(2, cache.disk_cache()->create_count());
3109 RemoveMockTransaction(&transaction);
3112 // Tests that processing a POST before creating the backend doesn't crash.
3113 TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
3114 // This will initialize a cache object with NULL backend.
3115 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
3116 factory->set_fail(true);
3117 factory->FinishCreation();
3118 MockHttpCache cache(factory);
3120 ScopedVector<UploadElementReader> element_readers;
3121 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3122 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3124 MockTransaction transaction(kSimplePOST_Transaction);
3125 AddMockTransaction(&transaction);
3126 MockHttpRequest req(transaction);
3127 req.upload_data_stream = &upload_data_stream;
3129 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
3131 RemoveMockTransaction(&transaction);
3134 // Tests that we don't invalidate entries as a result of a failed POST.
3135 TEST(HttpCache, SimplePOST_DontInvalidate_100) {
3136 MockHttpCache cache;
3138 MockTransaction transaction(kSimpleGET_Transaction);
3139 AddMockTransaction(&transaction);
3140 MockHttpRequest req1(transaction);
3142 // Attempt to populate the cache.
3143 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3145 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3146 EXPECT_EQ(0, cache.disk_cache()->open_count());
3147 EXPECT_EQ(1, cache.disk_cache()->create_count());
3149 ScopedVector<UploadElementReader> element_readers;
3150 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3151 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
3153 transaction.method = "POST";
3154 transaction.status = "HTTP/1.1 100 Continue";
3155 MockHttpRequest req2(transaction);
3156 req2.upload_data_stream = &upload_data_stream;
3158 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3160 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3161 EXPECT_EQ(0, cache.disk_cache()->open_count());
3162 EXPECT_EQ(2, cache.disk_cache()->create_count());
3164 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3166 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3167 EXPECT_EQ(1, cache.disk_cache()->open_count());
3168 EXPECT_EQ(2, cache.disk_cache()->create_count());
3169 RemoveMockTransaction(&transaction);
3172 // Tests that a HEAD request is not cached by itself.
3173 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
3174 MockHttpCache cache;
3175 MockTransaction transaction(kSimplePOST_Transaction);
3176 AddMockTransaction(&transaction);
3177 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3178 transaction.method = "HEAD";
3180 MockHttpRequest request(transaction);
3181 TestCompletionCallback callback;
3183 scoped_ptr<HttpTransaction> trans;
3184 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
3185 ASSERT_TRUE(trans.get());
3187 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3188 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
3190 trans.reset();
3192 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3193 EXPECT_EQ(0, cache.disk_cache()->open_count());
3194 EXPECT_EQ(0, cache.disk_cache()->create_count());
3195 RemoveMockTransaction(&transaction);
3198 // Tests that a HEAD request is served from a cached GET.
3199 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3200 MockHttpCache cache;
3201 MockTransaction transaction(kSimpleGET_Transaction);
3202 AddMockTransaction(&transaction);
3204 // Populate the cache.
3205 RunTransactionTest(cache.http_cache(), transaction);
3207 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3208 EXPECT_EQ(0, cache.disk_cache()->open_count());
3209 EXPECT_EQ(1, cache.disk_cache()->create_count());
3211 // Load from cache.
3212 transaction.method = "HEAD";
3213 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3214 transaction.data = "";
3215 RunTransactionTest(cache.http_cache(), transaction);
3217 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3218 EXPECT_EQ(1, cache.disk_cache()->open_count());
3219 EXPECT_EQ(1, cache.disk_cache()->create_count());
3220 RemoveMockTransaction(&transaction);
3223 // Tests that a read-only request served from the cache preserves CL.
3224 TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3225 MockHttpCache cache;
3226 MockTransaction transaction(kSimpleGET_Transaction);
3227 AddMockTransaction(&transaction);
3228 transaction.response_headers = "Content-Length: 42\n";
3230 // Populate the cache.
3231 RunTransactionTest(cache.http_cache(), transaction);
3233 // Load from cache.
3234 transaction.method = "HEAD";
3235 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3236 transaction.data = "";
3237 std::string headers;
3239 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3241 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3242 RemoveMockTransaction(&transaction);
3245 // Tests that a read-write request served from the cache preserves CL.
3246 TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3247 MockHttpCache cache;
3248 MockTransaction transaction(kETagGET_Transaction);
3249 AddMockTransaction(&transaction);
3250 std::string server_headers(kETagGET_Transaction.response_headers);
3251 server_headers.append("Content-Length: 42\n");
3252 transaction.response_headers = server_headers.data();
3254 // Populate the cache.
3255 RunTransactionTest(cache.http_cache(), transaction);
3257 // Load from cache.
3258 transaction.method = "HEAD";
3259 transaction.data = "";
3260 std::string headers;
3262 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3264 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3265 RemoveMockTransaction(&transaction);
3268 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3269 TEST(HttpCache, SimpleHEAD_WithRanges) {
3270 MockHttpCache cache;
3271 MockTransaction transaction(kSimpleGET_Transaction);
3272 AddMockTransaction(&transaction);
3274 // Populate the cache.
3275 RunTransactionTest(cache.http_cache(), transaction);
3277 // Load from cache.
3278 transaction.method = "HEAD";
3279 transaction.request_headers = "Range: bytes = 0-4\r\n";
3280 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3281 transaction.return_code = ERR_CACHE_MISS;
3282 RunTransactionTest(cache.http_cache(), transaction);
3284 EXPECT_EQ(0, cache.disk_cache()->open_count());
3285 EXPECT_EQ(1, cache.disk_cache()->create_count());
3286 RemoveMockTransaction(&transaction);
3289 // Tests that a HEAD request can be served from a partialy cached resource.
3290 TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3291 MockHttpCache cache;
3292 AddMockTransaction(&kRangeGET_TransactionOK);
3294 // Write to the cache (40-49).
3295 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3296 RemoveMockTransaction(&kRangeGET_TransactionOK);
3298 MockTransaction transaction(kSimpleGET_Transaction);
3300 transaction.url = kRangeGET_TransactionOK.url;
3301 transaction.method = "HEAD";
3302 transaction.data = "";
3303 AddMockTransaction(&transaction);
3304 std::string headers;
3306 // Load from cache.
3307 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3309 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3310 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3311 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3312 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3313 EXPECT_EQ(1, cache.disk_cache()->open_count());
3314 EXPECT_EQ(1, cache.disk_cache()->create_count());
3315 RemoveMockTransaction(&transaction);
3318 // Tests that a HEAD request can be served from a truncated resource.
3319 TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3320 MockHttpCache cache;
3321 AddMockTransaction(&kRangeGET_TransactionOK);
3323 std::string raw_headers("HTTP/1.1 200 OK\n"
3324 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3325 "ETag: \"foo\"\n"
3326 "Accept-Ranges: bytes\n"
3327 "Content-Length: 80\n");
3328 CreateTruncatedEntry(raw_headers, &cache);
3329 RemoveMockTransaction(&kRangeGET_TransactionOK);
3331 MockTransaction transaction(kSimpleGET_Transaction);
3333 transaction.url = kRangeGET_TransactionOK.url;
3334 transaction.method = "HEAD";
3335 transaction.data = "";
3336 AddMockTransaction(&transaction);
3337 std::string headers;
3339 // Load from cache.
3340 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3342 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3343 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3344 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3345 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3346 EXPECT_EQ(1, cache.disk_cache()->open_count());
3347 EXPECT_EQ(1, cache.disk_cache()->create_count());
3348 RemoveMockTransaction(&transaction);
3351 // Tests that a HEAD request updates the cached response.
3352 TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3353 MockHttpCache cache;
3354 MockTransaction transaction(kTypicalGET_Transaction);
3355 AddMockTransaction(&transaction);
3357 // Populate the cache.
3358 RunTransactionTest(cache.http_cache(), transaction);
3360 // Update the cache.
3361 transaction.method = "HEAD";
3362 transaction.response_headers = "Foo: bar\n";
3363 transaction.data = "";
3364 transaction.status = "HTTP/1.1 304 Not Modified\n";
3365 std::string headers;
3366 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3367 RemoveMockTransaction(&transaction);
3369 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3370 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3372 MockTransaction transaction2(kTypicalGET_Transaction);
3373 AddMockTransaction(&transaction2);
3375 // Make sure we are done with the previous transaction.
3376 base::MessageLoop::current()->RunUntilIdle();
3378 // Load from the cache.
3379 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
3380 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3382 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3383 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3384 EXPECT_EQ(2, cache.disk_cache()->open_count());
3385 EXPECT_EQ(1, cache.disk_cache()->create_count());
3386 RemoveMockTransaction(&transaction2);
3389 // Tests that an externally conditionalized HEAD request updates the cache.
3390 TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3391 MockHttpCache cache;
3392 MockTransaction transaction(kTypicalGET_Transaction);
3393 AddMockTransaction(&transaction);
3395 // Populate the cache.
3396 RunTransactionTest(cache.http_cache(), transaction);
3398 // Update the cache.
3399 transaction.method = "HEAD";
3400 transaction.request_headers =
3401 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3402 transaction.response_headers = "Foo: bar\n";
3403 transaction.data = "";
3404 transaction.status = "HTTP/1.1 304 Not Modified\n";
3405 std::string headers;
3406 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3407 RemoveMockTransaction(&transaction);
3409 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3410 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3412 MockTransaction transaction2(kTypicalGET_Transaction);
3413 AddMockTransaction(&transaction2);
3415 // Make sure we are done with the previous transaction.
3416 base::MessageLoop::current()->RunUntilIdle();
3418 // Load from the cache.
3419 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
3420 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3422 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3423 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3424 EXPECT_EQ(2, cache.disk_cache()->open_count());
3425 EXPECT_EQ(1, cache.disk_cache()->create_count());
3426 RemoveMockTransaction(&transaction2);
3429 // Tests that a HEAD request invalidates an old cached entry.
3430 TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3431 MockHttpCache cache;
3432 MockTransaction transaction(kTypicalGET_Transaction);
3433 AddMockTransaction(&transaction);
3435 // Populate the cache.
3436 RunTransactionTest(cache.http_cache(), transaction);
3438 // Update the cache.
3439 transaction.method = "HEAD";
3440 transaction.data = "";
3441 RunTransactionTest(cache.http_cache(), transaction);
3442 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3444 // Load from the cache.
3445 transaction.method = "GET";
3446 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3447 transaction.return_code = ERR_CACHE_MISS;
3448 RunTransactionTest(cache.http_cache(), transaction);
3450 RemoveMockTransaction(&transaction);
3453 // Tests that we do not cache the response of a PUT.
3454 TEST(HttpCache, SimplePUT_Miss) {
3455 MockHttpCache cache;
3457 MockTransaction transaction(kSimplePOST_Transaction);
3458 transaction.method = "PUT";
3460 ScopedVector<UploadElementReader> element_readers;
3461 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3462 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3464 MockHttpRequest request(transaction);
3465 request.upload_data_stream = &upload_data_stream;
3467 // Attempt to populate the cache.
3468 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3470 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3471 EXPECT_EQ(0, cache.disk_cache()->open_count());
3472 EXPECT_EQ(0, cache.disk_cache()->create_count());
3475 // Tests that we invalidate entries as a result of a PUT.
3476 TEST(HttpCache, SimplePUT_Invalidate) {
3477 MockHttpCache cache;
3479 MockTransaction transaction(kSimpleGET_Transaction);
3480 MockHttpRequest req1(transaction);
3482 // Attempt to populate the cache.
3483 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3485 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3486 EXPECT_EQ(0, cache.disk_cache()->open_count());
3487 EXPECT_EQ(1, cache.disk_cache()->create_count());
3489 ScopedVector<UploadElementReader> element_readers;
3490 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3491 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3493 transaction.method = "PUT";
3494 MockHttpRequest req2(transaction);
3495 req2.upload_data_stream = &upload_data_stream;
3497 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3499 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3500 EXPECT_EQ(1, cache.disk_cache()->open_count());
3501 EXPECT_EQ(1, cache.disk_cache()->create_count());
3503 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3505 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3506 EXPECT_EQ(1, cache.disk_cache()->open_count());
3507 EXPECT_EQ(2, cache.disk_cache()->create_count());
3510 // Tests that we invalidate entries as a result of a PUT.
3511 TEST(HttpCache, SimplePUT_Invalidate_305) {
3512 MockHttpCache cache;
3514 MockTransaction transaction(kSimpleGET_Transaction);
3515 AddMockTransaction(&transaction);
3516 MockHttpRequest req1(transaction);
3518 // Attempt to populate the cache.
3519 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3521 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3522 EXPECT_EQ(0, cache.disk_cache()->open_count());
3523 EXPECT_EQ(1, cache.disk_cache()->create_count());
3525 ScopedVector<UploadElementReader> element_readers;
3526 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3527 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3529 transaction.method = "PUT";
3530 transaction.status = "HTTP/1.1 305 Use Proxy";
3531 MockHttpRequest req2(transaction);
3532 req2.upload_data_stream = &upload_data_stream;
3534 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3536 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3537 EXPECT_EQ(1, cache.disk_cache()->open_count());
3538 EXPECT_EQ(1, cache.disk_cache()->create_count());
3540 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3542 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3543 EXPECT_EQ(1, cache.disk_cache()->open_count());
3544 EXPECT_EQ(2, cache.disk_cache()->create_count());
3545 RemoveMockTransaction(&transaction);
3548 // Tests that we don't invalidate entries as a result of a failed PUT.
3549 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3550 MockHttpCache cache;
3552 MockTransaction transaction(kSimpleGET_Transaction);
3553 AddMockTransaction(&transaction);
3554 MockHttpRequest req1(transaction);
3556 // Attempt to populate the cache.
3557 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3559 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3560 EXPECT_EQ(0, cache.disk_cache()->open_count());
3561 EXPECT_EQ(1, cache.disk_cache()->create_count());
3563 ScopedVector<UploadElementReader> element_readers;
3564 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3565 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3567 transaction.method = "PUT";
3568 transaction.status = "HTTP/1.1 404 Not Found";
3569 MockHttpRequest req2(transaction);
3570 req2.upload_data_stream = &upload_data_stream;
3572 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3574 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3575 EXPECT_EQ(1, cache.disk_cache()->open_count());
3576 EXPECT_EQ(1, cache.disk_cache()->create_count());
3578 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3580 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3581 EXPECT_EQ(2, cache.disk_cache()->open_count());
3582 EXPECT_EQ(1, cache.disk_cache()->create_count());
3583 RemoveMockTransaction(&transaction);
3586 // Tests that we do not cache the response of a DELETE.
3587 TEST(HttpCache, SimpleDELETE_Miss) {
3588 MockHttpCache cache;
3590 MockTransaction transaction(kSimplePOST_Transaction);
3591 transaction.method = "DELETE";
3593 ScopedVector<UploadElementReader> element_readers;
3594 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3595 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3597 MockHttpRequest request(transaction);
3598 request.upload_data_stream = &upload_data_stream;
3600 // Attempt to populate the cache.
3601 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3603 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3604 EXPECT_EQ(0, cache.disk_cache()->open_count());
3605 EXPECT_EQ(0, cache.disk_cache()->create_count());
3608 // Tests that we invalidate entries as a result of a DELETE.
3609 TEST(HttpCache, SimpleDELETE_Invalidate) {
3610 MockHttpCache cache;
3612 MockTransaction transaction(kSimpleGET_Transaction);
3613 MockHttpRequest req1(transaction);
3615 // Attempt to populate the cache.
3616 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3618 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3619 EXPECT_EQ(0, cache.disk_cache()->open_count());
3620 EXPECT_EQ(1, cache.disk_cache()->create_count());
3622 ScopedVector<UploadElementReader> element_readers;
3623 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3624 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3626 transaction.method = "DELETE";
3627 MockHttpRequest req2(transaction);
3628 req2.upload_data_stream = &upload_data_stream;
3630 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3632 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3633 EXPECT_EQ(1, cache.disk_cache()->open_count());
3634 EXPECT_EQ(1, cache.disk_cache()->create_count());
3636 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3638 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3639 EXPECT_EQ(1, cache.disk_cache()->open_count());
3640 EXPECT_EQ(2, cache.disk_cache()->create_count());
3643 // Tests that we invalidate entries as a result of a DELETE.
3644 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3645 MockHttpCache cache;
3647 MockTransaction transaction(kSimpleGET_Transaction);
3648 AddMockTransaction(&transaction);
3650 // Attempt to populate the cache.
3651 RunTransactionTest(cache.http_cache(), transaction);
3653 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3654 EXPECT_EQ(0, cache.disk_cache()->open_count());
3655 EXPECT_EQ(1, cache.disk_cache()->create_count());
3657 transaction.method = "DELETE";
3658 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3660 RunTransactionTest(cache.http_cache(), transaction);
3662 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3663 EXPECT_EQ(1, cache.disk_cache()->open_count());
3664 EXPECT_EQ(1, cache.disk_cache()->create_count());
3666 transaction.method = "GET";
3667 RunTransactionTest(cache.http_cache(), transaction);
3669 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3670 EXPECT_EQ(1, cache.disk_cache()->open_count());
3671 EXPECT_EQ(2, cache.disk_cache()->create_count());
3672 RemoveMockTransaction(&transaction);
3675 // Tests that we don't invalidate entries as a result of a failed DELETE.
3676 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3677 MockHttpCache cache;
3679 MockTransaction transaction(kSimpleGET_Transaction);
3680 AddMockTransaction(&transaction);
3682 // Attempt to populate the cache.
3683 RunTransactionTest(cache.http_cache(), transaction);
3685 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3686 EXPECT_EQ(0, cache.disk_cache()->open_count());
3687 EXPECT_EQ(1, cache.disk_cache()->create_count());
3689 transaction.method = "DELETE";
3690 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3692 RunTransactionTest(cache.http_cache(), transaction);
3694 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3695 EXPECT_EQ(1, cache.disk_cache()->open_count());
3696 EXPECT_EQ(1, cache.disk_cache()->create_count());
3698 transaction.method = "GET";
3699 transaction.status = "HTTP/1.1 200 OK";
3700 RunTransactionTest(cache.http_cache(), transaction);
3702 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3703 EXPECT_EQ(2, cache.disk_cache()->open_count());
3704 EXPECT_EQ(1, cache.disk_cache()->create_count());
3705 RemoveMockTransaction(&transaction);
3708 // Tests that we don't invalidate entries after a failed network transaction.
3709 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3710 MockHttpCache cache;
3712 // Populate the cache.
3713 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3714 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3716 // Fail the network request.
3717 MockTransaction transaction(kSimpleGET_Transaction);
3718 transaction.return_code = ERR_FAILED;
3719 transaction.load_flags |= LOAD_VALIDATE_CACHE;
3721 AddMockTransaction(&transaction);
3722 RunTransactionTest(cache.http_cache(), transaction);
3723 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3724 RemoveMockTransaction(&transaction);
3726 transaction.load_flags = LOAD_ONLY_FROM_CACHE;
3727 transaction.return_code = OK;
3728 AddMockTransaction(&transaction);
3729 RunTransactionTest(cache.http_cache(), transaction);
3731 // Make sure the transaction didn't reach the network.
3732 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3733 RemoveMockTransaction(&transaction);
3736 TEST(HttpCache, RangeGET_SkipsCache) {
3737 MockHttpCache cache;
3739 // Test that we skip the cache for range GET requests. Eventually, we will
3740 // want to cache these, but we'll still have cases where skipping the cache
3741 // makes sense, so we want to make sure that it works properly.
3743 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3745 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3746 EXPECT_EQ(0, cache.disk_cache()->open_count());
3747 EXPECT_EQ(0, cache.disk_cache()->create_count());
3749 MockTransaction transaction(kSimpleGET_Transaction);
3750 transaction.request_headers = "If-None-Match: foo\r\n";
3751 RunTransactionTest(cache.http_cache(), transaction);
3753 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3754 EXPECT_EQ(0, cache.disk_cache()->open_count());
3755 EXPECT_EQ(0, cache.disk_cache()->create_count());
3757 transaction.request_headers =
3758 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3759 RunTransactionTest(cache.http_cache(), transaction);
3761 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3762 EXPECT_EQ(0, cache.disk_cache()->open_count());
3763 EXPECT_EQ(0, cache.disk_cache()->create_count());
3766 // Test that we skip the cache for range requests that include a validation
3767 // header.
3768 TEST(HttpCache, RangeGET_SkipsCache2) {
3769 MockHttpCache cache;
3771 MockTransaction transaction(kRangeGET_Transaction);
3772 transaction.request_headers = "If-None-Match: foo\r\n"
3773 EXTRA_HEADER
3774 "Range: bytes = 40-49\r\n";
3775 RunTransactionTest(cache.http_cache(), transaction);
3777 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3778 EXPECT_EQ(0, cache.disk_cache()->open_count());
3779 EXPECT_EQ(0, cache.disk_cache()->create_count());
3781 transaction.request_headers =
3782 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3783 EXTRA_HEADER
3784 "Range: bytes = 40-49\r\n";
3785 RunTransactionTest(cache.http_cache(), transaction);
3787 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3788 EXPECT_EQ(0, cache.disk_cache()->open_count());
3789 EXPECT_EQ(0, cache.disk_cache()->create_count());
3791 transaction.request_headers = "If-Range: bla\r\n"
3792 EXTRA_HEADER
3793 "Range: bytes = 40-49\r\n";
3794 RunTransactionTest(cache.http_cache(), transaction);
3796 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3797 EXPECT_EQ(0, cache.disk_cache()->open_count());
3798 EXPECT_EQ(0, cache.disk_cache()->create_count());
3801 TEST(HttpCache, SimpleGET_DoesntLogHeaders) {
3802 MockHttpCache cache;
3804 BoundTestNetLog log;
3805 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
3806 log.bound());
3808 EXPECT_FALSE(LogContainsEventType(
3809 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3812 TEST(HttpCache, RangeGET_LogsHeaders) {
3813 MockHttpCache cache;
3815 BoundTestNetLog log;
3816 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
3817 log.bound());
3819 EXPECT_TRUE(LogContainsEventType(
3820 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3823 TEST(HttpCache, ExternalValidation_LogsHeaders) {
3824 MockHttpCache cache;
3826 BoundTestNetLog log;
3827 MockTransaction transaction(kSimpleGET_Transaction);
3828 transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
3829 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3831 EXPECT_TRUE(LogContainsEventType(
3832 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3835 TEST(HttpCache, SpecialHeaders_LogsHeaders) {
3836 MockHttpCache cache;
3838 BoundTestNetLog log;
3839 MockTransaction transaction(kSimpleGET_Transaction);
3840 transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
3841 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3843 EXPECT_TRUE(LogContainsEventType(
3844 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3847 // Tests that receiving 206 for a regular request is handled correctly.
3848 TEST(HttpCache, GET_Crazy206) {
3849 MockHttpCache cache;
3851 // Write to the cache.
3852 MockTransaction transaction(kRangeGET_TransactionOK);
3853 AddMockTransaction(&transaction);
3854 transaction.request_headers = EXTRA_HEADER;
3855 transaction.handler = NULL;
3856 RunTransactionTest(cache.http_cache(), transaction);
3858 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3859 EXPECT_EQ(0, cache.disk_cache()->open_count());
3860 EXPECT_EQ(1, cache.disk_cache()->create_count());
3862 // This should read again from the net.
3863 RunTransactionTest(cache.http_cache(), transaction);
3865 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3866 EXPECT_EQ(0, cache.disk_cache()->open_count());
3867 EXPECT_EQ(2, cache.disk_cache()->create_count());
3868 RemoveMockTransaction(&transaction);
3871 // Tests that receiving 416 for a regular request is handled correctly.
3872 TEST(HttpCache, GET_Crazy416) {
3873 MockHttpCache cache;
3875 // Write to the cache.
3876 MockTransaction transaction(kSimpleGET_Transaction);
3877 AddMockTransaction(&transaction);
3878 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3879 RunTransactionTest(cache.http_cache(), transaction);
3881 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3882 EXPECT_EQ(0, cache.disk_cache()->open_count());
3883 EXPECT_EQ(1, cache.disk_cache()->create_count());
3885 RemoveMockTransaction(&transaction);
3888 // Tests that we don't store partial responses that can't be validated.
3889 TEST(HttpCache, RangeGET_NoStrongValidators) {
3890 MockHttpCache cache;
3891 std::string headers;
3893 // Attempt to write to the cache (40-49).
3894 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3895 transaction.response_headers = "Content-Length: 10\n"
3896 "Cache-Control: max-age=3600\n"
3897 "ETag: w/\"foo\"\n";
3898 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3900 Verify206Response(headers, 40, 49);
3901 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3902 EXPECT_EQ(0, cache.disk_cache()->open_count());
3903 EXPECT_EQ(1, cache.disk_cache()->create_count());
3905 // Now verify that there's no cached data.
3906 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3907 &headers);
3909 Verify206Response(headers, 40, 49);
3910 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3911 EXPECT_EQ(0, cache.disk_cache()->open_count());
3912 EXPECT_EQ(2, cache.disk_cache()->create_count());
3915 // Tests failures to conditionalize byte range requests.
3916 TEST(HttpCache, RangeGET_NoConditionalization) {
3917 MockHttpCache cache;
3918 cache.FailConditionalizations();
3919 std::string headers;
3921 // Write to the cache (40-49).
3922 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3923 transaction.response_headers = "Content-Length: 10\n"
3924 "ETag: \"foo\"\n";
3925 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3927 Verify206Response(headers, 40, 49);
3928 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3929 EXPECT_EQ(0, cache.disk_cache()->open_count());
3930 EXPECT_EQ(1, cache.disk_cache()->create_count());
3932 // Now verify that the cached data is not used.
3933 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3934 &headers);
3936 Verify206Response(headers, 40, 49);
3937 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3938 EXPECT_EQ(1, cache.disk_cache()->open_count());
3939 EXPECT_EQ(2, cache.disk_cache()->create_count());
3942 // Tests that restarting a partial request when the cached data cannot be
3943 // revalidated logs an event.
3944 TEST(HttpCache, RangeGET_NoValidation_LogsRestart) {
3945 MockHttpCache cache;
3946 cache.FailConditionalizations();
3948 // Write to the cache (40-49).
3949 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3950 transaction.response_headers = "Content-Length: 10\n"
3951 "ETag: \"foo\"\n";
3952 RunTransactionTest(cache.http_cache(), transaction);
3954 // Now verify that the cached data is not used.
3955 BoundTestNetLog log;
3956 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
3957 log.bound());
3959 EXPECT_TRUE(LogContainsEventType(
3960 log, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST));
3963 // Tests that a failure to conditionalize a regular request (no range) with a
3964 // sparse entry results in a full response.
3965 TEST(HttpCache, GET_NoConditionalization) {
3966 MockHttpCache cache;
3967 cache.FailConditionalizations();
3968 std::string headers;
3970 // Write to the cache (40-49).
3971 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3972 transaction.response_headers = "Content-Length: 10\n"
3973 "ETag: \"foo\"\n";
3974 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3976 Verify206Response(headers, 40, 49);
3977 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3978 EXPECT_EQ(0, cache.disk_cache()->open_count());
3979 EXPECT_EQ(1, cache.disk_cache()->create_count());
3981 // Now verify that the cached data is not used.
3982 // Don't ask for a range. The cache will attempt to use the cached data but
3983 // should discard it as it cannot be validated. A regular request should go
3984 // to the server and a new entry should be created.
3985 transaction.request_headers = EXTRA_HEADER;
3986 transaction.data = "Not a range";
3987 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3989 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3990 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3991 EXPECT_EQ(1, cache.disk_cache()->open_count());
3992 EXPECT_EQ(2, cache.disk_cache()->create_count());
3994 // The last response was saved.
3995 RunTransactionTest(cache.http_cache(), transaction);
3996 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3997 EXPECT_EQ(2, cache.disk_cache()->open_count());
3998 EXPECT_EQ(2, cache.disk_cache()->create_count());
4001 // Verifies that conditionalization failures when asking for a range that would
4002 // require the cache to modify the range to ask, result in a network request
4003 // that matches the user's one.
4004 TEST(HttpCache, RangeGET_NoConditionalization2) {
4005 MockHttpCache cache;
4006 cache.FailConditionalizations();
4007 std::string headers;
4009 // Write to the cache (40-49).
4010 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4011 transaction.response_headers = "Content-Length: 10\n"
4012 "ETag: \"foo\"\n";
4013 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4015 Verify206Response(headers, 40, 49);
4016 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4017 EXPECT_EQ(0, cache.disk_cache()->open_count());
4018 EXPECT_EQ(1, cache.disk_cache()->create_count());
4020 // Now verify that the cached data is not used.
4021 // Ask for a range that extends before and after the cached data so that the
4022 // cache would normally mix data from three sources. After deleting the entry,
4023 // the response will come from a single network request.
4024 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4025 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4026 transaction.response_headers = kRangeGET_TransactionOK.response_headers;
4027 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4029 Verify206Response(headers, 20, 59);
4030 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4031 EXPECT_EQ(1, cache.disk_cache()->open_count());
4032 EXPECT_EQ(2, cache.disk_cache()->create_count());
4034 // The last response was saved.
4035 RunTransactionTest(cache.http_cache(), transaction);
4036 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4037 EXPECT_EQ(2, cache.disk_cache()->open_count());
4038 EXPECT_EQ(2, cache.disk_cache()->create_count());
4041 // Tests that we cache partial responses that lack content-length.
4042 TEST(HttpCache, RangeGET_NoContentLength) {
4043 MockHttpCache cache;
4044 std::string headers;
4046 // Attempt to write to the cache (40-49).
4047 MockTransaction transaction(kRangeGET_TransactionOK);
4048 AddMockTransaction(&transaction);
4049 transaction.response_headers = "ETag: \"foo\"\n"
4050 "Accept-Ranges: bytes\n"
4051 "Content-Range: bytes 40-49/80\n";
4052 transaction.handler = NULL;
4053 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4055 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4056 EXPECT_EQ(0, cache.disk_cache()->open_count());
4057 EXPECT_EQ(1, cache.disk_cache()->create_count());
4059 // Now verify that there's no cached data.
4060 transaction.handler = &RangeTransactionServer::RangeHandler;
4061 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4062 &headers);
4064 Verify206Response(headers, 40, 49);
4065 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4066 EXPECT_EQ(1, cache.disk_cache()->open_count());
4067 EXPECT_EQ(1, cache.disk_cache()->create_count());
4069 RemoveMockTransaction(&transaction);
4072 // Tests that we can cache range requests and fetch random blocks from the
4073 // cache and the network.
4074 TEST(HttpCache, RangeGET_OK) {
4075 MockHttpCache cache;
4076 AddMockTransaction(&kRangeGET_TransactionOK);
4077 std::string headers;
4079 // Write to the cache (40-49).
4080 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4081 &headers);
4083 Verify206Response(headers, 40, 49);
4084 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4085 EXPECT_EQ(0, cache.disk_cache()->open_count());
4086 EXPECT_EQ(1, cache.disk_cache()->create_count());
4088 // Read from the cache (40-49).
4089 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4090 &headers);
4092 Verify206Response(headers, 40, 49);
4093 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4094 EXPECT_EQ(1, cache.disk_cache()->open_count());
4095 EXPECT_EQ(1, cache.disk_cache()->create_count());
4097 // Make sure we are done with the previous transaction.
4098 base::MessageLoop::current()->RunUntilIdle();
4100 // Write to the cache (30-39).
4101 MockTransaction transaction(kRangeGET_TransactionOK);
4102 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
4103 transaction.data = "rg: 30-39 ";
4104 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4106 Verify206Response(headers, 30, 39);
4107 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4108 EXPECT_EQ(2, cache.disk_cache()->open_count());
4109 EXPECT_EQ(1, cache.disk_cache()->create_count());
4111 // Make sure we are done with the previous transaction.
4112 base::MessageLoop::current()->RunUntilIdle();
4114 // Write and read from the cache (20-59).
4115 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4116 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4117 BoundTestNetLog log;
4118 LoadTimingInfo load_timing_info;
4119 RunTransactionTestWithResponseAndGetTiming(
4120 cache.http_cache(), transaction, &headers, log.bound(),
4121 &load_timing_info);
4123 Verify206Response(headers, 20, 59);
4124 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4125 EXPECT_EQ(3, cache.disk_cache()->open_count());
4126 EXPECT_EQ(1, cache.disk_cache()->create_count());
4127 TestLoadTimingNetworkRequest(load_timing_info);
4129 RemoveMockTransaction(&kRangeGET_TransactionOK);
4132 // Tests that we can cache range requests and fetch random blocks from the
4133 // cache and the network, with synchronous responses.
4134 TEST(HttpCache, RangeGET_SyncOK) {
4135 MockHttpCache cache;
4137 MockTransaction transaction(kRangeGET_TransactionOK);
4138 transaction.test_mode = TEST_MODE_SYNC_ALL;
4139 AddMockTransaction(&transaction);
4141 // Write to the cache (40-49).
4142 std::string headers;
4143 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4145 Verify206Response(headers, 40, 49);
4146 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4147 EXPECT_EQ(0, cache.disk_cache()->open_count());
4148 EXPECT_EQ(1, cache.disk_cache()->create_count());
4150 // Read from the cache (40-49).
4151 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4153 Verify206Response(headers, 40, 49);
4154 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4155 EXPECT_EQ(0, cache.disk_cache()->open_count());
4156 EXPECT_EQ(1, cache.disk_cache()->create_count());
4158 // Make sure we are done with the previous transaction.
4159 base::MessageLoop::current()->RunUntilIdle();
4161 // Write to the cache (30-39).
4162 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
4163 transaction.data = "rg: 30-39 ";
4164 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4166 Verify206Response(headers, 30, 39);
4167 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4168 EXPECT_EQ(1, cache.disk_cache()->open_count());
4169 EXPECT_EQ(1, cache.disk_cache()->create_count());
4171 // Make sure we are done with the previous transaction.
4172 base::MessageLoop::current()->RunUntilIdle();
4174 // Write and read from the cache (20-59).
4175 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4176 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4177 BoundTestNetLog log;
4178 LoadTimingInfo load_timing_info;
4179 RunTransactionTestWithResponseAndGetTiming(
4180 cache.http_cache(), transaction, &headers, log.bound(),
4181 &load_timing_info);
4183 Verify206Response(headers, 20, 59);
4184 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4185 EXPECT_EQ(2, cache.disk_cache()->open_count());
4186 EXPECT_EQ(1, cache.disk_cache()->create_count());
4187 TestLoadTimingNetworkRequest(load_timing_info);
4189 RemoveMockTransaction(&transaction);
4192 // Tests that we don't revalidate an entry unless we are required to do so.
4193 TEST(HttpCache, RangeGET_Revalidate1) {
4194 MockHttpCache cache;
4195 std::string headers;
4197 // Write to the cache (40-49).
4198 MockTransaction transaction(kRangeGET_TransactionOK);
4199 transaction.response_headers =
4200 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4201 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4202 "ETag: \"foo\"\n"
4203 "Accept-Ranges: bytes\n"
4204 "Content-Length: 10\n";
4205 AddMockTransaction(&transaction);
4206 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4208 Verify206Response(headers, 40, 49);
4209 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4210 EXPECT_EQ(0, cache.disk_cache()->open_count());
4211 EXPECT_EQ(1, cache.disk_cache()->create_count());
4213 // Read from the cache (40-49).
4214 BoundTestNetLog log;
4215 LoadTimingInfo load_timing_info;
4216 RunTransactionTestWithResponseAndGetTiming(
4217 cache.http_cache(), transaction, &headers, log.bound(),
4218 &load_timing_info);
4220 Verify206Response(headers, 40, 49);
4221 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4222 EXPECT_EQ(1, cache.disk_cache()->open_count());
4223 EXPECT_EQ(1, cache.disk_cache()->create_count());
4224 TestLoadTimingCachedResponse(load_timing_info);
4226 // Read again forcing the revalidation.
4227 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4228 RunTransactionTestWithResponseAndGetTiming(
4229 cache.http_cache(), transaction, &headers, log.bound(),
4230 &load_timing_info);
4232 Verify206Response(headers, 40, 49);
4233 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4234 EXPECT_EQ(1, cache.disk_cache()->open_count());
4235 EXPECT_EQ(1, cache.disk_cache()->create_count());
4236 TestLoadTimingNetworkRequest(load_timing_info);
4238 RemoveMockTransaction(&transaction);
4241 // Checks that we revalidate an entry when the headers say so.
4242 TEST(HttpCache, RangeGET_Revalidate2) {
4243 MockHttpCache cache;
4244 std::string headers;
4246 // Write to the cache (40-49).
4247 MockTransaction transaction(kRangeGET_TransactionOK);
4248 transaction.response_headers =
4249 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4250 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4251 "ETag: \"foo\"\n"
4252 "Accept-Ranges: bytes\n"
4253 "Content-Length: 10\n";
4254 AddMockTransaction(&transaction);
4255 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4257 Verify206Response(headers, 40, 49);
4258 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4259 EXPECT_EQ(0, cache.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache.disk_cache()->create_count());
4262 // Read from the cache (40-49).
4263 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4264 Verify206Response(headers, 40, 49);
4266 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4267 EXPECT_EQ(1, cache.disk_cache()->open_count());
4268 EXPECT_EQ(1, cache.disk_cache()->create_count());
4270 RemoveMockTransaction(&transaction);
4273 // Tests that we deal with 304s for range requests.
4274 TEST(HttpCache, RangeGET_304) {
4275 MockHttpCache cache;
4276 AddMockTransaction(&kRangeGET_TransactionOK);
4277 std::string headers;
4279 // Write to the cache (40-49).
4280 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4281 &headers);
4283 Verify206Response(headers, 40, 49);
4284 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4285 EXPECT_EQ(0, cache.disk_cache()->open_count());
4286 EXPECT_EQ(1, cache.disk_cache()->create_count());
4288 // Read from the cache (40-49).
4289 RangeTransactionServer handler;
4290 handler.set_not_modified(true);
4291 MockTransaction transaction(kRangeGET_TransactionOK);
4292 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4293 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4295 Verify206Response(headers, 40, 49);
4296 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4297 EXPECT_EQ(1, cache.disk_cache()->open_count());
4298 EXPECT_EQ(1, cache.disk_cache()->create_count());
4300 RemoveMockTransaction(&kRangeGET_TransactionOK);
4303 // Tests that we deal with 206s when revalidating range requests.
4304 TEST(HttpCache, RangeGET_ModifiedResult) {
4305 MockHttpCache cache;
4306 AddMockTransaction(&kRangeGET_TransactionOK);
4307 std::string headers;
4309 // Write to the cache (40-49).
4310 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4311 &headers);
4313 Verify206Response(headers, 40, 49);
4314 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4315 EXPECT_EQ(0, cache.disk_cache()->open_count());
4316 EXPECT_EQ(1, cache.disk_cache()->create_count());
4318 // Attempt to read from the cache (40-49).
4319 RangeTransactionServer handler;
4320 handler.set_modified(true);
4321 MockTransaction transaction(kRangeGET_TransactionOK);
4322 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4323 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4325 Verify206Response(headers, 40, 49);
4326 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4327 EXPECT_EQ(1, cache.disk_cache()->open_count());
4328 EXPECT_EQ(1, cache.disk_cache()->create_count());
4330 // And the entry should be gone.
4331 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4332 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4333 EXPECT_EQ(1, cache.disk_cache()->open_count());
4334 EXPECT_EQ(2, cache.disk_cache()->create_count());
4336 RemoveMockTransaction(&kRangeGET_TransactionOK);
4339 // Tests that when a server returns 206 with a sub-range of the requested range,
4340 // and there is nothing stored in the cache, the returned response is passed to
4341 // the caller as is. In this context, a subrange means a response that starts
4342 // with the same byte that was requested, but that is not the whole range that
4343 // was requested.
4344 TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
4345 MockHttpCache cache;
4346 std::string headers;
4348 // Request a large range (40-59). The server sends 40-49.
4349 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4350 transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
4351 transaction.response_headers =
4352 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4353 "ETag: \"foo\"\n"
4354 "Accept-Ranges: bytes\n"
4355 "Content-Length: 10\n"
4356 "Content-Range: bytes 40-49/80\n";
4357 transaction.handler = nullptr;
4358 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4360 Verify206Response(headers, 40, 49);
4361 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4362 EXPECT_EQ(0, cache.disk_cache()->open_count());
4363 EXPECT_EQ(1, cache.disk_cache()->create_count());
4366 // Tests that when a server returns 206 with a sub-range of the requested range,
4367 // and there was an entry stored in the cache, the cache gets out of the way.
4368 TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_CachedContent) {
4369 MockHttpCache cache;
4370 std::string headers;
4372 // Write to the cache (70-79).
4373 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4374 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4375 transaction.data = "rg: 70-79 ";
4376 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4377 Verify206Response(headers, 70, 79);
4379 // Request a large range (40-79). The cache will ask the server for 40-59.
4380 // The server returns 40-49. The cache should consider the server confused and
4381 // abort caching, restarting the request without caching.
4382 transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
4383 transaction.response_headers =
4384 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4385 "ETag: \"foo\"\n"
4386 "Accept-Ranges: bytes\n"
4387 "Content-Length: 10\n"
4388 "Content-Range: bytes 40-49/80\n";
4389 transaction.handler = nullptr;
4390 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4392 // Two new network requests were issued, one from the cache and another after
4393 // deleting the entry.
4394 Verify206Response(headers, 40, 49);
4395 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4396 EXPECT_EQ(1, cache.disk_cache()->open_count());
4397 EXPECT_EQ(1, cache.disk_cache()->create_count());
4399 // The entry was deleted.
4400 RunTransactionTest(cache.http_cache(), transaction);
4401 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4402 EXPECT_EQ(1, cache.disk_cache()->open_count());
4403 EXPECT_EQ(2, cache.disk_cache()->create_count());
4406 // Tests that when a server returns 206 with a sub-range of the requested range,
4407 // and there was an entry stored in the cache, the cache gets out of the way,
4408 // when the caller is not using ranges.
4409 TEST(HttpCache, GET_206ReturnsSubrangeRange_CachedContent) {
4410 MockHttpCache cache;
4411 std::string headers;
4413 // Write to the cache (70-79).
4414 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4415 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4416 transaction.data = "rg: 70-79 ";
4417 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4418 Verify206Response(headers, 70, 79);
4420 // Don't ask for a range. The cache will ask the server for 0-69.
4421 // The server returns 40-49. The cache should consider the server confused and
4422 // abort caching, restarting the request.
4423 // The second network request should not be a byte range request so the server
4424 // should return 200 + "Not a range"
4425 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
4426 transaction.data = "Not a range";
4427 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4429 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4430 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4431 EXPECT_EQ(1, cache.disk_cache()->open_count());
4432 EXPECT_EQ(1, cache.disk_cache()->create_count());
4434 // The entry was deleted.
4435 RunTransactionTest(cache.http_cache(), transaction);
4436 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4437 EXPECT_EQ(1, cache.disk_cache()->open_count());
4438 EXPECT_EQ(2, cache.disk_cache()->create_count());
4441 // Tests that when a server returns 206 with a random range and there is
4442 // nothing stored in the cache, the returned response is passed to the caller
4443 // as is. In this context, a WrongRange means that the returned range may or may
4444 // not have any relationship with the requested range (may or may not be
4445 // contained). The important part is that the first byte doesn't match the first
4446 // requested byte.
4447 TEST(HttpCache, RangeGET_206ReturnsWrongRange_NoCachedContent) {
4448 MockHttpCache cache;
4449 std::string headers;
4451 // Request a large range (30-59). The server sends (40-49).
4452 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4453 transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
4454 transaction.response_headers =
4455 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4456 "ETag: \"foo\"\n"
4457 "Accept-Ranges: bytes\n"
4458 "Content-Length: 10\n"
4459 "Content-Range: bytes 40-49/80\n";
4460 transaction.handler = nullptr;
4461 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4463 Verify206Response(headers, 40, 49);
4464 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4465 EXPECT_EQ(0, cache.disk_cache()->open_count());
4466 EXPECT_EQ(1, cache.disk_cache()->create_count());
4468 // The entry was deleted.
4469 RunTransactionTest(cache.http_cache(), transaction);
4470 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4471 EXPECT_EQ(0, cache.disk_cache()->open_count());
4472 EXPECT_EQ(2, cache.disk_cache()->create_count());
4475 // Tests that when a server returns 206 with a random range and there is
4476 // an entry stored in the cache, the cache gets out of the way.
4477 TEST(HttpCache, RangeGET_206ReturnsWrongRange_CachedContent) {
4478 MockHttpCache cache;
4479 std::string headers;
4481 // Write to the cache (70-79).
4482 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4483 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4484 transaction.data = "rg: 70-79 ";
4485 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4486 Verify206Response(headers, 70, 79);
4488 // Request a large range (30-79). The cache will ask the server for 30-69.
4489 // The server returns 40-49. The cache should consider the server confused and
4490 // abort caching, returning the weird range to the caller.
4491 transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
4492 transaction.response_headers =
4493 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4494 "ETag: \"foo\"\n"
4495 "Accept-Ranges: bytes\n"
4496 "Content-Length: 10\n"
4497 "Content-Range: bytes 40-49/80\n";
4498 transaction.handler = nullptr;
4499 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4501 Verify206Response(headers, 40, 49);
4502 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4503 EXPECT_EQ(1, cache.disk_cache()->open_count());
4504 EXPECT_EQ(1, cache.disk_cache()->create_count());
4506 // The entry was deleted.
4507 RunTransactionTest(cache.http_cache(), transaction);
4508 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4509 EXPECT_EQ(1, cache.disk_cache()->open_count());
4510 EXPECT_EQ(2, cache.disk_cache()->create_count());
4513 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4514 // the response matches the one provided by the server.
4515 TEST(HttpCache, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
4516 MockHttpCache cache;
4517 std::string headers;
4519 // Request a large range (70-99). The server sends 70-79.
4520 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4521 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4522 transaction.data = "rg: 70-79 ";
4523 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4525 Verify206Response(headers, 70, 79);
4526 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4527 EXPECT_EQ(0, cache.disk_cache()->open_count());
4528 EXPECT_EQ(1, cache.disk_cache()->create_count());
4530 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4531 EXPECT_EQ(1, cache.disk_cache()->open_count());
4534 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4535 // the cache automatically fixes the request.
4536 TEST(HttpCache, RangeGET_206ReturnsSmallerFile_CachedContent) {
4537 MockHttpCache cache;
4538 std::string headers;
4540 // Write to the cache (40-49).
4541 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4542 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4544 // Request a large range (70-99). The server sends 70-79.
4545 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4546 transaction.data = "rg: 70-79 ";
4547 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4549 Verify206Response(headers, 70, 79);
4550 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4551 EXPECT_EQ(1, cache.disk_cache()->open_count());
4552 EXPECT_EQ(1, cache.disk_cache()->create_count());
4554 // The entry was not deleted (the range was automatically fixed).
4555 RunTransactionTest(cache.http_cache(), transaction);
4556 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4557 EXPECT_EQ(2, cache.disk_cache()->open_count());
4558 EXPECT_EQ(1, cache.disk_cache()->create_count());
4561 // Tests that when a caller asks for a not-satisfiable range, the server's
4562 // response is forwarded to the caller.
4563 TEST(HttpCache, RangeGET_416_NoCachedContent) {
4564 MockHttpCache cache;
4565 std::string headers;
4567 // Request a range beyond EOF (80-99).
4568 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4569 transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
4570 transaction.data = "";
4571 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
4572 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4574 EXPECT_EQ(0U, headers.find(transaction.status));
4575 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4576 EXPECT_EQ(0, cache.disk_cache()->open_count());
4577 EXPECT_EQ(1, cache.disk_cache()->create_count());
4579 // The entry was deleted.
4580 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4581 EXPECT_EQ(2, cache.disk_cache()->create_count());
4584 // Tests that we cache 301s for range requests.
4585 TEST(HttpCache, RangeGET_301) {
4586 MockHttpCache cache;
4587 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4588 transaction.status = "HTTP/1.1 301 Moved Permanently";
4589 transaction.response_headers = "Location: http://www.bar.com/\n";
4590 transaction.data = "";
4591 transaction.handler = NULL;
4593 // Write to the cache.
4594 RunTransactionTest(cache.http_cache(), transaction);
4595 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4596 EXPECT_EQ(0, cache.disk_cache()->open_count());
4597 EXPECT_EQ(1, cache.disk_cache()->create_count());
4599 // Read from the cache.
4600 RunTransactionTest(cache.http_cache(), transaction);
4601 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4602 EXPECT_EQ(1, cache.disk_cache()->open_count());
4603 EXPECT_EQ(1, cache.disk_cache()->create_count());
4606 // Tests that we can cache range requests when the start or end is unknown.
4607 // We start with one suffix request, followed by a request from a given point.
4608 TEST(HttpCache, UnknownRangeGET_1) {
4609 MockHttpCache cache;
4610 AddMockTransaction(&kRangeGET_TransactionOK);
4611 std::string headers;
4613 // Write to the cache (70-79).
4614 MockTransaction transaction(kRangeGET_TransactionOK);
4615 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4616 transaction.data = "rg: 70-79 ";
4617 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4619 Verify206Response(headers, 70, 79);
4620 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4621 EXPECT_EQ(0, cache.disk_cache()->open_count());
4622 EXPECT_EQ(1, cache.disk_cache()->create_count());
4624 // Make sure we are done with the previous transaction.
4625 base::MessageLoop::current()->RunUntilIdle();
4627 // Write and read from the cache (60-79).
4628 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
4629 transaction.data = "rg: 60-69 rg: 70-79 ";
4630 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4632 Verify206Response(headers, 60, 79);
4633 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4634 EXPECT_EQ(1, cache.disk_cache()->open_count());
4635 EXPECT_EQ(1, cache.disk_cache()->create_count());
4637 RemoveMockTransaction(&kRangeGET_TransactionOK);
4640 // Tests that we can cache range requests when the start or end is unknown.
4641 // We start with one request from a given point, followed by a suffix request.
4642 // We'll also verify that synchronous cache responses work as intended.
4643 TEST(HttpCache, UnknownRangeGET_2) {
4644 MockHttpCache cache;
4645 std::string headers;
4647 MockTransaction transaction(kRangeGET_TransactionOK);
4648 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
4649 TEST_MODE_SYNC_CACHE_READ |
4650 TEST_MODE_SYNC_CACHE_WRITE;
4651 AddMockTransaction(&transaction);
4653 // Write to the cache (70-79).
4654 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4655 transaction.data = "rg: 70-79 ";
4656 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4658 Verify206Response(headers, 70, 79);
4659 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4660 EXPECT_EQ(0, cache.disk_cache()->open_count());
4661 EXPECT_EQ(1, cache.disk_cache()->create_count());
4663 // Make sure we are done with the previous transaction.
4664 base::MessageLoop::current()->RunUntilIdle();
4666 // Write and read from the cache (60-79).
4667 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
4668 transaction.data = "rg: 60-69 rg: 70-79 ";
4669 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4671 Verify206Response(headers, 60, 79);
4672 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4673 EXPECT_EQ(1, cache.disk_cache()->open_count());
4674 EXPECT_EQ(1, cache.disk_cache()->create_count());
4676 RemoveMockTransaction(&transaction);
4679 // Tests that receiving Not Modified when asking for an open range doesn't mess
4680 // up things.
4681 TEST(HttpCache, UnknownRangeGET_304) {
4682 MockHttpCache cache;
4683 std::string headers;
4685 MockTransaction transaction(kRangeGET_TransactionOK);
4686 AddMockTransaction(&transaction);
4688 RangeTransactionServer handler;
4689 handler.set_not_modified(true);
4691 // Ask for the end of the file, without knowing the length.
4692 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4693 transaction.data = "";
4694 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4696 // We just bypass the cache.
4697 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4698 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4699 EXPECT_EQ(0, cache.disk_cache()->open_count());
4700 EXPECT_EQ(1, cache.disk_cache()->create_count());
4702 RunTransactionTest(cache.http_cache(), transaction);
4703 EXPECT_EQ(2, cache.disk_cache()->create_count());
4705 RemoveMockTransaction(&transaction);
4708 // Tests that we can handle non-range requests when we have cached a range.
4709 TEST(HttpCache, GET_Previous206) {
4710 MockHttpCache cache;
4711 AddMockTransaction(&kRangeGET_TransactionOK);
4712 std::string headers;
4713 BoundTestNetLog log;
4714 LoadTimingInfo load_timing_info;
4716 // Write to the cache (40-49).
4717 RunTransactionTestWithResponseAndGetTiming(
4718 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4719 &load_timing_info);
4721 Verify206Response(headers, 40, 49);
4722 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4723 EXPECT_EQ(0, cache.disk_cache()->open_count());
4724 EXPECT_EQ(1, cache.disk_cache()->create_count());
4725 TestLoadTimingNetworkRequest(load_timing_info);
4727 // Write and read from the cache (0-79), when not asked for a range.
4728 MockTransaction transaction(kRangeGET_TransactionOK);
4729 transaction.request_headers = EXTRA_HEADER;
4730 transaction.data = kFullRangeData;
4731 RunTransactionTestWithResponseAndGetTiming(
4732 cache.http_cache(), transaction, &headers, log.bound(),
4733 &load_timing_info);
4735 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4736 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4737 EXPECT_EQ(1, cache.disk_cache()->open_count());
4738 EXPECT_EQ(1, cache.disk_cache()->create_count());
4739 TestLoadTimingNetworkRequest(load_timing_info);
4741 RemoveMockTransaction(&kRangeGET_TransactionOK);
4744 // Tests that we can handle non-range requests when we have cached the first
4745 // part of the object and the server replies with 304 (Not Modified).
4746 TEST(HttpCache, GET_Previous206_NotModified) {
4747 MockHttpCache cache;
4749 MockTransaction transaction(kRangeGET_TransactionOK);
4750 AddMockTransaction(&transaction);
4751 std::string headers;
4752 BoundTestNetLog log;
4753 LoadTimingInfo load_timing_info;
4755 // Write to the cache (0-9).
4756 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4757 transaction.data = "rg: 00-09 ";
4758 RunTransactionTestWithResponseAndGetTiming(
4759 cache.http_cache(), transaction, &headers, log.bound(),
4760 &load_timing_info);
4761 Verify206Response(headers, 0, 9);
4762 TestLoadTimingNetworkRequest(load_timing_info);
4764 // Write to the cache (70-79).
4765 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4766 transaction.data = "rg: 70-79 ";
4767 RunTransactionTestWithResponseAndGetTiming(
4768 cache.http_cache(), transaction, &headers, log.bound(),
4769 &load_timing_info);
4770 Verify206Response(headers, 70, 79);
4772 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4773 EXPECT_EQ(1, cache.disk_cache()->open_count());
4774 EXPECT_EQ(1, cache.disk_cache()->create_count());
4775 TestLoadTimingNetworkRequest(load_timing_info);
4777 // Read from the cache (0-9), write and read from cache (10 - 79).
4778 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4779 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
4780 transaction.data = kFullRangeData;
4781 RunTransactionTestWithResponseAndGetTiming(
4782 cache.http_cache(), transaction, &headers, log.bound(),
4783 &load_timing_info);
4785 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4786 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4787 EXPECT_EQ(2, cache.disk_cache()->open_count());
4788 EXPECT_EQ(1, cache.disk_cache()->create_count());
4789 TestLoadTimingNetworkRequest(load_timing_info);
4791 RemoveMockTransaction(&transaction);
4794 // Tests that we can handle a regular request to a sparse entry, that results in
4795 // new content provided by the server (206).
4796 TEST(HttpCache, GET_Previous206_NewContent) {
4797 MockHttpCache cache;
4798 AddMockTransaction(&kRangeGET_TransactionOK);
4799 std::string headers;
4801 // Write to the cache (0-9).
4802 MockTransaction transaction(kRangeGET_TransactionOK);
4803 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4804 transaction.data = "rg: 00-09 ";
4805 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4807 Verify206Response(headers, 0, 9);
4808 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4809 EXPECT_EQ(0, cache.disk_cache()->open_count());
4810 EXPECT_EQ(1, cache.disk_cache()->create_count());
4812 // Now we'll issue a request without any range that should result first in a
4813 // 206 (when revalidating), and then in a weird standard answer: the test
4814 // server will not modify the response so we'll get the default range... a
4815 // real server will answer with 200.
4816 MockTransaction transaction2(kRangeGET_TransactionOK);
4817 transaction2.request_headers = EXTRA_HEADER;
4818 transaction2.load_flags |= LOAD_VALIDATE_CACHE;
4819 transaction2.data = "Not a range";
4820 RangeTransactionServer handler;
4821 handler.set_modified(true);
4822 BoundTestNetLog log;
4823 LoadTimingInfo load_timing_info;
4824 RunTransactionTestWithResponseAndGetTiming(
4825 cache.http_cache(), transaction2, &headers, log.bound(),
4826 &load_timing_info);
4828 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4829 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4830 EXPECT_EQ(1, cache.disk_cache()->open_count());
4831 EXPECT_EQ(1, cache.disk_cache()->create_count());
4832 TestLoadTimingNetworkRequest(load_timing_info);
4834 // Verify that the previous request deleted the entry.
4835 RunTransactionTest(cache.http_cache(), transaction);
4836 EXPECT_EQ(2, cache.disk_cache()->create_count());
4838 RemoveMockTransaction(&transaction);
4841 // Tests that we can handle cached 206 responses that are not sparse.
4842 TEST(HttpCache, GET_Previous206_NotSparse) {
4843 MockHttpCache cache;
4845 // Create a disk cache entry that stores 206 headers while not being sparse.
4846 disk_cache::Entry* entry;
4847 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4848 NULL));
4850 std::string raw_headers(kRangeGET_TransactionOK.status);
4851 raw_headers.append("\n");
4852 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4853 raw_headers =
4854 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
4856 HttpResponseInfo response;
4857 response.headers = new HttpResponseHeaders(raw_headers);
4858 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4860 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
4861 int len = static_cast<int>(base::strlcpy(buf->data(),
4862 kRangeGET_TransactionOK.data, 500));
4863 TestCompletionCallback cb;
4864 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4865 EXPECT_EQ(len, cb.GetResult(rv));
4866 entry->Close();
4868 // Now see that we don't use the stored entry.
4869 std::string headers;
4870 BoundTestNetLog log;
4871 LoadTimingInfo load_timing_info;
4872 RunTransactionTestWithResponseAndGetTiming(
4873 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4874 &load_timing_info);
4876 // We are expecting a 200.
4877 std::string expected_headers(kSimpleGET_Transaction.status);
4878 expected_headers.append("\n");
4879 expected_headers.append(kSimpleGET_Transaction.response_headers);
4880 EXPECT_EQ(expected_headers, headers);
4881 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4882 EXPECT_EQ(1, cache.disk_cache()->open_count());
4883 EXPECT_EQ(2, cache.disk_cache()->create_count());
4884 TestLoadTimingNetworkRequest(load_timing_info);
4887 // Tests that we can handle cached 206 responses that are not sparse. This time
4888 // we issue a range request and expect to receive a range.
4889 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4890 MockHttpCache cache;
4891 AddMockTransaction(&kRangeGET_TransactionOK);
4893 // Create a disk cache entry that stores 206 headers while not being sparse.
4894 disk_cache::Entry* entry;
4895 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4896 NULL));
4898 std::string raw_headers(kRangeGET_TransactionOK.status);
4899 raw_headers.append("\n");
4900 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4901 raw_headers =
4902 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
4904 HttpResponseInfo response;
4905 response.headers = new HttpResponseHeaders(raw_headers);
4906 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4908 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
4909 int len = static_cast<int>(base::strlcpy(buf->data(),
4910 kRangeGET_TransactionOK.data, 500));
4911 TestCompletionCallback cb;
4912 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4913 EXPECT_EQ(len, cb.GetResult(rv));
4914 entry->Close();
4916 // Now see that we don't use the stored entry.
4917 std::string headers;
4918 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4919 &headers);
4921 // We are expecting a 206.
4922 Verify206Response(headers, 40, 49);
4923 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4924 EXPECT_EQ(1, cache.disk_cache()->open_count());
4925 EXPECT_EQ(2, cache.disk_cache()->create_count());
4927 RemoveMockTransaction(&kRangeGET_TransactionOK);
4930 // Tests that we can handle cached 206 responses that can't be validated.
4931 TEST(HttpCache, GET_Previous206_NotValidation) {
4932 MockHttpCache cache;
4934 // Create a disk cache entry that stores 206 headers.
4935 disk_cache::Entry* entry;
4936 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4937 NULL));
4939 // Make sure that the headers cannot be validated with the server.
4940 std::string raw_headers(kRangeGET_TransactionOK.status);
4941 raw_headers.append("\n");
4942 raw_headers.append("Content-Length: 80\n");
4943 raw_headers =
4944 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
4946 HttpResponseInfo response;
4947 response.headers = new HttpResponseHeaders(raw_headers);
4948 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4950 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
4951 int len = static_cast<int>(base::strlcpy(buf->data(),
4952 kRangeGET_TransactionOK.data, 500));
4953 TestCompletionCallback cb;
4954 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4955 EXPECT_EQ(len, cb.GetResult(rv));
4956 entry->Close();
4958 // Now see that we don't use the stored entry.
4959 std::string headers;
4960 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4961 &headers);
4963 // We are expecting a 200.
4964 std::string expected_headers(kSimpleGET_Transaction.status);
4965 expected_headers.append("\n");
4966 expected_headers.append(kSimpleGET_Transaction.response_headers);
4967 EXPECT_EQ(expected_headers, headers);
4968 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4969 EXPECT_EQ(1, cache.disk_cache()->open_count());
4970 EXPECT_EQ(2, cache.disk_cache()->create_count());
4973 // Tests that we can handle range requests with cached 200 responses.
4974 TEST(HttpCache, RangeGET_Previous200) {
4975 MockHttpCache cache;
4977 // Store the whole thing with status 200.
4978 MockTransaction transaction(kTypicalGET_Transaction);
4979 transaction.url = kRangeGET_TransactionOK.url;
4980 transaction.data = kFullRangeData;
4981 AddMockTransaction(&transaction);
4982 RunTransactionTest(cache.http_cache(), transaction);
4983 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4984 EXPECT_EQ(0, cache.disk_cache()->open_count());
4985 EXPECT_EQ(1, cache.disk_cache()->create_count());
4987 RemoveMockTransaction(&transaction);
4988 AddMockTransaction(&kRangeGET_TransactionOK);
4990 // Now see that we use the stored entry.
4991 std::string headers;
4992 MockTransaction transaction2(kRangeGET_TransactionOK);
4993 RangeTransactionServer handler;
4994 handler.set_not_modified(true);
4995 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4997 // We are expecting a 206.
4998 Verify206Response(headers, 40, 49);
4999 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5000 EXPECT_EQ(1, cache.disk_cache()->open_count());
5001 EXPECT_EQ(1, cache.disk_cache()->create_count());
5003 // The last transaction has finished so make sure the entry is deactivated.
5004 base::MessageLoop::current()->RunUntilIdle();
5006 // Make a request for an invalid range.
5007 MockTransaction transaction3(kRangeGET_TransactionOK);
5008 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
5009 transaction3.data = transaction.data;
5010 transaction3.load_flags = LOAD_PREFERRING_CACHE;
5011 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
5012 EXPECT_EQ(2, cache.disk_cache()->open_count());
5013 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
5014 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
5015 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
5017 // Make sure the entry is deactivated.
5018 base::MessageLoop::current()->RunUntilIdle();
5020 // Even though the request was invalid, we should have the entry.
5021 RunTransactionTest(cache.http_cache(), transaction2);
5022 EXPECT_EQ(3, cache.disk_cache()->open_count());
5024 // Make sure the entry is deactivated.
5025 base::MessageLoop::current()->RunUntilIdle();
5027 // Now we should receive a range from the server and drop the stored entry.
5028 handler.set_not_modified(false);
5029 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
5030 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
5031 Verify206Response(headers, 40, 49);
5032 EXPECT_EQ(4, cache.network_layer()->transaction_count());
5033 EXPECT_EQ(4, cache.disk_cache()->open_count());
5034 EXPECT_EQ(1, cache.disk_cache()->create_count());
5036 RunTransactionTest(cache.http_cache(), transaction2);
5037 EXPECT_EQ(2, cache.disk_cache()->create_count());
5039 RemoveMockTransaction(&kRangeGET_TransactionOK);
5042 // Tests that we can handle a 200 response when dealing with sparse entries.
5043 TEST(HttpCache, RangeRequestResultsIn200) {
5044 MockHttpCache cache;
5045 AddMockTransaction(&kRangeGET_TransactionOK);
5046 std::string headers;
5048 // Write to the cache (70-79).
5049 MockTransaction transaction(kRangeGET_TransactionOK);
5050 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
5051 transaction.data = "rg: 70-79 ";
5052 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5054 Verify206Response(headers, 70, 79);
5055 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5056 EXPECT_EQ(0, cache.disk_cache()->open_count());
5057 EXPECT_EQ(1, cache.disk_cache()->create_count());
5059 // Now we'll issue a request that results in a plain 200 response, but to
5060 // the to the same URL that we used to store sparse data, and making sure
5061 // that we ask for a range.
5062 RemoveMockTransaction(&kRangeGET_TransactionOK);
5063 MockTransaction transaction2(kSimpleGET_Transaction);
5064 transaction2.url = kRangeGET_TransactionOK.url;
5065 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
5066 AddMockTransaction(&transaction2);
5068 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
5070 std::string expected_headers(kSimpleGET_Transaction.status);
5071 expected_headers.append("\n");
5072 expected_headers.append(kSimpleGET_Transaction.response_headers);
5073 EXPECT_EQ(expected_headers, headers);
5074 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5075 EXPECT_EQ(1, cache.disk_cache()->open_count());
5076 EXPECT_EQ(1, cache.disk_cache()->create_count());
5078 RemoveMockTransaction(&transaction2);
5081 // Tests that a range request that falls outside of the size that we know about
5082 // only deletes the entry if the resource has indeed changed.
5083 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
5084 MockHttpCache cache;
5085 AddMockTransaction(&kRangeGET_TransactionOK);
5086 std::string headers;
5088 // Write to the cache (40-49).
5089 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5090 &headers);
5092 Verify206Response(headers, 40, 49);
5093 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5094 EXPECT_EQ(0, cache.disk_cache()->open_count());
5095 EXPECT_EQ(1, cache.disk_cache()->create_count());
5097 // A weird request should not delete this entry. Ask for bytes 120-.
5098 MockTransaction transaction(kRangeGET_TransactionOK);
5099 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
5100 transaction.data = "";
5101 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5103 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
5104 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5105 EXPECT_EQ(1, cache.disk_cache()->open_count());
5106 EXPECT_EQ(1, cache.disk_cache()->create_count());
5108 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5109 EXPECT_EQ(2, cache.disk_cache()->open_count());
5110 EXPECT_EQ(1, cache.disk_cache()->create_count());
5112 RemoveMockTransaction(&kRangeGET_TransactionOK);
5115 // Tests that we don't delete a sparse entry when we cancel a request.
5116 TEST(HttpCache, RangeGET_Cancel) {
5117 MockHttpCache cache;
5118 AddMockTransaction(&kRangeGET_TransactionOK);
5120 MockHttpRequest request(kRangeGET_TransactionOK);
5122 Context* c = new Context();
5123 int rv = cache.CreateTransaction(&c->trans);
5124 ASSERT_EQ(OK, rv);
5126 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5127 if (rv == ERR_IO_PENDING)
5128 rv = c->callback.WaitForResult();
5130 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5131 EXPECT_EQ(0, cache.disk_cache()->open_count());
5132 EXPECT_EQ(1, cache.disk_cache()->create_count());
5134 // Make sure that the entry has some data stored.
5135 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5136 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5137 if (rv == ERR_IO_PENDING)
5138 rv = c->callback.WaitForResult();
5139 EXPECT_EQ(buf->size(), rv);
5141 // Destroy the transaction.
5142 delete c;
5144 // Verify that the entry has not been deleted.
5145 disk_cache::Entry* entry;
5146 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5147 entry->Close();
5148 RemoveMockTransaction(&kRangeGET_TransactionOK);
5151 // Tests that we don't delete a sparse entry when we start a new request after
5152 // cancelling the previous one.
5153 TEST(HttpCache, RangeGET_Cancel2) {
5154 MockHttpCache cache;
5155 AddMockTransaction(&kRangeGET_TransactionOK);
5157 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5158 MockHttpRequest request(kRangeGET_TransactionOK);
5159 request.load_flags |= LOAD_VALIDATE_CACHE;
5161 Context* c = new Context();
5162 int rv = cache.CreateTransaction(&c->trans);
5163 ASSERT_EQ(OK, rv);
5165 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5166 if (rv == ERR_IO_PENDING)
5167 rv = c->callback.WaitForResult();
5169 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5170 EXPECT_EQ(1, cache.disk_cache()->open_count());
5171 EXPECT_EQ(1, cache.disk_cache()->create_count());
5173 // Make sure that we revalidate the entry and read from the cache (a single
5174 // read will return while waiting for the network).
5175 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
5176 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5177 EXPECT_EQ(5, c->callback.GetResult(rv));
5178 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5179 EXPECT_EQ(ERR_IO_PENDING, rv);
5181 // Destroy the transaction before completing the read.
5182 delete c;
5184 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5185 // message loop. This means that a new transaction will just reuse the same
5186 // active entry (no open or create).
5188 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5190 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5191 EXPECT_EQ(1, cache.disk_cache()->open_count());
5192 EXPECT_EQ(1, cache.disk_cache()->create_count());
5193 RemoveMockTransaction(&kRangeGET_TransactionOK);
5196 // A slight variation of the previous test, this time we cancel two requests in
5197 // a row, making sure that the second is waiting for the entry to be ready.
5198 TEST(HttpCache, RangeGET_Cancel3) {
5199 MockHttpCache cache;
5200 AddMockTransaction(&kRangeGET_TransactionOK);
5202 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5203 MockHttpRequest request(kRangeGET_TransactionOK);
5204 request.load_flags |= LOAD_VALIDATE_CACHE;
5206 Context* c = new Context();
5207 int rv = cache.CreateTransaction(&c->trans);
5208 ASSERT_EQ(OK, rv);
5210 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5211 EXPECT_EQ(ERR_IO_PENDING, rv);
5212 rv = c->callback.WaitForResult();
5214 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5215 EXPECT_EQ(1, cache.disk_cache()->open_count());
5216 EXPECT_EQ(1, cache.disk_cache()->create_count());
5218 // Make sure that we revalidate the entry and read from the cache (a single
5219 // read will return while waiting for the network).
5220 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
5221 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5222 EXPECT_EQ(5, c->callback.GetResult(rv));
5223 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5224 EXPECT_EQ(ERR_IO_PENDING, rv);
5226 // Destroy the transaction before completing the read.
5227 delete c;
5229 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5230 // message loop. This means that a new transaction will just reuse the same
5231 // active entry (no open or create).
5233 c = new Context();
5234 rv = cache.CreateTransaction(&c->trans);
5235 ASSERT_EQ(OK, rv);
5237 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5238 EXPECT_EQ(ERR_IO_PENDING, rv);
5240 MockDiskEntry::IgnoreCallbacks(true);
5241 base::MessageLoop::current()->RunUntilIdle();
5242 MockDiskEntry::IgnoreCallbacks(false);
5244 // The new transaction is waiting for the query range callback.
5245 delete c;
5247 // And we should not crash when the callback is delivered.
5248 base::MessageLoop::current()->RunUntilIdle();
5250 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5251 EXPECT_EQ(1, cache.disk_cache()->open_count());
5252 EXPECT_EQ(1, cache.disk_cache()->create_count());
5253 RemoveMockTransaction(&kRangeGET_TransactionOK);
5256 // Tests that an invalid range response results in no cached entry.
5257 TEST(HttpCache, RangeGET_InvalidResponse1) {
5258 MockHttpCache cache;
5259 std::string headers;
5261 MockTransaction transaction(kRangeGET_TransactionOK);
5262 transaction.handler = NULL;
5263 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
5264 "Content-Length: 10\n";
5265 AddMockTransaction(&transaction);
5266 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5268 std::string expected(transaction.status);
5269 expected.append("\n");
5270 expected.append(transaction.response_headers);
5271 EXPECT_EQ(expected, headers);
5273 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5274 EXPECT_EQ(0, cache.disk_cache()->open_count());
5275 EXPECT_EQ(1, cache.disk_cache()->create_count());
5277 // Verify that we don't have a cached entry.
5278 disk_cache::Entry* entry;
5279 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5281 RemoveMockTransaction(&kRangeGET_TransactionOK);
5284 // Tests that we reject a range that doesn't match the content-length.
5285 TEST(HttpCache, RangeGET_InvalidResponse2) {
5286 MockHttpCache cache;
5287 std::string headers;
5289 MockTransaction transaction(kRangeGET_TransactionOK);
5290 transaction.handler = NULL;
5291 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
5292 "Content-Length: 20\n";
5293 AddMockTransaction(&transaction);
5294 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5296 std::string expected(transaction.status);
5297 expected.append("\n");
5298 expected.append(transaction.response_headers);
5299 EXPECT_EQ(expected, headers);
5301 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5302 EXPECT_EQ(0, cache.disk_cache()->open_count());
5303 EXPECT_EQ(1, cache.disk_cache()->create_count());
5305 // Verify that we don't have a cached entry.
5306 disk_cache::Entry* entry;
5307 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5309 RemoveMockTransaction(&kRangeGET_TransactionOK);
5312 // Tests that if a server tells us conflicting information about a resource we
5313 // drop the entry.
5314 TEST(HttpCache, RangeGET_InvalidResponse3) {
5315 MockHttpCache cache;
5316 std::string headers;
5318 MockTransaction transaction(kRangeGET_TransactionOK);
5319 transaction.handler = NULL;
5320 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
5321 std::string response_headers(transaction.response_headers);
5322 response_headers.append("Content-Range: bytes 50-59/160\n");
5323 transaction.response_headers = response_headers.c_str();
5324 AddMockTransaction(&transaction);
5325 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5327 Verify206Response(headers, 50, 59);
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 RemoveMockTransaction(&transaction);
5333 AddMockTransaction(&kRangeGET_TransactionOK);
5335 // This transaction will report a resource size of 80 bytes, and we think it's
5336 // 160 so we should ignore the response.
5337 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5338 &headers);
5340 Verify206Response(headers, 40, 49);
5341 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5342 EXPECT_EQ(1, cache.disk_cache()->open_count());
5343 EXPECT_EQ(1, cache.disk_cache()->create_count());
5345 // Verify that the entry is gone.
5346 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5347 EXPECT_EQ(1, cache.disk_cache()->open_count());
5348 EXPECT_EQ(2, cache.disk_cache()->create_count());
5349 RemoveMockTransaction(&kRangeGET_TransactionOK);
5352 // Tests that we handle large range values properly.
5353 TEST(HttpCache, RangeGET_LargeValues) {
5354 // We need a real sparse cache for this test.
5355 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5356 std::string headers;
5358 MockTransaction transaction(kRangeGET_TransactionOK);
5359 transaction.handler = NULL;
5360 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
5361 EXTRA_HEADER;
5362 transaction.response_headers =
5363 "ETag: \"foo\"\n"
5364 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5365 "Content-Length: 10\n";
5366 AddMockTransaction(&transaction);
5367 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5369 std::string expected(transaction.status);
5370 expected.append("\n");
5371 expected.append(transaction.response_headers);
5372 EXPECT_EQ(expected, headers);
5374 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5376 // Verify that we have a cached entry.
5377 disk_cache::Entry* en;
5378 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
5379 en->Close();
5381 RemoveMockTransaction(&kRangeGET_TransactionOK);
5384 // Tests that we don't crash with a range request if the disk cache was not
5385 // initialized properly.
5386 TEST(HttpCache, RangeGET_NoDiskCache) {
5387 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
5388 factory->set_fail(true);
5389 factory->FinishCreation(); // We'll complete synchronously.
5390 MockHttpCache cache(factory);
5392 AddMockTransaction(&kRangeGET_TransactionOK);
5394 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5395 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5397 RemoveMockTransaction(&kRangeGET_TransactionOK);
5400 // Tests that we handle byte range requests that skip the cache.
5401 TEST(HttpCache, RangeHEAD) {
5402 MockHttpCache cache;
5403 AddMockTransaction(&kRangeGET_TransactionOK);
5405 MockTransaction transaction(kRangeGET_TransactionOK);
5406 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
5407 transaction.method = "HEAD";
5408 transaction.data = "rg: 70-79 ";
5410 std::string headers;
5411 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5413 Verify206Response(headers, 70, 79);
5414 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5415 EXPECT_EQ(0, cache.disk_cache()->open_count());
5416 EXPECT_EQ(0, cache.disk_cache()->create_count());
5418 RemoveMockTransaction(&kRangeGET_TransactionOK);
5421 // Tests that we don't crash when after reading from the cache we issue a
5422 // request for the next range and the server gives us a 200 synchronously.
5423 TEST(HttpCache, RangeGET_FastFlakyServer) {
5424 MockHttpCache cache;
5426 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5427 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
5428 transaction.test_mode = TEST_MODE_SYNC_NET_START;
5429 transaction.load_flags |= LOAD_VALIDATE_CACHE;
5431 // Write to the cache.
5432 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5434 // And now read from the cache and the network.
5435 RangeTransactionServer handler;
5436 handler.set_bad_200(true);
5437 transaction.data = "Not a range";
5438 BoundTestNetLog log;
5439 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
5441 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5442 EXPECT_EQ(1, cache.disk_cache()->open_count());
5443 EXPECT_EQ(1, cache.disk_cache()->create_count());
5444 EXPECT_TRUE(LogContainsEventType(
5445 log, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
5448 // Tests that when the server gives us less data than expected, we don't keep
5449 // asking for more data.
5450 TEST(HttpCache, RangeGET_FastFlakyServer2) {
5451 MockHttpCache cache;
5453 // First, check with an empty cache (WRITE mode).
5454 MockTransaction transaction(kRangeGET_TransactionOK);
5455 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
5456 transaction.data = "rg: 40-"; // Less than expected.
5457 transaction.handler = NULL;
5458 std::string headers(transaction.response_headers);
5459 headers.append("Content-Range: bytes 40-49/80\n");
5460 transaction.response_headers = headers.c_str();
5462 AddMockTransaction(&transaction);
5464 // Write to the cache.
5465 RunTransactionTest(cache.http_cache(), transaction);
5467 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5468 EXPECT_EQ(0, cache.disk_cache()->open_count());
5469 EXPECT_EQ(1, cache.disk_cache()->create_count());
5471 // Now verify that even in READ_WRITE mode, we forward the bad response to
5472 // the caller.
5473 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
5474 transaction.data = "rg: 60-"; // Less than expected.
5475 headers = kRangeGET_TransactionOK.response_headers;
5476 headers.append("Content-Range: bytes 60-69/80\n");
5477 transaction.response_headers = headers.c_str();
5479 RunTransactionTest(cache.http_cache(), transaction);
5481 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5482 EXPECT_EQ(1, cache.disk_cache()->open_count());
5483 EXPECT_EQ(1, cache.disk_cache()->create_count());
5485 RemoveMockTransaction(&transaction);
5488 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5489 // This test hits a NOTREACHED so it is a release mode only test.
5490 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
5491 MockHttpCache cache;
5492 AddMockTransaction(&kRangeGET_TransactionOK);
5494 // Write to the cache (40-49).
5495 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5496 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5497 EXPECT_EQ(0, cache.disk_cache()->open_count());
5498 EXPECT_EQ(1, cache.disk_cache()->create_count());
5500 // Force this transaction to read from the cache.
5501 MockTransaction transaction(kRangeGET_TransactionOK);
5502 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
5504 MockHttpRequest request(transaction);
5505 TestCompletionCallback callback;
5507 scoped_ptr<HttpTransaction> trans;
5508 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5509 EXPECT_EQ(OK, rv);
5510 ASSERT_TRUE(trans.get());
5512 rv = trans->Start(&request, callback.callback(), BoundNetLog());
5513 if (rv == ERR_IO_PENDING)
5514 rv = callback.WaitForResult();
5515 ASSERT_EQ(ERR_CACHE_MISS, rv);
5517 trans.reset();
5519 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5520 EXPECT_EQ(1, cache.disk_cache()->open_count());
5521 EXPECT_EQ(1, cache.disk_cache()->create_count());
5523 RemoveMockTransaction(&kRangeGET_TransactionOK);
5525 #endif
5527 // Tests the handling of the "truncation" flag.
5528 TEST(HttpCache, WriteResponseInfo_Truncated) {
5529 MockHttpCache cache;
5530 disk_cache::Entry* entry;
5531 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5532 NULL));
5534 std::string headers("HTTP/1.1 200 OK");
5535 headers = HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5536 HttpResponseInfo response;
5537 response.headers = new HttpResponseHeaders(headers);
5539 // Set the last argument for this to be an incomplete request.
5540 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
5541 bool truncated = false;
5542 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5543 EXPECT_TRUE(truncated);
5545 // And now test the opposite case.
5546 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
5547 truncated = true;
5548 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5549 EXPECT_FALSE(truncated);
5550 entry->Close();
5553 // Tests basic pickling/unpickling of HttpResponseInfo.
5554 TEST(HttpCache, PersistHttpResponseInfo) {
5555 // Set some fields (add more if needed.)
5556 HttpResponseInfo response1;
5557 response1.was_cached = false;
5558 response1.socket_address = HostPortPair("1.2.3.4", 80);
5559 response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK");
5561 // Pickle.
5562 Pickle pickle;
5563 response1.Persist(&pickle, false, false);
5565 // Unpickle.
5566 HttpResponseInfo response2;
5567 bool response_truncated;
5568 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5569 EXPECT_FALSE(response_truncated);
5571 // Verify fields.
5572 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5573 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5574 EXPECT_EQ(80, response2.socket_address.port());
5575 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5578 // Tests that we delete an entry when the request is cancelled before starting
5579 // to read from the network.
5580 TEST(HttpCache, DoomOnDestruction) {
5581 MockHttpCache cache;
5583 MockHttpRequest request(kSimpleGET_Transaction);
5585 Context* c = new Context();
5586 int rv = cache.CreateTransaction(&c->trans);
5587 ASSERT_EQ(OK, rv);
5589 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5590 if (rv == ERR_IO_PENDING)
5591 c->result = c->callback.WaitForResult();
5593 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5594 EXPECT_EQ(0, cache.disk_cache()->open_count());
5595 EXPECT_EQ(1, cache.disk_cache()->create_count());
5597 // Destroy the transaction. We only have the headers so we should delete this
5598 // entry.
5599 delete c;
5601 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5603 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5604 EXPECT_EQ(0, cache.disk_cache()->open_count());
5605 EXPECT_EQ(2, cache.disk_cache()->create_count());
5608 // Tests that we delete an entry when the request is cancelled if the response
5609 // does not have content-length and strong validators.
5610 TEST(HttpCache, DoomOnDestruction2) {
5611 MockHttpCache cache;
5613 MockHttpRequest request(kSimpleGET_Transaction);
5615 Context* c = new Context();
5616 int rv = cache.CreateTransaction(&c->trans);
5617 ASSERT_EQ(OK, rv);
5619 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5620 if (rv == ERR_IO_PENDING)
5621 rv = c->callback.WaitForResult();
5623 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5624 EXPECT_EQ(0, cache.disk_cache()->open_count());
5625 EXPECT_EQ(1, cache.disk_cache()->create_count());
5627 // Make sure that the entry has some data stored.
5628 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5629 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5630 if (rv == ERR_IO_PENDING)
5631 rv = c->callback.WaitForResult();
5632 EXPECT_EQ(buf->size(), rv);
5634 // Destroy the transaction.
5635 delete c;
5637 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5639 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5640 EXPECT_EQ(0, cache.disk_cache()->open_count());
5641 EXPECT_EQ(2, cache.disk_cache()->create_count());
5644 // Tests that we delete an entry when the request is cancelled if the response
5645 // has an "Accept-Ranges: none" header.
5646 TEST(HttpCache, DoomOnDestruction3) {
5647 MockHttpCache cache;
5649 MockTransaction transaction(kSimpleGET_Transaction);
5650 transaction.response_headers =
5651 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5652 "Content-Length: 22\n"
5653 "Accept-Ranges: none\n"
5654 "Etag: \"foopy\"\n";
5655 AddMockTransaction(&transaction);
5656 MockHttpRequest request(transaction);
5658 Context* c = new Context();
5659 int rv = cache.CreateTransaction(&c->trans);
5660 ASSERT_EQ(OK, rv);
5662 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5663 if (rv == ERR_IO_PENDING)
5664 rv = c->callback.WaitForResult();
5666 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5667 EXPECT_EQ(0, cache.disk_cache()->open_count());
5668 EXPECT_EQ(1, cache.disk_cache()->create_count());
5670 // Make sure that the entry has some data stored.
5671 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5672 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5673 if (rv == ERR_IO_PENDING)
5674 rv = c->callback.WaitForResult();
5675 EXPECT_EQ(buf->size(), rv);
5677 // Destroy the transaction.
5678 delete c;
5680 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5682 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5683 EXPECT_EQ(0, cache.disk_cache()->open_count());
5684 EXPECT_EQ(2, cache.disk_cache()->create_count());
5686 RemoveMockTransaction(&transaction);
5689 // Tests that we mark an entry as incomplete when the request is cancelled.
5690 TEST(HttpCache, SetTruncatedFlag) {
5691 MockHttpCache cache;
5693 MockTransaction transaction(kSimpleGET_Transaction);
5694 transaction.response_headers =
5695 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5696 "Content-Length: 22\n"
5697 "Etag: \"foopy\"\n";
5698 AddMockTransaction(&transaction);
5699 MockHttpRequest request(transaction);
5701 scoped_ptr<Context> c(new Context());
5703 int rv = cache.CreateTransaction(&c->trans);
5704 ASSERT_EQ(OK, rv);
5706 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5707 if (rv == ERR_IO_PENDING)
5708 rv = c->callback.WaitForResult();
5710 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5711 EXPECT_EQ(0, cache.disk_cache()->open_count());
5712 EXPECT_EQ(1, cache.disk_cache()->create_count());
5714 // Make sure that the entry has some data stored.
5715 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5716 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5717 if (rv == ERR_IO_PENDING)
5718 rv = c->callback.WaitForResult();
5719 EXPECT_EQ(buf->size(), rv);
5721 // We want to cancel the request when the transaction is busy.
5722 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5723 EXPECT_EQ(ERR_IO_PENDING, rv);
5724 EXPECT_FALSE(c->callback.have_result());
5726 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
5728 // Destroy the transaction.
5729 c->trans.reset();
5730 MockHttpCache::SetTestMode(0);
5733 // Make sure that we don't invoke the callback. We may have an issue if the
5734 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5735 // could end up with the transaction being deleted twice if we send any
5736 // notification from the transaction destructor (see http://crbug.com/31723).
5737 EXPECT_FALSE(c->callback.have_result());
5739 // Verify that the entry is marked as incomplete.
5740 disk_cache::Entry* entry;
5741 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5742 HttpResponseInfo response;
5743 bool truncated = false;
5744 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5745 EXPECT_TRUE(truncated);
5746 entry->Close();
5748 RemoveMockTransaction(&transaction);
5751 // Tests that we don't mark an entry as truncated when we read everything.
5752 TEST(HttpCache, DontSetTruncatedFlag) {
5753 MockHttpCache cache;
5755 MockTransaction transaction(kSimpleGET_Transaction);
5756 transaction.response_headers =
5757 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5758 "Content-Length: 22\n"
5759 "Etag: \"foopy\"\n";
5760 AddMockTransaction(&transaction);
5761 MockHttpRequest request(transaction);
5763 scoped_ptr<Context> c(new Context());
5764 int rv = cache.CreateTransaction(&c->trans);
5765 ASSERT_EQ(OK, rv);
5767 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5768 EXPECT_EQ(OK, c->callback.GetResult(rv));
5770 // Read everything.
5771 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(22));
5772 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5773 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5775 // Destroy the transaction.
5776 c->trans.reset();
5778 // Verify that the entry is not marked as truncated.
5779 disk_cache::Entry* entry;
5780 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5781 HttpResponseInfo response;
5782 bool truncated = true;
5783 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5784 EXPECT_FALSE(truncated);
5785 entry->Close();
5787 RemoveMockTransaction(&transaction);
5790 // Tests that we can continue with a request that was interrupted.
5791 TEST(HttpCache, GET_IncompleteResource) {
5792 MockHttpCache cache;
5793 AddMockTransaction(&kRangeGET_TransactionOK);
5795 std::string raw_headers("HTTP/1.1 200 OK\n"
5796 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5797 "ETag: \"foo\"\n"
5798 "Accept-Ranges: bytes\n"
5799 "Content-Length: 80\n");
5800 CreateTruncatedEntry(raw_headers, &cache);
5802 // Now make a regular request.
5803 std::string headers;
5804 MockTransaction transaction(kRangeGET_TransactionOK);
5805 transaction.request_headers = EXTRA_HEADER;
5806 transaction.data = kFullRangeData;
5807 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5809 // We update the headers with the ones received while revalidating.
5810 std::string expected_headers(
5811 "HTTP/1.1 200 OK\n"
5812 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5813 "Accept-Ranges: bytes\n"
5814 "ETag: \"foo\"\n"
5815 "Content-Length: 80\n");
5817 EXPECT_EQ(expected_headers, headers);
5818 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5819 EXPECT_EQ(1, cache.disk_cache()->open_count());
5820 EXPECT_EQ(1, cache.disk_cache()->create_count());
5822 // Verify that the disk entry was updated.
5823 disk_cache::Entry* entry;
5824 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5825 EXPECT_EQ(80, entry->GetDataSize(1));
5826 bool truncated = true;
5827 HttpResponseInfo response;
5828 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5829 EXPECT_FALSE(truncated);
5830 entry->Close();
5832 RemoveMockTransaction(&kRangeGET_TransactionOK);
5835 // Tests the handling of no-store when revalidating a truncated entry.
5836 TEST(HttpCache, GET_IncompleteResource_NoStore) {
5837 MockHttpCache cache;
5838 AddMockTransaction(&kRangeGET_TransactionOK);
5840 std::string raw_headers("HTTP/1.1 200 OK\n"
5841 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5842 "ETag: \"foo\"\n"
5843 "Accept-Ranges: bytes\n"
5844 "Content-Length: 80\n");
5845 CreateTruncatedEntry(raw_headers, &cache);
5846 RemoveMockTransaction(&kRangeGET_TransactionOK);
5848 // Now make a regular request.
5849 MockTransaction transaction(kRangeGET_TransactionOK);
5850 transaction.request_headers = EXTRA_HEADER;
5851 std::string response_headers(transaction.response_headers);
5852 response_headers += ("Cache-Control: no-store\n");
5853 transaction.response_headers = response_headers.c_str();
5854 transaction.data = kFullRangeData;
5855 AddMockTransaction(&transaction);
5857 std::string headers;
5858 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5860 // We update the headers with the ones received while revalidating.
5861 std::string expected_headers(
5862 "HTTP/1.1 200 OK\n"
5863 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5864 "Accept-Ranges: bytes\n"
5865 "Cache-Control: no-store\n"
5866 "ETag: \"foo\"\n"
5867 "Content-Length: 80\n");
5869 EXPECT_EQ(expected_headers, headers);
5870 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5871 EXPECT_EQ(1, cache.disk_cache()->open_count());
5872 EXPECT_EQ(1, cache.disk_cache()->create_count());
5874 // Verify that the disk entry was deleted.
5875 disk_cache::Entry* entry;
5876 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5877 RemoveMockTransaction(&transaction);
5880 // Tests cancelling a request after the server sent no-store.
5881 TEST(HttpCache, GET_IncompleteResource_Cancel) {
5882 MockHttpCache cache;
5883 AddMockTransaction(&kRangeGET_TransactionOK);
5885 std::string raw_headers("HTTP/1.1 200 OK\n"
5886 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5887 "ETag: \"foo\"\n"
5888 "Accept-Ranges: bytes\n"
5889 "Content-Length: 80\n");
5890 CreateTruncatedEntry(raw_headers, &cache);
5891 RemoveMockTransaction(&kRangeGET_TransactionOK);
5893 // Now make a regular request.
5894 MockTransaction transaction(kRangeGET_TransactionOK);
5895 transaction.request_headers = EXTRA_HEADER;
5896 std::string response_headers(transaction.response_headers);
5897 response_headers += ("Cache-Control: no-store\n");
5898 transaction.response_headers = response_headers.c_str();
5899 transaction.data = kFullRangeData;
5900 AddMockTransaction(&transaction);
5902 MockHttpRequest request(transaction);
5903 Context* c = new Context();
5905 int rv = cache.CreateTransaction(&c->trans);
5906 ASSERT_EQ(OK, rv);
5908 // Queue another request to this transaction. We have to start this request
5909 // before the first one gets the response from the server and dooms the entry,
5910 // otherwise it will just create a new entry without being queued to the first
5911 // request.
5912 Context* pending = new Context();
5913 ASSERT_EQ(OK, cache.CreateTransaction(&pending->trans));
5915 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5916 EXPECT_EQ(ERR_IO_PENDING,
5917 pending->trans->Start(&request, pending->callback.callback(),
5918 BoundNetLog()));
5919 EXPECT_EQ(OK, c->callback.GetResult(rv));
5921 // Make sure that the entry has some data stored.
5922 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
5923 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5924 EXPECT_EQ(5, c->callback.GetResult(rv));
5926 // Cancel the requests.
5927 delete c;
5928 delete pending;
5930 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5931 EXPECT_EQ(1, cache.disk_cache()->open_count());
5932 EXPECT_EQ(2, cache.disk_cache()->create_count());
5934 base::MessageLoop::current()->RunUntilIdle();
5935 RemoveMockTransaction(&transaction);
5938 // Tests that we delete truncated entries if the server changes its mind midway.
5939 TEST(HttpCache, GET_IncompleteResource2) {
5940 MockHttpCache cache;
5941 AddMockTransaction(&kRangeGET_TransactionOK);
5943 // Content-length will be intentionally bad.
5944 std::string raw_headers("HTTP/1.1 200 OK\n"
5945 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5946 "ETag: \"foo\"\n"
5947 "Accept-Ranges: bytes\n"
5948 "Content-Length: 50\n");
5949 CreateTruncatedEntry(raw_headers, &cache);
5951 // Now make a regular request. We expect the code to fail the validation and
5952 // retry the request without using byte ranges.
5953 std::string headers;
5954 MockTransaction transaction(kRangeGET_TransactionOK);
5955 transaction.request_headers = EXTRA_HEADER;
5956 transaction.data = "Not a range";
5957 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5959 // The server will return 200 instead of a byte range.
5960 std::string expected_headers(
5961 "HTTP/1.1 200 OK\n"
5962 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5964 EXPECT_EQ(expected_headers, headers);
5965 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5966 EXPECT_EQ(1, cache.disk_cache()->open_count());
5967 EXPECT_EQ(1, cache.disk_cache()->create_count());
5969 // Verify that the disk entry was deleted.
5970 disk_cache::Entry* entry;
5971 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5972 RemoveMockTransaction(&kRangeGET_TransactionOK);
5975 // Tests that we always validate a truncated request.
5976 TEST(HttpCache, GET_IncompleteResource3) {
5977 MockHttpCache cache;
5978 AddMockTransaction(&kRangeGET_TransactionOK);
5980 // This should not require validation for 10 hours.
5981 std::string raw_headers("HTTP/1.1 200 OK\n"
5982 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5983 "ETag: \"foo\"\n"
5984 "Cache-Control: max-age= 36000\n"
5985 "Accept-Ranges: bytes\n"
5986 "Content-Length: 80\n");
5987 CreateTruncatedEntry(raw_headers, &cache);
5989 // Now make a regular request.
5990 std::string headers;
5991 MockTransaction transaction(kRangeGET_TransactionOK);
5992 transaction.request_headers = EXTRA_HEADER;
5993 transaction.data = kFullRangeData;
5995 scoped_ptr<Context> c(new Context);
5996 int rv = cache.CreateTransaction(&c->trans);
5997 ASSERT_EQ(OK, rv);
5999 MockHttpRequest request(transaction);
6000 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6001 EXPECT_EQ(OK, c->callback.GetResult(rv));
6003 // We should have checked with the server before finishing Start().
6004 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6005 EXPECT_EQ(1, cache.disk_cache()->open_count());
6006 EXPECT_EQ(1, cache.disk_cache()->create_count());
6008 RemoveMockTransaction(&kRangeGET_TransactionOK);
6011 // Tests that we handle 401s for truncated resources.
6012 TEST(HttpCache, GET_IncompleteResourceWithAuth) {
6013 MockHttpCache cache;
6014 AddMockTransaction(&kRangeGET_TransactionOK);
6016 std::string raw_headers("HTTP/1.1 200 OK\n"
6017 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6018 "ETag: \"foo\"\n"
6019 "Accept-Ranges: bytes\n"
6020 "Content-Length: 80\n");
6021 CreateTruncatedEntry(raw_headers, &cache);
6023 // Now make a regular request.
6024 MockTransaction transaction(kRangeGET_TransactionOK);
6025 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
6026 EXTRA_HEADER;
6027 transaction.data = kFullRangeData;
6028 RangeTransactionServer handler;
6030 scoped_ptr<Context> c(new Context);
6031 int rv = cache.CreateTransaction(&c->trans);
6032 ASSERT_EQ(OK, rv);
6034 MockHttpRequest request(transaction);
6035 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6036 EXPECT_EQ(OK, c->callback.GetResult(rv));
6038 const HttpResponseInfo* response = c->trans->GetResponseInfo();
6039 ASSERT_TRUE(response);
6040 ASSERT_EQ(401, response->headers->response_code());
6041 rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
6042 EXPECT_EQ(OK, c->callback.GetResult(rv));
6043 response = c->trans->GetResponseInfo();
6044 ASSERT_TRUE(response);
6045 ASSERT_EQ(200, response->headers->response_code());
6047 ReadAndVerifyTransaction(c->trans.get(), transaction);
6048 c.reset(); // The destructor could delete the entry.
6049 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6051 // Verify that the entry was not deleted.
6052 disk_cache::Entry* entry;
6053 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6054 entry->Close();
6056 RemoveMockTransaction(&kRangeGET_TransactionOK);
6059 // Tests that we cache a 200 response to the validation request.
6060 TEST(HttpCache, GET_IncompleteResource4) {
6061 MockHttpCache cache;
6062 AddMockTransaction(&kRangeGET_TransactionOK);
6064 std::string raw_headers("HTTP/1.1 200 OK\n"
6065 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6066 "ETag: \"foo\"\n"
6067 "Accept-Ranges: bytes\n"
6068 "Content-Length: 80\n");
6069 CreateTruncatedEntry(raw_headers, &cache);
6071 // Now make a regular request.
6072 std::string headers;
6073 MockTransaction transaction(kRangeGET_TransactionOK);
6074 transaction.request_headers = EXTRA_HEADER;
6075 transaction.data = "Not a range";
6076 RangeTransactionServer handler;
6077 handler.set_bad_200(true);
6078 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
6080 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6081 EXPECT_EQ(1, cache.disk_cache()->open_count());
6082 EXPECT_EQ(1, cache.disk_cache()->create_count());
6084 // Verify that the disk entry was updated.
6085 disk_cache::Entry* entry;
6086 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6087 EXPECT_EQ(11, entry->GetDataSize(1));
6088 bool truncated = true;
6089 HttpResponseInfo response;
6090 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6091 EXPECT_FALSE(truncated);
6092 entry->Close();
6094 RemoveMockTransaction(&kRangeGET_TransactionOK);
6097 // Tests that when we cancel a request that was interrupted, we mark it again
6098 // as truncated.
6099 TEST(HttpCache, GET_CancelIncompleteResource) {
6100 MockHttpCache cache;
6101 AddMockTransaction(&kRangeGET_TransactionOK);
6103 std::string raw_headers("HTTP/1.1 200 OK\n"
6104 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6105 "ETag: \"foo\"\n"
6106 "Accept-Ranges: bytes\n"
6107 "Content-Length: 80\n");
6108 CreateTruncatedEntry(raw_headers, &cache);
6110 // Now make a regular request.
6111 MockTransaction transaction(kRangeGET_TransactionOK);
6112 transaction.request_headers = EXTRA_HEADER;
6114 MockHttpRequest request(transaction);
6115 Context* c = new Context();
6116 int rv = cache.CreateTransaction(&c->trans);
6117 ASSERT_EQ(OK, rv);
6119 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6120 EXPECT_EQ(OK, c->callback.GetResult(rv));
6122 // Read 20 bytes from the cache, and 10 from the net.
6123 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
6124 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
6125 EXPECT_EQ(20, c->callback.GetResult(rv));
6126 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
6127 EXPECT_EQ(10, c->callback.GetResult(rv));
6129 // At this point, we are already reading so canceling the request should leave
6130 // a truncated one.
6131 delete c;
6133 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6134 EXPECT_EQ(1, cache.disk_cache()->open_count());
6135 EXPECT_EQ(1, cache.disk_cache()->create_count());
6137 // Verify that the disk entry was updated: now we have 30 bytes.
6138 disk_cache::Entry* entry;
6139 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6140 EXPECT_EQ(30, entry->GetDataSize(1));
6141 bool truncated = false;
6142 HttpResponseInfo response;
6143 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6144 EXPECT_TRUE(truncated);
6145 entry->Close();
6146 RemoveMockTransaction(&kRangeGET_TransactionOK);
6149 // Tests that we can handle range requests when we have a truncated entry.
6150 TEST(HttpCache, RangeGET_IncompleteResource) {
6151 MockHttpCache cache;
6152 AddMockTransaction(&kRangeGET_TransactionOK);
6154 // Content-length will be intentionally bogus.
6155 std::string raw_headers("HTTP/1.1 200 OK\n"
6156 "Last-Modified: something\n"
6157 "ETag: \"foo\"\n"
6158 "Accept-Ranges: bytes\n"
6159 "Content-Length: 10\n");
6160 CreateTruncatedEntry(raw_headers, &cache);
6162 // Now make a range request.
6163 std::string headers;
6164 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
6165 &headers);
6167 Verify206Response(headers, 40, 49);
6168 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6169 EXPECT_EQ(1, cache.disk_cache()->open_count());
6170 EXPECT_EQ(2, cache.disk_cache()->create_count());
6172 RemoveMockTransaction(&kRangeGET_TransactionOK);
6175 TEST(HttpCache, SyncRead) {
6176 MockHttpCache cache;
6178 // This test ensures that a read that completes synchronously does not cause
6179 // any problems.
6181 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6182 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
6183 TEST_MODE_SYNC_CACHE_READ |
6184 TEST_MODE_SYNC_CACHE_WRITE);
6186 MockHttpRequest r1(transaction),
6187 r2(transaction),
6188 r3(transaction);
6190 TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
6191 c2(DEFAULT_PRIORITY, cache.http_cache()),
6192 c3(DEFAULT_PRIORITY, cache.http_cache());
6194 c1.Start(&r1, BoundNetLog());
6196 r2.load_flags |= LOAD_ONLY_FROM_CACHE;
6197 c2.Start(&r2, BoundNetLog());
6199 r3.load_flags |= LOAD_ONLY_FROM_CACHE;
6200 c3.Start(&r3, BoundNetLog());
6202 base::MessageLoop::current()->Run();
6204 EXPECT_TRUE(c1.is_done());
6205 EXPECT_TRUE(c2.is_done());
6206 EXPECT_TRUE(c3.is_done());
6208 EXPECT_EQ(OK, c1.error());
6209 EXPECT_EQ(OK, c2.error());
6210 EXPECT_EQ(OK, c3.error());
6213 TEST(HttpCache, ValidationResultsIn200) {
6214 MockHttpCache cache;
6216 // This test ensures that a conditional request, which results in a 200
6217 // instead of a 304, properly truncates the existing response data.
6219 // write to the cache
6220 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6222 // force this transaction to validate the cache
6223 MockTransaction transaction(kETagGET_Transaction);
6224 transaction.load_flags |= LOAD_VALIDATE_CACHE;
6225 RunTransactionTest(cache.http_cache(), transaction);
6227 // read from the cache
6228 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6231 TEST(HttpCache, CachedRedirect) {
6232 MockHttpCache cache;
6234 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
6235 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
6236 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
6238 MockHttpRequest request(kTestTransaction);
6239 TestCompletionCallback callback;
6241 // Write to the cache.
6243 scoped_ptr<HttpTransaction> trans;
6244 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6246 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6247 if (rv == ERR_IO_PENDING)
6248 rv = callback.WaitForResult();
6249 ASSERT_EQ(OK, rv);
6251 const HttpResponseInfo* info = trans->GetResponseInfo();
6252 ASSERT_TRUE(info);
6254 EXPECT_EQ(info->headers->response_code(), 301);
6256 std::string location;
6257 info->headers->EnumerateHeader(NULL, "Location", &location);
6258 EXPECT_EQ(location, "http://www.bar.com/");
6260 // Mark the transaction as completed so it is cached.
6261 trans->DoneReading();
6263 // Destroy transaction when going out of scope. We have not actually
6264 // read the response body -- want to test that it is still getting cached.
6266 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6267 EXPECT_EQ(0, cache.disk_cache()->open_count());
6268 EXPECT_EQ(1, cache.disk_cache()->create_count());
6270 // Active entries in the cache are not retired synchronously. Make
6271 // sure the next run hits the MockHttpCache and open_count is
6272 // correct.
6273 base::MessageLoop::current()->RunUntilIdle();
6275 // Read from the cache.
6277 scoped_ptr<HttpTransaction> trans;
6278 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6280 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6281 if (rv == ERR_IO_PENDING)
6282 rv = callback.WaitForResult();
6283 ASSERT_EQ(OK, rv);
6285 const HttpResponseInfo* info = trans->GetResponseInfo();
6286 ASSERT_TRUE(info);
6288 EXPECT_EQ(info->headers->response_code(), 301);
6290 std::string location;
6291 info->headers->EnumerateHeader(NULL, "Location", &location);
6292 EXPECT_EQ(location, "http://www.bar.com/");
6294 // Mark the transaction as completed so it is cached.
6295 trans->DoneReading();
6297 // Destroy transaction when going out of scope. We have not actually
6298 // read the response body -- want to test that it is still getting cached.
6300 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6301 EXPECT_EQ(1, cache.disk_cache()->open_count());
6302 EXPECT_EQ(1, cache.disk_cache()->create_count());
6305 // Verify that no-cache resources are stored in cache, but are not fetched from
6306 // cache during normal loads.
6307 TEST(HttpCache, CacheControlNoCacheNormalLoad) {
6308 MockHttpCache cache;
6310 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6311 transaction.response_headers = "cache-control: no-cache\n";
6313 // Initial load.
6314 RunTransactionTest(cache.http_cache(), transaction);
6316 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6317 EXPECT_EQ(0, cache.disk_cache()->open_count());
6318 EXPECT_EQ(1, cache.disk_cache()->create_count());
6320 // Try loading again; it should result in a network fetch.
6321 RunTransactionTest(cache.http_cache(), transaction);
6323 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6324 EXPECT_EQ(1, cache.disk_cache()->open_count());
6325 EXPECT_EQ(1, cache.disk_cache()->create_count());
6327 disk_cache::Entry* entry;
6328 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6329 entry->Close();
6332 // Verify that no-cache resources are stored in cache and fetched from cache
6333 // when the LOAD_PREFERRING_CACHE flag is set.
6334 TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
6335 MockHttpCache cache;
6337 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6338 transaction.response_headers = "cache-control: no-cache\n";
6340 // Initial load.
6341 RunTransactionTest(cache.http_cache(), transaction);
6343 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6344 EXPECT_EQ(0, cache.disk_cache()->open_count());
6345 EXPECT_EQ(1, cache.disk_cache()->create_count());
6347 // Try loading again with LOAD_PREFERRING_CACHE.
6348 transaction.load_flags = LOAD_PREFERRING_CACHE;
6349 RunTransactionTest(cache.http_cache(), transaction);
6351 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6352 EXPECT_EQ(1, cache.disk_cache()->open_count());
6353 EXPECT_EQ(1, cache.disk_cache()->create_count());
6355 disk_cache::Entry* entry;
6356 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6357 entry->Close();
6360 TEST(HttpCache, CacheControlNoStore) {
6361 MockHttpCache cache;
6363 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6364 transaction.response_headers = "cache-control: no-store\n";
6366 // initial load
6367 RunTransactionTest(cache.http_cache(), transaction);
6369 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6370 EXPECT_EQ(0, cache.disk_cache()->open_count());
6371 EXPECT_EQ(1, cache.disk_cache()->create_count());
6373 // try loading again; it should result in a network fetch
6374 RunTransactionTest(cache.http_cache(), transaction);
6376 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6377 EXPECT_EQ(0, cache.disk_cache()->open_count());
6378 EXPECT_EQ(2, cache.disk_cache()->create_count());
6380 disk_cache::Entry* entry;
6381 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
6384 TEST(HttpCache, CacheControlNoStore2) {
6385 // this test is similar to the above test, except that the initial response
6386 // is cachable, but when it is validated, no-store is received causing the
6387 // cached document to be deleted.
6388 MockHttpCache cache;
6390 ScopedMockTransaction transaction(kETagGET_Transaction);
6392 // initial load
6393 RunTransactionTest(cache.http_cache(), transaction);
6395 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6396 EXPECT_EQ(0, cache.disk_cache()->open_count());
6397 EXPECT_EQ(1, cache.disk_cache()->create_count());
6399 // try loading again; it should result in a network fetch
6400 transaction.load_flags = LOAD_VALIDATE_CACHE;
6401 transaction.response_headers = "cache-control: no-store\n";
6402 RunTransactionTest(cache.http_cache(), transaction);
6404 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6405 EXPECT_EQ(1, cache.disk_cache()->open_count());
6406 EXPECT_EQ(1, cache.disk_cache()->create_count());
6408 disk_cache::Entry* entry;
6409 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
6412 TEST(HttpCache, CacheControlNoStore3) {
6413 // this test is similar to the above test, except that the response is a 304
6414 // instead of a 200. this should never happen in practice, but it seems like
6415 // a good thing to verify that we still destroy the cache entry.
6416 MockHttpCache cache;
6418 ScopedMockTransaction transaction(kETagGET_Transaction);
6420 // initial load
6421 RunTransactionTest(cache.http_cache(), transaction);
6423 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6424 EXPECT_EQ(0, cache.disk_cache()->open_count());
6425 EXPECT_EQ(1, cache.disk_cache()->create_count());
6427 // try loading again; it should result in a network fetch
6428 transaction.load_flags = LOAD_VALIDATE_CACHE;
6429 transaction.response_headers = "cache-control: no-store\n";
6430 transaction.status = "HTTP/1.1 304 Not Modified";
6431 RunTransactionTest(cache.http_cache(), transaction);
6433 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6434 EXPECT_EQ(1, cache.disk_cache()->open_count());
6435 EXPECT_EQ(1, cache.disk_cache()->create_count());
6437 disk_cache::Entry* entry;
6438 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
6441 // Ensure that we don't cache requests served over bad HTTPS.
6442 TEST(HttpCache, SimpleGET_SSLError) {
6443 MockHttpCache cache;
6445 MockTransaction transaction = kSimpleGET_Transaction;
6446 transaction.cert_status = CERT_STATUS_REVOKED;
6447 ScopedMockTransaction scoped_transaction(transaction);
6449 // write to the cache
6450 RunTransactionTest(cache.http_cache(), transaction);
6452 // Test that it was not cached.
6453 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
6455 MockHttpRequest request(transaction);
6456 TestCompletionCallback callback;
6458 scoped_ptr<HttpTransaction> trans;
6459 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6461 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6462 if (rv == ERR_IO_PENDING)
6463 rv = callback.WaitForResult();
6464 ASSERT_EQ(ERR_CACHE_MISS, rv);
6467 // Ensure that we don't crash by if left-behind transactions.
6468 TEST(HttpCache, OutlivedTransactions) {
6469 MockHttpCache* cache = new MockHttpCache;
6471 scoped_ptr<HttpTransaction> trans;
6472 EXPECT_EQ(OK, cache->CreateTransaction(&trans));
6474 delete cache;
6475 trans.reset();
6478 // Test that the disabled mode works.
6479 TEST(HttpCache, CacheDisabledMode) {
6480 MockHttpCache cache;
6482 // write to the cache
6483 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6485 // go into disabled mode
6486 cache.http_cache()->set_mode(HttpCache::DISABLE);
6488 // force this transaction to write to the cache again
6489 MockTransaction transaction(kSimpleGET_Transaction);
6491 RunTransactionTest(cache.http_cache(), transaction);
6493 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6494 EXPECT_EQ(0, cache.disk_cache()->open_count());
6495 EXPECT_EQ(1, cache.disk_cache()->create_count());
6498 // Other tests check that the response headers of the cached response
6499 // get updated on 304. Here we specifically check that the
6500 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6501 // fields also gets updated.
6502 // http://crbug.com/20594.
6503 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
6504 MockHttpCache cache;
6506 const char kUrl[] = "http://foobar";
6507 const char kData[] = "body";
6509 MockTransaction mock_network_response = { 0 };
6510 mock_network_response.url = kUrl;
6512 AddMockTransaction(&mock_network_response);
6514 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6516 MockTransaction request = { 0 };
6517 request.url = kUrl;
6518 request.method = "GET";
6519 request.request_headers = "\r\n";
6520 request.data = kData;
6522 static const Response kNetResponse1 = {
6523 "HTTP/1.1 200 OK",
6524 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6525 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6526 kData
6529 kNetResponse1.AssignTo(&mock_network_response);
6531 RunTransactionTest(cache.http_cache(), request);
6533 // Request |kUrl| again, this time validating the cache and getting
6534 // a 304 back.
6536 request.load_flags = LOAD_VALIDATE_CACHE;
6538 static const Response kNetResponse2 = {
6539 "HTTP/1.1 304 Not Modified",
6540 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6544 kNetResponse2.AssignTo(&mock_network_response);
6546 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6547 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6549 mock_network_response.request_time = request_time;
6550 mock_network_response.response_time = response_time;
6552 HttpResponseInfo response;
6553 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6555 // The request and response times should have been updated.
6556 EXPECT_EQ(request_time.ToInternalValue(),
6557 response.request_time.ToInternalValue());
6558 EXPECT_EQ(response_time.ToInternalValue(),
6559 response.response_time.ToInternalValue());
6561 std::string headers;
6562 response.headers->GetNormalizedHeaders(&headers);
6564 EXPECT_EQ("HTTP/1.1 200 OK\n"
6565 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6566 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6567 headers);
6569 RemoveMockTransaction(&mock_network_response);
6572 // Tests that we can write metadata to an entry.
6573 TEST(HttpCache, WriteMetadata_OK) {
6574 MockHttpCache cache;
6576 // Write to the cache
6577 HttpResponseInfo response;
6578 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6579 &response);
6580 EXPECT_TRUE(response.metadata.get() == NULL);
6582 // Trivial call.
6583 cache.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY, Time::Now(),
6584 NULL, 0);
6586 // Write meta data to the same entry.
6587 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6588 memset(buf->data(), 0, buf->size());
6589 base::strlcpy(buf->data(), "Hi there", buf->size());
6590 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6591 DEFAULT_PRIORITY, response.response_time,
6592 buf.get(), buf->size());
6594 // Release the buffer before the operation takes place.
6595 buf = NULL;
6597 // Makes sure we finish pending operations.
6598 base::MessageLoop::current()->RunUntilIdle();
6600 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6601 &response);
6602 ASSERT_TRUE(response.metadata.get() != NULL);
6603 EXPECT_EQ(50, response.metadata->size());
6604 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6606 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6607 EXPECT_EQ(2, cache.disk_cache()->open_count());
6608 EXPECT_EQ(1, cache.disk_cache()->create_count());
6611 // Tests that we only write metadata to an entry if the time stamp matches.
6612 TEST(HttpCache, WriteMetadata_Fail) {
6613 MockHttpCache cache;
6615 // Write to the cache
6616 HttpResponseInfo response;
6617 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6618 &response);
6619 EXPECT_TRUE(response.metadata.get() == NULL);
6621 // Attempt to write meta data to the same entry.
6622 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6623 memset(buf->data(), 0, buf->size());
6624 base::strlcpy(buf->data(), "Hi there", buf->size());
6625 base::Time expected_time = response.response_time -
6626 base::TimeDelta::FromMilliseconds(20);
6627 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6628 DEFAULT_PRIORITY, expected_time, buf.get(),
6629 buf->size());
6631 // Makes sure we finish pending operations.
6632 base::MessageLoop::current()->RunUntilIdle();
6634 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6635 &response);
6636 EXPECT_TRUE(response.metadata.get() == NULL);
6638 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6639 EXPECT_EQ(2, cache.disk_cache()->open_count());
6640 EXPECT_EQ(1, cache.disk_cache()->create_count());
6643 // Tests that we can read metadata after validating the entry and with READ mode
6644 // transactions.
6645 TEST(HttpCache, ReadMetadata) {
6646 MockHttpCache cache;
6648 // Write to the cache
6649 HttpResponseInfo response;
6650 RunTransactionTestWithResponseInfo(cache.http_cache(),
6651 kTypicalGET_Transaction, &response);
6652 EXPECT_TRUE(response.metadata.get() == NULL);
6654 // Write meta data to the same entry.
6655 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6656 memset(buf->data(), 0, buf->size());
6657 base::strlcpy(buf->data(), "Hi there", buf->size());
6658 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6659 DEFAULT_PRIORITY, response.response_time,
6660 buf.get(), buf->size());
6662 // Makes sure we finish pending operations.
6663 base::MessageLoop::current()->RunUntilIdle();
6665 // Start with a READ mode transaction.
6666 MockTransaction trans1(kTypicalGET_Transaction);
6667 trans1.load_flags = LOAD_ONLY_FROM_CACHE;
6669 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6670 ASSERT_TRUE(response.metadata.get() != NULL);
6671 EXPECT_EQ(50, response.metadata->size());
6672 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6674 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6675 EXPECT_EQ(2, cache.disk_cache()->open_count());
6676 EXPECT_EQ(1, cache.disk_cache()->create_count());
6677 base::MessageLoop::current()->RunUntilIdle();
6679 // Now make sure that the entry is re-validated with the server.
6680 trans1.load_flags = LOAD_VALIDATE_CACHE;
6681 trans1.status = "HTTP/1.1 304 Not Modified";
6682 AddMockTransaction(&trans1);
6684 response.metadata = NULL;
6685 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6686 EXPECT_TRUE(response.metadata.get() != NULL);
6688 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6689 EXPECT_EQ(3, cache.disk_cache()->open_count());
6690 EXPECT_EQ(1, cache.disk_cache()->create_count());
6691 base::MessageLoop::current()->RunUntilIdle();
6692 RemoveMockTransaction(&trans1);
6694 // Now return 200 when validating the entry so the metadata will be lost.
6695 MockTransaction trans2(kTypicalGET_Transaction);
6696 trans2.load_flags = LOAD_VALIDATE_CACHE;
6697 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6698 EXPECT_TRUE(response.metadata.get() == NULL);
6700 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6701 EXPECT_EQ(4, cache.disk_cache()->open_count());
6702 EXPECT_EQ(1, cache.disk_cache()->create_count());
6705 // Tests that we don't mark entries as truncated when a filter detects the end
6706 // of the stream.
6707 TEST(HttpCache, FilterCompletion) {
6708 MockHttpCache cache;
6709 TestCompletionCallback callback;
6712 scoped_ptr<HttpTransaction> trans;
6713 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6715 MockHttpRequest request(kSimpleGET_Transaction);
6716 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6717 EXPECT_EQ(OK, callback.GetResult(rv));
6719 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6720 rv = trans->Read(buf.get(), 256, callback.callback());
6721 EXPECT_GT(callback.GetResult(rv), 0);
6723 // Now make sure that the entry is preserved.
6724 trans->DoneReading();
6727 // Make sure that the ActiveEntry is gone.
6728 base::MessageLoop::current()->RunUntilIdle();
6730 // Read from the cache.
6731 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6733 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6734 EXPECT_EQ(1, cache.disk_cache()->open_count());
6735 EXPECT_EQ(1, cache.disk_cache()->create_count());
6738 // Tests that we don't mark entries as truncated and release the cache
6739 // entry when DoneReading() is called before any Read() calls, such as
6740 // for a redirect.
6741 TEST(HttpCache, DoneReading) {
6742 MockHttpCache cache;
6743 TestCompletionCallback callback;
6745 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6746 transaction.data = "";
6748 scoped_ptr<HttpTransaction> trans;
6749 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6751 MockHttpRequest request(transaction);
6752 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6753 EXPECT_EQ(OK, callback.GetResult(rv));
6755 trans->DoneReading();
6756 // Leave the transaction around.
6758 // Make sure that the ActiveEntry is gone.
6759 base::MessageLoop::current()->RunUntilIdle();
6761 // Read from the cache. This should not deadlock.
6762 RunTransactionTest(cache.http_cache(), transaction);
6764 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6765 EXPECT_EQ(1, cache.disk_cache()->open_count());
6766 EXPECT_EQ(1, cache.disk_cache()->create_count());
6769 // Tests that we stop caching when told.
6770 TEST(HttpCache, StopCachingDeletesEntry) {
6771 MockHttpCache cache;
6772 TestCompletionCallback callback;
6773 MockHttpRequest request(kSimpleGET_Transaction);
6776 scoped_ptr<HttpTransaction> trans;
6777 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6779 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6780 EXPECT_EQ(OK, callback.GetResult(rv));
6782 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6783 rv = trans->Read(buf.get(), 10, callback.callback());
6784 EXPECT_EQ(10, callback.GetResult(rv));
6786 trans->StopCaching();
6788 // We should be able to keep reading.
6789 rv = trans->Read(buf.get(), 256, callback.callback());
6790 EXPECT_GT(callback.GetResult(rv), 0);
6791 rv = trans->Read(buf.get(), 256, callback.callback());
6792 EXPECT_EQ(0, callback.GetResult(rv));
6795 // Make sure that the ActiveEntry is gone.
6796 base::MessageLoop::current()->RunUntilIdle();
6798 // Verify that the entry is gone.
6799 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6801 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6802 EXPECT_EQ(0, cache.disk_cache()->open_count());
6803 EXPECT_EQ(2, cache.disk_cache()->create_count());
6806 // Tests that we stop caching when told, even if DoneReading is called
6807 // after StopCaching.
6808 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6809 MockHttpCache cache;
6810 TestCompletionCallback callback;
6811 MockHttpRequest request(kSimpleGET_Transaction);
6814 scoped_ptr<HttpTransaction> trans;
6815 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6817 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6818 EXPECT_EQ(OK, callback.GetResult(rv));
6820 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6821 rv = trans->Read(buf.get(), 10, callback.callback());
6822 EXPECT_EQ(10, callback.GetResult(rv));
6824 trans->StopCaching();
6826 // We should be able to keep reading.
6827 rv = trans->Read(buf.get(), 256, callback.callback());
6828 EXPECT_GT(callback.GetResult(rv), 0);
6829 rv = trans->Read(buf.get(), 256, callback.callback());
6830 EXPECT_EQ(0, callback.GetResult(rv));
6832 // We should be able to call DoneReading.
6833 trans->DoneReading();
6836 // Make sure that the ActiveEntry is gone.
6837 base::MessageLoop::current()->RunUntilIdle();
6839 // Verify that the entry is gone.
6840 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6842 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6843 EXPECT_EQ(0, cache.disk_cache()->open_count());
6844 EXPECT_EQ(2, cache.disk_cache()->create_count());
6847 // Tests that we stop caching when told, when using auth.
6848 TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6849 MockHttpCache cache;
6850 TestCompletionCallback callback;
6851 MockTransaction mock_transaction(kSimpleGET_Transaction);
6852 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6853 AddMockTransaction(&mock_transaction);
6854 MockHttpRequest request(mock_transaction);
6857 scoped_ptr<HttpTransaction> trans;
6858 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6860 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6861 EXPECT_EQ(OK, callback.GetResult(rv));
6863 trans->StopCaching();
6865 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6866 rv = trans->Read(buf.get(), 10, callback.callback());
6867 EXPECT_EQ(callback.GetResult(rv), 10);
6869 RemoveMockTransaction(&mock_transaction);
6871 // Make sure that the ActiveEntry is gone.
6872 base::MessageLoop::current()->RunUntilIdle();
6874 // Verify that the entry is gone.
6875 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6877 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6878 EXPECT_EQ(0, cache.disk_cache()->open_count());
6879 EXPECT_EQ(2, cache.disk_cache()->create_count());
6882 // Tests that when we are told to stop caching we don't throw away valid data.
6883 TEST(HttpCache, StopCachingSavesEntry) {
6884 MockHttpCache cache;
6885 TestCompletionCallback callback;
6886 MockHttpRequest request(kSimpleGET_Transaction);
6889 scoped_ptr<HttpTransaction> trans;
6890 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6892 // Force a response that can be resumed.
6893 MockTransaction mock_transaction(kSimpleGET_Transaction);
6894 AddMockTransaction(&mock_transaction);
6895 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6896 "Content-Length: 42\n"
6897 "Etag: \"foo\"\n";
6899 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6900 EXPECT_EQ(OK, callback.GetResult(rv));
6902 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6903 rv = trans->Read(buf.get(), 10, callback.callback());
6904 EXPECT_EQ(callback.GetResult(rv), 10);
6906 trans->StopCaching();
6908 // We should be able to keep reading.
6909 rv = trans->Read(buf.get(), 256, callback.callback());
6910 EXPECT_GT(callback.GetResult(rv), 0);
6911 rv = trans->Read(buf.get(), 256, callback.callback());
6912 EXPECT_EQ(callback.GetResult(rv), 0);
6914 RemoveMockTransaction(&mock_transaction);
6917 // Verify that the entry is marked as incomplete.
6918 disk_cache::Entry* entry;
6919 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6920 HttpResponseInfo response;
6921 bool truncated = false;
6922 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6923 EXPECT_TRUE(truncated);
6924 entry->Close();
6927 // Tests that we handle truncated enries when StopCaching is called.
6928 TEST(HttpCache, StopCachingTruncatedEntry) {
6929 MockHttpCache cache;
6930 TestCompletionCallback callback;
6931 MockHttpRequest request(kRangeGET_TransactionOK);
6932 request.extra_headers.Clear();
6933 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6934 AddMockTransaction(&kRangeGET_TransactionOK);
6936 std::string raw_headers("HTTP/1.1 200 OK\n"
6937 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6938 "ETag: \"foo\"\n"
6939 "Accept-Ranges: bytes\n"
6940 "Content-Length: 80\n");
6941 CreateTruncatedEntry(raw_headers, &cache);
6944 // Now make a regular request.
6945 scoped_ptr<HttpTransaction> trans;
6946 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6948 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6949 EXPECT_EQ(OK, callback.GetResult(rv));
6951 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6952 rv = trans->Read(buf.get(), 10, callback.callback());
6953 EXPECT_EQ(callback.GetResult(rv), 10);
6955 // This is actually going to do nothing.
6956 trans->StopCaching();
6958 // We should be able to keep reading.
6959 rv = trans->Read(buf.get(), 256, callback.callback());
6960 EXPECT_GT(callback.GetResult(rv), 0);
6961 rv = trans->Read(buf.get(), 256, callback.callback());
6962 EXPECT_GT(callback.GetResult(rv), 0);
6963 rv = trans->Read(buf.get(), 256, callback.callback());
6964 EXPECT_EQ(callback.GetResult(rv), 0);
6967 // Verify that the disk entry was updated.
6968 disk_cache::Entry* entry;
6969 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6970 EXPECT_EQ(80, entry->GetDataSize(1));
6971 bool truncated = true;
6972 HttpResponseInfo response;
6973 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6974 EXPECT_FALSE(truncated);
6975 entry->Close();
6977 RemoveMockTransaction(&kRangeGET_TransactionOK);
6980 // Tests that we detect truncated resources from the net when there is
6981 // a Content-Length header.
6982 TEST(HttpCache, TruncatedByContentLength) {
6983 MockHttpCache cache;
6984 TestCompletionCallback callback;
6986 MockTransaction transaction(kSimpleGET_Transaction);
6987 AddMockTransaction(&transaction);
6988 transaction.response_headers = "Cache-Control: max-age=10000\n"
6989 "Content-Length: 100\n";
6990 RunTransactionTest(cache.http_cache(), transaction);
6991 RemoveMockTransaction(&transaction);
6993 // Read from the cache.
6994 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6996 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6997 EXPECT_EQ(0, cache.disk_cache()->open_count());
6998 EXPECT_EQ(2, cache.disk_cache()->create_count());
7001 // Tests that we actually flag entries as truncated when we detect an error
7002 // from the net.
7003 TEST(HttpCache, TruncatedByContentLength2) {
7004 MockHttpCache cache;
7005 TestCompletionCallback callback;
7007 MockTransaction transaction(kSimpleGET_Transaction);
7008 AddMockTransaction(&transaction);
7009 transaction.response_headers = "Cache-Control: max-age=10000\n"
7010 "Content-Length: 100\n"
7011 "Etag: \"foo\"\n";
7012 RunTransactionTest(cache.http_cache(), transaction);
7013 RemoveMockTransaction(&transaction);
7015 // Verify that the entry is marked as incomplete.
7016 disk_cache::Entry* entry;
7017 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
7018 HttpResponseInfo response;
7019 bool truncated = false;
7020 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
7021 EXPECT_TRUE(truncated);
7022 entry->Close();
7025 // Make sure that calling SetPriority on a cache transaction passes on
7026 // its priority updates to its underlying network transaction.
7027 TEST(HttpCache, SetPriority) {
7028 MockHttpCache cache;
7030 scoped_ptr<HttpTransaction> trans;
7031 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
7033 // Shouldn't crash, but doesn't do anything either.
7034 trans->SetPriority(LOW);
7036 EXPECT_FALSE(cache.network_layer()->last_transaction());
7037 EXPECT_EQ(DEFAULT_PRIORITY,
7038 cache.network_layer()->last_create_transaction_priority());
7040 HttpRequestInfo info;
7041 info.url = GURL(kSimpleGET_Transaction.url);
7042 TestCompletionCallback callback;
7043 EXPECT_EQ(ERR_IO_PENDING,
7044 trans->Start(&info, callback.callback(), BoundNetLog()));
7046 EXPECT_TRUE(cache.network_layer()->last_transaction());
7047 if (cache.network_layer()->last_transaction()) {
7048 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
7049 EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
7052 trans->SetPriority(HIGHEST);
7054 if (cache.network_layer()->last_transaction()) {
7055 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
7056 EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
7059 EXPECT_EQ(OK, callback.WaitForResult());
7062 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7063 // transaction passes on its argument to the underlying network transaction.
7064 TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
7065 MockHttpCache cache;
7067 FakeWebSocketHandshakeStreamCreateHelper create_helper;
7068 scoped_ptr<HttpTransaction> trans;
7069 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
7071 EXPECT_FALSE(cache.network_layer()->last_transaction());
7073 HttpRequestInfo info;
7074 info.url = GURL(kSimpleGET_Transaction.url);
7075 TestCompletionCallback callback;
7076 EXPECT_EQ(ERR_IO_PENDING,
7077 trans->Start(&info, callback.callback(), BoundNetLog()));
7079 ASSERT_TRUE(cache.network_layer()->last_transaction());
7080 EXPECT_FALSE(cache.network_layer()->last_transaction()->
7081 websocket_handshake_stream_create_helper());
7082 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
7083 EXPECT_EQ(&create_helper,
7084 cache.network_layer()->last_transaction()->
7085 websocket_handshake_stream_create_helper());
7086 EXPECT_EQ(OK, callback.WaitForResult());
7089 // Make sure that a cache transaction passes on its priority to
7090 // newly-created network transactions.
7091 TEST(HttpCache, SetPriorityNewTransaction) {
7092 MockHttpCache cache;
7093 AddMockTransaction(&kRangeGET_TransactionOK);
7095 std::string raw_headers("HTTP/1.1 200 OK\n"
7096 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7097 "ETag: \"foo\"\n"
7098 "Accept-Ranges: bytes\n"
7099 "Content-Length: 80\n");
7100 CreateTruncatedEntry(raw_headers, &cache);
7102 // Now make a regular request.
7103 std::string headers;
7104 MockTransaction transaction(kRangeGET_TransactionOK);
7105 transaction.request_headers = EXTRA_HEADER;
7106 transaction.data = kFullRangeData;
7108 scoped_ptr<HttpTransaction> trans;
7109 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(MEDIUM, &trans));
7110 EXPECT_EQ(DEFAULT_PRIORITY,
7111 cache.network_layer()->last_create_transaction_priority());
7113 MockHttpRequest info(transaction);
7114 TestCompletionCallback callback;
7115 EXPECT_EQ(ERR_IO_PENDING,
7116 trans->Start(&info, callback.callback(), BoundNetLog()));
7117 EXPECT_EQ(OK, callback.WaitForResult());
7119 EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
7121 trans->SetPriority(HIGHEST);
7122 // Should trigger a new network transaction and pick up the new
7123 // priority.
7124 ReadAndVerifyTransaction(trans.get(), transaction);
7126 EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
7128 RemoveMockTransaction(&kRangeGET_TransactionOK);
7131 int64 RunTransactionAndGetReceivedBytes(
7132 MockHttpCache& cache,
7133 const MockTransaction& trans_info) {
7134 int64 received_bytes = -1;
7135 RunTransactionTestBase(cache.http_cache(), trans_info,
7136 MockHttpRequest(trans_info), NULL, BoundNetLog(), NULL,
7137 &received_bytes);
7138 return received_bytes;
7141 int64 TransactionSize(const MockTransaction& transaction) {
7142 return strlen(transaction.status) + strlen(transaction.response_headers) +
7143 strlen(transaction.data);
7146 TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
7147 MockHttpCache cache;
7149 MockTransaction transaction(kSimpleGET_Transaction);
7150 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7151 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7153 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7154 EXPECT_EQ(0, received_bytes);
7157 TEST(HttpCache, ReceivedBytesConditionalRequest304) {
7158 MockHttpCache cache;
7160 ScopedMockTransaction transaction(kETagGET_Transaction);
7161 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7162 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7164 transaction.load_flags = LOAD_VALIDATE_CACHE;
7165 transaction.handler = ETagGet_ConditionalRequest_Handler;
7166 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7167 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7170 TEST(HttpCache, ReceivedBytesConditionalRequest200) {
7171 MockHttpCache cache;
7173 MockTransaction transaction(kTypicalGET_Transaction);
7174 transaction.request_headers = "Foo: bar\r\n";
7175 transaction.response_headers =
7176 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7177 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7178 "Etag: \"foopy\"\n"
7179 "Cache-Control: max-age=0\n"
7180 "Vary: Foo\n";
7181 AddMockTransaction(&transaction);
7182 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7183 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7185 RevalidationServer server;
7186 transaction.handler = server.Handler;
7187 transaction.request_headers = "Foo: none\r\n";
7188 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7189 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7191 RemoveMockTransaction(&transaction);
7194 TEST(HttpCache, ReceivedBytesRange) {
7195 MockHttpCache cache;
7196 AddMockTransaction(&kRangeGET_TransactionOK);
7197 MockTransaction transaction(kRangeGET_TransactionOK);
7199 // Read bytes 40-49 from the network.
7200 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7201 int64 range_response_size = TransactionSize(transaction);
7202 EXPECT_EQ(range_response_size, received_bytes);
7204 // Read bytes 40-49 from the cache.
7205 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7206 EXPECT_EQ(0, received_bytes);
7207 base::MessageLoop::current()->RunUntilIdle();
7209 // Read bytes 30-39 from the network.
7210 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
7211 transaction.data = "rg: 30-39 ";
7212 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7213 EXPECT_EQ(range_response_size, received_bytes);
7214 base::MessageLoop::current()->RunUntilIdle();
7216 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7217 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
7218 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7219 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7220 EXPECT_EQ(range_response_size * 2, received_bytes);
7222 RemoveMockTransaction(&kRangeGET_TransactionOK);
7225 class HttpCachePrefetchValidationTest : public ::testing::Test {
7226 protected:
7227 static const int kMaxAgeSecs = 100;
7228 static const int kRequireValidationSecs = kMaxAgeSecs + 1;
7230 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
7231 DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
7233 clock_ = new base::SimpleTestClock();
7234 cache_.http_cache()->SetClockForTesting(make_scoped_ptr(clock_));
7235 cache_.network_layer()->SetClock(clock_);
7237 transaction_.response_headers = "Cache-Control: max-age=100\n";
7240 bool TransactionRequiredNetwork(int load_flags) {
7241 int pre_transaction_count = transaction_count();
7242 transaction_.load_flags = load_flags;
7243 RunTransactionTest(cache_.http_cache(), transaction_);
7244 return pre_transaction_count != transaction_count();
7247 void AdvanceTime(int seconds) {
7248 clock_->Advance(base::TimeDelta::FromSeconds(seconds));
7251 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
7253 // How many times this test has sent requests to the (fake) origin
7254 // server. Every test case needs to make at least one request to initialise
7255 // the cache.
7256 int transaction_count() {
7257 return cache_.network_layer()->transaction_count();
7260 MockHttpCache cache_;
7261 ScopedMockTransaction transaction_;
7262 std::string response_headers_;
7263 base::SimpleTestClock* clock_;
7266 TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
7267 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7268 AdvanceTime(kRequireValidationSecs);
7269 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7272 TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
7273 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7274 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
7275 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7278 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
7279 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7280 AdvanceTime(kRequireValidationSecs);
7281 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7282 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7285 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
7286 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7287 AdvanceTime(kRequireValidationSecs);
7288 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE));
7289 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7292 TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
7293 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7294 AdvanceTime(kRequireValidationSecs);
7295 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
7296 AdvanceTime(kRequireValidationSecs);
7297 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7300 TEST_F(HttpCachePrefetchValidationTest,
7301 SkipValidationOnExistingEntryThatNeedsValidation) {
7302 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7303 AdvanceTime(kRequireValidationSecs);
7304 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7305 AdvanceTime(kRequireValidationSecs);
7306 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7307 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7310 TEST_F(HttpCachePrefetchValidationTest,
7311 SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
7312 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7313 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
7314 AdvanceTime(kRequireValidationSecs);
7315 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7316 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7319 TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
7320 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7321 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
7322 AdvanceTime(kRequireValidationSecs);
7323 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7326 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
7327 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7328 AdvanceTime(kRequireValidationSecs);
7329 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7330 AdvanceTime(kRequireValidationSecs);
7331 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7334 // Framework for tests of stale-while-revalidate related functionality. With
7335 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
7336 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
7337 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
7338 // synchronous revalidation.
7339 class HttpCacheStaleWhileRevalidateTest : public ::testing::Test {
7340 protected:
7341 HttpCacheStaleWhileRevalidateTest()
7342 : transaction_(kSimpleGET_Transaction),
7343 age_(3601),
7344 stale_while_revalidate_(7200),
7345 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
7346 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true);
7349 // RunTransactionTest() with the arguments from this fixture.
7350 void RunFixtureTransactionTest() {
7351 std::string response_headers = base::StringPrintf(
7352 "%s\n"
7353 "Age: %d\n"
7354 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
7355 validator_.c_str(),
7356 age_,
7357 stale_while_revalidate_);
7358 transaction_.response_headers = response_headers.c_str();
7359 RunTransactionTest(cache_.http_cache(), transaction_);
7360 transaction_.response_headers = "";
7363 // How many times this test has sent requests to the (fake) origin
7364 // server. Every test case needs to make at least one request to initialise
7365 // the cache.
7366 int transaction_count() {
7367 return cache_.network_layer()->transaction_count();
7370 // How many times an existing cache entry was opened during the test case.
7371 int open_count() { return cache_.disk_cache()->open_count(); }
7373 MockHttpCache cache_;
7374 ScopedMockTransaction transaction_;
7375 int age_;
7376 int stale_while_revalidate_;
7377 std::string validator_;
7380 static void CheckResourceFreshnessHeader(const HttpRequestInfo* request,
7381 std::string* response_status,
7382 std::string* response_headers,
7383 std::string* response_data) {
7384 std::string value;
7385 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
7386 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
7389 // Verify that the Resource-Freshness header is sent on a revalidation if the
7390 // stale-while-revalidate directive was on the response.
7391 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) {
7392 age_ = 10801; // Outside the stale-while-revalidate window.
7394 // Write to the cache.
7395 RunFixtureTransactionTest();
7397 EXPECT_EQ(1, transaction_count());
7399 // Send the request again and check that Resource-Freshness header is added.
7400 transaction_.handler = CheckResourceFreshnessHeader;
7402 RunFixtureTransactionTest();
7404 EXPECT_EQ(2, transaction_count());
7407 static void CheckResourceFreshnessAbsent(const HttpRequestInfo* request,
7408 std::string* response_status,
7409 std::string* response_headers,
7410 std::string* response_data) {
7411 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
7414 // Verify that the Resource-Freshness header is not sent when
7415 // stale-while-revalidate is 0.
7416 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) {
7417 age_ = 10801;
7418 stale_while_revalidate_ = 0;
7420 // Write to the cache.
7421 RunFixtureTransactionTest();
7423 EXPECT_EQ(1, transaction_count());
7425 // Send the request again and check that Resource-Freshness header is absent.
7426 transaction_.handler = CheckResourceFreshnessAbsent;
7428 RunFixtureTransactionTest();
7430 EXPECT_EQ(2, transaction_count());
7433 // Verify that when stale-while-revalidate applies the response is read from
7434 // cache.
7435 TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) {
7436 // Write to the cache.
7437 RunFixtureTransactionTest();
7439 EXPECT_EQ(0, open_count());
7440 EXPECT_EQ(1, transaction_count());
7442 // Read back from the cache.
7443 RunFixtureTransactionTest();
7445 EXPECT_EQ(1, open_count());
7446 EXPECT_EQ(1, transaction_count());
7449 // Verify that when stale-while-revalidate applies an asynchronous request is
7450 // sent.
7451 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) {
7452 // Write to the cache.
7453 RunFixtureTransactionTest();
7455 EXPECT_EQ(1, transaction_count());
7457 // Read back from the cache.
7458 RunFixtureTransactionTest();
7460 EXPECT_EQ(1, transaction_count());
7462 // Let the async request execute.
7463 base::RunLoop().RunUntilIdle();
7464 EXPECT_EQ(2, transaction_count());
7467 // Verify that tearing down the HttpCache with an async revalidation in progress
7468 // does not break anything (this test is most likely to find problems when run
7469 // with a memory checker such as AddressSanitizer).
7470 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) {
7471 // Write to the cache.
7472 RunFixtureTransactionTest();
7474 // Read back from the cache.
7475 RunFixtureTransactionTest();
7478 static void CheckIfModifiedSinceHeader(const HttpRequestInfo* request,
7479 std::string* response_status,
7480 std::string* response_headers,
7481 std::string* response_data) {
7482 std::string value;
7483 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value));
7484 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value);
7487 // Verify that the async revalidation contains an If-Modified-Since header.
7488 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) {
7489 // Write to the cache.
7490 RunFixtureTransactionTest();
7492 transaction_.handler = CheckIfModifiedSinceHeader;
7494 // Read back from the cache.
7495 RunFixtureTransactionTest();
7498 static void CheckIfNoneMatchHeader(const HttpRequestInfo* request,
7499 std::string* response_status,
7500 std::string* response_headers,
7501 std::string* response_data) {
7502 std::string value;
7503 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value));
7504 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value);
7507 // If the response had ETag rather than Last-Modified, then that is used to
7508 // conditionalise the response.
7509 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) {
7510 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\"";
7512 // Write to the cache.
7513 RunFixtureTransactionTest();
7515 transaction_.handler = CheckIfNoneMatchHeader;
7517 // Read back from the cache.
7518 RunFixtureTransactionTest();
7521 static void CheckResourceFreshnessHeaderPresent(const HttpRequestInfo* request,
7522 std::string* response_status,
7523 std::string* response_headers,
7524 std::string* response_data) {
7525 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness"));
7528 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) {
7529 // Write to the cache.
7530 RunFixtureTransactionTest();
7532 transaction_.handler = CheckResourceFreshnessHeaderPresent;
7534 // Read back from the cache.
7535 RunFixtureTransactionTest();
7538 // Verify that when age > max-age + stale-while-revalidate stale results are
7539 // not returned.
7540 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) {
7541 age_ = 10801;
7543 // Write to the cache.
7544 RunFixtureTransactionTest();
7546 EXPECT_EQ(0, open_count());
7547 EXPECT_EQ(1, transaction_count());
7549 // Reading back reads from the network.
7550 RunFixtureTransactionTest();
7552 EXPECT_EQ(1, open_count());
7553 EXPECT_EQ(2, transaction_count());
7556 // HEAD requests should be able to take advantage of stale-while-revalidate.
7557 TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) {
7558 // Write to the cache. This has to be a GET request; HEAD requests don't
7559 // create new cache entries.
7560 RunFixtureTransactionTest();
7562 EXPECT_EQ(0, open_count());
7563 EXPECT_EQ(1, transaction_count());
7565 // Read back from the cache, and trigger an asynchronous HEAD request.
7566 transaction_.method = "HEAD";
7567 transaction_.data = "";
7569 RunFixtureTransactionTest();
7571 EXPECT_EQ(1, open_count());
7572 EXPECT_EQ(1, transaction_count());
7574 // Let the network request proceed.
7575 base::RunLoop().RunUntilIdle();
7577 EXPECT_EQ(2, transaction_count());
7580 // POST requests should not use stale-while-revalidate.
7581 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) {
7582 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction);
7584 // Write to the cache.
7585 RunFixtureTransactionTest();
7587 EXPECT_EQ(0, open_count());
7588 EXPECT_EQ(1, transaction_count());
7590 // Reading back reads from the network.
7591 RunFixtureTransactionTest();
7593 EXPECT_EQ(0, open_count());
7594 EXPECT_EQ(2, transaction_count());
7597 static void CheckUrlMatches(const HttpRequestInfo* request,
7598 std::string* response_status,
7599 std::string* response_headers,
7600 std::string* response_data) {
7601 EXPECT_EQ("http://www.google.com/", request->url.spec());
7604 // Async revalidation is issued to the original URL.
7605 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) {
7606 transaction_.url = "http://www.google.com/";
7607 // Write to the cache.
7608 RunFixtureTransactionTest();
7610 // Read back from the cache.
7611 RunFixtureTransactionTest();
7613 EXPECT_EQ(1, transaction_count());
7615 transaction_.handler = CheckUrlMatches;
7617 // Let the async request execute and perform the check.
7618 base::RunLoop().RunUntilIdle();
7619 EXPECT_EQ(2, transaction_count());
7622 class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest,
7623 public ::testing::WithParamInterface<int> {};
7625 // Flags which should always cause the request to be synchronous.
7626 TEST_P(SyncLoadFlagTest, MustBeSynchronous) {
7627 transaction_.load_flags |= GetParam();
7628 // Write to the cache.
7629 RunFixtureTransactionTest();
7631 EXPECT_EQ(1, transaction_count());
7633 // Reading back reads from the network.
7634 RunFixtureTransactionTest();
7636 EXPECT_EQ(2, transaction_count());
7639 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate,
7640 SyncLoadFlagTest,
7641 ::testing::Values(LOAD_VALIDATE_CACHE,
7642 LOAD_BYPASS_CACHE,
7643 LOAD_DISABLE_CACHE));
7645 TEST_F(HttpCacheStaleWhileRevalidateTest,
7646 PreferringCacheDoesNotTriggerAsyncRequest) {
7647 transaction_.load_flags |= LOAD_PREFERRING_CACHE;
7648 // Write to the cache.
7649 RunFixtureTransactionTest();
7651 EXPECT_EQ(1, transaction_count());
7653 // Reading back reads from the cache.
7654 RunFixtureTransactionTest();
7656 EXPECT_EQ(1, transaction_count());
7658 // If there was an async transaction created, it would run now.
7659 base::RunLoop().RunUntilIdle();
7661 // There was no async transaction.
7662 EXPECT_EQ(1, transaction_count());
7665 TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) {
7666 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7667 // Write to the cache.
7668 RunFixtureTransactionTest();
7670 EXPECT_EQ(1, transaction_count());
7672 // A synchronous revalidation is performed.
7673 RunFixtureTransactionTest();
7675 EXPECT_EQ(2, transaction_count());
7678 TEST_F(HttpCacheStaleWhileRevalidateTest,
7679 OnlyFromCacheDoesNotTriggerAsyncRequest) {
7680 transaction_.load_flags |= LOAD_ONLY_FROM_CACHE;
7681 transaction_.return_code = ERR_CACHE_MISS;
7683 // Writing to the cache should fail, because we are avoiding the network.
7684 RunFixtureTransactionTest();
7686 EXPECT_EQ(0, transaction_count());
7688 base::RunLoop().RunUntilIdle();
7690 // Still nothing.
7691 EXPECT_EQ(0, transaction_count());
7694 // A certificate error during an asynchronous fetch should cause the next fetch
7695 // to proceed synchronously.
7696 // TODO(ricea): In future, only certificate errors which require user
7697 // interaction should fail the asynchronous revalidation, and they should cause
7698 // the next revalidation to be synchronous rather than requiring a total
7699 // refetch. This test will need to be updated appropriately.
7700 TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) {
7701 // Write to the cache.
7702 RunFixtureTransactionTest();
7704 EXPECT_EQ(1, transaction_count());
7706 // Now read back. RunTransactionTestBase() expects to receive the network
7707 // error back from the HttpCache::Transaction, but since the cache request
7708 // will return OK we need to duplicate some of its implementation here.
7709 transaction_.return_code = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
7710 TestCompletionCallback callback;
7711 scoped_ptr<HttpTransaction> trans;
7712 int rv = cache_.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
7713 EXPECT_EQ(OK, rv);
7714 ASSERT_TRUE(trans.get());
7716 MockHttpRequest request(transaction_);
7717 rv = trans->Start(&request, callback.callback(), BoundNetLog());
7718 ASSERT_EQ(ERR_IO_PENDING, rv);
7719 ASSERT_EQ(OK, callback.WaitForResult());
7720 ReadAndVerifyTransaction(trans.get(), transaction_);
7722 EXPECT_EQ(1, transaction_count());
7724 // Allow the asynchronous fetch to run.
7725 base::RunLoop().RunUntilIdle();
7727 EXPECT_EQ(2, transaction_count());
7729 // Now run the transaction again. It should run synchronously.
7730 transaction_.return_code = OK;
7731 RunFixtureTransactionTest();
7733 EXPECT_EQ(3, transaction_count());
7736 // Ensure that the response cached by the asynchronous request is not truncated,
7737 // even if the server is slow.
7738 TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) {
7739 transaction_.test_mode = TEST_MODE_SLOW_READ;
7740 // Write to the cache.
7741 RunFixtureTransactionTest();
7743 // Read back from the cache.
7744 RunFixtureTransactionTest();
7746 // Let the async request execute.
7747 base::RunLoop().RunUntilIdle();
7749 // The cache entry should still be complete.
7750 transaction_.load_flags = LOAD_ONLY_FROM_CACHE;
7751 RunFixtureTransactionTest();
7754 // Verify that there are no race conditions in the completely synchronous case.
7755 TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) {
7756 transaction_.test_mode = TEST_MODE_SYNC_ALL;
7757 // Write to the cache.
7758 RunFixtureTransactionTest();
7760 EXPECT_EQ(1, transaction_count());
7762 // Read back from the cache.
7763 RunFixtureTransactionTest();
7765 EXPECT_EQ(1, transaction_count());
7767 // Let the async request execute.
7768 base::RunLoop().RunUntilIdle();
7769 EXPECT_EQ(2, transaction_count());
7772 static void CheckLoadFlagsAsyncRevalidation(const HttpRequestInfo* request,
7773 std::string* response_status,
7774 std::string* response_headers,
7775 std::string* response_data) {
7776 EXPECT_EQ(LOAD_ASYNC_REVALIDATION, request->load_flags);
7779 // Check that the load flags on the async request are the same as the load flags
7780 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7781 TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) {
7782 transaction_.load_flags = LOAD_NORMAL;
7783 // Write to the cache.
7784 RunFixtureTransactionTest();
7786 EXPECT_EQ(1, transaction_count());
7788 // Read back from the cache.
7789 RunFixtureTransactionTest();
7791 EXPECT_EQ(1, transaction_count());
7793 transaction_.handler = CheckLoadFlagsAsyncRevalidation;
7794 // Let the async request execute.
7795 base::RunLoop().RunUntilIdle();
7796 EXPECT_EQ(2, transaction_count());
7799 static void SimpleMockAuthHandler(const HttpRequestInfo* request,
7800 std::string* response_status,
7801 std::string* response_headers,
7802 std::string* response_data) {
7803 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
7804 !request->extra_headers.HasHeader("Authorization")) {
7805 response_status->assign("HTTP/1.1 401 Unauthorized");
7806 response_headers->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7807 return;
7809 response_status->assign("HTTP/1.1 200 OK");
7812 TEST_F(HttpCacheStaleWhileRevalidateTest, RestartForAuth) {
7813 // Write to the cache.
7814 RunFixtureTransactionTest();
7816 EXPECT_EQ(1, transaction_count());
7818 // Now make the transaction require auth.
7819 transaction_.request_headers = "X-Require-Mock-Auth: dummy\r\n\r\n";
7820 transaction_.handler = SimpleMockAuthHandler;
7822 // Read back from the cache.
7823 RunFixtureTransactionTest();
7825 EXPECT_EQ(1, transaction_count());
7827 // Let the async request execute.
7828 base::RunLoop().RunUntilIdle();
7830 EXPECT_EQ(2, transaction_count());
7833 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7834 // take place on a sparse entry.
7835 TEST(HttpCache, RangeGET_MultipleRequests) {
7836 MockHttpCache cache;
7838 // Create a transaction for bytes 0-9.
7839 MockHttpRequest request(kRangeGET_TransactionOK);
7840 MockTransaction transaction(kRangeGET_TransactionOK);
7841 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7842 transaction.data = "rg: 00-09 ";
7843 AddMockTransaction(&transaction);
7845 TestCompletionCallback callback;
7846 scoped_ptr<HttpTransaction> trans;
7847 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
7848 EXPECT_EQ(OK, rv);
7849 ASSERT_TRUE(trans.get());
7851 // Start our transaction.
7852 trans->Start(&request, callback.callback(), BoundNetLog());
7854 // A second transaction on a different part of the file (the default
7855 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7856 // the already pending transaction.
7857 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7859 // Let the first transaction complete.
7860 callback.WaitForResult();
7862 RemoveMockTransaction(&transaction);
7865 // Makes sure that a request stops using the cache when the response headers
7866 // with "Cache-Control: no-store" arrives. That means that another request for
7867 // the same URL can be processed before the response body of the original
7868 // request arrives.
7869 TEST(HttpCache, NoStoreResponseShouldNotBlockFollowingRequests) {
7870 MockHttpCache cache;
7871 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
7872 mock_transaction.response_headers = "Cache-Control: no-store\n";
7873 MockHttpRequest request(mock_transaction);
7875 scoped_ptr<Context> first(new Context);
7876 first->result = cache.CreateTransaction(&first->trans);
7877 ASSERT_EQ(OK, first->result);
7878 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
7879 first->result =
7880 first->trans->Start(&request, first->callback.callback(), BoundNetLog());
7881 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
7883 base::MessageLoop::current()->RunUntilIdle();
7884 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
7885 ASSERT_TRUE(first->trans->GetResponseInfo());
7886 EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
7887 "Cache-Control", "no-store"));
7888 // Here we have read the response header but not read the response body yet.
7890 // Let us create the second (read) transaction.
7891 scoped_ptr<Context> second(new Context);
7892 second->result = cache.CreateTransaction(&second->trans);
7893 ASSERT_EQ(OK, second->result);
7894 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
7895 second->result = second->trans->Start(&request, second->callback.callback(),
7896 BoundNetLog());
7898 // Here the second transaction proceeds without reading the first body.
7899 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
7900 base::MessageLoop::current()->RunUntilIdle();
7901 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
7902 ASSERT_TRUE(second->trans->GetResponseInfo());
7903 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
7904 "Cache-Control", "no-store"));
7905 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
7908 } // namespace net