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