[Extensions Toolbar] Move tab-specific logic and increase test robustness
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blob519936829b735347b954a8506a88a24891391e0a
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 ~FakeWebSocketHandshakeStreamCreateHelper() override {}
500 net::WebSocketHandshakeStreamBase* CreateBasicStream(
501 scoped_ptr<net::ClientSocketHandle> connect,
502 bool using_proxy) override {
503 return NULL;
505 net::WebSocketHandshakeStreamBase* CreateSpdyStream(
506 const base::WeakPtr<net::SpdySession>& session,
507 bool use_relative_url) override {
508 return NULL;
512 // Returns true if |entry| is not one of the log types paid attention to in this
513 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
514 // ignored.
515 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry& entry) {
516 switch (entry.type) {
517 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
518 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
519 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
520 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
521 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
522 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO:
523 return false;
524 default:
525 return true;
529 // Modifies |entries| to only include log entries created by the cache layer and
530 // asserted on in these tests.
531 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList* entries) {
532 entries->erase(std::remove_if(entries->begin(), entries->end(),
533 &ShouldIgnoreLogEntry),
534 entries->end());
537 } // namespace
540 //-----------------------------------------------------------------------------
541 // Tests.
543 TEST(HttpCache, CreateThenDestroy) {
544 MockHttpCache cache;
546 scoped_ptr<net::HttpTransaction> trans;
547 EXPECT_EQ(net::OK, cache.CreateTransaction(&trans));
548 ASSERT_TRUE(trans.get());
551 TEST(HttpCache, GetBackend) {
552 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
554 disk_cache::Backend* backend;
555 net::TestCompletionCallback cb;
556 // This will lazily initialize the backend.
557 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
558 EXPECT_EQ(net::OK, cb.GetResult(rv));
561 TEST(HttpCache, SimpleGET) {
562 MockHttpCache cache;
563 net::CapturingBoundNetLog log;
564 net::LoadTimingInfo load_timing_info;
566 // Write to the cache.
567 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
568 log.bound(), &load_timing_info);
570 EXPECT_EQ(1, cache.network_layer()->transaction_count());
571 EXPECT_EQ(0, cache.disk_cache()->open_count());
572 EXPECT_EQ(1, cache.disk_cache()->create_count());
573 TestLoadTimingNetworkRequest(load_timing_info);
576 TEST(HttpCache, SimpleGETNoDiskCache) {
577 MockHttpCache cache;
579 cache.disk_cache()->set_fail_requests();
581 net::CapturingBoundNetLog log;
582 net::LoadTimingInfo load_timing_info;
584 // Read from the network, and don't use the cache.
585 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
586 log.bound(), &load_timing_info);
588 // Check that the NetLog was filled as expected.
589 // (We attempted to both Open and Create entries, but both failed).
590 net::CapturingNetLog::CapturedEntryList entries;
591 log.GetEntries(&entries);
592 FilterLogEntries(&entries);
594 EXPECT_EQ(6u, entries.size());
595 EXPECT_TRUE(net::LogContainsBeginEvent(
596 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
597 EXPECT_TRUE(net::LogContainsEndEvent(
598 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
599 EXPECT_TRUE(net::LogContainsBeginEvent(
600 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
601 EXPECT_TRUE(net::LogContainsEndEvent(
602 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
603 EXPECT_TRUE(net::LogContainsBeginEvent(
604 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
605 EXPECT_TRUE(net::LogContainsEndEvent(
606 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
608 EXPECT_EQ(1, cache.network_layer()->transaction_count());
609 EXPECT_EQ(0, cache.disk_cache()->open_count());
610 EXPECT_EQ(0, cache.disk_cache()->create_count());
611 TestLoadTimingNetworkRequest(load_timing_info);
614 TEST(HttpCache, SimpleGETNoDiskCache2) {
615 // This will initialize a cache object with NULL backend.
616 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
617 factory->set_fail(true);
618 factory->FinishCreation(); // We'll complete synchronously.
619 MockHttpCache cache(factory);
621 // Read from the network, and don't use the cache.
622 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
624 EXPECT_EQ(1, cache.network_layer()->transaction_count());
625 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
628 // Tests that IOBuffers are not referenced after IO completes.
629 TEST(HttpCache, ReleaseBuffer) {
630 MockHttpCache cache;
632 // Write to the cache.
633 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
635 MockHttpRequest request(kSimpleGET_Transaction);
636 scoped_ptr<net::HttpTransaction> trans;
637 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
639 const int kBufferSize = 10;
640 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
641 net::ReleaseBufferCompletionCallback cb(buffer.get());
643 int rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
644 EXPECT_EQ(net::OK, cb.GetResult(rv));
646 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
647 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
650 TEST(HttpCache, SimpleGETWithDiskFailures) {
651 MockHttpCache cache;
653 cache.disk_cache()->set_soft_failures(true);
655 // Read from the network, and fail to write to the cache.
656 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
658 EXPECT_EQ(1, cache.network_layer()->transaction_count());
659 EXPECT_EQ(0, cache.disk_cache()->open_count());
660 EXPECT_EQ(1, cache.disk_cache()->create_count());
662 // This one should see an empty cache again.
663 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
665 EXPECT_EQ(2, cache.network_layer()->transaction_count());
666 EXPECT_EQ(0, cache.disk_cache()->open_count());
667 EXPECT_EQ(2, cache.disk_cache()->create_count());
670 // Tests that disk failures after the transaction has started don't cause the
671 // request to fail.
672 TEST(HttpCache, SimpleGETWithDiskFailures2) {
673 MockHttpCache cache;
675 MockHttpRequest request(kSimpleGET_Transaction);
677 scoped_ptr<Context> c(new Context());
678 int rv = cache.CreateTransaction(&c->trans);
679 ASSERT_EQ(net::OK, rv);
681 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
682 EXPECT_EQ(net::ERR_IO_PENDING, rv);
683 rv = c->callback.WaitForResult();
685 // Start failing request now.
686 cache.disk_cache()->set_soft_failures(true);
688 // We have to open the entry again to propagate the failure flag.
689 disk_cache::Entry* en;
690 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
691 en->Close();
693 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
694 c.reset();
696 EXPECT_EQ(1, cache.network_layer()->transaction_count());
697 EXPECT_EQ(1, cache.disk_cache()->open_count());
698 EXPECT_EQ(1, cache.disk_cache()->create_count());
700 // This one should see an empty cache again.
701 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
703 EXPECT_EQ(2, cache.network_layer()->transaction_count());
704 EXPECT_EQ(1, cache.disk_cache()->open_count());
705 EXPECT_EQ(2, cache.disk_cache()->create_count());
708 // Tests that we handle failures to read from the cache.
709 TEST(HttpCache, SimpleGETWithDiskFailures3) {
710 MockHttpCache cache;
712 // Read from the network, and write to the cache.
713 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
715 EXPECT_EQ(1, cache.network_layer()->transaction_count());
716 EXPECT_EQ(0, cache.disk_cache()->open_count());
717 EXPECT_EQ(1, cache.disk_cache()->create_count());
719 cache.disk_cache()->set_soft_failures(true);
721 // Now fail to read from the cache.
722 scoped_ptr<Context> c(new Context());
723 int rv = cache.CreateTransaction(&c->trans);
724 ASSERT_EQ(net::OK, rv);
726 MockHttpRequest request(kSimpleGET_Transaction);
727 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
728 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
730 // Now verify that the entry was removed from the cache.
731 cache.disk_cache()->set_soft_failures(false);
733 EXPECT_EQ(2, cache.network_layer()->transaction_count());
734 EXPECT_EQ(1, cache.disk_cache()->open_count());
735 EXPECT_EQ(2, cache.disk_cache()->create_count());
737 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
739 EXPECT_EQ(3, cache.network_layer()->transaction_count());
740 EXPECT_EQ(1, cache.disk_cache()->open_count());
741 EXPECT_EQ(3, cache.disk_cache()->create_count());
744 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
745 MockHttpCache cache;
747 net::CapturingBoundNetLog log;
748 net::LoadTimingInfo load_timing_info;
750 // Write to the cache.
751 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
752 log.bound(), &load_timing_info);
754 // Check that the NetLog was filled as expected.
755 net::CapturingNetLog::CapturedEntryList entries;
756 log.GetEntries(&entries);
757 FilterLogEntries(&entries);
759 EXPECT_EQ(8u, entries.size());
760 EXPECT_TRUE(net::LogContainsBeginEvent(
761 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
762 EXPECT_TRUE(net::LogContainsEndEvent(
763 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
764 EXPECT_TRUE(net::LogContainsBeginEvent(
765 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
766 EXPECT_TRUE(net::LogContainsEndEvent(
767 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
768 EXPECT_TRUE(net::LogContainsBeginEvent(
769 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
770 EXPECT_TRUE(net::LogContainsEndEvent(
771 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
772 EXPECT_TRUE(net::LogContainsBeginEvent(
773 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
774 EXPECT_TRUE(net::LogContainsEndEvent(
775 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
777 TestLoadTimingNetworkRequest(load_timing_info);
779 // Force this transaction to read from the cache.
780 MockTransaction transaction(kSimpleGET_Transaction);
781 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
783 log.Clear();
785 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
786 &load_timing_info);
788 // Check that the NetLog was filled as expected.
789 log.GetEntries(&entries);
790 FilterLogEntries(&entries);
792 EXPECT_EQ(8u, entries.size());
793 EXPECT_TRUE(net::LogContainsBeginEvent(
794 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
795 EXPECT_TRUE(net::LogContainsEndEvent(
796 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
797 EXPECT_TRUE(net::LogContainsBeginEvent(
798 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
799 EXPECT_TRUE(net::LogContainsEndEvent(
800 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
801 EXPECT_TRUE(net::LogContainsBeginEvent(
802 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
803 EXPECT_TRUE(net::LogContainsEndEvent(
804 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
805 EXPECT_TRUE(net::LogContainsBeginEvent(
806 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
807 EXPECT_TRUE(net::LogContainsEndEvent(
808 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
810 EXPECT_EQ(1, cache.network_layer()->transaction_count());
811 EXPECT_EQ(1, cache.disk_cache()->open_count());
812 EXPECT_EQ(1, cache.disk_cache()->create_count());
813 TestLoadTimingCachedResponse(load_timing_info);
816 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
817 MockHttpCache cache;
819 // force this transaction to read from the cache
820 MockTransaction transaction(kSimpleGET_Transaction);
821 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
823 MockHttpRequest request(transaction);
824 net::TestCompletionCallback callback;
826 scoped_ptr<net::HttpTransaction> trans;
827 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
829 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
830 if (rv == net::ERR_IO_PENDING)
831 rv = callback.WaitForResult();
832 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
834 trans.reset();
836 EXPECT_EQ(0, cache.network_layer()->transaction_count());
837 EXPECT_EQ(0, cache.disk_cache()->open_count());
838 EXPECT_EQ(0, cache.disk_cache()->create_count());
841 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
842 MockHttpCache cache;
844 // write to the cache
845 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
847 // force this transaction to read from the cache if valid
848 MockTransaction transaction(kSimpleGET_Transaction);
849 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
851 RunTransactionTest(cache.http_cache(), transaction);
853 EXPECT_EQ(1, cache.network_layer()->transaction_count());
854 EXPECT_EQ(1, cache.disk_cache()->open_count());
855 EXPECT_EQ(1, cache.disk_cache()->create_count());
858 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
859 MockHttpCache cache;
861 // force this transaction to read from the cache if valid
862 MockTransaction transaction(kSimpleGET_Transaction);
863 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
865 RunTransactionTest(cache.http_cache(), transaction);
867 EXPECT_EQ(1, cache.network_layer()->transaction_count());
868 EXPECT_EQ(0, cache.disk_cache()->open_count());
869 EXPECT_EQ(1, cache.disk_cache()->create_count());
872 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
873 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
874 MockHttpCache cache;
876 // Write to the cache.
877 MockTransaction transaction(kSimpleGET_Transaction);
878 transaction.request_headers = "Foo: bar\r\n";
879 transaction.response_headers = "Cache-Control: max-age=10000\n"
880 "Vary: Foo\n";
881 AddMockTransaction(&transaction);
882 RunTransactionTest(cache.http_cache(), transaction);
884 // Read from the cache.
885 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
886 RunTransactionTest(cache.http_cache(), transaction);
888 EXPECT_EQ(1, cache.network_layer()->transaction_count());
889 EXPECT_EQ(1, cache.disk_cache()->open_count());
890 EXPECT_EQ(1, cache.disk_cache()->create_count());
891 RemoveMockTransaction(&transaction);
894 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
895 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
896 MockHttpCache cache;
898 // Write to the cache.
899 MockTransaction transaction(kSimpleGET_Transaction);
900 transaction.request_headers = "Foo: bar\r\n";
901 transaction.response_headers = "Cache-Control: max-age=10000\n"
902 "Vary: Foo\n";
903 AddMockTransaction(&transaction);
904 RunTransactionTest(cache.http_cache(), transaction);
906 // Attempt to read from the cache... this is a vary mismatch that must reach
907 // the network again.
908 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
909 transaction.request_headers = "Foo: none\r\n";
910 net::CapturingBoundNetLog log;
911 net::LoadTimingInfo load_timing_info;
912 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
913 &load_timing_info);
915 EXPECT_EQ(2, cache.network_layer()->transaction_count());
916 EXPECT_EQ(1, cache.disk_cache()->open_count());
917 EXPECT_EQ(1, cache.disk_cache()->create_count());
918 TestLoadTimingNetworkRequest(load_timing_info);
919 RemoveMockTransaction(&transaction);
922 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
923 // network success
924 TEST(HttpCache, SimpleGET_CacheOverride_Network) {
925 MockHttpCache cache;
927 // Prime cache.
928 MockTransaction transaction(kSimpleGET_Transaction);
929 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
930 transaction.response_headers = "Cache-Control: no-cache\n";
932 AddMockTransaction(&transaction);
933 RunTransactionTest(cache.http_cache(), transaction);
934 EXPECT_EQ(1, cache.network_layer()->transaction_count());
935 EXPECT_EQ(1, cache.disk_cache()->create_count());
936 RemoveMockTransaction(&transaction);
938 // Re-run transaction; make sure the result came from the network,
939 // not the cache.
940 transaction.data = "Changed data.";
941 AddMockTransaction(&transaction);
942 net::HttpResponseInfo response_info;
943 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
944 &response_info);
946 EXPECT_EQ(2, cache.network_layer()->transaction_count());
947 EXPECT_FALSE(response_info.server_data_unavailable);
948 EXPECT_TRUE(response_info.network_accessed);
950 RemoveMockTransaction(&transaction);
953 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
954 // offline failure
955 TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
956 MockHttpCache cache;
958 // Prime cache.
959 MockTransaction transaction(kSimpleGET_Transaction);
960 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
961 transaction.response_headers = "Cache-Control: no-cache\n";
963 AddMockTransaction(&transaction);
964 RunTransactionTest(cache.http_cache(), transaction);
965 EXPECT_EQ(1, cache.network_layer()->transaction_count());
966 EXPECT_EQ(1, cache.disk_cache()->create_count());
967 RemoveMockTransaction(&transaction);
969 // Network failure with offline error; should return cache entry above +
970 // flag signalling stale data.
971 transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
972 AddMockTransaction(&transaction);
974 MockHttpRequest request(transaction);
975 net::TestCompletionCallback callback;
976 scoped_ptr<net::HttpTransaction> trans;
977 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
978 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
979 EXPECT_EQ(net::OK, callback.GetResult(rv));
981 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
982 ASSERT_TRUE(response_info);
983 EXPECT_TRUE(response_info->server_data_unavailable);
984 EXPECT_TRUE(response_info->was_cached);
985 EXPECT_FALSE(response_info->network_accessed);
986 ReadAndVerifyTransaction(trans.get(), transaction);
987 EXPECT_EQ(2, cache.network_layer()->transaction_count());
989 RemoveMockTransaction(&transaction);
992 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
993 // non-offline failure.
994 TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
995 MockHttpCache cache;
997 // Prime cache.
998 MockTransaction transaction(kSimpleGET_Transaction);
999 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1000 transaction.response_headers = "Cache-Control: no-cache\n";
1002 AddMockTransaction(&transaction);
1003 RunTransactionTest(cache.http_cache(), transaction);
1004 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1005 EXPECT_EQ(1, cache.disk_cache()->create_count());
1006 RemoveMockTransaction(&transaction);
1008 // Network failure with non-offline error; should fail with that error.
1009 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1010 AddMockTransaction(&transaction);
1012 net::HttpResponseInfo response_info2;
1013 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1014 &response_info2);
1016 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1017 EXPECT_FALSE(response_info2.server_data_unavailable);
1019 RemoveMockTransaction(&transaction);
1022 // Tests that was_cached was set properly on a failure, even if the cached
1023 // response wasn't returned.
1024 TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
1025 MockHttpCache cache;
1027 // Prime cache.
1028 MockTransaction transaction(kSimpleGET_Transaction);
1029 transaction.response_headers = "Cache-Control: no-cache\n";
1031 AddMockTransaction(&transaction);
1032 RunTransactionTest(cache.http_cache(), transaction);
1033 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1034 EXPECT_EQ(1, cache.disk_cache()->create_count());
1035 RemoveMockTransaction(&transaction);
1037 // Network failure with error; should fail but have was_cached set.
1038 transaction.return_code = net::ERR_FAILED;
1039 AddMockTransaction(&transaction);
1041 MockHttpRequest request(transaction);
1042 net::TestCompletionCallback callback;
1043 scoped_ptr<net::HttpTransaction> trans;
1044 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
1045 EXPECT_EQ(net::OK, rv);
1046 ASSERT_TRUE(trans.get());
1047 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1048 EXPECT_EQ(net::ERR_FAILED, callback.GetResult(rv));
1050 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1051 ASSERT_TRUE(response_info);
1052 EXPECT_TRUE(response_info->was_cached);
1053 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1055 RemoveMockTransaction(&transaction);
1058 // Confirm if we have an empty cache, a read is marked as network verified.
1059 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1060 MockHttpCache cache;
1062 // write to the cache
1063 net::HttpResponseInfo response_info;
1064 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1065 &response_info);
1067 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1068 EXPECT_EQ(0, cache.disk_cache()->open_count());
1069 EXPECT_EQ(1, cache.disk_cache()->create_count());
1070 EXPECT_TRUE(response_info.network_accessed);
1073 // Confirm if we have a fresh entry in cache, it isn't marked as
1074 // network verified.
1075 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1076 MockHttpCache cache;
1078 // Prime cache.
1079 MockTransaction transaction(kSimpleGET_Transaction);
1081 RunTransactionTest(cache.http_cache(), transaction);
1082 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1083 EXPECT_EQ(1, cache.disk_cache()->create_count());
1085 // Re-run transaction; make sure we don't mark the network as accessed.
1086 net::HttpResponseInfo response_info;
1087 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1088 &response_info);
1090 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1091 EXPECT_FALSE(response_info.server_data_unavailable);
1092 EXPECT_FALSE(response_info.network_accessed);
1095 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1096 MockHttpCache cache;
1098 // Write to the cache.
1099 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1101 // Force this transaction to write to the cache again.
1102 MockTransaction transaction(kSimpleGET_Transaction);
1103 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1105 net::CapturingBoundNetLog log;
1106 net::LoadTimingInfo load_timing_info;
1108 // Write to the cache.
1109 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1110 &load_timing_info);
1112 // Check that the NetLog was filled as expected.
1113 net::CapturingNetLog::CapturedEntryList entries;
1114 log.GetEntries(&entries);
1115 FilterLogEntries(&entries);
1117 EXPECT_EQ(8u, entries.size());
1118 EXPECT_TRUE(net::LogContainsBeginEvent(
1119 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1120 EXPECT_TRUE(net::LogContainsEndEvent(
1121 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1122 EXPECT_TRUE(net::LogContainsBeginEvent(
1123 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1124 EXPECT_TRUE(net::LogContainsEndEvent(
1125 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1126 EXPECT_TRUE(net::LogContainsBeginEvent(
1127 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1128 EXPECT_TRUE(net::LogContainsEndEvent(
1129 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1130 EXPECT_TRUE(net::LogContainsBeginEvent(
1131 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1132 EXPECT_TRUE(net::LogContainsEndEvent(
1133 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1135 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1136 EXPECT_EQ(0, cache.disk_cache()->open_count());
1137 EXPECT_EQ(2, cache.disk_cache()->create_count());
1138 TestLoadTimingNetworkRequest(load_timing_info);
1141 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1142 MockHttpCache cache;
1144 // write to the cache
1145 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1147 // force this transaction to write to the cache again
1148 MockTransaction transaction(kSimpleGET_Transaction);
1149 transaction.request_headers = "pragma: no-cache\r\n";
1151 RunTransactionTest(cache.http_cache(), transaction);
1153 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1154 EXPECT_EQ(0, cache.disk_cache()->open_count());
1155 EXPECT_EQ(2, cache.disk_cache()->create_count());
1158 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1159 MockHttpCache cache;
1161 // write to the cache
1162 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1164 // force this transaction to write to the cache again
1165 MockTransaction transaction(kSimpleGET_Transaction);
1166 transaction.request_headers = "cache-control: no-cache\r\n";
1168 RunTransactionTest(cache.http_cache(), transaction);
1170 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1171 EXPECT_EQ(0, cache.disk_cache()->open_count());
1172 EXPECT_EQ(2, cache.disk_cache()->create_count());
1175 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1176 MockHttpCache cache;
1178 // Write to the cache.
1179 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1181 // Read from the cache.
1182 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1184 // Force this transaction to validate the cache.
1185 MockTransaction transaction(kSimpleGET_Transaction);
1186 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1188 net::HttpResponseInfo response_info;
1189 net::CapturingBoundNetLog log;
1190 net::LoadTimingInfo load_timing_info;
1191 RunTransactionTestWithResponseInfoAndGetTiming(
1192 cache.http_cache(), transaction, &response_info, log.bound(),
1193 &load_timing_info);
1195 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1196 EXPECT_EQ(1, cache.disk_cache()->open_count());
1197 EXPECT_EQ(1, cache.disk_cache()->create_count());
1198 EXPECT_TRUE(response_info.network_accessed);
1199 TestLoadTimingNetworkRequest(load_timing_info);
1202 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1203 MockHttpCache cache;
1205 // write to the cache
1206 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1208 // read from the cache
1209 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1211 // force this transaction to validate the cache
1212 MockTransaction transaction(kSimpleGET_Transaction);
1213 transaction.request_headers = "cache-control: max-age=0\r\n";
1215 RunTransactionTest(cache.http_cache(), transaction);
1217 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1218 EXPECT_EQ(1, cache.disk_cache()->open_count());
1219 EXPECT_EQ(1, cache.disk_cache()->create_count());
1222 static void PreserveRequestHeaders_Handler(
1223 const net::HttpRequestInfo* request,
1224 std::string* response_status,
1225 std::string* response_headers,
1226 std::string* response_data) {
1227 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1230 // Tests that we don't remove extra headers for simple requests.
1231 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1232 MockHttpCache cache;
1234 MockTransaction transaction(kSimpleGET_Transaction);
1235 transaction.handler = PreserveRequestHeaders_Handler;
1236 transaction.request_headers = EXTRA_HEADER;
1237 transaction.response_headers = "Cache-Control: max-age=0\n";
1238 AddMockTransaction(&transaction);
1240 // Write, then revalidate the entry.
1241 RunTransactionTest(cache.http_cache(), transaction);
1242 RunTransactionTest(cache.http_cache(), transaction);
1244 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1245 EXPECT_EQ(1, cache.disk_cache()->open_count());
1246 EXPECT_EQ(1, cache.disk_cache()->create_count());
1247 RemoveMockTransaction(&transaction);
1250 // Tests that we don't remove extra headers for conditionalized requests.
1251 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1252 MockHttpCache cache;
1254 // Write to the cache.
1255 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1257 MockTransaction transaction(kETagGET_Transaction);
1258 transaction.handler = PreserveRequestHeaders_Handler;
1259 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1260 EXTRA_HEADER;
1261 AddMockTransaction(&transaction);
1263 RunTransactionTest(cache.http_cache(), transaction);
1265 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1266 EXPECT_EQ(1, cache.disk_cache()->open_count());
1267 EXPECT_EQ(1, cache.disk_cache()->create_count());
1268 RemoveMockTransaction(&transaction);
1271 TEST(HttpCache, SimpleGET_ManyReaders) {
1272 MockHttpCache cache;
1274 MockHttpRequest request(kSimpleGET_Transaction);
1276 std::vector<Context*> context_list;
1277 const int kNumTransactions = 5;
1279 for (int i = 0; i < kNumTransactions; ++i) {
1280 context_list.push_back(new Context());
1281 Context* c = context_list[i];
1283 c->result = cache.CreateTransaction(&c->trans);
1284 ASSERT_EQ(net::OK, c->result);
1285 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1287 c->result = c->trans->Start(
1288 &request, c->callback.callback(), net::BoundNetLog());
1291 // All requests are waiting for the active entry.
1292 for (int i = 0; i < kNumTransactions; ++i) {
1293 Context* c = context_list[i];
1294 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1297 // Allow all requests to move from the Create queue to the active entry.
1298 base::MessageLoop::current()->RunUntilIdle();
1300 // The first request should be a writer at this point, and the subsequent
1301 // requests should be pending.
1303 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1304 EXPECT_EQ(0, cache.disk_cache()->open_count());
1305 EXPECT_EQ(1, cache.disk_cache()->create_count());
1307 // All requests depend on the writer, and the writer is between Start and
1308 // Read, i.e. idle.
1309 for (int i = 0; i < kNumTransactions; ++i) {
1310 Context* c = context_list[i];
1311 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1314 for (int i = 0; i < kNumTransactions; ++i) {
1315 Context* c = context_list[i];
1316 if (c->result == net::ERR_IO_PENDING)
1317 c->result = c->callback.WaitForResult();
1318 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1321 // We should not have had to re-open the disk entry
1323 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1324 EXPECT_EQ(0, cache.disk_cache()->open_count());
1325 EXPECT_EQ(1, cache.disk_cache()->create_count());
1327 for (int i = 0; i < kNumTransactions; ++i) {
1328 Context* c = context_list[i];
1329 delete c;
1333 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1334 // If cancelling a request is racing with another request for the same resource
1335 // finishing, we have to make sure that we remove both transactions from the
1336 // entry.
1337 TEST(HttpCache, SimpleGET_RacingReaders) {
1338 MockHttpCache cache;
1340 MockHttpRequest request(kSimpleGET_Transaction);
1341 MockHttpRequest reader_request(kSimpleGET_Transaction);
1342 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1344 std::vector<Context*> context_list;
1345 const int kNumTransactions = 5;
1347 for (int i = 0; i < kNumTransactions; ++i) {
1348 context_list.push_back(new Context());
1349 Context* c = context_list[i];
1351 c->result = cache.CreateTransaction(&c->trans);
1352 ASSERT_EQ(net::OK, c->result);
1354 MockHttpRequest* this_request = &request;
1355 if (i == 1 || i == 2)
1356 this_request = &reader_request;
1358 c->result = c->trans->Start(
1359 this_request, c->callback.callback(), net::BoundNetLog());
1362 // Allow all requests to move from the Create queue to the active entry.
1363 base::MessageLoop::current()->RunUntilIdle();
1365 // The first request should be a writer at this point, and the subsequent
1366 // requests should be pending.
1368 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1369 EXPECT_EQ(0, cache.disk_cache()->open_count());
1370 EXPECT_EQ(1, cache.disk_cache()->create_count());
1372 Context* c = context_list[0];
1373 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1374 c->result = c->callback.WaitForResult();
1375 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1377 // Now we have 2 active readers and two queued transactions.
1379 EXPECT_EQ(net::LOAD_STATE_IDLE,
1380 context_list[2]->trans->GetLoadState());
1381 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1382 context_list[3]->trans->GetLoadState());
1384 c = context_list[1];
1385 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1386 c->result = c->callback.WaitForResult();
1387 if (c->result == net::OK)
1388 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1390 // At this point we have one reader, two pending transactions and a task on
1391 // the queue to move to the next transaction. Now we cancel the request that
1392 // is the current reader, and expect the queued task to be able to start the
1393 // next request.
1395 c = context_list[2];
1396 c->trans.reset();
1398 for (int i = 3; i < kNumTransactions; ++i) {
1399 Context* c = context_list[i];
1400 if (c->result == net::ERR_IO_PENDING)
1401 c->result = c->callback.WaitForResult();
1402 if (c->result == net::OK)
1403 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1406 // We should not have had to re-open the disk entry.
1408 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1409 EXPECT_EQ(0, cache.disk_cache()->open_count());
1410 EXPECT_EQ(1, cache.disk_cache()->create_count());
1412 for (int i = 0; i < kNumTransactions; ++i) {
1413 Context* c = context_list[i];
1414 delete c;
1418 // Tests that we can doom an entry with pending transactions and delete one of
1419 // the pending transactions before the first one completes.
1420 // See http://code.google.com/p/chromium/issues/detail?id=25588
1421 TEST(HttpCache, SimpleGET_DoomWithPending) {
1422 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1423 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1425 MockHttpRequest request(kSimpleGET_Transaction);
1426 MockHttpRequest writer_request(kSimpleGET_Transaction);
1427 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1429 ScopedVector<Context> context_list;
1430 const int kNumTransactions = 4;
1432 for (int i = 0; i < kNumTransactions; ++i) {
1433 context_list.push_back(new Context());
1434 Context* c = context_list[i];
1436 c->result = cache.CreateTransaction(&c->trans);
1437 ASSERT_EQ(net::OK, c->result);
1439 MockHttpRequest* this_request = &request;
1440 if (i == 3)
1441 this_request = &writer_request;
1443 c->result = c->trans->Start(
1444 this_request, c->callback.callback(), net::BoundNetLog());
1447 // The first request should be a writer at this point, and the two subsequent
1448 // requests should be pending. The last request doomed the first entry.
1450 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1452 // Cancel the first queued transaction.
1453 delete context_list[1];
1454 context_list.get()[1] = NULL;
1456 for (int i = 0; i < kNumTransactions; ++i) {
1457 if (i == 1)
1458 continue;
1459 Context* c = context_list[i];
1460 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1461 c->result = c->callback.WaitForResult();
1462 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1466 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1467 // We may attempt to delete an entry synchronously with the act of adding a new
1468 // transaction to said entry.
1469 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1470 MockHttpCache cache;
1472 // The headers will be served right from the call to Start() the request.
1473 MockHttpRequest request(kFastNoStoreGET_Transaction);
1474 FastTransactionServer request_handler;
1475 AddMockTransaction(&kFastNoStoreGET_Transaction);
1477 std::vector<Context*> context_list;
1478 const int kNumTransactions = 3;
1480 for (int i = 0; i < kNumTransactions; ++i) {
1481 context_list.push_back(new Context());
1482 Context* c = context_list[i];
1484 c->result = cache.CreateTransaction(&c->trans);
1485 ASSERT_EQ(net::OK, c->result);
1487 c->result = c->trans->Start(
1488 &request, c->callback.callback(), net::BoundNetLog());
1491 // Allow all requests to move from the Create queue to the active entry.
1492 base::MessageLoop::current()->RunUntilIdle();
1494 // The first request should be a writer at this point, and the subsequent
1495 // requests should be pending.
1497 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1498 EXPECT_EQ(0, cache.disk_cache()->open_count());
1499 EXPECT_EQ(1, cache.disk_cache()->create_count());
1501 // Now, make sure that the second request asks for the entry not to be stored.
1502 request_handler.set_no_store(true);
1504 for (int i = 0; i < kNumTransactions; ++i) {
1505 Context* c = context_list[i];
1506 if (c->result == net::ERR_IO_PENDING)
1507 c->result = c->callback.WaitForResult();
1508 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1509 delete c;
1512 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1513 EXPECT_EQ(0, cache.disk_cache()->open_count());
1514 EXPECT_EQ(2, cache.disk_cache()->create_count());
1516 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1519 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1520 MockHttpCache cache;
1522 MockHttpRequest request(kSimpleGET_Transaction);
1524 std::vector<Context*> context_list;
1525 const int kNumTransactions = 2;
1527 for (int i = 0; i < kNumTransactions; ++i) {
1528 context_list.push_back(new Context());
1529 Context* c = context_list[i];
1531 c->result = cache.CreateTransaction(&c->trans);
1532 ASSERT_EQ(net::OK, c->result);
1534 c->result = c->trans->Start(
1535 &request, c->callback.callback(), net::BoundNetLog());
1538 // Allow all requests to move from the Create queue to the active entry.
1539 base::MessageLoop::current()->RunUntilIdle();
1541 // The first request should be a writer at this point, and the subsequent
1542 // requests should be pending.
1544 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1545 EXPECT_EQ(0, cache.disk_cache()->open_count());
1546 EXPECT_EQ(1, cache.disk_cache()->create_count());
1548 for (int i = 0; i < kNumTransactions; ++i) {
1549 Context* c = context_list[i];
1550 if (c->result == net::ERR_IO_PENDING)
1551 c->result = c->callback.WaitForResult();
1552 // Destroy only the first transaction.
1553 if (i == 0) {
1554 delete c;
1555 context_list[i] = NULL;
1559 // Complete the rest of the transactions.
1560 for (int i = 1; i < kNumTransactions; ++i) {
1561 Context* c = context_list[i];
1562 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1565 // We should have had to re-open the disk entry.
1567 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1568 EXPECT_EQ(0, cache.disk_cache()->open_count());
1569 EXPECT_EQ(2, cache.disk_cache()->create_count());
1571 for (int i = 1; i < kNumTransactions; ++i) {
1572 Context* c = context_list[i];
1573 delete c;
1577 // Tests that we can cancel requests that are queued waiting to open the disk
1578 // cache entry.
1579 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1580 MockHttpCache cache;
1582 MockHttpRequest request(kSimpleGET_Transaction);
1584 std::vector<Context*> context_list;
1585 const int kNumTransactions = 5;
1587 for (int i = 0; i < kNumTransactions; i++) {
1588 context_list.push_back(new Context());
1589 Context* c = context_list[i];
1591 c->result = cache.CreateTransaction(&c->trans);
1592 ASSERT_EQ(net::OK, c->result);
1594 c->result = c->trans->Start(
1595 &request, c->callback.callback(), net::BoundNetLog());
1598 // The first request should be creating the disk cache entry and the others
1599 // should be pending.
1601 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1602 EXPECT_EQ(0, cache.disk_cache()->open_count());
1603 EXPECT_EQ(1, cache.disk_cache()->create_count());
1605 // Cancel a request from the pending queue.
1606 delete context_list[3];
1607 context_list[3] = NULL;
1609 // Cancel the request that is creating the entry. This will force the pending
1610 // operations to restart.
1611 delete context_list[0];
1612 context_list[0] = NULL;
1614 // Complete the rest of the transactions.
1615 for (int i = 1; i < kNumTransactions; i++) {
1616 Context* c = context_list[i];
1617 if (c) {
1618 c->result = c->callback.GetResult(c->result);
1619 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1623 // We should have had to re-create the disk entry.
1625 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1626 EXPECT_EQ(0, cache.disk_cache()->open_count());
1627 EXPECT_EQ(2, cache.disk_cache()->create_count());
1629 for (int i = 1; i < kNumTransactions; ++i) {
1630 delete context_list[i];
1634 // Tests that we can cancel a single request to open a disk cache entry.
1635 TEST(HttpCache, SimpleGET_CancelCreate) {
1636 MockHttpCache cache;
1638 MockHttpRequest request(kSimpleGET_Transaction);
1640 Context* c = new Context();
1642 c->result = cache.CreateTransaction(&c->trans);
1643 ASSERT_EQ(net::OK, c->result);
1645 c->result = c->trans->Start(
1646 &request, c->callback.callback(), net::BoundNetLog());
1647 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1649 // Release the reference that the mock disk cache keeps for this entry, so
1650 // that we test that the http cache handles the cancellation correctly.
1651 cache.disk_cache()->ReleaseAll();
1652 delete c;
1654 base::MessageLoop::current()->RunUntilIdle();
1655 EXPECT_EQ(1, cache.disk_cache()->create_count());
1658 // Tests that we delete/create entries even if multiple requests are queued.
1659 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1660 MockHttpCache cache;
1662 MockHttpRequest request(kSimpleGET_Transaction);
1663 request.load_flags = net::LOAD_BYPASS_CACHE;
1665 std::vector<Context*> context_list;
1666 const int kNumTransactions = 5;
1668 for (int i = 0; i < kNumTransactions; i++) {
1669 context_list.push_back(new Context());
1670 Context* c = context_list[i];
1672 c->result = cache.CreateTransaction(&c->trans);
1673 ASSERT_EQ(net::OK, c->result);
1675 c->result = c->trans->Start(
1676 &request, c->callback.callback(), net::BoundNetLog());
1679 // The first request should be deleting the disk cache entry and the others
1680 // should be pending.
1682 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1683 EXPECT_EQ(0, cache.disk_cache()->open_count());
1684 EXPECT_EQ(0, cache.disk_cache()->create_count());
1686 // Complete the transactions.
1687 for (int i = 0; i < kNumTransactions; i++) {
1688 Context* c = context_list[i];
1689 c->result = c->callback.GetResult(c->result);
1690 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1693 // We should have had to re-create the disk entry multiple times.
1695 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1696 EXPECT_EQ(0, cache.disk_cache()->open_count());
1697 EXPECT_EQ(5, cache.disk_cache()->create_count());
1699 for (int i = 0; i < kNumTransactions; ++i) {
1700 delete context_list[i];
1704 // Tests that a (simulated) timeout allows transactions waiting on the cache
1705 // lock to continue.
1706 TEST(HttpCache, SimpleGET_WriterTimeout) {
1707 MockHttpCache cache;
1708 cache.BypassCacheLock();
1710 MockHttpRequest request(kSimpleGET_Transaction);
1711 Context c1, c2;
1712 ASSERT_EQ(net::OK, cache.CreateTransaction(&c1.trans));
1713 ASSERT_EQ(net::ERR_IO_PENDING,
1714 c1.trans->Start(&request, c1.callback.callback(),
1715 net::BoundNetLog()));
1716 ASSERT_EQ(net::OK, cache.CreateTransaction(&c2.trans));
1717 ASSERT_EQ(net::ERR_IO_PENDING,
1718 c2.trans->Start(&request, c2.callback.callback(),
1719 net::BoundNetLog()));
1721 // The second request is queued after the first one.
1723 c2.callback.WaitForResult();
1724 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1726 // Complete the first transaction.
1727 c1.callback.WaitForResult();
1728 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1731 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1732 MockHttpCache cache;
1734 // write to the cache
1735 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1737 MockHttpRequest request(kSimpleGET_Transaction);
1738 net::TestCompletionCallback callback;
1740 scoped_ptr<net::HttpTransaction> trans;
1741 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
1742 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1743 if (rv == net::ERR_IO_PENDING)
1744 rv = callback.WaitForResult();
1745 ASSERT_EQ(net::OK, rv);
1747 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1748 rv = trans->Read(buf.get(), 256, callback.callback());
1749 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1751 // Test that destroying the transaction while it is reading from the cache
1752 // works properly.
1753 trans.reset();
1755 // Make sure we pump any pending events, which should include a call to
1756 // HttpCache::Transaction::OnCacheReadCompleted.
1757 base::MessageLoop::current()->RunUntilIdle();
1760 // Tests that we can delete the HttpCache and deal with queued transactions
1761 // ("waiting for the backend" as opposed to Active or Doomed entries).
1762 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1763 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1764 new MockBackendNoCbFactory()));
1766 MockHttpRequest request(kSimpleGET_Transaction);
1768 std::vector<Context*> context_list;
1769 const int kNumTransactions = 5;
1771 for (int i = 0; i < kNumTransactions; i++) {
1772 context_list.push_back(new Context());
1773 Context* c = context_list[i];
1775 c->result = cache->CreateTransaction(&c->trans);
1776 ASSERT_EQ(net::OK, c->result);
1778 c->result = c->trans->Start(
1779 &request, c->callback.callback(), net::BoundNetLog());
1782 // The first request should be creating the disk cache entry and the others
1783 // should be pending.
1785 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1786 EXPECT_EQ(0, cache->disk_cache()->open_count());
1787 EXPECT_EQ(0, cache->disk_cache()->create_count());
1789 cache.reset();
1791 // There is not much to do with the transactions at this point... they are
1792 // waiting for a callback that will not fire.
1793 for (int i = 0; i < kNumTransactions; ++i) {
1794 delete context_list[i];
1798 // Tests that we queue requests when initializing the backend.
1799 TEST(HttpCache, SimpleGET_WaitForBackend) {
1800 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1801 MockHttpCache cache(factory);
1803 MockHttpRequest request0(kSimpleGET_Transaction);
1804 MockHttpRequest request1(kTypicalGET_Transaction);
1805 MockHttpRequest request2(kETagGET_Transaction);
1807 std::vector<Context*> context_list;
1808 const int kNumTransactions = 3;
1810 for (int i = 0; i < kNumTransactions; i++) {
1811 context_list.push_back(new Context());
1812 Context* c = context_list[i];
1814 c->result = cache.CreateTransaction(&c->trans);
1815 ASSERT_EQ(net::OK, c->result);
1818 context_list[0]->result = context_list[0]->trans->Start(
1819 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1820 context_list[1]->result = context_list[1]->trans->Start(
1821 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1822 context_list[2]->result = context_list[2]->trans->Start(
1823 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1825 // Just to make sure that everything is still pending.
1826 base::MessageLoop::current()->RunUntilIdle();
1828 // The first request should be creating the disk cache.
1829 EXPECT_FALSE(context_list[0]->callback.have_result());
1831 factory->FinishCreation();
1833 base::MessageLoop::current()->RunUntilIdle();
1834 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1835 EXPECT_EQ(3, cache.disk_cache()->create_count());
1837 for (int i = 0; i < kNumTransactions; ++i) {
1838 EXPECT_TRUE(context_list[i]->callback.have_result());
1839 delete context_list[i];
1843 // Tests that we can cancel requests that are queued waiting for the backend
1844 // to be initialized.
1845 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1846 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1847 MockHttpCache cache(factory);
1849 MockHttpRequest request0(kSimpleGET_Transaction);
1850 MockHttpRequest request1(kTypicalGET_Transaction);
1851 MockHttpRequest request2(kETagGET_Transaction);
1853 std::vector<Context*> context_list;
1854 const int kNumTransactions = 3;
1856 for (int i = 0; i < kNumTransactions; i++) {
1857 context_list.push_back(new Context());
1858 Context* c = context_list[i];
1860 c->result = cache.CreateTransaction(&c->trans);
1861 ASSERT_EQ(net::OK, c->result);
1864 context_list[0]->result = context_list[0]->trans->Start(
1865 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1866 context_list[1]->result = context_list[1]->trans->Start(
1867 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1868 context_list[2]->result = context_list[2]->trans->Start(
1869 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1871 // Just to make sure that everything is still pending.
1872 base::MessageLoop::current()->RunUntilIdle();
1874 // The first request should be creating the disk cache.
1875 EXPECT_FALSE(context_list[0]->callback.have_result());
1877 // Cancel a request from the pending queue.
1878 delete context_list[1];
1879 context_list[1] = NULL;
1881 // Cancel the request that is creating the entry.
1882 delete context_list[0];
1883 context_list[0] = NULL;
1885 // Complete the last transaction.
1886 factory->FinishCreation();
1888 context_list[2]->result =
1889 context_list[2]->callback.GetResult(context_list[2]->result);
1890 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1892 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1893 EXPECT_EQ(1, cache.disk_cache()->create_count());
1895 delete context_list[2];
1898 // Tests that we can delete the cache while creating the backend.
1899 TEST(HttpCache, DeleteCacheWaitingForBackend) {
1900 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1901 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1903 MockHttpRequest request(kSimpleGET_Transaction);
1905 scoped_ptr<Context> c(new Context());
1906 c->result = cache->CreateTransaction(&c->trans);
1907 ASSERT_EQ(net::OK, c->result);
1909 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1911 // Just to make sure that everything is still pending.
1912 base::MessageLoop::current()->RunUntilIdle();
1914 // The request should be creating the disk cache.
1915 EXPECT_FALSE(c->callback.have_result());
1917 // We cannot call FinishCreation because the factory itself will go away with
1918 // the cache, so grab the callback and attempt to use it.
1919 net::CompletionCallback callback = factory->callback();
1920 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1922 cache.reset();
1923 base::MessageLoop::current()->RunUntilIdle();
1925 backend->reset();
1926 callback.Run(net::ERR_ABORTED);
1929 // Tests that we can delete the cache while creating the backend, from within
1930 // one of the callbacks.
1931 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1932 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1933 MockHttpCache* cache = new MockHttpCache(factory);
1935 DeleteCacheCompletionCallback cb(cache);
1936 disk_cache::Backend* backend;
1937 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1938 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1940 // Now let's queue a regular transaction
1941 MockHttpRequest request(kSimpleGET_Transaction);
1943 scoped_ptr<Context> c(new Context());
1944 c->result = cache->CreateTransaction(&c->trans);
1945 ASSERT_EQ(net::OK, c->result);
1947 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1949 // And another direct backend request.
1950 net::TestCompletionCallback cb2;
1951 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1952 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1954 // Just to make sure that everything is still pending.
1955 base::MessageLoop::current()->RunUntilIdle();
1957 // The request should be queued.
1958 EXPECT_FALSE(c->callback.have_result());
1960 // Generate the callback.
1961 factory->FinishCreation();
1962 rv = cb.WaitForResult();
1964 // The cache should be gone by now.
1965 base::MessageLoop::current()->RunUntilIdle();
1966 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1967 EXPECT_FALSE(cb2.have_result());
1970 TEST(HttpCache, TypicalGET_ConditionalRequest) {
1971 MockHttpCache cache;
1973 // write to the cache
1974 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1976 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1977 EXPECT_EQ(0, cache.disk_cache()->open_count());
1978 EXPECT_EQ(1, cache.disk_cache()->create_count());
1980 // Get the same URL again, but this time we expect it to result
1981 // in a conditional request.
1982 net::CapturingBoundNetLog log;
1983 net::LoadTimingInfo load_timing_info;
1984 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1985 log.bound(), &load_timing_info);
1987 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1988 EXPECT_EQ(1, cache.disk_cache()->open_count());
1989 EXPECT_EQ(1, cache.disk_cache()->create_count());
1990 TestLoadTimingNetworkRequest(load_timing_info);
1993 static void ETagGet_ConditionalRequest_Handler(
1994 const net::HttpRequestInfo* request,
1995 std::string* response_status,
1996 std::string* response_headers,
1997 std::string* response_data) {
1998 EXPECT_TRUE(
1999 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2000 response_status->assign("HTTP/1.1 304 Not Modified");
2001 response_headers->assign(kETagGET_Transaction.response_headers);
2002 response_data->clear();
2005 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2006 MockHttpCache cache;
2008 ScopedMockTransaction transaction(kETagGET_Transaction);
2010 // write to the cache
2011 RunTransactionTest(cache.http_cache(), transaction);
2013 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2014 EXPECT_EQ(0, cache.disk_cache()->open_count());
2015 EXPECT_EQ(1, cache.disk_cache()->create_count());
2017 // Get the same URL again, but this time we expect it to result
2018 // in a conditional request.
2019 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2020 transaction.handler = ETagGet_ConditionalRequest_Handler;
2021 net::CapturingBoundNetLog log;
2022 net::LoadTimingInfo load_timing_info;
2023 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2024 &load_timing_info);
2026 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2027 EXPECT_EQ(1, cache.disk_cache()->open_count());
2028 EXPECT_EQ(1, cache.disk_cache()->create_count());
2029 TestLoadTimingNetworkRequest(load_timing_info);
2032 class RevalidationServer {
2033 public:
2034 RevalidationServer() {
2035 s_etag_used_ = false;
2036 s_last_modified_used_ = false;
2039 bool EtagUsed() { return s_etag_used_; }
2040 bool LastModifiedUsed() { return s_last_modified_used_; }
2042 static void Handler(const net::HttpRequestInfo* request,
2043 std::string* response_status,
2044 std::string* response_headers,
2045 std::string* response_data);
2047 private:
2048 static bool s_etag_used_;
2049 static bool s_last_modified_used_;
2051 bool RevalidationServer::s_etag_used_ = false;
2052 bool RevalidationServer::s_last_modified_used_ = false;
2054 void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2055 std::string* response_status,
2056 std::string* response_headers,
2057 std::string* response_data) {
2058 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2059 s_etag_used_ = true;
2061 if (request->extra_headers.HasHeader(
2062 net::HttpRequestHeaders::kIfModifiedSince)) {
2063 s_last_modified_used_ = true;
2066 if (s_etag_used_ || s_last_modified_used_) {
2067 response_status->assign("HTTP/1.1 304 Not Modified");
2068 response_headers->assign(kTypicalGET_Transaction.response_headers);
2069 response_data->clear();
2070 } else {
2071 response_status->assign(kTypicalGET_Transaction.status);
2072 response_headers->assign(kTypicalGET_Transaction.response_headers);
2073 response_data->assign(kTypicalGET_Transaction.data);
2077 // Tests revalidation after a vary match.
2078 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2079 MockHttpCache cache;
2081 // Write to the cache.
2082 MockTransaction transaction(kTypicalGET_Transaction);
2083 transaction.request_headers = "Foo: bar\r\n";
2084 transaction.response_headers =
2085 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2086 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2087 "Etag: \"foopy\"\n"
2088 "Cache-Control: max-age=0\n"
2089 "Vary: Foo\n";
2090 AddMockTransaction(&transaction);
2091 RunTransactionTest(cache.http_cache(), transaction);
2093 // Read from the cache.
2094 RevalidationServer server;
2095 transaction.handler = server.Handler;
2096 net::CapturingBoundNetLog log;
2097 net::LoadTimingInfo load_timing_info;
2098 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2099 &load_timing_info);
2101 EXPECT_TRUE(server.EtagUsed());
2102 EXPECT_TRUE(server.LastModifiedUsed());
2103 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2104 EXPECT_EQ(1, cache.disk_cache()->open_count());
2105 EXPECT_EQ(1, cache.disk_cache()->create_count());
2106 TestLoadTimingNetworkRequest(load_timing_info);
2107 RemoveMockTransaction(&transaction);
2110 // Tests revalidation after a vary mismatch if etag is present.
2111 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2112 MockHttpCache cache;
2114 // Write to the cache.
2115 MockTransaction transaction(kTypicalGET_Transaction);
2116 transaction.request_headers = "Foo: bar\r\n";
2117 transaction.response_headers =
2118 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2119 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2120 "Etag: \"foopy\"\n"
2121 "Cache-Control: max-age=0\n"
2122 "Vary: Foo\n";
2123 AddMockTransaction(&transaction);
2124 RunTransactionTest(cache.http_cache(), transaction);
2126 // Read from the cache and revalidate the entry.
2127 RevalidationServer server;
2128 transaction.handler = server.Handler;
2129 transaction.request_headers = "Foo: none\r\n";
2130 net::CapturingBoundNetLog log;
2131 net::LoadTimingInfo load_timing_info;
2132 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2133 &load_timing_info);
2135 EXPECT_TRUE(server.EtagUsed());
2136 EXPECT_FALSE(server.LastModifiedUsed());
2137 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2138 EXPECT_EQ(1, cache.disk_cache()->open_count());
2139 EXPECT_EQ(1, cache.disk_cache()->create_count());
2140 TestLoadTimingNetworkRequest(load_timing_info);
2141 RemoveMockTransaction(&transaction);
2144 // Tests lack of revalidation after a vary mismatch and no etag.
2145 TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2146 MockHttpCache cache;
2148 // Write to the cache.
2149 MockTransaction transaction(kTypicalGET_Transaction);
2150 transaction.request_headers = "Foo: bar\r\n";
2151 transaction.response_headers =
2152 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2153 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2154 "Cache-Control: max-age=0\n"
2155 "Vary: Foo\n";
2156 AddMockTransaction(&transaction);
2157 RunTransactionTest(cache.http_cache(), transaction);
2159 // Read from the cache and don't revalidate the entry.
2160 RevalidationServer server;
2161 transaction.handler = server.Handler;
2162 transaction.request_headers = "Foo: none\r\n";
2163 net::CapturingBoundNetLog log;
2164 net::LoadTimingInfo load_timing_info;
2165 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2166 &load_timing_info);
2168 EXPECT_FALSE(server.EtagUsed());
2169 EXPECT_FALSE(server.LastModifiedUsed());
2170 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2171 EXPECT_EQ(1, cache.disk_cache()->open_count());
2172 EXPECT_EQ(1, cache.disk_cache()->create_count());
2173 TestLoadTimingNetworkRequest(load_timing_info);
2174 RemoveMockTransaction(&transaction);
2177 static void ETagGet_UnconditionalRequest_Handler(
2178 const net::HttpRequestInfo* request,
2179 std::string* response_status,
2180 std::string* response_headers,
2181 std::string* response_data) {
2182 EXPECT_FALSE(
2183 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2186 TEST(HttpCache, ETagGET_Http10) {
2187 MockHttpCache cache;
2189 ScopedMockTransaction transaction(kETagGET_Transaction);
2190 transaction.status = "HTTP/1.0 200 OK";
2192 // Write to the cache.
2193 RunTransactionTest(cache.http_cache(), transaction);
2195 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2196 EXPECT_EQ(0, cache.disk_cache()->open_count());
2197 EXPECT_EQ(1, cache.disk_cache()->create_count());
2199 // Get the same URL again, without generating a conditional request.
2200 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2201 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2202 RunTransactionTest(cache.http_cache(), transaction);
2204 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2205 EXPECT_EQ(1, cache.disk_cache()->open_count());
2206 EXPECT_EQ(1, cache.disk_cache()->create_count());
2209 TEST(HttpCache, ETagGET_Http10_Range) {
2210 MockHttpCache cache;
2212 ScopedMockTransaction transaction(kETagGET_Transaction);
2213 transaction.status = "HTTP/1.0 200 OK";
2215 // Write to the cache.
2216 RunTransactionTest(cache.http_cache(), transaction);
2218 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2219 EXPECT_EQ(0, cache.disk_cache()->open_count());
2220 EXPECT_EQ(1, cache.disk_cache()->create_count());
2222 // Get the same URL again, but use a byte range request.
2223 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2224 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2225 transaction.request_headers = "Range: bytes = 5-\r\n";
2226 RunTransactionTest(cache.http_cache(), transaction);
2228 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2229 EXPECT_EQ(1, cache.disk_cache()->open_count());
2230 EXPECT_EQ(2, cache.disk_cache()->create_count());
2233 static void ETagGet_ConditionalRequest_NoStore_Handler(
2234 const net::HttpRequestInfo* request,
2235 std::string* response_status,
2236 std::string* response_headers,
2237 std::string* response_data) {
2238 EXPECT_TRUE(
2239 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2240 response_status->assign("HTTP/1.1 304 Not Modified");
2241 response_headers->assign("Cache-Control: no-store\n");
2242 response_data->clear();
2245 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2246 MockHttpCache cache;
2248 ScopedMockTransaction transaction(kETagGET_Transaction);
2250 // Write to the cache.
2251 RunTransactionTest(cache.http_cache(), transaction);
2253 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2254 EXPECT_EQ(0, cache.disk_cache()->open_count());
2255 EXPECT_EQ(1, cache.disk_cache()->create_count());
2257 // Get the same URL again, but this time we expect it to result
2258 // in a conditional request.
2259 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2260 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2261 RunTransactionTest(cache.http_cache(), transaction);
2263 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2264 EXPECT_EQ(1, cache.disk_cache()->open_count());
2265 EXPECT_EQ(1, cache.disk_cache()->create_count());
2267 ScopedMockTransaction transaction2(kETagGET_Transaction);
2269 // Write to the cache again. This should create a new entry.
2270 RunTransactionTest(cache.http_cache(), transaction2);
2272 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2273 EXPECT_EQ(1, cache.disk_cache()->open_count());
2274 EXPECT_EQ(2, cache.disk_cache()->create_count());
2277 // Helper that does 4 requests using HttpCache:
2279 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2280 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2281 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2282 // be returned.
2283 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2284 // returned.
2285 static void ConditionalizedRequestUpdatesCacheHelper(
2286 const Response& net_response_1,
2287 const Response& net_response_2,
2288 const Response& cached_response_2,
2289 const char* extra_request_headers) {
2290 MockHttpCache cache;
2292 // The URL we will be requesting.
2293 const char* kUrl = "http://foobar.com/main.css";
2295 // Junk network response.
2296 static const Response kUnexpectedResponse = {
2297 "HTTP/1.1 500 Unexpected",
2298 "Server: unexpected_header",
2299 "unexpected body"
2302 // We will control the network layer's responses for |kUrl| using
2303 // |mock_network_response|.
2304 MockTransaction mock_network_response = { 0 };
2305 mock_network_response.url = kUrl;
2306 AddMockTransaction(&mock_network_response);
2308 // Request |kUrl| for the first time. It should hit the network and
2309 // receive |kNetResponse1|, which it saves into the HTTP cache.
2311 MockTransaction request = { 0 };
2312 request.url = kUrl;
2313 request.method = "GET";
2314 request.request_headers = "";
2316 net_response_1.AssignTo(&mock_network_response); // Network mock.
2317 net_response_1.AssignTo(&request); // Expected result.
2319 std::string response_headers;
2320 RunTransactionTestWithResponse(
2321 cache.http_cache(), request, &response_headers);
2323 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2324 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2325 EXPECT_EQ(0, cache.disk_cache()->open_count());
2326 EXPECT_EQ(1, cache.disk_cache()->create_count());
2328 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2329 // cache, so we don't hit the network.
2331 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2333 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2334 net_response_1.AssignTo(&request); // Expected result.
2336 RunTransactionTestWithResponse(
2337 cache.http_cache(), request, &response_headers);
2339 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2340 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2341 EXPECT_EQ(1, cache.disk_cache()->open_count());
2342 EXPECT_EQ(1, cache.disk_cache()->create_count());
2344 // Request |kUrl| yet again, but this time give the request an
2345 // "If-Modified-Since" header. This will cause the request to re-hit the
2346 // network. However now the network response is going to be
2347 // different -- this simulates a change made to the CSS file.
2349 request.request_headers = extra_request_headers;
2350 request.load_flags = net::LOAD_NORMAL;
2352 net_response_2.AssignTo(&mock_network_response); // Network mock.
2353 net_response_2.AssignTo(&request); // Expected result.
2355 RunTransactionTestWithResponse(
2356 cache.http_cache(), request, &response_headers);
2358 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2359 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2360 EXPECT_EQ(1, cache.disk_cache()->open_count());
2361 EXPECT_EQ(1, cache.disk_cache()->create_count());
2363 // Finally, request |kUrl| again. This request should be serviced from
2364 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2365 // and NOT |kNetResponse1|. The previous step should have replaced the
2366 // value in the cache with the modified response.
2368 request.request_headers = "";
2369 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2371 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2372 cached_response_2.AssignTo(&request); // Expected result.
2374 RunTransactionTestWithResponse(
2375 cache.http_cache(), request, &response_headers);
2377 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2378 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2379 EXPECT_EQ(2, cache.disk_cache()->open_count());
2380 EXPECT_EQ(1, cache.disk_cache()->create_count());
2382 RemoveMockTransaction(&mock_network_response);
2385 // Check that when an "if-modified-since" header is attached
2386 // to the request, the result still updates the cached entry.
2387 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2388 // First network response for |kUrl|.
2389 static const Response kNetResponse1 = {
2390 "HTTP/1.1 200 OK",
2391 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2392 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2393 "body1"
2396 // Second network response for |kUrl|.
2397 static const Response kNetResponse2 = {
2398 "HTTP/1.1 200 OK",
2399 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2400 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2401 "body2"
2404 const char* extra_headers =
2405 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2407 ConditionalizedRequestUpdatesCacheHelper(
2408 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2411 // Check that when an "if-none-match" header is attached
2412 // to the request, the result updates the cached entry.
2413 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2414 // First network response for |kUrl|.
2415 static const Response kNetResponse1 = {
2416 "HTTP/1.1 200 OK",
2417 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2418 "Etag: \"ETAG1\"\n"
2419 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2420 "body1"
2423 // Second network response for |kUrl|.
2424 static const Response kNetResponse2 = {
2425 "HTTP/1.1 200 OK",
2426 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2427 "Etag: \"ETAG2\"\n"
2428 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2429 "body2"
2432 const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
2434 ConditionalizedRequestUpdatesCacheHelper(
2435 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2438 // Check that when an "if-modified-since" header is attached
2439 // to a request, the 304 (not modified result) result updates the cached
2440 // headers, and the 304 response is returned rather than the cached response.
2441 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2442 // First network response for |kUrl|.
2443 static const Response kNetResponse1 = {
2444 "HTTP/1.1 200 OK",
2445 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2446 "Server: server1\n"
2447 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2448 "body1"
2451 // Second network response for |kUrl|.
2452 static const Response kNetResponse2 = {
2453 "HTTP/1.1 304 Not Modified",
2454 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2455 "Server: server2\n"
2456 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2460 static const Response kCachedResponse2 = {
2461 "HTTP/1.1 200 OK",
2462 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2463 "Server: server2\n"
2464 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2465 "body1"
2468 const char* extra_headers =
2469 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2471 ConditionalizedRequestUpdatesCacheHelper(
2472 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2475 // Test that when doing an externally conditionalized if-modified-since
2476 // and there is no corresponding cache entry, a new cache entry is NOT
2477 // created (304 response).
2478 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2479 MockHttpCache cache;
2481 const char* kUrl = "http://foobar.com/main.css";
2483 static const Response kNetResponse = {
2484 "HTTP/1.1 304 Not Modified",
2485 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2486 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2490 const char* kExtraRequestHeaders =
2491 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2493 // We will control the network layer's responses for |kUrl| using
2494 // |mock_network_response|.
2495 MockTransaction mock_network_response = { 0 };
2496 mock_network_response.url = kUrl;
2497 AddMockTransaction(&mock_network_response);
2499 MockTransaction request = { 0 };
2500 request.url = kUrl;
2501 request.method = "GET";
2502 request.request_headers = kExtraRequestHeaders;
2504 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2505 kNetResponse.AssignTo(&request); // Expected result.
2507 std::string response_headers;
2508 RunTransactionTestWithResponse(
2509 cache.http_cache(), request, &response_headers);
2511 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2512 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2513 EXPECT_EQ(0, cache.disk_cache()->open_count());
2514 EXPECT_EQ(0, cache.disk_cache()->create_count());
2516 RemoveMockTransaction(&mock_network_response);
2519 // Test that when doing an externally conditionalized if-modified-since
2520 // and there is no corresponding cache entry, a new cache entry is NOT
2521 // created (200 response).
2522 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2523 MockHttpCache cache;
2525 const char* kUrl = "http://foobar.com/main.css";
2527 static const Response kNetResponse = {
2528 "HTTP/1.1 200 OK",
2529 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2530 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2531 "foobar!!!"
2534 const char* kExtraRequestHeaders =
2535 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2537 // We will control the network layer's responses for |kUrl| using
2538 // |mock_network_response|.
2539 MockTransaction mock_network_response = { 0 };
2540 mock_network_response.url = kUrl;
2541 AddMockTransaction(&mock_network_response);
2543 MockTransaction request = { 0 };
2544 request.url = kUrl;
2545 request.method = "GET";
2546 request.request_headers = kExtraRequestHeaders;
2548 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2549 kNetResponse.AssignTo(&request); // Expected result.
2551 std::string response_headers;
2552 RunTransactionTestWithResponse(
2553 cache.http_cache(), request, &response_headers);
2555 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2556 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2557 EXPECT_EQ(0, cache.disk_cache()->open_count());
2558 EXPECT_EQ(0, cache.disk_cache()->create_count());
2560 RemoveMockTransaction(&mock_network_response);
2563 // Test that when doing an externally conditionalized if-modified-since
2564 // if the date does not match the cache entry's last-modified date,
2565 // then we do NOT use the response (304) to update the cache.
2566 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2567 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2568 static const Response kNetResponse1 = {
2569 "HTTP/1.1 200 OK",
2570 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2571 "Server: server1\n"
2572 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2573 "body1"
2576 // Second network response for |kUrl|.
2577 static const Response kNetResponse2 = {
2578 "HTTP/1.1 304 Not Modified",
2579 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2580 "Server: server2\n"
2581 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2585 // This is two days in the future from the original response's last-modified
2586 // date!
2587 const char* kExtraRequestHeaders =
2588 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2590 ConditionalizedRequestUpdatesCacheHelper(
2591 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2594 // Test that when doing an externally conditionalized if-none-match
2595 // if the etag does not match the cache entry's etag, then we do not use the
2596 // response (304) to update the cache.
2597 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2598 static const Response kNetResponse1 = {
2599 "HTTP/1.1 200 OK",
2600 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2601 "Etag: \"Foo1\"\n"
2602 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2603 "body1"
2606 // Second network response for |kUrl|.
2607 static const Response kNetResponse2 = {
2608 "HTTP/1.1 304 Not Modified",
2609 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2610 "Etag: \"Foo2\"\n"
2611 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2615 // Different etag from original response.
2616 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
2618 ConditionalizedRequestUpdatesCacheHelper(
2619 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2622 // Test that doing an externally conditionalized request with both if-none-match
2623 // and if-modified-since updates the cache.
2624 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2625 static const Response kNetResponse1 = {
2626 "HTTP/1.1 200 OK",
2627 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2628 "Etag: \"Foo1\"\n"
2629 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2630 "body1"
2633 // Second network response for |kUrl|.
2634 static const Response kNetResponse2 = {
2635 "HTTP/1.1 200 OK",
2636 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2637 "Etag: \"Foo2\"\n"
2638 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2639 "body2"
2642 const char* kExtraRequestHeaders =
2643 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2644 "If-None-Match: \"Foo1\"\r\n";
2646 ConditionalizedRequestUpdatesCacheHelper(
2647 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2650 // Test that doing an externally conditionalized request with both if-none-match
2651 // and if-modified-since does not update the cache with only one match.
2652 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2653 static const Response kNetResponse1 = {
2654 "HTTP/1.1 200 OK",
2655 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2656 "Etag: \"Foo1\"\n"
2657 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2658 "body1"
2661 // Second network response for |kUrl|.
2662 static const Response kNetResponse2 = {
2663 "HTTP/1.1 200 OK",
2664 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2665 "Etag: \"Foo2\"\n"
2666 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2667 "body2"
2670 // The etag doesn't match what we have stored.
2671 const char* kExtraRequestHeaders =
2672 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2673 "If-None-Match: \"Foo2\"\r\n";
2675 ConditionalizedRequestUpdatesCacheHelper(
2676 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2679 // Test that doing an externally conditionalized request with both if-none-match
2680 // and if-modified-since does not update the cache with only one match.
2681 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2682 static const Response kNetResponse1 = {
2683 "HTTP/1.1 200 OK",
2684 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2685 "Etag: \"Foo1\"\n"
2686 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2687 "body1"
2690 // Second network response for |kUrl|.
2691 static const Response kNetResponse2 = {
2692 "HTTP/1.1 200 OK",
2693 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2694 "Etag: \"Foo2\"\n"
2695 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2696 "body2"
2699 // The modification date doesn't match what we have stored.
2700 const char* kExtraRequestHeaders =
2701 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2702 "If-None-Match: \"Foo1\"\r\n";
2704 ConditionalizedRequestUpdatesCacheHelper(
2705 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2708 TEST(HttpCache, UrlContainingHash) {
2709 MockHttpCache cache;
2711 // Do a typical GET request -- should write an entry into our cache.
2712 MockTransaction trans(kTypicalGET_Transaction);
2713 RunTransactionTest(cache.http_cache(), trans);
2715 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2716 EXPECT_EQ(0, cache.disk_cache()->open_count());
2717 EXPECT_EQ(1, cache.disk_cache()->create_count());
2719 // Request the same URL, but this time with a reference section (hash).
2720 // Since the cache key strips the hash sections, this should be a cache hit.
2721 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2722 trans.url = url_with_hash.c_str();
2723 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2725 RunTransactionTest(cache.http_cache(), trans);
2727 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2728 EXPECT_EQ(1, cache.disk_cache()->open_count());
2729 EXPECT_EQ(1, cache.disk_cache()->create_count());
2732 // Tests that we skip the cache for POST requests that do not have an upload
2733 // identifier.
2734 TEST(HttpCache, SimplePOST_SkipsCache) {
2735 MockHttpCache cache;
2737 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2739 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2740 EXPECT_EQ(0, cache.disk_cache()->open_count());
2741 EXPECT_EQ(0, cache.disk_cache()->create_count());
2744 // Tests POST handling with a disabled cache (no DCHECK).
2745 TEST(HttpCache, SimplePOST_DisabledCache) {
2746 MockHttpCache cache;
2747 cache.http_cache()->set_mode(net::HttpCache::Mode::DISABLE);
2749 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2751 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2752 EXPECT_EQ(0, cache.disk_cache()->open_count());
2753 EXPECT_EQ(0, cache.disk_cache()->create_count());
2756 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2757 MockHttpCache cache;
2759 MockTransaction transaction(kSimplePOST_Transaction);
2760 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2762 MockHttpRequest request(transaction);
2763 net::TestCompletionCallback callback;
2765 scoped_ptr<net::HttpTransaction> trans;
2766 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
2767 ASSERT_TRUE(trans.get());
2769 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
2770 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
2772 trans.reset();
2774 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2775 EXPECT_EQ(0, cache.disk_cache()->open_count());
2776 EXPECT_EQ(0, cache.disk_cache()->create_count());
2779 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2780 MockHttpCache cache;
2782 // Test that we hit the cache for POST requests.
2784 MockTransaction transaction(kSimplePOST_Transaction);
2786 const int64 kUploadId = 1; // Just a dummy value.
2788 ScopedVector<net::UploadElementReader> element_readers;
2789 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2790 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2791 kUploadId);
2792 MockHttpRequest request(transaction);
2793 request.upload_data_stream = &upload_data_stream;
2795 // Populate the cache.
2796 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2798 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2799 EXPECT_EQ(0, cache.disk_cache()->open_count());
2800 EXPECT_EQ(1, cache.disk_cache()->create_count());
2802 // Load from cache.
2803 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2804 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2806 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2807 EXPECT_EQ(1, cache.disk_cache()->open_count());
2808 EXPECT_EQ(1, cache.disk_cache()->create_count());
2811 // Test that we don't hit the cache for POST requests if there is a byte range.
2812 TEST(HttpCache, SimplePOST_WithRanges) {
2813 MockHttpCache cache;
2815 MockTransaction transaction(kSimplePOST_Transaction);
2816 transaction.request_headers = "Range: bytes = 0-4\r\n";
2818 const int64 kUploadId = 1; // Just a dummy value.
2820 ScopedVector<net::UploadElementReader> element_readers;
2821 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2822 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2823 kUploadId);
2825 MockHttpRequest request(transaction);
2826 request.upload_data_stream = &upload_data_stream;
2828 // Attempt to populate the cache.
2829 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2831 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2832 EXPECT_EQ(0, cache.disk_cache()->open_count());
2833 EXPECT_EQ(0, cache.disk_cache()->create_count());
2836 // Tests that a POST is cached separately from a previously cached GET.
2837 TEST(HttpCache, SimplePOST_SeparateCache) {
2838 MockHttpCache cache;
2840 ScopedVector<net::UploadElementReader> element_readers;
2841 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2842 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2844 MockTransaction transaction(kSimplePOST_Transaction);
2845 MockHttpRequest req1(transaction);
2846 req1.upload_data_stream = &upload_data_stream;
2848 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2850 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2851 EXPECT_EQ(0, cache.disk_cache()->open_count());
2852 EXPECT_EQ(1, cache.disk_cache()->create_count());
2854 transaction.method = "GET";
2855 MockHttpRequest req2(transaction);
2857 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2859 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2860 EXPECT_EQ(0, cache.disk_cache()->open_count());
2861 EXPECT_EQ(2, cache.disk_cache()->create_count());
2864 // Tests that a successful POST invalidates a previously cached GET.
2865 TEST(HttpCache, SimplePOST_Invalidate_205) {
2866 MockHttpCache cache;
2868 MockTransaction transaction(kSimpleGET_Transaction);
2869 AddMockTransaction(&transaction);
2870 MockHttpRequest req1(transaction);
2872 // Attempt to populate the cache.
2873 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2875 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2876 EXPECT_EQ(0, cache.disk_cache()->open_count());
2877 EXPECT_EQ(1, cache.disk_cache()->create_count());
2879 ScopedVector<net::UploadElementReader> element_readers;
2880 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2881 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2883 transaction.method = "POST";
2884 transaction.status = "HTTP/1.1 205 No Content";
2885 MockHttpRequest req2(transaction);
2886 req2.upload_data_stream = &upload_data_stream;
2888 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2890 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2891 EXPECT_EQ(0, cache.disk_cache()->open_count());
2892 EXPECT_EQ(2, cache.disk_cache()->create_count());
2894 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2896 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2897 EXPECT_EQ(0, cache.disk_cache()->open_count());
2898 EXPECT_EQ(3, cache.disk_cache()->create_count());
2899 RemoveMockTransaction(&transaction);
2902 // Tests that a successful POST invalidates a previously cached GET, even when
2903 // there is no upload identifier.
2904 TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
2905 MockHttpCache cache;
2907 MockTransaction transaction(kSimpleGET_Transaction);
2908 AddMockTransaction(&transaction);
2909 MockHttpRequest req1(transaction);
2911 // Attempt to populate the cache.
2912 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2914 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2915 EXPECT_EQ(0, cache.disk_cache()->open_count());
2916 EXPECT_EQ(1, cache.disk_cache()->create_count());
2918 ScopedVector<net::UploadElementReader> element_readers;
2919 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2920 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
2922 transaction.method = "POST";
2923 transaction.status = "HTTP/1.1 205 No Content";
2924 MockHttpRequest req2(transaction);
2925 req2.upload_data_stream = &upload_data_stream;
2927 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2929 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2930 EXPECT_EQ(0, cache.disk_cache()->open_count());
2931 EXPECT_EQ(1, cache.disk_cache()->create_count());
2933 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2935 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2936 EXPECT_EQ(0, cache.disk_cache()->open_count());
2937 EXPECT_EQ(2, cache.disk_cache()->create_count());
2938 RemoveMockTransaction(&transaction);
2941 // Tests that processing a POST before creating the backend doesn't crash.
2942 TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
2943 // This will initialize a cache object with NULL backend.
2944 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2945 factory->set_fail(true);
2946 factory->FinishCreation();
2947 MockHttpCache cache(factory);
2949 ScopedVector<net::UploadElementReader> element_readers;
2950 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2951 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
2953 MockTransaction transaction(kSimplePOST_Transaction);
2954 AddMockTransaction(&transaction);
2955 MockHttpRequest req(transaction);
2956 req.upload_data_stream = &upload_data_stream;
2958 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
2960 RemoveMockTransaction(&transaction);
2963 // Tests that we don't invalidate entries as a result of a failed POST.
2964 TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2965 MockHttpCache cache;
2967 MockTransaction transaction(kSimpleGET_Transaction);
2968 AddMockTransaction(&transaction);
2969 MockHttpRequest req1(transaction);
2971 // Attempt to populate the cache.
2972 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2974 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2975 EXPECT_EQ(0, cache.disk_cache()->open_count());
2976 EXPECT_EQ(1, cache.disk_cache()->create_count());
2978 ScopedVector<net::UploadElementReader> element_readers;
2979 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2980 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2982 transaction.method = "POST";
2983 transaction.status = "HTTP/1.1 100 Continue";
2984 MockHttpRequest req2(transaction);
2985 req2.upload_data_stream = &upload_data_stream;
2987 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2989 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2990 EXPECT_EQ(0, cache.disk_cache()->open_count());
2991 EXPECT_EQ(2, cache.disk_cache()->create_count());
2993 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2995 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2996 EXPECT_EQ(1, cache.disk_cache()->open_count());
2997 EXPECT_EQ(2, cache.disk_cache()->create_count());
2998 RemoveMockTransaction(&transaction);
3001 // Tests that a HEAD request is not cached by itself.
3002 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
3003 MockHttpCache cache;
3004 MockTransaction transaction(kSimplePOST_Transaction);
3005 AddMockTransaction(&transaction);
3006 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3007 transaction.method = "HEAD";
3009 MockHttpRequest request(transaction);
3010 net::TestCompletionCallback callback;
3012 scoped_ptr<net::HttpTransaction> trans;
3013 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
3014 ASSERT_TRUE(trans.get());
3016 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
3017 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
3019 trans.reset();
3021 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3022 EXPECT_EQ(0, cache.disk_cache()->open_count());
3023 EXPECT_EQ(0, cache.disk_cache()->create_count());
3024 RemoveMockTransaction(&transaction);
3027 // Tests that a HEAD request is served from a cached GET.
3028 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3029 MockHttpCache cache;
3030 MockTransaction transaction(kSimpleGET_Transaction);
3031 AddMockTransaction(&transaction);
3033 // Populate the cache.
3034 RunTransactionTest(cache.http_cache(), transaction);
3036 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3037 EXPECT_EQ(0, cache.disk_cache()->open_count());
3038 EXPECT_EQ(1, cache.disk_cache()->create_count());
3040 // Load from cache.
3041 transaction.method = "HEAD";
3042 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3043 transaction.data = "";
3044 RunTransactionTest(cache.http_cache(), transaction);
3046 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3047 EXPECT_EQ(1, cache.disk_cache()->open_count());
3048 EXPECT_EQ(1, cache.disk_cache()->create_count());
3049 RemoveMockTransaction(&transaction);
3052 // Tests that a read-only request served from the cache preserves CL.
3053 TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3054 MockHttpCache cache;
3055 MockTransaction transaction(kSimpleGET_Transaction);
3056 AddMockTransaction(&transaction);
3057 transaction.response_headers = "Content-Length: 42\n";
3059 // Populate the cache.
3060 RunTransactionTest(cache.http_cache(), transaction);
3062 // Load from cache.
3063 transaction.method = "HEAD";
3064 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3065 transaction.data = "";
3066 std::string headers;
3068 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3070 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3071 RemoveMockTransaction(&transaction);
3074 // Tests that a read-write request served from the cache preserves CL.
3075 TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3076 MockHttpCache cache;
3077 MockTransaction transaction(kETagGET_Transaction);
3078 AddMockTransaction(&transaction);
3079 std::string server_headers(kETagGET_Transaction.response_headers);
3080 server_headers.append("Content-Length: 42\n");
3081 transaction.response_headers = server_headers.data();
3083 // Populate the cache.
3084 RunTransactionTest(cache.http_cache(), transaction);
3086 // Load from cache.
3087 transaction.method = "HEAD";
3088 transaction.data = "";
3089 std::string headers;
3091 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3093 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3094 RemoveMockTransaction(&transaction);
3097 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3098 TEST(HttpCache, SimpleHEAD_WithRanges) {
3099 MockHttpCache cache;
3100 MockTransaction transaction(kSimpleGET_Transaction);
3101 AddMockTransaction(&transaction);
3103 // Populate the cache.
3104 RunTransactionTest(cache.http_cache(), transaction);
3106 // Load from cache.
3107 transaction.method = "HEAD";
3108 transaction.request_headers = "Range: bytes = 0-4\r\n";
3109 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3110 transaction.return_code = net::ERR_CACHE_MISS;
3111 RunTransactionTest(cache.http_cache(), transaction);
3113 EXPECT_EQ(0, cache.disk_cache()->open_count());
3114 EXPECT_EQ(1, cache.disk_cache()->create_count());
3115 RemoveMockTransaction(&transaction);
3118 // Tests that a HEAD request can be served from a partialy cached resource.
3119 TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3120 MockHttpCache cache;
3121 AddMockTransaction(&kRangeGET_TransactionOK);
3123 // Write to the cache (40-49).
3124 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3125 RemoveMockTransaction(&kRangeGET_TransactionOK);
3127 MockTransaction transaction(kSimpleGET_Transaction);
3129 transaction.url = kRangeGET_TransactionOK.url;
3130 transaction.method = "HEAD";
3131 transaction.data = "";
3132 AddMockTransaction(&transaction);
3133 std::string headers;
3135 // Load from cache.
3136 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3138 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3139 EXPECT_EQ(std::string::npos, headers.find("Content-Length"));
3140 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3141 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3142 EXPECT_EQ(1, cache.disk_cache()->open_count());
3143 EXPECT_EQ(1, cache.disk_cache()->create_count());
3144 RemoveMockTransaction(&transaction);
3147 // Tests that a HEAD request can be served from a truncated resource.
3148 TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3149 MockHttpCache cache;
3150 AddMockTransaction(&kRangeGET_TransactionOK);
3152 std::string raw_headers("HTTP/1.1 200 OK\n"
3153 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3154 "ETag: \"foo\"\n"
3155 "Accept-Ranges: bytes\n"
3156 "Content-Length: 80\n");
3157 CreateTruncatedEntry(raw_headers, &cache);
3158 RemoveMockTransaction(&kRangeGET_TransactionOK);
3160 MockTransaction transaction(kSimpleGET_Transaction);
3162 transaction.url = kRangeGET_TransactionOK.url;
3163 transaction.method = "HEAD";
3164 transaction.data = "";
3165 AddMockTransaction(&transaction);
3166 std::string headers;
3168 // Load from cache.
3169 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3171 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3172 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3173 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3174 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3175 EXPECT_EQ(1, cache.disk_cache()->open_count());
3176 EXPECT_EQ(1, cache.disk_cache()->create_count());
3177 RemoveMockTransaction(&transaction);
3180 // Tests that a HEAD request updates the cached response.
3181 TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3182 MockHttpCache cache;
3183 MockTransaction transaction(kTypicalGET_Transaction);
3184 AddMockTransaction(&transaction);
3186 // Populate the cache.
3187 RunTransactionTest(cache.http_cache(), transaction);
3189 // Update the cache.
3190 transaction.method = "HEAD";
3191 transaction.response_headers = "Foo: bar\n";
3192 transaction.data = "";
3193 transaction.status = "HTTP/1.1 304 Not Modified\n";
3194 std::string headers;
3195 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3196 RemoveMockTransaction(&transaction);
3198 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3199 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3201 MockTransaction transaction2(kTypicalGET_Transaction);
3202 AddMockTransaction(&transaction2);
3204 // Make sure we are done with the previous transaction.
3205 base::MessageLoop::current()->RunUntilIdle();
3207 // Load from the cache.
3208 transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3209 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3211 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3212 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3213 EXPECT_EQ(2, cache.disk_cache()->open_count());
3214 EXPECT_EQ(1, cache.disk_cache()->create_count());
3215 RemoveMockTransaction(&transaction2);
3218 // Tests that an externally conditionalized HEAD request updates the cache.
3219 TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3220 MockHttpCache cache;
3221 MockTransaction transaction(kTypicalGET_Transaction);
3222 AddMockTransaction(&transaction);
3224 // Populate the cache.
3225 RunTransactionTest(cache.http_cache(), transaction);
3227 // Update the cache.
3228 transaction.method = "HEAD";
3229 transaction.request_headers =
3230 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3231 transaction.response_headers = "Foo: bar\n";
3232 transaction.data = "";
3233 transaction.status = "HTTP/1.1 304 Not Modified\n";
3234 std::string headers;
3235 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3236 RemoveMockTransaction(&transaction);
3238 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3239 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3241 MockTransaction transaction2(kTypicalGET_Transaction);
3242 AddMockTransaction(&transaction2);
3244 // Make sure we are done with the previous transaction.
3245 base::MessageLoop::current()->RunUntilIdle();
3247 // Load from the cache.
3248 transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3249 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3251 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3252 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3253 EXPECT_EQ(2, cache.disk_cache()->open_count());
3254 EXPECT_EQ(1, cache.disk_cache()->create_count());
3255 RemoveMockTransaction(&transaction2);
3258 // Tests that a HEAD request invalidates an old cached entry.
3259 TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3260 MockHttpCache cache;
3261 MockTransaction transaction(kTypicalGET_Transaction);
3262 AddMockTransaction(&transaction);
3264 // Populate the cache.
3265 RunTransactionTest(cache.http_cache(), transaction);
3267 // Update the cache.
3268 transaction.method = "HEAD";
3269 transaction.data = "";
3270 RunTransactionTest(cache.http_cache(), transaction);
3271 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3273 // Load from the cache.
3274 transaction.method = "GET";
3275 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3276 transaction.return_code = net::ERR_CACHE_MISS;
3277 RunTransactionTest(cache.http_cache(), transaction);
3279 RemoveMockTransaction(&transaction);
3282 // Tests that we do not cache the response of a PUT.
3283 TEST(HttpCache, SimplePUT_Miss) {
3284 MockHttpCache cache;
3286 MockTransaction transaction(kSimplePOST_Transaction);
3287 transaction.method = "PUT";
3289 ScopedVector<net::UploadElementReader> element_readers;
3290 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3291 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3293 MockHttpRequest request(transaction);
3294 request.upload_data_stream = &upload_data_stream;
3296 // Attempt to populate the cache.
3297 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3299 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3300 EXPECT_EQ(0, cache.disk_cache()->open_count());
3301 EXPECT_EQ(0, cache.disk_cache()->create_count());
3304 // Tests that we invalidate entries as a result of a PUT.
3305 TEST(HttpCache, SimplePUT_Invalidate) {
3306 MockHttpCache cache;
3308 MockTransaction transaction(kSimpleGET_Transaction);
3309 MockHttpRequest req1(transaction);
3311 // Attempt to populate the cache.
3312 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3314 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3315 EXPECT_EQ(0, cache.disk_cache()->open_count());
3316 EXPECT_EQ(1, cache.disk_cache()->create_count());
3318 ScopedVector<net::UploadElementReader> element_readers;
3319 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3320 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3322 transaction.method = "PUT";
3323 MockHttpRequest req2(transaction);
3324 req2.upload_data_stream = &upload_data_stream;
3326 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3328 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3329 EXPECT_EQ(1, cache.disk_cache()->open_count());
3330 EXPECT_EQ(1, cache.disk_cache()->create_count());
3332 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3334 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3335 EXPECT_EQ(1, cache.disk_cache()->open_count());
3336 EXPECT_EQ(2, cache.disk_cache()->create_count());
3339 // Tests that we invalidate entries as a result of a PUT.
3340 TEST(HttpCache, SimplePUT_Invalidate_305) {
3341 MockHttpCache cache;
3343 MockTransaction transaction(kSimpleGET_Transaction);
3344 AddMockTransaction(&transaction);
3345 MockHttpRequest req1(transaction);
3347 // Attempt to populate the cache.
3348 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3350 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3351 EXPECT_EQ(0, cache.disk_cache()->open_count());
3352 EXPECT_EQ(1, cache.disk_cache()->create_count());
3354 ScopedVector<net::UploadElementReader> element_readers;
3355 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3356 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3358 transaction.method = "PUT";
3359 transaction.status = "HTTP/1.1 305 Use Proxy";
3360 MockHttpRequest req2(transaction);
3361 req2.upload_data_stream = &upload_data_stream;
3363 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3365 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3366 EXPECT_EQ(1, cache.disk_cache()->open_count());
3367 EXPECT_EQ(1, cache.disk_cache()->create_count());
3369 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3371 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3372 EXPECT_EQ(1, cache.disk_cache()->open_count());
3373 EXPECT_EQ(2, cache.disk_cache()->create_count());
3374 RemoveMockTransaction(&transaction);
3377 // Tests that we don't invalidate entries as a result of a failed PUT.
3378 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3379 MockHttpCache cache;
3381 MockTransaction transaction(kSimpleGET_Transaction);
3382 AddMockTransaction(&transaction);
3383 MockHttpRequest req1(transaction);
3385 // Attempt to populate the cache.
3386 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3388 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3389 EXPECT_EQ(0, cache.disk_cache()->open_count());
3390 EXPECT_EQ(1, cache.disk_cache()->create_count());
3392 ScopedVector<net::UploadElementReader> element_readers;
3393 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3394 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3396 transaction.method = "PUT";
3397 transaction.status = "HTTP/1.1 404 Not Found";
3398 MockHttpRequest req2(transaction);
3399 req2.upload_data_stream = &upload_data_stream;
3401 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3403 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3404 EXPECT_EQ(1, cache.disk_cache()->open_count());
3405 EXPECT_EQ(1, cache.disk_cache()->create_count());
3407 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3409 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3410 EXPECT_EQ(2, cache.disk_cache()->open_count());
3411 EXPECT_EQ(1, cache.disk_cache()->create_count());
3412 RemoveMockTransaction(&transaction);
3415 // Tests that we do not cache the response of a DELETE.
3416 TEST(HttpCache, SimpleDELETE_Miss) {
3417 MockHttpCache cache;
3419 MockTransaction transaction(kSimplePOST_Transaction);
3420 transaction.method = "DELETE";
3422 ScopedVector<net::UploadElementReader> element_readers;
3423 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3424 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3426 MockHttpRequest request(transaction);
3427 request.upload_data_stream = &upload_data_stream;
3429 // Attempt to populate the cache.
3430 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3432 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3433 EXPECT_EQ(0, cache.disk_cache()->open_count());
3434 EXPECT_EQ(0, cache.disk_cache()->create_count());
3437 // Tests that we invalidate entries as a result of a DELETE.
3438 TEST(HttpCache, SimpleDELETE_Invalidate) {
3439 MockHttpCache cache;
3441 MockTransaction transaction(kSimpleGET_Transaction);
3442 MockHttpRequest req1(transaction);
3444 // Attempt to populate the cache.
3445 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3447 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3448 EXPECT_EQ(0, cache.disk_cache()->open_count());
3449 EXPECT_EQ(1, cache.disk_cache()->create_count());
3451 ScopedVector<net::UploadElementReader> element_readers;
3452 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3453 net::ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3455 transaction.method = "DELETE";
3456 MockHttpRequest req2(transaction);
3457 req2.upload_data_stream = &upload_data_stream;
3459 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3461 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3462 EXPECT_EQ(1, cache.disk_cache()->open_count());
3463 EXPECT_EQ(1, cache.disk_cache()->create_count());
3465 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3467 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3468 EXPECT_EQ(1, cache.disk_cache()->open_count());
3469 EXPECT_EQ(2, cache.disk_cache()->create_count());
3472 // Tests that we invalidate entries as a result of a DELETE.
3473 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3474 MockHttpCache cache;
3476 MockTransaction transaction(kSimpleGET_Transaction);
3477 AddMockTransaction(&transaction);
3479 // Attempt to populate the cache.
3480 RunTransactionTest(cache.http_cache(), transaction);
3482 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3483 EXPECT_EQ(0, cache.disk_cache()->open_count());
3484 EXPECT_EQ(1, cache.disk_cache()->create_count());
3486 transaction.method = "DELETE";
3487 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3489 RunTransactionTest(cache.http_cache(), transaction);
3491 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3492 EXPECT_EQ(1, cache.disk_cache()->open_count());
3493 EXPECT_EQ(1, cache.disk_cache()->create_count());
3495 transaction.method = "GET";
3496 RunTransactionTest(cache.http_cache(), transaction);
3498 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3499 EXPECT_EQ(1, cache.disk_cache()->open_count());
3500 EXPECT_EQ(2, cache.disk_cache()->create_count());
3501 RemoveMockTransaction(&transaction);
3504 // Tests that we don't invalidate entries as a result of a failed DELETE.
3505 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3506 MockHttpCache cache;
3508 MockTransaction transaction(kSimpleGET_Transaction);
3509 AddMockTransaction(&transaction);
3511 // Attempt to populate the cache.
3512 RunTransactionTest(cache.http_cache(), transaction);
3514 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3515 EXPECT_EQ(0, cache.disk_cache()->open_count());
3516 EXPECT_EQ(1, cache.disk_cache()->create_count());
3518 transaction.method = "DELETE";
3519 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3521 RunTransactionTest(cache.http_cache(), transaction);
3523 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3524 EXPECT_EQ(1, cache.disk_cache()->open_count());
3525 EXPECT_EQ(1, cache.disk_cache()->create_count());
3527 transaction.method = "GET";
3528 transaction.status = "HTTP/1.1 200 OK";
3529 RunTransactionTest(cache.http_cache(), transaction);
3531 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3532 EXPECT_EQ(2, cache.disk_cache()->open_count());
3533 EXPECT_EQ(1, cache.disk_cache()->create_count());
3534 RemoveMockTransaction(&transaction);
3537 // Tests that we don't invalidate entries after a failed network transaction.
3538 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3539 MockHttpCache cache;
3541 // Populate the cache.
3542 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3543 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3545 // Fail the network request.
3546 MockTransaction transaction(kSimpleGET_Transaction);
3547 transaction.return_code = net::ERR_FAILED;
3548 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3550 AddMockTransaction(&transaction);
3551 RunTransactionTest(cache.http_cache(), transaction);
3552 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3553 RemoveMockTransaction(&transaction);
3555 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3556 transaction.return_code = net::OK;
3557 AddMockTransaction(&transaction);
3558 RunTransactionTest(cache.http_cache(), transaction);
3560 // Make sure the transaction didn't reach the network.
3561 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3562 RemoveMockTransaction(&transaction);
3565 TEST(HttpCache, RangeGET_SkipsCache) {
3566 MockHttpCache cache;
3568 // Test that we skip the cache for range GET requests. Eventually, we will
3569 // want to cache these, but we'll still have cases where skipping the cache
3570 // makes sense, so we want to make sure that it works properly.
3572 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3574 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3575 EXPECT_EQ(0, cache.disk_cache()->open_count());
3576 EXPECT_EQ(0, cache.disk_cache()->create_count());
3578 MockTransaction transaction(kSimpleGET_Transaction);
3579 transaction.request_headers = "If-None-Match: foo\r\n";
3580 RunTransactionTest(cache.http_cache(), transaction);
3582 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3583 EXPECT_EQ(0, cache.disk_cache()->open_count());
3584 EXPECT_EQ(0, cache.disk_cache()->create_count());
3586 transaction.request_headers =
3587 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3588 RunTransactionTest(cache.http_cache(), transaction);
3590 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3591 EXPECT_EQ(0, cache.disk_cache()->open_count());
3592 EXPECT_EQ(0, cache.disk_cache()->create_count());
3595 // Test that we skip the cache for range requests that include a validation
3596 // header.
3597 TEST(HttpCache, RangeGET_SkipsCache2) {
3598 MockHttpCache cache;
3600 MockTransaction transaction(kRangeGET_Transaction);
3601 transaction.request_headers = "If-None-Match: foo\r\n"
3602 EXTRA_HEADER
3603 "Range: bytes = 40-49\r\n";
3604 RunTransactionTest(cache.http_cache(), transaction);
3606 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3607 EXPECT_EQ(0, cache.disk_cache()->open_count());
3608 EXPECT_EQ(0, cache.disk_cache()->create_count());
3610 transaction.request_headers =
3611 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3612 EXTRA_HEADER
3613 "Range: bytes = 40-49\r\n";
3614 RunTransactionTest(cache.http_cache(), transaction);
3616 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3617 EXPECT_EQ(0, cache.disk_cache()->open_count());
3618 EXPECT_EQ(0, cache.disk_cache()->create_count());
3620 transaction.request_headers = "If-Range: bla\r\n"
3621 EXTRA_HEADER
3622 "Range: bytes = 40-49\r\n";
3623 RunTransactionTest(cache.http_cache(), transaction);
3625 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3626 EXPECT_EQ(0, cache.disk_cache()->open_count());
3627 EXPECT_EQ(0, cache.disk_cache()->create_count());
3630 // Tests that receiving 206 for a regular request is handled correctly.
3631 TEST(HttpCache, GET_Crazy206) {
3632 MockHttpCache cache;
3634 // Write to the cache.
3635 MockTransaction transaction(kRangeGET_TransactionOK);
3636 AddMockTransaction(&transaction);
3637 transaction.request_headers = EXTRA_HEADER;
3638 transaction.handler = NULL;
3639 RunTransactionTest(cache.http_cache(), transaction);
3641 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3642 EXPECT_EQ(0, cache.disk_cache()->open_count());
3643 EXPECT_EQ(1, cache.disk_cache()->create_count());
3645 // This should read again from the net.
3646 RunTransactionTest(cache.http_cache(), transaction);
3648 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3649 EXPECT_EQ(0, cache.disk_cache()->open_count());
3650 EXPECT_EQ(2, cache.disk_cache()->create_count());
3651 RemoveMockTransaction(&transaction);
3654 // Tests that receiving 416 for a regular request is handled correctly.
3655 TEST(HttpCache, GET_Crazy416) {
3656 MockHttpCache cache;
3658 // Write to the cache.
3659 MockTransaction transaction(kSimpleGET_Transaction);
3660 AddMockTransaction(&transaction);
3661 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3662 RunTransactionTest(cache.http_cache(), transaction);
3664 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3665 EXPECT_EQ(0, cache.disk_cache()->open_count());
3666 EXPECT_EQ(1, cache.disk_cache()->create_count());
3668 RemoveMockTransaction(&transaction);
3671 // Tests that we store partial responses that can't be validated, as they can
3672 // be used for requests that don't require revalidation.
3673 TEST(HttpCache, RangeGET_NoStrongValidators) {
3674 MockHttpCache cache;
3675 std::string headers;
3677 // Write to the cache (40-49).
3678 MockTransaction transaction(kRangeGET_TransactionOK);
3679 AddMockTransaction(&transaction);
3680 transaction.response_headers = "Content-Length: 10\n"
3681 "Cache-Control: max-age=3600\n"
3682 "ETag: w/\"foo\"\n";
3683 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3685 Verify206Response(headers, 40, 49);
3686 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3687 EXPECT_EQ(0, cache.disk_cache()->open_count());
3688 EXPECT_EQ(1, cache.disk_cache()->create_count());
3690 // Now verify that there's cached data.
3691 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3692 &headers);
3694 Verify206Response(headers, 40, 49);
3695 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3696 EXPECT_EQ(1, cache.disk_cache()->open_count());
3697 EXPECT_EQ(1, cache.disk_cache()->create_count());
3699 RemoveMockTransaction(&transaction);
3702 // Tests failures to validate cache partial responses that lack strong
3703 // validators.
3704 TEST(HttpCache, RangeGET_NoValidation) {
3705 MockHttpCache cache;
3706 std::string headers;
3708 // Write to the cache (40-49).
3709 MockTransaction transaction(kRangeGET_TransactionOK);
3710 AddMockTransaction(&transaction);
3711 transaction.response_headers = "Content-Length: 10\n"
3712 "ETag: w/\"foo\"\n";
3713 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3715 Verify206Response(headers, 40, 49);
3716 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3717 EXPECT_EQ(0, cache.disk_cache()->open_count());
3718 EXPECT_EQ(1, cache.disk_cache()->create_count());
3720 // Now verify that the cached data is not used.
3721 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3722 &headers);
3724 Verify206Response(headers, 40, 49);
3725 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3726 EXPECT_EQ(1, cache.disk_cache()->open_count());
3727 EXPECT_EQ(2, cache.disk_cache()->create_count());
3729 RemoveMockTransaction(&transaction);
3732 // Tests that we cache partial responses that lack content-length.
3733 TEST(HttpCache, RangeGET_NoContentLength) {
3734 MockHttpCache cache;
3735 std::string headers;
3737 // Attempt to write to the cache (40-49).
3738 MockTransaction transaction(kRangeGET_TransactionOK);
3739 AddMockTransaction(&transaction);
3740 transaction.response_headers = "ETag: \"foo\"\n"
3741 "Accept-Ranges: bytes\n"
3742 "Content-Range: bytes 40-49/80\n";
3743 transaction.handler = NULL;
3744 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3746 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3747 EXPECT_EQ(0, cache.disk_cache()->open_count());
3748 EXPECT_EQ(1, cache.disk_cache()->create_count());
3750 // Now verify that there's no cached data.
3751 transaction.handler = &RangeTransactionServer::RangeHandler;
3752 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3753 &headers);
3755 Verify206Response(headers, 40, 49);
3756 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3757 EXPECT_EQ(1, cache.disk_cache()->open_count());
3758 EXPECT_EQ(1, cache.disk_cache()->create_count());
3760 RemoveMockTransaction(&transaction);
3763 // Tests that we can cache range requests and fetch random blocks from the
3764 // cache and the network.
3765 TEST(HttpCache, RangeGET_OK) {
3766 MockHttpCache cache;
3767 AddMockTransaction(&kRangeGET_TransactionOK);
3768 std::string headers;
3770 // Write to the cache (40-49).
3771 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3772 &headers);
3774 Verify206Response(headers, 40, 49);
3775 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3776 EXPECT_EQ(0, cache.disk_cache()->open_count());
3777 EXPECT_EQ(1, cache.disk_cache()->create_count());
3779 // Read from the cache (40-49).
3780 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3781 &headers);
3783 Verify206Response(headers, 40, 49);
3784 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3785 EXPECT_EQ(1, cache.disk_cache()->open_count());
3786 EXPECT_EQ(1, cache.disk_cache()->create_count());
3788 // Make sure we are done with the previous transaction.
3789 base::MessageLoop::current()->RunUntilIdle();
3791 // Write to the cache (30-39).
3792 MockTransaction transaction(kRangeGET_TransactionOK);
3793 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3794 transaction.data = "rg: 30-39 ";
3795 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3797 Verify206Response(headers, 30, 39);
3798 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3799 EXPECT_EQ(2, cache.disk_cache()->open_count());
3800 EXPECT_EQ(1, cache.disk_cache()->create_count());
3802 // Make sure we are done with the previous transaction.
3803 base::MessageLoop::current()->RunUntilIdle();
3805 // Write and read from the cache (20-59).
3806 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3807 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3808 net::CapturingBoundNetLog log;
3809 net::LoadTimingInfo load_timing_info;
3810 RunTransactionTestWithResponseAndGetTiming(
3811 cache.http_cache(), transaction, &headers, log.bound(),
3812 &load_timing_info);
3814 Verify206Response(headers, 20, 59);
3815 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3816 EXPECT_EQ(3, cache.disk_cache()->open_count());
3817 EXPECT_EQ(1, cache.disk_cache()->create_count());
3818 TestLoadTimingNetworkRequest(load_timing_info);
3820 RemoveMockTransaction(&kRangeGET_TransactionOK);
3823 // Checks that with a cache backend having Sparse IO unimplementes the cache
3824 // entry would be doomed after a range request.
3825 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3826 TEST(HttpCache, RangeGET_SparseNotImplemented) {
3827 MockHttpCache cache;
3828 cache.disk_cache()->set_fail_sparse_requests();
3830 // Run a cacheable request to prime the cache.
3831 MockTransaction transaction(kTypicalGET_Transaction);
3832 transaction.url = kRangeGET_TransactionOK.url;
3833 AddMockTransaction(&transaction);
3834 RunTransactionTest(cache.http_cache(), transaction);
3835 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3836 EXPECT_EQ(0, cache.disk_cache()->open_count());
3837 EXPECT_EQ(1, cache.disk_cache()->create_count());
3839 // Verify that we added the entry.
3840 disk_cache::Entry* entry;
3841 net::TestCompletionCallback cb;
3842 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3843 &entry,
3844 cb.callback());
3845 ASSERT_EQ(net::OK, cb.GetResult(rv));
3846 EXPECT_EQ(1, cache.disk_cache()->open_count());
3847 entry->Close();
3848 RemoveMockTransaction(&transaction);
3850 // Request the range with the backend that does not support it.
3851 MockTransaction transaction2(kRangeGET_TransactionOK);
3852 std::string headers;
3853 AddMockTransaction(&transaction2);
3854 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3855 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3856 EXPECT_EQ(2, cache.disk_cache()->open_count());
3857 EXPECT_EQ(2, cache.disk_cache()->create_count());
3859 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3860 // if it was re-created later, so this effectively checks that the old data is
3861 // gone.
3862 disk_cache::Entry* entry2;
3863 rv = cache.disk_cache()->OpenEntry(transaction2.url,
3864 &entry2,
3865 cb.callback());
3866 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3867 RemoveMockTransaction(&transaction2);
3870 TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3871 MockHttpCache cache;
3872 cache.disk_cache()->set_fail_sparse_requests();
3874 // Request the range with the backend that does not support it.
3875 MockTransaction transaction(kRangeGET_TransactionOK);
3876 std::string headers;
3877 AddMockTransaction(&transaction);
3878 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3879 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3880 EXPECT_EQ(0, cache.disk_cache()->open_count());
3881 EXPECT_EQ(1, cache.disk_cache()->create_count());
3883 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3884 // if it was re-created later, so this effectively checks that the old data is
3885 // gone as a result of a failed range write.
3886 disk_cache::Entry* entry;
3887 net::TestCompletionCallback cb;
3888 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3889 &entry,
3890 cb.callback());
3891 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3892 RemoveMockTransaction(&transaction);
3895 // Tests that we can cache range requests and fetch random blocks from the
3896 // cache and the network, with synchronous responses.
3897 TEST(HttpCache, RangeGET_SyncOK) {
3898 MockHttpCache cache;
3900 MockTransaction transaction(kRangeGET_TransactionOK);
3901 transaction.test_mode = TEST_MODE_SYNC_ALL;
3902 AddMockTransaction(&transaction);
3904 // Write to the cache (40-49).
3905 std::string headers;
3906 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3908 Verify206Response(headers, 40, 49);
3909 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3910 EXPECT_EQ(0, cache.disk_cache()->open_count());
3911 EXPECT_EQ(1, cache.disk_cache()->create_count());
3913 // Read from the cache (40-49).
3914 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3916 Verify206Response(headers, 40, 49);
3917 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3918 EXPECT_EQ(0, 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 to the cache (30-39).
3925 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3926 transaction.data = "rg: 30-39 ";
3927 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3929 Verify206Response(headers, 30, 39);
3930 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3931 EXPECT_EQ(1, cache.disk_cache()->open_count());
3932 EXPECT_EQ(1, cache.disk_cache()->create_count());
3934 // Make sure we are done with the previous transaction.
3935 base::MessageLoop::current()->RunUntilIdle();
3937 // Write and read from the cache (20-59).
3938 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3939 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3940 net::CapturingBoundNetLog log;
3941 net::LoadTimingInfo load_timing_info;
3942 RunTransactionTestWithResponseAndGetTiming(
3943 cache.http_cache(), transaction, &headers, log.bound(),
3944 &load_timing_info);
3946 Verify206Response(headers, 20, 59);
3947 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3948 EXPECT_EQ(2, cache.disk_cache()->open_count());
3949 EXPECT_EQ(1, cache.disk_cache()->create_count());
3950 TestLoadTimingNetworkRequest(load_timing_info);
3952 RemoveMockTransaction(&transaction);
3955 // Tests that we don't revalidate an entry unless we are required to do so.
3956 TEST(HttpCache, RangeGET_Revalidate1) {
3957 MockHttpCache cache;
3958 std::string headers;
3960 // Write to the cache (40-49).
3961 MockTransaction transaction(kRangeGET_TransactionOK);
3962 transaction.response_headers =
3963 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3964 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3965 "ETag: \"foo\"\n"
3966 "Accept-Ranges: bytes\n"
3967 "Content-Length: 10\n";
3968 AddMockTransaction(&transaction);
3969 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3971 Verify206Response(headers, 40, 49);
3972 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3973 EXPECT_EQ(0, cache.disk_cache()->open_count());
3974 EXPECT_EQ(1, cache.disk_cache()->create_count());
3976 // Read from the cache (40-49).
3977 net::CapturingBoundNetLog log;
3978 net::LoadTimingInfo load_timing_info;
3979 RunTransactionTestWithResponseAndGetTiming(
3980 cache.http_cache(), transaction, &headers, log.bound(),
3981 &load_timing_info);
3983 Verify206Response(headers, 40, 49);
3984 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3985 EXPECT_EQ(1, cache.disk_cache()->open_count());
3986 EXPECT_EQ(1, cache.disk_cache()->create_count());
3987 TestLoadTimingCachedResponse(load_timing_info);
3989 // Read again forcing the revalidation.
3990 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3991 RunTransactionTestWithResponseAndGetTiming(
3992 cache.http_cache(), transaction, &headers, log.bound(),
3993 &load_timing_info);
3995 Verify206Response(headers, 40, 49);
3996 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3997 EXPECT_EQ(1, cache.disk_cache()->open_count());
3998 EXPECT_EQ(1, cache.disk_cache()->create_count());
3999 TestLoadTimingNetworkRequest(load_timing_info);
4001 RemoveMockTransaction(&transaction);
4004 // Checks that we revalidate an entry when the headers say so.
4005 TEST(HttpCache, RangeGET_Revalidate2) {
4006 MockHttpCache cache;
4007 std::string headers;
4009 // Write to the cache (40-49).
4010 MockTransaction transaction(kRangeGET_TransactionOK);
4011 transaction.response_headers =
4012 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4013 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4014 "ETag: \"foo\"\n"
4015 "Accept-Ranges: bytes\n"
4016 "Content-Length: 10\n";
4017 AddMockTransaction(&transaction);
4018 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4020 Verify206Response(headers, 40, 49);
4021 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4022 EXPECT_EQ(0, cache.disk_cache()->open_count());
4023 EXPECT_EQ(1, cache.disk_cache()->create_count());
4025 // Read from the cache (40-49).
4026 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4027 Verify206Response(headers, 40, 49);
4029 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4030 EXPECT_EQ(1, cache.disk_cache()->open_count());
4031 EXPECT_EQ(1, cache.disk_cache()->create_count());
4033 RemoveMockTransaction(&transaction);
4036 // Tests that we deal with 304s for range requests.
4037 TEST(HttpCache, RangeGET_304) {
4038 MockHttpCache cache;
4039 AddMockTransaction(&kRangeGET_TransactionOK);
4040 std::string headers;
4042 // Write to the cache (40-49).
4043 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4044 &headers);
4046 Verify206Response(headers, 40, 49);
4047 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4048 EXPECT_EQ(0, cache.disk_cache()->open_count());
4049 EXPECT_EQ(1, cache.disk_cache()->create_count());
4051 // Read from the cache (40-49).
4052 RangeTransactionServer handler;
4053 handler.set_not_modified(true);
4054 MockTransaction transaction(kRangeGET_TransactionOK);
4055 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4056 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4058 Verify206Response(headers, 40, 49);
4059 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4060 EXPECT_EQ(1, cache.disk_cache()->open_count());
4061 EXPECT_EQ(1, cache.disk_cache()->create_count());
4063 RemoveMockTransaction(&kRangeGET_TransactionOK);
4066 // Tests that we deal with 206s when revalidating range requests.
4067 TEST(HttpCache, RangeGET_ModifiedResult) {
4068 MockHttpCache cache;
4069 AddMockTransaction(&kRangeGET_TransactionOK);
4070 std::string headers;
4072 // Write to the cache (40-49).
4073 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4074 &headers);
4076 Verify206Response(headers, 40, 49);
4077 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4078 EXPECT_EQ(0, cache.disk_cache()->open_count());
4079 EXPECT_EQ(1, cache.disk_cache()->create_count());
4081 // Attempt to read from the cache (40-49).
4082 RangeTransactionServer handler;
4083 handler.set_modified(true);
4084 MockTransaction transaction(kRangeGET_TransactionOK);
4085 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4086 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4088 Verify206Response(headers, 40, 49);
4089 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4090 EXPECT_EQ(1, cache.disk_cache()->open_count());
4091 EXPECT_EQ(1, cache.disk_cache()->create_count());
4093 // And the entry should be gone.
4094 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4095 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4096 EXPECT_EQ(1, cache.disk_cache()->open_count());
4097 EXPECT_EQ(2, cache.disk_cache()->create_count());
4099 RemoveMockTransaction(&kRangeGET_TransactionOK);
4102 // Tests that we cache 301s for range requests.
4103 TEST(HttpCache, RangeGET_301) {
4104 MockHttpCache cache;
4105 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4106 transaction.status = "HTTP/1.1 301 Moved Permanently";
4107 transaction.response_headers = "Location: http://www.bar.com/\n";
4108 transaction.data = "";
4109 transaction.handler = NULL;
4110 AddMockTransaction(&transaction);
4112 // Write to the cache.
4113 RunTransactionTest(cache.http_cache(), transaction);
4114 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4115 EXPECT_EQ(0, cache.disk_cache()->open_count());
4116 EXPECT_EQ(1, cache.disk_cache()->create_count());
4118 // Read from the cache.
4119 RunTransactionTest(cache.http_cache(), transaction);
4120 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4121 EXPECT_EQ(1, cache.disk_cache()->open_count());
4122 EXPECT_EQ(1, cache.disk_cache()->create_count());
4124 RemoveMockTransaction(&transaction);
4127 // Tests that we can cache range requests when the start or end is unknown.
4128 // We start with one suffix request, followed by a request from a given point.
4129 TEST(HttpCache, UnknownRangeGET_1) {
4130 MockHttpCache cache;
4131 AddMockTransaction(&kRangeGET_TransactionOK);
4132 std::string headers;
4134 // Write to the cache (70-79).
4135 MockTransaction transaction(kRangeGET_TransactionOK);
4136 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4137 transaction.data = "rg: 70-79 ";
4138 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4140 Verify206Response(headers, 70, 79);
4141 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4142 EXPECT_EQ(0, cache.disk_cache()->open_count());
4143 EXPECT_EQ(1, cache.disk_cache()->create_count());
4145 // Make sure we are done with the previous transaction.
4146 base::MessageLoop::current()->RunUntilIdle();
4148 // Write and read from the cache (60-79).
4149 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
4150 transaction.data = "rg: 60-69 rg: 70-79 ";
4151 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4153 Verify206Response(headers, 60, 79);
4154 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4155 EXPECT_EQ(1, cache.disk_cache()->open_count());
4156 EXPECT_EQ(1, cache.disk_cache()->create_count());
4158 RemoveMockTransaction(&kRangeGET_TransactionOK);
4161 // Tests that we can cache range requests when the start or end is unknown.
4162 // We start with one request from a given point, followed by a suffix request.
4163 // We'll also verify that synchronous cache responses work as intended.
4164 TEST(HttpCache, UnknownRangeGET_2) {
4165 MockHttpCache cache;
4166 std::string headers;
4168 MockTransaction transaction(kRangeGET_TransactionOK);
4169 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
4170 TEST_MODE_SYNC_CACHE_READ |
4171 TEST_MODE_SYNC_CACHE_WRITE;
4172 AddMockTransaction(&transaction);
4174 // Write to the cache (70-79).
4175 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4176 transaction.data = "rg: 70-79 ";
4177 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4179 Verify206Response(headers, 70, 79);
4180 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4181 EXPECT_EQ(0, cache.disk_cache()->open_count());
4182 EXPECT_EQ(1, cache.disk_cache()->create_count());
4184 // Make sure we are done with the previous transaction.
4185 base::MessageLoop::current()->RunUntilIdle();
4187 // Write and read from the cache (60-79).
4188 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
4189 transaction.data = "rg: 60-69 rg: 70-79 ";
4190 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4192 Verify206Response(headers, 60, 79);
4193 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4194 EXPECT_EQ(1, cache.disk_cache()->open_count());
4195 EXPECT_EQ(1, cache.disk_cache()->create_count());
4197 RemoveMockTransaction(&transaction);
4200 // Tests that receiving Not Modified when asking for an open range doesn't mess
4201 // up things.
4202 TEST(HttpCache, UnknownRangeGET_304) {
4203 MockHttpCache cache;
4204 std::string headers;
4206 MockTransaction transaction(kRangeGET_TransactionOK);
4207 AddMockTransaction(&transaction);
4209 RangeTransactionServer handler;
4210 handler.set_not_modified(true);
4212 // Ask for the end of the file, without knowing the length.
4213 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4214 transaction.data = "";
4215 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4217 // We just bypass the cache.
4218 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4219 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4220 EXPECT_EQ(0, cache.disk_cache()->open_count());
4221 EXPECT_EQ(1, cache.disk_cache()->create_count());
4223 RunTransactionTest(cache.http_cache(), transaction);
4224 EXPECT_EQ(2, cache.disk_cache()->create_count());
4226 RemoveMockTransaction(&transaction);
4229 // Tests that we can handle non-range requests when we have cached a range.
4230 TEST(HttpCache, GET_Previous206) {
4231 MockHttpCache cache;
4232 AddMockTransaction(&kRangeGET_TransactionOK);
4233 std::string headers;
4234 net::CapturingBoundNetLog log;
4235 net::LoadTimingInfo load_timing_info;
4237 // Write to the cache (40-49).
4238 RunTransactionTestWithResponseAndGetTiming(
4239 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4240 &load_timing_info);
4242 Verify206Response(headers, 40, 49);
4243 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4244 EXPECT_EQ(0, cache.disk_cache()->open_count());
4245 EXPECT_EQ(1, cache.disk_cache()->create_count());
4246 TestLoadTimingNetworkRequest(load_timing_info);
4248 // Write and read from the cache (0-79), when not asked for a range.
4249 MockTransaction transaction(kRangeGET_TransactionOK);
4250 transaction.request_headers = EXTRA_HEADER;
4251 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4252 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4253 RunTransactionTestWithResponseAndGetTiming(
4254 cache.http_cache(), transaction, &headers, log.bound(),
4255 &load_timing_info);
4257 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4258 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4259 EXPECT_EQ(1, cache.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache.disk_cache()->create_count());
4261 TestLoadTimingNetworkRequest(load_timing_info);
4263 RemoveMockTransaction(&kRangeGET_TransactionOK);
4266 // Tests that we can handle non-range requests when we have cached the first
4267 // part of the object and the server replies with 304 (Not Modified).
4268 TEST(HttpCache, GET_Previous206_NotModified) {
4269 MockHttpCache cache;
4271 MockTransaction transaction(kRangeGET_TransactionOK);
4272 AddMockTransaction(&transaction);
4273 std::string headers;
4274 net::CapturingBoundNetLog log;
4275 net::LoadTimingInfo load_timing_info;
4277 // Write to the cache (0-9).
4278 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4279 transaction.data = "rg: 00-09 ";
4280 RunTransactionTestWithResponseAndGetTiming(
4281 cache.http_cache(), transaction, &headers, log.bound(),
4282 &load_timing_info);
4283 Verify206Response(headers, 0, 9);
4284 TestLoadTimingNetworkRequest(load_timing_info);
4286 // Write to the cache (70-79).
4287 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4288 transaction.data = "rg: 70-79 ";
4289 RunTransactionTestWithResponseAndGetTiming(
4290 cache.http_cache(), transaction, &headers, log.bound(),
4291 &load_timing_info);
4292 Verify206Response(headers, 70, 79);
4294 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4295 EXPECT_EQ(1, cache.disk_cache()->open_count());
4296 EXPECT_EQ(1, cache.disk_cache()->create_count());
4297 TestLoadTimingNetworkRequest(load_timing_info);
4299 // Read from the cache (0-9), write and read from cache (10 - 79).
4300 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4301 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
4302 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4303 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4304 RunTransactionTestWithResponseAndGetTiming(
4305 cache.http_cache(), transaction, &headers, log.bound(),
4306 &load_timing_info);
4308 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4309 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4310 EXPECT_EQ(2, cache.disk_cache()->open_count());
4311 EXPECT_EQ(1, cache.disk_cache()->create_count());
4312 TestLoadTimingNetworkRequest(load_timing_info);
4314 RemoveMockTransaction(&transaction);
4317 // Tests that we can handle a regular request to a sparse entry, that results in
4318 // new content provided by the server (206).
4319 TEST(HttpCache, GET_Previous206_NewContent) {
4320 MockHttpCache cache;
4321 AddMockTransaction(&kRangeGET_TransactionOK);
4322 std::string headers;
4324 // Write to the cache (0-9).
4325 MockTransaction transaction(kRangeGET_TransactionOK);
4326 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4327 transaction.data = "rg: 00-09 ";
4328 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4330 Verify206Response(headers, 0, 9);
4331 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4332 EXPECT_EQ(0, cache.disk_cache()->open_count());
4333 EXPECT_EQ(1, cache.disk_cache()->create_count());
4335 // Now we'll issue a request without any range that should result first in a
4336 // 206 (when revalidating), and then in a weird standard answer: the test
4337 // server will not modify the response so we'll get the default range... a
4338 // real server will answer with 200.
4339 MockTransaction transaction2(kRangeGET_TransactionOK);
4340 transaction2.request_headers = EXTRA_HEADER;
4341 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
4342 transaction2.data = "Not a range";
4343 RangeTransactionServer handler;
4344 handler.set_modified(true);
4345 net::CapturingBoundNetLog log;
4346 net::LoadTimingInfo load_timing_info;
4347 RunTransactionTestWithResponseAndGetTiming(
4348 cache.http_cache(), transaction2, &headers, log.bound(),
4349 &load_timing_info);
4351 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4352 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4353 EXPECT_EQ(1, cache.disk_cache()->open_count());
4354 EXPECT_EQ(1, cache.disk_cache()->create_count());
4355 TestLoadTimingNetworkRequest(load_timing_info);
4357 // Verify that the previous request deleted the entry.
4358 RunTransactionTest(cache.http_cache(), transaction);
4359 EXPECT_EQ(2, cache.disk_cache()->create_count());
4361 RemoveMockTransaction(&transaction);
4364 // Tests that we can handle cached 206 responses that are not sparse.
4365 TEST(HttpCache, GET_Previous206_NotSparse) {
4366 MockHttpCache cache;
4368 // Create a disk cache entry that stores 206 headers while not being sparse.
4369 disk_cache::Entry* entry;
4370 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4371 NULL));
4373 std::string raw_headers(kRangeGET_TransactionOK.status);
4374 raw_headers.append("\n");
4375 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4376 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4377 raw_headers.size());
4379 net::HttpResponseInfo response;
4380 response.headers = new net::HttpResponseHeaders(raw_headers);
4381 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4383 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4384 int len = static_cast<int>(base::strlcpy(buf->data(),
4385 kRangeGET_TransactionOK.data, 500));
4386 net::TestCompletionCallback cb;
4387 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4388 EXPECT_EQ(len, cb.GetResult(rv));
4389 entry->Close();
4391 // Now see that we don't use the stored entry.
4392 std::string headers;
4393 net::CapturingBoundNetLog log;
4394 net::LoadTimingInfo load_timing_info;
4395 RunTransactionTestWithResponseAndGetTiming(
4396 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4397 &load_timing_info);
4399 // We are expecting a 200.
4400 std::string expected_headers(kSimpleGET_Transaction.status);
4401 expected_headers.append("\n");
4402 expected_headers.append(kSimpleGET_Transaction.response_headers);
4403 EXPECT_EQ(expected_headers, headers);
4404 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4405 EXPECT_EQ(1, cache.disk_cache()->open_count());
4406 EXPECT_EQ(2, cache.disk_cache()->create_count());
4407 TestLoadTimingNetworkRequest(load_timing_info);
4410 // Tests that we can handle cached 206 responses that are not sparse. This time
4411 // we issue a range request and expect to receive a range.
4412 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4413 MockHttpCache cache;
4414 AddMockTransaction(&kRangeGET_TransactionOK);
4416 // Create a disk cache entry that stores 206 headers while not being sparse.
4417 disk_cache::Entry* entry;
4418 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4419 NULL));
4421 std::string raw_headers(kRangeGET_TransactionOK.status);
4422 raw_headers.append("\n");
4423 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4424 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4425 raw_headers.size());
4427 net::HttpResponseInfo response;
4428 response.headers = new net::HttpResponseHeaders(raw_headers);
4429 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4431 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4432 int len = static_cast<int>(base::strlcpy(buf->data(),
4433 kRangeGET_TransactionOK.data, 500));
4434 net::TestCompletionCallback cb;
4435 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4436 EXPECT_EQ(len, cb.GetResult(rv));
4437 entry->Close();
4439 // Now see that we don't use the stored entry.
4440 std::string headers;
4441 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4442 &headers);
4444 // We are expecting a 206.
4445 Verify206Response(headers, 40, 49);
4446 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4447 EXPECT_EQ(1, cache.disk_cache()->open_count());
4448 EXPECT_EQ(2, cache.disk_cache()->create_count());
4450 RemoveMockTransaction(&kRangeGET_TransactionOK);
4453 // Tests that we can handle cached 206 responses that can't be validated.
4454 TEST(HttpCache, GET_Previous206_NotValidation) {
4455 MockHttpCache cache;
4457 // Create a disk cache entry that stores 206 headers.
4458 disk_cache::Entry* entry;
4459 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4460 NULL));
4462 // Make sure that the headers cannot be validated with the server.
4463 std::string raw_headers(kRangeGET_TransactionOK.status);
4464 raw_headers.append("\n");
4465 raw_headers.append("Content-Length: 80\n");
4466 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4467 raw_headers.size());
4469 net::HttpResponseInfo response;
4470 response.headers = new net::HttpResponseHeaders(raw_headers);
4471 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4473 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4474 int len = static_cast<int>(base::strlcpy(buf->data(),
4475 kRangeGET_TransactionOK.data, 500));
4476 net::TestCompletionCallback cb;
4477 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4478 EXPECT_EQ(len, cb.GetResult(rv));
4479 entry->Close();
4481 // Now see that we don't use the stored entry.
4482 std::string headers;
4483 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4484 &headers);
4486 // We are expecting a 200.
4487 std::string expected_headers(kSimpleGET_Transaction.status);
4488 expected_headers.append("\n");
4489 expected_headers.append(kSimpleGET_Transaction.response_headers);
4490 EXPECT_EQ(expected_headers, headers);
4491 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4492 EXPECT_EQ(1, cache.disk_cache()->open_count());
4493 EXPECT_EQ(2, cache.disk_cache()->create_count());
4496 // Tests that we can handle range requests with cached 200 responses.
4497 TEST(HttpCache, RangeGET_Previous200) {
4498 MockHttpCache cache;
4500 // Store the whole thing with status 200.
4501 MockTransaction transaction(kTypicalGET_Transaction);
4502 transaction.url = kRangeGET_TransactionOK.url;
4503 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4504 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4505 AddMockTransaction(&transaction);
4506 RunTransactionTest(cache.http_cache(), transaction);
4507 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4508 EXPECT_EQ(0, cache.disk_cache()->open_count());
4509 EXPECT_EQ(1, cache.disk_cache()->create_count());
4511 RemoveMockTransaction(&transaction);
4512 AddMockTransaction(&kRangeGET_TransactionOK);
4514 // Now see that we use the stored entry.
4515 std::string headers;
4516 MockTransaction transaction2(kRangeGET_TransactionOK);
4517 RangeTransactionServer handler;
4518 handler.set_not_modified(true);
4519 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4521 // We are expecting a 206.
4522 Verify206Response(headers, 40, 49);
4523 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4524 EXPECT_EQ(1, cache.disk_cache()->open_count());
4525 EXPECT_EQ(1, cache.disk_cache()->create_count());
4527 // The last transaction has finished so make sure the entry is deactivated.
4528 base::MessageLoop::current()->RunUntilIdle();
4530 // Make a request for an invalid range.
4531 MockTransaction transaction3(kRangeGET_TransactionOK);
4532 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4533 transaction3.data = transaction.data;
4534 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4535 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4536 EXPECT_EQ(2, cache.disk_cache()->open_count());
4537 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4538 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4539 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4541 // Make sure the entry is deactivated.
4542 base::MessageLoop::current()->RunUntilIdle();
4544 // Even though the request was invalid, we should have the entry.
4545 RunTransactionTest(cache.http_cache(), transaction2);
4546 EXPECT_EQ(3, cache.disk_cache()->open_count());
4548 // Make sure the entry is deactivated.
4549 base::MessageLoop::current()->RunUntilIdle();
4551 // Now we should receive a range from the server and drop the stored entry.
4552 handler.set_not_modified(false);
4553 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4554 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4555 Verify206Response(headers, 40, 49);
4556 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4557 EXPECT_EQ(4, cache.disk_cache()->open_count());
4558 EXPECT_EQ(1, cache.disk_cache()->create_count());
4560 RunTransactionTest(cache.http_cache(), transaction2);
4561 EXPECT_EQ(2, cache.disk_cache()->create_count());
4563 RemoveMockTransaction(&kRangeGET_TransactionOK);
4566 // Tests that we can handle a 200 response when dealing with sparse entries.
4567 TEST(HttpCache, RangeRequestResultsIn200) {
4568 MockHttpCache cache;
4569 AddMockTransaction(&kRangeGET_TransactionOK);
4570 std::string headers;
4572 // Write to the cache (70-79).
4573 MockTransaction transaction(kRangeGET_TransactionOK);
4574 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4575 transaction.data = "rg: 70-79 ";
4576 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4578 Verify206Response(headers, 70, 79);
4579 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4580 EXPECT_EQ(0, cache.disk_cache()->open_count());
4581 EXPECT_EQ(1, cache.disk_cache()->create_count());
4583 // Now we'll issue a request that results in a plain 200 response, but to
4584 // the to the same URL that we used to store sparse data, and making sure
4585 // that we ask for a range.
4586 RemoveMockTransaction(&kRangeGET_TransactionOK);
4587 MockTransaction transaction2(kSimpleGET_Transaction);
4588 transaction2.url = kRangeGET_TransactionOK.url;
4589 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4590 AddMockTransaction(&transaction2);
4592 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4594 std::string expected_headers(kSimpleGET_Transaction.status);
4595 expected_headers.append("\n");
4596 expected_headers.append(kSimpleGET_Transaction.response_headers);
4597 EXPECT_EQ(expected_headers, headers);
4598 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4599 EXPECT_EQ(1, cache.disk_cache()->open_count());
4600 EXPECT_EQ(1, cache.disk_cache()->create_count());
4602 RemoveMockTransaction(&transaction2);
4605 // Tests that a range request that falls outside of the size that we know about
4606 // only deletes the entry if the resource has indeed changed.
4607 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4608 MockHttpCache cache;
4609 AddMockTransaction(&kRangeGET_TransactionOK);
4610 std::string headers;
4612 // Write to the cache (40-49).
4613 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4614 &headers);
4616 Verify206Response(headers, 40, 49);
4617 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4618 EXPECT_EQ(0, cache.disk_cache()->open_count());
4619 EXPECT_EQ(1, cache.disk_cache()->create_count());
4621 // A weird request should not delete this entry. Ask for bytes 120-.
4622 MockTransaction transaction(kRangeGET_TransactionOK);
4623 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4624 transaction.data = "";
4625 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4627 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4628 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4629 EXPECT_EQ(1, cache.disk_cache()->open_count());
4630 EXPECT_EQ(1, cache.disk_cache()->create_count());
4632 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4633 EXPECT_EQ(2, cache.disk_cache()->open_count());
4634 EXPECT_EQ(1, cache.disk_cache()->create_count());
4636 RemoveMockTransaction(&kRangeGET_TransactionOK);
4639 // Tests that we don't delete a sparse entry when we cancel a request.
4640 TEST(HttpCache, RangeGET_Cancel) {
4641 MockHttpCache cache;
4642 AddMockTransaction(&kRangeGET_TransactionOK);
4644 MockHttpRequest request(kRangeGET_TransactionOK);
4646 Context* c = new Context();
4647 int rv = cache.CreateTransaction(&c->trans);
4648 ASSERT_EQ(net::OK, rv);
4650 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4651 if (rv == net::ERR_IO_PENDING)
4652 rv = c->callback.WaitForResult();
4654 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4655 EXPECT_EQ(0, cache.disk_cache()->open_count());
4656 EXPECT_EQ(1, cache.disk_cache()->create_count());
4658 // Make sure that the entry has some data stored.
4659 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4660 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4661 if (rv == net::ERR_IO_PENDING)
4662 rv = c->callback.WaitForResult();
4663 EXPECT_EQ(buf->size(), rv);
4665 // Destroy the transaction.
4666 delete c;
4668 // Verify that the entry has not been deleted.
4669 disk_cache::Entry* entry;
4670 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4671 entry->Close();
4672 RemoveMockTransaction(&kRangeGET_TransactionOK);
4675 // Tests that we don't delete a sparse entry when we start a new request after
4676 // cancelling the previous one.
4677 TEST(HttpCache, RangeGET_Cancel2) {
4678 MockHttpCache cache;
4679 AddMockTransaction(&kRangeGET_TransactionOK);
4681 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4682 MockHttpRequest request(kRangeGET_TransactionOK);
4683 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4685 Context* c = new Context();
4686 int rv = cache.CreateTransaction(&c->trans);
4687 ASSERT_EQ(net::OK, rv);
4689 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4690 if (rv == net::ERR_IO_PENDING)
4691 rv = c->callback.WaitForResult();
4693 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4694 EXPECT_EQ(1, cache.disk_cache()->open_count());
4695 EXPECT_EQ(1, cache.disk_cache()->create_count());
4697 // Make sure that we revalidate the entry and read from the cache (a single
4698 // read will return while waiting for the network).
4699 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4700 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4701 EXPECT_EQ(5, c->callback.GetResult(rv));
4702 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4703 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4705 // Destroy the transaction before completing the read.
4706 delete c;
4708 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4709 // message loop. This means that a new transaction will just reuse the same
4710 // active entry (no open or create).
4712 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4714 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4715 EXPECT_EQ(1, cache.disk_cache()->open_count());
4716 EXPECT_EQ(1, cache.disk_cache()->create_count());
4717 RemoveMockTransaction(&kRangeGET_TransactionOK);
4720 // A slight variation of the previous test, this time we cancel two requests in
4721 // a row, making sure that the second is waiting for the entry to be ready.
4722 TEST(HttpCache, RangeGET_Cancel3) {
4723 MockHttpCache cache;
4724 AddMockTransaction(&kRangeGET_TransactionOK);
4726 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4727 MockHttpRequest request(kRangeGET_TransactionOK);
4728 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4730 Context* c = new Context();
4731 int rv = cache.CreateTransaction(&c->trans);
4732 ASSERT_EQ(net::OK, rv);
4734 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4735 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4736 rv = c->callback.WaitForResult();
4738 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4739 EXPECT_EQ(1, cache.disk_cache()->open_count());
4740 EXPECT_EQ(1, cache.disk_cache()->create_count());
4742 // Make sure that we revalidate the entry and read from the cache (a single
4743 // read will return while waiting for the network).
4744 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4745 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4746 EXPECT_EQ(5, c->callback.GetResult(rv));
4747 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4748 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4750 // Destroy the transaction before completing the read.
4751 delete c;
4753 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4754 // message loop. This means that a new transaction will just reuse the same
4755 // active entry (no open or create).
4757 c = new Context();
4758 rv = cache.CreateTransaction(&c->trans);
4759 ASSERT_EQ(net::OK, rv);
4761 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4762 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4764 MockDiskEntry::IgnoreCallbacks(true);
4765 base::MessageLoop::current()->RunUntilIdle();
4766 MockDiskEntry::IgnoreCallbacks(false);
4768 // The new transaction is waiting for the query range callback.
4769 delete c;
4771 // And we should not crash when the callback is delivered.
4772 base::MessageLoop::current()->RunUntilIdle();
4774 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4775 EXPECT_EQ(1, cache.disk_cache()->open_count());
4776 EXPECT_EQ(1, cache.disk_cache()->create_count());
4777 RemoveMockTransaction(&kRangeGET_TransactionOK);
4780 // Tests that an invalid range response results in no cached entry.
4781 TEST(HttpCache, RangeGET_InvalidResponse1) {
4782 MockHttpCache cache;
4783 std::string headers;
4785 MockTransaction transaction(kRangeGET_TransactionOK);
4786 transaction.handler = NULL;
4787 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4788 "Content-Length: 10\n";
4789 AddMockTransaction(&transaction);
4790 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4792 std::string expected(transaction.status);
4793 expected.append("\n");
4794 expected.append(transaction.response_headers);
4795 EXPECT_EQ(expected, headers);
4797 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4798 EXPECT_EQ(0, cache.disk_cache()->open_count());
4799 EXPECT_EQ(1, cache.disk_cache()->create_count());
4801 // Verify that we don't have a cached entry.
4802 disk_cache::Entry* entry;
4803 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4805 RemoveMockTransaction(&kRangeGET_TransactionOK);
4808 // Tests that we reject a range that doesn't match the content-length.
4809 TEST(HttpCache, RangeGET_InvalidResponse2) {
4810 MockHttpCache cache;
4811 std::string headers;
4813 MockTransaction transaction(kRangeGET_TransactionOK);
4814 transaction.handler = NULL;
4815 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4816 "Content-Length: 20\n";
4817 AddMockTransaction(&transaction);
4818 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4820 std::string expected(transaction.status);
4821 expected.append("\n");
4822 expected.append(transaction.response_headers);
4823 EXPECT_EQ(expected, headers);
4825 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4826 EXPECT_EQ(0, cache.disk_cache()->open_count());
4827 EXPECT_EQ(1, cache.disk_cache()->create_count());
4829 // Verify that we don't have a cached entry.
4830 disk_cache::Entry* entry;
4831 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4833 RemoveMockTransaction(&kRangeGET_TransactionOK);
4836 // Tests that if a server tells us conflicting information about a resource we
4837 // ignore the response.
4838 TEST(HttpCache, RangeGET_InvalidResponse3) {
4839 MockHttpCache cache;
4840 std::string headers;
4842 MockTransaction transaction(kRangeGET_TransactionOK);
4843 transaction.handler = NULL;
4844 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4845 std::string response_headers(transaction.response_headers);
4846 response_headers.append("Content-Range: bytes 50-59/160\n");
4847 transaction.response_headers = response_headers.c_str();
4848 AddMockTransaction(&transaction);
4849 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4851 Verify206Response(headers, 50, 59);
4852 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4853 EXPECT_EQ(0, cache.disk_cache()->open_count());
4854 EXPECT_EQ(1, cache.disk_cache()->create_count());
4856 RemoveMockTransaction(&transaction);
4857 AddMockTransaction(&kRangeGET_TransactionOK);
4859 // This transaction will report a resource size of 80 bytes, and we think it's
4860 // 160 so we should ignore the response.
4861 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4862 &headers);
4864 Verify206Response(headers, 40, 49);
4865 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4866 EXPECT_EQ(1, cache.disk_cache()->open_count());
4867 EXPECT_EQ(1, cache.disk_cache()->create_count());
4869 // Verify that we cached the first response but not the second one.
4870 disk_cache::Entry* en;
4871 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4873 int64 cached_start = 0;
4874 net::TestCompletionCallback cb;
4875 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4876 EXPECT_EQ(10, cb.GetResult(rv));
4877 EXPECT_EQ(50, cached_start);
4878 en->Close();
4880 RemoveMockTransaction(&kRangeGET_TransactionOK);
4883 // Tests that we handle large range values properly.
4884 TEST(HttpCache, RangeGET_LargeValues) {
4885 // We need a real sparse cache for this test.
4886 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4887 std::string headers;
4889 MockTransaction transaction(kRangeGET_TransactionOK);
4890 transaction.handler = NULL;
4891 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4892 EXTRA_HEADER;
4893 transaction.response_headers =
4894 "ETag: \"foo\"\n"
4895 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4896 "Content-Length: 10\n";
4897 AddMockTransaction(&transaction);
4898 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4900 std::string expected(transaction.status);
4901 expected.append("\n");
4902 expected.append(transaction.response_headers);
4903 EXPECT_EQ(expected, headers);
4905 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4907 // Verify that we have a cached entry.
4908 disk_cache::Entry* en;
4909 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4910 en->Close();
4912 RemoveMockTransaction(&kRangeGET_TransactionOK);
4915 // Tests that we don't crash with a range request if the disk cache was not
4916 // initialized properly.
4917 TEST(HttpCache, RangeGET_NoDiskCache) {
4918 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4919 factory->set_fail(true);
4920 factory->FinishCreation(); // We'll complete synchronously.
4921 MockHttpCache cache(factory);
4923 AddMockTransaction(&kRangeGET_TransactionOK);
4925 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4926 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4928 RemoveMockTransaction(&kRangeGET_TransactionOK);
4931 // Tests that we handle byte range requests that skip the cache.
4932 TEST(HttpCache, RangeHEAD) {
4933 MockHttpCache cache;
4934 AddMockTransaction(&kRangeGET_TransactionOK);
4936 MockTransaction transaction(kRangeGET_TransactionOK);
4937 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4938 transaction.method = "HEAD";
4939 transaction.data = "rg: 70-79 ";
4941 std::string headers;
4942 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4944 Verify206Response(headers, 70, 79);
4945 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4946 EXPECT_EQ(0, cache.disk_cache()->open_count());
4947 EXPECT_EQ(0, cache.disk_cache()->create_count());
4949 RemoveMockTransaction(&kRangeGET_TransactionOK);
4952 // Tests that we don't crash when after reading from the cache we issue a
4953 // request for the next range and the server gives us a 200 synchronously.
4954 TEST(HttpCache, RangeGET_FastFlakyServer) {
4955 MockHttpCache cache;
4957 MockTransaction transaction(kRangeGET_TransactionOK);
4958 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4959 transaction.test_mode = TEST_MODE_SYNC_NET_START;
4960 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4961 AddMockTransaction(&transaction);
4963 // Write to the cache.
4964 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4966 // And now read from the cache and the network.
4967 RangeTransactionServer handler;
4968 handler.set_bad_200(true);
4969 transaction.data = "Not a range";
4970 RunTransactionTest(cache.http_cache(), transaction);
4972 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4973 EXPECT_EQ(1, cache.disk_cache()->open_count());
4974 EXPECT_EQ(1, cache.disk_cache()->create_count());
4976 RemoveMockTransaction(&transaction);
4979 // Tests that when the server gives us less data than expected, we don't keep
4980 // asking for more data.
4981 TEST(HttpCache, RangeGET_FastFlakyServer2) {
4982 MockHttpCache cache;
4984 // First, check with an empty cache (WRITE mode).
4985 MockTransaction transaction(kRangeGET_TransactionOK);
4986 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4987 transaction.data = "rg: 40-"; // Less than expected.
4988 transaction.handler = NULL;
4989 std::string headers(transaction.response_headers);
4990 headers.append("Content-Range: bytes 40-49/80\n");
4991 transaction.response_headers = headers.c_str();
4993 AddMockTransaction(&transaction);
4995 // Write to the cache.
4996 RunTransactionTest(cache.http_cache(), transaction);
4998 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4999 EXPECT_EQ(0, cache.disk_cache()->open_count());
5000 EXPECT_EQ(1, cache.disk_cache()->create_count());
5002 // Now verify that even in READ_WRITE mode, we forward the bad response to
5003 // the caller.
5004 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
5005 transaction.data = "rg: 60-"; // Less than expected.
5006 headers = kRangeGET_TransactionOK.response_headers;
5007 headers.append("Content-Range: bytes 60-69/80\n");
5008 transaction.response_headers = headers.c_str();
5010 RunTransactionTest(cache.http_cache(), transaction);
5012 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5013 EXPECT_EQ(1, cache.disk_cache()->open_count());
5014 EXPECT_EQ(1, cache.disk_cache()->create_count());
5016 RemoveMockTransaction(&transaction);
5019 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5020 // This test hits a NOTREACHED so it is a release mode only test.
5021 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
5022 MockHttpCache cache;
5023 AddMockTransaction(&kRangeGET_TransactionOK);
5025 // Write to the cache (40-49).
5026 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5027 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5028 EXPECT_EQ(0, cache.disk_cache()->open_count());
5029 EXPECT_EQ(1, cache.disk_cache()->create_count());
5031 // Force this transaction to read from the cache.
5032 MockTransaction transaction(kRangeGET_TransactionOK);
5033 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5035 MockHttpRequest request(transaction);
5036 net::TestCompletionCallback callback;
5038 scoped_ptr<net::HttpTransaction> trans;
5039 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
5040 EXPECT_EQ(net::OK, rv);
5041 ASSERT_TRUE(trans.get());
5043 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5044 if (rv == net::ERR_IO_PENDING)
5045 rv = callback.WaitForResult();
5046 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5048 trans.reset();
5050 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5051 EXPECT_EQ(1, cache.disk_cache()->open_count());
5052 EXPECT_EQ(1, cache.disk_cache()->create_count());
5054 RemoveMockTransaction(&kRangeGET_TransactionOK);
5056 #endif
5058 // Tests the handling of the "truncation" flag.
5059 TEST(HttpCache, WriteResponseInfo_Truncated) {
5060 MockHttpCache cache;
5061 disk_cache::Entry* entry;
5062 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5063 NULL));
5065 std::string headers("HTTP/1.1 200 OK");
5066 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5067 net::HttpResponseInfo response;
5068 response.headers = new net::HttpResponseHeaders(headers);
5070 // Set the last argument for this to be an incomplete request.
5071 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
5072 bool truncated = false;
5073 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5074 EXPECT_TRUE(truncated);
5076 // And now test the opposite case.
5077 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
5078 truncated = true;
5079 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5080 EXPECT_FALSE(truncated);
5081 entry->Close();
5084 // Tests basic pickling/unpickling of HttpResponseInfo.
5085 TEST(HttpCache, PersistHttpResponseInfo) {
5086 // Set some fields (add more if needed.)
5087 net::HttpResponseInfo response1;
5088 response1.was_cached = false;
5089 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
5090 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5092 // Pickle.
5093 Pickle pickle;
5094 response1.Persist(&pickle, false, false);
5096 // Unpickle.
5097 net::HttpResponseInfo response2;
5098 bool response_truncated;
5099 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5100 EXPECT_FALSE(response_truncated);
5102 // Verify fields.
5103 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5104 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5105 EXPECT_EQ(80, response2.socket_address.port());
5106 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5109 // Tests that we delete an entry when the request is cancelled before starting
5110 // to read from the network.
5111 TEST(HttpCache, DoomOnDestruction) {
5112 MockHttpCache cache;
5114 MockHttpRequest request(kSimpleGET_Transaction);
5116 Context* c = new Context();
5117 int rv = cache.CreateTransaction(&c->trans);
5118 ASSERT_EQ(net::OK, rv);
5120 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5121 if (rv == net::ERR_IO_PENDING)
5122 c->result = c->callback.WaitForResult();
5124 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5125 EXPECT_EQ(0, cache.disk_cache()->open_count());
5126 EXPECT_EQ(1, cache.disk_cache()->create_count());
5128 // Destroy the transaction. We only have the headers so we should delete this
5129 // entry.
5130 delete c;
5132 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5134 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5135 EXPECT_EQ(0, cache.disk_cache()->open_count());
5136 EXPECT_EQ(2, cache.disk_cache()->create_count());
5139 // Tests that we delete an entry when the request is cancelled if the response
5140 // does not have content-length and strong validators.
5141 TEST(HttpCache, DoomOnDestruction2) {
5142 MockHttpCache cache;
5144 MockHttpRequest request(kSimpleGET_Transaction);
5146 Context* c = new Context();
5147 int rv = cache.CreateTransaction(&c->trans);
5148 ASSERT_EQ(net::OK, rv);
5150 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5151 if (rv == net::ERR_IO_PENDING)
5152 rv = c->callback.WaitForResult();
5154 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5155 EXPECT_EQ(0, cache.disk_cache()->open_count());
5156 EXPECT_EQ(1, cache.disk_cache()->create_count());
5158 // Make sure that the entry has some data stored.
5159 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5160 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5161 if (rv == net::ERR_IO_PENDING)
5162 rv = c->callback.WaitForResult();
5163 EXPECT_EQ(buf->size(), rv);
5165 // Destroy the transaction.
5166 delete c;
5168 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5170 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5171 EXPECT_EQ(0, cache.disk_cache()->open_count());
5172 EXPECT_EQ(2, cache.disk_cache()->create_count());
5175 // Tests that we delete an entry when the request is cancelled if the response
5176 // has an "Accept-Ranges: none" header.
5177 TEST(HttpCache, DoomOnDestruction3) {
5178 MockHttpCache cache;
5180 MockTransaction transaction(kSimpleGET_Transaction);
5181 transaction.response_headers =
5182 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5183 "Content-Length: 22\n"
5184 "Accept-Ranges: none\n"
5185 "Etag: \"foopy\"\n";
5186 AddMockTransaction(&transaction);
5187 MockHttpRequest request(transaction);
5189 Context* c = new Context();
5190 int rv = cache.CreateTransaction(&c->trans);
5191 ASSERT_EQ(net::OK, rv);
5193 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5194 if (rv == net::ERR_IO_PENDING)
5195 rv = c->callback.WaitForResult();
5197 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5198 EXPECT_EQ(0, cache.disk_cache()->open_count());
5199 EXPECT_EQ(1, cache.disk_cache()->create_count());
5201 // Make sure that the entry has some data stored.
5202 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5203 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5204 if (rv == net::ERR_IO_PENDING)
5205 rv = c->callback.WaitForResult();
5206 EXPECT_EQ(buf->size(), rv);
5208 // Destroy the transaction.
5209 delete c;
5211 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5213 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5214 EXPECT_EQ(0, cache.disk_cache()->open_count());
5215 EXPECT_EQ(2, cache.disk_cache()->create_count());
5217 RemoveMockTransaction(&transaction);
5220 // Tests that we mark an entry as incomplete when the request is cancelled.
5221 TEST(HttpCache, SetTruncatedFlag) {
5222 MockHttpCache cache;
5224 MockTransaction transaction(kSimpleGET_Transaction);
5225 transaction.response_headers =
5226 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5227 "Content-Length: 22\n"
5228 "Etag: \"foopy\"\n";
5229 AddMockTransaction(&transaction);
5230 MockHttpRequest request(transaction);
5232 scoped_ptr<Context> c(new Context());
5234 int rv = cache.CreateTransaction(&c->trans);
5235 ASSERT_EQ(net::OK, rv);
5237 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5238 if (rv == net::ERR_IO_PENDING)
5239 rv = c->callback.WaitForResult();
5241 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5242 EXPECT_EQ(0, cache.disk_cache()->open_count());
5243 EXPECT_EQ(1, cache.disk_cache()->create_count());
5245 // Make sure that the entry has some data stored.
5246 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5247 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5248 if (rv == net::ERR_IO_PENDING)
5249 rv = c->callback.WaitForResult();
5250 EXPECT_EQ(buf->size(), rv);
5252 // We want to cancel the request when the transaction is busy.
5253 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5254 EXPECT_EQ(net::ERR_IO_PENDING, rv);
5255 EXPECT_FALSE(c->callback.have_result());
5257 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
5259 // Destroy the transaction.
5260 c->trans.reset();
5261 MockHttpCache::SetTestMode(0);
5264 // Make sure that we don't invoke the callback. We may have an issue if the
5265 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5266 // could end up with the transaction being deleted twice if we send any
5267 // notification from the transaction destructor (see http://crbug.com/31723).
5268 EXPECT_FALSE(c->callback.have_result());
5270 // Verify that the entry is marked as incomplete.
5271 disk_cache::Entry* entry;
5272 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5273 net::HttpResponseInfo response;
5274 bool truncated = false;
5275 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5276 EXPECT_TRUE(truncated);
5277 entry->Close();
5279 RemoveMockTransaction(&transaction);
5282 // Tests that we don't mark an entry as truncated when we read everything.
5283 TEST(HttpCache, DontSetTruncatedFlag) {
5284 MockHttpCache cache;
5286 MockTransaction transaction(kSimpleGET_Transaction);
5287 transaction.response_headers =
5288 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5289 "Content-Length: 22\n"
5290 "Etag: \"foopy\"\n";
5291 AddMockTransaction(&transaction);
5292 MockHttpRequest request(transaction);
5294 scoped_ptr<Context> c(new Context());
5295 int rv = cache.CreateTransaction(&c->trans);
5296 ASSERT_EQ(net::OK, rv);
5298 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5299 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5301 // Read everything.
5302 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
5303 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5304 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5306 // Destroy the transaction.
5307 c->trans.reset();
5309 // Verify that the entry is not marked as truncated.
5310 disk_cache::Entry* entry;
5311 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5312 net::HttpResponseInfo response;
5313 bool truncated = true;
5314 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5315 EXPECT_FALSE(truncated);
5316 entry->Close();
5318 RemoveMockTransaction(&transaction);
5321 // Tests that we can continue with a request that was interrupted.
5322 TEST(HttpCache, GET_IncompleteResource) {
5323 MockHttpCache cache;
5324 AddMockTransaction(&kRangeGET_TransactionOK);
5326 std::string raw_headers("HTTP/1.1 200 OK\n"
5327 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5328 "ETag: \"foo\"\n"
5329 "Accept-Ranges: bytes\n"
5330 "Content-Length: 80\n");
5331 CreateTruncatedEntry(raw_headers, &cache);
5333 // Now make a regular request.
5334 std::string headers;
5335 MockTransaction transaction(kRangeGET_TransactionOK);
5336 transaction.request_headers = EXTRA_HEADER;
5337 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5338 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5339 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5341 // We update the headers with the ones received while revalidating.
5342 std::string expected_headers(
5343 "HTTP/1.1 200 OK\n"
5344 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5345 "Accept-Ranges: bytes\n"
5346 "ETag: \"foo\"\n"
5347 "Content-Length: 80\n");
5349 EXPECT_EQ(expected_headers, headers);
5350 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5351 EXPECT_EQ(1, cache.disk_cache()->open_count());
5352 EXPECT_EQ(1, cache.disk_cache()->create_count());
5354 // Verify that the disk entry was updated.
5355 disk_cache::Entry* entry;
5356 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5357 EXPECT_EQ(80, entry->GetDataSize(1));
5358 bool truncated = true;
5359 net::HttpResponseInfo response;
5360 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5361 EXPECT_FALSE(truncated);
5362 entry->Close();
5364 RemoveMockTransaction(&kRangeGET_TransactionOK);
5367 // Tests the handling of no-store when revalidating a truncated entry.
5368 TEST(HttpCache, GET_IncompleteResource_NoStore) {
5369 MockHttpCache cache;
5370 AddMockTransaction(&kRangeGET_TransactionOK);
5372 std::string raw_headers("HTTP/1.1 200 OK\n"
5373 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5374 "ETag: \"foo\"\n"
5375 "Accept-Ranges: bytes\n"
5376 "Content-Length: 80\n");
5377 CreateTruncatedEntry(raw_headers, &cache);
5378 RemoveMockTransaction(&kRangeGET_TransactionOK);
5380 // Now make a regular request.
5381 MockTransaction transaction(kRangeGET_TransactionOK);
5382 transaction.request_headers = EXTRA_HEADER;
5383 std::string response_headers(transaction.response_headers);
5384 response_headers += ("Cache-Control: no-store\n");
5385 transaction.response_headers = response_headers.c_str();
5386 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5387 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5388 AddMockTransaction(&transaction);
5390 std::string headers;
5391 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5393 // We update the headers with the ones received while revalidating.
5394 std::string expected_headers(
5395 "HTTP/1.1 200 OK\n"
5396 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5397 "Accept-Ranges: bytes\n"
5398 "Cache-Control: no-store\n"
5399 "ETag: \"foo\"\n"
5400 "Content-Length: 80\n");
5402 EXPECT_EQ(expected_headers, headers);
5403 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5404 EXPECT_EQ(1, cache.disk_cache()->open_count());
5405 EXPECT_EQ(1, cache.disk_cache()->create_count());
5407 // Verify that the disk entry was deleted.
5408 disk_cache::Entry* entry;
5409 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5410 RemoveMockTransaction(&transaction);
5413 // Tests cancelling a request after the server sent no-store.
5414 TEST(HttpCache, GET_IncompleteResource_Cancel) {
5415 MockHttpCache cache;
5416 AddMockTransaction(&kRangeGET_TransactionOK);
5418 std::string raw_headers("HTTP/1.1 200 OK\n"
5419 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5420 "ETag: \"foo\"\n"
5421 "Accept-Ranges: bytes\n"
5422 "Content-Length: 80\n");
5423 CreateTruncatedEntry(raw_headers, &cache);
5424 RemoveMockTransaction(&kRangeGET_TransactionOK);
5426 // Now make a regular request.
5427 MockTransaction transaction(kRangeGET_TransactionOK);
5428 transaction.request_headers = EXTRA_HEADER;
5429 std::string response_headers(transaction.response_headers);
5430 response_headers += ("Cache-Control: no-store\n");
5431 transaction.response_headers = response_headers.c_str();
5432 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5433 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5434 AddMockTransaction(&transaction);
5436 MockHttpRequest request(transaction);
5437 Context* c = new Context();
5439 int rv = cache.CreateTransaction(&c->trans);
5440 ASSERT_EQ(net::OK, rv);
5442 // Queue another request to this transaction. We have to start this request
5443 // before the first one gets the response from the server and dooms the entry,
5444 // otherwise it will just create a new entry without being queued to the first
5445 // request.
5446 Context* pending = new Context();
5447 ASSERT_EQ(net::OK, cache.CreateTransaction(&pending->trans));
5449 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5450 EXPECT_EQ(net::ERR_IO_PENDING,
5451 pending->trans->Start(&request, pending->callback.callback(),
5452 net::BoundNetLog()));
5453 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5455 // Make sure that the entry has some data stored.
5456 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
5457 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5458 EXPECT_EQ(5, c->callback.GetResult(rv));
5460 // Cancel the requests.
5461 delete c;
5462 delete pending;
5464 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5465 EXPECT_EQ(1, cache.disk_cache()->open_count());
5466 EXPECT_EQ(2, cache.disk_cache()->create_count());
5468 base::MessageLoop::current()->RunUntilIdle();
5469 RemoveMockTransaction(&transaction);
5472 // Tests that we delete truncated entries if the server changes its mind midway.
5473 TEST(HttpCache, GET_IncompleteResource2) {
5474 MockHttpCache cache;
5475 AddMockTransaction(&kRangeGET_TransactionOK);
5477 // Content-length will be intentionally bad.
5478 std::string raw_headers("HTTP/1.1 200 OK\n"
5479 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5480 "ETag: \"foo\"\n"
5481 "Accept-Ranges: bytes\n"
5482 "Content-Length: 50\n");
5483 CreateTruncatedEntry(raw_headers, &cache);
5485 // Now make a regular request. We expect the code to fail the validation and
5486 // retry the request without using byte ranges.
5487 std::string headers;
5488 MockTransaction transaction(kRangeGET_TransactionOK);
5489 transaction.request_headers = EXTRA_HEADER;
5490 transaction.data = "Not a range";
5491 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5493 // The server will return 200 instead of a byte range.
5494 std::string expected_headers(
5495 "HTTP/1.1 200 OK\n"
5496 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5498 EXPECT_EQ(expected_headers, headers);
5499 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5500 EXPECT_EQ(1, cache.disk_cache()->open_count());
5501 EXPECT_EQ(1, cache.disk_cache()->create_count());
5503 // Verify that the disk entry was deleted.
5504 disk_cache::Entry* entry;
5505 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5506 RemoveMockTransaction(&kRangeGET_TransactionOK);
5509 // Tests that we always validate a truncated request.
5510 TEST(HttpCache, GET_IncompleteResource3) {
5511 MockHttpCache cache;
5512 AddMockTransaction(&kRangeGET_TransactionOK);
5514 // This should not require validation for 10 hours.
5515 std::string raw_headers("HTTP/1.1 200 OK\n"
5516 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5517 "ETag: \"foo\"\n"
5518 "Cache-Control: max-age= 36000\n"
5519 "Accept-Ranges: bytes\n"
5520 "Content-Length: 80\n");
5521 CreateTruncatedEntry(raw_headers, &cache);
5523 // Now make a regular request.
5524 std::string headers;
5525 MockTransaction transaction(kRangeGET_TransactionOK);
5526 transaction.request_headers = EXTRA_HEADER;
5527 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5528 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5530 scoped_ptr<Context> c(new Context);
5531 int rv = cache.CreateTransaction(&c->trans);
5532 ASSERT_EQ(net::OK, rv);
5534 MockHttpRequest request(transaction);
5535 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5536 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5538 // We should have checked with the server before finishing Start().
5539 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5540 EXPECT_EQ(1, cache.disk_cache()->open_count());
5541 EXPECT_EQ(1, cache.disk_cache()->create_count());
5543 RemoveMockTransaction(&kRangeGET_TransactionOK);
5546 // Tests that we handle 401s for truncated resources.
5547 TEST(HttpCache, GET_IncompleteResourceWithAuth) {
5548 MockHttpCache cache;
5549 AddMockTransaction(&kRangeGET_TransactionOK);
5551 std::string raw_headers("HTTP/1.1 200 OK\n"
5552 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5553 "ETag: \"foo\"\n"
5554 "Accept-Ranges: bytes\n"
5555 "Content-Length: 80\n");
5556 CreateTruncatedEntry(raw_headers, &cache);
5558 // Now make a regular request.
5559 MockTransaction transaction(kRangeGET_TransactionOK);
5560 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
5561 EXTRA_HEADER;
5562 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5563 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5564 RangeTransactionServer handler;
5566 scoped_ptr<Context> c(new Context);
5567 int rv = cache.CreateTransaction(&c->trans);
5568 ASSERT_EQ(net::OK, rv);
5570 MockHttpRequest request(transaction);
5571 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5572 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5574 const net::HttpResponseInfo* response = c->trans->GetResponseInfo();
5575 ASSERT_TRUE(response);
5576 ASSERT_EQ(401, response->headers->response_code());
5577 rv = c->trans->RestartWithAuth(net::AuthCredentials(),
5578 c->callback.callback());
5579 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5580 response = c->trans->GetResponseInfo();
5581 ASSERT_TRUE(response);
5582 ASSERT_EQ(200, response->headers->response_code());
5584 ReadAndVerifyTransaction(c->trans.get(), transaction);
5585 c.reset(); // The destructor could delete the entry.
5586 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5588 // Verify that the entry was not deleted.
5589 disk_cache::Entry* entry;
5590 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5591 entry->Close();
5593 RemoveMockTransaction(&kRangeGET_TransactionOK);
5596 // Tests that we cache a 200 response to the validation request.
5597 TEST(HttpCache, GET_IncompleteResource4) {
5598 MockHttpCache cache;
5599 AddMockTransaction(&kRangeGET_TransactionOK);
5601 std::string raw_headers("HTTP/1.1 200 OK\n"
5602 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5603 "ETag: \"foo\"\n"
5604 "Accept-Ranges: bytes\n"
5605 "Content-Length: 80\n");
5606 CreateTruncatedEntry(raw_headers, &cache);
5608 // Now make a regular request.
5609 std::string headers;
5610 MockTransaction transaction(kRangeGET_TransactionOK);
5611 transaction.request_headers = EXTRA_HEADER;
5612 transaction.data = "Not a range";
5613 RangeTransactionServer handler;
5614 handler.set_bad_200(true);
5615 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5617 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5618 EXPECT_EQ(1, cache.disk_cache()->open_count());
5619 EXPECT_EQ(1, cache.disk_cache()->create_count());
5621 // Verify that the disk entry was updated.
5622 disk_cache::Entry* entry;
5623 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5624 EXPECT_EQ(11, entry->GetDataSize(1));
5625 bool truncated = true;
5626 net::HttpResponseInfo response;
5627 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5628 EXPECT_FALSE(truncated);
5629 entry->Close();
5631 RemoveMockTransaction(&kRangeGET_TransactionOK);
5634 // Tests that when we cancel a request that was interrupted, we mark it again
5635 // as truncated.
5636 TEST(HttpCache, GET_CancelIncompleteResource) {
5637 MockHttpCache cache;
5638 AddMockTransaction(&kRangeGET_TransactionOK);
5640 std::string raw_headers("HTTP/1.1 200 OK\n"
5641 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5642 "ETag: \"foo\"\n"
5643 "Accept-Ranges: bytes\n"
5644 "Content-Length: 80\n");
5645 CreateTruncatedEntry(raw_headers, &cache);
5647 // Now make a regular request.
5648 MockTransaction transaction(kRangeGET_TransactionOK);
5649 transaction.request_headers = EXTRA_HEADER;
5651 MockHttpRequest request(transaction);
5652 Context* c = new Context();
5653 int rv = cache.CreateTransaction(&c->trans);
5654 ASSERT_EQ(net::OK, rv);
5656 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5657 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5659 // Read 20 bytes from the cache, and 10 from the net.
5660 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5661 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5662 EXPECT_EQ(20, c->callback.GetResult(rv));
5663 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5664 EXPECT_EQ(10, c->callback.GetResult(rv));
5666 // At this point, we are already reading so canceling the request should leave
5667 // a truncated one.
5668 delete c;
5670 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5671 EXPECT_EQ(1, cache.disk_cache()->open_count());
5672 EXPECT_EQ(1, cache.disk_cache()->create_count());
5674 // Verify that the disk entry was updated: now we have 30 bytes.
5675 disk_cache::Entry* entry;
5676 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5677 EXPECT_EQ(30, entry->GetDataSize(1));
5678 bool truncated = false;
5679 net::HttpResponseInfo response;
5680 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5681 EXPECT_TRUE(truncated);
5682 entry->Close();
5683 RemoveMockTransaction(&kRangeGET_TransactionOK);
5686 // Tests that we can handle range requests when we have a truncated entry.
5687 TEST(HttpCache, RangeGET_IncompleteResource) {
5688 MockHttpCache cache;
5689 AddMockTransaction(&kRangeGET_TransactionOK);
5691 // Content-length will be intentionally bogus.
5692 std::string raw_headers("HTTP/1.1 200 OK\n"
5693 "Last-Modified: something\n"
5694 "ETag: \"foo\"\n"
5695 "Accept-Ranges: bytes\n"
5696 "Content-Length: 10\n");
5697 CreateTruncatedEntry(raw_headers, &cache);
5699 // Now make a range request.
5700 std::string headers;
5701 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5702 &headers);
5704 Verify206Response(headers, 40, 49);
5705 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5706 EXPECT_EQ(1, cache.disk_cache()->open_count());
5707 EXPECT_EQ(2, cache.disk_cache()->create_count());
5709 RemoveMockTransaction(&kRangeGET_TransactionOK);
5712 TEST(HttpCache, SyncRead) {
5713 MockHttpCache cache;
5715 // This test ensures that a read that completes synchronously does not cause
5716 // any problems.
5718 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5719 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5720 TEST_MODE_SYNC_CACHE_READ |
5721 TEST_MODE_SYNC_CACHE_WRITE);
5723 MockHttpRequest r1(transaction),
5724 r2(transaction),
5725 r3(transaction);
5727 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5728 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5729 c3(net::DEFAULT_PRIORITY, cache.http_cache());
5731 c1.Start(&r1, net::BoundNetLog());
5733 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5734 c2.Start(&r2, net::BoundNetLog());
5736 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5737 c3.Start(&r3, net::BoundNetLog());
5739 base::MessageLoop::current()->Run();
5741 EXPECT_TRUE(c1.is_done());
5742 EXPECT_TRUE(c2.is_done());
5743 EXPECT_TRUE(c3.is_done());
5745 EXPECT_EQ(net::OK, c1.error());
5746 EXPECT_EQ(net::OK, c2.error());
5747 EXPECT_EQ(net::OK, c3.error());
5750 TEST(HttpCache, ValidationResultsIn200) {
5751 MockHttpCache cache;
5753 // This test ensures that a conditional request, which results in a 200
5754 // instead of a 304, properly truncates the existing response data.
5756 // write to the cache
5757 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5759 // force this transaction to validate the cache
5760 MockTransaction transaction(kETagGET_Transaction);
5761 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5762 RunTransactionTest(cache.http_cache(), transaction);
5764 // read from the cache
5765 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5768 TEST(HttpCache, CachedRedirect) {
5769 MockHttpCache cache;
5771 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5772 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5773 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5775 MockHttpRequest request(kTestTransaction);
5776 net::TestCompletionCallback callback;
5778 // Write to the cache.
5780 scoped_ptr<net::HttpTransaction> trans;
5781 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5783 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5784 if (rv == net::ERR_IO_PENDING)
5785 rv = callback.WaitForResult();
5786 ASSERT_EQ(net::OK, rv);
5788 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5789 ASSERT_TRUE(info);
5791 EXPECT_EQ(info->headers->response_code(), 301);
5793 std::string location;
5794 info->headers->EnumerateHeader(NULL, "Location", &location);
5795 EXPECT_EQ(location, "http://www.bar.com/");
5797 // Mark the transaction as completed so it is cached.
5798 trans->DoneReading();
5800 // Destroy transaction when going out of scope. We have not actually
5801 // read the response body -- want to test that it is still getting cached.
5803 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5804 EXPECT_EQ(0, cache.disk_cache()->open_count());
5805 EXPECT_EQ(1, cache.disk_cache()->create_count());
5807 // Active entries in the cache are not retired synchronously. Make
5808 // sure the next run hits the MockHttpCache and open_count is
5809 // correct.
5810 base::MessageLoop::current()->RunUntilIdle();
5812 // Read from the cache.
5814 scoped_ptr<net::HttpTransaction> trans;
5815 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5817 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5818 if (rv == net::ERR_IO_PENDING)
5819 rv = callback.WaitForResult();
5820 ASSERT_EQ(net::OK, rv);
5822 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5823 ASSERT_TRUE(info);
5825 EXPECT_EQ(info->headers->response_code(), 301);
5827 std::string location;
5828 info->headers->EnumerateHeader(NULL, "Location", &location);
5829 EXPECT_EQ(location, "http://www.bar.com/");
5831 // Mark the transaction as completed so it is cached.
5832 trans->DoneReading();
5834 // Destroy transaction when going out of scope. We have not actually
5835 // read the response body -- want to test that it is still getting cached.
5837 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5838 EXPECT_EQ(1, cache.disk_cache()->open_count());
5839 EXPECT_EQ(1, cache.disk_cache()->create_count());
5842 // Verify that no-cache resources are stored in cache, but are not fetched from
5843 // cache during normal loads.
5844 TEST(HttpCache, CacheControlNoCacheNormalLoad) {
5845 MockHttpCache cache;
5847 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5848 transaction.response_headers = "cache-control: no-cache\n";
5850 // Initial load.
5851 RunTransactionTest(cache.http_cache(), transaction);
5853 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5854 EXPECT_EQ(0, cache.disk_cache()->open_count());
5855 EXPECT_EQ(1, cache.disk_cache()->create_count());
5857 // Try loading again; it should result in a network fetch.
5858 RunTransactionTest(cache.http_cache(), transaction);
5860 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5861 EXPECT_EQ(1, cache.disk_cache()->open_count());
5862 EXPECT_EQ(1, cache.disk_cache()->create_count());
5864 disk_cache::Entry* entry;
5865 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5866 entry->Close();
5869 // Verify that no-cache resources are stored in cache and fetched from cache
5870 // when the LOAD_PREFERRING_CACHE flag is set.
5871 TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
5872 MockHttpCache cache;
5874 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5875 transaction.response_headers = "cache-control: no-cache\n";
5877 // Initial load.
5878 RunTransactionTest(cache.http_cache(), transaction);
5880 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5881 EXPECT_EQ(0, cache.disk_cache()->open_count());
5882 EXPECT_EQ(1, cache.disk_cache()->create_count());
5884 // Try loading again with LOAD_PREFERRING_CACHE.
5885 transaction.load_flags = net::LOAD_PREFERRING_CACHE;
5886 RunTransactionTest(cache.http_cache(), transaction);
5888 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5889 EXPECT_EQ(1, cache.disk_cache()->open_count());
5890 EXPECT_EQ(1, cache.disk_cache()->create_count());
5892 disk_cache::Entry* entry;
5893 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5894 entry->Close();
5897 TEST(HttpCache, CacheControlNoStore) {
5898 MockHttpCache cache;
5900 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5901 transaction.response_headers = "cache-control: no-store\n";
5903 // initial load
5904 RunTransactionTest(cache.http_cache(), transaction);
5906 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5907 EXPECT_EQ(0, cache.disk_cache()->open_count());
5908 EXPECT_EQ(1, cache.disk_cache()->create_count());
5910 // try loading again; it should result in a network fetch
5911 RunTransactionTest(cache.http_cache(), transaction);
5913 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5914 EXPECT_EQ(0, cache.disk_cache()->open_count());
5915 EXPECT_EQ(2, cache.disk_cache()->create_count());
5917 disk_cache::Entry* entry;
5918 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5921 TEST(HttpCache, CacheControlNoStore2) {
5922 // this test is similar to the above test, except that the initial response
5923 // is cachable, but when it is validated, no-store is received causing the
5924 // cached document to be deleted.
5925 MockHttpCache cache;
5927 ScopedMockTransaction transaction(kETagGET_Transaction);
5929 // initial load
5930 RunTransactionTest(cache.http_cache(), transaction);
5932 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5933 EXPECT_EQ(0, cache.disk_cache()->open_count());
5934 EXPECT_EQ(1, cache.disk_cache()->create_count());
5936 // try loading again; it should result in a network fetch
5937 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5938 transaction.response_headers = "cache-control: no-store\n";
5939 RunTransactionTest(cache.http_cache(), transaction);
5941 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5942 EXPECT_EQ(1, cache.disk_cache()->open_count());
5943 EXPECT_EQ(1, cache.disk_cache()->create_count());
5945 disk_cache::Entry* entry;
5946 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5949 TEST(HttpCache, CacheControlNoStore3) {
5950 // this test is similar to the above test, except that the response is a 304
5951 // instead of a 200. this should never happen in practice, but it seems like
5952 // a good thing to verify that we still destroy the cache entry.
5953 MockHttpCache cache;
5955 ScopedMockTransaction transaction(kETagGET_Transaction);
5957 // initial load
5958 RunTransactionTest(cache.http_cache(), transaction);
5960 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5961 EXPECT_EQ(0, cache.disk_cache()->open_count());
5962 EXPECT_EQ(1, cache.disk_cache()->create_count());
5964 // try loading again; it should result in a network fetch
5965 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5966 transaction.response_headers = "cache-control: no-store\n";
5967 transaction.status = "HTTP/1.1 304 Not Modified";
5968 RunTransactionTest(cache.http_cache(), transaction);
5970 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5971 EXPECT_EQ(1, cache.disk_cache()->open_count());
5972 EXPECT_EQ(1, cache.disk_cache()->create_count());
5974 disk_cache::Entry* entry;
5975 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5978 // Ensure that we don't cache requests served over bad HTTPS.
5979 TEST(HttpCache, SimpleGET_SSLError) {
5980 MockHttpCache cache;
5982 MockTransaction transaction = kSimpleGET_Transaction;
5983 transaction.cert_status = net::CERT_STATUS_REVOKED;
5984 ScopedMockTransaction scoped_transaction(transaction);
5986 // write to the cache
5987 RunTransactionTest(cache.http_cache(), transaction);
5989 // Test that it was not cached.
5990 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5992 MockHttpRequest request(transaction);
5993 net::TestCompletionCallback callback;
5995 scoped_ptr<net::HttpTransaction> trans;
5996 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5998 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5999 if (rv == net::ERR_IO_PENDING)
6000 rv = callback.WaitForResult();
6001 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
6004 // Ensure that we don't crash by if left-behind transactions.
6005 TEST(HttpCache, OutlivedTransactions) {
6006 MockHttpCache* cache = new MockHttpCache;
6008 scoped_ptr<net::HttpTransaction> trans;
6009 EXPECT_EQ(net::OK, cache->CreateTransaction(&trans));
6011 delete cache;
6012 trans.reset();
6015 // Test that the disabled mode works.
6016 TEST(HttpCache, CacheDisabledMode) {
6017 MockHttpCache cache;
6019 // write to the cache
6020 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6022 // go into disabled mode
6023 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
6025 // force this transaction to write to the cache again
6026 MockTransaction transaction(kSimpleGET_Transaction);
6028 RunTransactionTest(cache.http_cache(), transaction);
6030 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6031 EXPECT_EQ(0, cache.disk_cache()->open_count());
6032 EXPECT_EQ(1, cache.disk_cache()->create_count());
6035 // Other tests check that the response headers of the cached response
6036 // get updated on 304. Here we specifically check that the
6037 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6038 // fields also gets updated.
6039 // http://crbug.com/20594.
6040 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
6041 MockHttpCache cache;
6043 const char* kUrl = "http://foobar";
6044 const char* kData = "body";
6046 MockTransaction mock_network_response = { 0 };
6047 mock_network_response.url = kUrl;
6049 AddMockTransaction(&mock_network_response);
6051 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6053 MockTransaction request = { 0 };
6054 request.url = kUrl;
6055 request.method = "GET";
6056 request.request_headers = "\r\n";
6057 request.data = kData;
6059 static const Response kNetResponse1 = {
6060 "HTTP/1.1 200 OK",
6061 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6062 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6063 kData
6066 kNetResponse1.AssignTo(&mock_network_response);
6068 RunTransactionTest(cache.http_cache(), request);
6070 // Request |kUrl| again, this time validating the cache and getting
6071 // a 304 back.
6073 request.load_flags = net::LOAD_VALIDATE_CACHE;
6075 static const Response kNetResponse2 = {
6076 "HTTP/1.1 304 Not Modified",
6077 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6081 kNetResponse2.AssignTo(&mock_network_response);
6083 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6084 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6086 mock_network_response.request_time = request_time;
6087 mock_network_response.response_time = response_time;
6089 net::HttpResponseInfo response;
6090 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6092 // The request and response times should have been updated.
6093 EXPECT_EQ(request_time.ToInternalValue(),
6094 response.request_time.ToInternalValue());
6095 EXPECT_EQ(response_time.ToInternalValue(),
6096 response.response_time.ToInternalValue());
6098 std::string headers;
6099 response.headers->GetNormalizedHeaders(&headers);
6101 EXPECT_EQ("HTTP/1.1 200 OK\n"
6102 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6103 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6104 headers);
6106 RemoveMockTransaction(&mock_network_response);
6109 // Tests that we can write metadata to an entry.
6110 TEST(HttpCache, WriteMetadata_OK) {
6111 MockHttpCache cache;
6113 // Write to the cache
6114 net::HttpResponseInfo response;
6115 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6116 &response);
6117 EXPECT_TRUE(response.metadata.get() == NULL);
6119 // Trivial call.
6120 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
6121 Time::Now(), NULL, 0);
6123 // Write meta data to the same entry.
6124 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6125 memset(buf->data(), 0, buf->size());
6126 base::strlcpy(buf->data(), "Hi there", buf->size());
6127 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6128 net::DEFAULT_PRIORITY,
6129 response.response_time,
6130 buf.get(),
6131 buf->size());
6133 // Release the buffer before the operation takes place.
6134 buf = NULL;
6136 // Makes sure we finish pending operations.
6137 base::MessageLoop::current()->RunUntilIdle();
6139 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6140 &response);
6141 ASSERT_TRUE(response.metadata.get() != NULL);
6142 EXPECT_EQ(50, response.metadata->size());
6143 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6145 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6146 EXPECT_EQ(2, cache.disk_cache()->open_count());
6147 EXPECT_EQ(1, cache.disk_cache()->create_count());
6150 // Tests that we only write metadata to an entry if the time stamp matches.
6151 TEST(HttpCache, WriteMetadata_Fail) {
6152 MockHttpCache cache;
6154 // Write to the cache
6155 net::HttpResponseInfo response;
6156 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6157 &response);
6158 EXPECT_TRUE(response.metadata.get() == NULL);
6160 // Attempt to write meta data to the same entry.
6161 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6162 memset(buf->data(), 0, buf->size());
6163 base::strlcpy(buf->data(), "Hi there", buf->size());
6164 base::Time expected_time = response.response_time -
6165 base::TimeDelta::FromMilliseconds(20);
6166 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6167 net::DEFAULT_PRIORITY,
6168 expected_time,
6169 buf.get(),
6170 buf->size());
6172 // Makes sure we finish pending operations.
6173 base::MessageLoop::current()->RunUntilIdle();
6175 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6176 &response);
6177 EXPECT_TRUE(response.metadata.get() == NULL);
6179 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6180 EXPECT_EQ(2, cache.disk_cache()->open_count());
6181 EXPECT_EQ(1, cache.disk_cache()->create_count());
6184 // Tests that we can read metadata after validating the entry and with READ mode
6185 // transactions.
6186 TEST(HttpCache, ReadMetadata) {
6187 MockHttpCache cache;
6189 // Write to the cache
6190 net::HttpResponseInfo response;
6191 RunTransactionTestWithResponseInfo(cache.http_cache(),
6192 kTypicalGET_Transaction, &response);
6193 EXPECT_TRUE(response.metadata.get() == NULL);
6195 // Write meta data to the same entry.
6196 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6197 memset(buf->data(), 0, buf->size());
6198 base::strlcpy(buf->data(), "Hi there", buf->size());
6199 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6200 net::DEFAULT_PRIORITY,
6201 response.response_time,
6202 buf.get(),
6203 buf->size());
6205 // Makes sure we finish pending operations.
6206 base::MessageLoop::current()->RunUntilIdle();
6208 // Start with a READ mode transaction.
6209 MockTransaction trans1(kTypicalGET_Transaction);
6210 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
6212 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6213 ASSERT_TRUE(response.metadata.get() != NULL);
6214 EXPECT_EQ(50, response.metadata->size());
6215 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6217 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6218 EXPECT_EQ(2, cache.disk_cache()->open_count());
6219 EXPECT_EQ(1, cache.disk_cache()->create_count());
6220 base::MessageLoop::current()->RunUntilIdle();
6222 // Now make sure that the entry is re-validated with the server.
6223 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
6224 trans1.status = "HTTP/1.1 304 Not Modified";
6225 AddMockTransaction(&trans1);
6227 response.metadata = NULL;
6228 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6229 EXPECT_TRUE(response.metadata.get() != NULL);
6231 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6232 EXPECT_EQ(3, cache.disk_cache()->open_count());
6233 EXPECT_EQ(1, cache.disk_cache()->create_count());
6234 base::MessageLoop::current()->RunUntilIdle();
6235 RemoveMockTransaction(&trans1);
6237 // Now return 200 when validating the entry so the metadata will be lost.
6238 MockTransaction trans2(kTypicalGET_Transaction);
6239 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
6240 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6241 EXPECT_TRUE(response.metadata.get() == NULL);
6243 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6244 EXPECT_EQ(4, cache.disk_cache()->open_count());
6245 EXPECT_EQ(1, cache.disk_cache()->create_count());
6248 // Tests that we don't mark entries as truncated when a filter detects the end
6249 // of the stream.
6250 TEST(HttpCache, FilterCompletion) {
6251 MockHttpCache cache;
6252 net::TestCompletionCallback callback;
6255 scoped_ptr<net::HttpTransaction> trans;
6256 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6258 MockHttpRequest request(kSimpleGET_Transaction);
6259 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6260 EXPECT_EQ(net::OK, callback.GetResult(rv));
6262 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6263 rv = trans->Read(buf.get(), 256, callback.callback());
6264 EXPECT_GT(callback.GetResult(rv), 0);
6266 // Now make sure that the entry is preserved.
6267 trans->DoneReading();
6270 // Make sure that the ActiveEntry is gone.
6271 base::MessageLoop::current()->RunUntilIdle();
6273 // Read from the cache.
6274 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6276 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6277 EXPECT_EQ(1, cache.disk_cache()->open_count());
6278 EXPECT_EQ(1, cache.disk_cache()->create_count());
6281 // Tests that we don't mark entries as truncated and release the cache
6282 // entry when DoneReading() is called before any Read() calls, such as
6283 // for a redirect.
6284 TEST(HttpCache, DoneReading) {
6285 MockHttpCache cache;
6286 net::TestCompletionCallback callback;
6288 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6289 transaction.data = "";
6291 scoped_ptr<net::HttpTransaction> trans;
6292 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6294 MockHttpRequest request(transaction);
6295 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6296 EXPECT_EQ(net::OK, callback.GetResult(rv));
6298 trans->DoneReading();
6299 // Leave the transaction around.
6301 // Make sure that the ActiveEntry is gone.
6302 base::MessageLoop::current()->RunUntilIdle();
6304 // Read from the cache. This should not deadlock.
6305 RunTransactionTest(cache.http_cache(), transaction);
6307 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6308 EXPECT_EQ(1, cache.disk_cache()->open_count());
6309 EXPECT_EQ(1, cache.disk_cache()->create_count());
6312 // Tests that we stop caching when told.
6313 TEST(HttpCache, StopCachingDeletesEntry) {
6314 MockHttpCache cache;
6315 net::TestCompletionCallback callback;
6316 MockHttpRequest request(kSimpleGET_Transaction);
6319 scoped_ptr<net::HttpTransaction> trans;
6320 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6322 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6323 EXPECT_EQ(net::OK, callback.GetResult(rv));
6325 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6326 rv = trans->Read(buf.get(), 10, callback.callback());
6327 EXPECT_EQ(10, callback.GetResult(rv));
6329 trans->StopCaching();
6331 // We should be able to keep reading.
6332 rv = trans->Read(buf.get(), 256, callback.callback());
6333 EXPECT_GT(callback.GetResult(rv), 0);
6334 rv = trans->Read(buf.get(), 256, callback.callback());
6335 EXPECT_EQ(0, callback.GetResult(rv));
6338 // Make sure that the ActiveEntry is gone.
6339 base::MessageLoop::current()->RunUntilIdle();
6341 // Verify that the entry is gone.
6342 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6344 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6345 EXPECT_EQ(0, cache.disk_cache()->open_count());
6346 EXPECT_EQ(2, cache.disk_cache()->create_count());
6349 // Tests that we stop caching when told, even if DoneReading is called
6350 // after StopCaching.
6351 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6352 MockHttpCache cache;
6353 net::TestCompletionCallback callback;
6354 MockHttpRequest request(kSimpleGET_Transaction);
6357 scoped_ptr<net::HttpTransaction> trans;
6358 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6360 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6361 EXPECT_EQ(net::OK, callback.GetResult(rv));
6363 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6364 rv = trans->Read(buf.get(), 10, callback.callback());
6365 EXPECT_EQ(10, callback.GetResult(rv));
6367 trans->StopCaching();
6369 // We should be able to keep reading.
6370 rv = trans->Read(buf.get(), 256, callback.callback());
6371 EXPECT_GT(callback.GetResult(rv), 0);
6372 rv = trans->Read(buf.get(), 256, callback.callback());
6373 EXPECT_EQ(0, callback.GetResult(rv));
6375 // We should be able to call DoneReading.
6376 trans->DoneReading();
6379 // Make sure that the ActiveEntry is gone.
6380 base::MessageLoop::current()->RunUntilIdle();
6382 // Verify that the entry is gone.
6383 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6385 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6386 EXPECT_EQ(0, cache.disk_cache()->open_count());
6387 EXPECT_EQ(2, cache.disk_cache()->create_count());
6390 // Tests that we stop caching when told, when using auth.
6391 TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6392 MockHttpCache cache;
6393 net::TestCompletionCallback callback;
6394 MockTransaction mock_transaction(kSimpleGET_Transaction);
6395 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6396 AddMockTransaction(&mock_transaction);
6397 MockHttpRequest request(mock_transaction);
6400 scoped_ptr<net::HttpTransaction> trans;
6401 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6403 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6404 EXPECT_EQ(net::OK, callback.GetResult(rv));
6406 trans->StopCaching();
6408 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6409 rv = trans->Read(buf.get(), 10, callback.callback());
6410 EXPECT_EQ(callback.GetResult(rv), 10);
6412 RemoveMockTransaction(&mock_transaction);
6414 // Make sure that the ActiveEntry is gone.
6415 base::MessageLoop::current()->RunUntilIdle();
6417 // Verify that the entry is gone.
6418 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6420 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6421 EXPECT_EQ(0, cache.disk_cache()->open_count());
6422 EXPECT_EQ(2, cache.disk_cache()->create_count());
6425 // Tests that when we are told to stop caching we don't throw away valid data.
6426 TEST(HttpCache, StopCachingSavesEntry) {
6427 MockHttpCache cache;
6428 net::TestCompletionCallback callback;
6429 MockHttpRequest request(kSimpleGET_Transaction);
6432 scoped_ptr<net::HttpTransaction> trans;
6433 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6435 // Force a response that can be resumed.
6436 MockTransaction mock_transaction(kSimpleGET_Transaction);
6437 AddMockTransaction(&mock_transaction);
6438 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6439 "Content-Length: 42\n"
6440 "Etag: \"foo\"\n";
6442 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6443 EXPECT_EQ(net::OK, callback.GetResult(rv));
6445 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6446 rv = trans->Read(buf.get(), 10, callback.callback());
6447 EXPECT_EQ(callback.GetResult(rv), 10);
6449 trans->StopCaching();
6451 // We should be able to keep reading.
6452 rv = trans->Read(buf.get(), 256, callback.callback());
6453 EXPECT_GT(callback.GetResult(rv), 0);
6454 rv = trans->Read(buf.get(), 256, callback.callback());
6455 EXPECT_EQ(callback.GetResult(rv), 0);
6457 RemoveMockTransaction(&mock_transaction);
6460 // Verify that the entry is marked as incomplete.
6461 disk_cache::Entry* entry;
6462 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6463 net::HttpResponseInfo response;
6464 bool truncated = false;
6465 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6466 EXPECT_TRUE(truncated);
6467 entry->Close();
6470 // Tests that we handle truncated enries when StopCaching is called.
6471 TEST(HttpCache, StopCachingTruncatedEntry) {
6472 MockHttpCache cache;
6473 net::TestCompletionCallback callback;
6474 MockHttpRequest request(kRangeGET_TransactionOK);
6475 request.extra_headers.Clear();
6476 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6477 AddMockTransaction(&kRangeGET_TransactionOK);
6479 std::string raw_headers("HTTP/1.1 200 OK\n"
6480 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6481 "ETag: \"foo\"\n"
6482 "Accept-Ranges: bytes\n"
6483 "Content-Length: 80\n");
6484 CreateTruncatedEntry(raw_headers, &cache);
6487 // Now make a regular request.
6488 scoped_ptr<net::HttpTransaction> trans;
6489 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6491 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6492 EXPECT_EQ(net::OK, callback.GetResult(rv));
6494 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6495 rv = trans->Read(buf.get(), 10, callback.callback());
6496 EXPECT_EQ(callback.GetResult(rv), 10);
6498 // This is actually going to do nothing.
6499 trans->StopCaching();
6501 // We should be able to keep reading.
6502 rv = trans->Read(buf.get(), 256, callback.callback());
6503 EXPECT_GT(callback.GetResult(rv), 0);
6504 rv = trans->Read(buf.get(), 256, callback.callback());
6505 EXPECT_GT(callback.GetResult(rv), 0);
6506 rv = trans->Read(buf.get(), 256, callback.callback());
6507 EXPECT_EQ(callback.GetResult(rv), 0);
6510 // Verify that the disk entry was updated.
6511 disk_cache::Entry* entry;
6512 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6513 EXPECT_EQ(80, entry->GetDataSize(1));
6514 bool truncated = true;
6515 net::HttpResponseInfo response;
6516 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6517 EXPECT_FALSE(truncated);
6518 entry->Close();
6520 RemoveMockTransaction(&kRangeGET_TransactionOK);
6523 // Tests that we detect truncated resources from the net when there is
6524 // a Content-Length header.
6525 TEST(HttpCache, TruncatedByContentLength) {
6526 MockHttpCache cache;
6527 net::TestCompletionCallback callback;
6529 MockTransaction transaction(kSimpleGET_Transaction);
6530 AddMockTransaction(&transaction);
6531 transaction.response_headers = "Cache-Control: max-age=10000\n"
6532 "Content-Length: 100\n";
6533 RunTransactionTest(cache.http_cache(), transaction);
6534 RemoveMockTransaction(&transaction);
6536 // Read from the cache.
6537 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6539 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6540 EXPECT_EQ(0, cache.disk_cache()->open_count());
6541 EXPECT_EQ(2, cache.disk_cache()->create_count());
6544 // Tests that we actually flag entries as truncated when we detect an error
6545 // from the net.
6546 TEST(HttpCache, TruncatedByContentLength2) {
6547 MockHttpCache cache;
6548 net::TestCompletionCallback callback;
6550 MockTransaction transaction(kSimpleGET_Transaction);
6551 AddMockTransaction(&transaction);
6552 transaction.response_headers = "Cache-Control: max-age=10000\n"
6553 "Content-Length: 100\n"
6554 "Etag: \"foo\"\n";
6555 RunTransactionTest(cache.http_cache(), transaction);
6556 RemoveMockTransaction(&transaction);
6558 // Verify that the entry is marked as incomplete.
6559 disk_cache::Entry* entry;
6560 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6561 net::HttpResponseInfo response;
6562 bool truncated = false;
6563 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6564 EXPECT_TRUE(truncated);
6565 entry->Close();
6568 // Make sure that calling SetPriority on a cache transaction passes on
6569 // its priority updates to its underlying network transaction.
6570 TEST(HttpCache, SetPriority) {
6571 MockHttpCache cache;
6573 scoped_ptr<net::HttpTransaction> trans;
6574 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6576 // Shouldn't crash, but doesn't do anything either.
6577 trans->SetPriority(net::LOW);
6579 EXPECT_FALSE(cache.network_layer()->last_transaction());
6580 EXPECT_EQ(net::DEFAULT_PRIORITY,
6581 cache.network_layer()->last_create_transaction_priority());
6583 net::HttpRequestInfo info;
6584 info.url = GURL(kSimpleGET_Transaction.url);
6585 net::TestCompletionCallback callback;
6586 EXPECT_EQ(net::ERR_IO_PENDING,
6587 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6589 EXPECT_TRUE(cache.network_layer()->last_transaction());
6590 if (cache.network_layer()->last_transaction()) {
6591 EXPECT_EQ(net::LOW,
6592 cache.network_layer()->last_create_transaction_priority());
6593 EXPECT_EQ(net::LOW,
6594 cache.network_layer()->last_transaction()->priority());
6597 trans->SetPriority(net::HIGHEST);
6599 if (cache.network_layer()->last_transaction()) {
6600 EXPECT_EQ(net::LOW,
6601 cache.network_layer()->last_create_transaction_priority());
6602 EXPECT_EQ(net::HIGHEST,
6603 cache.network_layer()->last_transaction()->priority());
6606 EXPECT_EQ(net::OK, callback.WaitForResult());
6609 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6610 // transaction passes on its argument to the underlying network transaction.
6611 TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
6612 MockHttpCache cache;
6614 FakeWebSocketHandshakeStreamCreateHelper create_helper;
6615 scoped_ptr<net::HttpTransaction> trans;
6616 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6618 EXPECT_FALSE(cache.network_layer()->last_transaction());
6620 net::HttpRequestInfo info;
6621 info.url = GURL(kSimpleGET_Transaction.url);
6622 net::TestCompletionCallback callback;
6623 EXPECT_EQ(net::ERR_IO_PENDING,
6624 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6626 ASSERT_TRUE(cache.network_layer()->last_transaction());
6627 EXPECT_FALSE(cache.network_layer()->last_transaction()->
6628 websocket_handshake_stream_create_helper());
6629 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
6630 EXPECT_EQ(&create_helper,
6631 cache.network_layer()->last_transaction()->
6632 websocket_handshake_stream_create_helper());
6633 EXPECT_EQ(net::OK, callback.WaitForResult());
6636 // Make sure that a cache transaction passes on its priority to
6637 // newly-created network transactions.
6638 TEST(HttpCache, SetPriorityNewTransaction) {
6639 MockHttpCache cache;
6640 AddMockTransaction(&kRangeGET_TransactionOK);
6642 std::string raw_headers("HTTP/1.1 200 OK\n"
6643 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6644 "ETag: \"foo\"\n"
6645 "Accept-Ranges: bytes\n"
6646 "Content-Length: 80\n");
6647 CreateTruncatedEntry(raw_headers, &cache);
6649 // Now make a regular request.
6650 std::string headers;
6651 MockTransaction transaction(kRangeGET_TransactionOK);
6652 transaction.request_headers = EXTRA_HEADER;
6653 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6654 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6656 scoped_ptr<net::HttpTransaction> trans;
6657 ASSERT_EQ(net::OK,
6658 cache.http_cache()->CreateTransaction(net::MEDIUM, &trans));
6659 EXPECT_EQ(net::DEFAULT_PRIORITY,
6660 cache.network_layer()->last_create_transaction_priority());
6662 MockHttpRequest info(transaction);
6663 net::TestCompletionCallback callback;
6664 EXPECT_EQ(net::ERR_IO_PENDING,
6665 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6666 EXPECT_EQ(net::OK, callback.WaitForResult());
6668 EXPECT_EQ(net::MEDIUM,
6669 cache.network_layer()->last_create_transaction_priority());
6671 trans->SetPriority(net::HIGHEST);
6672 // Should trigger a new network transaction and pick up the new
6673 // priority.
6674 ReadAndVerifyTransaction(trans.get(), transaction);
6676 EXPECT_EQ(net::HIGHEST,
6677 cache.network_layer()->last_create_transaction_priority());
6679 RemoveMockTransaction(&kRangeGET_TransactionOK);
6682 int64 RunTransactionAndGetReceivedBytes(
6683 MockHttpCache& cache,
6684 const MockTransaction& trans_info) {
6685 int64 received_bytes = -1;
6686 RunTransactionTestBase(cache.http_cache(), trans_info,
6687 MockHttpRequest(trans_info), NULL, net::BoundNetLog(),
6688 NULL, &received_bytes);
6689 return received_bytes;
6692 int64 TransactionSize(const MockTransaction& transaction) {
6693 return strlen(transaction.status) + strlen(transaction.response_headers) +
6694 strlen(transaction.data);
6697 TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
6698 MockHttpCache cache;
6700 MockTransaction transaction(kSimpleGET_Transaction);
6701 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6702 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6704 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6705 EXPECT_EQ(0, received_bytes);
6708 TEST(HttpCache, ReceivedBytesConditionalRequest304) {
6709 MockHttpCache cache;
6711 ScopedMockTransaction transaction(kETagGET_Transaction);
6712 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6713 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6715 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
6716 transaction.handler = ETagGet_ConditionalRequest_Handler;
6717 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6718 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6721 TEST(HttpCache, ReceivedBytesConditionalRequest200) {
6722 MockHttpCache cache;
6724 MockTransaction transaction(kTypicalGET_Transaction);
6725 transaction.request_headers = "Foo: bar\r\n";
6726 transaction.response_headers =
6727 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6728 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6729 "Etag: \"foopy\"\n"
6730 "Cache-Control: max-age=0\n"
6731 "Vary: Foo\n";
6732 AddMockTransaction(&transaction);
6733 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6734 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6736 RevalidationServer server;
6737 transaction.handler = server.Handler;
6738 transaction.request_headers = "Foo: none\r\n";
6739 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6740 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6742 RemoveMockTransaction(&transaction);
6745 TEST(HttpCache, ReceivedBytesRange) {
6746 MockHttpCache cache;
6747 AddMockTransaction(&kRangeGET_TransactionOK);
6748 MockTransaction transaction(kRangeGET_TransactionOK);
6750 // Read bytes 40-49 from the network.
6751 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6752 int64 range_response_size = TransactionSize(transaction);
6753 EXPECT_EQ(range_response_size, received_bytes);
6755 // Read bytes 40-49 from the cache.
6756 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6757 EXPECT_EQ(0, received_bytes);
6758 base::MessageLoop::current()->RunUntilIdle();
6760 // Read bytes 30-39 from the network.
6761 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
6762 transaction.data = "rg: 30-39 ";
6763 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6764 EXPECT_EQ(range_response_size, received_bytes);
6765 base::MessageLoop::current()->RunUntilIdle();
6767 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6768 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
6769 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6770 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6771 EXPECT_EQ(range_response_size * 2, received_bytes);
6773 RemoveMockTransaction(&kRangeGET_TransactionOK);
6776 // Framework for tests of stale-while-revalidate related functionality. With
6777 // the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
6778 // will trigger the stale-while-revalidate asynchronous revalidation. Setting
6779 // |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
6780 // synchronous revalidation.
6781 class HttpCacheStaleWhileRevalidateTest : public ::testing::Test {
6782 protected:
6783 HttpCacheStaleWhileRevalidateTest()
6784 : transaction_(kSimpleGET_Transaction),
6785 age_(3601),
6786 stale_while_revalidate_(7200),
6787 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
6788 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true);
6791 // RunTransactionTest() with the arguments from this fixture.
6792 void RunFixtureTransactionTest() {
6793 std::string response_headers = base::StringPrintf(
6794 "%s\n"
6795 "Age: %d\n"
6796 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
6797 validator_.c_str(),
6798 age_,
6799 stale_while_revalidate_);
6800 transaction_.response_headers = response_headers.c_str();
6801 RunTransactionTest(cache_.http_cache(), transaction_);
6802 transaction_.response_headers = "";
6805 // How many times this test has sent requests to the (fake) origin
6806 // server. Every test case needs to make at least one request to initialise
6807 // the cache.
6808 int transaction_count() {
6809 return cache_.network_layer()->transaction_count();
6812 // How many times an existing cache entry was opened during the test case.
6813 int open_count() { return cache_.disk_cache()->open_count(); }
6815 MockHttpCache cache_;
6816 ScopedMockTransaction transaction_;
6817 int age_;
6818 int stale_while_revalidate_;
6819 std::string validator_;
6822 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request,
6823 std::string* response_status,
6824 std::string* response_headers,
6825 std::string* response_data) {
6826 std::string value;
6827 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
6828 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
6831 // Verify that the Resource-Freshness header is sent on a revalidation if the
6832 // stale-while-revalidate directive was on the response.
6833 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) {
6834 age_ = 10801; // Outside the stale-while-revalidate window.
6836 // Write to the cache.
6837 RunFixtureTransactionTest();
6839 EXPECT_EQ(1, transaction_count());
6841 // Send the request again and check that Resource-Freshness header is added.
6842 transaction_.handler = CheckResourceFreshnessHeader;
6844 RunFixtureTransactionTest();
6846 EXPECT_EQ(2, transaction_count());
6849 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request,
6850 std::string* response_status,
6851 std::string* response_headers,
6852 std::string* response_data) {
6853 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
6856 // Verify that the Resource-Freshness header is not sent when
6857 // stale-while-revalidate is 0.
6858 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) {
6859 age_ = 10801;
6860 stale_while_revalidate_ = 0;
6862 // Write to the cache.
6863 RunFixtureTransactionTest();
6865 EXPECT_EQ(1, transaction_count());
6867 // Send the request again and check that Resource-Freshness header is absent.
6868 transaction_.handler = CheckResourceFreshnessAbsent;
6870 RunFixtureTransactionTest();
6872 EXPECT_EQ(2, transaction_count());
6875 // Verify that when stale-while-revalidate applies the response is read from
6876 // cache.
6877 TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) {
6878 // Write to the cache.
6879 RunFixtureTransactionTest();
6881 EXPECT_EQ(0, open_count());
6882 EXPECT_EQ(1, transaction_count());
6884 // Read back from the cache.
6885 RunFixtureTransactionTest();
6887 EXPECT_EQ(1, open_count());
6888 EXPECT_EQ(1, transaction_count());
6891 // Verify that when stale-while-revalidate applies an asynchronous request is
6892 // sent.
6893 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) {
6894 // Write to the cache.
6895 RunFixtureTransactionTest();
6897 EXPECT_EQ(1, transaction_count());
6899 // Read back from the cache.
6900 RunFixtureTransactionTest();
6902 EXPECT_EQ(1, transaction_count());
6904 // Let the async request execute.
6905 base::RunLoop().RunUntilIdle();
6906 EXPECT_EQ(2, transaction_count());
6909 // Verify that tearing down the HttpCache with an async revalidation in progress
6910 // does not break anything (this test is most likely to find problems when run
6911 // with a memory checker such as AddressSanitizer).
6912 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) {
6913 // Write to the cache.
6914 RunFixtureTransactionTest();
6916 // Read back from the cache.
6917 RunFixtureTransactionTest();
6920 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo* request,
6921 std::string* response_status,
6922 std::string* response_headers,
6923 std::string* response_data) {
6924 std::string value;
6925 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value));
6926 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value);
6929 // Verify that the async revalidation contains an If-Modified-Since header.
6930 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) {
6931 // Write to the cache.
6932 RunFixtureTransactionTest();
6934 transaction_.handler = CheckIfModifiedSinceHeader;
6936 // Read back from the cache.
6937 RunFixtureTransactionTest();
6940 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo* request,
6941 std::string* response_status,
6942 std::string* response_headers,
6943 std::string* response_data) {
6944 std::string value;
6945 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value));
6946 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value);
6949 // If the response had ETag rather than Last-Modified, then that is used to
6950 // conditionalise the response.
6951 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) {
6952 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\"";
6954 // Write to the cache.
6955 RunFixtureTransactionTest();
6957 transaction_.handler = CheckIfNoneMatchHeader;
6959 // Read back from the cache.
6960 RunFixtureTransactionTest();
6963 static void CheckResourceFreshnessHeaderPresent(
6964 const net::HttpRequestInfo* request,
6965 std::string* response_status,
6966 std::string* response_headers,
6967 std::string* response_data) {
6968 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness"));
6971 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) {
6972 // Write to the cache.
6973 RunFixtureTransactionTest();
6975 transaction_.handler = CheckResourceFreshnessHeaderPresent;
6977 // Read back from the cache.
6978 RunFixtureTransactionTest();
6981 // Verify that when age > max-age + stale-while-revalidate stale results are
6982 // not returned.
6983 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) {
6984 age_ = 10801;
6986 // Write to the cache.
6987 RunFixtureTransactionTest();
6989 EXPECT_EQ(0, open_count());
6990 EXPECT_EQ(1, transaction_count());
6992 // Reading back reads from the network.
6993 RunFixtureTransactionTest();
6995 EXPECT_EQ(1, open_count());
6996 EXPECT_EQ(2, transaction_count());
6999 // HEAD requests should be able to take advantage of stale-while-revalidate.
7000 TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) {
7001 // Write to the cache. This has to be a GET request; HEAD requests don't
7002 // create new cache entries.
7003 RunFixtureTransactionTest();
7005 EXPECT_EQ(0, open_count());
7006 EXPECT_EQ(1, transaction_count());
7008 // Read back from the cache, and trigger an asynchronous HEAD request.
7009 transaction_.method = "HEAD";
7010 transaction_.data = "";
7012 RunFixtureTransactionTest();
7014 EXPECT_EQ(1, open_count());
7015 EXPECT_EQ(1, transaction_count());
7017 // Let the network request proceed.
7018 base::RunLoop().RunUntilIdle();
7020 EXPECT_EQ(2, transaction_count());
7023 // POST requests should not use stale-while-revalidate.
7024 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) {
7025 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction);
7027 // Write to the cache.
7028 RunFixtureTransactionTest();
7030 EXPECT_EQ(0, open_count());
7031 EXPECT_EQ(1, transaction_count());
7033 // Reading back reads from the network.
7034 RunFixtureTransactionTest();
7036 EXPECT_EQ(0, open_count());
7037 EXPECT_EQ(2, transaction_count());
7040 static void CheckUrlMatches(const net::HttpRequestInfo* request,
7041 std::string* response_status,
7042 std::string* response_headers,
7043 std::string* response_data) {
7044 EXPECT_EQ("http://www.google.com/", request->url.spec());
7047 // Async revalidation is issued to the original URL.
7048 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) {
7049 transaction_.url = "http://www.google.com/";
7050 // Write to the cache.
7051 RunFixtureTransactionTest();
7053 // Read back from the cache.
7054 RunFixtureTransactionTest();
7056 EXPECT_EQ(1, transaction_count());
7058 transaction_.handler = CheckUrlMatches;
7060 // Let the async request execute and perform the check.
7061 base::RunLoop().RunUntilIdle();
7062 EXPECT_EQ(2, transaction_count());
7065 class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest,
7066 public ::testing::WithParamInterface<int> {};
7068 // Flags which should always cause the request to be synchronous.
7069 TEST_P(SyncLoadFlagTest, MustBeSynchronous) {
7070 transaction_.load_flags |= GetParam();
7071 // Write to the cache.
7072 RunFixtureTransactionTest();
7074 EXPECT_EQ(1, transaction_count());
7076 // Reading back reads from the network.
7077 RunFixtureTransactionTest();
7079 EXPECT_EQ(2, transaction_count());
7082 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate,
7083 SyncLoadFlagTest,
7084 ::testing::Values(net::LOAD_VALIDATE_CACHE,
7085 net::LOAD_BYPASS_CACHE,
7086 net::LOAD_DISABLE_CACHE));
7088 TEST_F(HttpCacheStaleWhileRevalidateTest,
7089 PreferringCacheDoesNotTriggerAsyncRequest) {
7090 transaction_.load_flags |= net::LOAD_PREFERRING_CACHE;
7091 // Write to the cache.
7092 RunFixtureTransactionTest();
7094 EXPECT_EQ(1, transaction_count());
7096 // Reading back reads from the cache.
7097 RunFixtureTransactionTest();
7099 EXPECT_EQ(1, transaction_count());
7101 // If there was an async transaction created, it would run now.
7102 base::RunLoop().RunUntilIdle();
7104 // There was no async transaction.
7105 EXPECT_EQ(1, transaction_count());
7108 TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) {
7109 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7110 // Write to the cache.
7111 RunFixtureTransactionTest();
7113 EXPECT_EQ(1, transaction_count());
7115 // A synchronous revalidation is performed.
7116 RunFixtureTransactionTest();
7118 EXPECT_EQ(2, transaction_count());
7121 TEST_F(HttpCacheStaleWhileRevalidateTest,
7122 OnlyFromCacheDoesNotTriggerAsyncRequest) {
7123 transaction_.load_flags |= net::LOAD_ONLY_FROM_CACHE;
7124 transaction_.return_code = net::ERR_CACHE_MISS;
7126 // Writing to the cache should fail, because we are avoiding the network.
7127 RunFixtureTransactionTest();
7129 EXPECT_EQ(0, transaction_count());
7131 base::RunLoop().RunUntilIdle();
7133 // Still nothing.
7134 EXPECT_EQ(0, transaction_count());
7137 // A certificate error during an asynchronous fetch should cause the next fetch
7138 // to proceed synchronously.
7139 // TODO(ricea): In future, only certificate errors which require user
7140 // interaction should fail the asynchronous revalidation, and they should cause
7141 // the next revalidation to be synchronous rather than requiring a total
7142 // refetch. This test will need to be updated appropriately.
7143 TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) {
7144 // Write to the cache.
7145 RunFixtureTransactionTest();
7147 EXPECT_EQ(1, transaction_count());
7149 // Now read back. RunTransactionTestBase() expects to receive the network
7150 // error back from the HttpCache::Transaction, but since the cache request
7151 // will return OK we need to duplicate some of its implementation here.
7152 transaction_.return_code = net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
7153 net::TestCompletionCallback callback;
7154 scoped_ptr<net::HttpTransaction> trans;
7155 int rv =
7156 cache_.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
7157 EXPECT_EQ(net::OK, rv);
7158 ASSERT_TRUE(trans.get());
7160 MockHttpRequest request(transaction_);
7161 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
7162 ASSERT_EQ(net::ERR_IO_PENDING, rv);
7163 ASSERT_EQ(net::OK, callback.WaitForResult());
7164 ReadAndVerifyTransaction(trans.get(), transaction_);
7166 EXPECT_EQ(1, transaction_count());
7168 // Allow the asynchronous fetch to run.
7169 base::RunLoop().RunUntilIdle();
7171 EXPECT_EQ(2, transaction_count());
7173 // Now run the transaction again. It should run synchronously.
7174 transaction_.return_code = net::OK;
7175 RunFixtureTransactionTest();
7177 EXPECT_EQ(3, transaction_count());
7180 // Ensure that the response cached by the asynchronous request is not truncated,
7181 // even if the server is slow.
7182 TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) {
7183 transaction_.test_mode = TEST_MODE_SLOW_READ;
7184 // Write to the cache.
7185 RunFixtureTransactionTest();
7187 // Read back from the cache.
7188 RunFixtureTransactionTest();
7190 // Let the async request execute.
7191 base::RunLoop().RunUntilIdle();
7193 // The cache entry should still be complete.
7194 transaction_.load_flags = net::LOAD_ONLY_FROM_CACHE;
7195 RunFixtureTransactionTest();
7198 // Verify that there are no race conditions in the completely synchronous case.
7199 TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) {
7200 transaction_.test_mode = TEST_MODE_SYNC_ALL;
7201 // Write to the cache.
7202 RunFixtureTransactionTest();
7204 EXPECT_EQ(1, transaction_count());
7206 // Read back from the cache.
7207 RunFixtureTransactionTest();
7209 EXPECT_EQ(1, transaction_count());
7211 // Let the async request execute.
7212 base::RunLoop().RunUntilIdle();
7213 EXPECT_EQ(2, transaction_count());
7216 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo* request,
7217 std::string* response_status,
7218 std::string* response_headers,
7219 std::string* response_data) {
7220 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION, request->load_flags);
7223 // Check that the load flags on the async request are the same as the load flags
7224 // on the original request, plus LOAD_ASYNC_REVALIDATION.
7225 TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) {
7226 transaction_.load_flags = net::LOAD_NORMAL;
7227 // Write to the cache.
7228 RunFixtureTransactionTest();
7230 EXPECT_EQ(1, transaction_count());
7232 // Read back from the cache.
7233 RunFixtureTransactionTest();
7235 EXPECT_EQ(1, transaction_count());
7237 transaction_.handler = CheckLoadFlagsAsyncRevalidation;
7238 // Let the async request execute.
7239 base::RunLoop().RunUntilIdle();
7240 EXPECT_EQ(2, transaction_count());
7243 static void SimpleMockAuthHandler(const net::HttpRequestInfo* request,
7244 std::string* response_status,
7245 std::string* response_headers,
7246 std::string* response_data) {
7247 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
7248 !request->extra_headers.HasHeader("Authorization")) {
7249 response_status->assign("HTTP/1.1 401 Unauthorized");
7250 response_headers->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7251 return;
7253 response_status->assign("HTTP/1.1 200 OK");
7256 TEST_F(HttpCacheStaleWhileRevalidateTest, RestartForAuth) {
7257 // Write to the cache.
7258 RunFixtureTransactionTest();
7260 EXPECT_EQ(1, transaction_count());
7262 // Now make the transaction require auth.
7263 transaction_.request_headers = "X-Require-Mock-Auth: dummy\r\n\r\n";
7264 transaction_.handler = SimpleMockAuthHandler;
7266 // Read back from the cache.
7267 RunFixtureTransactionTest();
7269 EXPECT_EQ(1, transaction_count());
7271 // Let the async request execute.
7272 base::RunLoop().RunUntilIdle();
7274 EXPECT_EQ(2, transaction_count());
7277 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7278 // take place on a sparse entry.
7279 TEST(HttpCache, RangeGET_MultipleRequests) {
7280 MockHttpCache cache;
7282 // Create a transaction for bytes 0-9.
7283 MockHttpRequest request(kRangeGET_TransactionOK);
7284 MockTransaction transaction(kRangeGET_TransactionOK);
7285 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7286 transaction.data = "rg: 00-09 ";
7287 AddMockTransaction(&transaction);
7289 net::TestCompletionCallback callback;
7290 scoped_ptr<net::HttpTransaction> trans;
7291 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
7292 EXPECT_EQ(net::OK, rv);
7293 ASSERT_TRUE(trans.get());
7295 // Start our transaction.
7296 trans->Start(&request, callback.callback(), net::BoundNetLog());
7298 // A second transaction on a different part of the file (the default
7299 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7300 // the already pending transaction.
7301 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7303 // Let the first transaction complete.
7304 callback.WaitForResult();
7306 RemoveMockTransaction(&transaction);
7309 // Makes sure that a request stops using the cache when the response headers
7310 // with "Cache-Control: no-store" arrives. That means that another request for
7311 // the same URL can be processed before the response body of the original
7312 // request arrives.
7313 TEST(HttpCache, NoStoreResponseShouldNotBlockFollowingRequests) {
7314 MockHttpCache cache;
7315 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
7316 mock_transaction.response_headers = "Cache-Control: no-store\n";
7317 MockHttpRequest request(mock_transaction);
7319 scoped_ptr<Context> first(new Context);
7320 first->result = cache.CreateTransaction(&first->trans);
7321 ASSERT_EQ(net::OK, first->result);
7322 EXPECT_EQ(net::LOAD_STATE_IDLE, first->trans->GetLoadState());
7323 first->result = first->trans->Start(
7324 &request, first->callback.callback(), net::BoundNetLog());
7325 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
7327 base::MessageLoop::current()->RunUntilIdle();
7328 EXPECT_EQ(net::LOAD_STATE_IDLE, first->trans->GetLoadState());
7329 ASSERT_TRUE(first->trans->GetResponseInfo());
7330 EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
7331 "Cache-Control", "no-store"));
7332 // Here we have read the response header but not read the response body yet.
7334 // Let us create the second (read) transaction.
7335 scoped_ptr<Context> second(new Context);
7336 second->result = cache.CreateTransaction(&second->trans);
7337 ASSERT_EQ(net::OK, second->result);
7338 EXPECT_EQ(net::LOAD_STATE_IDLE, second->trans->GetLoadState());
7339 second->result = second->trans->Start(
7340 &request, second->callback.callback(), net::BoundNetLog());
7342 // Here the second transaction proceeds without reading the first body.
7343 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
7344 base::MessageLoop::current()->RunUntilIdle();
7345 EXPECT_EQ(net::LOAD_STATE_IDLE, second->trans->GetLoadState());
7346 ASSERT_TRUE(second->trans->GetResponseInfo());
7347 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
7348 "Cache-Control", "no-store"));
7349 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);