Support Promise<T> syntax in the IDL parser.
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blob0b0505770d564891745e5889b2e932e9dea602e9
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 RunTransactionTestWithResponseInfo(net::HttpCache* cache,
189 const MockTransaction& trans_info,
190 net::HttpResponseInfo* response) {
191 RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
192 response);
195 void RunTransactionTestWithResponseInfoAndGetTiming(
196 net::HttpCache* cache,
197 const MockTransaction& trans_info,
198 net::HttpResponseInfo* response,
199 const net::BoundNetLog& log,
200 net::LoadTimingInfo* load_timing_info) {
201 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
202 response, log, load_timing_info, NULL);
205 void RunTransactionTestWithResponse(net::HttpCache* cache,
206 const MockTransaction& trans_info,
207 std::string* response_headers) {
208 net::HttpResponseInfo response;
209 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
210 response.headers->GetNormalizedHeaders(response_headers);
213 void RunTransactionTestWithResponseAndGetTiming(
214 net::HttpCache* cache,
215 const MockTransaction& trans_info,
216 std::string* response_headers,
217 const net::BoundNetLog& log,
218 net::LoadTimingInfo* load_timing_info) {
219 net::HttpResponseInfo response;
220 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
221 &response, log, load_timing_info, NULL);
222 response.headers->GetNormalizedHeaders(response_headers);
225 // This class provides a handler for kFastNoStoreGET_Transaction so that the
226 // no-store header can be included on demand.
227 class FastTransactionServer {
228 public:
229 FastTransactionServer() {
230 no_store = false;
232 ~FastTransactionServer() {}
234 void set_no_store(bool value) { no_store = value; }
236 static void FastNoStoreHandler(const net::HttpRequestInfo* request,
237 std::string* response_status,
238 std::string* response_headers,
239 std::string* response_data) {
240 if (no_store)
241 *response_headers = "Cache-Control: no-store\n";
244 private:
245 static bool no_store;
246 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
248 bool FastTransactionServer::no_store;
250 const MockTransaction kFastNoStoreGET_Transaction = {
251 "http://www.google.com/nostore",
252 "GET",
253 base::Time(),
255 net::LOAD_VALIDATE_CACHE,
256 "HTTP/1.1 200 OK",
257 "Cache-Control: max-age=10000\n",
258 base::Time(),
259 "<html><body>Google Blah Blah</body></html>",
260 TEST_MODE_SYNC_NET_START,
261 &FastTransactionServer::FastNoStoreHandler,
263 net::OK
266 // This class provides a handler for kRangeGET_TransactionOK so that the range
267 // request can be served on demand.
268 class RangeTransactionServer {
269 public:
270 RangeTransactionServer() {
271 not_modified_ = false;
272 modified_ = false;
273 bad_200_ = false;
275 ~RangeTransactionServer() {
276 not_modified_ = false;
277 modified_ = false;
278 bad_200_ = false;
281 // Returns only 416 or 304 when set.
282 void set_not_modified(bool value) { not_modified_ = value; }
284 // Returns 206 when revalidating a range (instead of 304).
285 void set_modified(bool value) { modified_ = value; }
287 // Returns 200 instead of 206 (a malformed response overall).
288 void set_bad_200(bool value) { bad_200_ = value; }
290 static void RangeHandler(const net::HttpRequestInfo* request,
291 std::string* response_status,
292 std::string* response_headers,
293 std::string* response_data);
295 private:
296 static bool not_modified_;
297 static bool modified_;
298 static bool bad_200_;
299 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
301 bool RangeTransactionServer::not_modified_ = false;
302 bool RangeTransactionServer::modified_ = false;
303 bool RangeTransactionServer::bad_200_ = false;
305 // A dummy extra header that must be preserved on a given request.
307 // EXTRA_HEADER_LINE doesn't include a line terminator because it
308 // will be passed to AddHeaderFromString() which doesn't accept them.
309 #define EXTRA_HEADER_LINE "Extra: header"
311 // EXTRA_HEADER contains a line terminator, as expected by
312 // AddHeadersFromString() (_not_ AddHeaderFromString()).
313 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
315 static const char kExtraHeaderKey[] = "Extra";
317 // Static.
318 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
319 std::string* response_status,
320 std::string* response_headers,
321 std::string* response_data) {
322 if (request->extra_headers.IsEmpty()) {
323 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
324 response_data->clear();
325 return;
328 // We want to make sure we don't delete extra headers.
329 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
331 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
332 !request->extra_headers.HasHeader("Authorization")) {
333 response_status->assign("HTTP/1.1 401 Unauthorized");
334 response_data->assign("WWW-Authenticate: Foo\n");
335 return;
338 if (not_modified_) {
339 response_status->assign("HTTP/1.1 304 Not Modified");
340 response_data->clear();
341 return;
344 std::vector<net::HttpByteRange> ranges;
345 std::string range_header;
346 if (!request->extra_headers.GetHeader(
347 net::HttpRequestHeaders::kRange, &range_header) ||
348 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
349 ranges.size() != 1) {
350 // This is not a byte range request. We return 200.
351 response_status->assign("HTTP/1.1 200 OK");
352 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
353 response_data->assign("Not a range");
354 return;
357 // We can handle this range request.
358 net::HttpByteRange byte_range = ranges[0];
359 if (byte_range.first_byte_position() > 79) {
360 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
361 response_data->clear();
362 return;
365 EXPECT_TRUE(byte_range.ComputeBounds(80));
366 int start = static_cast<int>(byte_range.first_byte_position());
367 int end = static_cast<int>(byte_range.last_byte_position());
369 EXPECT_LT(end, 80);
371 std::string content_range = base::StringPrintf(
372 "Content-Range: bytes %d-%d/80\n", start, end);
373 response_headers->append(content_range);
375 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
376 std::string data;
377 if (end == start) {
378 EXPECT_EQ(0, end % 10);
379 data = "r";
380 } else {
381 EXPECT_EQ(9, (end - start) % 10);
382 for (int block_start = start; block_start < end; block_start += 10) {
383 base::StringAppendF(&data, "rg: %02d-%02d ",
384 block_start, block_start + 9);
387 *response_data = data;
389 if (end - start != 9) {
390 // We also have to fix content-length.
391 int len = end - start + 1;
392 std::string content_length = base::StringPrintf("Content-Length: %d\n",
393 len);
394 response_headers->replace(response_headers->find("Content-Length:"),
395 content_length.size(), content_length);
397 } else {
398 response_status->assign("HTTP/1.1 304 Not Modified");
399 response_data->clear();
403 const MockTransaction kRangeGET_TransactionOK = {
404 "http://www.google.com/range",
405 "GET",
406 base::Time(),
407 "Range: bytes = 40-49\r\n"
408 EXTRA_HEADER,
409 net::LOAD_NORMAL,
410 "HTTP/1.1 206 Partial Content",
411 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
412 "ETag: \"foo\"\n"
413 "Accept-Ranges: bytes\n"
414 "Content-Length: 10\n",
415 base::Time(),
416 "rg: 40-49 ",
417 TEST_MODE_NORMAL,
418 &RangeTransactionServer::RangeHandler,
420 net::OK
423 // Verifies the response headers (|response|) match a partial content
424 // response for the range starting at |start| and ending at |end|.
425 void Verify206Response(std::string response, int start, int end) {
426 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
427 response.size()));
428 scoped_refptr<net::HttpResponseHeaders> headers(
429 new net::HttpResponseHeaders(raw_headers));
431 ASSERT_EQ(206, headers->response_code());
433 int64 range_start, range_end, object_size;
434 ASSERT_TRUE(
435 headers->GetContentRange(&range_start, &range_end, &object_size));
436 int64 content_length = headers->GetContentLength();
438 int length = end - start + 1;
439 ASSERT_EQ(length, content_length);
440 ASSERT_EQ(start, range_start);
441 ASSERT_EQ(end, range_end);
444 // Creates a truncated entry that can be resumed using byte ranges.
445 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
446 // Create a disk cache entry that stores an incomplete resource.
447 disk_cache::Entry* entry;
448 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
449 NULL));
451 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
452 raw_headers.size());
454 net::HttpResponseInfo response;
455 response.response_time = base::Time::Now();
456 response.request_time = base::Time::Now();
457 response.headers = new net::HttpResponseHeaders(raw_headers);
458 // Set the last argument for this to be an incomplete request.
459 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
461 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
462 int len = static_cast<int>(base::strlcpy(buf->data(),
463 "rg: 00-09 rg: 10-19 ", 100));
464 net::TestCompletionCallback cb;
465 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
466 EXPECT_EQ(len, cb.GetResult(rv));
467 entry->Close();
470 // Helper to represent a network HTTP response.
471 struct Response {
472 // Set this response into |trans|.
473 void AssignTo(MockTransaction* trans) const {
474 trans->status = status;
475 trans->response_headers = headers;
476 trans->data = body;
479 std::string status_and_headers() const {
480 return std::string(status) + "\n" + std::string(headers);
483 const char* status;
484 const char* headers;
485 const char* body;
488 struct Context {
489 Context() : result(net::ERR_IO_PENDING) {}
491 int result;
492 net::TestCompletionCallback callback;
493 scoped_ptr<net::HttpTransaction> trans;
496 class FakeWebSocketHandshakeStreamCreateHelper
497 : public net::WebSocketHandshakeStreamBase::CreateHelper {
498 public:
499 virtual ~FakeWebSocketHandshakeStreamCreateHelper() {}
500 virtual net::WebSocketHandshakeStreamBase* CreateBasicStream(
501 scoped_ptr<net::ClientSocketHandle> connect, bool using_proxy) override {
502 return NULL;
504 virtual net::WebSocketHandshakeStreamBase* CreateSpdyStream(
505 const base::WeakPtr<net::SpdySession>& session,
506 bool use_relative_url) override {
507 return NULL;
511 // Returns true if |entry| is not one of the log types paid attention to in this
512 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
513 // ignored.
514 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry& entry) {
515 switch (entry.type) {
516 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
517 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
518 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
519 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
520 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
521 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO:
522 return false;
523 default:
524 return true;
528 // Modifies |entries| to only include log entries created by the cache layer and
529 // asserted on in these tests.
530 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList* entries) {
531 entries->erase(std::remove_if(entries->begin(), entries->end(),
532 &ShouldIgnoreLogEntry),
533 entries->end());
536 } // namespace
539 //-----------------------------------------------------------------------------
540 // Tests.
542 TEST(HttpCache, CreateThenDestroy) {
543 MockHttpCache cache;
545 scoped_ptr<net::HttpTransaction> trans;
546 EXPECT_EQ(net::OK, cache.CreateTransaction(&trans));
547 ASSERT_TRUE(trans.get());
550 TEST(HttpCache, GetBackend) {
551 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
553 disk_cache::Backend* backend;
554 net::TestCompletionCallback cb;
555 // This will lazily initialize the backend.
556 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
557 EXPECT_EQ(net::OK, cb.GetResult(rv));
560 TEST(HttpCache, SimpleGET) {
561 MockHttpCache cache;
562 net::CapturingBoundNetLog log;
563 net::LoadTimingInfo load_timing_info;
565 // Write to the cache.
566 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
567 log.bound(), &load_timing_info);
569 EXPECT_EQ(1, cache.network_layer()->transaction_count());
570 EXPECT_EQ(0, cache.disk_cache()->open_count());
571 EXPECT_EQ(1, cache.disk_cache()->create_count());
572 TestLoadTimingNetworkRequest(load_timing_info);
575 TEST(HttpCache, SimpleGETNoDiskCache) {
576 MockHttpCache cache;
578 cache.disk_cache()->set_fail_requests();
580 net::CapturingBoundNetLog log;
581 net::LoadTimingInfo load_timing_info;
583 // Read from the network, and don't use the cache.
584 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
585 log.bound(), &load_timing_info);
587 // Check that the NetLog was filled as expected.
588 // (We attempted to both Open and Create entries, but both failed).
589 net::CapturingNetLog::CapturedEntryList entries;
590 log.GetEntries(&entries);
591 FilterLogEntries(&entries);
593 EXPECT_EQ(6u, entries.size());
594 EXPECT_TRUE(net::LogContainsBeginEvent(
595 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
596 EXPECT_TRUE(net::LogContainsEndEvent(
597 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
598 EXPECT_TRUE(net::LogContainsBeginEvent(
599 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
600 EXPECT_TRUE(net::LogContainsEndEvent(
601 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
602 EXPECT_TRUE(net::LogContainsBeginEvent(
603 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
604 EXPECT_TRUE(net::LogContainsEndEvent(
605 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
607 EXPECT_EQ(1, cache.network_layer()->transaction_count());
608 EXPECT_EQ(0, cache.disk_cache()->open_count());
609 EXPECT_EQ(0, cache.disk_cache()->create_count());
610 TestLoadTimingNetworkRequest(load_timing_info);
613 TEST(HttpCache, SimpleGETNoDiskCache2) {
614 // This will initialize a cache object with NULL backend.
615 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
616 factory->set_fail(true);
617 factory->FinishCreation(); // We'll complete synchronously.
618 MockHttpCache cache(factory);
620 // Read from the network, and don't use the cache.
621 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
623 EXPECT_EQ(1, cache.network_layer()->transaction_count());
624 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
627 // Tests that IOBuffers are not referenced after IO completes.
628 TEST(HttpCache, ReleaseBuffer) {
629 MockHttpCache cache;
631 // Write to the cache.
632 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
634 MockHttpRequest request(kSimpleGET_Transaction);
635 scoped_ptr<net::HttpTransaction> trans;
636 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
638 const int kBufferSize = 10;
639 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
640 net::ReleaseBufferCompletionCallback cb(buffer.get());
642 int rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
643 EXPECT_EQ(net::OK, cb.GetResult(rv));
645 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
646 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
649 TEST(HttpCache, SimpleGETWithDiskFailures) {
650 MockHttpCache cache;
652 cache.disk_cache()->set_soft_failures(true);
654 // Read from the network, and fail to write to the cache.
655 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
657 EXPECT_EQ(1, cache.network_layer()->transaction_count());
658 EXPECT_EQ(0, cache.disk_cache()->open_count());
659 EXPECT_EQ(1, cache.disk_cache()->create_count());
661 // This one should see an empty cache again.
662 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
664 EXPECT_EQ(2, cache.network_layer()->transaction_count());
665 EXPECT_EQ(0, cache.disk_cache()->open_count());
666 EXPECT_EQ(2, cache.disk_cache()->create_count());
669 // Tests that disk failures after the transaction has started don't cause the
670 // request to fail.
671 TEST(HttpCache, SimpleGETWithDiskFailures2) {
672 MockHttpCache cache;
674 MockHttpRequest request(kSimpleGET_Transaction);
676 scoped_ptr<Context> c(new Context());
677 int rv = cache.CreateTransaction(&c->trans);
678 ASSERT_EQ(net::OK, rv);
680 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
681 EXPECT_EQ(net::ERR_IO_PENDING, rv);
682 rv = c->callback.WaitForResult();
684 // Start failing request now.
685 cache.disk_cache()->set_soft_failures(true);
687 // We have to open the entry again to propagate the failure flag.
688 disk_cache::Entry* en;
689 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
690 en->Close();
692 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
693 c.reset();
695 EXPECT_EQ(1, cache.network_layer()->transaction_count());
696 EXPECT_EQ(1, cache.disk_cache()->open_count());
697 EXPECT_EQ(1, cache.disk_cache()->create_count());
699 // This one should see an empty cache again.
700 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
702 EXPECT_EQ(2, cache.network_layer()->transaction_count());
703 EXPECT_EQ(1, cache.disk_cache()->open_count());
704 EXPECT_EQ(2, cache.disk_cache()->create_count());
707 // Tests that we handle failures to read from the cache.
708 TEST(HttpCache, SimpleGETWithDiskFailures3) {
709 MockHttpCache cache;
711 // Read from the network, and write to the cache.
712 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
714 EXPECT_EQ(1, cache.network_layer()->transaction_count());
715 EXPECT_EQ(0, cache.disk_cache()->open_count());
716 EXPECT_EQ(1, cache.disk_cache()->create_count());
718 cache.disk_cache()->set_soft_failures(true);
720 // Now fail to read from the cache.
721 scoped_ptr<Context> c(new Context());
722 int rv = cache.CreateTransaction(&c->trans);
723 ASSERT_EQ(net::OK, rv);
725 MockHttpRequest request(kSimpleGET_Transaction);
726 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
727 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
729 // Now verify that the entry was removed from the cache.
730 cache.disk_cache()->set_soft_failures(false);
732 EXPECT_EQ(2, cache.network_layer()->transaction_count());
733 EXPECT_EQ(1, cache.disk_cache()->open_count());
734 EXPECT_EQ(2, cache.disk_cache()->create_count());
736 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
738 EXPECT_EQ(3, cache.network_layer()->transaction_count());
739 EXPECT_EQ(1, cache.disk_cache()->open_count());
740 EXPECT_EQ(3, cache.disk_cache()->create_count());
743 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
744 MockHttpCache cache;
746 net::CapturingBoundNetLog log;
747 net::LoadTimingInfo load_timing_info;
749 // Write to the cache.
750 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
751 log.bound(), &load_timing_info);
753 // Check that the NetLog was filled as expected.
754 net::CapturingNetLog::CapturedEntryList entries;
755 log.GetEntries(&entries);
756 FilterLogEntries(&entries);
758 EXPECT_EQ(8u, entries.size());
759 EXPECT_TRUE(net::LogContainsBeginEvent(
760 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
761 EXPECT_TRUE(net::LogContainsEndEvent(
762 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
763 EXPECT_TRUE(net::LogContainsBeginEvent(
764 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
765 EXPECT_TRUE(net::LogContainsEndEvent(
766 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
767 EXPECT_TRUE(net::LogContainsBeginEvent(
768 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
769 EXPECT_TRUE(net::LogContainsEndEvent(
770 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
771 EXPECT_TRUE(net::LogContainsBeginEvent(
772 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
773 EXPECT_TRUE(net::LogContainsEndEvent(
774 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
776 TestLoadTimingNetworkRequest(load_timing_info);
778 // Force this transaction to read from the cache.
779 MockTransaction transaction(kSimpleGET_Transaction);
780 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
782 log.Clear();
784 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
785 &load_timing_info);
787 // Check that the NetLog was filled as expected.
788 log.GetEntries(&entries);
789 FilterLogEntries(&entries);
791 EXPECT_EQ(8u, entries.size());
792 EXPECT_TRUE(net::LogContainsBeginEvent(
793 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
794 EXPECT_TRUE(net::LogContainsEndEvent(
795 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
796 EXPECT_TRUE(net::LogContainsBeginEvent(
797 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
798 EXPECT_TRUE(net::LogContainsEndEvent(
799 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
800 EXPECT_TRUE(net::LogContainsBeginEvent(
801 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
802 EXPECT_TRUE(net::LogContainsEndEvent(
803 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
804 EXPECT_TRUE(net::LogContainsBeginEvent(
805 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
806 EXPECT_TRUE(net::LogContainsEndEvent(
807 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
809 EXPECT_EQ(1, cache.network_layer()->transaction_count());
810 EXPECT_EQ(1, cache.disk_cache()->open_count());
811 EXPECT_EQ(1, cache.disk_cache()->create_count());
812 TestLoadTimingCachedResponse(load_timing_info);
815 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
816 MockHttpCache cache;
818 // force this transaction to read from the cache
819 MockTransaction transaction(kSimpleGET_Transaction);
820 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
822 MockHttpRequest request(transaction);
823 net::TestCompletionCallback callback;
825 scoped_ptr<net::HttpTransaction> trans;
826 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
828 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
829 if (rv == net::ERR_IO_PENDING)
830 rv = callback.WaitForResult();
831 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
833 trans.reset();
835 EXPECT_EQ(0, cache.network_layer()->transaction_count());
836 EXPECT_EQ(0, cache.disk_cache()->open_count());
837 EXPECT_EQ(0, cache.disk_cache()->create_count());
840 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
841 MockHttpCache cache;
843 // write to the cache
844 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
846 // force this transaction to read from the cache if valid
847 MockTransaction transaction(kSimpleGET_Transaction);
848 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
850 RunTransactionTest(cache.http_cache(), transaction);
852 EXPECT_EQ(1, cache.network_layer()->transaction_count());
853 EXPECT_EQ(1, cache.disk_cache()->open_count());
854 EXPECT_EQ(1, cache.disk_cache()->create_count());
857 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
858 MockHttpCache cache;
860 // force this transaction to read from the cache if valid
861 MockTransaction transaction(kSimpleGET_Transaction);
862 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
864 RunTransactionTest(cache.http_cache(), transaction);
866 EXPECT_EQ(1, cache.network_layer()->transaction_count());
867 EXPECT_EQ(0, cache.disk_cache()->open_count());
868 EXPECT_EQ(1, cache.disk_cache()->create_count());
871 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
872 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
873 MockHttpCache cache;
875 // Write to the cache.
876 MockTransaction transaction(kSimpleGET_Transaction);
877 transaction.request_headers = "Foo: bar\r\n";
878 transaction.response_headers = "Cache-Control: max-age=10000\n"
879 "Vary: Foo\n";
880 AddMockTransaction(&transaction);
881 RunTransactionTest(cache.http_cache(), transaction);
883 // Read from the cache.
884 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
885 RunTransactionTest(cache.http_cache(), transaction);
887 EXPECT_EQ(1, cache.network_layer()->transaction_count());
888 EXPECT_EQ(1, cache.disk_cache()->open_count());
889 EXPECT_EQ(1, cache.disk_cache()->create_count());
890 RemoveMockTransaction(&transaction);
893 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
894 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
895 MockHttpCache cache;
897 // Write to the cache.
898 MockTransaction transaction(kSimpleGET_Transaction);
899 transaction.request_headers = "Foo: bar\r\n";
900 transaction.response_headers = "Cache-Control: max-age=10000\n"
901 "Vary: Foo\n";
902 AddMockTransaction(&transaction);
903 RunTransactionTest(cache.http_cache(), transaction);
905 // Attempt to read from the cache... this is a vary mismatch that must reach
906 // the network again.
907 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
908 transaction.request_headers = "Foo: none\r\n";
909 net::CapturingBoundNetLog log;
910 net::LoadTimingInfo load_timing_info;
911 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
912 &load_timing_info);
914 EXPECT_EQ(2, cache.network_layer()->transaction_count());
915 EXPECT_EQ(1, cache.disk_cache()->open_count());
916 EXPECT_EQ(1, cache.disk_cache()->create_count());
917 TestLoadTimingNetworkRequest(load_timing_info);
918 RemoveMockTransaction(&transaction);
921 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
922 // network success
923 TEST(HttpCache, SimpleGET_CacheOverride_Network) {
924 MockHttpCache cache;
926 // Prime cache.
927 MockTransaction transaction(kSimpleGET_Transaction);
928 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
929 transaction.response_headers = "Cache-Control: no-cache\n";
931 AddMockTransaction(&transaction);
932 RunTransactionTest(cache.http_cache(), transaction);
933 EXPECT_EQ(1, cache.network_layer()->transaction_count());
934 EXPECT_EQ(1, cache.disk_cache()->create_count());
935 RemoveMockTransaction(&transaction);
937 // Re-run transaction; make sure the result came from the network,
938 // not the cache.
939 transaction.data = "Changed data.";
940 AddMockTransaction(&transaction);
941 net::HttpResponseInfo response_info;
942 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
943 &response_info);
945 EXPECT_EQ(2, cache.network_layer()->transaction_count());
946 EXPECT_FALSE(response_info.server_data_unavailable);
947 EXPECT_TRUE(response_info.network_accessed);
949 RemoveMockTransaction(&transaction);
952 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
953 // offline failure
954 TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
955 MockHttpCache cache;
957 // Prime cache.
958 MockTransaction transaction(kSimpleGET_Transaction);
959 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
960 transaction.response_headers = "Cache-Control: no-cache\n";
962 AddMockTransaction(&transaction);
963 RunTransactionTest(cache.http_cache(), transaction);
964 EXPECT_EQ(1, cache.network_layer()->transaction_count());
965 EXPECT_EQ(1, cache.disk_cache()->create_count());
966 RemoveMockTransaction(&transaction);
968 // Network failure with offline error; should return cache entry above +
969 // flag signalling stale data.
970 transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
971 AddMockTransaction(&transaction);
973 MockHttpRequest request(transaction);
974 net::TestCompletionCallback callback;
975 scoped_ptr<net::HttpTransaction> trans;
976 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
977 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
978 EXPECT_EQ(net::OK, callback.GetResult(rv));
980 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
981 ASSERT_TRUE(response_info);
982 EXPECT_TRUE(response_info->server_data_unavailable);
983 EXPECT_TRUE(response_info->was_cached);
984 EXPECT_FALSE(response_info->network_accessed);
985 ReadAndVerifyTransaction(trans.get(), transaction);
986 EXPECT_EQ(2, cache.network_layer()->transaction_count());
988 RemoveMockTransaction(&transaction);
991 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
992 // non-offline failure.
993 TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
994 MockHttpCache cache;
996 // Prime cache.
997 MockTransaction transaction(kSimpleGET_Transaction);
998 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
999 transaction.response_headers = "Cache-Control: no-cache\n";
1001 AddMockTransaction(&transaction);
1002 RunTransactionTest(cache.http_cache(), transaction);
1003 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1004 EXPECT_EQ(1, cache.disk_cache()->create_count());
1005 RemoveMockTransaction(&transaction);
1007 // Network failure with non-offline error; should fail with that error.
1008 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1009 AddMockTransaction(&transaction);
1011 net::HttpResponseInfo response_info2;
1012 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1013 &response_info2);
1015 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1016 EXPECT_FALSE(response_info2.server_data_unavailable);
1018 RemoveMockTransaction(&transaction);
1021 // Tests that was_cached was set properly on a failure, even if the cached
1022 // response wasn't returned.
1023 TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
1024 MockHttpCache cache;
1026 // Prime cache.
1027 MockTransaction transaction(kSimpleGET_Transaction);
1028 transaction.response_headers = "Cache-Control: no-cache\n";
1030 AddMockTransaction(&transaction);
1031 RunTransactionTest(cache.http_cache(), transaction);
1032 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1033 EXPECT_EQ(1, cache.disk_cache()->create_count());
1034 RemoveMockTransaction(&transaction);
1036 // Network failure with error; should fail but have was_cached set.
1037 transaction.return_code = net::ERR_FAILED;
1038 AddMockTransaction(&transaction);
1040 MockHttpRequest request(transaction);
1041 net::TestCompletionCallback callback;
1042 scoped_ptr<net::HttpTransaction> trans;
1043 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
1044 EXPECT_EQ(net::OK, rv);
1045 ASSERT_TRUE(trans.get());
1046 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1047 EXPECT_EQ(net::ERR_FAILED, callback.GetResult(rv));
1049 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1050 ASSERT_TRUE(response_info);
1051 EXPECT_TRUE(response_info->was_cached);
1052 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1054 RemoveMockTransaction(&transaction);
1057 // Confirm if we have an empty cache, a read is marked as network verified.
1058 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1059 MockHttpCache cache;
1061 // write to the cache
1062 net::HttpResponseInfo response_info;
1063 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1064 &response_info);
1066 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1067 EXPECT_EQ(0, cache.disk_cache()->open_count());
1068 EXPECT_EQ(1, cache.disk_cache()->create_count());
1069 EXPECT_TRUE(response_info.network_accessed);
1072 // Confirm if we have a fresh entry in cache, it isn't marked as
1073 // network verified.
1074 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1075 MockHttpCache cache;
1077 // Prime cache.
1078 MockTransaction transaction(kSimpleGET_Transaction);
1080 RunTransactionTest(cache.http_cache(), transaction);
1081 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1082 EXPECT_EQ(1, cache.disk_cache()->create_count());
1084 // Re-run transaction; make sure we don't mark the network as accessed.
1085 net::HttpResponseInfo response_info;
1086 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1087 &response_info);
1089 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1090 EXPECT_FALSE(response_info.server_data_unavailable);
1091 EXPECT_FALSE(response_info.network_accessed);
1094 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1095 MockHttpCache cache;
1097 // Write to the cache.
1098 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1100 // Force this transaction to write to the cache again.
1101 MockTransaction transaction(kSimpleGET_Transaction);
1102 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1104 net::CapturingBoundNetLog log;
1105 net::LoadTimingInfo load_timing_info;
1107 // Write to the cache.
1108 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1109 &load_timing_info);
1111 // Check that the NetLog was filled as expected.
1112 net::CapturingNetLog::CapturedEntryList entries;
1113 log.GetEntries(&entries);
1114 FilterLogEntries(&entries);
1116 EXPECT_EQ(8u, entries.size());
1117 EXPECT_TRUE(net::LogContainsBeginEvent(
1118 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1119 EXPECT_TRUE(net::LogContainsEndEvent(
1120 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1121 EXPECT_TRUE(net::LogContainsBeginEvent(
1122 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1123 EXPECT_TRUE(net::LogContainsEndEvent(
1124 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1125 EXPECT_TRUE(net::LogContainsBeginEvent(
1126 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1127 EXPECT_TRUE(net::LogContainsEndEvent(
1128 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1129 EXPECT_TRUE(net::LogContainsBeginEvent(
1130 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1131 EXPECT_TRUE(net::LogContainsEndEvent(
1132 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1134 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1135 EXPECT_EQ(0, cache.disk_cache()->open_count());
1136 EXPECT_EQ(2, cache.disk_cache()->create_count());
1137 TestLoadTimingNetworkRequest(load_timing_info);
1140 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1141 MockHttpCache cache;
1143 // write to the cache
1144 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1146 // force this transaction to write to the cache again
1147 MockTransaction transaction(kSimpleGET_Transaction);
1148 transaction.request_headers = "pragma: no-cache\r\n";
1150 RunTransactionTest(cache.http_cache(), transaction);
1152 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1153 EXPECT_EQ(0, cache.disk_cache()->open_count());
1154 EXPECT_EQ(2, cache.disk_cache()->create_count());
1157 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1158 MockHttpCache cache;
1160 // write to the cache
1161 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1163 // force this transaction to write to the cache again
1164 MockTransaction transaction(kSimpleGET_Transaction);
1165 transaction.request_headers = "cache-control: no-cache\r\n";
1167 RunTransactionTest(cache.http_cache(), transaction);
1169 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1170 EXPECT_EQ(0, cache.disk_cache()->open_count());
1171 EXPECT_EQ(2, cache.disk_cache()->create_count());
1174 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1175 MockHttpCache cache;
1177 // Write to the cache.
1178 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1180 // Read from the cache.
1181 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1183 // Force this transaction to validate the cache.
1184 MockTransaction transaction(kSimpleGET_Transaction);
1185 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1187 net::HttpResponseInfo response_info;
1188 net::CapturingBoundNetLog log;
1189 net::LoadTimingInfo load_timing_info;
1190 RunTransactionTestWithResponseInfoAndGetTiming(
1191 cache.http_cache(), transaction, &response_info, log.bound(),
1192 &load_timing_info);
1194 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1195 EXPECT_EQ(1, cache.disk_cache()->open_count());
1196 EXPECT_EQ(1, cache.disk_cache()->create_count());
1197 EXPECT_TRUE(response_info.network_accessed);
1198 TestLoadTimingNetworkRequest(load_timing_info);
1201 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1202 MockHttpCache cache;
1204 // write to the cache
1205 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1207 // read from the cache
1208 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1210 // force this transaction to validate the cache
1211 MockTransaction transaction(kSimpleGET_Transaction);
1212 transaction.request_headers = "cache-control: max-age=0\r\n";
1214 RunTransactionTest(cache.http_cache(), transaction);
1216 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1217 EXPECT_EQ(1, cache.disk_cache()->open_count());
1218 EXPECT_EQ(1, cache.disk_cache()->create_count());
1221 static void PreserveRequestHeaders_Handler(
1222 const net::HttpRequestInfo* request,
1223 std::string* response_status,
1224 std::string* response_headers,
1225 std::string* response_data) {
1226 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1229 // Tests that we don't remove extra headers for simple requests.
1230 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1231 MockHttpCache cache;
1233 MockTransaction transaction(kSimpleGET_Transaction);
1234 transaction.handler = PreserveRequestHeaders_Handler;
1235 transaction.request_headers = EXTRA_HEADER;
1236 transaction.response_headers = "Cache-Control: max-age=0\n";
1237 AddMockTransaction(&transaction);
1239 // Write, then revalidate the entry.
1240 RunTransactionTest(cache.http_cache(), transaction);
1241 RunTransactionTest(cache.http_cache(), transaction);
1243 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1244 EXPECT_EQ(1, cache.disk_cache()->open_count());
1245 EXPECT_EQ(1, cache.disk_cache()->create_count());
1246 RemoveMockTransaction(&transaction);
1249 // Tests that we don't remove extra headers for conditionalized requests.
1250 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1251 MockHttpCache cache;
1253 // Write to the cache.
1254 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1256 MockTransaction transaction(kETagGET_Transaction);
1257 transaction.handler = PreserveRequestHeaders_Handler;
1258 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1259 EXTRA_HEADER;
1260 AddMockTransaction(&transaction);
1262 RunTransactionTest(cache.http_cache(), transaction);
1264 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1265 EXPECT_EQ(1, cache.disk_cache()->open_count());
1266 EXPECT_EQ(1, cache.disk_cache()->create_count());
1267 RemoveMockTransaction(&transaction);
1270 TEST(HttpCache, SimpleGET_ManyReaders) {
1271 MockHttpCache cache;
1273 MockHttpRequest request(kSimpleGET_Transaction);
1275 std::vector<Context*> context_list;
1276 const int kNumTransactions = 5;
1278 for (int i = 0; i < kNumTransactions; ++i) {
1279 context_list.push_back(new Context());
1280 Context* c = context_list[i];
1282 c->result = cache.CreateTransaction(&c->trans);
1283 ASSERT_EQ(net::OK, c->result);
1284 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1286 c->result = c->trans->Start(
1287 &request, c->callback.callback(), net::BoundNetLog());
1290 // All requests are waiting for the active entry.
1291 for (int i = 0; i < kNumTransactions; ++i) {
1292 Context* c = context_list[i];
1293 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1296 // Allow all requests to move from the Create queue to the active entry.
1297 base::MessageLoop::current()->RunUntilIdle();
1299 // The first request should be a writer at this point, and the subsequent
1300 // requests should be pending.
1302 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1303 EXPECT_EQ(0, cache.disk_cache()->open_count());
1304 EXPECT_EQ(1, cache.disk_cache()->create_count());
1306 // All requests depend on the writer, and the writer is between Start and
1307 // Read, i.e. idle.
1308 for (int i = 0; i < kNumTransactions; ++i) {
1309 Context* c = context_list[i];
1310 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1313 for (int i = 0; i < kNumTransactions; ++i) {
1314 Context* c = context_list[i];
1315 if (c->result == net::ERR_IO_PENDING)
1316 c->result = c->callback.WaitForResult();
1317 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1320 // We should not have had to re-open the disk entry
1322 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1323 EXPECT_EQ(0, cache.disk_cache()->open_count());
1324 EXPECT_EQ(1, cache.disk_cache()->create_count());
1326 for (int i = 0; i < kNumTransactions; ++i) {
1327 Context* c = context_list[i];
1328 delete c;
1332 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1333 // If cancelling a request is racing with another request for the same resource
1334 // finishing, we have to make sure that we remove both transactions from the
1335 // entry.
1336 TEST(HttpCache, SimpleGET_RacingReaders) {
1337 MockHttpCache cache;
1339 MockHttpRequest request(kSimpleGET_Transaction);
1340 MockHttpRequest reader_request(kSimpleGET_Transaction);
1341 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1343 std::vector<Context*> context_list;
1344 const int kNumTransactions = 5;
1346 for (int i = 0; i < kNumTransactions; ++i) {
1347 context_list.push_back(new Context());
1348 Context* c = context_list[i];
1350 c->result = cache.CreateTransaction(&c->trans);
1351 ASSERT_EQ(net::OK, c->result);
1353 MockHttpRequest* this_request = &request;
1354 if (i == 1 || i == 2)
1355 this_request = &reader_request;
1357 c->result = c->trans->Start(
1358 this_request, c->callback.callback(), net::BoundNetLog());
1361 // Allow all requests to move from the Create queue to the active entry.
1362 base::MessageLoop::current()->RunUntilIdle();
1364 // The first request should be a writer at this point, and the subsequent
1365 // requests should be pending.
1367 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1368 EXPECT_EQ(0, cache.disk_cache()->open_count());
1369 EXPECT_EQ(1, cache.disk_cache()->create_count());
1371 Context* c = context_list[0];
1372 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1373 c->result = c->callback.WaitForResult();
1374 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1376 // Now we have 2 active readers and two queued transactions.
1378 EXPECT_EQ(net::LOAD_STATE_IDLE,
1379 context_list[2]->trans->GetLoadState());
1380 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1381 context_list[3]->trans->GetLoadState());
1383 c = context_list[1];
1384 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1385 c->result = c->callback.WaitForResult();
1386 if (c->result == net::OK)
1387 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1389 // At this point we have one reader, two pending transactions and a task on
1390 // the queue to move to the next transaction. Now we cancel the request that
1391 // is the current reader, and expect the queued task to be able to start the
1392 // next request.
1394 c = context_list[2];
1395 c->trans.reset();
1397 for (int i = 3; i < kNumTransactions; ++i) {
1398 Context* c = context_list[i];
1399 if (c->result == net::ERR_IO_PENDING)
1400 c->result = c->callback.WaitForResult();
1401 if (c->result == net::OK)
1402 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1405 // We should not have had to re-open the disk entry.
1407 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1408 EXPECT_EQ(0, cache.disk_cache()->open_count());
1409 EXPECT_EQ(1, cache.disk_cache()->create_count());
1411 for (int i = 0; i < kNumTransactions; ++i) {
1412 Context* c = context_list[i];
1413 delete c;
1417 // Tests that we can doom an entry with pending transactions and delete one of
1418 // the pending transactions before the first one completes.
1419 // See http://code.google.com/p/chromium/issues/detail?id=25588
1420 TEST(HttpCache, SimpleGET_DoomWithPending) {
1421 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1422 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1424 MockHttpRequest request(kSimpleGET_Transaction);
1425 MockHttpRequest writer_request(kSimpleGET_Transaction);
1426 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1428 ScopedVector<Context> context_list;
1429 const int kNumTransactions = 4;
1431 for (int i = 0; i < kNumTransactions; ++i) {
1432 context_list.push_back(new Context());
1433 Context* c = context_list[i];
1435 c->result = cache.CreateTransaction(&c->trans);
1436 ASSERT_EQ(net::OK, c->result);
1438 MockHttpRequest* this_request = &request;
1439 if (i == 3)
1440 this_request = &writer_request;
1442 c->result = c->trans->Start(
1443 this_request, c->callback.callback(), net::BoundNetLog());
1446 // The first request should be a writer at this point, and the two subsequent
1447 // requests should be pending. The last request doomed the first entry.
1449 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1451 // Cancel the first queued transaction.
1452 delete context_list[1];
1453 context_list.get()[1] = NULL;
1455 for (int i = 0; i < kNumTransactions; ++i) {
1456 if (i == 1)
1457 continue;
1458 Context* c = context_list[i];
1459 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1460 c->result = c->callback.WaitForResult();
1461 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1465 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1466 // We may attempt to delete an entry synchronously with the act of adding a new
1467 // transaction to said entry.
1468 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1469 MockHttpCache cache;
1471 // The headers will be served right from the call to Start() the request.
1472 MockHttpRequest request(kFastNoStoreGET_Transaction);
1473 FastTransactionServer request_handler;
1474 AddMockTransaction(&kFastNoStoreGET_Transaction);
1476 std::vector<Context*> context_list;
1477 const int kNumTransactions = 3;
1479 for (int i = 0; i < kNumTransactions; ++i) {
1480 context_list.push_back(new Context());
1481 Context* c = context_list[i];
1483 c->result = cache.CreateTransaction(&c->trans);
1484 ASSERT_EQ(net::OK, c->result);
1486 c->result = c->trans->Start(
1487 &request, c->callback.callback(), net::BoundNetLog());
1490 // Allow all requests to move from the Create queue to the active entry.
1491 base::MessageLoop::current()->RunUntilIdle();
1493 // The first request should be a writer at this point, and the subsequent
1494 // requests should be pending.
1496 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1497 EXPECT_EQ(0, cache.disk_cache()->open_count());
1498 EXPECT_EQ(1, cache.disk_cache()->create_count());
1500 // Now, make sure that the second request asks for the entry not to be stored.
1501 request_handler.set_no_store(true);
1503 for (int i = 0; i < kNumTransactions; ++i) {
1504 Context* c = context_list[i];
1505 if (c->result == net::ERR_IO_PENDING)
1506 c->result = c->callback.WaitForResult();
1507 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1508 delete c;
1511 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1512 EXPECT_EQ(0, cache.disk_cache()->open_count());
1513 EXPECT_EQ(2, cache.disk_cache()->create_count());
1515 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1518 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1519 MockHttpCache cache;
1521 MockHttpRequest request(kSimpleGET_Transaction);
1523 std::vector<Context*> context_list;
1524 const int kNumTransactions = 2;
1526 for (int i = 0; i < kNumTransactions; ++i) {
1527 context_list.push_back(new Context());
1528 Context* c = context_list[i];
1530 c->result = cache.CreateTransaction(&c->trans);
1531 ASSERT_EQ(net::OK, c->result);
1533 c->result = c->trans->Start(
1534 &request, c->callback.callback(), net::BoundNetLog());
1537 // Allow all requests to move from the Create queue to the active entry.
1538 base::MessageLoop::current()->RunUntilIdle();
1540 // The first request should be a writer at this point, and the subsequent
1541 // requests should be pending.
1543 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1544 EXPECT_EQ(0, cache.disk_cache()->open_count());
1545 EXPECT_EQ(1, cache.disk_cache()->create_count());
1547 for (int i = 0; i < kNumTransactions; ++i) {
1548 Context* c = context_list[i];
1549 if (c->result == net::ERR_IO_PENDING)
1550 c->result = c->callback.WaitForResult();
1551 // Destroy only the first transaction.
1552 if (i == 0) {
1553 delete c;
1554 context_list[i] = NULL;
1558 // Complete the rest of the transactions.
1559 for (int i = 1; i < kNumTransactions; ++i) {
1560 Context* c = context_list[i];
1561 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1564 // We should have had to re-open the disk entry.
1566 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1567 EXPECT_EQ(0, cache.disk_cache()->open_count());
1568 EXPECT_EQ(2, cache.disk_cache()->create_count());
1570 for (int i = 1; i < kNumTransactions; ++i) {
1571 Context* c = context_list[i];
1572 delete c;
1576 // Tests that we can cancel requests that are queued waiting to open the disk
1577 // cache entry.
1578 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1579 MockHttpCache cache;
1581 MockHttpRequest request(kSimpleGET_Transaction);
1583 std::vector<Context*> context_list;
1584 const int kNumTransactions = 5;
1586 for (int i = 0; i < kNumTransactions; i++) {
1587 context_list.push_back(new Context());
1588 Context* c = context_list[i];
1590 c->result = cache.CreateTransaction(&c->trans);
1591 ASSERT_EQ(net::OK, c->result);
1593 c->result = c->trans->Start(
1594 &request, c->callback.callback(), net::BoundNetLog());
1597 // The first request should be creating the disk cache entry and the others
1598 // should be pending.
1600 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1601 EXPECT_EQ(0, cache.disk_cache()->open_count());
1602 EXPECT_EQ(1, cache.disk_cache()->create_count());
1604 // Cancel a request from the pending queue.
1605 delete context_list[3];
1606 context_list[3] = NULL;
1608 // Cancel the request that is creating the entry. This will force the pending
1609 // operations to restart.
1610 delete context_list[0];
1611 context_list[0] = NULL;
1613 // Complete the rest of the transactions.
1614 for (int i = 1; i < kNumTransactions; i++) {
1615 Context* c = context_list[i];
1616 if (c) {
1617 c->result = c->callback.GetResult(c->result);
1618 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1622 // We should have had to re-create the disk entry.
1624 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1625 EXPECT_EQ(0, cache.disk_cache()->open_count());
1626 EXPECT_EQ(2, cache.disk_cache()->create_count());
1628 for (int i = 1; i < kNumTransactions; ++i) {
1629 delete context_list[i];
1633 // Tests that we can cancel a single request to open a disk cache entry.
1634 TEST(HttpCache, SimpleGET_CancelCreate) {
1635 MockHttpCache cache;
1637 MockHttpRequest request(kSimpleGET_Transaction);
1639 Context* c = new Context();
1641 c->result = cache.CreateTransaction(&c->trans);
1642 ASSERT_EQ(net::OK, c->result);
1644 c->result = c->trans->Start(
1645 &request, c->callback.callback(), net::BoundNetLog());
1646 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1648 // Release the reference that the mock disk cache keeps for this entry, so
1649 // that we test that the http cache handles the cancellation correctly.
1650 cache.disk_cache()->ReleaseAll();
1651 delete c;
1653 base::MessageLoop::current()->RunUntilIdle();
1654 EXPECT_EQ(1, cache.disk_cache()->create_count());
1657 // Tests that we delete/create entries even if multiple requests are queued.
1658 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1659 MockHttpCache cache;
1661 MockHttpRequest request(kSimpleGET_Transaction);
1662 request.load_flags = net::LOAD_BYPASS_CACHE;
1664 std::vector<Context*> context_list;
1665 const int kNumTransactions = 5;
1667 for (int i = 0; i < kNumTransactions; i++) {
1668 context_list.push_back(new Context());
1669 Context* c = context_list[i];
1671 c->result = cache.CreateTransaction(&c->trans);
1672 ASSERT_EQ(net::OK, c->result);
1674 c->result = c->trans->Start(
1675 &request, c->callback.callback(), net::BoundNetLog());
1678 // The first request should be deleting the disk cache entry and the others
1679 // should be pending.
1681 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1682 EXPECT_EQ(0, cache.disk_cache()->open_count());
1683 EXPECT_EQ(0, cache.disk_cache()->create_count());
1685 // Complete the transactions.
1686 for (int i = 0; i < kNumTransactions; i++) {
1687 Context* c = context_list[i];
1688 c->result = c->callback.GetResult(c->result);
1689 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1692 // We should have had to re-create the disk entry multiple times.
1694 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1695 EXPECT_EQ(0, cache.disk_cache()->open_count());
1696 EXPECT_EQ(5, cache.disk_cache()->create_count());
1698 for (int i = 0; i < kNumTransactions; ++i) {
1699 delete context_list[i];
1703 // Tests that a (simulated) timeout allows transactions waiting on the cache
1704 // lock to continue.
1705 TEST(HttpCache, SimpleGET_WriterTimeout) {
1706 MockHttpCache cache;
1707 cache.BypassCacheLock();
1709 MockHttpRequest request(kSimpleGET_Transaction);
1710 Context c1, c2;
1711 ASSERT_EQ(net::OK, cache.CreateTransaction(&c1.trans));
1712 ASSERT_EQ(net::ERR_IO_PENDING,
1713 c1.trans->Start(&request, c1.callback.callback(),
1714 net::BoundNetLog()));
1715 ASSERT_EQ(net::OK, cache.CreateTransaction(&c2.trans));
1716 ASSERT_EQ(net::ERR_IO_PENDING,
1717 c2.trans->Start(&request, c2.callback.callback(),
1718 net::BoundNetLog()));
1720 // The second request is queued after the first one.
1722 c2.callback.WaitForResult();
1723 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1725 // Complete the first transaction.
1726 c1.callback.WaitForResult();
1727 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1730 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1731 MockHttpCache cache;
1733 // write to the cache
1734 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1736 MockHttpRequest request(kSimpleGET_Transaction);
1737 net::TestCompletionCallback callback;
1739 scoped_ptr<net::HttpTransaction> trans;
1740 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
1741 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1742 if (rv == net::ERR_IO_PENDING)
1743 rv = callback.WaitForResult();
1744 ASSERT_EQ(net::OK, rv);
1746 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1747 rv = trans->Read(buf.get(), 256, callback.callback());
1748 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1750 // Test that destroying the transaction while it is reading from the cache
1751 // works properly.
1752 trans.reset();
1754 // Make sure we pump any pending events, which should include a call to
1755 // HttpCache::Transaction::OnCacheReadCompleted.
1756 base::MessageLoop::current()->RunUntilIdle();
1759 // Tests that we can delete the HttpCache and deal with queued transactions
1760 // ("waiting for the backend" as opposed to Active or Doomed entries).
1761 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1762 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1763 new MockBackendNoCbFactory()));
1765 MockHttpRequest request(kSimpleGET_Transaction);
1767 std::vector<Context*> context_list;
1768 const int kNumTransactions = 5;
1770 for (int i = 0; i < kNumTransactions; i++) {
1771 context_list.push_back(new Context());
1772 Context* c = context_list[i];
1774 c->result = cache->CreateTransaction(&c->trans);
1775 ASSERT_EQ(net::OK, c->result);
1777 c->result = c->trans->Start(
1778 &request, c->callback.callback(), net::BoundNetLog());
1781 // The first request should be creating the disk cache entry and the others
1782 // should be pending.
1784 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1785 EXPECT_EQ(0, cache->disk_cache()->open_count());
1786 EXPECT_EQ(0, cache->disk_cache()->create_count());
1788 cache.reset();
1790 // There is not much to do with the transactions at this point... they are
1791 // waiting for a callback that will not fire.
1792 for (int i = 0; i < kNumTransactions; ++i) {
1793 delete context_list[i];
1797 // Tests that we queue requests when initializing the backend.
1798 TEST(HttpCache, SimpleGET_WaitForBackend) {
1799 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1800 MockHttpCache cache(factory);
1802 MockHttpRequest request0(kSimpleGET_Transaction);
1803 MockHttpRequest request1(kTypicalGET_Transaction);
1804 MockHttpRequest request2(kETagGET_Transaction);
1806 std::vector<Context*> context_list;
1807 const int kNumTransactions = 3;
1809 for (int i = 0; i < kNumTransactions; i++) {
1810 context_list.push_back(new Context());
1811 Context* c = context_list[i];
1813 c->result = cache.CreateTransaction(&c->trans);
1814 ASSERT_EQ(net::OK, c->result);
1817 context_list[0]->result = context_list[0]->trans->Start(
1818 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1819 context_list[1]->result = context_list[1]->trans->Start(
1820 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1821 context_list[2]->result = context_list[2]->trans->Start(
1822 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1824 // Just to make sure that everything is still pending.
1825 base::MessageLoop::current()->RunUntilIdle();
1827 // The first request should be creating the disk cache.
1828 EXPECT_FALSE(context_list[0]->callback.have_result());
1830 factory->FinishCreation();
1832 base::MessageLoop::current()->RunUntilIdle();
1833 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1834 EXPECT_EQ(3, cache.disk_cache()->create_count());
1836 for (int i = 0; i < kNumTransactions; ++i) {
1837 EXPECT_TRUE(context_list[i]->callback.have_result());
1838 delete context_list[i];
1842 // Tests that we can cancel requests that are queued waiting for the backend
1843 // to be initialized.
1844 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1845 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1846 MockHttpCache cache(factory);
1848 MockHttpRequest request0(kSimpleGET_Transaction);
1849 MockHttpRequest request1(kTypicalGET_Transaction);
1850 MockHttpRequest request2(kETagGET_Transaction);
1852 std::vector<Context*> context_list;
1853 const int kNumTransactions = 3;
1855 for (int i = 0; i < kNumTransactions; i++) {
1856 context_list.push_back(new Context());
1857 Context* c = context_list[i];
1859 c->result = cache.CreateTransaction(&c->trans);
1860 ASSERT_EQ(net::OK, c->result);
1863 context_list[0]->result = context_list[0]->trans->Start(
1864 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1865 context_list[1]->result = context_list[1]->trans->Start(
1866 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1867 context_list[2]->result = context_list[2]->trans->Start(
1868 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1870 // Just to make sure that everything is still pending.
1871 base::MessageLoop::current()->RunUntilIdle();
1873 // The first request should be creating the disk cache.
1874 EXPECT_FALSE(context_list[0]->callback.have_result());
1876 // Cancel a request from the pending queue.
1877 delete context_list[1];
1878 context_list[1] = NULL;
1880 // Cancel the request that is creating the entry.
1881 delete context_list[0];
1882 context_list[0] = NULL;
1884 // Complete the last transaction.
1885 factory->FinishCreation();
1887 context_list[2]->result =
1888 context_list[2]->callback.GetResult(context_list[2]->result);
1889 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1891 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1892 EXPECT_EQ(1, cache.disk_cache()->create_count());
1894 delete context_list[2];
1897 // Tests that we can delete the cache while creating the backend.
1898 TEST(HttpCache, DeleteCacheWaitingForBackend) {
1899 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1900 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1902 MockHttpRequest request(kSimpleGET_Transaction);
1904 scoped_ptr<Context> c(new Context());
1905 c->result = cache->CreateTransaction(&c->trans);
1906 ASSERT_EQ(net::OK, c->result);
1908 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1910 // Just to make sure that everything is still pending.
1911 base::MessageLoop::current()->RunUntilIdle();
1913 // The request should be creating the disk cache.
1914 EXPECT_FALSE(c->callback.have_result());
1916 // We cannot call FinishCreation because the factory itself will go away with
1917 // the cache, so grab the callback and attempt to use it.
1918 net::CompletionCallback callback = factory->callback();
1919 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1921 cache.reset();
1922 base::MessageLoop::current()->RunUntilIdle();
1924 backend->reset();
1925 callback.Run(net::ERR_ABORTED);
1928 // Tests that we can delete the cache while creating the backend, from within
1929 // one of the callbacks.
1930 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1931 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1932 MockHttpCache* cache = new MockHttpCache(factory);
1934 DeleteCacheCompletionCallback cb(cache);
1935 disk_cache::Backend* backend;
1936 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1937 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1939 // Now let's queue a regular transaction
1940 MockHttpRequest request(kSimpleGET_Transaction);
1942 scoped_ptr<Context> c(new Context());
1943 c->result = cache->CreateTransaction(&c->trans);
1944 ASSERT_EQ(net::OK, c->result);
1946 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1948 // And another direct backend request.
1949 net::TestCompletionCallback cb2;
1950 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1951 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1953 // Just to make sure that everything is still pending.
1954 base::MessageLoop::current()->RunUntilIdle();
1956 // The request should be queued.
1957 EXPECT_FALSE(c->callback.have_result());
1959 // Generate the callback.
1960 factory->FinishCreation();
1961 rv = cb.WaitForResult();
1963 // The cache should be gone by now.
1964 base::MessageLoop::current()->RunUntilIdle();
1965 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1966 EXPECT_FALSE(cb2.have_result());
1969 TEST(HttpCache, TypicalGET_ConditionalRequest) {
1970 MockHttpCache cache;
1972 // write to the cache
1973 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1975 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1976 EXPECT_EQ(0, cache.disk_cache()->open_count());
1977 EXPECT_EQ(1, cache.disk_cache()->create_count());
1979 // Get the same URL again, but this time we expect it to result
1980 // in a conditional request.
1981 net::CapturingBoundNetLog log;
1982 net::LoadTimingInfo load_timing_info;
1983 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1984 log.bound(), &load_timing_info);
1986 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1987 EXPECT_EQ(1, cache.disk_cache()->open_count());
1988 EXPECT_EQ(1, cache.disk_cache()->create_count());
1989 TestLoadTimingNetworkRequest(load_timing_info);
1992 static void ETagGet_ConditionalRequest_Handler(
1993 const net::HttpRequestInfo* request,
1994 std::string* response_status,
1995 std::string* response_headers,
1996 std::string* response_data) {
1997 EXPECT_TRUE(
1998 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
1999 response_status->assign("HTTP/1.1 304 Not Modified");
2000 response_headers->assign(kETagGET_Transaction.response_headers);
2001 response_data->clear();
2004 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2005 MockHttpCache cache;
2007 ScopedMockTransaction transaction(kETagGET_Transaction);
2009 // write to the cache
2010 RunTransactionTest(cache.http_cache(), transaction);
2012 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2013 EXPECT_EQ(0, cache.disk_cache()->open_count());
2014 EXPECT_EQ(1, cache.disk_cache()->create_count());
2016 // Get the same URL again, but this time we expect it to result
2017 // in a conditional request.
2018 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2019 transaction.handler = ETagGet_ConditionalRequest_Handler;
2020 net::CapturingBoundNetLog log;
2021 net::LoadTimingInfo load_timing_info;
2022 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2023 &load_timing_info);
2025 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2026 EXPECT_EQ(1, cache.disk_cache()->open_count());
2027 EXPECT_EQ(1, cache.disk_cache()->create_count());
2028 TestLoadTimingNetworkRequest(load_timing_info);
2031 class RevalidationServer {
2032 public:
2033 RevalidationServer() {
2034 s_etag_used_ = false;
2035 s_last_modified_used_ = false;
2038 bool EtagUsed() { return s_etag_used_; }
2039 bool LastModifiedUsed() { return s_last_modified_used_; }
2041 static void Handler(const net::HttpRequestInfo* request,
2042 std::string* response_status,
2043 std::string* response_headers,
2044 std::string* response_data);
2046 private:
2047 static bool s_etag_used_;
2048 static bool s_last_modified_used_;
2050 bool RevalidationServer::s_etag_used_ = false;
2051 bool RevalidationServer::s_last_modified_used_ = false;
2053 void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2054 std::string* response_status,
2055 std::string* response_headers,
2056 std::string* response_data) {
2057 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2058 s_etag_used_ = true;
2060 if (request->extra_headers.HasHeader(
2061 net::HttpRequestHeaders::kIfModifiedSince)) {
2062 s_last_modified_used_ = true;
2065 if (s_etag_used_ || s_last_modified_used_) {
2066 response_status->assign("HTTP/1.1 304 Not Modified");
2067 response_headers->assign(kTypicalGET_Transaction.response_headers);
2068 response_data->clear();
2069 } else {
2070 response_status->assign(kTypicalGET_Transaction.status);
2071 response_headers->assign(kTypicalGET_Transaction.response_headers);
2072 response_data->assign(kTypicalGET_Transaction.data);
2076 // Tests revalidation after a vary match.
2077 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2078 MockHttpCache cache;
2080 // Write to the cache.
2081 MockTransaction transaction(kTypicalGET_Transaction);
2082 transaction.request_headers = "Foo: bar\r\n";
2083 transaction.response_headers =
2084 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2085 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2086 "Etag: \"foopy\"\n"
2087 "Cache-Control: max-age=0\n"
2088 "Vary: Foo\n";
2089 AddMockTransaction(&transaction);
2090 RunTransactionTest(cache.http_cache(), transaction);
2092 // Read from the cache.
2093 RevalidationServer server;
2094 transaction.handler = server.Handler;
2095 net::CapturingBoundNetLog log;
2096 net::LoadTimingInfo load_timing_info;
2097 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2098 &load_timing_info);
2100 EXPECT_TRUE(server.EtagUsed());
2101 EXPECT_TRUE(server.LastModifiedUsed());
2102 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2103 EXPECT_EQ(1, cache.disk_cache()->open_count());
2104 EXPECT_EQ(1, cache.disk_cache()->create_count());
2105 TestLoadTimingNetworkRequest(load_timing_info);
2106 RemoveMockTransaction(&transaction);
2109 // Tests revalidation after a vary mismatch if etag is present.
2110 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2111 MockHttpCache cache;
2113 // Write to the cache.
2114 MockTransaction transaction(kTypicalGET_Transaction);
2115 transaction.request_headers = "Foo: bar\r\n";
2116 transaction.response_headers =
2117 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2118 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2119 "Etag: \"foopy\"\n"
2120 "Cache-Control: max-age=0\n"
2121 "Vary: Foo\n";
2122 AddMockTransaction(&transaction);
2123 RunTransactionTest(cache.http_cache(), transaction);
2125 // Read from the cache and revalidate the entry.
2126 RevalidationServer server;
2127 transaction.handler = server.Handler;
2128 transaction.request_headers = "Foo: none\r\n";
2129 net::CapturingBoundNetLog log;
2130 net::LoadTimingInfo load_timing_info;
2131 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2132 &load_timing_info);
2134 EXPECT_TRUE(server.EtagUsed());
2135 EXPECT_FALSE(server.LastModifiedUsed());
2136 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2137 EXPECT_EQ(1, cache.disk_cache()->open_count());
2138 EXPECT_EQ(1, cache.disk_cache()->create_count());
2139 TestLoadTimingNetworkRequest(load_timing_info);
2140 RemoveMockTransaction(&transaction);
2143 // Tests lack of revalidation after a vary mismatch and no etag.
2144 TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2145 MockHttpCache cache;
2147 // Write to the cache.
2148 MockTransaction transaction(kTypicalGET_Transaction);
2149 transaction.request_headers = "Foo: bar\r\n";
2150 transaction.response_headers =
2151 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2152 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2153 "Cache-Control: max-age=0\n"
2154 "Vary: Foo\n";
2155 AddMockTransaction(&transaction);
2156 RunTransactionTest(cache.http_cache(), transaction);
2158 // Read from the cache and don't revalidate the entry.
2159 RevalidationServer server;
2160 transaction.handler = server.Handler;
2161 transaction.request_headers = "Foo: none\r\n";
2162 net::CapturingBoundNetLog log;
2163 net::LoadTimingInfo load_timing_info;
2164 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2165 &load_timing_info);
2167 EXPECT_FALSE(server.EtagUsed());
2168 EXPECT_FALSE(server.LastModifiedUsed());
2169 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2170 EXPECT_EQ(1, cache.disk_cache()->open_count());
2171 EXPECT_EQ(1, cache.disk_cache()->create_count());
2172 TestLoadTimingNetworkRequest(load_timing_info);
2173 RemoveMockTransaction(&transaction);
2176 static void ETagGet_UnconditionalRequest_Handler(
2177 const net::HttpRequestInfo* request,
2178 std::string* response_status,
2179 std::string* response_headers,
2180 std::string* response_data) {
2181 EXPECT_FALSE(
2182 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2185 TEST(HttpCache, ETagGET_Http10) {
2186 MockHttpCache cache;
2188 ScopedMockTransaction transaction(kETagGET_Transaction);
2189 transaction.status = "HTTP/1.0 200 OK";
2191 // Write to the cache.
2192 RunTransactionTest(cache.http_cache(), transaction);
2194 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2195 EXPECT_EQ(0, cache.disk_cache()->open_count());
2196 EXPECT_EQ(1, cache.disk_cache()->create_count());
2198 // Get the same URL again, without generating a conditional request.
2199 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2200 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2201 RunTransactionTest(cache.http_cache(), transaction);
2203 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2204 EXPECT_EQ(1, cache.disk_cache()->open_count());
2205 EXPECT_EQ(1, cache.disk_cache()->create_count());
2208 TEST(HttpCache, ETagGET_Http10_Range) {
2209 MockHttpCache cache;
2211 ScopedMockTransaction transaction(kETagGET_Transaction);
2212 transaction.status = "HTTP/1.0 200 OK";
2214 // Write to the cache.
2215 RunTransactionTest(cache.http_cache(), transaction);
2217 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2218 EXPECT_EQ(0, cache.disk_cache()->open_count());
2219 EXPECT_EQ(1, cache.disk_cache()->create_count());
2221 // Get the same URL again, but use a byte range request.
2222 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2223 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2224 transaction.request_headers = "Range: bytes = 5-\r\n";
2225 RunTransactionTest(cache.http_cache(), transaction);
2227 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2228 EXPECT_EQ(1, cache.disk_cache()->open_count());
2229 EXPECT_EQ(2, cache.disk_cache()->create_count());
2232 static void ETagGet_ConditionalRequest_NoStore_Handler(
2233 const net::HttpRequestInfo* request,
2234 std::string* response_status,
2235 std::string* response_headers,
2236 std::string* response_data) {
2237 EXPECT_TRUE(
2238 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2239 response_status->assign("HTTP/1.1 304 Not Modified");
2240 response_headers->assign("Cache-Control: no-store\n");
2241 response_data->clear();
2244 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2245 MockHttpCache cache;
2247 ScopedMockTransaction transaction(kETagGET_Transaction);
2249 // Write to the cache.
2250 RunTransactionTest(cache.http_cache(), transaction);
2252 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2253 EXPECT_EQ(0, cache.disk_cache()->open_count());
2254 EXPECT_EQ(1, cache.disk_cache()->create_count());
2256 // Get the same URL again, but this time we expect it to result
2257 // in a conditional request.
2258 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2259 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2260 RunTransactionTest(cache.http_cache(), transaction);
2262 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2263 EXPECT_EQ(1, cache.disk_cache()->open_count());
2264 EXPECT_EQ(1, cache.disk_cache()->create_count());
2266 ScopedMockTransaction transaction2(kETagGET_Transaction);
2268 // Write to the cache again. This should create a new entry.
2269 RunTransactionTest(cache.http_cache(), transaction2);
2271 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2272 EXPECT_EQ(1, cache.disk_cache()->open_count());
2273 EXPECT_EQ(2, cache.disk_cache()->create_count());
2276 // Helper that does 4 requests using HttpCache:
2278 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2279 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2280 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2281 // be returned.
2282 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2283 // returned.
2284 static void ConditionalizedRequestUpdatesCacheHelper(
2285 const Response& net_response_1,
2286 const Response& net_response_2,
2287 const Response& cached_response_2,
2288 const char* extra_request_headers) {
2289 MockHttpCache cache;
2291 // The URL we will be requesting.
2292 const char* kUrl = "http://foobar.com/main.css";
2294 // Junk network response.
2295 static const Response kUnexpectedResponse = {
2296 "HTTP/1.1 500 Unexpected",
2297 "Server: unexpected_header",
2298 "unexpected body"
2301 // We will control the network layer's responses for |kUrl| using
2302 // |mock_network_response|.
2303 MockTransaction mock_network_response = { 0 };
2304 mock_network_response.url = kUrl;
2305 AddMockTransaction(&mock_network_response);
2307 // Request |kUrl| for the first time. It should hit the network and
2308 // receive |kNetResponse1|, which it saves into the HTTP cache.
2310 MockTransaction request = { 0 };
2311 request.url = kUrl;
2312 request.method = "GET";
2313 request.request_headers = "";
2315 net_response_1.AssignTo(&mock_network_response); // Network mock.
2316 net_response_1.AssignTo(&request); // Expected result.
2318 std::string response_headers;
2319 RunTransactionTestWithResponse(
2320 cache.http_cache(), request, &response_headers);
2322 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2323 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2324 EXPECT_EQ(0, cache.disk_cache()->open_count());
2325 EXPECT_EQ(1, cache.disk_cache()->create_count());
2327 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2328 // cache, so we don't hit the network.
2330 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2332 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2333 net_response_1.AssignTo(&request); // Expected result.
2335 RunTransactionTestWithResponse(
2336 cache.http_cache(), request, &response_headers);
2338 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2339 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2340 EXPECT_EQ(1, cache.disk_cache()->open_count());
2341 EXPECT_EQ(1, cache.disk_cache()->create_count());
2343 // Request |kUrl| yet again, but this time give the request an
2344 // "If-Modified-Since" header. This will cause the request to re-hit the
2345 // network. However now the network response is going to be
2346 // different -- this simulates a change made to the CSS file.
2348 request.request_headers = extra_request_headers;
2349 request.load_flags = net::LOAD_NORMAL;
2351 net_response_2.AssignTo(&mock_network_response); // Network mock.
2352 net_response_2.AssignTo(&request); // Expected result.
2354 RunTransactionTestWithResponse(
2355 cache.http_cache(), request, &response_headers);
2357 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2358 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2359 EXPECT_EQ(1, cache.disk_cache()->open_count());
2360 EXPECT_EQ(1, cache.disk_cache()->create_count());
2362 // Finally, request |kUrl| again. This request should be serviced from
2363 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2364 // and NOT |kNetResponse1|. The previous step should have replaced the
2365 // value in the cache with the modified response.
2367 request.request_headers = "";
2368 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2370 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2371 cached_response_2.AssignTo(&request); // Expected result.
2373 RunTransactionTestWithResponse(
2374 cache.http_cache(), request, &response_headers);
2376 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2377 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2378 EXPECT_EQ(2, cache.disk_cache()->open_count());
2379 EXPECT_EQ(1, cache.disk_cache()->create_count());
2381 RemoveMockTransaction(&mock_network_response);
2384 // Check that when an "if-modified-since" header is attached
2385 // to the request, the result still updates the cached entry.
2386 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2387 // First network response for |kUrl|.
2388 static const Response kNetResponse1 = {
2389 "HTTP/1.1 200 OK",
2390 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2391 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2392 "body1"
2395 // Second network response for |kUrl|.
2396 static const Response kNetResponse2 = {
2397 "HTTP/1.1 200 OK",
2398 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2399 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2400 "body2"
2403 const char* extra_headers =
2404 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2406 ConditionalizedRequestUpdatesCacheHelper(
2407 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2410 // Check that when an "if-none-match" header is attached
2411 // to the request, the result updates the cached entry.
2412 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2413 // First network response for |kUrl|.
2414 static const Response kNetResponse1 = {
2415 "HTTP/1.1 200 OK",
2416 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2417 "Etag: \"ETAG1\"\n"
2418 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2419 "body1"
2422 // Second network response for |kUrl|.
2423 static const Response kNetResponse2 = {
2424 "HTTP/1.1 200 OK",
2425 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2426 "Etag: \"ETAG2\"\n"
2427 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2428 "body2"
2431 const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
2433 ConditionalizedRequestUpdatesCacheHelper(
2434 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2437 // Check that when an "if-modified-since" header is attached
2438 // to a request, the 304 (not modified result) result updates the cached
2439 // headers, and the 304 response is returned rather than the cached response.
2440 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2441 // First network response for |kUrl|.
2442 static const Response kNetResponse1 = {
2443 "HTTP/1.1 200 OK",
2444 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2445 "Server: server1\n"
2446 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2447 "body1"
2450 // Second network response for |kUrl|.
2451 static const Response kNetResponse2 = {
2452 "HTTP/1.1 304 Not Modified",
2453 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2454 "Server: server2\n"
2455 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2459 static const Response kCachedResponse2 = {
2460 "HTTP/1.1 200 OK",
2461 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2462 "Server: server2\n"
2463 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2464 "body1"
2467 const char* extra_headers =
2468 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2470 ConditionalizedRequestUpdatesCacheHelper(
2471 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2474 // Test that when doing an externally conditionalized if-modified-since
2475 // and there is no corresponding cache entry, a new cache entry is NOT
2476 // created (304 response).
2477 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2478 MockHttpCache cache;
2480 const char* kUrl = "http://foobar.com/main.css";
2482 static const Response kNetResponse = {
2483 "HTTP/1.1 304 Not Modified",
2484 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2485 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2489 const char* kExtraRequestHeaders =
2490 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2492 // We will control the network layer's responses for |kUrl| using
2493 // |mock_network_response|.
2494 MockTransaction mock_network_response = { 0 };
2495 mock_network_response.url = kUrl;
2496 AddMockTransaction(&mock_network_response);
2498 MockTransaction request = { 0 };
2499 request.url = kUrl;
2500 request.method = "GET";
2501 request.request_headers = kExtraRequestHeaders;
2503 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2504 kNetResponse.AssignTo(&request); // Expected result.
2506 std::string response_headers;
2507 RunTransactionTestWithResponse(
2508 cache.http_cache(), request, &response_headers);
2510 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2511 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2512 EXPECT_EQ(0, cache.disk_cache()->open_count());
2513 EXPECT_EQ(0, cache.disk_cache()->create_count());
2515 RemoveMockTransaction(&mock_network_response);
2518 // Test that when doing an externally conditionalized if-modified-since
2519 // and there is no corresponding cache entry, a new cache entry is NOT
2520 // created (200 response).
2521 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2522 MockHttpCache cache;
2524 const char* kUrl = "http://foobar.com/main.css";
2526 static const Response kNetResponse = {
2527 "HTTP/1.1 200 OK",
2528 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2529 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2530 "foobar!!!"
2533 const char* kExtraRequestHeaders =
2534 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2536 // We will control the network layer's responses for |kUrl| using
2537 // |mock_network_response|.
2538 MockTransaction mock_network_response = { 0 };
2539 mock_network_response.url = kUrl;
2540 AddMockTransaction(&mock_network_response);
2542 MockTransaction request = { 0 };
2543 request.url = kUrl;
2544 request.method = "GET";
2545 request.request_headers = kExtraRequestHeaders;
2547 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2548 kNetResponse.AssignTo(&request); // Expected result.
2550 std::string response_headers;
2551 RunTransactionTestWithResponse(
2552 cache.http_cache(), request, &response_headers);
2554 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2555 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2556 EXPECT_EQ(0, cache.disk_cache()->open_count());
2557 EXPECT_EQ(0, cache.disk_cache()->create_count());
2559 RemoveMockTransaction(&mock_network_response);
2562 // Test that when doing an externally conditionalized if-modified-since
2563 // if the date does not match the cache entry's last-modified date,
2564 // then we do NOT use the response (304) to update the cache.
2565 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2566 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2567 static const Response kNetResponse1 = {
2568 "HTTP/1.1 200 OK",
2569 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2570 "Server: server1\n"
2571 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2572 "body1"
2575 // Second network response for |kUrl|.
2576 static const Response kNetResponse2 = {
2577 "HTTP/1.1 304 Not Modified",
2578 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2579 "Server: server2\n"
2580 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2584 // This is two days in the future from the original response's last-modified
2585 // date!
2586 const char* kExtraRequestHeaders =
2587 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2589 ConditionalizedRequestUpdatesCacheHelper(
2590 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2593 // Test that when doing an externally conditionalized if-none-match
2594 // if the etag does not match the cache entry's etag, then we do not use the
2595 // response (304) to update the cache.
2596 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2597 static const Response kNetResponse1 = {
2598 "HTTP/1.1 200 OK",
2599 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2600 "Etag: \"Foo1\"\n"
2601 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2602 "body1"
2605 // Second network response for |kUrl|.
2606 static const Response kNetResponse2 = {
2607 "HTTP/1.1 304 Not Modified",
2608 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2609 "Etag: \"Foo2\"\n"
2610 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2614 // Different etag from original response.
2615 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
2617 ConditionalizedRequestUpdatesCacheHelper(
2618 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2621 // Test that doing an externally conditionalized request with both if-none-match
2622 // and if-modified-since updates the cache.
2623 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2624 static const Response kNetResponse1 = {
2625 "HTTP/1.1 200 OK",
2626 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2627 "Etag: \"Foo1\"\n"
2628 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2629 "body1"
2632 // Second network response for |kUrl|.
2633 static const Response kNetResponse2 = {
2634 "HTTP/1.1 200 OK",
2635 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2636 "Etag: \"Foo2\"\n"
2637 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2638 "body2"
2641 const char* kExtraRequestHeaders =
2642 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2643 "If-None-Match: \"Foo1\"\r\n";
2645 ConditionalizedRequestUpdatesCacheHelper(
2646 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2649 // Test that doing an externally conditionalized request with both if-none-match
2650 // and if-modified-since does not update the cache with only one match.
2651 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2652 static const Response kNetResponse1 = {
2653 "HTTP/1.1 200 OK",
2654 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2655 "Etag: \"Foo1\"\n"
2656 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2657 "body1"
2660 // Second network response for |kUrl|.
2661 static const Response kNetResponse2 = {
2662 "HTTP/1.1 200 OK",
2663 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2664 "Etag: \"Foo2\"\n"
2665 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2666 "body2"
2669 // The etag doesn't match what we have stored.
2670 const char* kExtraRequestHeaders =
2671 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2672 "If-None-Match: \"Foo2\"\r\n";
2674 ConditionalizedRequestUpdatesCacheHelper(
2675 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2678 // Test that doing an externally conditionalized request with both if-none-match
2679 // and if-modified-since does not update the cache with only one match.
2680 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2681 static const Response kNetResponse1 = {
2682 "HTTP/1.1 200 OK",
2683 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2684 "Etag: \"Foo1\"\n"
2685 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2686 "body1"
2689 // Second network response for |kUrl|.
2690 static const Response kNetResponse2 = {
2691 "HTTP/1.1 200 OK",
2692 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2693 "Etag: \"Foo2\"\n"
2694 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2695 "body2"
2698 // The modification date doesn't match what we have stored.
2699 const char* kExtraRequestHeaders =
2700 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2701 "If-None-Match: \"Foo1\"\r\n";
2703 ConditionalizedRequestUpdatesCacheHelper(
2704 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2707 TEST(HttpCache, UrlContainingHash) {
2708 MockHttpCache cache;
2710 // Do a typical GET request -- should write an entry into our cache.
2711 MockTransaction trans(kTypicalGET_Transaction);
2712 RunTransactionTest(cache.http_cache(), trans);
2714 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2715 EXPECT_EQ(0, cache.disk_cache()->open_count());
2716 EXPECT_EQ(1, cache.disk_cache()->create_count());
2718 // Request the same URL, but this time with a reference section (hash).
2719 // Since the cache key strips the hash sections, this should be a cache hit.
2720 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2721 trans.url = url_with_hash.c_str();
2722 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2724 RunTransactionTest(cache.http_cache(), trans);
2726 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2727 EXPECT_EQ(1, cache.disk_cache()->open_count());
2728 EXPECT_EQ(1, cache.disk_cache()->create_count());
2731 // Tests that we skip the cache for POST requests that do not have an upload
2732 // identifier.
2733 TEST(HttpCache, SimplePOST_SkipsCache) {
2734 MockHttpCache cache;
2736 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2738 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2739 EXPECT_EQ(0, cache.disk_cache()->open_count());
2740 EXPECT_EQ(0, cache.disk_cache()->create_count());
2743 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2744 MockHttpCache cache;
2746 MockTransaction transaction(kSimplePOST_Transaction);
2747 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2749 MockHttpRequest request(transaction);
2750 net::TestCompletionCallback callback;
2752 scoped_ptr<net::HttpTransaction> trans;
2753 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
2754 ASSERT_TRUE(trans.get());
2756 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
2757 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
2759 trans.reset();
2761 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2762 EXPECT_EQ(0, cache.disk_cache()->open_count());
2763 EXPECT_EQ(0, cache.disk_cache()->create_count());
2766 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2767 MockHttpCache cache;
2769 // Test that we hit the cache for POST requests.
2771 MockTransaction transaction(kSimplePOST_Transaction);
2773 const int64 kUploadId = 1; // Just a dummy value.
2775 ScopedVector<net::UploadElementReader> element_readers;
2776 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2777 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2778 kUploadId);
2779 MockHttpRequest request(transaction);
2780 request.upload_data_stream = &upload_data_stream;
2782 // Populate the cache.
2783 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2785 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2786 EXPECT_EQ(0, cache.disk_cache()->open_count());
2787 EXPECT_EQ(1, cache.disk_cache()->create_count());
2789 // Load from cache.
2790 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2791 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2793 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2794 EXPECT_EQ(1, cache.disk_cache()->open_count());
2795 EXPECT_EQ(1, cache.disk_cache()->create_count());
2798 // Test that we don't hit the cache for POST requests if there is a byte range.
2799 TEST(HttpCache, SimplePOST_WithRanges) {
2800 MockHttpCache cache;
2802 MockTransaction transaction(kSimplePOST_Transaction);
2803 transaction.request_headers = "Range: bytes = 0-4\r\n";
2805 const int64 kUploadId = 1; // Just a dummy value.
2807 ScopedVector<net::UploadElementReader> element_readers;
2808 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2809 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2810 kUploadId);
2812 MockHttpRequest request(transaction);
2813 request.upload_data_stream = &upload_data_stream;
2815 // Attempt to populate the cache.
2816 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2818 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2819 EXPECT_EQ(0, cache.disk_cache()->open_count());
2820 EXPECT_EQ(0, cache.disk_cache()->create_count());
2823 // Tests that a POST is cached separately from a previously cached GET.
2824 TEST(HttpCache, SimplePOST_SeparateCache) {
2825 MockHttpCache cache;
2827 ScopedVector<net::UploadElementReader> element_readers;
2828 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2829 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2831 MockTransaction transaction(kSimplePOST_Transaction);
2832 MockHttpRequest req1(transaction);
2833 req1.upload_data_stream = &upload_data_stream;
2835 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2837 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2838 EXPECT_EQ(0, cache.disk_cache()->open_count());
2839 EXPECT_EQ(1, cache.disk_cache()->create_count());
2841 transaction.method = "GET";
2842 MockHttpRequest req2(transaction);
2844 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2846 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2847 EXPECT_EQ(0, cache.disk_cache()->open_count());
2848 EXPECT_EQ(2, cache.disk_cache()->create_count());
2851 // Tests that a successful POST invalidates a previously cached GET.
2852 TEST(HttpCache, SimplePOST_Invalidate_205) {
2853 MockHttpCache cache;
2855 MockTransaction transaction(kSimpleGET_Transaction);
2856 AddMockTransaction(&transaction);
2857 MockHttpRequest req1(transaction);
2859 // Attempt to populate the cache.
2860 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2862 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2863 EXPECT_EQ(0, cache.disk_cache()->open_count());
2864 EXPECT_EQ(1, cache.disk_cache()->create_count());
2866 ScopedVector<net::UploadElementReader> element_readers;
2867 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2868 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2870 transaction.method = "POST";
2871 transaction.status = "HTTP/1.1 205 No Content";
2872 MockHttpRequest req2(transaction);
2873 req2.upload_data_stream = &upload_data_stream;
2875 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2877 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2878 EXPECT_EQ(0, cache.disk_cache()->open_count());
2879 EXPECT_EQ(2, cache.disk_cache()->create_count());
2881 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2883 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2884 EXPECT_EQ(0, cache.disk_cache()->open_count());
2885 EXPECT_EQ(3, cache.disk_cache()->create_count());
2886 RemoveMockTransaction(&transaction);
2889 // Tests that a successful POST invalidates a previously cached GET, even when
2890 // there is no upload identifier.
2891 TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
2892 MockHttpCache cache;
2894 MockTransaction transaction(kSimpleGET_Transaction);
2895 AddMockTransaction(&transaction);
2896 MockHttpRequest req1(transaction);
2898 // Attempt to populate the cache.
2899 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2901 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2902 EXPECT_EQ(0, cache.disk_cache()->open_count());
2903 EXPECT_EQ(1, cache.disk_cache()->create_count());
2905 ScopedVector<net::UploadElementReader> element_readers;
2906 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2907 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
2909 transaction.method = "POST";
2910 transaction.status = "HTTP/1.1 205 No Content";
2911 MockHttpRequest req2(transaction);
2912 req2.upload_data_stream = &upload_data_stream;
2914 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2916 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2917 EXPECT_EQ(0, cache.disk_cache()->open_count());
2918 EXPECT_EQ(1, cache.disk_cache()->create_count());
2920 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2922 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2923 EXPECT_EQ(0, cache.disk_cache()->open_count());
2924 EXPECT_EQ(2, cache.disk_cache()->create_count());
2925 RemoveMockTransaction(&transaction);
2928 // Tests that processing a POST before creating the backend doesn't crash.
2929 TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
2930 // This will initialize a cache object with NULL backend.
2931 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2932 factory->set_fail(true);
2933 factory->FinishCreation();
2934 MockHttpCache cache(factory);
2936 ScopedVector<net::UploadElementReader> element_readers;
2937 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2938 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
2940 MockTransaction transaction(kSimplePOST_Transaction);
2941 AddMockTransaction(&transaction);
2942 MockHttpRequest req(transaction);
2943 req.upload_data_stream = &upload_data_stream;
2945 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
2947 RemoveMockTransaction(&transaction);
2950 // Tests that we don't invalidate entries as a result of a failed POST.
2951 TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2952 MockHttpCache cache;
2954 MockTransaction transaction(kSimpleGET_Transaction);
2955 AddMockTransaction(&transaction);
2956 MockHttpRequest req1(transaction);
2958 // Attempt to populate the cache.
2959 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2961 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2962 EXPECT_EQ(0, cache.disk_cache()->open_count());
2963 EXPECT_EQ(1, cache.disk_cache()->create_count());
2965 ScopedVector<net::UploadElementReader> element_readers;
2966 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2967 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2969 transaction.method = "POST";
2970 transaction.status = "HTTP/1.1 100 Continue";
2971 MockHttpRequest req2(transaction);
2972 req2.upload_data_stream = &upload_data_stream;
2974 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2976 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2977 EXPECT_EQ(0, cache.disk_cache()->open_count());
2978 EXPECT_EQ(2, cache.disk_cache()->create_count());
2980 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2982 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2983 EXPECT_EQ(1, cache.disk_cache()->open_count());
2984 EXPECT_EQ(2, cache.disk_cache()->create_count());
2985 RemoveMockTransaction(&transaction);
2988 // Tests that a HEAD request is not cached by itself.
2989 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
2990 MockHttpCache cache;
2991 MockTransaction transaction(kSimplePOST_Transaction);
2992 AddMockTransaction(&transaction);
2993 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2994 transaction.method = "HEAD";
2996 MockHttpRequest request(transaction);
2997 net::TestCompletionCallback callback;
2999 scoped_ptr<net::HttpTransaction> trans;
3000 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
3001 ASSERT_TRUE(trans.get());
3003 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
3004 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
3006 trans.reset();
3008 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3009 EXPECT_EQ(0, cache.disk_cache()->open_count());
3010 EXPECT_EQ(0, cache.disk_cache()->create_count());
3011 RemoveMockTransaction(&transaction);
3014 // Tests that a HEAD request is served from a cached GET.
3015 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3016 MockHttpCache cache;
3017 MockTransaction transaction(kSimpleGET_Transaction);
3018 AddMockTransaction(&transaction);
3020 // Populate the cache.
3021 RunTransactionTest(cache.http_cache(), transaction);
3023 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3024 EXPECT_EQ(0, cache.disk_cache()->open_count());
3025 EXPECT_EQ(1, cache.disk_cache()->create_count());
3027 // Load from cache.
3028 transaction.method = "HEAD";
3029 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3030 transaction.data = "";
3031 RunTransactionTest(cache.http_cache(), transaction);
3033 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3034 EXPECT_EQ(1, cache.disk_cache()->open_count());
3035 EXPECT_EQ(1, cache.disk_cache()->create_count());
3036 RemoveMockTransaction(&transaction);
3039 // Tests that a read-only request served from the cache preserves CL.
3040 TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3041 MockHttpCache cache;
3042 MockTransaction transaction(kSimpleGET_Transaction);
3043 AddMockTransaction(&transaction);
3044 transaction.response_headers = "Content-Length: 42\n";
3046 // Populate the cache.
3047 RunTransactionTest(cache.http_cache(), transaction);
3049 // Load from cache.
3050 transaction.method = "HEAD";
3051 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3052 transaction.data = "";
3053 std::string headers;
3055 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3057 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3058 RemoveMockTransaction(&transaction);
3061 // Tests that a read-write request served from the cache preserves CL.
3062 TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3063 MockHttpCache cache;
3064 MockTransaction transaction(kETagGET_Transaction);
3065 AddMockTransaction(&transaction);
3066 std::string server_headers(kETagGET_Transaction.response_headers);
3067 server_headers.append("Content-Length: 42\n");
3068 transaction.response_headers = server_headers.data();
3070 // Populate the cache.
3071 RunTransactionTest(cache.http_cache(), transaction);
3073 // Load from cache.
3074 transaction.method = "HEAD";
3075 transaction.data = "";
3076 std::string headers;
3078 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3080 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3081 RemoveMockTransaction(&transaction);
3084 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3085 TEST(HttpCache, SimpleHEAD_WithRanges) {
3086 MockHttpCache cache;
3087 MockTransaction transaction(kSimpleGET_Transaction);
3088 AddMockTransaction(&transaction);
3090 // Populate the cache.
3091 RunTransactionTest(cache.http_cache(), transaction);
3093 // Load from cache.
3094 transaction.method = "HEAD";
3095 transaction.request_headers = "Range: bytes = 0-4\r\n";
3096 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3097 transaction.return_code = net::ERR_CACHE_MISS;
3098 RunTransactionTest(cache.http_cache(), transaction);
3100 EXPECT_EQ(0, cache.disk_cache()->open_count());
3101 EXPECT_EQ(1, cache.disk_cache()->create_count());
3102 RemoveMockTransaction(&transaction);
3105 // Tests that a HEAD request can be served from a partialy cached resource.
3106 TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3107 MockHttpCache cache;
3108 AddMockTransaction(&kRangeGET_TransactionOK);
3110 // Write to the cache (40-49).
3111 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3112 RemoveMockTransaction(&kRangeGET_TransactionOK);
3114 MockTransaction transaction(kSimpleGET_Transaction);
3116 transaction.url = kRangeGET_TransactionOK.url;
3117 transaction.method = "HEAD";
3118 transaction.data = "";
3119 AddMockTransaction(&transaction);
3120 std::string headers;
3122 // Load from cache.
3123 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3125 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3126 EXPECT_EQ(std::string::npos, headers.find("Content-Length"));
3127 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3128 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3129 EXPECT_EQ(1, cache.disk_cache()->open_count());
3130 EXPECT_EQ(1, cache.disk_cache()->create_count());
3131 RemoveMockTransaction(&transaction);
3134 // Tests that a HEAD request can be served from a truncated resource.
3135 TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3136 MockHttpCache cache;
3137 AddMockTransaction(&kRangeGET_TransactionOK);
3139 std::string raw_headers("HTTP/1.1 200 OK\n"
3140 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3141 "ETag: \"foo\"\n"
3142 "Accept-Ranges: bytes\n"
3143 "Content-Length: 80\n");
3144 CreateTruncatedEntry(raw_headers, &cache);
3145 RemoveMockTransaction(&kRangeGET_TransactionOK);
3147 MockTransaction transaction(kSimpleGET_Transaction);
3149 transaction.url = kRangeGET_TransactionOK.url;
3150 transaction.method = "HEAD";
3151 transaction.data = "";
3152 AddMockTransaction(&transaction);
3153 std::string headers;
3155 // Load from cache.
3156 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3158 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3159 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3160 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3161 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3162 EXPECT_EQ(1, cache.disk_cache()->open_count());
3163 EXPECT_EQ(1, cache.disk_cache()->create_count());
3164 RemoveMockTransaction(&transaction);
3167 // Tests that a HEAD request updates the cached response.
3168 TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3169 MockHttpCache cache;
3170 MockTransaction transaction(kTypicalGET_Transaction);
3171 AddMockTransaction(&transaction);
3173 // Populate the cache.
3174 RunTransactionTest(cache.http_cache(), transaction);
3176 // Update the cache.
3177 transaction.method = "HEAD";
3178 transaction.response_headers = "Foo: bar\n";
3179 transaction.data = "";
3180 transaction.status = "HTTP/1.1 304 Not Modified\n";
3181 std::string headers;
3182 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3183 RemoveMockTransaction(&transaction);
3185 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3186 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3188 MockTransaction transaction2(kTypicalGET_Transaction);
3189 AddMockTransaction(&transaction2);
3191 // Make sure we are done with the previous transaction.
3192 base::MessageLoop::current()->RunUntilIdle();
3194 // Load from the cache.
3195 transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3196 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3198 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3199 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3200 EXPECT_EQ(2, cache.disk_cache()->open_count());
3201 EXPECT_EQ(1, cache.disk_cache()->create_count());
3202 RemoveMockTransaction(&transaction2);
3205 // Tests that an externally conditionalized HEAD request updates the cache.
3206 TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3207 MockHttpCache cache;
3208 MockTransaction transaction(kTypicalGET_Transaction);
3209 AddMockTransaction(&transaction);
3211 // Populate the cache.
3212 RunTransactionTest(cache.http_cache(), transaction);
3214 // Update the cache.
3215 transaction.method = "HEAD";
3216 transaction.request_headers =
3217 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3218 transaction.response_headers = "Foo: bar\n";
3219 transaction.data = "";
3220 transaction.status = "HTTP/1.1 304 Not Modified\n";
3221 std::string headers;
3222 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3223 RemoveMockTransaction(&transaction);
3225 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3226 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3228 MockTransaction transaction2(kTypicalGET_Transaction);
3229 AddMockTransaction(&transaction2);
3231 // Make sure we are done with the previous transaction.
3232 base::MessageLoop::current()->RunUntilIdle();
3234 // Load from the cache.
3235 transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3236 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3238 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3239 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3240 EXPECT_EQ(2, cache.disk_cache()->open_count());
3241 EXPECT_EQ(1, cache.disk_cache()->create_count());
3242 RemoveMockTransaction(&transaction2);
3245 // Tests that a HEAD request invalidates an old cached entry.
3246 TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3247 MockHttpCache cache;
3248 MockTransaction transaction(kTypicalGET_Transaction);
3249 AddMockTransaction(&transaction);
3251 // Populate the cache.
3252 RunTransactionTest(cache.http_cache(), transaction);
3254 // Update the cache.
3255 transaction.method = "HEAD";
3256 transaction.data = "";
3257 RunTransactionTest(cache.http_cache(), transaction);
3258 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3260 // Load from the cache.
3261 transaction.method = "GET";
3262 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3263 transaction.return_code = net::ERR_CACHE_MISS;
3264 RunTransactionTest(cache.http_cache(), transaction);
3266 RemoveMockTransaction(&transaction);
3269 // Tests that we do not cache the response of a PUT.
3270 TEST(HttpCache, SimplePUT_Miss) {
3271 MockHttpCache cache;
3273 MockTransaction transaction(kSimplePOST_Transaction);
3274 transaction.method = "PUT";
3276 ScopedVector<net::UploadElementReader> element_readers;
3277 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3278 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3280 MockHttpRequest request(transaction);
3281 request.upload_data_stream = &upload_data_stream;
3283 // Attempt to populate the cache.
3284 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3286 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3287 EXPECT_EQ(0, cache.disk_cache()->open_count());
3288 EXPECT_EQ(0, cache.disk_cache()->create_count());
3291 // Tests that we invalidate entries as a result of a PUT.
3292 TEST(HttpCache, SimplePUT_Invalidate) {
3293 MockHttpCache cache;
3295 MockTransaction transaction(kSimpleGET_Transaction);
3296 MockHttpRequest req1(transaction);
3298 // Attempt to populate the cache.
3299 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3301 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3302 EXPECT_EQ(0, cache.disk_cache()->open_count());
3303 EXPECT_EQ(1, cache.disk_cache()->create_count());
3305 ScopedVector<net::UploadElementReader> element_readers;
3306 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3307 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3309 transaction.method = "PUT";
3310 MockHttpRequest req2(transaction);
3311 req2.upload_data_stream = &upload_data_stream;
3313 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3315 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3316 EXPECT_EQ(1, cache.disk_cache()->open_count());
3317 EXPECT_EQ(1, cache.disk_cache()->create_count());
3319 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3321 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3322 EXPECT_EQ(1, cache.disk_cache()->open_count());
3323 EXPECT_EQ(2, cache.disk_cache()->create_count());
3326 // Tests that we invalidate entries as a result of a PUT.
3327 TEST(HttpCache, SimplePUT_Invalidate_305) {
3328 MockHttpCache cache;
3330 MockTransaction transaction(kSimpleGET_Transaction);
3331 AddMockTransaction(&transaction);
3332 MockHttpRequest req1(transaction);
3334 // Attempt to populate the cache.
3335 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3337 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3338 EXPECT_EQ(0, cache.disk_cache()->open_count());
3339 EXPECT_EQ(1, cache.disk_cache()->create_count());
3341 ScopedVector<net::UploadElementReader> element_readers;
3342 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3343 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3345 transaction.method = "PUT";
3346 transaction.status = "HTTP/1.1 305 Use Proxy";
3347 MockHttpRequest req2(transaction);
3348 req2.upload_data_stream = &upload_data_stream;
3350 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3352 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3353 EXPECT_EQ(1, cache.disk_cache()->open_count());
3354 EXPECT_EQ(1, cache.disk_cache()->create_count());
3356 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3358 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3359 EXPECT_EQ(1, cache.disk_cache()->open_count());
3360 EXPECT_EQ(2, cache.disk_cache()->create_count());
3361 RemoveMockTransaction(&transaction);
3364 // Tests that we don't invalidate entries as a result of a failed PUT.
3365 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3366 MockHttpCache cache;
3368 MockTransaction transaction(kSimpleGET_Transaction);
3369 AddMockTransaction(&transaction);
3370 MockHttpRequest req1(transaction);
3372 // Attempt to populate the cache.
3373 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3375 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3376 EXPECT_EQ(0, cache.disk_cache()->open_count());
3377 EXPECT_EQ(1, cache.disk_cache()->create_count());
3379 ScopedVector<net::UploadElementReader> element_readers;
3380 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3381 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3383 transaction.method = "PUT";
3384 transaction.status = "HTTP/1.1 404 Not Found";
3385 MockHttpRequest req2(transaction);
3386 req2.upload_data_stream = &upload_data_stream;
3388 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3390 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3391 EXPECT_EQ(1, cache.disk_cache()->open_count());
3392 EXPECT_EQ(1, cache.disk_cache()->create_count());
3394 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3396 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3397 EXPECT_EQ(2, cache.disk_cache()->open_count());
3398 EXPECT_EQ(1, cache.disk_cache()->create_count());
3399 RemoveMockTransaction(&transaction);
3402 // Tests that we do not cache the response of a DELETE.
3403 TEST(HttpCache, SimpleDELETE_Miss) {
3404 MockHttpCache cache;
3406 MockTransaction transaction(kSimplePOST_Transaction);
3407 transaction.method = "DELETE";
3409 ScopedVector<net::UploadElementReader> element_readers;
3410 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3411 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3413 MockHttpRequest request(transaction);
3414 request.upload_data_stream = &upload_data_stream;
3416 // Attempt to populate the cache.
3417 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3419 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3420 EXPECT_EQ(0, cache.disk_cache()->open_count());
3421 EXPECT_EQ(0, cache.disk_cache()->create_count());
3424 // Tests that we invalidate entries as a result of a DELETE.
3425 TEST(HttpCache, SimpleDELETE_Invalidate) {
3426 MockHttpCache cache;
3428 MockTransaction transaction(kSimpleGET_Transaction);
3429 MockHttpRequest req1(transaction);
3431 // Attempt to populate the cache.
3432 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3434 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3435 EXPECT_EQ(0, cache.disk_cache()->open_count());
3436 EXPECT_EQ(1, cache.disk_cache()->create_count());
3438 ScopedVector<net::UploadElementReader> element_readers;
3439 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3440 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3442 transaction.method = "DELETE";
3443 MockHttpRequest req2(transaction);
3444 req2.upload_data_stream = &upload_data_stream;
3446 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3448 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3449 EXPECT_EQ(1, cache.disk_cache()->open_count());
3450 EXPECT_EQ(1, cache.disk_cache()->create_count());
3452 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3454 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3455 EXPECT_EQ(1, cache.disk_cache()->open_count());
3456 EXPECT_EQ(2, cache.disk_cache()->create_count());
3459 // Tests that we invalidate entries as a result of a DELETE.
3460 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3461 MockHttpCache cache;
3463 MockTransaction transaction(kSimpleGET_Transaction);
3464 AddMockTransaction(&transaction);
3466 // Attempt to populate the cache.
3467 RunTransactionTest(cache.http_cache(), transaction);
3469 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3470 EXPECT_EQ(0, cache.disk_cache()->open_count());
3471 EXPECT_EQ(1, cache.disk_cache()->create_count());
3473 transaction.method = "DELETE";
3474 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3476 RunTransactionTest(cache.http_cache(), transaction);
3478 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3479 EXPECT_EQ(1, cache.disk_cache()->open_count());
3480 EXPECT_EQ(1, cache.disk_cache()->create_count());
3482 transaction.method = "GET";
3483 RunTransactionTest(cache.http_cache(), transaction);
3485 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3486 EXPECT_EQ(1, cache.disk_cache()->open_count());
3487 EXPECT_EQ(2, cache.disk_cache()->create_count());
3488 RemoveMockTransaction(&transaction);
3491 // Tests that we don't invalidate entries as a result of a failed DELETE.
3492 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3493 MockHttpCache cache;
3495 MockTransaction transaction(kSimpleGET_Transaction);
3496 AddMockTransaction(&transaction);
3498 // Attempt to populate the cache.
3499 RunTransactionTest(cache.http_cache(), transaction);
3501 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3502 EXPECT_EQ(0, cache.disk_cache()->open_count());
3503 EXPECT_EQ(1, cache.disk_cache()->create_count());
3505 transaction.method = "DELETE";
3506 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3508 RunTransactionTest(cache.http_cache(), transaction);
3510 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3511 EXPECT_EQ(1, cache.disk_cache()->open_count());
3512 EXPECT_EQ(1, cache.disk_cache()->create_count());
3514 transaction.method = "GET";
3515 transaction.status = "HTTP/1.1 200 OK";
3516 RunTransactionTest(cache.http_cache(), transaction);
3518 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3519 EXPECT_EQ(2, cache.disk_cache()->open_count());
3520 EXPECT_EQ(1, cache.disk_cache()->create_count());
3521 RemoveMockTransaction(&transaction);
3524 // Tests that we don't invalidate entries after a failed network transaction.
3525 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3526 MockHttpCache cache;
3528 // Populate the cache.
3529 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3530 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3532 // Fail the network request.
3533 MockTransaction transaction(kSimpleGET_Transaction);
3534 transaction.return_code = net::ERR_FAILED;
3535 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3537 AddMockTransaction(&transaction);
3538 RunTransactionTest(cache.http_cache(), transaction);
3539 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3540 RemoveMockTransaction(&transaction);
3542 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3543 transaction.return_code = net::OK;
3544 AddMockTransaction(&transaction);
3545 RunTransactionTest(cache.http_cache(), transaction);
3547 // Make sure the transaction didn't reach the network.
3548 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3549 RemoveMockTransaction(&transaction);
3552 TEST(HttpCache, RangeGET_SkipsCache) {
3553 MockHttpCache cache;
3555 // Test that we skip the cache for range GET requests. Eventually, we will
3556 // want to cache these, but we'll still have cases where skipping the cache
3557 // makes sense, so we want to make sure that it works properly.
3559 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3561 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3562 EXPECT_EQ(0, cache.disk_cache()->open_count());
3563 EXPECT_EQ(0, cache.disk_cache()->create_count());
3565 MockTransaction transaction(kSimpleGET_Transaction);
3566 transaction.request_headers = "If-None-Match: foo\r\n";
3567 RunTransactionTest(cache.http_cache(), transaction);
3569 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3570 EXPECT_EQ(0, cache.disk_cache()->open_count());
3571 EXPECT_EQ(0, cache.disk_cache()->create_count());
3573 transaction.request_headers =
3574 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3575 RunTransactionTest(cache.http_cache(), transaction);
3577 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3578 EXPECT_EQ(0, cache.disk_cache()->open_count());
3579 EXPECT_EQ(0, cache.disk_cache()->create_count());
3582 // Test that we skip the cache for range requests that include a validation
3583 // header.
3584 TEST(HttpCache, RangeGET_SkipsCache2) {
3585 MockHttpCache cache;
3587 MockTransaction transaction(kRangeGET_Transaction);
3588 transaction.request_headers = "If-None-Match: foo\r\n"
3589 EXTRA_HEADER
3590 "Range: bytes = 40-49\r\n";
3591 RunTransactionTest(cache.http_cache(), transaction);
3593 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3594 EXPECT_EQ(0, cache.disk_cache()->open_count());
3595 EXPECT_EQ(0, cache.disk_cache()->create_count());
3597 transaction.request_headers =
3598 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3599 EXTRA_HEADER
3600 "Range: bytes = 40-49\r\n";
3601 RunTransactionTest(cache.http_cache(), transaction);
3603 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3604 EXPECT_EQ(0, cache.disk_cache()->open_count());
3605 EXPECT_EQ(0, cache.disk_cache()->create_count());
3607 transaction.request_headers = "If-Range: bla\r\n"
3608 EXTRA_HEADER
3609 "Range: bytes = 40-49\r\n";
3610 RunTransactionTest(cache.http_cache(), transaction);
3612 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3613 EXPECT_EQ(0, cache.disk_cache()->open_count());
3614 EXPECT_EQ(0, cache.disk_cache()->create_count());
3617 // Tests that receiving 206 for a regular request is handled correctly.
3618 TEST(HttpCache, GET_Crazy206) {
3619 MockHttpCache cache;
3621 // Write to the cache.
3622 MockTransaction transaction(kRangeGET_TransactionOK);
3623 AddMockTransaction(&transaction);
3624 transaction.request_headers = EXTRA_HEADER;
3625 transaction.handler = NULL;
3626 RunTransactionTest(cache.http_cache(), transaction);
3628 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3629 EXPECT_EQ(0, cache.disk_cache()->open_count());
3630 EXPECT_EQ(1, cache.disk_cache()->create_count());
3632 // This should read again from the net.
3633 RunTransactionTest(cache.http_cache(), transaction);
3635 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3636 EXPECT_EQ(0, cache.disk_cache()->open_count());
3637 EXPECT_EQ(2, cache.disk_cache()->create_count());
3638 RemoveMockTransaction(&transaction);
3641 // Tests that receiving 416 for a regular request is handled correctly.
3642 TEST(HttpCache, GET_Crazy416) {
3643 MockHttpCache cache;
3645 // Write to the cache.
3646 MockTransaction transaction(kSimpleGET_Transaction);
3647 AddMockTransaction(&transaction);
3648 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3649 RunTransactionTest(cache.http_cache(), transaction);
3651 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3652 EXPECT_EQ(0, cache.disk_cache()->open_count());
3653 EXPECT_EQ(1, cache.disk_cache()->create_count());
3655 RemoveMockTransaction(&transaction);
3658 // Tests that we store partial responses that can't be validated, as they can
3659 // be used for requests that don't require revalidation.
3660 TEST(HttpCache, RangeGET_NoStrongValidators) {
3661 MockHttpCache cache;
3662 std::string headers;
3664 // Write to the cache (40-49).
3665 MockTransaction transaction(kRangeGET_TransactionOK);
3666 AddMockTransaction(&transaction);
3667 transaction.response_headers = "Content-Length: 10\n"
3668 "Cache-Control: max-age=3600\n"
3669 "ETag: w/\"foo\"\n";
3670 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3672 Verify206Response(headers, 40, 49);
3673 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3674 EXPECT_EQ(0, cache.disk_cache()->open_count());
3675 EXPECT_EQ(1, cache.disk_cache()->create_count());
3677 // Now verify that there's cached data.
3678 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3679 &headers);
3681 Verify206Response(headers, 40, 49);
3682 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3683 EXPECT_EQ(1, cache.disk_cache()->open_count());
3684 EXPECT_EQ(1, cache.disk_cache()->create_count());
3686 RemoveMockTransaction(&transaction);
3689 // Tests failures to validate cache partial responses that lack strong
3690 // validators.
3691 TEST(HttpCache, RangeGET_NoValidation) {
3692 MockHttpCache cache;
3693 std::string headers;
3695 // Write to the cache (40-49).
3696 MockTransaction transaction(kRangeGET_TransactionOK);
3697 AddMockTransaction(&transaction);
3698 transaction.response_headers = "Content-Length: 10\n"
3699 "ETag: w/\"foo\"\n";
3700 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3702 Verify206Response(headers, 40, 49);
3703 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3704 EXPECT_EQ(0, cache.disk_cache()->open_count());
3705 EXPECT_EQ(1, cache.disk_cache()->create_count());
3707 // Now verify that the cached data is not used.
3708 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3709 &headers);
3711 Verify206Response(headers, 40, 49);
3712 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3713 EXPECT_EQ(1, cache.disk_cache()->open_count());
3714 EXPECT_EQ(2, cache.disk_cache()->create_count());
3716 RemoveMockTransaction(&transaction);
3719 // Tests that we cache partial responses that lack content-length.
3720 TEST(HttpCache, RangeGET_NoContentLength) {
3721 MockHttpCache cache;
3722 std::string headers;
3724 // Attempt to write to the cache (40-49).
3725 MockTransaction transaction(kRangeGET_TransactionOK);
3726 AddMockTransaction(&transaction);
3727 transaction.response_headers = "ETag: \"foo\"\n"
3728 "Accept-Ranges: bytes\n"
3729 "Content-Range: bytes 40-49/80\n";
3730 transaction.handler = NULL;
3731 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3733 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3734 EXPECT_EQ(0, cache.disk_cache()->open_count());
3735 EXPECT_EQ(1, cache.disk_cache()->create_count());
3737 // Now verify that there's no cached data.
3738 transaction.handler = &RangeTransactionServer::RangeHandler;
3739 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3740 &headers);
3742 Verify206Response(headers, 40, 49);
3743 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3744 EXPECT_EQ(1, cache.disk_cache()->open_count());
3745 EXPECT_EQ(1, cache.disk_cache()->create_count());
3747 RemoveMockTransaction(&transaction);
3750 // Tests that we can cache range requests and fetch random blocks from the
3751 // cache and the network.
3752 TEST(HttpCache, RangeGET_OK) {
3753 MockHttpCache cache;
3754 AddMockTransaction(&kRangeGET_TransactionOK);
3755 std::string headers;
3757 // Write to the cache (40-49).
3758 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3759 &headers);
3761 Verify206Response(headers, 40, 49);
3762 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3763 EXPECT_EQ(0, cache.disk_cache()->open_count());
3764 EXPECT_EQ(1, cache.disk_cache()->create_count());
3766 // Read from the cache (40-49).
3767 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3768 &headers);
3770 Verify206Response(headers, 40, 49);
3771 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3772 EXPECT_EQ(1, cache.disk_cache()->open_count());
3773 EXPECT_EQ(1, cache.disk_cache()->create_count());
3775 // Make sure we are done with the previous transaction.
3776 base::MessageLoop::current()->RunUntilIdle();
3778 // Write to the cache (30-39).
3779 MockTransaction transaction(kRangeGET_TransactionOK);
3780 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3781 transaction.data = "rg: 30-39 ";
3782 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3784 Verify206Response(headers, 30, 39);
3785 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3786 EXPECT_EQ(2, cache.disk_cache()->open_count());
3787 EXPECT_EQ(1, cache.disk_cache()->create_count());
3789 // Make sure we are done with the previous transaction.
3790 base::MessageLoop::current()->RunUntilIdle();
3792 // Write and read from the cache (20-59).
3793 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3794 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3795 net::CapturingBoundNetLog log;
3796 net::LoadTimingInfo load_timing_info;
3797 RunTransactionTestWithResponseAndGetTiming(
3798 cache.http_cache(), transaction, &headers, log.bound(),
3799 &load_timing_info);
3801 Verify206Response(headers, 20, 59);
3802 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3803 EXPECT_EQ(3, cache.disk_cache()->open_count());
3804 EXPECT_EQ(1, cache.disk_cache()->create_count());
3805 TestLoadTimingNetworkRequest(load_timing_info);
3807 RemoveMockTransaction(&kRangeGET_TransactionOK);
3810 // Checks that with a cache backend having Sparse IO unimplementes the cache
3811 // entry would be doomed after a range request.
3812 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3813 TEST(HttpCache, RangeGET_SparseNotImplemented) {
3814 MockHttpCache cache;
3815 cache.disk_cache()->set_fail_sparse_requests();
3817 // Run a cacheable request to prime the cache.
3818 MockTransaction transaction(kTypicalGET_Transaction);
3819 transaction.url = kRangeGET_TransactionOK.url;
3820 AddMockTransaction(&transaction);
3821 RunTransactionTest(cache.http_cache(), transaction);
3822 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3823 EXPECT_EQ(0, cache.disk_cache()->open_count());
3824 EXPECT_EQ(1, cache.disk_cache()->create_count());
3826 // Verify that we added the entry.
3827 disk_cache::Entry* entry;
3828 net::TestCompletionCallback cb;
3829 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3830 &entry,
3831 cb.callback());
3832 ASSERT_EQ(net::OK, cb.GetResult(rv));
3833 EXPECT_EQ(1, cache.disk_cache()->open_count());
3834 entry->Close();
3835 RemoveMockTransaction(&transaction);
3837 // Request the range with the backend that does not support it.
3838 MockTransaction transaction2(kRangeGET_TransactionOK);
3839 std::string headers;
3840 AddMockTransaction(&transaction2);
3841 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3842 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3843 EXPECT_EQ(2, cache.disk_cache()->open_count());
3844 EXPECT_EQ(2, cache.disk_cache()->create_count());
3846 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3847 // if it was re-created later, so this effectively checks that the old data is
3848 // gone.
3849 disk_cache::Entry* entry2;
3850 rv = cache.disk_cache()->OpenEntry(transaction2.url,
3851 &entry2,
3852 cb.callback());
3853 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3854 RemoveMockTransaction(&transaction2);
3857 TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3858 MockHttpCache cache;
3859 cache.disk_cache()->set_fail_sparse_requests();
3861 // Request the range with the backend that does not support it.
3862 MockTransaction transaction(kRangeGET_TransactionOK);
3863 std::string headers;
3864 AddMockTransaction(&transaction);
3865 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3866 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3867 EXPECT_EQ(0, cache.disk_cache()->open_count());
3868 EXPECT_EQ(1, cache.disk_cache()->create_count());
3870 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3871 // if it was re-created later, so this effectively checks that the old data is
3872 // gone as a result of a failed range write.
3873 disk_cache::Entry* entry;
3874 net::TestCompletionCallback cb;
3875 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3876 &entry,
3877 cb.callback());
3878 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3879 RemoveMockTransaction(&transaction);
3882 // Tests that we can cache range requests and fetch random blocks from the
3883 // cache and the network, with synchronous responses.
3884 TEST(HttpCache, RangeGET_SyncOK) {
3885 MockHttpCache cache;
3887 MockTransaction transaction(kRangeGET_TransactionOK);
3888 transaction.test_mode = TEST_MODE_SYNC_ALL;
3889 AddMockTransaction(&transaction);
3891 // Write to the cache (40-49).
3892 std::string headers;
3893 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3895 Verify206Response(headers, 40, 49);
3896 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3897 EXPECT_EQ(0, cache.disk_cache()->open_count());
3898 EXPECT_EQ(1, cache.disk_cache()->create_count());
3900 // Read from the cache (40-49).
3901 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3903 Verify206Response(headers, 40, 49);
3904 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3905 EXPECT_EQ(0, cache.disk_cache()->open_count());
3906 EXPECT_EQ(1, cache.disk_cache()->create_count());
3908 // Make sure we are done with the previous transaction.
3909 base::MessageLoop::current()->RunUntilIdle();
3911 // Write to the cache (30-39).
3912 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3913 transaction.data = "rg: 30-39 ";
3914 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3916 Verify206Response(headers, 30, 39);
3917 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3918 EXPECT_EQ(1, cache.disk_cache()->open_count());
3919 EXPECT_EQ(1, cache.disk_cache()->create_count());
3921 // Make sure we are done with the previous transaction.
3922 base::MessageLoop::current()->RunUntilIdle();
3924 // Write and read from the cache (20-59).
3925 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3926 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3927 net::CapturingBoundNetLog log;
3928 net::LoadTimingInfo load_timing_info;
3929 RunTransactionTestWithResponseAndGetTiming(
3930 cache.http_cache(), transaction, &headers, log.bound(),
3931 &load_timing_info);
3933 Verify206Response(headers, 20, 59);
3934 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3935 EXPECT_EQ(2, cache.disk_cache()->open_count());
3936 EXPECT_EQ(1, cache.disk_cache()->create_count());
3937 TestLoadTimingNetworkRequest(load_timing_info);
3939 RemoveMockTransaction(&transaction);
3942 // Tests that we don't revalidate an entry unless we are required to do so.
3943 TEST(HttpCache, RangeGET_Revalidate1) {
3944 MockHttpCache cache;
3945 std::string headers;
3947 // Write to the cache (40-49).
3948 MockTransaction transaction(kRangeGET_TransactionOK);
3949 transaction.response_headers =
3950 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3951 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3952 "ETag: \"foo\"\n"
3953 "Accept-Ranges: bytes\n"
3954 "Content-Length: 10\n";
3955 AddMockTransaction(&transaction);
3956 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3958 Verify206Response(headers, 40, 49);
3959 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3960 EXPECT_EQ(0, cache.disk_cache()->open_count());
3961 EXPECT_EQ(1, cache.disk_cache()->create_count());
3963 // Read from the cache (40-49).
3964 net::CapturingBoundNetLog log;
3965 net::LoadTimingInfo load_timing_info;
3966 RunTransactionTestWithResponseAndGetTiming(
3967 cache.http_cache(), transaction, &headers, log.bound(),
3968 &load_timing_info);
3970 Verify206Response(headers, 40, 49);
3971 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3972 EXPECT_EQ(1, cache.disk_cache()->open_count());
3973 EXPECT_EQ(1, cache.disk_cache()->create_count());
3974 TestLoadTimingCachedResponse(load_timing_info);
3976 // Read again forcing the revalidation.
3977 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3978 RunTransactionTestWithResponseAndGetTiming(
3979 cache.http_cache(), transaction, &headers, log.bound(),
3980 &load_timing_info);
3982 Verify206Response(headers, 40, 49);
3983 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3984 EXPECT_EQ(1, cache.disk_cache()->open_count());
3985 EXPECT_EQ(1, cache.disk_cache()->create_count());
3986 TestLoadTimingNetworkRequest(load_timing_info);
3988 RemoveMockTransaction(&transaction);
3991 // Checks that we revalidate an entry when the headers say so.
3992 TEST(HttpCache, RangeGET_Revalidate2) {
3993 MockHttpCache cache;
3994 std::string headers;
3996 // Write to the cache (40-49).
3997 MockTransaction transaction(kRangeGET_TransactionOK);
3998 transaction.response_headers =
3999 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4000 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4001 "ETag: \"foo\"\n"
4002 "Accept-Ranges: bytes\n"
4003 "Content-Length: 10\n";
4004 AddMockTransaction(&transaction);
4005 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4007 Verify206Response(headers, 40, 49);
4008 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4009 EXPECT_EQ(0, cache.disk_cache()->open_count());
4010 EXPECT_EQ(1, cache.disk_cache()->create_count());
4012 // Read from the cache (40-49).
4013 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4014 Verify206Response(headers, 40, 49);
4016 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4017 EXPECT_EQ(1, cache.disk_cache()->open_count());
4018 EXPECT_EQ(1, cache.disk_cache()->create_count());
4020 RemoveMockTransaction(&transaction);
4023 // Tests that we deal with 304s for range requests.
4024 TEST(HttpCache, RangeGET_304) {
4025 MockHttpCache cache;
4026 AddMockTransaction(&kRangeGET_TransactionOK);
4027 std::string headers;
4029 // Write to the cache (40-49).
4030 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4031 &headers);
4033 Verify206Response(headers, 40, 49);
4034 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4035 EXPECT_EQ(0, cache.disk_cache()->open_count());
4036 EXPECT_EQ(1, cache.disk_cache()->create_count());
4038 // Read from the cache (40-49).
4039 RangeTransactionServer handler;
4040 handler.set_not_modified(true);
4041 MockTransaction transaction(kRangeGET_TransactionOK);
4042 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4043 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4045 Verify206Response(headers, 40, 49);
4046 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4047 EXPECT_EQ(1, cache.disk_cache()->open_count());
4048 EXPECT_EQ(1, cache.disk_cache()->create_count());
4050 RemoveMockTransaction(&kRangeGET_TransactionOK);
4053 // Tests that we deal with 206s when revalidating range requests.
4054 TEST(HttpCache, RangeGET_ModifiedResult) {
4055 MockHttpCache cache;
4056 AddMockTransaction(&kRangeGET_TransactionOK);
4057 std::string headers;
4059 // Write to the cache (40-49).
4060 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4061 &headers);
4063 Verify206Response(headers, 40, 49);
4064 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4065 EXPECT_EQ(0, cache.disk_cache()->open_count());
4066 EXPECT_EQ(1, cache.disk_cache()->create_count());
4068 // Attempt to read from the cache (40-49).
4069 RangeTransactionServer handler;
4070 handler.set_modified(true);
4071 MockTransaction transaction(kRangeGET_TransactionOK);
4072 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4073 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4075 Verify206Response(headers, 40, 49);
4076 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4077 EXPECT_EQ(1, cache.disk_cache()->open_count());
4078 EXPECT_EQ(1, cache.disk_cache()->create_count());
4080 // And the entry should be gone.
4081 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4082 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4083 EXPECT_EQ(1, cache.disk_cache()->open_count());
4084 EXPECT_EQ(2, cache.disk_cache()->create_count());
4086 RemoveMockTransaction(&kRangeGET_TransactionOK);
4089 // Tests that we cache 301s for range requests.
4090 TEST(HttpCache, RangeGET_301) {
4091 MockHttpCache cache;
4092 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4093 transaction.status = "HTTP/1.1 301 Moved Permanently";
4094 transaction.response_headers = "Location: http://www.bar.com/\n";
4095 transaction.data = "";
4096 transaction.handler = NULL;
4097 AddMockTransaction(&transaction);
4099 // Write to the cache.
4100 RunTransactionTest(cache.http_cache(), transaction);
4101 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4102 EXPECT_EQ(0, cache.disk_cache()->open_count());
4103 EXPECT_EQ(1, cache.disk_cache()->create_count());
4105 // Read from the cache.
4106 RunTransactionTest(cache.http_cache(), transaction);
4107 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4108 EXPECT_EQ(1, cache.disk_cache()->open_count());
4109 EXPECT_EQ(1, cache.disk_cache()->create_count());
4111 RemoveMockTransaction(&transaction);
4114 // Tests that we can cache range requests when the start or end is unknown.
4115 // We start with one suffix request, followed by a request from a given point.
4116 TEST(HttpCache, UnknownRangeGET_1) {
4117 MockHttpCache cache;
4118 AddMockTransaction(&kRangeGET_TransactionOK);
4119 std::string headers;
4121 // Write to the cache (70-79).
4122 MockTransaction transaction(kRangeGET_TransactionOK);
4123 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4124 transaction.data = "rg: 70-79 ";
4125 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4127 Verify206Response(headers, 70, 79);
4128 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4129 EXPECT_EQ(0, cache.disk_cache()->open_count());
4130 EXPECT_EQ(1, cache.disk_cache()->create_count());
4132 // Make sure we are done with the previous transaction.
4133 base::MessageLoop::current()->RunUntilIdle();
4135 // Write and read from the cache (60-79).
4136 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
4137 transaction.data = "rg: 60-69 rg: 70-79 ";
4138 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4140 Verify206Response(headers, 60, 79);
4141 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4142 EXPECT_EQ(1, cache.disk_cache()->open_count());
4143 EXPECT_EQ(1, cache.disk_cache()->create_count());
4145 RemoveMockTransaction(&kRangeGET_TransactionOK);
4148 // Tests that we can cache range requests when the start or end is unknown.
4149 // We start with one request from a given point, followed by a suffix request.
4150 // We'll also verify that synchronous cache responses work as intended.
4151 TEST(HttpCache, UnknownRangeGET_2) {
4152 MockHttpCache cache;
4153 std::string headers;
4155 MockTransaction transaction(kRangeGET_TransactionOK);
4156 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
4157 TEST_MODE_SYNC_CACHE_READ |
4158 TEST_MODE_SYNC_CACHE_WRITE;
4159 AddMockTransaction(&transaction);
4161 // Write to the cache (70-79).
4162 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4163 transaction.data = "rg: 70-79 ";
4164 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4166 Verify206Response(headers, 70, 79);
4167 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4168 EXPECT_EQ(0, cache.disk_cache()->open_count());
4169 EXPECT_EQ(1, cache.disk_cache()->create_count());
4171 // Make sure we are done with the previous transaction.
4172 base::MessageLoop::current()->RunUntilIdle();
4174 // Write and read from the cache (60-79).
4175 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
4176 transaction.data = "rg: 60-69 rg: 70-79 ";
4177 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4179 Verify206Response(headers, 60, 79);
4180 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4181 EXPECT_EQ(1, cache.disk_cache()->open_count());
4182 EXPECT_EQ(1, cache.disk_cache()->create_count());
4184 RemoveMockTransaction(&transaction);
4187 // Tests that receiving Not Modified when asking for an open range doesn't mess
4188 // up things.
4189 TEST(HttpCache, UnknownRangeGET_304) {
4190 MockHttpCache cache;
4191 std::string headers;
4193 MockTransaction transaction(kRangeGET_TransactionOK);
4194 AddMockTransaction(&transaction);
4196 RangeTransactionServer handler;
4197 handler.set_not_modified(true);
4199 // Ask for the end of the file, without knowing the length.
4200 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4201 transaction.data = "";
4202 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4204 // We just bypass the cache.
4205 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4206 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4207 EXPECT_EQ(0, cache.disk_cache()->open_count());
4208 EXPECT_EQ(1, cache.disk_cache()->create_count());
4210 RunTransactionTest(cache.http_cache(), transaction);
4211 EXPECT_EQ(2, cache.disk_cache()->create_count());
4213 RemoveMockTransaction(&transaction);
4216 // Tests that we can handle non-range requests when we have cached a range.
4217 TEST(HttpCache, GET_Previous206) {
4218 MockHttpCache cache;
4219 AddMockTransaction(&kRangeGET_TransactionOK);
4220 std::string headers;
4221 net::CapturingBoundNetLog log;
4222 net::LoadTimingInfo load_timing_info;
4224 // Write to the cache (40-49).
4225 RunTransactionTestWithResponseAndGetTiming(
4226 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4227 &load_timing_info);
4229 Verify206Response(headers, 40, 49);
4230 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4231 EXPECT_EQ(0, cache.disk_cache()->open_count());
4232 EXPECT_EQ(1, cache.disk_cache()->create_count());
4233 TestLoadTimingNetworkRequest(load_timing_info);
4235 // Write and read from the cache (0-79), when not asked for a range.
4236 MockTransaction transaction(kRangeGET_TransactionOK);
4237 transaction.request_headers = EXTRA_HEADER;
4238 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4239 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4240 RunTransactionTestWithResponseAndGetTiming(
4241 cache.http_cache(), transaction, &headers, log.bound(),
4242 &load_timing_info);
4244 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4245 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4246 EXPECT_EQ(1, cache.disk_cache()->open_count());
4247 EXPECT_EQ(1, cache.disk_cache()->create_count());
4248 TestLoadTimingNetworkRequest(load_timing_info);
4250 RemoveMockTransaction(&kRangeGET_TransactionOK);
4253 // Tests that we can handle non-range requests when we have cached the first
4254 // part of the object and the server replies with 304 (Not Modified).
4255 TEST(HttpCache, GET_Previous206_NotModified) {
4256 MockHttpCache cache;
4258 MockTransaction transaction(kRangeGET_TransactionOK);
4259 AddMockTransaction(&transaction);
4260 std::string headers;
4261 net::CapturingBoundNetLog log;
4262 net::LoadTimingInfo load_timing_info;
4264 // Write to the cache (0-9).
4265 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4266 transaction.data = "rg: 00-09 ";
4267 RunTransactionTestWithResponseAndGetTiming(
4268 cache.http_cache(), transaction, &headers, log.bound(),
4269 &load_timing_info);
4270 Verify206Response(headers, 0, 9);
4271 TestLoadTimingNetworkRequest(load_timing_info);
4273 // Write to the cache (70-79).
4274 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4275 transaction.data = "rg: 70-79 ";
4276 RunTransactionTestWithResponseAndGetTiming(
4277 cache.http_cache(), transaction, &headers, log.bound(),
4278 &load_timing_info);
4279 Verify206Response(headers, 70, 79);
4281 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4282 EXPECT_EQ(1, cache.disk_cache()->open_count());
4283 EXPECT_EQ(1, cache.disk_cache()->create_count());
4284 TestLoadTimingNetworkRequest(load_timing_info);
4286 // Read from the cache (0-9), write and read from cache (10 - 79).
4287 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4288 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
4289 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4290 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4291 RunTransactionTestWithResponseAndGetTiming(
4292 cache.http_cache(), transaction, &headers, log.bound(),
4293 &load_timing_info);
4295 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4296 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4297 EXPECT_EQ(2, cache.disk_cache()->open_count());
4298 EXPECT_EQ(1, cache.disk_cache()->create_count());
4299 TestLoadTimingNetworkRequest(load_timing_info);
4301 RemoveMockTransaction(&transaction);
4304 // Tests that we can handle a regular request to a sparse entry, that results in
4305 // new content provided by the server (206).
4306 TEST(HttpCache, GET_Previous206_NewContent) {
4307 MockHttpCache cache;
4308 AddMockTransaction(&kRangeGET_TransactionOK);
4309 std::string headers;
4311 // Write to the cache (0-9).
4312 MockTransaction transaction(kRangeGET_TransactionOK);
4313 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4314 transaction.data = "rg: 00-09 ";
4315 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4317 Verify206Response(headers, 0, 9);
4318 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4319 EXPECT_EQ(0, cache.disk_cache()->open_count());
4320 EXPECT_EQ(1, cache.disk_cache()->create_count());
4322 // Now we'll issue a request without any range that should result first in a
4323 // 206 (when revalidating), and then in a weird standard answer: the test
4324 // server will not modify the response so we'll get the default range... a
4325 // real server will answer with 200.
4326 MockTransaction transaction2(kRangeGET_TransactionOK);
4327 transaction2.request_headers = EXTRA_HEADER;
4328 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
4329 transaction2.data = "Not a range";
4330 RangeTransactionServer handler;
4331 handler.set_modified(true);
4332 net::CapturingBoundNetLog log;
4333 net::LoadTimingInfo load_timing_info;
4334 RunTransactionTestWithResponseAndGetTiming(
4335 cache.http_cache(), transaction2, &headers, log.bound(),
4336 &load_timing_info);
4338 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4339 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4340 EXPECT_EQ(1, cache.disk_cache()->open_count());
4341 EXPECT_EQ(1, cache.disk_cache()->create_count());
4342 TestLoadTimingNetworkRequest(load_timing_info);
4344 // Verify that the previous request deleted the entry.
4345 RunTransactionTest(cache.http_cache(), transaction);
4346 EXPECT_EQ(2, cache.disk_cache()->create_count());
4348 RemoveMockTransaction(&transaction);
4351 // Tests that we can handle cached 206 responses that are not sparse.
4352 TEST(HttpCache, GET_Previous206_NotSparse) {
4353 MockHttpCache cache;
4355 // Create a disk cache entry that stores 206 headers while not being sparse.
4356 disk_cache::Entry* entry;
4357 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4358 NULL));
4360 std::string raw_headers(kRangeGET_TransactionOK.status);
4361 raw_headers.append("\n");
4362 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4363 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4364 raw_headers.size());
4366 net::HttpResponseInfo response;
4367 response.headers = new net::HttpResponseHeaders(raw_headers);
4368 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4370 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4371 int len = static_cast<int>(base::strlcpy(buf->data(),
4372 kRangeGET_TransactionOK.data, 500));
4373 net::TestCompletionCallback cb;
4374 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4375 EXPECT_EQ(len, cb.GetResult(rv));
4376 entry->Close();
4378 // Now see that we don't use the stored entry.
4379 std::string headers;
4380 net::CapturingBoundNetLog log;
4381 net::LoadTimingInfo load_timing_info;
4382 RunTransactionTestWithResponseAndGetTiming(
4383 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4384 &load_timing_info);
4386 // We are expecting a 200.
4387 std::string expected_headers(kSimpleGET_Transaction.status);
4388 expected_headers.append("\n");
4389 expected_headers.append(kSimpleGET_Transaction.response_headers);
4390 EXPECT_EQ(expected_headers, headers);
4391 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4392 EXPECT_EQ(1, cache.disk_cache()->open_count());
4393 EXPECT_EQ(2, cache.disk_cache()->create_count());
4394 TestLoadTimingNetworkRequest(load_timing_info);
4397 // Tests that we can handle cached 206 responses that are not sparse. This time
4398 // we issue a range request and expect to receive a range.
4399 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4400 MockHttpCache cache;
4401 AddMockTransaction(&kRangeGET_TransactionOK);
4403 // Create a disk cache entry that stores 206 headers while not being sparse.
4404 disk_cache::Entry* entry;
4405 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4406 NULL));
4408 std::string raw_headers(kRangeGET_TransactionOK.status);
4409 raw_headers.append("\n");
4410 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4411 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4412 raw_headers.size());
4414 net::HttpResponseInfo response;
4415 response.headers = new net::HttpResponseHeaders(raw_headers);
4416 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4418 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4419 int len = static_cast<int>(base::strlcpy(buf->data(),
4420 kRangeGET_TransactionOK.data, 500));
4421 net::TestCompletionCallback cb;
4422 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4423 EXPECT_EQ(len, cb.GetResult(rv));
4424 entry->Close();
4426 // Now see that we don't use the stored entry.
4427 std::string headers;
4428 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4429 &headers);
4431 // We are expecting a 206.
4432 Verify206Response(headers, 40, 49);
4433 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4434 EXPECT_EQ(1, cache.disk_cache()->open_count());
4435 EXPECT_EQ(2, cache.disk_cache()->create_count());
4437 RemoveMockTransaction(&kRangeGET_TransactionOK);
4440 // Tests that we can handle cached 206 responses that can't be validated.
4441 TEST(HttpCache, GET_Previous206_NotValidation) {
4442 MockHttpCache cache;
4444 // Create a disk cache entry that stores 206 headers.
4445 disk_cache::Entry* entry;
4446 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4447 NULL));
4449 // Make sure that the headers cannot be validated with the server.
4450 std::string raw_headers(kRangeGET_TransactionOK.status);
4451 raw_headers.append("\n");
4452 raw_headers.append("Content-Length: 80\n");
4453 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4454 raw_headers.size());
4456 net::HttpResponseInfo response;
4457 response.headers = new net::HttpResponseHeaders(raw_headers);
4458 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4460 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4461 int len = static_cast<int>(base::strlcpy(buf->data(),
4462 kRangeGET_TransactionOK.data, 500));
4463 net::TestCompletionCallback cb;
4464 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4465 EXPECT_EQ(len, cb.GetResult(rv));
4466 entry->Close();
4468 // Now see that we don't use the stored entry.
4469 std::string headers;
4470 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4471 &headers);
4473 // We are expecting a 200.
4474 std::string expected_headers(kSimpleGET_Transaction.status);
4475 expected_headers.append("\n");
4476 expected_headers.append(kSimpleGET_Transaction.response_headers);
4477 EXPECT_EQ(expected_headers, headers);
4478 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4479 EXPECT_EQ(1, cache.disk_cache()->open_count());
4480 EXPECT_EQ(2, cache.disk_cache()->create_count());
4483 // Tests that we can handle range requests with cached 200 responses.
4484 TEST(HttpCache, RangeGET_Previous200) {
4485 MockHttpCache cache;
4487 // Store the whole thing with status 200.
4488 MockTransaction transaction(kTypicalGET_Transaction);
4489 transaction.url = kRangeGET_TransactionOK.url;
4490 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4491 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4492 AddMockTransaction(&transaction);
4493 RunTransactionTest(cache.http_cache(), transaction);
4494 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4495 EXPECT_EQ(0, cache.disk_cache()->open_count());
4496 EXPECT_EQ(1, cache.disk_cache()->create_count());
4498 RemoveMockTransaction(&transaction);
4499 AddMockTransaction(&kRangeGET_TransactionOK);
4501 // Now see that we use the stored entry.
4502 std::string headers;
4503 MockTransaction transaction2(kRangeGET_TransactionOK);
4504 RangeTransactionServer handler;
4505 handler.set_not_modified(true);
4506 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4508 // We are expecting a 206.
4509 Verify206Response(headers, 40, 49);
4510 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4511 EXPECT_EQ(1, cache.disk_cache()->open_count());
4512 EXPECT_EQ(1, cache.disk_cache()->create_count());
4514 // The last transaction has finished so make sure the entry is deactivated.
4515 base::MessageLoop::current()->RunUntilIdle();
4517 // Make a request for an invalid range.
4518 MockTransaction transaction3(kRangeGET_TransactionOK);
4519 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4520 transaction3.data = transaction.data;
4521 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4522 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4523 EXPECT_EQ(2, cache.disk_cache()->open_count());
4524 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4525 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4526 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4528 // Make sure the entry is deactivated.
4529 base::MessageLoop::current()->RunUntilIdle();
4531 // Even though the request was invalid, we should have the entry.
4532 RunTransactionTest(cache.http_cache(), transaction2);
4533 EXPECT_EQ(3, cache.disk_cache()->open_count());
4535 // Make sure the entry is deactivated.
4536 base::MessageLoop::current()->RunUntilIdle();
4538 // Now we should receive a range from the server and drop the stored entry.
4539 handler.set_not_modified(false);
4540 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4541 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4542 Verify206Response(headers, 40, 49);
4543 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4544 EXPECT_EQ(4, cache.disk_cache()->open_count());
4545 EXPECT_EQ(1, cache.disk_cache()->create_count());
4547 RunTransactionTest(cache.http_cache(), transaction2);
4548 EXPECT_EQ(2, cache.disk_cache()->create_count());
4550 RemoveMockTransaction(&kRangeGET_TransactionOK);
4553 // Tests that we can handle a 200 response when dealing with sparse entries.
4554 TEST(HttpCache, RangeRequestResultsIn200) {
4555 MockHttpCache cache;
4556 AddMockTransaction(&kRangeGET_TransactionOK);
4557 std::string headers;
4559 // Write to the cache (70-79).
4560 MockTransaction transaction(kRangeGET_TransactionOK);
4561 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4562 transaction.data = "rg: 70-79 ";
4563 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4565 Verify206Response(headers, 70, 79);
4566 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4567 EXPECT_EQ(0, cache.disk_cache()->open_count());
4568 EXPECT_EQ(1, cache.disk_cache()->create_count());
4570 // Now we'll issue a request that results in a plain 200 response, but to
4571 // the to the same URL that we used to store sparse data, and making sure
4572 // that we ask for a range.
4573 RemoveMockTransaction(&kRangeGET_TransactionOK);
4574 MockTransaction transaction2(kSimpleGET_Transaction);
4575 transaction2.url = kRangeGET_TransactionOK.url;
4576 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4577 AddMockTransaction(&transaction2);
4579 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4581 std::string expected_headers(kSimpleGET_Transaction.status);
4582 expected_headers.append("\n");
4583 expected_headers.append(kSimpleGET_Transaction.response_headers);
4584 EXPECT_EQ(expected_headers, headers);
4585 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4586 EXPECT_EQ(1, cache.disk_cache()->open_count());
4587 EXPECT_EQ(1, cache.disk_cache()->create_count());
4589 RemoveMockTransaction(&transaction2);
4592 // Tests that a range request that falls outside of the size that we know about
4593 // only deletes the entry if the resource has indeed changed.
4594 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4595 MockHttpCache cache;
4596 AddMockTransaction(&kRangeGET_TransactionOK);
4597 std::string headers;
4599 // Write to the cache (40-49).
4600 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4601 &headers);
4603 Verify206Response(headers, 40, 49);
4604 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4605 EXPECT_EQ(0, cache.disk_cache()->open_count());
4606 EXPECT_EQ(1, cache.disk_cache()->create_count());
4608 // A weird request should not delete this entry. Ask for bytes 120-.
4609 MockTransaction transaction(kRangeGET_TransactionOK);
4610 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4611 transaction.data = "";
4612 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4614 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4615 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4616 EXPECT_EQ(1, cache.disk_cache()->open_count());
4617 EXPECT_EQ(1, cache.disk_cache()->create_count());
4619 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4620 EXPECT_EQ(2, cache.disk_cache()->open_count());
4621 EXPECT_EQ(1, cache.disk_cache()->create_count());
4623 RemoveMockTransaction(&kRangeGET_TransactionOK);
4626 // Tests that we don't delete a sparse entry when we cancel a request.
4627 TEST(HttpCache, RangeGET_Cancel) {
4628 MockHttpCache cache;
4629 AddMockTransaction(&kRangeGET_TransactionOK);
4631 MockHttpRequest request(kRangeGET_TransactionOK);
4633 Context* c = new Context();
4634 int rv = cache.CreateTransaction(&c->trans);
4635 ASSERT_EQ(net::OK, rv);
4637 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4638 if (rv == net::ERR_IO_PENDING)
4639 rv = c->callback.WaitForResult();
4641 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4642 EXPECT_EQ(0, cache.disk_cache()->open_count());
4643 EXPECT_EQ(1, cache.disk_cache()->create_count());
4645 // Make sure that the entry has some data stored.
4646 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4647 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4648 if (rv == net::ERR_IO_PENDING)
4649 rv = c->callback.WaitForResult();
4650 EXPECT_EQ(buf->size(), rv);
4652 // Destroy the transaction.
4653 delete c;
4655 // Verify that the entry has not been deleted.
4656 disk_cache::Entry* entry;
4657 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4658 entry->Close();
4659 RemoveMockTransaction(&kRangeGET_TransactionOK);
4662 // Tests that we don't delete a sparse entry when we start a new request after
4663 // cancelling the previous one.
4664 TEST(HttpCache, RangeGET_Cancel2) {
4665 MockHttpCache cache;
4666 AddMockTransaction(&kRangeGET_TransactionOK);
4668 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4669 MockHttpRequest request(kRangeGET_TransactionOK);
4670 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4672 Context* c = new Context();
4673 int rv = cache.CreateTransaction(&c->trans);
4674 ASSERT_EQ(net::OK, rv);
4676 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4677 if (rv == net::ERR_IO_PENDING)
4678 rv = c->callback.WaitForResult();
4680 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4681 EXPECT_EQ(1, cache.disk_cache()->open_count());
4682 EXPECT_EQ(1, cache.disk_cache()->create_count());
4684 // Make sure that we revalidate the entry and read from the cache (a single
4685 // read will return while waiting for the network).
4686 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4687 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4688 EXPECT_EQ(5, c->callback.GetResult(rv));
4689 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4690 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4692 // Destroy the transaction before completing the read.
4693 delete c;
4695 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4696 // message loop. This means that a new transaction will just reuse the same
4697 // active entry (no open or create).
4699 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4701 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4702 EXPECT_EQ(1, cache.disk_cache()->open_count());
4703 EXPECT_EQ(1, cache.disk_cache()->create_count());
4704 RemoveMockTransaction(&kRangeGET_TransactionOK);
4707 // A slight variation of the previous test, this time we cancel two requests in
4708 // a row, making sure that the second is waiting for the entry to be ready.
4709 TEST(HttpCache, RangeGET_Cancel3) {
4710 MockHttpCache cache;
4711 AddMockTransaction(&kRangeGET_TransactionOK);
4713 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4714 MockHttpRequest request(kRangeGET_TransactionOK);
4715 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4717 Context* c = new Context();
4718 int rv = cache.CreateTransaction(&c->trans);
4719 ASSERT_EQ(net::OK, rv);
4721 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4722 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4723 rv = c->callback.WaitForResult();
4725 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4726 EXPECT_EQ(1, cache.disk_cache()->open_count());
4727 EXPECT_EQ(1, cache.disk_cache()->create_count());
4729 // Make sure that we revalidate the entry and read from the cache (a single
4730 // read will return while waiting for the network).
4731 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4732 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4733 EXPECT_EQ(5, c->callback.GetResult(rv));
4734 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4735 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4737 // Destroy the transaction before completing the read.
4738 delete c;
4740 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4741 // message loop. This means that a new transaction will just reuse the same
4742 // active entry (no open or create).
4744 c = new Context();
4745 rv = cache.CreateTransaction(&c->trans);
4746 ASSERT_EQ(net::OK, rv);
4748 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4749 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4751 MockDiskEntry::IgnoreCallbacks(true);
4752 base::MessageLoop::current()->RunUntilIdle();
4753 MockDiskEntry::IgnoreCallbacks(false);
4755 // The new transaction is waiting for the query range callback.
4756 delete c;
4758 // And we should not crash when the callback is delivered.
4759 base::MessageLoop::current()->RunUntilIdle();
4761 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4762 EXPECT_EQ(1, cache.disk_cache()->open_count());
4763 EXPECT_EQ(1, cache.disk_cache()->create_count());
4764 RemoveMockTransaction(&kRangeGET_TransactionOK);
4767 // Tests that an invalid range response results in no cached entry.
4768 TEST(HttpCache, RangeGET_InvalidResponse1) {
4769 MockHttpCache cache;
4770 std::string headers;
4772 MockTransaction transaction(kRangeGET_TransactionOK);
4773 transaction.handler = NULL;
4774 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4775 "Content-Length: 10\n";
4776 AddMockTransaction(&transaction);
4777 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4779 std::string expected(transaction.status);
4780 expected.append("\n");
4781 expected.append(transaction.response_headers);
4782 EXPECT_EQ(expected, headers);
4784 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4785 EXPECT_EQ(0, cache.disk_cache()->open_count());
4786 EXPECT_EQ(1, cache.disk_cache()->create_count());
4788 // Verify that we don't have a cached entry.
4789 disk_cache::Entry* entry;
4790 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4792 RemoveMockTransaction(&kRangeGET_TransactionOK);
4795 // Tests that we reject a range that doesn't match the content-length.
4796 TEST(HttpCache, RangeGET_InvalidResponse2) {
4797 MockHttpCache cache;
4798 std::string headers;
4800 MockTransaction transaction(kRangeGET_TransactionOK);
4801 transaction.handler = NULL;
4802 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4803 "Content-Length: 20\n";
4804 AddMockTransaction(&transaction);
4805 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4807 std::string expected(transaction.status);
4808 expected.append("\n");
4809 expected.append(transaction.response_headers);
4810 EXPECT_EQ(expected, headers);
4812 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4813 EXPECT_EQ(0, cache.disk_cache()->open_count());
4814 EXPECT_EQ(1, cache.disk_cache()->create_count());
4816 // Verify that we don't have a cached entry.
4817 disk_cache::Entry* entry;
4818 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4820 RemoveMockTransaction(&kRangeGET_TransactionOK);
4823 // Tests that if a server tells us conflicting information about a resource we
4824 // ignore the response.
4825 TEST(HttpCache, RangeGET_InvalidResponse3) {
4826 MockHttpCache cache;
4827 std::string headers;
4829 MockTransaction transaction(kRangeGET_TransactionOK);
4830 transaction.handler = NULL;
4831 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4832 std::string response_headers(transaction.response_headers);
4833 response_headers.append("Content-Range: bytes 50-59/160\n");
4834 transaction.response_headers = response_headers.c_str();
4835 AddMockTransaction(&transaction);
4836 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4838 Verify206Response(headers, 50, 59);
4839 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4840 EXPECT_EQ(0, cache.disk_cache()->open_count());
4841 EXPECT_EQ(1, cache.disk_cache()->create_count());
4843 RemoveMockTransaction(&transaction);
4844 AddMockTransaction(&kRangeGET_TransactionOK);
4846 // This transaction will report a resource size of 80 bytes, and we think it's
4847 // 160 so we should ignore the response.
4848 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4849 &headers);
4851 Verify206Response(headers, 40, 49);
4852 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4853 EXPECT_EQ(1, cache.disk_cache()->open_count());
4854 EXPECT_EQ(1, cache.disk_cache()->create_count());
4856 // Verify that we cached the first response but not the second one.
4857 disk_cache::Entry* en;
4858 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4860 int64 cached_start = 0;
4861 net::TestCompletionCallback cb;
4862 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4863 EXPECT_EQ(10, cb.GetResult(rv));
4864 EXPECT_EQ(50, cached_start);
4865 en->Close();
4867 RemoveMockTransaction(&kRangeGET_TransactionOK);
4870 // Tests that we handle large range values properly.
4871 TEST(HttpCache, RangeGET_LargeValues) {
4872 // We need a real sparse cache for this test.
4873 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4874 std::string headers;
4876 MockTransaction transaction(kRangeGET_TransactionOK);
4877 transaction.handler = NULL;
4878 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4879 EXTRA_HEADER;
4880 transaction.response_headers =
4881 "ETag: \"foo\"\n"
4882 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4883 "Content-Length: 10\n";
4884 AddMockTransaction(&transaction);
4885 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4887 std::string expected(transaction.status);
4888 expected.append("\n");
4889 expected.append(transaction.response_headers);
4890 EXPECT_EQ(expected, headers);
4892 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4894 // Verify that we have a cached entry.
4895 disk_cache::Entry* en;
4896 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4897 en->Close();
4899 RemoveMockTransaction(&kRangeGET_TransactionOK);
4902 // Tests that we don't crash with a range request if the disk cache was not
4903 // initialized properly.
4904 TEST(HttpCache, RangeGET_NoDiskCache) {
4905 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4906 factory->set_fail(true);
4907 factory->FinishCreation(); // We'll complete synchronously.
4908 MockHttpCache cache(factory);
4910 AddMockTransaction(&kRangeGET_TransactionOK);
4912 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4913 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4915 RemoveMockTransaction(&kRangeGET_TransactionOK);
4918 // Tests that we handle byte range requests that skip the cache.
4919 TEST(HttpCache, RangeHEAD) {
4920 MockHttpCache cache;
4921 AddMockTransaction(&kRangeGET_TransactionOK);
4923 MockTransaction transaction(kRangeGET_TransactionOK);
4924 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4925 transaction.method = "HEAD";
4926 transaction.data = "rg: 70-79 ";
4928 std::string headers;
4929 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4931 Verify206Response(headers, 70, 79);
4932 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4933 EXPECT_EQ(0, cache.disk_cache()->open_count());
4934 EXPECT_EQ(0, cache.disk_cache()->create_count());
4936 RemoveMockTransaction(&kRangeGET_TransactionOK);
4939 // Tests that we don't crash when after reading from the cache we issue a
4940 // request for the next range and the server gives us a 200 synchronously.
4941 TEST(HttpCache, RangeGET_FastFlakyServer) {
4942 MockHttpCache cache;
4944 MockTransaction transaction(kRangeGET_TransactionOK);
4945 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4946 transaction.test_mode = TEST_MODE_SYNC_NET_START;
4947 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4948 AddMockTransaction(&transaction);
4950 // Write to the cache.
4951 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4953 // And now read from the cache and the network.
4954 RangeTransactionServer handler;
4955 handler.set_bad_200(true);
4956 transaction.data = "Not a range";
4957 RunTransactionTest(cache.http_cache(), transaction);
4959 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4960 EXPECT_EQ(1, cache.disk_cache()->open_count());
4961 EXPECT_EQ(1, cache.disk_cache()->create_count());
4963 RemoveMockTransaction(&transaction);
4966 // Tests that when the server gives us less data than expected, we don't keep
4967 // asking for more data.
4968 TEST(HttpCache, RangeGET_FastFlakyServer2) {
4969 MockHttpCache cache;
4971 // First, check with an empty cache (WRITE mode).
4972 MockTransaction transaction(kRangeGET_TransactionOK);
4973 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4974 transaction.data = "rg: 40-"; // Less than expected.
4975 transaction.handler = NULL;
4976 std::string headers(transaction.response_headers);
4977 headers.append("Content-Range: bytes 40-49/80\n");
4978 transaction.response_headers = headers.c_str();
4980 AddMockTransaction(&transaction);
4982 // Write to the cache.
4983 RunTransactionTest(cache.http_cache(), transaction);
4985 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4986 EXPECT_EQ(0, cache.disk_cache()->open_count());
4987 EXPECT_EQ(1, cache.disk_cache()->create_count());
4989 // Now verify that even in READ_WRITE mode, we forward the bad response to
4990 // the caller.
4991 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4992 transaction.data = "rg: 60-"; // Less than expected.
4993 headers = kRangeGET_TransactionOK.response_headers;
4994 headers.append("Content-Range: bytes 60-69/80\n");
4995 transaction.response_headers = headers.c_str();
4997 RunTransactionTest(cache.http_cache(), transaction);
4999 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5000 EXPECT_EQ(1, cache.disk_cache()->open_count());
5001 EXPECT_EQ(1, cache.disk_cache()->create_count());
5003 RemoveMockTransaction(&transaction);
5006 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5007 // This test hits a NOTREACHED so it is a release mode only test.
5008 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
5009 MockHttpCache cache;
5010 AddMockTransaction(&kRangeGET_TransactionOK);
5012 // Write to the cache (40-49).
5013 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5014 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5015 EXPECT_EQ(0, cache.disk_cache()->open_count());
5016 EXPECT_EQ(1, cache.disk_cache()->create_count());
5018 // Force this transaction to read from the cache.
5019 MockTransaction transaction(kRangeGET_TransactionOK);
5020 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5022 MockHttpRequest request(transaction);
5023 net::TestCompletionCallback callback;
5025 scoped_ptr<net::HttpTransaction> trans;
5026 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
5027 EXPECT_EQ(net::OK, rv);
5028 ASSERT_TRUE(trans.get());
5030 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5031 if (rv == net::ERR_IO_PENDING)
5032 rv = callback.WaitForResult();
5033 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5035 trans.reset();
5037 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5038 EXPECT_EQ(1, cache.disk_cache()->open_count());
5039 EXPECT_EQ(1, cache.disk_cache()->create_count());
5041 RemoveMockTransaction(&kRangeGET_TransactionOK);
5043 #endif
5045 // Tests the handling of the "truncation" flag.
5046 TEST(HttpCache, WriteResponseInfo_Truncated) {
5047 MockHttpCache cache;
5048 disk_cache::Entry* entry;
5049 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5050 NULL));
5052 std::string headers("HTTP/1.1 200 OK");
5053 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5054 net::HttpResponseInfo response;
5055 response.headers = new net::HttpResponseHeaders(headers);
5057 // Set the last argument for this to be an incomplete request.
5058 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
5059 bool truncated = false;
5060 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5061 EXPECT_TRUE(truncated);
5063 // And now test the opposite case.
5064 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
5065 truncated = true;
5066 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5067 EXPECT_FALSE(truncated);
5068 entry->Close();
5071 // Tests basic pickling/unpickling of HttpResponseInfo.
5072 TEST(HttpCache, PersistHttpResponseInfo) {
5073 // Set some fields (add more if needed.)
5074 net::HttpResponseInfo response1;
5075 response1.was_cached = false;
5076 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
5077 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5079 // Pickle.
5080 Pickle pickle;
5081 response1.Persist(&pickle, false, false);
5083 // Unpickle.
5084 net::HttpResponseInfo response2;
5085 bool response_truncated;
5086 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5087 EXPECT_FALSE(response_truncated);
5089 // Verify fields.
5090 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5091 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5092 EXPECT_EQ(80, response2.socket_address.port());
5093 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5096 // Tests that we delete an entry when the request is cancelled before starting
5097 // to read from the network.
5098 TEST(HttpCache, DoomOnDestruction) {
5099 MockHttpCache cache;
5101 MockHttpRequest request(kSimpleGET_Transaction);
5103 Context* c = new Context();
5104 int rv = cache.CreateTransaction(&c->trans);
5105 ASSERT_EQ(net::OK, rv);
5107 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5108 if (rv == net::ERR_IO_PENDING)
5109 c->result = c->callback.WaitForResult();
5111 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5112 EXPECT_EQ(0, cache.disk_cache()->open_count());
5113 EXPECT_EQ(1, cache.disk_cache()->create_count());
5115 // Destroy the transaction. We only have the headers so we should delete this
5116 // entry.
5117 delete c;
5119 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5121 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5122 EXPECT_EQ(0, cache.disk_cache()->open_count());
5123 EXPECT_EQ(2, cache.disk_cache()->create_count());
5126 // Tests that we delete an entry when the request is cancelled if the response
5127 // does not have content-length and strong validators.
5128 TEST(HttpCache, DoomOnDestruction2) {
5129 MockHttpCache cache;
5131 MockHttpRequest request(kSimpleGET_Transaction);
5133 Context* c = new Context();
5134 int rv = cache.CreateTransaction(&c->trans);
5135 ASSERT_EQ(net::OK, rv);
5137 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5138 if (rv == net::ERR_IO_PENDING)
5139 rv = c->callback.WaitForResult();
5141 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5142 EXPECT_EQ(0, cache.disk_cache()->open_count());
5143 EXPECT_EQ(1, cache.disk_cache()->create_count());
5145 // Make sure that the entry has some data stored.
5146 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5147 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5148 if (rv == net::ERR_IO_PENDING)
5149 rv = c->callback.WaitForResult();
5150 EXPECT_EQ(buf->size(), rv);
5152 // Destroy the transaction.
5153 delete c;
5155 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5157 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5158 EXPECT_EQ(0, cache.disk_cache()->open_count());
5159 EXPECT_EQ(2, cache.disk_cache()->create_count());
5162 // Tests that we delete an entry when the request is cancelled if the response
5163 // has an "Accept-Ranges: none" header.
5164 TEST(HttpCache, DoomOnDestruction3) {
5165 MockHttpCache cache;
5167 MockTransaction transaction(kSimpleGET_Transaction);
5168 transaction.response_headers =
5169 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5170 "Content-Length: 22\n"
5171 "Accept-Ranges: none\n"
5172 "Etag: \"foopy\"\n";
5173 AddMockTransaction(&transaction);
5174 MockHttpRequest request(transaction);
5176 Context* c = new Context();
5177 int rv = cache.CreateTransaction(&c->trans);
5178 ASSERT_EQ(net::OK, rv);
5180 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5181 if (rv == net::ERR_IO_PENDING)
5182 rv = c->callback.WaitForResult();
5184 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5185 EXPECT_EQ(0, cache.disk_cache()->open_count());
5186 EXPECT_EQ(1, cache.disk_cache()->create_count());
5188 // Make sure that the entry has some data stored.
5189 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5190 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5191 if (rv == net::ERR_IO_PENDING)
5192 rv = c->callback.WaitForResult();
5193 EXPECT_EQ(buf->size(), rv);
5195 // Destroy the transaction.
5196 delete c;
5198 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5200 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5201 EXPECT_EQ(0, cache.disk_cache()->open_count());
5202 EXPECT_EQ(2, cache.disk_cache()->create_count());
5204 RemoveMockTransaction(&transaction);
5207 // Tests that we mark an entry as incomplete when the request is cancelled.
5208 TEST(HttpCache, SetTruncatedFlag) {
5209 MockHttpCache cache;
5211 MockTransaction transaction(kSimpleGET_Transaction);
5212 transaction.response_headers =
5213 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5214 "Content-Length: 22\n"
5215 "Etag: \"foopy\"\n";
5216 AddMockTransaction(&transaction);
5217 MockHttpRequest request(transaction);
5219 scoped_ptr<Context> c(new Context());
5221 int rv = cache.CreateTransaction(&c->trans);
5222 ASSERT_EQ(net::OK, rv);
5224 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5225 if (rv == net::ERR_IO_PENDING)
5226 rv = c->callback.WaitForResult();
5228 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5229 EXPECT_EQ(0, cache.disk_cache()->open_count());
5230 EXPECT_EQ(1, cache.disk_cache()->create_count());
5232 // Make sure that the entry has some data stored.
5233 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5234 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5235 if (rv == net::ERR_IO_PENDING)
5236 rv = c->callback.WaitForResult();
5237 EXPECT_EQ(buf->size(), rv);
5239 // We want to cancel the request when the transaction is busy.
5240 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5241 EXPECT_EQ(net::ERR_IO_PENDING, rv);
5242 EXPECT_FALSE(c->callback.have_result());
5244 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
5246 // Destroy the transaction.
5247 c->trans.reset();
5248 MockHttpCache::SetTestMode(0);
5251 // Make sure that we don't invoke the callback. We may have an issue if the
5252 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5253 // could end up with the transaction being deleted twice if we send any
5254 // notification from the transaction destructor (see http://crbug.com/31723).
5255 EXPECT_FALSE(c->callback.have_result());
5257 // Verify that the entry is marked as incomplete.
5258 disk_cache::Entry* entry;
5259 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5260 net::HttpResponseInfo response;
5261 bool truncated = false;
5262 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5263 EXPECT_TRUE(truncated);
5264 entry->Close();
5266 RemoveMockTransaction(&transaction);
5269 // Tests that we don't mark an entry as truncated when we read everything.
5270 TEST(HttpCache, DontSetTruncatedFlag) {
5271 MockHttpCache cache;
5273 MockTransaction transaction(kSimpleGET_Transaction);
5274 transaction.response_headers =
5275 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5276 "Content-Length: 22\n"
5277 "Etag: \"foopy\"\n";
5278 AddMockTransaction(&transaction);
5279 MockHttpRequest request(transaction);
5281 scoped_ptr<Context> c(new Context());
5282 int rv = cache.CreateTransaction(&c->trans);
5283 ASSERT_EQ(net::OK, rv);
5285 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5286 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5288 // Read everything.
5289 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
5290 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5291 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5293 // Destroy the transaction.
5294 c->trans.reset();
5296 // Verify that the entry is not marked as truncated.
5297 disk_cache::Entry* entry;
5298 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5299 net::HttpResponseInfo response;
5300 bool truncated = true;
5301 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5302 EXPECT_FALSE(truncated);
5303 entry->Close();
5305 RemoveMockTransaction(&transaction);
5308 // Tests that we can continue with a request that was interrupted.
5309 TEST(HttpCache, GET_IncompleteResource) {
5310 MockHttpCache cache;
5311 AddMockTransaction(&kRangeGET_TransactionOK);
5313 std::string raw_headers("HTTP/1.1 200 OK\n"
5314 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5315 "ETag: \"foo\"\n"
5316 "Accept-Ranges: bytes\n"
5317 "Content-Length: 80\n");
5318 CreateTruncatedEntry(raw_headers, &cache);
5320 // Now make a regular request.
5321 std::string headers;
5322 MockTransaction transaction(kRangeGET_TransactionOK);
5323 transaction.request_headers = EXTRA_HEADER;
5324 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5325 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5326 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5328 // We update the headers with the ones received while revalidating.
5329 std::string expected_headers(
5330 "HTTP/1.1 200 OK\n"
5331 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5332 "Accept-Ranges: bytes\n"
5333 "ETag: \"foo\"\n"
5334 "Content-Length: 80\n");
5336 EXPECT_EQ(expected_headers, headers);
5337 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5338 EXPECT_EQ(1, cache.disk_cache()->open_count());
5339 EXPECT_EQ(1, cache.disk_cache()->create_count());
5341 // Verify that the disk entry was updated.
5342 disk_cache::Entry* entry;
5343 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5344 EXPECT_EQ(80, entry->GetDataSize(1));
5345 bool truncated = true;
5346 net::HttpResponseInfo response;
5347 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5348 EXPECT_FALSE(truncated);
5349 entry->Close();
5351 RemoveMockTransaction(&kRangeGET_TransactionOK);
5354 // Tests the handling of no-store when revalidating a truncated entry.
5355 TEST(HttpCache, GET_IncompleteResource_NoStore) {
5356 MockHttpCache cache;
5357 AddMockTransaction(&kRangeGET_TransactionOK);
5359 std::string raw_headers("HTTP/1.1 200 OK\n"
5360 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5361 "ETag: \"foo\"\n"
5362 "Accept-Ranges: bytes\n"
5363 "Content-Length: 80\n");
5364 CreateTruncatedEntry(raw_headers, &cache);
5365 RemoveMockTransaction(&kRangeGET_TransactionOK);
5367 // Now make a regular request.
5368 MockTransaction transaction(kRangeGET_TransactionOK);
5369 transaction.request_headers = EXTRA_HEADER;
5370 std::string response_headers(transaction.response_headers);
5371 response_headers += ("Cache-Control: no-store\n");
5372 transaction.response_headers = response_headers.c_str();
5373 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5374 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5375 AddMockTransaction(&transaction);
5377 std::string headers;
5378 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5380 // We update the headers with the ones received while revalidating.
5381 std::string expected_headers(
5382 "HTTP/1.1 200 OK\n"
5383 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5384 "Accept-Ranges: bytes\n"
5385 "Cache-Control: no-store\n"
5386 "ETag: \"foo\"\n"
5387 "Content-Length: 80\n");
5389 EXPECT_EQ(expected_headers, headers);
5390 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5391 EXPECT_EQ(1, cache.disk_cache()->open_count());
5392 EXPECT_EQ(1, cache.disk_cache()->create_count());
5394 // Verify that the disk entry was deleted.
5395 disk_cache::Entry* entry;
5396 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5397 RemoveMockTransaction(&transaction);
5400 // Tests cancelling a request after the server sent no-store.
5401 TEST(HttpCache, GET_IncompleteResource_Cancel) {
5402 MockHttpCache cache;
5403 AddMockTransaction(&kRangeGET_TransactionOK);
5405 std::string raw_headers("HTTP/1.1 200 OK\n"
5406 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5407 "ETag: \"foo\"\n"
5408 "Accept-Ranges: bytes\n"
5409 "Content-Length: 80\n");
5410 CreateTruncatedEntry(raw_headers, &cache);
5411 RemoveMockTransaction(&kRangeGET_TransactionOK);
5413 // Now make a regular request.
5414 MockTransaction transaction(kRangeGET_TransactionOK);
5415 transaction.request_headers = EXTRA_HEADER;
5416 std::string response_headers(transaction.response_headers);
5417 response_headers += ("Cache-Control: no-store\n");
5418 transaction.response_headers = response_headers.c_str();
5419 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5420 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5421 AddMockTransaction(&transaction);
5423 MockHttpRequest request(transaction);
5424 Context* c = new Context();
5426 int rv = cache.CreateTransaction(&c->trans);
5427 ASSERT_EQ(net::OK, rv);
5429 // Queue another request to this transaction. We have to start this request
5430 // before the first one gets the response from the server and dooms the entry,
5431 // otherwise it will just create a new entry without being queued to the first
5432 // request.
5433 Context* pending = new Context();
5434 ASSERT_EQ(net::OK, cache.CreateTransaction(&pending->trans));
5436 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5437 EXPECT_EQ(net::ERR_IO_PENDING,
5438 pending->trans->Start(&request, pending->callback.callback(),
5439 net::BoundNetLog()));
5440 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5442 // Make sure that the entry has some data stored.
5443 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
5444 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5445 EXPECT_EQ(5, c->callback.GetResult(rv));
5447 // Cancel the requests.
5448 delete c;
5449 delete pending;
5451 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache.disk_cache()->open_count());
5453 EXPECT_EQ(2, cache.disk_cache()->create_count());
5455 base::MessageLoop::current()->RunUntilIdle();
5456 RemoveMockTransaction(&transaction);
5459 // Tests that we delete truncated entries if the server changes its mind midway.
5460 TEST(HttpCache, GET_IncompleteResource2) {
5461 MockHttpCache cache;
5462 AddMockTransaction(&kRangeGET_TransactionOK);
5464 // Content-length will be intentionally bad.
5465 std::string raw_headers("HTTP/1.1 200 OK\n"
5466 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5467 "ETag: \"foo\"\n"
5468 "Accept-Ranges: bytes\n"
5469 "Content-Length: 50\n");
5470 CreateTruncatedEntry(raw_headers, &cache);
5472 // Now make a regular request. We expect the code to fail the validation and
5473 // retry the request without using byte ranges.
5474 std::string headers;
5475 MockTransaction transaction(kRangeGET_TransactionOK);
5476 transaction.request_headers = EXTRA_HEADER;
5477 transaction.data = "Not a range";
5478 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5480 // The server will return 200 instead of a byte range.
5481 std::string expected_headers(
5482 "HTTP/1.1 200 OK\n"
5483 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5485 EXPECT_EQ(expected_headers, headers);
5486 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5487 EXPECT_EQ(1, cache.disk_cache()->open_count());
5488 EXPECT_EQ(1, cache.disk_cache()->create_count());
5490 // Verify that the disk entry was deleted.
5491 disk_cache::Entry* entry;
5492 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5493 RemoveMockTransaction(&kRangeGET_TransactionOK);
5496 // Tests that we always validate a truncated request.
5497 TEST(HttpCache, GET_IncompleteResource3) {
5498 MockHttpCache cache;
5499 AddMockTransaction(&kRangeGET_TransactionOK);
5501 // This should not require validation for 10 hours.
5502 std::string raw_headers("HTTP/1.1 200 OK\n"
5503 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5504 "ETag: \"foo\"\n"
5505 "Cache-Control: max-age= 36000\n"
5506 "Accept-Ranges: bytes\n"
5507 "Content-Length: 80\n");
5508 CreateTruncatedEntry(raw_headers, &cache);
5510 // Now make a regular request.
5511 std::string headers;
5512 MockTransaction transaction(kRangeGET_TransactionOK);
5513 transaction.request_headers = EXTRA_HEADER;
5514 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5515 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5517 scoped_ptr<Context> c(new Context);
5518 int rv = cache.CreateTransaction(&c->trans);
5519 ASSERT_EQ(net::OK, rv);
5521 MockHttpRequest request(transaction);
5522 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5523 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5525 // We should have checked with the server before finishing Start().
5526 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5527 EXPECT_EQ(1, cache.disk_cache()->open_count());
5528 EXPECT_EQ(1, cache.disk_cache()->create_count());
5530 RemoveMockTransaction(&kRangeGET_TransactionOK);
5533 // Tests that we handle 401s for truncated resources.
5534 TEST(HttpCache, GET_IncompleteResourceWithAuth) {
5535 MockHttpCache cache;
5536 AddMockTransaction(&kRangeGET_TransactionOK);
5538 std::string raw_headers("HTTP/1.1 200 OK\n"
5539 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5540 "ETag: \"foo\"\n"
5541 "Accept-Ranges: bytes\n"
5542 "Content-Length: 80\n");
5543 CreateTruncatedEntry(raw_headers, &cache);
5545 // Now make a regular request.
5546 MockTransaction transaction(kRangeGET_TransactionOK);
5547 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
5548 EXTRA_HEADER;
5549 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5550 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5551 RangeTransactionServer handler;
5553 scoped_ptr<Context> c(new Context);
5554 int rv = cache.CreateTransaction(&c->trans);
5555 ASSERT_EQ(net::OK, rv);
5557 MockHttpRequest request(transaction);
5558 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5559 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5561 const net::HttpResponseInfo* response = c->trans->GetResponseInfo();
5562 ASSERT_TRUE(response);
5563 ASSERT_EQ(401, response->headers->response_code());
5564 rv = c->trans->RestartWithAuth(net::AuthCredentials(),
5565 c->callback.callback());
5566 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5567 response = c->trans->GetResponseInfo();
5568 ASSERT_TRUE(response);
5569 ASSERT_EQ(200, response->headers->response_code());
5571 ReadAndVerifyTransaction(c->trans.get(), transaction);
5572 c.reset(); // The destructor could delete the entry.
5573 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5575 // Verify that the entry was not deleted.
5576 disk_cache::Entry* entry;
5577 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5578 entry->Close();
5580 RemoveMockTransaction(&kRangeGET_TransactionOK);
5583 // Tests that we cache a 200 response to the validation request.
5584 TEST(HttpCache, GET_IncompleteResource4) {
5585 MockHttpCache cache;
5586 AddMockTransaction(&kRangeGET_TransactionOK);
5588 std::string raw_headers("HTTP/1.1 200 OK\n"
5589 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5590 "ETag: \"foo\"\n"
5591 "Accept-Ranges: bytes\n"
5592 "Content-Length: 80\n");
5593 CreateTruncatedEntry(raw_headers, &cache);
5595 // Now make a regular request.
5596 std::string headers;
5597 MockTransaction transaction(kRangeGET_TransactionOK);
5598 transaction.request_headers = EXTRA_HEADER;
5599 transaction.data = "Not a range";
5600 RangeTransactionServer handler;
5601 handler.set_bad_200(true);
5602 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5604 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5605 EXPECT_EQ(1, cache.disk_cache()->open_count());
5606 EXPECT_EQ(1, cache.disk_cache()->create_count());
5608 // Verify that the disk entry was updated.
5609 disk_cache::Entry* entry;
5610 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5611 EXPECT_EQ(11, entry->GetDataSize(1));
5612 bool truncated = true;
5613 net::HttpResponseInfo response;
5614 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5615 EXPECT_FALSE(truncated);
5616 entry->Close();
5618 RemoveMockTransaction(&kRangeGET_TransactionOK);
5621 // Tests that when we cancel a request that was interrupted, we mark it again
5622 // as truncated.
5623 TEST(HttpCache, GET_CancelIncompleteResource) {
5624 MockHttpCache cache;
5625 AddMockTransaction(&kRangeGET_TransactionOK);
5627 std::string raw_headers("HTTP/1.1 200 OK\n"
5628 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5629 "ETag: \"foo\"\n"
5630 "Accept-Ranges: bytes\n"
5631 "Content-Length: 80\n");
5632 CreateTruncatedEntry(raw_headers, &cache);
5634 // Now make a regular request.
5635 MockTransaction transaction(kRangeGET_TransactionOK);
5636 transaction.request_headers = EXTRA_HEADER;
5638 MockHttpRequest request(transaction);
5639 Context* c = new Context();
5640 int rv = cache.CreateTransaction(&c->trans);
5641 ASSERT_EQ(net::OK, rv);
5643 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5644 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5646 // Read 20 bytes from the cache, and 10 from the net.
5647 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5648 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5649 EXPECT_EQ(20, c->callback.GetResult(rv));
5650 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5651 EXPECT_EQ(10, c->callback.GetResult(rv));
5653 // At this point, we are already reading so canceling the request should leave
5654 // a truncated one.
5655 delete c;
5657 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5658 EXPECT_EQ(1, cache.disk_cache()->open_count());
5659 EXPECT_EQ(1, cache.disk_cache()->create_count());
5661 // Verify that the disk entry was updated: now we have 30 bytes.
5662 disk_cache::Entry* entry;
5663 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5664 EXPECT_EQ(30, entry->GetDataSize(1));
5665 bool truncated = false;
5666 net::HttpResponseInfo response;
5667 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5668 EXPECT_TRUE(truncated);
5669 entry->Close();
5670 RemoveMockTransaction(&kRangeGET_TransactionOK);
5673 // Tests that we can handle range requests when we have a truncated entry.
5674 TEST(HttpCache, RangeGET_IncompleteResource) {
5675 MockHttpCache cache;
5676 AddMockTransaction(&kRangeGET_TransactionOK);
5678 // Content-length will be intentionally bogus.
5679 std::string raw_headers("HTTP/1.1 200 OK\n"
5680 "Last-Modified: something\n"
5681 "ETag: \"foo\"\n"
5682 "Accept-Ranges: bytes\n"
5683 "Content-Length: 10\n");
5684 CreateTruncatedEntry(raw_headers, &cache);
5686 // Now make a range request.
5687 std::string headers;
5688 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5689 &headers);
5691 Verify206Response(headers, 40, 49);
5692 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5693 EXPECT_EQ(1, cache.disk_cache()->open_count());
5694 EXPECT_EQ(2, cache.disk_cache()->create_count());
5696 RemoveMockTransaction(&kRangeGET_TransactionOK);
5699 TEST(HttpCache, SyncRead) {
5700 MockHttpCache cache;
5702 // This test ensures that a read that completes synchronously does not cause
5703 // any problems.
5705 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5706 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5707 TEST_MODE_SYNC_CACHE_READ |
5708 TEST_MODE_SYNC_CACHE_WRITE);
5710 MockHttpRequest r1(transaction),
5711 r2(transaction),
5712 r3(transaction);
5714 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5715 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5716 c3(net::DEFAULT_PRIORITY, cache.http_cache());
5718 c1.Start(&r1, net::BoundNetLog());
5720 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5721 c2.Start(&r2, net::BoundNetLog());
5723 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5724 c3.Start(&r3, net::BoundNetLog());
5726 base::MessageLoop::current()->Run();
5728 EXPECT_TRUE(c1.is_done());
5729 EXPECT_TRUE(c2.is_done());
5730 EXPECT_TRUE(c3.is_done());
5732 EXPECT_EQ(net::OK, c1.error());
5733 EXPECT_EQ(net::OK, c2.error());
5734 EXPECT_EQ(net::OK, c3.error());
5737 TEST(HttpCache, ValidationResultsIn200) {
5738 MockHttpCache cache;
5740 // This test ensures that a conditional request, which results in a 200
5741 // instead of a 304, properly truncates the existing response data.
5743 // write to the cache
5744 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5746 // force this transaction to validate the cache
5747 MockTransaction transaction(kETagGET_Transaction);
5748 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5749 RunTransactionTest(cache.http_cache(), transaction);
5751 // read from the cache
5752 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5755 TEST(HttpCache, CachedRedirect) {
5756 MockHttpCache cache;
5758 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5759 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5760 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5762 MockHttpRequest request(kTestTransaction);
5763 net::TestCompletionCallback callback;
5765 // Write to the cache.
5767 scoped_ptr<net::HttpTransaction> trans;
5768 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5770 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5771 if (rv == net::ERR_IO_PENDING)
5772 rv = callback.WaitForResult();
5773 ASSERT_EQ(net::OK, rv);
5775 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5776 ASSERT_TRUE(info);
5778 EXPECT_EQ(info->headers->response_code(), 301);
5780 std::string location;
5781 info->headers->EnumerateHeader(NULL, "Location", &location);
5782 EXPECT_EQ(location, "http://www.bar.com/");
5784 // Mark the transaction as completed so it is cached.
5785 trans->DoneReading();
5787 // Destroy transaction when going out of scope. We have not actually
5788 // read the response body -- want to test that it is still getting cached.
5790 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5791 EXPECT_EQ(0, cache.disk_cache()->open_count());
5792 EXPECT_EQ(1, cache.disk_cache()->create_count());
5794 // Active entries in the cache are not retired synchronously. Make
5795 // sure the next run hits the MockHttpCache and open_count is
5796 // correct.
5797 base::MessageLoop::current()->RunUntilIdle();
5799 // Read from the cache.
5801 scoped_ptr<net::HttpTransaction> trans;
5802 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5804 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5805 if (rv == net::ERR_IO_PENDING)
5806 rv = callback.WaitForResult();
5807 ASSERT_EQ(net::OK, rv);
5809 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5810 ASSERT_TRUE(info);
5812 EXPECT_EQ(info->headers->response_code(), 301);
5814 std::string location;
5815 info->headers->EnumerateHeader(NULL, "Location", &location);
5816 EXPECT_EQ(location, "http://www.bar.com/");
5818 // Mark the transaction as completed so it is cached.
5819 trans->DoneReading();
5821 // Destroy transaction when going out of scope. We have not actually
5822 // read the response body -- want to test that it is still getting cached.
5824 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5825 EXPECT_EQ(1, cache.disk_cache()->open_count());
5826 EXPECT_EQ(1, cache.disk_cache()->create_count());
5829 // Verify that no-cache resources are stored in cache, but are not fetched from
5830 // cache during normal loads.
5831 TEST(HttpCache, CacheControlNoCacheNormalLoad) {
5832 MockHttpCache cache;
5834 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5835 transaction.response_headers = "cache-control: no-cache\n";
5837 // Initial load.
5838 RunTransactionTest(cache.http_cache(), transaction);
5840 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5841 EXPECT_EQ(0, cache.disk_cache()->open_count());
5842 EXPECT_EQ(1, cache.disk_cache()->create_count());
5844 // Try loading again; it should result in a network fetch.
5845 RunTransactionTest(cache.http_cache(), transaction);
5847 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5848 EXPECT_EQ(1, cache.disk_cache()->open_count());
5849 EXPECT_EQ(1, cache.disk_cache()->create_count());
5851 disk_cache::Entry* entry;
5852 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5853 entry->Close();
5856 // Verify that no-cache resources are stored in cache and fetched from cache
5857 // when the LOAD_PREFERRING_CACHE flag is set.
5858 TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
5859 MockHttpCache cache;
5861 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5862 transaction.response_headers = "cache-control: no-cache\n";
5864 // Initial load.
5865 RunTransactionTest(cache.http_cache(), transaction);
5867 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5868 EXPECT_EQ(0, cache.disk_cache()->open_count());
5869 EXPECT_EQ(1, cache.disk_cache()->create_count());
5871 // Try loading again with LOAD_PREFERRING_CACHE.
5872 transaction.load_flags = net::LOAD_PREFERRING_CACHE;
5873 RunTransactionTest(cache.http_cache(), transaction);
5875 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5876 EXPECT_EQ(1, cache.disk_cache()->open_count());
5877 EXPECT_EQ(1, cache.disk_cache()->create_count());
5879 disk_cache::Entry* entry;
5880 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5881 entry->Close();
5884 TEST(HttpCache, CacheControlNoStore) {
5885 MockHttpCache cache;
5887 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5888 transaction.response_headers = "cache-control: no-store\n";
5890 // initial load
5891 RunTransactionTest(cache.http_cache(), transaction);
5893 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5894 EXPECT_EQ(0, cache.disk_cache()->open_count());
5895 EXPECT_EQ(1, cache.disk_cache()->create_count());
5897 // try loading again; it should result in a network fetch
5898 RunTransactionTest(cache.http_cache(), transaction);
5900 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5901 EXPECT_EQ(0, cache.disk_cache()->open_count());
5902 EXPECT_EQ(2, cache.disk_cache()->create_count());
5904 disk_cache::Entry* entry;
5905 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5908 TEST(HttpCache, CacheControlNoStore2) {
5909 // this test is similar to the above test, except that the initial response
5910 // is cachable, but when it is validated, no-store is received causing the
5911 // cached document to be deleted.
5912 MockHttpCache cache;
5914 ScopedMockTransaction transaction(kETagGET_Transaction);
5916 // initial load
5917 RunTransactionTest(cache.http_cache(), transaction);
5919 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5920 EXPECT_EQ(0, cache.disk_cache()->open_count());
5921 EXPECT_EQ(1, cache.disk_cache()->create_count());
5923 // try loading again; it should result in a network fetch
5924 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5925 transaction.response_headers = "cache-control: no-store\n";
5926 RunTransactionTest(cache.http_cache(), transaction);
5928 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5929 EXPECT_EQ(1, cache.disk_cache()->open_count());
5930 EXPECT_EQ(1, cache.disk_cache()->create_count());
5932 disk_cache::Entry* entry;
5933 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5936 TEST(HttpCache, CacheControlNoStore3) {
5937 // this test is similar to the above test, except that the response is a 304
5938 // instead of a 200. this should never happen in practice, but it seems like
5939 // a good thing to verify that we still destroy the cache entry.
5940 MockHttpCache cache;
5942 ScopedMockTransaction transaction(kETagGET_Transaction);
5944 // initial load
5945 RunTransactionTest(cache.http_cache(), transaction);
5947 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5948 EXPECT_EQ(0, cache.disk_cache()->open_count());
5949 EXPECT_EQ(1, cache.disk_cache()->create_count());
5951 // try loading again; it should result in a network fetch
5952 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5953 transaction.response_headers = "cache-control: no-store\n";
5954 transaction.status = "HTTP/1.1 304 Not Modified";
5955 RunTransactionTest(cache.http_cache(), transaction);
5957 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5958 EXPECT_EQ(1, cache.disk_cache()->open_count());
5959 EXPECT_EQ(1, cache.disk_cache()->create_count());
5961 disk_cache::Entry* entry;
5962 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5965 // Ensure that we don't cache requests served over bad HTTPS.
5966 TEST(HttpCache, SimpleGET_SSLError) {
5967 MockHttpCache cache;
5969 MockTransaction transaction = kSimpleGET_Transaction;
5970 transaction.cert_status = net::CERT_STATUS_REVOKED;
5971 ScopedMockTransaction scoped_transaction(transaction);
5973 // write to the cache
5974 RunTransactionTest(cache.http_cache(), transaction);
5976 // Test that it was not cached.
5977 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5979 MockHttpRequest request(transaction);
5980 net::TestCompletionCallback callback;
5982 scoped_ptr<net::HttpTransaction> trans;
5983 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5985 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5986 if (rv == net::ERR_IO_PENDING)
5987 rv = callback.WaitForResult();
5988 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5991 // Ensure that we don't crash by if left-behind transactions.
5992 TEST(HttpCache, OutlivedTransactions) {
5993 MockHttpCache* cache = new MockHttpCache;
5995 scoped_ptr<net::HttpTransaction> trans;
5996 EXPECT_EQ(net::OK, cache->CreateTransaction(&trans));
5998 delete cache;
5999 trans.reset();
6002 // Test that the disabled mode works.
6003 TEST(HttpCache, CacheDisabledMode) {
6004 MockHttpCache cache;
6006 // write to the cache
6007 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6009 // go into disabled mode
6010 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
6012 // force this transaction to write to the cache again
6013 MockTransaction transaction(kSimpleGET_Transaction);
6015 RunTransactionTest(cache.http_cache(), transaction);
6017 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6018 EXPECT_EQ(0, cache.disk_cache()->open_count());
6019 EXPECT_EQ(1, cache.disk_cache()->create_count());
6022 // Other tests check that the response headers of the cached response
6023 // get updated on 304. Here we specifically check that the
6024 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6025 // fields also gets updated.
6026 // http://crbug.com/20594.
6027 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
6028 MockHttpCache cache;
6030 const char* kUrl = "http://foobar";
6031 const char* kData = "body";
6033 MockTransaction mock_network_response = { 0 };
6034 mock_network_response.url = kUrl;
6036 AddMockTransaction(&mock_network_response);
6038 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6040 MockTransaction request = { 0 };
6041 request.url = kUrl;
6042 request.method = "GET";
6043 request.request_headers = "\r\n";
6044 request.data = kData;
6046 static const Response kNetResponse1 = {
6047 "HTTP/1.1 200 OK",
6048 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6049 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6050 kData
6053 kNetResponse1.AssignTo(&mock_network_response);
6055 RunTransactionTest(cache.http_cache(), request);
6057 // Request |kUrl| again, this time validating the cache and getting
6058 // a 304 back.
6060 request.load_flags = net::LOAD_VALIDATE_CACHE;
6062 static const Response kNetResponse2 = {
6063 "HTTP/1.1 304 Not Modified",
6064 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6068 kNetResponse2.AssignTo(&mock_network_response);
6070 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6071 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6073 mock_network_response.request_time = request_time;
6074 mock_network_response.response_time = response_time;
6076 net::HttpResponseInfo response;
6077 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6079 // The request and response times should have been updated.
6080 EXPECT_EQ(request_time.ToInternalValue(),
6081 response.request_time.ToInternalValue());
6082 EXPECT_EQ(response_time.ToInternalValue(),
6083 response.response_time.ToInternalValue());
6085 std::string headers;
6086 response.headers->GetNormalizedHeaders(&headers);
6088 EXPECT_EQ("HTTP/1.1 200 OK\n"
6089 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6090 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6091 headers);
6093 RemoveMockTransaction(&mock_network_response);
6096 // Tests that we can write metadata to an entry.
6097 TEST(HttpCache, WriteMetadata_OK) {
6098 MockHttpCache cache;
6100 // Write to the cache
6101 net::HttpResponseInfo response;
6102 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6103 &response);
6104 EXPECT_TRUE(response.metadata.get() == NULL);
6106 // Trivial call.
6107 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
6108 Time::Now(), NULL, 0);
6110 // Write meta data to the same entry.
6111 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6112 memset(buf->data(), 0, buf->size());
6113 base::strlcpy(buf->data(), "Hi there", buf->size());
6114 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6115 net::DEFAULT_PRIORITY,
6116 response.response_time,
6117 buf.get(),
6118 buf->size());
6120 // Release the buffer before the operation takes place.
6121 buf = NULL;
6123 // Makes sure we finish pending operations.
6124 base::MessageLoop::current()->RunUntilIdle();
6126 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6127 &response);
6128 ASSERT_TRUE(response.metadata.get() != NULL);
6129 EXPECT_EQ(50, response.metadata->size());
6130 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6132 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6133 EXPECT_EQ(2, cache.disk_cache()->open_count());
6134 EXPECT_EQ(1, cache.disk_cache()->create_count());
6137 // Tests that we only write metadata to an entry if the time stamp matches.
6138 TEST(HttpCache, WriteMetadata_Fail) {
6139 MockHttpCache cache;
6141 // Write to the cache
6142 net::HttpResponseInfo response;
6143 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6144 &response);
6145 EXPECT_TRUE(response.metadata.get() == NULL);
6147 // Attempt to write meta data to the same entry.
6148 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6149 memset(buf->data(), 0, buf->size());
6150 base::strlcpy(buf->data(), "Hi there", buf->size());
6151 base::Time expected_time = response.response_time -
6152 base::TimeDelta::FromMilliseconds(20);
6153 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6154 net::DEFAULT_PRIORITY,
6155 expected_time,
6156 buf.get(),
6157 buf->size());
6159 // Makes sure we finish pending operations.
6160 base::MessageLoop::current()->RunUntilIdle();
6162 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6163 &response);
6164 EXPECT_TRUE(response.metadata.get() == NULL);
6166 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6167 EXPECT_EQ(2, cache.disk_cache()->open_count());
6168 EXPECT_EQ(1, cache.disk_cache()->create_count());
6171 // Tests that we can read metadata after validating the entry and with READ mode
6172 // transactions.
6173 TEST(HttpCache, ReadMetadata) {
6174 MockHttpCache cache;
6176 // Write to the cache
6177 net::HttpResponseInfo response;
6178 RunTransactionTestWithResponseInfo(cache.http_cache(),
6179 kTypicalGET_Transaction, &response);
6180 EXPECT_TRUE(response.metadata.get() == NULL);
6182 // Write meta data to the same entry.
6183 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6184 memset(buf->data(), 0, buf->size());
6185 base::strlcpy(buf->data(), "Hi there", buf->size());
6186 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6187 net::DEFAULT_PRIORITY,
6188 response.response_time,
6189 buf.get(),
6190 buf->size());
6192 // Makes sure we finish pending operations.
6193 base::MessageLoop::current()->RunUntilIdle();
6195 // Start with a READ mode transaction.
6196 MockTransaction trans1(kTypicalGET_Transaction);
6197 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
6199 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6200 ASSERT_TRUE(response.metadata.get() != NULL);
6201 EXPECT_EQ(50, response.metadata->size());
6202 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6204 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6205 EXPECT_EQ(2, cache.disk_cache()->open_count());
6206 EXPECT_EQ(1, cache.disk_cache()->create_count());
6207 base::MessageLoop::current()->RunUntilIdle();
6209 // Now make sure that the entry is re-validated with the server.
6210 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
6211 trans1.status = "HTTP/1.1 304 Not Modified";
6212 AddMockTransaction(&trans1);
6214 response.metadata = NULL;
6215 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6216 EXPECT_TRUE(response.metadata.get() != NULL);
6218 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6219 EXPECT_EQ(3, cache.disk_cache()->open_count());
6220 EXPECT_EQ(1, cache.disk_cache()->create_count());
6221 base::MessageLoop::current()->RunUntilIdle();
6222 RemoveMockTransaction(&trans1);
6224 // Now return 200 when validating the entry so the metadata will be lost.
6225 MockTransaction trans2(kTypicalGET_Transaction);
6226 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
6227 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6228 EXPECT_TRUE(response.metadata.get() == NULL);
6230 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6231 EXPECT_EQ(4, cache.disk_cache()->open_count());
6232 EXPECT_EQ(1, cache.disk_cache()->create_count());
6235 // Tests that we don't mark entries as truncated when a filter detects the end
6236 // of the stream.
6237 TEST(HttpCache, FilterCompletion) {
6238 MockHttpCache cache;
6239 net::TestCompletionCallback callback;
6242 scoped_ptr<net::HttpTransaction> trans;
6243 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6245 MockHttpRequest request(kSimpleGET_Transaction);
6246 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6247 EXPECT_EQ(net::OK, callback.GetResult(rv));
6249 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6250 rv = trans->Read(buf.get(), 256, callback.callback());
6251 EXPECT_GT(callback.GetResult(rv), 0);
6253 // Now make sure that the entry is preserved.
6254 trans->DoneReading();
6257 // Make sure that the ActiveEntry is gone.
6258 base::MessageLoop::current()->RunUntilIdle();
6260 // Read from the cache.
6261 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6263 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6264 EXPECT_EQ(1, cache.disk_cache()->open_count());
6265 EXPECT_EQ(1, cache.disk_cache()->create_count());
6268 // Tests that we don't mark entries as truncated and release the cache
6269 // entry when DoneReading() is called before any Read() calls, such as
6270 // for a redirect.
6271 TEST(HttpCache, DoneReading) {
6272 MockHttpCache cache;
6273 net::TestCompletionCallback callback;
6275 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6276 transaction.data = "";
6278 scoped_ptr<net::HttpTransaction> trans;
6279 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6281 MockHttpRequest request(transaction);
6282 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6283 EXPECT_EQ(net::OK, callback.GetResult(rv));
6285 trans->DoneReading();
6286 // Leave the transaction around.
6288 // Make sure that the ActiveEntry is gone.
6289 base::MessageLoop::current()->RunUntilIdle();
6291 // Read from the cache. This should not deadlock.
6292 RunTransactionTest(cache.http_cache(), transaction);
6294 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6295 EXPECT_EQ(1, cache.disk_cache()->open_count());
6296 EXPECT_EQ(1, cache.disk_cache()->create_count());
6299 // Tests that we stop caching when told.
6300 TEST(HttpCache, StopCachingDeletesEntry) {
6301 MockHttpCache cache;
6302 net::TestCompletionCallback callback;
6303 MockHttpRequest request(kSimpleGET_Transaction);
6306 scoped_ptr<net::HttpTransaction> trans;
6307 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6309 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6310 EXPECT_EQ(net::OK, callback.GetResult(rv));
6312 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6313 rv = trans->Read(buf.get(), 10, callback.callback());
6314 EXPECT_EQ(10, callback.GetResult(rv));
6316 trans->StopCaching();
6318 // We should be able to keep reading.
6319 rv = trans->Read(buf.get(), 256, callback.callback());
6320 EXPECT_GT(callback.GetResult(rv), 0);
6321 rv = trans->Read(buf.get(), 256, callback.callback());
6322 EXPECT_EQ(0, callback.GetResult(rv));
6325 // Make sure that the ActiveEntry is gone.
6326 base::MessageLoop::current()->RunUntilIdle();
6328 // Verify that the entry is gone.
6329 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6331 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6332 EXPECT_EQ(0, cache.disk_cache()->open_count());
6333 EXPECT_EQ(2, cache.disk_cache()->create_count());
6336 // Tests that we stop caching when told, even if DoneReading is called
6337 // after StopCaching.
6338 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6339 MockHttpCache cache;
6340 net::TestCompletionCallback callback;
6341 MockHttpRequest request(kSimpleGET_Transaction);
6344 scoped_ptr<net::HttpTransaction> trans;
6345 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6347 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6348 EXPECT_EQ(net::OK, callback.GetResult(rv));
6350 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6351 rv = trans->Read(buf.get(), 10, callback.callback());
6352 EXPECT_EQ(10, callback.GetResult(rv));
6354 trans->StopCaching();
6356 // We should be able to keep reading.
6357 rv = trans->Read(buf.get(), 256, callback.callback());
6358 EXPECT_GT(callback.GetResult(rv), 0);
6359 rv = trans->Read(buf.get(), 256, callback.callback());
6360 EXPECT_EQ(0, callback.GetResult(rv));
6362 // We should be able to call DoneReading.
6363 trans->DoneReading();
6366 // Make sure that the ActiveEntry is gone.
6367 base::MessageLoop::current()->RunUntilIdle();
6369 // Verify that the entry is gone.
6370 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6372 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6373 EXPECT_EQ(0, cache.disk_cache()->open_count());
6374 EXPECT_EQ(2, cache.disk_cache()->create_count());
6377 // Tests that we stop caching when told, when using auth.
6378 TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6379 MockHttpCache cache;
6380 net::TestCompletionCallback callback;
6381 MockTransaction mock_transaction(kSimpleGET_Transaction);
6382 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6383 AddMockTransaction(&mock_transaction);
6384 MockHttpRequest request(mock_transaction);
6387 scoped_ptr<net::HttpTransaction> trans;
6388 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6390 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6391 EXPECT_EQ(net::OK, callback.GetResult(rv));
6393 trans->StopCaching();
6395 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6396 rv = trans->Read(buf.get(), 10, callback.callback());
6397 EXPECT_EQ(callback.GetResult(rv), 10);
6399 RemoveMockTransaction(&mock_transaction);
6401 // Make sure that the ActiveEntry is gone.
6402 base::MessageLoop::current()->RunUntilIdle();
6404 // Verify that the entry is gone.
6405 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6407 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6408 EXPECT_EQ(0, cache.disk_cache()->open_count());
6409 EXPECT_EQ(2, cache.disk_cache()->create_count());
6412 // Tests that when we are told to stop caching we don't throw away valid data.
6413 TEST(HttpCache, StopCachingSavesEntry) {
6414 MockHttpCache cache;
6415 net::TestCompletionCallback callback;
6416 MockHttpRequest request(kSimpleGET_Transaction);
6419 scoped_ptr<net::HttpTransaction> trans;
6420 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6422 // Force a response that can be resumed.
6423 MockTransaction mock_transaction(kSimpleGET_Transaction);
6424 AddMockTransaction(&mock_transaction);
6425 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6426 "Content-Length: 42\n"
6427 "Etag: \"foo\"\n";
6429 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6430 EXPECT_EQ(net::OK, callback.GetResult(rv));
6432 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6433 rv = trans->Read(buf.get(), 10, callback.callback());
6434 EXPECT_EQ(callback.GetResult(rv), 10);
6436 trans->StopCaching();
6438 // We should be able to keep reading.
6439 rv = trans->Read(buf.get(), 256, callback.callback());
6440 EXPECT_GT(callback.GetResult(rv), 0);
6441 rv = trans->Read(buf.get(), 256, callback.callback());
6442 EXPECT_EQ(callback.GetResult(rv), 0);
6444 RemoveMockTransaction(&mock_transaction);
6447 // Verify that the entry is marked as incomplete.
6448 disk_cache::Entry* entry;
6449 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6450 net::HttpResponseInfo response;
6451 bool truncated = false;
6452 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6453 EXPECT_TRUE(truncated);
6454 entry->Close();
6457 // Tests that we handle truncated enries when StopCaching is called.
6458 TEST(HttpCache, StopCachingTruncatedEntry) {
6459 MockHttpCache cache;
6460 net::TestCompletionCallback callback;
6461 MockHttpRequest request(kRangeGET_TransactionOK);
6462 request.extra_headers.Clear();
6463 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6464 AddMockTransaction(&kRangeGET_TransactionOK);
6466 std::string raw_headers("HTTP/1.1 200 OK\n"
6467 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6468 "ETag: \"foo\"\n"
6469 "Accept-Ranges: bytes\n"
6470 "Content-Length: 80\n");
6471 CreateTruncatedEntry(raw_headers, &cache);
6474 // Now make a regular request.
6475 scoped_ptr<net::HttpTransaction> trans;
6476 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6478 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6479 EXPECT_EQ(net::OK, callback.GetResult(rv));
6481 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6482 rv = trans->Read(buf.get(), 10, callback.callback());
6483 EXPECT_EQ(callback.GetResult(rv), 10);
6485 // This is actually going to do nothing.
6486 trans->StopCaching();
6488 // We should be able to keep reading.
6489 rv = trans->Read(buf.get(), 256, callback.callback());
6490 EXPECT_GT(callback.GetResult(rv), 0);
6491 rv = trans->Read(buf.get(), 256, callback.callback());
6492 EXPECT_GT(callback.GetResult(rv), 0);
6493 rv = trans->Read(buf.get(), 256, callback.callback());
6494 EXPECT_EQ(callback.GetResult(rv), 0);
6497 // Verify that the disk entry was updated.
6498 disk_cache::Entry* entry;
6499 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6500 EXPECT_EQ(80, entry->GetDataSize(1));
6501 bool truncated = true;
6502 net::HttpResponseInfo response;
6503 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6504 EXPECT_FALSE(truncated);
6505 entry->Close();
6507 RemoveMockTransaction(&kRangeGET_TransactionOK);
6510 // Tests that we detect truncated resources from the net when there is
6511 // a Content-Length header.
6512 TEST(HttpCache, TruncatedByContentLength) {
6513 MockHttpCache cache;
6514 net::TestCompletionCallback callback;
6516 MockTransaction transaction(kSimpleGET_Transaction);
6517 AddMockTransaction(&transaction);
6518 transaction.response_headers = "Cache-Control: max-age=10000\n"
6519 "Content-Length: 100\n";
6520 RunTransactionTest(cache.http_cache(), transaction);
6521 RemoveMockTransaction(&transaction);
6523 // Read from the cache.
6524 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6526 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6527 EXPECT_EQ(0, cache.disk_cache()->open_count());
6528 EXPECT_EQ(2, cache.disk_cache()->create_count());
6531 // Tests that we actually flag entries as truncated when we detect an error
6532 // from the net.
6533 TEST(HttpCache, TruncatedByContentLength2) {
6534 MockHttpCache cache;
6535 net::TestCompletionCallback callback;
6537 MockTransaction transaction(kSimpleGET_Transaction);
6538 AddMockTransaction(&transaction);
6539 transaction.response_headers = "Cache-Control: max-age=10000\n"
6540 "Content-Length: 100\n"
6541 "Etag: \"foo\"\n";
6542 RunTransactionTest(cache.http_cache(), transaction);
6543 RemoveMockTransaction(&transaction);
6545 // Verify that the entry is marked as incomplete.
6546 disk_cache::Entry* entry;
6547 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6548 net::HttpResponseInfo response;
6549 bool truncated = false;
6550 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6551 EXPECT_TRUE(truncated);
6552 entry->Close();
6555 // Make sure that calling SetPriority on a cache transaction passes on
6556 // its priority updates to its underlying network transaction.
6557 TEST(HttpCache, SetPriority) {
6558 MockHttpCache cache;
6560 scoped_ptr<net::HttpTransaction> trans;
6561 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6563 // Shouldn't crash, but doesn't do anything either.
6564 trans->SetPriority(net::LOW);
6566 EXPECT_FALSE(cache.network_layer()->last_transaction());
6567 EXPECT_EQ(net::DEFAULT_PRIORITY,
6568 cache.network_layer()->last_create_transaction_priority());
6570 net::HttpRequestInfo info;
6571 info.url = GURL(kSimpleGET_Transaction.url);
6572 net::TestCompletionCallback callback;
6573 EXPECT_EQ(net::ERR_IO_PENDING,
6574 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6576 EXPECT_TRUE(cache.network_layer()->last_transaction());
6577 if (cache.network_layer()->last_transaction()) {
6578 EXPECT_EQ(net::LOW,
6579 cache.network_layer()->last_create_transaction_priority());
6580 EXPECT_EQ(net::LOW,
6581 cache.network_layer()->last_transaction()->priority());
6584 trans->SetPriority(net::HIGHEST);
6586 if (cache.network_layer()->last_transaction()) {
6587 EXPECT_EQ(net::LOW,
6588 cache.network_layer()->last_create_transaction_priority());
6589 EXPECT_EQ(net::HIGHEST,
6590 cache.network_layer()->last_transaction()->priority());
6593 EXPECT_EQ(net::OK, callback.WaitForResult());
6596 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6597 // transaction passes on its argument to the underlying network transaction.
6598 TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
6599 MockHttpCache cache;
6601 FakeWebSocketHandshakeStreamCreateHelper create_helper;
6602 scoped_ptr<net::HttpTransaction> trans;
6603 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6605 EXPECT_FALSE(cache.network_layer()->last_transaction());
6607 net::HttpRequestInfo info;
6608 info.url = GURL(kSimpleGET_Transaction.url);
6609 net::TestCompletionCallback callback;
6610 EXPECT_EQ(net::ERR_IO_PENDING,
6611 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6613 ASSERT_TRUE(cache.network_layer()->last_transaction());
6614 EXPECT_FALSE(cache.network_layer()->last_transaction()->
6615 websocket_handshake_stream_create_helper());
6616 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
6617 EXPECT_EQ(&create_helper,
6618 cache.network_layer()->last_transaction()->
6619 websocket_handshake_stream_create_helper());
6620 EXPECT_EQ(net::OK, callback.WaitForResult());
6623 // Make sure that a cache transaction passes on its priority to
6624 // newly-created network transactions.
6625 TEST(HttpCache, SetPriorityNewTransaction) {
6626 MockHttpCache cache;
6627 AddMockTransaction(&kRangeGET_TransactionOK);
6629 std::string raw_headers("HTTP/1.1 200 OK\n"
6630 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6631 "ETag: \"foo\"\n"
6632 "Accept-Ranges: bytes\n"
6633 "Content-Length: 80\n");
6634 CreateTruncatedEntry(raw_headers, &cache);
6636 // Now make a regular request.
6637 std::string headers;
6638 MockTransaction transaction(kRangeGET_TransactionOK);
6639 transaction.request_headers = EXTRA_HEADER;
6640 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6641 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6643 scoped_ptr<net::HttpTransaction> trans;
6644 ASSERT_EQ(net::OK,
6645 cache.http_cache()->CreateTransaction(net::MEDIUM, &trans));
6646 EXPECT_EQ(net::DEFAULT_PRIORITY,
6647 cache.network_layer()->last_create_transaction_priority());
6649 MockHttpRequest info(transaction);
6650 net::TestCompletionCallback callback;
6651 EXPECT_EQ(net::ERR_IO_PENDING,
6652 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6653 EXPECT_EQ(net::OK, callback.WaitForResult());
6655 EXPECT_EQ(net::MEDIUM,
6656 cache.network_layer()->last_create_transaction_priority());
6658 trans->SetPriority(net::HIGHEST);
6659 // Should trigger a new network transaction and pick up the new
6660 // priority.
6661 ReadAndVerifyTransaction(trans.get(), transaction);
6663 EXPECT_EQ(net::HIGHEST,
6664 cache.network_layer()->last_create_transaction_priority());
6666 RemoveMockTransaction(&kRangeGET_TransactionOK);
6669 int64 RunTransactionAndGetReceivedBytes(
6670 MockHttpCache& cache,
6671 const MockTransaction& trans_info) {
6672 int64 received_bytes = -1;
6673 RunTransactionTestBase(cache.http_cache(), trans_info,
6674 MockHttpRequest(trans_info), NULL, net::BoundNetLog(),
6675 NULL, &received_bytes);
6676 return received_bytes;
6679 int64 TransactionSize(const MockTransaction& transaction) {
6680 return strlen(transaction.status) + strlen(transaction.response_headers) +
6681 strlen(transaction.data);
6684 TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
6685 MockHttpCache cache;
6687 MockTransaction transaction(kSimpleGET_Transaction);
6688 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6689 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6691 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6692 EXPECT_EQ(0, received_bytes);
6695 TEST(HttpCache, ReceivedBytesConditionalRequest304) {
6696 MockHttpCache cache;
6698 ScopedMockTransaction transaction(kETagGET_Transaction);
6699 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6700 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6702 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
6703 transaction.handler = ETagGet_ConditionalRequest_Handler;
6704 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6705 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6708 TEST(HttpCache, ReceivedBytesConditionalRequest200) {
6709 MockHttpCache cache;
6711 MockTransaction transaction(kTypicalGET_Transaction);
6712 transaction.request_headers = "Foo: bar\r\n";
6713 transaction.response_headers =
6714 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6715 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6716 "Etag: \"foopy\"\n"
6717 "Cache-Control: max-age=0\n"
6718 "Vary: Foo\n";
6719 AddMockTransaction(&transaction);
6720 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6721 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6723 RevalidationServer server;
6724 transaction.handler = server.Handler;
6725 transaction.request_headers = "Foo: none\r\n";
6726 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6727 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6729 RemoveMockTransaction(&transaction);
6732 TEST(HttpCache, ReceivedBytesRange) {
6733 MockHttpCache cache;
6734 AddMockTransaction(&kRangeGET_TransactionOK);
6735 MockTransaction transaction(kRangeGET_TransactionOK);
6737 // Read bytes 40-49 from the network.
6738 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6739 int64 range_response_size = TransactionSize(transaction);
6740 EXPECT_EQ(range_response_size, received_bytes);
6742 // Read bytes 40-49 from the cache.
6743 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6744 EXPECT_EQ(0, received_bytes);
6745 base::MessageLoop::current()->RunUntilIdle();
6747 // Read bytes 30-39 from the network.
6748 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
6749 transaction.data = "rg: 30-39 ";
6750 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6751 EXPECT_EQ(range_response_size, received_bytes);
6752 base::MessageLoop::current()->RunUntilIdle();
6754 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6755 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
6756 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6757 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6758 EXPECT_EQ(range_response_size * 2, received_bytes);
6760 RemoveMockTransaction(&kRangeGET_TransactionOK);
6763 // Framework for tests of stale-while-revalidate related functionality. With
6764 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
6765 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
6766 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
6767 // synchronous revalidation.
6768 class HttpCacheStaleWhileRevalidateTest : public ::testing::Test {
6769 protected:
6770 HttpCacheStaleWhileRevalidateTest()
6771 : transaction_(kSimpleGET_Transaction),
6772 age_(3601),
6773 stale_while_revalidate_(7200),
6774 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
6775 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true);
6778 // RunTransactionTest() with the arguments from this fixture.
6779 void RunFixtureTransactionTest() {
6780 std::string response_headers = base::StringPrintf(
6781 "%s\n"
6782 "Age: %d\n"
6783 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
6784 validator_.c_str(),
6785 age_,
6786 stale_while_revalidate_);
6787 transaction_.response_headers = response_headers.c_str();
6788 RunTransactionTest(cache_.http_cache(), transaction_);
6789 transaction_.response_headers = "";
6792 // How many times this test has sent requests to the (fake) origin
6793 // server. Every test case needs to make at least one request to initialise
6794 // the cache.
6795 int transaction_count() {
6796 return cache_.network_layer()->transaction_count();
6799 // How many times an existing cache entry was opened during the test case.
6800 int open_count() { return cache_.disk_cache()->open_count(); }
6802 MockHttpCache cache_;
6803 ScopedMockTransaction transaction_;
6804 int age_;
6805 int stale_while_revalidate_;
6806 std::string validator_;
6809 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request,
6810 std::string* response_status,
6811 std::string* response_headers,
6812 std::string* response_data) {
6813 std::string value;
6814 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
6815 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
6818 // Verify that the Resource-Freshness header is sent on a revalidation if the
6819 // stale-while-revalidate directive was on the response.
6820 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) {
6821 age_ = 10801; // Outside the stale-while-revalidate window.
6823 // Write to the cache.
6824 RunFixtureTransactionTest();
6826 EXPECT_EQ(1, transaction_count());
6828 // Send the request again and check that Resource-Freshness header is added.
6829 transaction_.handler = CheckResourceFreshnessHeader;
6831 RunFixtureTransactionTest();
6833 EXPECT_EQ(2, transaction_count());
6836 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request,
6837 std::string* response_status,
6838 std::string* response_headers,
6839 std::string* response_data) {
6840 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
6843 // Verify that the Resource-Freshness header is not sent when
6844 // stale-while-revalidate is 0.
6845 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) {
6846 age_ = 10801;
6847 stale_while_revalidate_ = 0;
6849 // Write to the cache.
6850 RunFixtureTransactionTest();
6852 EXPECT_EQ(1, transaction_count());
6854 // Send the request again and check that Resource-Freshness header is absent.
6855 transaction_.handler = CheckResourceFreshnessAbsent;
6857 RunFixtureTransactionTest();
6859 EXPECT_EQ(2, transaction_count());
6862 // Verify that when stale-while-revalidate applies the response is read from
6863 // cache.
6864 TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) {
6865 // Write to the cache.
6866 RunFixtureTransactionTest();
6868 EXPECT_EQ(0, open_count());
6869 EXPECT_EQ(1, transaction_count());
6871 // Read back from the cache.
6872 RunFixtureTransactionTest();
6874 EXPECT_EQ(1, open_count());
6875 EXPECT_EQ(1, transaction_count());
6878 // Verify that when stale-while-revalidate applies an asynchronous request is
6879 // sent.
6880 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) {
6881 // Write to the cache.
6882 RunFixtureTransactionTest();
6884 EXPECT_EQ(1, transaction_count());
6886 // Read back from the cache.
6887 RunFixtureTransactionTest();
6889 EXPECT_EQ(1, transaction_count());
6891 // Let the async request execute.
6892 base::RunLoop().RunUntilIdle();
6893 EXPECT_EQ(2, transaction_count());
6896 // Verify that tearing down the HttpCache with an async revalidation in progress
6897 // does not break anything (this test is most likely to find problems when run
6898 // with a memory checker such as AddressSanitizer).
6899 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) {
6900 // Write to the cache.
6901 RunFixtureTransactionTest();
6903 // Read back from the cache.
6904 RunFixtureTransactionTest();
6907 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo* request,
6908 std::string* response_status,
6909 std::string* response_headers,
6910 std::string* response_data) {
6911 std::string value;
6912 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value));
6913 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value);
6916 // Verify that the async revalidation contains an If-Modified-Since header.
6917 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) {
6918 // Write to the cache.
6919 RunFixtureTransactionTest();
6921 transaction_.handler = CheckIfModifiedSinceHeader;
6923 // Read back from the cache.
6924 RunFixtureTransactionTest();
6927 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo* request,
6928 std::string* response_status,
6929 std::string* response_headers,
6930 std::string* response_data) {
6931 std::string value;
6932 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value));
6933 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value);
6936 // If the response had ETag rather than Last-Modified, then that is used to
6937 // conditionalise the response.
6938 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) {
6939 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\"";
6941 // Write to the cache.
6942 RunFixtureTransactionTest();
6944 transaction_.handler = CheckIfNoneMatchHeader;
6946 // Read back from the cache.
6947 RunFixtureTransactionTest();
6950 static void CheckResourceFreshnessHeaderPresent(
6951 const net::HttpRequestInfo* request,
6952 std::string* response_status,
6953 std::string* response_headers,
6954 std::string* response_data) {
6955 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness"));
6958 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) {
6959 // Write to the cache.
6960 RunFixtureTransactionTest();
6962 transaction_.handler = CheckResourceFreshnessHeaderPresent;
6964 // Read back from the cache.
6965 RunFixtureTransactionTest();
6968 // Verify that when age > max-age + stale-while-revalidate stale results are
6969 // not returned.
6970 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) {
6971 age_ = 10801;
6973 // Write to the cache.
6974 RunFixtureTransactionTest();
6976 EXPECT_EQ(0, open_count());
6977 EXPECT_EQ(1, transaction_count());
6979 // Reading back reads from the network.
6980 RunFixtureTransactionTest();
6982 EXPECT_EQ(1, open_count());
6983 EXPECT_EQ(2, transaction_count());
6986 // HEAD requests should be able to take advantage of stale-while-revalidate.
6987 TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) {
6988 // Write to the cache. This has to be a GET request; HEAD requests don't
6989 // create new cache entries.
6990 RunFixtureTransactionTest();
6992 EXPECT_EQ(0, open_count());
6993 EXPECT_EQ(1, transaction_count());
6995 // Read back from the cache, and trigger an asynchronous HEAD request.
6996 transaction_.method = "HEAD";
6997 transaction_.data = "";
6999 RunFixtureTransactionTest();
7001 EXPECT_EQ(1, open_count());
7002 EXPECT_EQ(1, transaction_count());
7004 // Let the network request proceed.
7005 base::RunLoop().RunUntilIdle();
7007 EXPECT_EQ(2, transaction_count());
7010 // POST requests should not use stale-while-revalidate.
7011 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) {
7012 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction);
7014 // Write to the cache.
7015 RunFixtureTransactionTest();
7017 EXPECT_EQ(0, open_count());
7018 EXPECT_EQ(1, transaction_count());
7020 // Reading back reads from the network.
7021 RunFixtureTransactionTest();
7023 EXPECT_EQ(0, open_count());
7024 EXPECT_EQ(2, transaction_count());
7027 static void CheckUrlMatches(const net::HttpRequestInfo* request,
7028 std::string* response_status,
7029 std::string* response_headers,
7030 std::string* response_data) {
7031 EXPECT_EQ("http://www.google.com/", request->url.spec());
7034 // Async revalidation is issued to the original URL.
7035 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) {
7036 transaction_.url = "http://www.google.com/";
7037 // Write to the cache.
7038 RunFixtureTransactionTest();
7040 // Read back from the cache.
7041 RunFixtureTransactionTest();
7043 EXPECT_EQ(1, transaction_count());
7045 transaction_.handler = CheckUrlMatches;
7047 // Let the async request execute and perform the check.
7048 base::RunLoop().RunUntilIdle();
7049 EXPECT_EQ(2, transaction_count());
7052 class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest,
7053 public ::testing::WithParamInterface<int> {};
7055 // Flags which should always cause the request to be synchronous.
7056 TEST_P(SyncLoadFlagTest, MustBeSynchronous) {
7057 transaction_.load_flags |= GetParam();
7058 // Write to the cache.
7059 RunFixtureTransactionTest();
7061 EXPECT_EQ(1, transaction_count());
7063 // Reading back reads from the network.
7064 RunFixtureTransactionTest();
7066 EXPECT_EQ(2, transaction_count());
7069 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate,
7070 SyncLoadFlagTest,
7071 ::testing::Values(net::LOAD_VALIDATE_CACHE,
7072 net::LOAD_BYPASS_CACHE,
7073 net::LOAD_DISABLE_CACHE));
7075 TEST_F(HttpCacheStaleWhileRevalidateTest,
7076 PreferringCacheDoesNotTriggerAsyncRequest) {
7077 transaction_.load_flags |= net::LOAD_PREFERRING_CACHE;
7078 // Write to the cache.
7079 RunFixtureTransactionTest();
7081 EXPECT_EQ(1, transaction_count());
7083 // Reading back reads from the cache.
7084 RunFixtureTransactionTest();
7086 EXPECT_EQ(1, transaction_count());
7088 // If there was an async transaction created, it would run now.
7089 base::RunLoop().RunUntilIdle();
7091 // There was no async transaction.
7092 EXPECT_EQ(1, transaction_count());
7095 TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) {
7096 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7097 // Write to the cache.
7098 RunFixtureTransactionTest();
7100 EXPECT_EQ(1, transaction_count());
7102 // A synchronous revalidation is performed.
7103 RunFixtureTransactionTest();
7105 EXPECT_EQ(2, transaction_count());
7108 TEST_F(HttpCacheStaleWhileRevalidateTest,
7109 OnlyFromCacheDoesNotTriggerAsyncRequest) {
7110 transaction_.load_flags |= net::LOAD_ONLY_FROM_CACHE;
7111 transaction_.return_code = net::ERR_CACHE_MISS;
7113 // Writing to the cache should fail, because we are avoiding the network.
7114 RunFixtureTransactionTest();
7116 EXPECT_EQ(0, transaction_count());
7118 base::RunLoop().RunUntilIdle();
7120 // Still nothing.
7121 EXPECT_EQ(0, transaction_count());
7124 // A certificate error during an asynchronous fetch should cause the next fetch
7125 // to proceed synchronously.
7126 // TODO(ricea): In future, only certificate errors which require user
7127 // interaction should fail the asynchronous revalidation, and they should cause
7128 // the next revalidation to be synchronous rather than requiring a total
7129 // refetch. This test will need to be updated appropriately.
7130 TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) {
7131 // Write to the cache.
7132 RunFixtureTransactionTest();
7134 EXPECT_EQ(1, transaction_count());
7136 // Now read back. RunTransactionTestBase() expects to receive the network
7137 // error back from the HttpCache::Transaction, but since the cache request
7138 // will return OK we need to duplicate some of its implementation here.
7139 transaction_.return_code = net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
7140 net::TestCompletionCallback callback;
7141 scoped_ptr<net::HttpTransaction> trans;
7142 int rv =
7143 cache_.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
7144 EXPECT_EQ(net::OK, rv);
7145 ASSERT_TRUE(trans.get());
7147 MockHttpRequest request(transaction_);
7148 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
7149 ASSERT_EQ(net::ERR_IO_PENDING, rv);
7150 ASSERT_EQ(net::OK, callback.WaitForResult());
7151 ReadAndVerifyTransaction(trans.get(), transaction_);
7153 EXPECT_EQ(1, transaction_count());
7155 // Allow the asynchronous fetch to run.
7156 base::RunLoop().RunUntilIdle();
7158 EXPECT_EQ(2, transaction_count());
7160 // Now run the transaction again. It should run synchronously.
7161 transaction_.return_code = net::OK;
7162 RunFixtureTransactionTest();
7164 EXPECT_EQ(3, transaction_count());
7167 // Ensure that the response cached by the asynchronous request is not truncated,
7168 // even if the server is slow.
7169 TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) {
7170 transaction_.test_mode = TEST_MODE_SLOW_READ;
7171 // Write to the cache.
7172 RunFixtureTransactionTest();
7174 // Read back from the cache.
7175 RunFixtureTransactionTest();
7177 // Let the async request execute.
7178 base::RunLoop().RunUntilIdle();
7180 // The cache entry should still be complete.
7181 transaction_.load_flags = net::LOAD_ONLY_FROM_CACHE;
7182 RunFixtureTransactionTest();
7185 // Verify that there are no race conditions in the completely synchronous case.
7186 TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) {
7187 transaction_.test_mode = TEST_MODE_SYNC_ALL;
7188 // Write to the cache.
7189 RunFixtureTransactionTest();
7191 EXPECT_EQ(1, transaction_count());
7193 // Read back from the cache.
7194 RunFixtureTransactionTest();
7196 EXPECT_EQ(1, transaction_count());
7198 // Let the async request execute.
7199 base::RunLoop().RunUntilIdle();
7200 EXPECT_EQ(2, transaction_count());
7203 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo* request,
7204 std::string* response_status,
7205 std::string* response_headers,
7206 std::string* response_data) {
7207 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION, request->load_flags);
7210 // Check that the load flags on the async request are the same as the load flags
7211 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7212 TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) {
7213 transaction_.load_flags = net::LOAD_NORMAL;
7214 // Write to the cache.
7215 RunFixtureTransactionTest();
7217 EXPECT_EQ(1, transaction_count());
7219 // Read back from the cache.
7220 RunFixtureTransactionTest();
7222 EXPECT_EQ(1, transaction_count());
7224 transaction_.handler = CheckLoadFlagsAsyncRevalidation;
7225 // Let the async request execute.
7226 base::RunLoop().RunUntilIdle();
7227 EXPECT_EQ(2, transaction_count());
7230 static void SimpleMockAuthHandler(const net::HttpRequestInfo* request,
7231 std::string* response_status,
7232 std::string* response_headers,
7233 std::string* response_data) {
7234 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
7235 !request->extra_headers.HasHeader("Authorization")) {
7236 response_status->assign("HTTP/1.1 401 Unauthorized");
7237 response_headers->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7238 return;
7240 response_status->assign("HTTP/1.1 200 OK");
7243 TEST_F(HttpCacheStaleWhileRevalidateTest, RestartForAuth) {
7244 // Write to the cache.
7245 RunFixtureTransactionTest();
7247 EXPECT_EQ(1, transaction_count());
7249 // Now make the transaction require auth.
7250 transaction_.request_headers = "X-Require-Mock-Auth: dummy\r\n\r\n";
7251 transaction_.handler = SimpleMockAuthHandler;
7253 // Read back from the cache.
7254 RunFixtureTransactionTest();
7256 EXPECT_EQ(1, transaction_count());
7258 // Let the async request execute.
7259 base::RunLoop().RunUntilIdle();
7261 EXPECT_EQ(2, transaction_count());
7264 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7265 // take place on a sparse entry.
7266 TEST(HttpCache, RangeGET_MultipleRequests) {
7267 MockHttpCache cache;
7269 // Create a transaction for bytes 0-9.
7270 MockHttpRequest request(kRangeGET_TransactionOK);
7271 MockTransaction transaction(kRangeGET_TransactionOK);
7272 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7273 transaction.data = "rg: 00-09 ";
7274 AddMockTransaction(&transaction);
7276 net::TestCompletionCallback callback;
7277 scoped_ptr<net::HttpTransaction> trans;
7278 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
7279 EXPECT_EQ(net::OK, rv);
7280 ASSERT_TRUE(trans.get());
7282 // Start our transaction.
7283 trans->Start(&request, callback.callback(), net::BoundNetLog());
7285 // A second transaction on a different part of the file (the default
7286 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7287 // the already pending transaction.
7288 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7290 // Let the first transaction complete.
7291 callback.WaitForResult();
7293 RemoveMockTransaction(&transaction);
7296 // Makes sure that a request stops using the cache when the response headers
7297 // with "Cache-Control: no-store" arrives. That means that another request for
7298 // the same URL can be processed before the response body of the original
7299 // request arrives.
7300 TEST(HttpCache, NoStoreResponseShouldNotBlockFollowingRequests) {
7301 MockHttpCache cache;
7302 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
7303 mock_transaction.response_headers = "Cache-Control: no-store\n";
7304 MockHttpRequest request(mock_transaction);
7306 scoped_ptr<Context> first(new Context);
7307 first->result = cache.CreateTransaction(&first->trans);
7308 ASSERT_EQ(net::OK, first->result);
7309 EXPECT_EQ(net::LOAD_STATE_IDLE, first->trans->GetLoadState());
7310 first->result = first->trans->Start(
7311 &request, first->callback.callback(), net::BoundNetLog());
7312 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
7314 base::MessageLoop::current()->RunUntilIdle();
7315 EXPECT_EQ(net::LOAD_STATE_IDLE, first->trans->GetLoadState());
7316 ASSERT_TRUE(first->trans->GetResponseInfo());
7317 EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
7318 "Cache-Control", "no-store"));
7319 // Here we have read the response header but not read the response body yet.
7321 // Let us create the second (read) transaction.
7322 scoped_ptr<Context> second(new Context);
7323 second->result = cache.CreateTransaction(&second->trans);
7324 ASSERT_EQ(net::OK, second->result);
7325 EXPECT_EQ(net::LOAD_STATE_IDLE, second->trans->GetLoadState());
7326 second->result = second->trans->Start(
7327 &request, second->callback.callback(), net::BoundNetLog());
7329 // Here the second transaction proceeds without reading the first body.
7330 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
7331 base::MessageLoop::current()->RunUntilIdle();
7332 EXPECT_EQ(net::LOAD_STATE_IDLE, second->trans->GetLoadState());
7333 ASSERT_TRUE(second->trans->GetResponseInfo());
7334 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
7335 "Cache-Control", "no-store"));
7336 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);