Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blob8473f5c00ffaee1d64ff13de6f30009ca36fad8c
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/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "net/base/cache_type.h"
16 #include "net/base/host_port_pair.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/load_timing_info.h"
19 #include "net/base/load_timing_info_test_util.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_log_unittest.h"
22 #include "net/base/upload_bytes_element_reader.h"
23 #include "net/base/upload_data_stream.h"
24 #include "net/cert/cert_status_flags.h"
25 #include "net/disk_cache/disk_cache.h"
26 #include "net/http/http_byte_range.h"
27 #include "net/http/http_request_headers.h"
28 #include "net/http/http_request_info.h"
29 #include "net/http/http_response_headers.h"
30 #include "net/http/http_response_info.h"
31 #include "net/http/http_transaction.h"
32 #include "net/http/http_transaction_test_util.h"
33 #include "net/http/http_util.h"
34 #include "net/http/mock_http_cache.h"
35 #include "net/socket/client_socket_handle.h"
36 #include "net/ssl/ssl_cert_request_info.h"
37 #include "net/websockets/websocket_handshake_stream_base.h"
38 #include "testing/gtest/include/gtest/gtest.h"
40 using base::Time;
42 namespace {
44 // Tests the load timing values of a request that goes through a
45 // MockNetworkTransaction.
46 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) {
47 EXPECT_FALSE(load_timing_info.socket_reused);
48 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
50 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
51 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
53 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
54 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
55 EXPECT_LE(load_timing_info.connect_timing.connect_end,
56 load_timing_info.send_start);
58 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
60 // Set by URLRequest / URLRequestHttpJob, at a higher level.
61 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
62 EXPECT_TRUE(load_timing_info.request_start.is_null());
63 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
66 // Tests the load timing values of a request that receives a cached response.
67 void TestLoadTimingCachedResponse(const net::LoadTimingInfo& load_timing_info) {
68 EXPECT_FALSE(load_timing_info.socket_reused);
69 EXPECT_EQ(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
71 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
72 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
74 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
76 // Only the send start / end times should be sent, and they should have the
77 // same value.
78 EXPECT_FALSE(load_timing_info.send_start.is_null());
79 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
81 // Set by URLRequest / URLRequestHttpJob, at a higher level.
82 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
83 EXPECT_TRUE(load_timing_info.request_start.is_null());
84 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
87 class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
88 public:
89 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
90 : cache_(cache),
91 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
92 base::Unretained(this))) {
95 const net::CompletionCallback& callback() const { return callback_; }
97 private:
98 void OnComplete(int result) {
99 delete cache_;
100 SetResult(result);
103 MockHttpCache* cache_;
104 net::CompletionCallback callback_;
106 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
109 //-----------------------------------------------------------------------------
110 // helpers
112 void ReadAndVerifyTransaction(net::HttpTransaction* trans,
113 const MockTransaction& trans_info) {
114 std::string content;
115 int rv = ReadTransaction(trans, &content);
117 EXPECT_EQ(net::OK, rv);
118 std::string expected(trans_info.data);
119 EXPECT_EQ(expected, content);
122 void RunTransactionTestBase(net::HttpCache* cache,
123 const MockTransaction& trans_info,
124 const MockHttpRequest& request,
125 net::HttpResponseInfo* response_info,
126 const net::BoundNetLog& net_log,
127 net::LoadTimingInfo* load_timing_info,
128 int64* received_bytes) {
129 net::TestCompletionCallback callback;
131 // write to the cache
133 scoped_ptr<net::HttpTransaction> trans;
134 int rv = cache->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
135 EXPECT_EQ(net::OK, rv);
136 ASSERT_TRUE(trans.get());
138 rv = trans->Start(&request, callback.callback(), net_log);
139 if (rv == net::ERR_IO_PENDING)
140 rv = callback.WaitForResult();
141 ASSERT_EQ(trans_info.return_code, rv);
143 if (net::OK != rv)
144 return;
146 const net::HttpResponseInfo* response = trans->GetResponseInfo();
147 ASSERT_TRUE(response);
149 if (response_info)
150 *response_info = *response;
152 if (load_timing_info) {
153 // If a fake network connection is used, need a NetLog to get a fake socket
154 // ID.
155 EXPECT_TRUE(net_log.net_log());
156 *load_timing_info = net::LoadTimingInfo();
157 trans->GetLoadTimingInfo(load_timing_info);
160 ReadAndVerifyTransaction(trans.get(), trans_info);
162 if (received_bytes)
163 *received_bytes = trans->GetTotalReceivedBytes();
166 void RunTransactionTestWithRequest(net::HttpCache* cache,
167 const MockTransaction& trans_info,
168 const MockHttpRequest& request,
169 net::HttpResponseInfo* response_info) {
170 RunTransactionTestBase(cache, trans_info, request, response_info,
171 net::BoundNetLog(), NULL, NULL);
174 void RunTransactionTestAndGetTiming(net::HttpCache* cache,
175 const MockTransaction& trans_info,
176 const net::BoundNetLog& log,
177 net::LoadTimingInfo* load_timing_info) {
178 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
179 NULL, log, load_timing_info, NULL);
182 void RunTransactionTest(net::HttpCache* cache,
183 const MockTransaction& trans_info) {
184 RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL);
187 void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
188 const MockTransaction& trans_info,
189 net::HttpResponseInfo* response) {
190 RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
191 response);
194 void RunTransactionTestWithResponseInfoAndGetTiming(
195 net::HttpCache* cache,
196 const MockTransaction& trans_info,
197 net::HttpResponseInfo* response,
198 const net::BoundNetLog& log,
199 net::LoadTimingInfo* load_timing_info) {
200 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
201 response, log, load_timing_info, NULL);
204 void RunTransactionTestWithResponse(net::HttpCache* cache,
205 const MockTransaction& trans_info,
206 std::string* response_headers) {
207 net::HttpResponseInfo response;
208 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
209 response.headers->GetNormalizedHeaders(response_headers);
212 void RunTransactionTestWithResponseAndGetTiming(
213 net::HttpCache* cache,
214 const MockTransaction& trans_info,
215 std::string* response_headers,
216 const net::BoundNetLog& log,
217 net::LoadTimingInfo* load_timing_info) {
218 net::HttpResponseInfo response;
219 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
220 &response, log, load_timing_info, NULL);
221 response.headers->GetNormalizedHeaders(response_headers);
224 // This class provides a handler for kFastNoStoreGET_Transaction so that the
225 // no-store header can be included on demand.
226 class FastTransactionServer {
227 public:
228 FastTransactionServer() {
229 no_store = false;
231 ~FastTransactionServer() {}
233 void set_no_store(bool value) { no_store = value; }
235 static void FastNoStoreHandler(const net::HttpRequestInfo* request,
236 std::string* response_status,
237 std::string* response_headers,
238 std::string* response_data) {
239 if (no_store)
240 *response_headers = "Cache-Control: no-store\n";
243 private:
244 static bool no_store;
245 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
247 bool FastTransactionServer::no_store;
249 const MockTransaction kFastNoStoreGET_Transaction = {
250 "http://www.google.com/nostore",
251 "GET",
252 base::Time(),
254 net::LOAD_VALIDATE_CACHE,
255 "HTTP/1.1 200 OK",
256 "Cache-Control: max-age=10000\n",
257 base::Time(),
258 "<html><body>Google Blah Blah</body></html>",
259 TEST_MODE_SYNC_NET_START,
260 &FastTransactionServer::FastNoStoreHandler,
262 net::OK
265 // This class provides a handler for kRangeGET_TransactionOK so that the range
266 // request can be served on demand.
267 class RangeTransactionServer {
268 public:
269 RangeTransactionServer() {
270 not_modified_ = false;
271 modified_ = false;
272 bad_200_ = false;
274 ~RangeTransactionServer() {
275 not_modified_ = false;
276 modified_ = false;
277 bad_200_ = false;
280 // Returns only 416 or 304 when set.
281 void set_not_modified(bool value) { not_modified_ = value; }
283 // Returns 206 when revalidating a range (instead of 304).
284 void set_modified(bool value) { modified_ = value; }
286 // Returns 200 instead of 206 (a malformed response overall).
287 void set_bad_200(bool value) { bad_200_ = value; }
289 static void RangeHandler(const net::HttpRequestInfo* request,
290 std::string* response_status,
291 std::string* response_headers,
292 std::string* response_data);
294 private:
295 static bool not_modified_;
296 static bool modified_;
297 static bool bad_200_;
298 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
300 bool RangeTransactionServer::not_modified_ = false;
301 bool RangeTransactionServer::modified_ = false;
302 bool RangeTransactionServer::bad_200_ = false;
304 // A dummy extra header that must be preserved on a given request.
306 // EXTRA_HEADER_LINE doesn't include a line terminator because it
307 // will be passed to AddHeaderFromString() which doesn't accept them.
308 #define EXTRA_HEADER_LINE "Extra: header"
310 // EXTRA_HEADER contains a line terminator, as expected by
311 // AddHeadersFromString() (_not_ AddHeaderFromString()).
312 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
314 static const char kExtraHeaderKey[] = "Extra";
316 // Static.
317 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
318 std::string* response_status,
319 std::string* response_headers,
320 std::string* response_data) {
321 if (request->extra_headers.IsEmpty()) {
322 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
323 response_data->clear();
324 return;
327 // We want to make sure we don't delete extra headers.
328 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
330 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
331 !request->extra_headers.HasHeader("Authorization")) {
332 response_status->assign("HTTP/1.1 401 Unauthorized");
333 response_data->assign("WWW-Authenticate: Foo\n");
334 return;
337 if (not_modified_) {
338 response_status->assign("HTTP/1.1 304 Not Modified");
339 response_data->clear();
340 return;
343 std::vector<net::HttpByteRange> ranges;
344 std::string range_header;
345 if (!request->extra_headers.GetHeader(
346 net::HttpRequestHeaders::kRange, &range_header) ||
347 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
348 ranges.size() != 1) {
349 // This is not a byte range request. We return 200.
350 response_status->assign("HTTP/1.1 200 OK");
351 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
352 response_data->assign("Not a range");
353 return;
356 // We can handle this range request.
357 net::HttpByteRange byte_range = ranges[0];
358 if (byte_range.first_byte_position() > 79) {
359 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
360 response_data->clear();
361 return;
364 EXPECT_TRUE(byte_range.ComputeBounds(80));
365 int start = static_cast<int>(byte_range.first_byte_position());
366 int end = static_cast<int>(byte_range.last_byte_position());
368 EXPECT_LT(end, 80);
370 std::string content_range = base::StringPrintf(
371 "Content-Range: bytes %d-%d/80\n", start, end);
372 response_headers->append(content_range);
374 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
375 std::string data;
376 if (end == start) {
377 EXPECT_EQ(0, end % 10);
378 data = "r";
379 } else {
380 EXPECT_EQ(9, (end - start) % 10);
381 for (int block_start = start; block_start < end; block_start += 10) {
382 base::StringAppendF(&data, "rg: %02d-%02d ",
383 block_start, block_start + 9);
386 *response_data = data;
388 if (end - start != 9) {
389 // We also have to fix content-length.
390 int len = end - start + 1;
391 std::string content_length = base::StringPrintf("Content-Length: %d\n",
392 len);
393 response_headers->replace(response_headers->find("Content-Length:"),
394 content_length.size(), content_length);
396 } else {
397 response_status->assign("HTTP/1.1 304 Not Modified");
398 response_data->clear();
402 const MockTransaction kRangeGET_TransactionOK = {
403 "http://www.google.com/range",
404 "GET",
405 base::Time(),
406 "Range: bytes = 40-49\r\n"
407 EXTRA_HEADER,
408 net::LOAD_NORMAL,
409 "HTTP/1.1 206 Partial Content",
410 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
411 "ETag: \"foo\"\n"
412 "Accept-Ranges: bytes\n"
413 "Content-Length: 10\n",
414 base::Time(),
415 "rg: 40-49 ",
416 TEST_MODE_NORMAL,
417 &RangeTransactionServer::RangeHandler,
419 net::OK
422 // Verifies the response headers (|response|) match a partial content
423 // response for the range starting at |start| and ending at |end|.
424 void Verify206Response(std::string response, int start, int end) {
425 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
426 response.size()));
427 scoped_refptr<net::HttpResponseHeaders> headers(
428 new net::HttpResponseHeaders(raw_headers));
430 ASSERT_EQ(206, headers->response_code());
432 int64 range_start, range_end, object_size;
433 ASSERT_TRUE(
434 headers->GetContentRange(&range_start, &range_end, &object_size));
435 int64 content_length = headers->GetContentLength();
437 int length = end - start + 1;
438 ASSERT_EQ(length, content_length);
439 ASSERT_EQ(start, range_start);
440 ASSERT_EQ(end, range_end);
443 // Creates a truncated entry that can be resumed using byte ranges.
444 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
445 // Create a disk cache entry that stores an incomplete resource.
446 disk_cache::Entry* entry;
447 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
448 NULL));
450 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
451 raw_headers.size());
453 net::HttpResponseInfo response;
454 response.response_time = base::Time::Now();
455 response.request_time = base::Time::Now();
456 response.headers = new net::HttpResponseHeaders(raw_headers);
457 // Set the last argument for this to be an incomplete request.
458 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
460 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
461 int len = static_cast<int>(base::strlcpy(buf->data(),
462 "rg: 00-09 rg: 10-19 ", 100));
463 net::TestCompletionCallback cb;
464 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
465 EXPECT_EQ(len, cb.GetResult(rv));
466 entry->Close();
469 // Helper to represent a network HTTP response.
470 struct Response {
471 // Set this response into |trans|.
472 void AssignTo(MockTransaction* trans) const {
473 trans->status = status;
474 trans->response_headers = headers;
475 trans->data = body;
478 std::string status_and_headers() const {
479 return std::string(status) + "\n" + std::string(headers);
482 const char* status;
483 const char* headers;
484 const char* body;
487 struct Context {
488 Context() : result(net::ERR_IO_PENDING) {}
490 int result;
491 net::TestCompletionCallback callback;
492 scoped_ptr<net::HttpTransaction> trans;
495 class FakeWebSocketHandshakeStreamCreateHelper
496 : public net::WebSocketHandshakeStreamBase::CreateHelper {
497 public:
498 virtual ~FakeWebSocketHandshakeStreamCreateHelper() {}
499 virtual net::WebSocketHandshakeStreamBase* CreateBasicStream(
500 scoped_ptr<net::ClientSocketHandle> connect, bool using_proxy) OVERRIDE {
501 return NULL;
503 virtual net::WebSocketHandshakeStreamBase* CreateSpdyStream(
504 const base::WeakPtr<net::SpdySession>& session,
505 bool use_relative_url) OVERRIDE {
506 return NULL;
510 // Returns true if |entry| is not one of the log types paid attention to in this
511 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
512 // ignored.
513 bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry& entry) {
514 switch (entry.type) {
515 case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
516 case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
517 case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
518 case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
519 case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
520 case net::NetLog::TYPE_HTTP_CACHE_READ_INFO:
521 return false;
522 default:
523 return true;
527 // Modifies |entries| to only include log entries created by the cache layer and
528 // asserted on in these tests.
529 void FilterLogEntries(net::CapturingNetLog::CapturedEntryList* entries) {
530 entries->erase(std::remove_if(entries->begin(), entries->end(),
531 &ShouldIgnoreLogEntry),
532 entries->end());
535 } // namespace
538 //-----------------------------------------------------------------------------
539 // Tests.
541 TEST(HttpCache, CreateThenDestroy) {
542 MockHttpCache cache;
544 scoped_ptr<net::HttpTransaction> trans;
545 EXPECT_EQ(net::OK, cache.CreateTransaction(&trans));
546 ASSERT_TRUE(trans.get());
549 TEST(HttpCache, GetBackend) {
550 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
552 disk_cache::Backend* backend;
553 net::TestCompletionCallback cb;
554 // This will lazily initialize the backend.
555 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
556 EXPECT_EQ(net::OK, cb.GetResult(rv));
559 TEST(HttpCache, SimpleGET) {
560 MockHttpCache cache;
561 net::CapturingBoundNetLog log;
562 net::LoadTimingInfo load_timing_info;
564 // Write to the cache.
565 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
566 log.bound(), &load_timing_info);
568 EXPECT_EQ(1, cache.network_layer()->transaction_count());
569 EXPECT_EQ(0, cache.disk_cache()->open_count());
570 EXPECT_EQ(1, cache.disk_cache()->create_count());
571 TestLoadTimingNetworkRequest(load_timing_info);
574 TEST(HttpCache, SimpleGETNoDiskCache) {
575 MockHttpCache cache;
577 cache.disk_cache()->set_fail_requests();
579 net::CapturingBoundNetLog log;
580 net::LoadTimingInfo load_timing_info;
582 // Read from the network, and don't use the cache.
583 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
584 log.bound(), &load_timing_info);
586 // Check that the NetLog was filled as expected.
587 // (We attempted to both Open and Create entries, but both failed).
588 net::CapturingNetLog::CapturedEntryList entries;
589 log.GetEntries(&entries);
590 FilterLogEntries(&entries);
592 EXPECT_EQ(6u, entries.size());
593 EXPECT_TRUE(net::LogContainsBeginEvent(
594 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
595 EXPECT_TRUE(net::LogContainsEndEvent(
596 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
597 EXPECT_TRUE(net::LogContainsBeginEvent(
598 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
599 EXPECT_TRUE(net::LogContainsEndEvent(
600 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
601 EXPECT_TRUE(net::LogContainsBeginEvent(
602 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
603 EXPECT_TRUE(net::LogContainsEndEvent(
604 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
606 EXPECT_EQ(1, cache.network_layer()->transaction_count());
607 EXPECT_EQ(0, cache.disk_cache()->open_count());
608 EXPECT_EQ(0, cache.disk_cache()->create_count());
609 TestLoadTimingNetworkRequest(load_timing_info);
612 TEST(HttpCache, SimpleGETNoDiskCache2) {
613 // This will initialize a cache object with NULL backend.
614 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
615 factory->set_fail(true);
616 factory->FinishCreation(); // We'll complete synchronously.
617 MockHttpCache cache(factory);
619 // Read from the network, and don't use the cache.
620 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
622 EXPECT_EQ(1, cache.network_layer()->transaction_count());
623 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
626 // Tests that IOBuffers are not referenced after IO completes.
627 TEST(HttpCache, ReleaseBuffer) {
628 MockHttpCache cache;
630 // Write to the cache.
631 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
633 MockHttpRequest request(kSimpleGET_Transaction);
634 scoped_ptr<net::HttpTransaction> trans;
635 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
637 const int kBufferSize = 10;
638 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
639 net::ReleaseBufferCompletionCallback cb(buffer.get());
641 int rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
642 EXPECT_EQ(net::OK, cb.GetResult(rv));
644 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
645 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
648 TEST(HttpCache, SimpleGETWithDiskFailures) {
649 MockHttpCache cache;
651 cache.disk_cache()->set_soft_failures(true);
653 // Read from the network, and fail to write to the cache.
654 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
656 EXPECT_EQ(1, cache.network_layer()->transaction_count());
657 EXPECT_EQ(0, cache.disk_cache()->open_count());
658 EXPECT_EQ(1, cache.disk_cache()->create_count());
660 // This one should see an empty cache again.
661 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
663 EXPECT_EQ(2, cache.network_layer()->transaction_count());
664 EXPECT_EQ(0, cache.disk_cache()->open_count());
665 EXPECT_EQ(2, cache.disk_cache()->create_count());
668 // Tests that disk failures after the transaction has started don't cause the
669 // request to fail.
670 TEST(HttpCache, SimpleGETWithDiskFailures2) {
671 MockHttpCache cache;
673 MockHttpRequest request(kSimpleGET_Transaction);
675 scoped_ptr<Context> c(new Context());
676 int rv = cache.CreateTransaction(&c->trans);
677 ASSERT_EQ(net::OK, rv);
679 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
680 EXPECT_EQ(net::ERR_IO_PENDING, rv);
681 rv = c->callback.WaitForResult();
683 // Start failing request now.
684 cache.disk_cache()->set_soft_failures(true);
686 // We have to open the entry again to propagate the failure flag.
687 disk_cache::Entry* en;
688 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
689 en->Close();
691 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
692 c.reset();
694 EXPECT_EQ(1, cache.network_layer()->transaction_count());
695 EXPECT_EQ(1, cache.disk_cache()->open_count());
696 EXPECT_EQ(1, cache.disk_cache()->create_count());
698 // This one should see an empty cache again.
699 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
701 EXPECT_EQ(2, cache.network_layer()->transaction_count());
702 EXPECT_EQ(1, cache.disk_cache()->open_count());
703 EXPECT_EQ(2, cache.disk_cache()->create_count());
706 // Tests that we handle failures to read from the cache.
707 TEST(HttpCache, SimpleGETWithDiskFailures3) {
708 MockHttpCache cache;
710 // Read from the network, and write to the cache.
711 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
713 EXPECT_EQ(1, cache.network_layer()->transaction_count());
714 EXPECT_EQ(0, cache.disk_cache()->open_count());
715 EXPECT_EQ(1, cache.disk_cache()->create_count());
717 cache.disk_cache()->set_soft_failures(true);
719 // Now fail to read from the cache.
720 scoped_ptr<Context> c(new Context());
721 int rv = cache.CreateTransaction(&c->trans);
722 ASSERT_EQ(net::OK, rv);
724 MockHttpRequest request(kSimpleGET_Transaction);
725 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
726 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
728 // Now verify that the entry was removed from the cache.
729 cache.disk_cache()->set_soft_failures(false);
731 EXPECT_EQ(2, cache.network_layer()->transaction_count());
732 EXPECT_EQ(1, cache.disk_cache()->open_count());
733 EXPECT_EQ(2, cache.disk_cache()->create_count());
735 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
737 EXPECT_EQ(3, cache.network_layer()->transaction_count());
738 EXPECT_EQ(1, cache.disk_cache()->open_count());
739 EXPECT_EQ(3, cache.disk_cache()->create_count());
742 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
743 MockHttpCache cache;
745 net::CapturingBoundNetLog log;
746 net::LoadTimingInfo load_timing_info;
748 // Write to the cache.
749 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
750 log.bound(), &load_timing_info);
752 // Check that the NetLog was filled as expected.
753 net::CapturingNetLog::CapturedEntryList entries;
754 log.GetEntries(&entries);
755 FilterLogEntries(&entries);
757 EXPECT_EQ(8u, entries.size());
758 EXPECT_TRUE(net::LogContainsBeginEvent(
759 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
760 EXPECT_TRUE(net::LogContainsEndEvent(
761 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
762 EXPECT_TRUE(net::LogContainsBeginEvent(
763 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
764 EXPECT_TRUE(net::LogContainsEndEvent(
765 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
766 EXPECT_TRUE(net::LogContainsBeginEvent(
767 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
768 EXPECT_TRUE(net::LogContainsEndEvent(
769 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
770 EXPECT_TRUE(net::LogContainsBeginEvent(
771 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
772 EXPECT_TRUE(net::LogContainsEndEvent(
773 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
775 TestLoadTimingNetworkRequest(load_timing_info);
777 // Force this transaction to read from the cache.
778 MockTransaction transaction(kSimpleGET_Transaction);
779 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
781 log.Clear();
783 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
784 &load_timing_info);
786 // Check that the NetLog was filled as expected.
787 log.GetEntries(&entries);
788 FilterLogEntries(&entries);
790 EXPECT_EQ(8u, entries.size());
791 EXPECT_TRUE(net::LogContainsBeginEvent(
792 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
793 EXPECT_TRUE(net::LogContainsEndEvent(
794 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
795 EXPECT_TRUE(net::LogContainsBeginEvent(
796 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
797 EXPECT_TRUE(net::LogContainsEndEvent(
798 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
799 EXPECT_TRUE(net::LogContainsBeginEvent(
800 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
801 EXPECT_TRUE(net::LogContainsEndEvent(
802 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
803 EXPECT_TRUE(net::LogContainsBeginEvent(
804 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
805 EXPECT_TRUE(net::LogContainsEndEvent(
806 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
808 EXPECT_EQ(1, cache.network_layer()->transaction_count());
809 EXPECT_EQ(1, cache.disk_cache()->open_count());
810 EXPECT_EQ(1, cache.disk_cache()->create_count());
811 TestLoadTimingCachedResponse(load_timing_info);
814 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
815 MockHttpCache cache;
817 // force this transaction to read from the cache
818 MockTransaction transaction(kSimpleGET_Transaction);
819 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
821 MockHttpRequest request(transaction);
822 net::TestCompletionCallback callback;
824 scoped_ptr<net::HttpTransaction> trans;
825 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
827 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
828 if (rv == net::ERR_IO_PENDING)
829 rv = callback.WaitForResult();
830 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
832 trans.reset();
834 EXPECT_EQ(0, cache.network_layer()->transaction_count());
835 EXPECT_EQ(0, cache.disk_cache()->open_count());
836 EXPECT_EQ(0, cache.disk_cache()->create_count());
839 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
840 MockHttpCache cache;
842 // write to the cache
843 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
845 // force this transaction to read from the cache if valid
846 MockTransaction transaction(kSimpleGET_Transaction);
847 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
849 RunTransactionTest(cache.http_cache(), transaction);
851 EXPECT_EQ(1, cache.network_layer()->transaction_count());
852 EXPECT_EQ(1, cache.disk_cache()->open_count());
853 EXPECT_EQ(1, cache.disk_cache()->create_count());
856 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
857 MockHttpCache cache;
859 // force this transaction to read from the cache if valid
860 MockTransaction transaction(kSimpleGET_Transaction);
861 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
863 RunTransactionTest(cache.http_cache(), transaction);
865 EXPECT_EQ(1, cache.network_layer()->transaction_count());
866 EXPECT_EQ(0, cache.disk_cache()->open_count());
867 EXPECT_EQ(1, cache.disk_cache()->create_count());
870 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
871 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
872 MockHttpCache cache;
874 // Write to the cache.
875 MockTransaction transaction(kSimpleGET_Transaction);
876 transaction.request_headers = "Foo: bar\r\n";
877 transaction.response_headers = "Cache-Control: max-age=10000\n"
878 "Vary: Foo\n";
879 AddMockTransaction(&transaction);
880 RunTransactionTest(cache.http_cache(), transaction);
882 // Read from the cache.
883 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
884 RunTransactionTest(cache.http_cache(), transaction);
886 EXPECT_EQ(1, cache.network_layer()->transaction_count());
887 EXPECT_EQ(1, cache.disk_cache()->open_count());
888 EXPECT_EQ(1, cache.disk_cache()->create_count());
889 RemoveMockTransaction(&transaction);
892 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
893 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
894 MockHttpCache cache;
896 // Write to the cache.
897 MockTransaction transaction(kSimpleGET_Transaction);
898 transaction.request_headers = "Foo: bar\r\n";
899 transaction.response_headers = "Cache-Control: max-age=10000\n"
900 "Vary: Foo\n";
901 AddMockTransaction(&transaction);
902 RunTransactionTest(cache.http_cache(), transaction);
904 // Attempt to read from the cache... this is a vary mismatch that must reach
905 // the network again.
906 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
907 transaction.request_headers = "Foo: none\r\n";
908 net::CapturingBoundNetLog log;
909 net::LoadTimingInfo load_timing_info;
910 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
911 &load_timing_info);
913 EXPECT_EQ(2, cache.network_layer()->transaction_count());
914 EXPECT_EQ(1, cache.disk_cache()->open_count());
915 EXPECT_EQ(1, cache.disk_cache()->create_count());
916 TestLoadTimingNetworkRequest(load_timing_info);
917 RemoveMockTransaction(&transaction);
920 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
921 // network success
922 TEST(HttpCache, SimpleGET_CacheOverride_Network) {
923 MockHttpCache cache;
925 // Prime cache.
926 MockTransaction transaction(kSimpleGET_Transaction);
927 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
928 transaction.response_headers = "Cache-Control: no-cache\n";
930 AddMockTransaction(&transaction);
931 RunTransactionTest(cache.http_cache(), transaction);
932 EXPECT_EQ(1, cache.network_layer()->transaction_count());
933 EXPECT_EQ(1, cache.disk_cache()->create_count());
934 RemoveMockTransaction(&transaction);
936 // Re-run transaction; make sure the result came from the network,
937 // not the cache.
938 transaction.data = "Changed data.";
939 AddMockTransaction(&transaction);
940 net::HttpResponseInfo response_info;
941 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
942 &response_info);
944 EXPECT_EQ(2, cache.network_layer()->transaction_count());
945 EXPECT_FALSE(response_info.server_data_unavailable);
946 EXPECT_TRUE(response_info.network_accessed);
948 RemoveMockTransaction(&transaction);
951 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
952 // offline failure
953 TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
954 MockHttpCache cache;
956 // Prime cache.
957 MockTransaction transaction(kSimpleGET_Transaction);
958 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
959 transaction.response_headers = "Cache-Control: no-cache\n";
961 AddMockTransaction(&transaction);
962 RunTransactionTest(cache.http_cache(), transaction);
963 EXPECT_EQ(1, cache.network_layer()->transaction_count());
964 EXPECT_EQ(1, cache.disk_cache()->create_count());
965 RemoveMockTransaction(&transaction);
967 // Network failure with offline error; should return cache entry above +
968 // flag signalling stale data.
969 transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
970 AddMockTransaction(&transaction);
972 MockHttpRequest request(transaction);
973 net::TestCompletionCallback callback;
974 scoped_ptr<net::HttpTransaction> trans;
975 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
976 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
977 EXPECT_EQ(net::OK, callback.GetResult(rv));
979 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
980 ASSERT_TRUE(response_info);
981 EXPECT_TRUE(response_info->server_data_unavailable);
982 EXPECT_TRUE(response_info->was_cached);
983 EXPECT_FALSE(response_info->network_accessed);
984 ReadAndVerifyTransaction(trans.get(), transaction);
985 EXPECT_EQ(2, cache.network_layer()->transaction_count());
987 RemoveMockTransaction(&transaction);
990 // Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
991 // non-offline failure.
992 TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
993 MockHttpCache cache;
995 // Prime cache.
996 MockTransaction transaction(kSimpleGET_Transaction);
997 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
998 transaction.response_headers = "Cache-Control: no-cache\n";
1000 AddMockTransaction(&transaction);
1001 RunTransactionTest(cache.http_cache(), transaction);
1002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1003 EXPECT_EQ(1, cache.disk_cache()->create_count());
1004 RemoveMockTransaction(&transaction);
1006 // Network failure with non-offline error; should fail with that error.
1007 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1008 AddMockTransaction(&transaction);
1010 net::HttpResponseInfo response_info2;
1011 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1012 &response_info2);
1014 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1015 EXPECT_FALSE(response_info2.server_data_unavailable);
1017 RemoveMockTransaction(&transaction);
1020 // Tests that was_cached was set properly on a failure, even if the cached
1021 // response wasn't returned.
1022 TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
1023 MockHttpCache cache;
1025 // Prime cache.
1026 MockTransaction transaction(kSimpleGET_Transaction);
1027 transaction.response_headers = "Cache-Control: no-cache\n";
1029 AddMockTransaction(&transaction);
1030 RunTransactionTest(cache.http_cache(), transaction);
1031 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1032 EXPECT_EQ(1, cache.disk_cache()->create_count());
1033 RemoveMockTransaction(&transaction);
1035 // Network failure with error; should fail but have was_cached set.
1036 transaction.return_code = net::ERR_FAILED;
1037 AddMockTransaction(&transaction);
1039 MockHttpRequest request(transaction);
1040 net::TestCompletionCallback callback;
1041 scoped_ptr<net::HttpTransaction> trans;
1042 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
1043 EXPECT_EQ(net::OK, rv);
1044 ASSERT_TRUE(trans.get());
1045 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1046 EXPECT_EQ(net::ERR_FAILED, callback.GetResult(rv));
1048 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1049 ASSERT_TRUE(response_info);
1050 EXPECT_TRUE(response_info->was_cached);
1051 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1053 RemoveMockTransaction(&transaction);
1056 // Confirm if we have an empty cache, a read is marked as network verified.
1057 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1058 MockHttpCache cache;
1060 // write to the cache
1061 net::HttpResponseInfo response_info;
1062 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1063 &response_info);
1065 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1066 EXPECT_EQ(0, cache.disk_cache()->open_count());
1067 EXPECT_EQ(1, cache.disk_cache()->create_count());
1068 EXPECT_TRUE(response_info.network_accessed);
1071 // Confirm if we have a fresh entry in cache, it isn't marked as
1072 // network verified.
1073 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1074 MockHttpCache cache;
1076 // Prime cache.
1077 MockTransaction transaction(kSimpleGET_Transaction);
1079 RunTransactionTest(cache.http_cache(), transaction);
1080 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1081 EXPECT_EQ(1, cache.disk_cache()->create_count());
1083 // Re-run transaction; make sure we don't mark the network as accessed.
1084 net::HttpResponseInfo response_info;
1085 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1086 &response_info);
1088 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1089 EXPECT_FALSE(response_info.server_data_unavailable);
1090 EXPECT_FALSE(response_info.network_accessed);
1093 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1094 MockHttpCache cache;
1096 // Write to the cache.
1097 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1099 // Force this transaction to write to the cache again.
1100 MockTransaction transaction(kSimpleGET_Transaction);
1101 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1103 net::CapturingBoundNetLog log;
1104 net::LoadTimingInfo load_timing_info;
1106 // Write to the cache.
1107 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1108 &load_timing_info);
1110 // Check that the NetLog was filled as expected.
1111 net::CapturingNetLog::CapturedEntryList entries;
1112 log.GetEntries(&entries);
1113 FilterLogEntries(&entries);
1115 EXPECT_EQ(8u, entries.size());
1116 EXPECT_TRUE(net::LogContainsBeginEvent(
1117 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1118 EXPECT_TRUE(net::LogContainsEndEvent(
1119 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1120 EXPECT_TRUE(net::LogContainsBeginEvent(
1121 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1122 EXPECT_TRUE(net::LogContainsEndEvent(
1123 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1124 EXPECT_TRUE(net::LogContainsBeginEvent(
1125 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1126 EXPECT_TRUE(net::LogContainsEndEvent(
1127 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1128 EXPECT_TRUE(net::LogContainsBeginEvent(
1129 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1130 EXPECT_TRUE(net::LogContainsEndEvent(
1131 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1133 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1134 EXPECT_EQ(0, cache.disk_cache()->open_count());
1135 EXPECT_EQ(2, cache.disk_cache()->create_count());
1136 TestLoadTimingNetworkRequest(load_timing_info);
1139 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1140 MockHttpCache cache;
1142 // write to the cache
1143 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1145 // force this transaction to write to the cache again
1146 MockTransaction transaction(kSimpleGET_Transaction);
1147 transaction.request_headers = "pragma: no-cache\r\n";
1149 RunTransactionTest(cache.http_cache(), transaction);
1151 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1152 EXPECT_EQ(0, cache.disk_cache()->open_count());
1153 EXPECT_EQ(2, cache.disk_cache()->create_count());
1156 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1157 MockHttpCache cache;
1159 // write to the cache
1160 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1162 // force this transaction to write to the cache again
1163 MockTransaction transaction(kSimpleGET_Transaction);
1164 transaction.request_headers = "cache-control: no-cache\r\n";
1166 RunTransactionTest(cache.http_cache(), transaction);
1168 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1169 EXPECT_EQ(0, cache.disk_cache()->open_count());
1170 EXPECT_EQ(2, cache.disk_cache()->create_count());
1173 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1174 MockHttpCache cache;
1176 // Write to the cache.
1177 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1179 // Read from the cache.
1180 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1182 // Force this transaction to validate the cache.
1183 MockTransaction transaction(kSimpleGET_Transaction);
1184 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1186 net::HttpResponseInfo response_info;
1187 net::CapturingBoundNetLog log;
1188 net::LoadTimingInfo load_timing_info;
1189 RunTransactionTestWithResponseInfoAndGetTiming(
1190 cache.http_cache(), transaction, &response_info, log.bound(),
1191 &load_timing_info);
1193 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1194 EXPECT_EQ(1, cache.disk_cache()->open_count());
1195 EXPECT_EQ(1, cache.disk_cache()->create_count());
1196 EXPECT_TRUE(response_info.network_accessed);
1197 TestLoadTimingNetworkRequest(load_timing_info);
1200 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1201 MockHttpCache cache;
1203 // write to the cache
1204 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1206 // read from the cache
1207 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1209 // force this transaction to validate the cache
1210 MockTransaction transaction(kSimpleGET_Transaction);
1211 transaction.request_headers = "cache-control: max-age=0\r\n";
1213 RunTransactionTest(cache.http_cache(), transaction);
1215 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1216 EXPECT_EQ(1, cache.disk_cache()->open_count());
1217 EXPECT_EQ(1, cache.disk_cache()->create_count());
1220 static void PreserveRequestHeaders_Handler(
1221 const net::HttpRequestInfo* request,
1222 std::string* response_status,
1223 std::string* response_headers,
1224 std::string* response_data) {
1225 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1228 // Tests that we don't remove extra headers for simple requests.
1229 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1230 MockHttpCache cache;
1232 MockTransaction transaction(kSimpleGET_Transaction);
1233 transaction.handler = PreserveRequestHeaders_Handler;
1234 transaction.request_headers = EXTRA_HEADER;
1235 transaction.response_headers = "Cache-Control: max-age=0\n";
1236 AddMockTransaction(&transaction);
1238 // Write, then revalidate the entry.
1239 RunTransactionTest(cache.http_cache(), transaction);
1240 RunTransactionTest(cache.http_cache(), transaction);
1242 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1243 EXPECT_EQ(1, cache.disk_cache()->open_count());
1244 EXPECT_EQ(1, cache.disk_cache()->create_count());
1245 RemoveMockTransaction(&transaction);
1248 // Tests that we don't remove extra headers for conditionalized requests.
1249 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1250 MockHttpCache cache;
1252 // Write to the cache.
1253 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1255 MockTransaction transaction(kETagGET_Transaction);
1256 transaction.handler = PreserveRequestHeaders_Handler;
1257 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1258 EXTRA_HEADER;
1259 AddMockTransaction(&transaction);
1261 RunTransactionTest(cache.http_cache(), transaction);
1263 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1264 EXPECT_EQ(1, cache.disk_cache()->open_count());
1265 EXPECT_EQ(1, cache.disk_cache()->create_count());
1266 RemoveMockTransaction(&transaction);
1269 TEST(HttpCache, SimpleGET_ManyReaders) {
1270 MockHttpCache cache;
1272 MockHttpRequest request(kSimpleGET_Transaction);
1274 std::vector<Context*> context_list;
1275 const int kNumTransactions = 5;
1277 for (int i = 0; i < kNumTransactions; ++i) {
1278 context_list.push_back(new Context());
1279 Context* c = context_list[i];
1281 c->result = cache.CreateTransaction(&c->trans);
1282 ASSERT_EQ(net::OK, c->result);
1283 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1285 c->result = c->trans->Start(
1286 &request, c->callback.callback(), net::BoundNetLog());
1289 // All requests are waiting for the active entry.
1290 for (int i = 0; i < kNumTransactions; ++i) {
1291 Context* c = context_list[i];
1292 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1295 // Allow all requests to move from the Create queue to the active entry.
1296 base::MessageLoop::current()->RunUntilIdle();
1298 // The first request should be a writer at this point, and the subsequent
1299 // requests should be pending.
1301 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1302 EXPECT_EQ(0, cache.disk_cache()->open_count());
1303 EXPECT_EQ(1, cache.disk_cache()->create_count());
1305 // All requests depend on the writer, and the writer is between Start and
1306 // Read, i.e. idle.
1307 for (int i = 0; i < kNumTransactions; ++i) {
1308 Context* c = context_list[i];
1309 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1312 for (int i = 0; i < kNumTransactions; ++i) {
1313 Context* c = context_list[i];
1314 if (c->result == net::ERR_IO_PENDING)
1315 c->result = c->callback.WaitForResult();
1316 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1319 // We should not have had to re-open the disk entry
1321 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1322 EXPECT_EQ(0, cache.disk_cache()->open_count());
1323 EXPECT_EQ(1, cache.disk_cache()->create_count());
1325 for (int i = 0; i < kNumTransactions; ++i) {
1326 Context* c = context_list[i];
1327 delete c;
1331 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1332 // If cancelling a request is racing with another request for the same resource
1333 // finishing, we have to make sure that we remove both transactions from the
1334 // entry.
1335 TEST(HttpCache, SimpleGET_RacingReaders) {
1336 MockHttpCache cache;
1338 MockHttpRequest request(kSimpleGET_Transaction);
1339 MockHttpRequest reader_request(kSimpleGET_Transaction);
1340 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1342 std::vector<Context*> context_list;
1343 const int kNumTransactions = 5;
1345 for (int i = 0; i < kNumTransactions; ++i) {
1346 context_list.push_back(new Context());
1347 Context* c = context_list[i];
1349 c->result = cache.CreateTransaction(&c->trans);
1350 ASSERT_EQ(net::OK, c->result);
1352 MockHttpRequest* this_request = &request;
1353 if (i == 1 || i == 2)
1354 this_request = &reader_request;
1356 c->result = c->trans->Start(
1357 this_request, c->callback.callback(), net::BoundNetLog());
1360 // Allow all requests to move from the Create queue to the active entry.
1361 base::MessageLoop::current()->RunUntilIdle();
1363 // The first request should be a writer at this point, and the subsequent
1364 // requests should be pending.
1366 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1367 EXPECT_EQ(0, cache.disk_cache()->open_count());
1368 EXPECT_EQ(1, cache.disk_cache()->create_count());
1370 Context* c = context_list[0];
1371 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1372 c->result = c->callback.WaitForResult();
1373 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1375 // Now we have 2 active readers and two queued transactions.
1377 EXPECT_EQ(net::LOAD_STATE_IDLE,
1378 context_list[2]->trans->GetLoadState());
1379 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1380 context_list[3]->trans->GetLoadState());
1382 c = context_list[1];
1383 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1384 c->result = c->callback.WaitForResult();
1385 if (c->result == net::OK)
1386 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1388 // At this point we have one reader, two pending transactions and a task on
1389 // the queue to move to the next transaction. Now we cancel the request that
1390 // is the current reader, and expect the queued task to be able to start the
1391 // next request.
1393 c = context_list[2];
1394 c->trans.reset();
1396 for (int i = 3; i < kNumTransactions; ++i) {
1397 Context* c = context_list[i];
1398 if (c->result == net::ERR_IO_PENDING)
1399 c->result = c->callback.WaitForResult();
1400 if (c->result == net::OK)
1401 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1404 // We should not have had to re-open the disk entry.
1406 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1407 EXPECT_EQ(0, cache.disk_cache()->open_count());
1408 EXPECT_EQ(1, cache.disk_cache()->create_count());
1410 for (int i = 0; i < kNumTransactions; ++i) {
1411 Context* c = context_list[i];
1412 delete c;
1416 // Tests that we can doom an entry with pending transactions and delete one of
1417 // the pending transactions before the first one completes.
1418 // See http://code.google.com/p/chromium/issues/detail?id=25588
1419 TEST(HttpCache, SimpleGET_DoomWithPending) {
1420 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1421 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1423 MockHttpRequest request(kSimpleGET_Transaction);
1424 MockHttpRequest writer_request(kSimpleGET_Transaction);
1425 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1427 ScopedVector<Context> context_list;
1428 const int kNumTransactions = 4;
1430 for (int i = 0; i < kNumTransactions; ++i) {
1431 context_list.push_back(new Context());
1432 Context* c = context_list[i];
1434 c->result = cache.CreateTransaction(&c->trans);
1435 ASSERT_EQ(net::OK, c->result);
1437 MockHttpRequest* this_request = &request;
1438 if (i == 3)
1439 this_request = &writer_request;
1441 c->result = c->trans->Start(
1442 this_request, c->callback.callback(), net::BoundNetLog());
1445 // The first request should be a writer at this point, and the two subsequent
1446 // requests should be pending. The last request doomed the first entry.
1448 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1450 // Cancel the first queued transaction.
1451 delete context_list[1];
1452 context_list.get()[1] = NULL;
1454 for (int i = 0; i < kNumTransactions; ++i) {
1455 if (i == 1)
1456 continue;
1457 Context* c = context_list[i];
1458 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1459 c->result = c->callback.WaitForResult();
1460 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1464 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1465 // We may attempt to delete an entry synchronously with the act of adding a new
1466 // transaction to said entry.
1467 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1468 MockHttpCache cache;
1470 // The headers will be served right from the call to Start() the request.
1471 MockHttpRequest request(kFastNoStoreGET_Transaction);
1472 FastTransactionServer request_handler;
1473 AddMockTransaction(&kFastNoStoreGET_Transaction);
1475 std::vector<Context*> context_list;
1476 const int kNumTransactions = 3;
1478 for (int i = 0; i < kNumTransactions; ++i) {
1479 context_list.push_back(new Context());
1480 Context* c = context_list[i];
1482 c->result = cache.CreateTransaction(&c->trans);
1483 ASSERT_EQ(net::OK, c->result);
1485 c->result = c->trans->Start(
1486 &request, c->callback.callback(), net::BoundNetLog());
1489 // Allow all requests to move from the Create queue to the active entry.
1490 base::MessageLoop::current()->RunUntilIdle();
1492 // The first request should be a writer at this point, and the subsequent
1493 // requests should be pending.
1495 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1496 EXPECT_EQ(0, cache.disk_cache()->open_count());
1497 EXPECT_EQ(1, cache.disk_cache()->create_count());
1499 // Now, make sure that the second request asks for the entry not to be stored.
1500 request_handler.set_no_store(true);
1502 for (int i = 0; i < kNumTransactions; ++i) {
1503 Context* c = context_list[i];
1504 if (c->result == net::ERR_IO_PENDING)
1505 c->result = c->callback.WaitForResult();
1506 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1507 delete c;
1510 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1511 EXPECT_EQ(0, cache.disk_cache()->open_count());
1512 EXPECT_EQ(2, cache.disk_cache()->create_count());
1514 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1517 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1518 MockHttpCache cache;
1520 MockHttpRequest request(kSimpleGET_Transaction);
1522 std::vector<Context*> context_list;
1523 const int kNumTransactions = 2;
1525 for (int i = 0; i < kNumTransactions; ++i) {
1526 context_list.push_back(new Context());
1527 Context* c = context_list[i];
1529 c->result = cache.CreateTransaction(&c->trans);
1530 ASSERT_EQ(net::OK, c->result);
1532 c->result = c->trans->Start(
1533 &request, c->callback.callback(), net::BoundNetLog());
1536 // Allow all requests to move from the Create queue to the active entry.
1537 base::MessageLoop::current()->RunUntilIdle();
1539 // The first request should be a writer at this point, and the subsequent
1540 // requests should be pending.
1542 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1543 EXPECT_EQ(0, cache.disk_cache()->open_count());
1544 EXPECT_EQ(1, cache.disk_cache()->create_count());
1546 for (int i = 0; i < kNumTransactions; ++i) {
1547 Context* c = context_list[i];
1548 if (c->result == net::ERR_IO_PENDING)
1549 c->result = c->callback.WaitForResult();
1550 // Destroy only the first transaction.
1551 if (i == 0) {
1552 delete c;
1553 context_list[i] = NULL;
1557 // Complete the rest of the transactions.
1558 for (int i = 1; i < kNumTransactions; ++i) {
1559 Context* c = context_list[i];
1560 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1563 // We should have had to re-open the disk entry.
1565 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1566 EXPECT_EQ(0, cache.disk_cache()->open_count());
1567 EXPECT_EQ(2, cache.disk_cache()->create_count());
1569 for (int i = 1; i < kNumTransactions; ++i) {
1570 Context* c = context_list[i];
1571 delete c;
1575 // Tests that we can cancel requests that are queued waiting to open the disk
1576 // cache entry.
1577 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1578 MockHttpCache cache;
1580 MockHttpRequest request(kSimpleGET_Transaction);
1582 std::vector<Context*> context_list;
1583 const int kNumTransactions = 5;
1585 for (int i = 0; i < kNumTransactions; i++) {
1586 context_list.push_back(new Context());
1587 Context* c = context_list[i];
1589 c->result = cache.CreateTransaction(&c->trans);
1590 ASSERT_EQ(net::OK, c->result);
1592 c->result = c->trans->Start(
1593 &request, c->callback.callback(), net::BoundNetLog());
1596 // The first request should be creating the disk cache entry and the others
1597 // should be pending.
1599 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1600 EXPECT_EQ(0, cache.disk_cache()->open_count());
1601 EXPECT_EQ(1, cache.disk_cache()->create_count());
1603 // Cancel a request from the pending queue.
1604 delete context_list[3];
1605 context_list[3] = NULL;
1607 // Cancel the request that is creating the entry. This will force the pending
1608 // operations to restart.
1609 delete context_list[0];
1610 context_list[0] = NULL;
1612 // Complete the rest of the transactions.
1613 for (int i = 1; i < kNumTransactions; i++) {
1614 Context* c = context_list[i];
1615 if (c) {
1616 c->result = c->callback.GetResult(c->result);
1617 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1621 // We should have had to re-create the disk entry.
1623 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1624 EXPECT_EQ(0, cache.disk_cache()->open_count());
1625 EXPECT_EQ(2, cache.disk_cache()->create_count());
1627 for (int i = 1; i < kNumTransactions; ++i) {
1628 delete context_list[i];
1632 // Tests that we can cancel a single request to open a disk cache entry.
1633 TEST(HttpCache, SimpleGET_CancelCreate) {
1634 MockHttpCache cache;
1636 MockHttpRequest request(kSimpleGET_Transaction);
1638 Context* c = new Context();
1640 c->result = cache.CreateTransaction(&c->trans);
1641 ASSERT_EQ(net::OK, c->result);
1643 c->result = c->trans->Start(
1644 &request, c->callback.callback(), net::BoundNetLog());
1645 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1647 // Release the reference that the mock disk cache keeps for this entry, so
1648 // that we test that the http cache handles the cancellation correctly.
1649 cache.disk_cache()->ReleaseAll();
1650 delete c;
1652 base::MessageLoop::current()->RunUntilIdle();
1653 EXPECT_EQ(1, cache.disk_cache()->create_count());
1656 // Tests that we delete/create entries even if multiple requests are queued.
1657 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1658 MockHttpCache cache;
1660 MockHttpRequest request(kSimpleGET_Transaction);
1661 request.load_flags = net::LOAD_BYPASS_CACHE;
1663 std::vector<Context*> context_list;
1664 const int kNumTransactions = 5;
1666 for (int i = 0; i < kNumTransactions; i++) {
1667 context_list.push_back(new Context());
1668 Context* c = context_list[i];
1670 c->result = cache.CreateTransaction(&c->trans);
1671 ASSERT_EQ(net::OK, c->result);
1673 c->result = c->trans->Start(
1674 &request, c->callback.callback(), net::BoundNetLog());
1677 // The first request should be deleting the disk cache entry and the others
1678 // should be pending.
1680 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1681 EXPECT_EQ(0, cache.disk_cache()->open_count());
1682 EXPECT_EQ(0, cache.disk_cache()->create_count());
1684 // Complete the transactions.
1685 for (int i = 0; i < kNumTransactions; i++) {
1686 Context* c = context_list[i];
1687 c->result = c->callback.GetResult(c->result);
1688 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1691 // We should have had to re-create the disk entry multiple times.
1693 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1694 EXPECT_EQ(0, cache.disk_cache()->open_count());
1695 EXPECT_EQ(5, cache.disk_cache()->create_count());
1697 for (int i = 0; i < kNumTransactions; ++i) {
1698 delete context_list[i];
1702 // Tests that a (simulated) timeout allows transactions waiting on the cache
1703 // lock to continue.
1704 TEST(HttpCache, SimpleGET_WriterTimeout) {
1705 MockHttpCache cache;
1706 cache.BypassCacheLock();
1708 MockHttpRequest request(kSimpleGET_Transaction);
1709 Context c1, c2;
1710 ASSERT_EQ(net::OK, cache.CreateTransaction(&c1.trans));
1711 ASSERT_EQ(net::ERR_IO_PENDING,
1712 c1.trans->Start(&request, c1.callback.callback(),
1713 net::BoundNetLog()));
1714 ASSERT_EQ(net::OK, cache.CreateTransaction(&c2.trans));
1715 ASSERT_EQ(net::ERR_IO_PENDING,
1716 c2.trans->Start(&request, c2.callback.callback(),
1717 net::BoundNetLog()));
1719 // The second request is queued after the first one.
1721 c2.callback.WaitForResult();
1722 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1724 // Complete the first transaction.
1725 c1.callback.WaitForResult();
1726 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1729 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1730 MockHttpCache cache;
1732 // write to the cache
1733 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1735 MockHttpRequest request(kSimpleGET_Transaction);
1736 net::TestCompletionCallback callback;
1738 scoped_ptr<net::HttpTransaction> trans;
1739 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
1740 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1741 if (rv == net::ERR_IO_PENDING)
1742 rv = callback.WaitForResult();
1743 ASSERT_EQ(net::OK, rv);
1745 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1746 rv = trans->Read(buf.get(), 256, callback.callback());
1747 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1749 // Test that destroying the transaction while it is reading from the cache
1750 // works properly.
1751 trans.reset();
1753 // Make sure we pump any pending events, which should include a call to
1754 // HttpCache::Transaction::OnCacheReadCompleted.
1755 base::MessageLoop::current()->RunUntilIdle();
1758 // Tests that we can delete the HttpCache and deal with queued transactions
1759 // ("waiting for the backend" as opposed to Active or Doomed entries).
1760 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1761 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1762 new MockBackendNoCbFactory()));
1764 MockHttpRequest request(kSimpleGET_Transaction);
1766 std::vector<Context*> context_list;
1767 const int kNumTransactions = 5;
1769 for (int i = 0; i < kNumTransactions; i++) {
1770 context_list.push_back(new Context());
1771 Context* c = context_list[i];
1773 c->result = cache->CreateTransaction(&c->trans);
1774 ASSERT_EQ(net::OK, c->result);
1776 c->result = c->trans->Start(
1777 &request, c->callback.callback(), net::BoundNetLog());
1780 // The first request should be creating the disk cache entry and the others
1781 // should be pending.
1783 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1784 EXPECT_EQ(0, cache->disk_cache()->open_count());
1785 EXPECT_EQ(0, cache->disk_cache()->create_count());
1787 cache.reset();
1789 // There is not much to do with the transactions at this point... they are
1790 // waiting for a callback that will not fire.
1791 for (int i = 0; i < kNumTransactions; ++i) {
1792 delete context_list[i];
1796 // Tests that we queue requests when initializing the backend.
1797 TEST(HttpCache, SimpleGET_WaitForBackend) {
1798 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1799 MockHttpCache cache(factory);
1801 MockHttpRequest request0(kSimpleGET_Transaction);
1802 MockHttpRequest request1(kTypicalGET_Transaction);
1803 MockHttpRequest request2(kETagGET_Transaction);
1805 std::vector<Context*> context_list;
1806 const int kNumTransactions = 3;
1808 for (int i = 0; i < kNumTransactions; i++) {
1809 context_list.push_back(new Context());
1810 Context* c = context_list[i];
1812 c->result = cache.CreateTransaction(&c->trans);
1813 ASSERT_EQ(net::OK, c->result);
1816 context_list[0]->result = context_list[0]->trans->Start(
1817 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1818 context_list[1]->result = context_list[1]->trans->Start(
1819 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1820 context_list[2]->result = context_list[2]->trans->Start(
1821 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1823 // Just to make sure that everything is still pending.
1824 base::MessageLoop::current()->RunUntilIdle();
1826 // The first request should be creating the disk cache.
1827 EXPECT_FALSE(context_list[0]->callback.have_result());
1829 factory->FinishCreation();
1831 base::MessageLoop::current()->RunUntilIdle();
1832 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1833 EXPECT_EQ(3, cache.disk_cache()->create_count());
1835 for (int i = 0; i < kNumTransactions; ++i) {
1836 EXPECT_TRUE(context_list[i]->callback.have_result());
1837 delete context_list[i];
1841 // Tests that we can cancel requests that are queued waiting for the backend
1842 // to be initialized.
1843 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1844 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1845 MockHttpCache cache(factory);
1847 MockHttpRequest request0(kSimpleGET_Transaction);
1848 MockHttpRequest request1(kTypicalGET_Transaction);
1849 MockHttpRequest request2(kETagGET_Transaction);
1851 std::vector<Context*> context_list;
1852 const int kNumTransactions = 3;
1854 for (int i = 0; i < kNumTransactions; i++) {
1855 context_list.push_back(new Context());
1856 Context* c = context_list[i];
1858 c->result = cache.CreateTransaction(&c->trans);
1859 ASSERT_EQ(net::OK, c->result);
1862 context_list[0]->result = context_list[0]->trans->Start(
1863 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1864 context_list[1]->result = context_list[1]->trans->Start(
1865 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1866 context_list[2]->result = context_list[2]->trans->Start(
1867 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1869 // Just to make sure that everything is still pending.
1870 base::MessageLoop::current()->RunUntilIdle();
1872 // The first request should be creating the disk cache.
1873 EXPECT_FALSE(context_list[0]->callback.have_result());
1875 // Cancel a request from the pending queue.
1876 delete context_list[1];
1877 context_list[1] = NULL;
1879 // Cancel the request that is creating the entry.
1880 delete context_list[0];
1881 context_list[0] = NULL;
1883 // Complete the last transaction.
1884 factory->FinishCreation();
1886 context_list[2]->result =
1887 context_list[2]->callback.GetResult(context_list[2]->result);
1888 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1890 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1891 EXPECT_EQ(1, cache.disk_cache()->create_count());
1893 delete context_list[2];
1896 // Tests that we can delete the cache while creating the backend.
1897 TEST(HttpCache, DeleteCacheWaitingForBackend) {
1898 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1899 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1901 MockHttpRequest request(kSimpleGET_Transaction);
1903 scoped_ptr<Context> c(new Context());
1904 c->result = cache->CreateTransaction(&c->trans);
1905 ASSERT_EQ(net::OK, c->result);
1907 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1909 // Just to make sure that everything is still pending.
1910 base::MessageLoop::current()->RunUntilIdle();
1912 // The request should be creating the disk cache.
1913 EXPECT_FALSE(c->callback.have_result());
1915 // We cannot call FinishCreation because the factory itself will go away with
1916 // the cache, so grab the callback and attempt to use it.
1917 net::CompletionCallback callback = factory->callback();
1918 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1920 cache.reset();
1921 base::MessageLoop::current()->RunUntilIdle();
1923 backend->reset();
1924 callback.Run(net::ERR_ABORTED);
1927 // Tests that we can delete the cache while creating the backend, from within
1928 // one of the callbacks.
1929 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1930 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1931 MockHttpCache* cache = new MockHttpCache(factory);
1933 DeleteCacheCompletionCallback cb(cache);
1934 disk_cache::Backend* backend;
1935 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1936 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1938 // Now let's queue a regular transaction
1939 MockHttpRequest request(kSimpleGET_Transaction);
1941 scoped_ptr<Context> c(new Context());
1942 c->result = cache->CreateTransaction(&c->trans);
1943 ASSERT_EQ(net::OK, c->result);
1945 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1947 // And another direct backend request.
1948 net::TestCompletionCallback cb2;
1949 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1950 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1952 // Just to make sure that everything is still pending.
1953 base::MessageLoop::current()->RunUntilIdle();
1955 // The request should be queued.
1956 EXPECT_FALSE(c->callback.have_result());
1958 // Generate the callback.
1959 factory->FinishCreation();
1960 rv = cb.WaitForResult();
1962 // The cache should be gone by now.
1963 base::MessageLoop::current()->RunUntilIdle();
1964 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1965 EXPECT_FALSE(cb2.have_result());
1968 TEST(HttpCache, TypicalGET_ConditionalRequest) {
1969 MockHttpCache cache;
1971 // write to the cache
1972 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1974 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1975 EXPECT_EQ(0, cache.disk_cache()->open_count());
1976 EXPECT_EQ(1, cache.disk_cache()->create_count());
1978 // Get the same URL again, but this time we expect it to result
1979 // in a conditional request.
1980 net::CapturingBoundNetLog log;
1981 net::LoadTimingInfo load_timing_info;
1982 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1983 log.bound(), &load_timing_info);
1985 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1986 EXPECT_EQ(1, cache.disk_cache()->open_count());
1987 EXPECT_EQ(1, cache.disk_cache()->create_count());
1988 TestLoadTimingNetworkRequest(load_timing_info);
1991 static void ETagGet_ConditionalRequest_Handler(
1992 const net::HttpRequestInfo* request,
1993 std::string* response_status,
1994 std::string* response_headers,
1995 std::string* response_data) {
1996 EXPECT_TRUE(
1997 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
1998 response_status->assign("HTTP/1.1 304 Not Modified");
1999 response_headers->assign(kETagGET_Transaction.response_headers);
2000 response_data->clear();
2003 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2004 MockHttpCache cache;
2006 ScopedMockTransaction transaction(kETagGET_Transaction);
2008 // write to the cache
2009 RunTransactionTest(cache.http_cache(), transaction);
2011 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2012 EXPECT_EQ(0, cache.disk_cache()->open_count());
2013 EXPECT_EQ(1, cache.disk_cache()->create_count());
2015 // Get the same URL again, but this time we expect it to result
2016 // in a conditional request.
2017 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2018 transaction.handler = ETagGet_ConditionalRequest_Handler;
2019 net::CapturingBoundNetLog log;
2020 net::LoadTimingInfo load_timing_info;
2021 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2022 &load_timing_info);
2024 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2025 EXPECT_EQ(1, cache.disk_cache()->open_count());
2026 EXPECT_EQ(1, cache.disk_cache()->create_count());
2027 TestLoadTimingNetworkRequest(load_timing_info);
2030 class RevalidationServer {
2031 public:
2032 RevalidationServer() {
2033 s_etag_used_ = false;
2034 s_last_modified_used_ = false;
2037 bool EtagUsed() { return s_etag_used_; }
2038 bool LastModifiedUsed() { return s_last_modified_used_; }
2040 static void Handler(const net::HttpRequestInfo* request,
2041 std::string* response_status,
2042 std::string* response_headers,
2043 std::string* response_data);
2045 private:
2046 static bool s_etag_used_;
2047 static bool s_last_modified_used_;
2049 bool RevalidationServer::s_etag_used_ = false;
2050 bool RevalidationServer::s_last_modified_used_ = false;
2052 void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2053 std::string* response_status,
2054 std::string* response_headers,
2055 std::string* response_data) {
2056 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2057 s_etag_used_ = true;
2059 if (request->extra_headers.HasHeader(
2060 net::HttpRequestHeaders::kIfModifiedSince)) {
2061 s_last_modified_used_ = true;
2064 if (s_etag_used_ || s_last_modified_used_) {
2065 response_status->assign("HTTP/1.1 304 Not Modified");
2066 response_headers->assign(kTypicalGET_Transaction.response_headers);
2067 response_data->clear();
2068 } else {
2069 response_status->assign(kTypicalGET_Transaction.status);
2070 response_headers->assign(kTypicalGET_Transaction.response_headers);
2071 response_data->assign(kTypicalGET_Transaction.data);
2075 // Tests revalidation after a vary match.
2076 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2077 MockHttpCache cache;
2079 // Write to the cache.
2080 MockTransaction transaction(kTypicalGET_Transaction);
2081 transaction.request_headers = "Foo: bar\r\n";
2082 transaction.response_headers =
2083 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2084 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2085 "Etag: \"foopy\"\n"
2086 "Cache-Control: max-age=0\n"
2087 "Vary: Foo\n";
2088 AddMockTransaction(&transaction);
2089 RunTransactionTest(cache.http_cache(), transaction);
2091 // Read from the cache.
2092 RevalidationServer server;
2093 transaction.handler = server.Handler;
2094 net::CapturingBoundNetLog log;
2095 net::LoadTimingInfo load_timing_info;
2096 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2097 &load_timing_info);
2099 EXPECT_TRUE(server.EtagUsed());
2100 EXPECT_TRUE(server.LastModifiedUsed());
2101 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2102 EXPECT_EQ(1, cache.disk_cache()->open_count());
2103 EXPECT_EQ(1, cache.disk_cache()->create_count());
2104 TestLoadTimingNetworkRequest(load_timing_info);
2105 RemoveMockTransaction(&transaction);
2108 // Tests revalidation after a vary mismatch if etag is present.
2109 TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2110 MockHttpCache cache;
2112 // Write to the cache.
2113 MockTransaction transaction(kTypicalGET_Transaction);
2114 transaction.request_headers = "Foo: bar\r\n";
2115 transaction.response_headers =
2116 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2117 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2118 "Etag: \"foopy\"\n"
2119 "Cache-Control: max-age=0\n"
2120 "Vary: Foo\n";
2121 AddMockTransaction(&transaction);
2122 RunTransactionTest(cache.http_cache(), transaction);
2124 // Read from the cache and revalidate the entry.
2125 RevalidationServer server;
2126 transaction.handler = server.Handler;
2127 transaction.request_headers = "Foo: none\r\n";
2128 net::CapturingBoundNetLog log;
2129 net::LoadTimingInfo load_timing_info;
2130 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2131 &load_timing_info);
2133 EXPECT_TRUE(server.EtagUsed());
2134 EXPECT_FALSE(server.LastModifiedUsed());
2135 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2136 EXPECT_EQ(1, cache.disk_cache()->open_count());
2137 EXPECT_EQ(1, cache.disk_cache()->create_count());
2138 TestLoadTimingNetworkRequest(load_timing_info);
2139 RemoveMockTransaction(&transaction);
2142 // Tests lack of revalidation after a vary mismatch and no etag.
2143 TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2144 MockHttpCache cache;
2146 // Write to the cache.
2147 MockTransaction transaction(kTypicalGET_Transaction);
2148 transaction.request_headers = "Foo: bar\r\n";
2149 transaction.response_headers =
2150 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2151 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2152 "Cache-Control: max-age=0\n"
2153 "Vary: Foo\n";
2154 AddMockTransaction(&transaction);
2155 RunTransactionTest(cache.http_cache(), transaction);
2157 // Read from the cache and don't revalidate the entry.
2158 RevalidationServer server;
2159 transaction.handler = server.Handler;
2160 transaction.request_headers = "Foo: none\r\n";
2161 net::CapturingBoundNetLog log;
2162 net::LoadTimingInfo load_timing_info;
2163 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2164 &load_timing_info);
2166 EXPECT_FALSE(server.EtagUsed());
2167 EXPECT_FALSE(server.LastModifiedUsed());
2168 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2169 EXPECT_EQ(1, cache.disk_cache()->open_count());
2170 EXPECT_EQ(1, cache.disk_cache()->create_count());
2171 TestLoadTimingNetworkRequest(load_timing_info);
2172 RemoveMockTransaction(&transaction);
2175 static void ETagGet_UnconditionalRequest_Handler(
2176 const net::HttpRequestInfo* request,
2177 std::string* response_status,
2178 std::string* response_headers,
2179 std::string* response_data) {
2180 EXPECT_FALSE(
2181 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2184 TEST(HttpCache, ETagGET_Http10) {
2185 MockHttpCache cache;
2187 ScopedMockTransaction transaction(kETagGET_Transaction);
2188 transaction.status = "HTTP/1.0 200 OK";
2190 // Write to the cache.
2191 RunTransactionTest(cache.http_cache(), transaction);
2193 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2194 EXPECT_EQ(0, cache.disk_cache()->open_count());
2195 EXPECT_EQ(1, cache.disk_cache()->create_count());
2197 // Get the same URL again, without generating a conditional request.
2198 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2199 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2200 RunTransactionTest(cache.http_cache(), transaction);
2202 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2203 EXPECT_EQ(1, cache.disk_cache()->open_count());
2204 EXPECT_EQ(1, cache.disk_cache()->create_count());
2207 TEST(HttpCache, ETagGET_Http10_Range) {
2208 MockHttpCache cache;
2210 ScopedMockTransaction transaction(kETagGET_Transaction);
2211 transaction.status = "HTTP/1.0 200 OK";
2213 // Write to the cache.
2214 RunTransactionTest(cache.http_cache(), transaction);
2216 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2217 EXPECT_EQ(0, cache.disk_cache()->open_count());
2218 EXPECT_EQ(1, cache.disk_cache()->create_count());
2220 // Get the same URL again, but use a byte range request.
2221 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2222 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2223 transaction.request_headers = "Range: bytes = 5-\r\n";
2224 RunTransactionTest(cache.http_cache(), transaction);
2226 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2227 EXPECT_EQ(1, cache.disk_cache()->open_count());
2228 EXPECT_EQ(2, cache.disk_cache()->create_count());
2231 static void ETagGet_ConditionalRequest_NoStore_Handler(
2232 const net::HttpRequestInfo* request,
2233 std::string* response_status,
2234 std::string* response_headers,
2235 std::string* response_data) {
2236 EXPECT_TRUE(
2237 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2238 response_status->assign("HTTP/1.1 304 Not Modified");
2239 response_headers->assign("Cache-Control: no-store\n");
2240 response_data->clear();
2243 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2244 MockHttpCache cache;
2246 ScopedMockTransaction transaction(kETagGET_Transaction);
2248 // Write to the cache.
2249 RunTransactionTest(cache.http_cache(), transaction);
2251 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2252 EXPECT_EQ(0, cache.disk_cache()->open_count());
2253 EXPECT_EQ(1, cache.disk_cache()->create_count());
2255 // Get the same URL again, but this time we expect it to result
2256 // in a conditional request.
2257 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2258 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2259 RunTransactionTest(cache.http_cache(), transaction);
2261 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2262 EXPECT_EQ(1, cache.disk_cache()->open_count());
2263 EXPECT_EQ(1, cache.disk_cache()->create_count());
2265 ScopedMockTransaction transaction2(kETagGET_Transaction);
2267 // Write to the cache again. This should create a new entry.
2268 RunTransactionTest(cache.http_cache(), transaction2);
2270 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2271 EXPECT_EQ(1, cache.disk_cache()->open_count());
2272 EXPECT_EQ(2, cache.disk_cache()->create_count());
2275 // Helper that does 4 requests using HttpCache:
2277 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2278 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2279 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2280 // be returned.
2281 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2282 // returned.
2283 static void ConditionalizedRequestUpdatesCacheHelper(
2284 const Response& net_response_1,
2285 const Response& net_response_2,
2286 const Response& cached_response_2,
2287 const char* extra_request_headers) {
2288 MockHttpCache cache;
2290 // The URL we will be requesting.
2291 const char* kUrl = "http://foobar.com/main.css";
2293 // Junk network response.
2294 static const Response kUnexpectedResponse = {
2295 "HTTP/1.1 500 Unexpected",
2296 "Server: unexpected_header",
2297 "unexpected body"
2300 // We will control the network layer's responses for |kUrl| using
2301 // |mock_network_response|.
2302 MockTransaction mock_network_response = { 0 };
2303 mock_network_response.url = kUrl;
2304 AddMockTransaction(&mock_network_response);
2306 // Request |kUrl| for the first time. It should hit the network and
2307 // receive |kNetResponse1|, which it saves into the HTTP cache.
2309 MockTransaction request = { 0 };
2310 request.url = kUrl;
2311 request.method = "GET";
2312 request.request_headers = "";
2314 net_response_1.AssignTo(&mock_network_response); // Network mock.
2315 net_response_1.AssignTo(&request); // Expected result.
2317 std::string response_headers;
2318 RunTransactionTestWithResponse(
2319 cache.http_cache(), request, &response_headers);
2321 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2322 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2323 EXPECT_EQ(0, cache.disk_cache()->open_count());
2324 EXPECT_EQ(1, cache.disk_cache()->create_count());
2326 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2327 // cache, so we don't hit the network.
2329 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2331 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2332 net_response_1.AssignTo(&request); // Expected result.
2334 RunTransactionTestWithResponse(
2335 cache.http_cache(), request, &response_headers);
2337 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2338 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2339 EXPECT_EQ(1, cache.disk_cache()->open_count());
2340 EXPECT_EQ(1, cache.disk_cache()->create_count());
2342 // Request |kUrl| yet again, but this time give the request an
2343 // "If-Modified-Since" header. This will cause the request to re-hit the
2344 // network. However now the network response is going to be
2345 // different -- this simulates a change made to the CSS file.
2347 request.request_headers = extra_request_headers;
2348 request.load_flags = net::LOAD_NORMAL;
2350 net_response_2.AssignTo(&mock_network_response); // Network mock.
2351 net_response_2.AssignTo(&request); // Expected result.
2353 RunTransactionTestWithResponse(
2354 cache.http_cache(), request, &response_headers);
2356 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2357 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2358 EXPECT_EQ(1, cache.disk_cache()->open_count());
2359 EXPECT_EQ(1, cache.disk_cache()->create_count());
2361 // Finally, request |kUrl| again. This request should be serviced from
2362 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2363 // and NOT |kNetResponse1|. The previous step should have replaced the
2364 // value in the cache with the modified response.
2366 request.request_headers = "";
2367 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2369 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2370 cached_response_2.AssignTo(&request); // Expected result.
2372 RunTransactionTestWithResponse(
2373 cache.http_cache(), request, &response_headers);
2375 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2376 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2377 EXPECT_EQ(2, cache.disk_cache()->open_count());
2378 EXPECT_EQ(1, cache.disk_cache()->create_count());
2380 RemoveMockTransaction(&mock_network_response);
2383 // Check that when an "if-modified-since" header is attached
2384 // to the request, the result still updates the cached entry.
2385 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2386 // First network response for |kUrl|.
2387 static const Response kNetResponse1 = {
2388 "HTTP/1.1 200 OK",
2389 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2390 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2391 "body1"
2394 // Second network response for |kUrl|.
2395 static const Response kNetResponse2 = {
2396 "HTTP/1.1 200 OK",
2397 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2398 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2399 "body2"
2402 const char* extra_headers =
2403 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2405 ConditionalizedRequestUpdatesCacheHelper(
2406 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2409 // Check that when an "if-none-match" header is attached
2410 // to the request, the result updates the cached entry.
2411 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2412 // First network response for |kUrl|.
2413 static const Response kNetResponse1 = {
2414 "HTTP/1.1 200 OK",
2415 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2416 "Etag: \"ETAG1\"\n"
2417 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2418 "body1"
2421 // Second network response for |kUrl|.
2422 static const Response kNetResponse2 = {
2423 "HTTP/1.1 200 OK",
2424 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2425 "Etag: \"ETAG2\"\n"
2426 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2427 "body2"
2430 const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
2432 ConditionalizedRequestUpdatesCacheHelper(
2433 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2436 // Check that when an "if-modified-since" header is attached
2437 // to a request, the 304 (not modified result) result updates the cached
2438 // headers, and the 304 response is returned rather than the cached response.
2439 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2440 // First network response for |kUrl|.
2441 static const Response kNetResponse1 = {
2442 "HTTP/1.1 200 OK",
2443 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2444 "Server: server1\n"
2445 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2446 "body1"
2449 // Second network response for |kUrl|.
2450 static const Response kNetResponse2 = {
2451 "HTTP/1.1 304 Not Modified",
2452 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2453 "Server: server2\n"
2454 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2458 static const Response kCachedResponse2 = {
2459 "HTTP/1.1 200 OK",
2460 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2461 "Server: server2\n"
2462 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2463 "body1"
2466 const char* extra_headers =
2467 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2469 ConditionalizedRequestUpdatesCacheHelper(
2470 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2473 // Test that when doing an externally conditionalized if-modified-since
2474 // and there is no corresponding cache entry, a new cache entry is NOT
2475 // created (304 response).
2476 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2477 MockHttpCache cache;
2479 const char* kUrl = "http://foobar.com/main.css";
2481 static const Response kNetResponse = {
2482 "HTTP/1.1 304 Not Modified",
2483 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2484 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2488 const char* kExtraRequestHeaders =
2489 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2491 // We will control the network layer's responses for |kUrl| using
2492 // |mock_network_response|.
2493 MockTransaction mock_network_response = { 0 };
2494 mock_network_response.url = kUrl;
2495 AddMockTransaction(&mock_network_response);
2497 MockTransaction request = { 0 };
2498 request.url = kUrl;
2499 request.method = "GET";
2500 request.request_headers = kExtraRequestHeaders;
2502 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2503 kNetResponse.AssignTo(&request); // Expected result.
2505 std::string response_headers;
2506 RunTransactionTestWithResponse(
2507 cache.http_cache(), request, &response_headers);
2509 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2510 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2511 EXPECT_EQ(0, cache.disk_cache()->open_count());
2512 EXPECT_EQ(0, cache.disk_cache()->create_count());
2514 RemoveMockTransaction(&mock_network_response);
2517 // Test that when doing an externally conditionalized if-modified-since
2518 // and there is no corresponding cache entry, a new cache entry is NOT
2519 // created (200 response).
2520 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2521 MockHttpCache cache;
2523 const char* kUrl = "http://foobar.com/main.css";
2525 static const Response kNetResponse = {
2526 "HTTP/1.1 200 OK",
2527 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2528 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2529 "foobar!!!"
2532 const char* kExtraRequestHeaders =
2533 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2535 // We will control the network layer's responses for |kUrl| using
2536 // |mock_network_response|.
2537 MockTransaction mock_network_response = { 0 };
2538 mock_network_response.url = kUrl;
2539 AddMockTransaction(&mock_network_response);
2541 MockTransaction request = { 0 };
2542 request.url = kUrl;
2543 request.method = "GET";
2544 request.request_headers = kExtraRequestHeaders;
2546 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2547 kNetResponse.AssignTo(&request); // Expected result.
2549 std::string response_headers;
2550 RunTransactionTestWithResponse(
2551 cache.http_cache(), request, &response_headers);
2553 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2554 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2555 EXPECT_EQ(0, cache.disk_cache()->open_count());
2556 EXPECT_EQ(0, cache.disk_cache()->create_count());
2558 RemoveMockTransaction(&mock_network_response);
2561 // Test that when doing an externally conditionalized if-modified-since
2562 // if the date does not match the cache entry's last-modified date,
2563 // then we do NOT use the response (304) to update the cache.
2564 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2565 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2566 static const Response kNetResponse1 = {
2567 "HTTP/1.1 200 OK",
2568 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2569 "Server: server1\n"
2570 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2571 "body1"
2574 // Second network response for |kUrl|.
2575 static const Response kNetResponse2 = {
2576 "HTTP/1.1 304 Not Modified",
2577 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2578 "Server: server2\n"
2579 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2583 // This is two days in the future from the original response's last-modified
2584 // date!
2585 const char* kExtraRequestHeaders =
2586 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2588 ConditionalizedRequestUpdatesCacheHelper(
2589 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2592 // Test that when doing an externally conditionalized if-none-match
2593 // if the etag does not match the cache entry's etag, then we do not use the
2594 // response (304) to update the cache.
2595 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2596 static const Response kNetResponse1 = {
2597 "HTTP/1.1 200 OK",
2598 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2599 "Etag: \"Foo1\"\n"
2600 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2601 "body1"
2604 // Second network response for |kUrl|.
2605 static const Response kNetResponse2 = {
2606 "HTTP/1.1 304 Not Modified",
2607 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2608 "Etag: \"Foo2\"\n"
2609 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2613 // Different etag from original response.
2614 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
2616 ConditionalizedRequestUpdatesCacheHelper(
2617 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2620 // Test that doing an externally conditionalized request with both if-none-match
2621 // and if-modified-since updates the cache.
2622 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2623 static const Response kNetResponse1 = {
2624 "HTTP/1.1 200 OK",
2625 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2626 "Etag: \"Foo1\"\n"
2627 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2628 "body1"
2631 // Second network response for |kUrl|.
2632 static const Response kNetResponse2 = {
2633 "HTTP/1.1 200 OK",
2634 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2635 "Etag: \"Foo2\"\n"
2636 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2637 "body2"
2640 const char* kExtraRequestHeaders =
2641 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2642 "If-None-Match: \"Foo1\"\r\n";
2644 ConditionalizedRequestUpdatesCacheHelper(
2645 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2648 // Test that doing an externally conditionalized request with both if-none-match
2649 // and if-modified-since does not update the cache with only one match.
2650 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2651 static const Response kNetResponse1 = {
2652 "HTTP/1.1 200 OK",
2653 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2654 "Etag: \"Foo1\"\n"
2655 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2656 "body1"
2659 // Second network response for |kUrl|.
2660 static const Response kNetResponse2 = {
2661 "HTTP/1.1 200 OK",
2662 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2663 "Etag: \"Foo2\"\n"
2664 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2665 "body2"
2668 // The etag doesn't match what we have stored.
2669 const char* kExtraRequestHeaders =
2670 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2671 "If-None-Match: \"Foo2\"\r\n";
2673 ConditionalizedRequestUpdatesCacheHelper(
2674 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2677 // Test that doing an externally conditionalized request with both if-none-match
2678 // and if-modified-since does not update the cache with only one match.
2679 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2680 static const Response kNetResponse1 = {
2681 "HTTP/1.1 200 OK",
2682 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2683 "Etag: \"Foo1\"\n"
2684 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2685 "body1"
2688 // Second network response for |kUrl|.
2689 static const Response kNetResponse2 = {
2690 "HTTP/1.1 200 OK",
2691 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2692 "Etag: \"Foo2\"\n"
2693 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2694 "body2"
2697 // The modification date doesn't match what we have stored.
2698 const char* kExtraRequestHeaders =
2699 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2700 "If-None-Match: \"Foo1\"\r\n";
2702 ConditionalizedRequestUpdatesCacheHelper(
2703 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2706 TEST(HttpCache, UrlContainingHash) {
2707 MockHttpCache cache;
2709 // Do a typical GET request -- should write an entry into our cache.
2710 MockTransaction trans(kTypicalGET_Transaction);
2711 RunTransactionTest(cache.http_cache(), trans);
2713 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2714 EXPECT_EQ(0, cache.disk_cache()->open_count());
2715 EXPECT_EQ(1, cache.disk_cache()->create_count());
2717 // Request the same URL, but this time with a reference section (hash).
2718 // Since the cache key strips the hash sections, this should be a cache hit.
2719 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2720 trans.url = url_with_hash.c_str();
2721 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2723 RunTransactionTest(cache.http_cache(), trans);
2725 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2726 EXPECT_EQ(1, cache.disk_cache()->open_count());
2727 EXPECT_EQ(1, cache.disk_cache()->create_count());
2730 // Tests that we skip the cache for POST requests that do not have an upload
2731 // identifier.
2732 TEST(HttpCache, SimplePOST_SkipsCache) {
2733 MockHttpCache cache;
2735 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2737 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2738 EXPECT_EQ(0, cache.disk_cache()->open_count());
2739 EXPECT_EQ(0, cache.disk_cache()->create_count());
2742 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2743 MockHttpCache cache;
2745 MockTransaction transaction(kSimplePOST_Transaction);
2746 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2748 MockHttpRequest request(transaction);
2749 net::TestCompletionCallback callback;
2751 scoped_ptr<net::HttpTransaction> trans;
2752 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
2753 ASSERT_TRUE(trans.get());
2755 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
2756 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
2758 trans.reset();
2760 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2761 EXPECT_EQ(0, cache.disk_cache()->open_count());
2762 EXPECT_EQ(0, cache.disk_cache()->create_count());
2765 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2766 MockHttpCache cache;
2768 // Test that we hit the cache for POST requests.
2770 MockTransaction transaction(kSimplePOST_Transaction);
2772 const int64 kUploadId = 1; // Just a dummy value.
2774 ScopedVector<net::UploadElementReader> element_readers;
2775 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2776 net::UploadDataStream upload_data_stream(element_readers.Pass(), kUploadId);
2777 MockHttpRequest request(transaction);
2778 request.upload_data_stream = &upload_data_stream;
2780 // Populate the cache.
2781 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2783 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2784 EXPECT_EQ(0, cache.disk_cache()->open_count());
2785 EXPECT_EQ(1, cache.disk_cache()->create_count());
2787 // Load from cache.
2788 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2789 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2791 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2792 EXPECT_EQ(1, cache.disk_cache()->open_count());
2793 EXPECT_EQ(1, cache.disk_cache()->create_count());
2796 // Test that we don't hit the cache for POST requests if there is a byte range.
2797 TEST(HttpCache, SimplePOST_WithRanges) {
2798 MockHttpCache cache;
2800 MockTransaction transaction(kSimplePOST_Transaction);
2801 transaction.request_headers = "Range: bytes = 0-4\r\n";
2803 const int64 kUploadId = 1; // Just a dummy value.
2805 ScopedVector<net::UploadElementReader> element_readers;
2806 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2807 net::UploadDataStream upload_data_stream(element_readers.Pass(), kUploadId);
2809 MockHttpRequest request(transaction);
2810 request.upload_data_stream = &upload_data_stream;
2812 // Attempt to populate the cache.
2813 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2815 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2816 EXPECT_EQ(0, cache.disk_cache()->open_count());
2817 EXPECT_EQ(0, cache.disk_cache()->create_count());
2820 // Tests that a POST is cached separately from a previously cached GET.
2821 TEST(HttpCache, SimplePOST_SeparateCache) {
2822 MockHttpCache cache;
2824 ScopedVector<net::UploadElementReader> element_readers;
2825 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2826 net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
2828 MockTransaction transaction(kSimplePOST_Transaction);
2829 MockHttpRequest req1(transaction);
2830 req1.upload_data_stream = &upload_data_stream;
2832 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2834 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2835 EXPECT_EQ(0, cache.disk_cache()->open_count());
2836 EXPECT_EQ(1, cache.disk_cache()->create_count());
2838 transaction.method = "GET";
2839 MockHttpRequest req2(transaction);
2841 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2843 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2844 EXPECT_EQ(0, cache.disk_cache()->open_count());
2845 EXPECT_EQ(2, cache.disk_cache()->create_count());
2848 // Tests that a successful POST invalidates a previously cached GET.
2849 TEST(HttpCache, SimplePOST_Invalidate_205) {
2850 MockHttpCache cache;
2852 MockTransaction transaction(kSimpleGET_Transaction);
2853 AddMockTransaction(&transaction);
2854 MockHttpRequest req1(transaction);
2856 // Attempt to populate the cache.
2857 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2859 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2860 EXPECT_EQ(0, cache.disk_cache()->open_count());
2861 EXPECT_EQ(1, cache.disk_cache()->create_count());
2863 ScopedVector<net::UploadElementReader> element_readers;
2864 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2865 net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
2867 transaction.method = "POST";
2868 transaction.status = "HTTP/1.1 205 No Content";
2869 MockHttpRequest req2(transaction);
2870 req2.upload_data_stream = &upload_data_stream;
2872 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2874 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2875 EXPECT_EQ(0, cache.disk_cache()->open_count());
2876 EXPECT_EQ(2, cache.disk_cache()->create_count());
2878 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2880 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2881 EXPECT_EQ(0, cache.disk_cache()->open_count());
2882 EXPECT_EQ(3, cache.disk_cache()->create_count());
2883 RemoveMockTransaction(&transaction);
2886 // Tests that a successful POST invalidates a previously cached GET, even when
2887 // there is no upload identifier.
2888 TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
2889 MockHttpCache cache;
2891 MockTransaction transaction(kSimpleGET_Transaction);
2892 AddMockTransaction(&transaction);
2893 MockHttpRequest req1(transaction);
2895 // Attempt to populate the cache.
2896 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2899 EXPECT_EQ(0, cache.disk_cache()->open_count());
2900 EXPECT_EQ(1, cache.disk_cache()->create_count());
2902 ScopedVector<net::UploadElementReader> element_readers;
2903 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2904 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
2906 transaction.method = "POST";
2907 transaction.status = "HTTP/1.1 205 No Content";
2908 MockHttpRequest req2(transaction);
2909 req2.upload_data_stream = &upload_data_stream;
2911 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2913 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2914 EXPECT_EQ(0, cache.disk_cache()->open_count());
2915 EXPECT_EQ(1, cache.disk_cache()->create_count());
2917 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2919 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2920 EXPECT_EQ(0, cache.disk_cache()->open_count());
2921 EXPECT_EQ(2, cache.disk_cache()->create_count());
2922 RemoveMockTransaction(&transaction);
2925 // Tests that processing a POST before creating the backend doesn't crash.
2926 TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
2927 // This will initialize a cache object with NULL backend.
2928 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2929 factory->set_fail(true);
2930 factory->FinishCreation();
2931 MockHttpCache cache(factory);
2933 ScopedVector<net::UploadElementReader> element_readers;
2934 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2935 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
2937 MockTransaction transaction(kSimplePOST_Transaction);
2938 AddMockTransaction(&transaction);
2939 MockHttpRequest req(transaction);
2940 req.upload_data_stream = &upload_data_stream;
2942 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
2944 RemoveMockTransaction(&transaction);
2947 // Tests that we don't invalidate entries as a result of a failed POST.
2948 TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2949 MockHttpCache cache;
2951 MockTransaction transaction(kSimpleGET_Transaction);
2952 AddMockTransaction(&transaction);
2953 MockHttpRequest req1(transaction);
2955 // Attempt to populate the cache.
2956 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2958 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2959 EXPECT_EQ(0, cache.disk_cache()->open_count());
2960 EXPECT_EQ(1, cache.disk_cache()->create_count());
2962 ScopedVector<net::UploadElementReader> element_readers;
2963 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2964 net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
2966 transaction.method = "POST";
2967 transaction.status = "HTTP/1.1 100 Continue";
2968 MockHttpRequest req2(transaction);
2969 req2.upload_data_stream = &upload_data_stream;
2971 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2973 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2974 EXPECT_EQ(0, cache.disk_cache()->open_count());
2975 EXPECT_EQ(2, cache.disk_cache()->create_count());
2977 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2979 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2980 EXPECT_EQ(1, cache.disk_cache()->open_count());
2981 EXPECT_EQ(2, cache.disk_cache()->create_count());
2982 RemoveMockTransaction(&transaction);
2985 // Tests that a HEAD request is not cached by itself.
2986 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
2987 MockHttpCache cache;
2988 MockTransaction transaction(kSimplePOST_Transaction);
2989 AddMockTransaction(&transaction);
2990 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2991 transaction.method = "HEAD";
2993 MockHttpRequest request(transaction);
2994 net::TestCompletionCallback callback;
2996 scoped_ptr<net::HttpTransaction> trans;
2997 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
2998 ASSERT_TRUE(trans.get());
3000 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
3001 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
3003 trans.reset();
3005 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3006 EXPECT_EQ(0, cache.disk_cache()->open_count());
3007 EXPECT_EQ(0, cache.disk_cache()->create_count());
3008 RemoveMockTransaction(&transaction);
3011 // Tests that a HEAD request is served from a cached GET.
3012 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3013 MockHttpCache cache;
3014 MockTransaction transaction(kSimpleGET_Transaction);
3015 AddMockTransaction(&transaction);
3017 // Populate the cache.
3018 RunTransactionTest(cache.http_cache(), transaction);
3020 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3021 EXPECT_EQ(0, cache.disk_cache()->open_count());
3022 EXPECT_EQ(1, cache.disk_cache()->create_count());
3024 // Load from cache.
3025 transaction.method = "HEAD";
3026 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3027 transaction.data = "";
3028 RunTransactionTest(cache.http_cache(), transaction);
3030 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3031 EXPECT_EQ(1, cache.disk_cache()->open_count());
3032 EXPECT_EQ(1, cache.disk_cache()->create_count());
3033 RemoveMockTransaction(&transaction);
3036 // Tests that a read-only request served from the cache preserves CL.
3037 TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3038 MockHttpCache cache;
3039 MockTransaction transaction(kSimpleGET_Transaction);
3040 AddMockTransaction(&transaction);
3041 transaction.response_headers = "Content-Length: 42\n";
3043 // Populate the cache.
3044 RunTransactionTest(cache.http_cache(), transaction);
3046 // Load from cache.
3047 transaction.method = "HEAD";
3048 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3049 transaction.data = "";
3050 std::string headers;
3052 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3054 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3055 RemoveMockTransaction(&transaction);
3058 // Tests that a read-write request served from the cache preserves CL.
3059 TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3060 MockHttpCache cache;
3061 MockTransaction transaction(kETagGET_Transaction);
3062 AddMockTransaction(&transaction);
3063 std::string server_headers(kETagGET_Transaction.response_headers);
3064 server_headers.append("Content-Length: 42\n");
3065 transaction.response_headers = server_headers.data();
3067 // Populate the cache.
3068 RunTransactionTest(cache.http_cache(), transaction);
3070 // Load from cache.
3071 transaction.method = "HEAD";
3072 transaction.data = "";
3073 std::string headers;
3075 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3077 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3078 RemoveMockTransaction(&transaction);
3081 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3082 TEST(HttpCache, SimpleHEAD_WithRanges) {
3083 MockHttpCache cache;
3084 MockTransaction transaction(kSimpleGET_Transaction);
3085 AddMockTransaction(&transaction);
3087 // Populate the cache.
3088 RunTransactionTest(cache.http_cache(), transaction);
3090 // Load from cache.
3091 transaction.method = "HEAD";
3092 transaction.request_headers = "Range: bytes = 0-4\r\n";
3093 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3094 transaction.return_code = net::ERR_CACHE_MISS;
3095 RunTransactionTest(cache.http_cache(), transaction);
3097 EXPECT_EQ(0, cache.disk_cache()->open_count());
3098 EXPECT_EQ(1, cache.disk_cache()->create_count());
3099 RemoveMockTransaction(&transaction);
3102 // Tests that a HEAD request can be served from a partialy cached resource.
3103 TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3104 MockHttpCache cache;
3105 AddMockTransaction(&kRangeGET_TransactionOK);
3107 // Write to the cache (40-49).
3108 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3109 RemoveMockTransaction(&kRangeGET_TransactionOK);
3111 MockTransaction transaction(kSimpleGET_Transaction);
3113 transaction.url = kRangeGET_TransactionOK.url;
3114 transaction.method = "HEAD";
3115 transaction.data = "";
3116 AddMockTransaction(&transaction);
3117 std::string headers;
3119 // Load from cache.
3120 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3122 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3123 EXPECT_EQ(std::string::npos, headers.find("Content-Length"));
3124 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3125 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3126 EXPECT_EQ(1, cache.disk_cache()->open_count());
3127 EXPECT_EQ(1, cache.disk_cache()->create_count());
3128 RemoveMockTransaction(&transaction);
3131 // Tests that a HEAD request can be served from a truncated resource.
3132 TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3133 MockHttpCache cache;
3134 AddMockTransaction(&kRangeGET_TransactionOK);
3136 std::string raw_headers("HTTP/1.1 200 OK\n"
3137 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3138 "ETag: \"foo\"\n"
3139 "Accept-Ranges: bytes\n"
3140 "Content-Length: 80\n");
3141 CreateTruncatedEntry(raw_headers, &cache);
3142 RemoveMockTransaction(&kRangeGET_TransactionOK);
3144 MockTransaction transaction(kSimpleGET_Transaction);
3146 transaction.url = kRangeGET_TransactionOK.url;
3147 transaction.method = "HEAD";
3148 transaction.data = "";
3149 AddMockTransaction(&transaction);
3150 std::string headers;
3152 // Load from cache.
3153 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3155 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3156 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3157 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3158 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3159 EXPECT_EQ(1, cache.disk_cache()->open_count());
3160 EXPECT_EQ(1, cache.disk_cache()->create_count());
3161 RemoveMockTransaction(&transaction);
3164 // Tests that a HEAD request updates the cached response.
3165 TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3166 MockHttpCache cache;
3167 MockTransaction transaction(kTypicalGET_Transaction);
3168 AddMockTransaction(&transaction);
3170 // Populate the cache.
3171 RunTransactionTest(cache.http_cache(), transaction);
3173 // Update the cache.
3174 transaction.method = "HEAD";
3175 transaction.response_headers = "Foo: bar\n";
3176 transaction.data = "";
3177 transaction.status = "HTTP/1.1 304 Not Modified\n";
3178 std::string headers;
3179 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3180 RemoveMockTransaction(&transaction);
3182 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3183 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3185 MockTransaction transaction2(kTypicalGET_Transaction);
3186 AddMockTransaction(&transaction2);
3188 // Make sure we are done with the previous transaction.
3189 base::MessageLoop::current()->RunUntilIdle();
3191 // Load from the cache.
3192 transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3193 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3195 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3196 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3197 EXPECT_EQ(2, cache.disk_cache()->open_count());
3198 EXPECT_EQ(1, cache.disk_cache()->create_count());
3199 RemoveMockTransaction(&transaction2);
3202 // Tests that an externally conditionalized HEAD request updates the cache.
3203 TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3204 MockHttpCache cache;
3205 MockTransaction transaction(kTypicalGET_Transaction);
3206 AddMockTransaction(&transaction);
3208 // Populate the cache.
3209 RunTransactionTest(cache.http_cache(), transaction);
3211 // Update the cache.
3212 transaction.method = "HEAD";
3213 transaction.request_headers =
3214 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3215 transaction.response_headers = "Foo: bar\n";
3216 transaction.data = "";
3217 transaction.status = "HTTP/1.1 304 Not Modified\n";
3218 std::string headers;
3219 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3220 RemoveMockTransaction(&transaction);
3222 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3223 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3225 MockTransaction transaction2(kTypicalGET_Transaction);
3226 AddMockTransaction(&transaction2);
3228 // Make sure we are done with the previous transaction.
3229 base::MessageLoop::current()->RunUntilIdle();
3231 // Load from the cache.
3232 transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3233 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3235 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3236 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3237 EXPECT_EQ(2, cache.disk_cache()->open_count());
3238 EXPECT_EQ(1, cache.disk_cache()->create_count());
3239 RemoveMockTransaction(&transaction2);
3242 // Tests that a HEAD request invalidates an old cached entry.
3243 TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3244 MockHttpCache cache;
3245 MockTransaction transaction(kTypicalGET_Transaction);
3246 AddMockTransaction(&transaction);
3248 // Populate the cache.
3249 RunTransactionTest(cache.http_cache(), transaction);
3251 // Update the cache.
3252 transaction.method = "HEAD";
3253 transaction.data = "";
3254 RunTransactionTest(cache.http_cache(), transaction);
3255 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3257 // Load from the cache.
3258 transaction.method = "GET";
3259 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3260 transaction.return_code = net::ERR_CACHE_MISS;
3261 RunTransactionTest(cache.http_cache(), transaction);
3263 RemoveMockTransaction(&transaction);
3266 // Tests that we do not cache the response of a PUT.
3267 TEST(HttpCache, SimplePUT_Miss) {
3268 MockHttpCache cache;
3270 MockTransaction transaction(kSimplePOST_Transaction);
3271 transaction.method = "PUT";
3273 ScopedVector<net::UploadElementReader> element_readers;
3274 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3275 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3277 MockHttpRequest request(transaction);
3278 request.upload_data_stream = &upload_data_stream;
3280 // Attempt to populate the cache.
3281 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3283 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3284 EXPECT_EQ(0, cache.disk_cache()->open_count());
3285 EXPECT_EQ(0, cache.disk_cache()->create_count());
3288 // Tests that we invalidate entries as a result of a PUT.
3289 TEST(HttpCache, SimplePUT_Invalidate) {
3290 MockHttpCache cache;
3292 MockTransaction transaction(kSimpleGET_Transaction);
3293 MockHttpRequest req1(transaction);
3295 // Attempt to populate the cache.
3296 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3298 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3299 EXPECT_EQ(0, cache.disk_cache()->open_count());
3300 EXPECT_EQ(1, cache.disk_cache()->create_count());
3302 ScopedVector<net::UploadElementReader> element_readers;
3303 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3304 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3306 transaction.method = "PUT";
3307 MockHttpRequest req2(transaction);
3308 req2.upload_data_stream = &upload_data_stream;
3310 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3312 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3313 EXPECT_EQ(1, cache.disk_cache()->open_count());
3314 EXPECT_EQ(1, cache.disk_cache()->create_count());
3316 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3318 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3319 EXPECT_EQ(1, cache.disk_cache()->open_count());
3320 EXPECT_EQ(2, cache.disk_cache()->create_count());
3323 // Tests that we invalidate entries as a result of a PUT.
3324 TEST(HttpCache, SimplePUT_Invalidate_305) {
3325 MockHttpCache cache;
3327 MockTransaction transaction(kSimpleGET_Transaction);
3328 AddMockTransaction(&transaction);
3329 MockHttpRequest req1(transaction);
3331 // Attempt to populate the cache.
3332 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3334 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3335 EXPECT_EQ(0, cache.disk_cache()->open_count());
3336 EXPECT_EQ(1, cache.disk_cache()->create_count());
3338 ScopedVector<net::UploadElementReader> element_readers;
3339 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3340 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3342 transaction.method = "PUT";
3343 transaction.status = "HTTP/1.1 305 Use Proxy";
3344 MockHttpRequest req2(transaction);
3345 req2.upload_data_stream = &upload_data_stream;
3347 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3349 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3350 EXPECT_EQ(1, cache.disk_cache()->open_count());
3351 EXPECT_EQ(1, cache.disk_cache()->create_count());
3353 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3355 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3356 EXPECT_EQ(1, cache.disk_cache()->open_count());
3357 EXPECT_EQ(2, cache.disk_cache()->create_count());
3358 RemoveMockTransaction(&transaction);
3361 // Tests that we don't invalidate entries as a result of a failed PUT.
3362 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3363 MockHttpCache cache;
3365 MockTransaction transaction(kSimpleGET_Transaction);
3366 AddMockTransaction(&transaction);
3367 MockHttpRequest req1(transaction);
3369 // Attempt to populate the cache.
3370 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3372 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3373 EXPECT_EQ(0, cache.disk_cache()->open_count());
3374 EXPECT_EQ(1, cache.disk_cache()->create_count());
3376 ScopedVector<net::UploadElementReader> element_readers;
3377 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3378 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3380 transaction.method = "PUT";
3381 transaction.status = "HTTP/1.1 404 Not Found";
3382 MockHttpRequest req2(transaction);
3383 req2.upload_data_stream = &upload_data_stream;
3385 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3387 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3388 EXPECT_EQ(1, cache.disk_cache()->open_count());
3389 EXPECT_EQ(1, cache.disk_cache()->create_count());
3391 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3393 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3394 EXPECT_EQ(2, cache.disk_cache()->open_count());
3395 EXPECT_EQ(1, cache.disk_cache()->create_count());
3396 RemoveMockTransaction(&transaction);
3399 // Tests that we do not cache the response of a DELETE.
3400 TEST(HttpCache, SimpleDELETE_Miss) {
3401 MockHttpCache cache;
3403 MockTransaction transaction(kSimplePOST_Transaction);
3404 transaction.method = "DELETE";
3406 ScopedVector<net::UploadElementReader> element_readers;
3407 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3408 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3410 MockHttpRequest request(transaction);
3411 request.upload_data_stream = &upload_data_stream;
3413 // Attempt to populate the cache.
3414 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3416 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3417 EXPECT_EQ(0, cache.disk_cache()->open_count());
3418 EXPECT_EQ(0, cache.disk_cache()->create_count());
3421 // Tests that we invalidate entries as a result of a DELETE.
3422 TEST(HttpCache, SimpleDELETE_Invalidate) {
3423 MockHttpCache cache;
3425 MockTransaction transaction(kSimpleGET_Transaction);
3426 MockHttpRequest req1(transaction);
3428 // Attempt to populate the cache.
3429 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3431 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3432 EXPECT_EQ(0, cache.disk_cache()->open_count());
3433 EXPECT_EQ(1, cache.disk_cache()->create_count());
3435 ScopedVector<net::UploadElementReader> element_readers;
3436 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3437 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3439 transaction.method = "DELETE";
3440 MockHttpRequest req2(transaction);
3441 req2.upload_data_stream = &upload_data_stream;
3443 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3445 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3446 EXPECT_EQ(1, cache.disk_cache()->open_count());
3447 EXPECT_EQ(1, cache.disk_cache()->create_count());
3449 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3451 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3452 EXPECT_EQ(1, cache.disk_cache()->open_count());
3453 EXPECT_EQ(2, cache.disk_cache()->create_count());
3456 // Tests that we invalidate entries as a result of a DELETE.
3457 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3458 MockHttpCache cache;
3460 MockTransaction transaction(kSimpleGET_Transaction);
3461 AddMockTransaction(&transaction);
3463 // Attempt to populate the cache.
3464 RunTransactionTest(cache.http_cache(), transaction);
3466 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3467 EXPECT_EQ(0, cache.disk_cache()->open_count());
3468 EXPECT_EQ(1, cache.disk_cache()->create_count());
3470 transaction.method = "DELETE";
3471 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3473 RunTransactionTest(cache.http_cache(), transaction);
3475 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3476 EXPECT_EQ(1, cache.disk_cache()->open_count());
3477 EXPECT_EQ(1, cache.disk_cache()->create_count());
3479 transaction.method = "GET";
3480 RunTransactionTest(cache.http_cache(), transaction);
3482 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3483 EXPECT_EQ(1, cache.disk_cache()->open_count());
3484 EXPECT_EQ(2, cache.disk_cache()->create_count());
3485 RemoveMockTransaction(&transaction);
3488 // Tests that we don't invalidate entries as a result of a failed DELETE.
3489 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3490 MockHttpCache cache;
3492 MockTransaction transaction(kSimpleGET_Transaction);
3493 AddMockTransaction(&transaction);
3495 // Attempt to populate the cache.
3496 RunTransactionTest(cache.http_cache(), transaction);
3498 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3499 EXPECT_EQ(0, cache.disk_cache()->open_count());
3500 EXPECT_EQ(1, cache.disk_cache()->create_count());
3502 transaction.method = "DELETE";
3503 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3505 RunTransactionTest(cache.http_cache(), transaction);
3507 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3508 EXPECT_EQ(1, cache.disk_cache()->open_count());
3509 EXPECT_EQ(1, cache.disk_cache()->create_count());
3511 transaction.method = "GET";
3512 transaction.status = "HTTP/1.1 200 OK";
3513 RunTransactionTest(cache.http_cache(), transaction);
3515 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3516 EXPECT_EQ(2, cache.disk_cache()->open_count());
3517 EXPECT_EQ(1, cache.disk_cache()->create_count());
3518 RemoveMockTransaction(&transaction);
3521 // Tests that we don't invalidate entries after a failed network transaction.
3522 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3523 MockHttpCache cache;
3525 // Populate the cache.
3526 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3527 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3529 // Fail the network request.
3530 MockTransaction transaction(kSimpleGET_Transaction);
3531 transaction.return_code = net::ERR_FAILED;
3532 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3534 AddMockTransaction(&transaction);
3535 RunTransactionTest(cache.http_cache(), transaction);
3536 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3537 RemoveMockTransaction(&transaction);
3539 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3540 transaction.return_code = net::OK;
3541 AddMockTransaction(&transaction);
3542 RunTransactionTest(cache.http_cache(), transaction);
3544 // Make sure the transaction didn't reach the network.
3545 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3546 RemoveMockTransaction(&transaction);
3549 TEST(HttpCache, RangeGET_SkipsCache) {
3550 MockHttpCache cache;
3552 // Test that we skip the cache for range GET requests. Eventually, we will
3553 // want to cache these, but we'll still have cases where skipping the cache
3554 // makes sense, so we want to make sure that it works properly.
3556 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3558 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3559 EXPECT_EQ(0, cache.disk_cache()->open_count());
3560 EXPECT_EQ(0, cache.disk_cache()->create_count());
3562 MockTransaction transaction(kSimpleGET_Transaction);
3563 transaction.request_headers = "If-None-Match: foo\r\n";
3564 RunTransactionTest(cache.http_cache(), transaction);
3566 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3567 EXPECT_EQ(0, cache.disk_cache()->open_count());
3568 EXPECT_EQ(0, cache.disk_cache()->create_count());
3570 transaction.request_headers =
3571 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3572 RunTransactionTest(cache.http_cache(), transaction);
3574 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3575 EXPECT_EQ(0, cache.disk_cache()->open_count());
3576 EXPECT_EQ(0, cache.disk_cache()->create_count());
3579 // Test that we skip the cache for range requests that include a validation
3580 // header.
3581 TEST(HttpCache, RangeGET_SkipsCache2) {
3582 MockHttpCache cache;
3584 MockTransaction transaction(kRangeGET_Transaction);
3585 transaction.request_headers = "If-None-Match: foo\r\n"
3586 EXTRA_HEADER
3587 "Range: bytes = 40-49\r\n";
3588 RunTransactionTest(cache.http_cache(), transaction);
3590 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3591 EXPECT_EQ(0, cache.disk_cache()->open_count());
3592 EXPECT_EQ(0, cache.disk_cache()->create_count());
3594 transaction.request_headers =
3595 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3596 EXTRA_HEADER
3597 "Range: bytes = 40-49\r\n";
3598 RunTransactionTest(cache.http_cache(), transaction);
3600 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3601 EXPECT_EQ(0, cache.disk_cache()->open_count());
3602 EXPECT_EQ(0, cache.disk_cache()->create_count());
3604 transaction.request_headers = "If-Range: bla\r\n"
3605 EXTRA_HEADER
3606 "Range: bytes = 40-49\r\n";
3607 RunTransactionTest(cache.http_cache(), transaction);
3609 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3610 EXPECT_EQ(0, cache.disk_cache()->open_count());
3611 EXPECT_EQ(0, cache.disk_cache()->create_count());
3614 // Tests that receiving 206 for a regular request is handled correctly.
3615 TEST(HttpCache, GET_Crazy206) {
3616 MockHttpCache cache;
3618 // Write to the cache.
3619 MockTransaction transaction(kRangeGET_TransactionOK);
3620 AddMockTransaction(&transaction);
3621 transaction.request_headers = EXTRA_HEADER;
3622 transaction.handler = NULL;
3623 RunTransactionTest(cache.http_cache(), transaction);
3625 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3626 EXPECT_EQ(0, cache.disk_cache()->open_count());
3627 EXPECT_EQ(1, cache.disk_cache()->create_count());
3629 // This should read again from the net.
3630 RunTransactionTest(cache.http_cache(), transaction);
3632 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3633 EXPECT_EQ(0, cache.disk_cache()->open_count());
3634 EXPECT_EQ(2, cache.disk_cache()->create_count());
3635 RemoveMockTransaction(&transaction);
3638 // Tests that receiving 416 for a regular request is handled correctly.
3639 TEST(HttpCache, GET_Crazy416) {
3640 MockHttpCache cache;
3642 // Write to the cache.
3643 MockTransaction transaction(kSimpleGET_Transaction);
3644 AddMockTransaction(&transaction);
3645 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3646 RunTransactionTest(cache.http_cache(), transaction);
3648 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3649 EXPECT_EQ(0, cache.disk_cache()->open_count());
3650 EXPECT_EQ(1, cache.disk_cache()->create_count());
3652 RemoveMockTransaction(&transaction);
3655 // Tests that we don't cache partial responses that can't be validated.
3656 TEST(HttpCache, RangeGET_NoStrongValidators) {
3657 MockHttpCache cache;
3658 std::string headers;
3660 // Attempt to write to the cache (40-49).
3661 MockTransaction transaction(kRangeGET_TransactionOK);
3662 AddMockTransaction(&transaction);
3663 transaction.response_headers = "Content-Length: 10\n"
3664 "ETag: w/\"foo\"\n";
3665 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3667 Verify206Response(headers, 40, 49);
3668 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3669 EXPECT_EQ(0, cache.disk_cache()->open_count());
3670 EXPECT_EQ(1, cache.disk_cache()->create_count());
3672 // Now verify that there's no cached data.
3673 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3674 &headers);
3676 Verify206Response(headers, 40, 49);
3677 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3678 EXPECT_EQ(0, cache.disk_cache()->open_count());
3679 EXPECT_EQ(2, cache.disk_cache()->create_count());
3681 RemoveMockTransaction(&transaction);
3684 // Tests that we cache partial responses that lack content-length.
3685 TEST(HttpCache, RangeGET_NoContentLength) {
3686 MockHttpCache cache;
3687 std::string headers;
3689 // Attempt to write to the cache (40-49).
3690 MockTransaction transaction(kRangeGET_TransactionOK);
3691 AddMockTransaction(&transaction);
3692 transaction.response_headers = "ETag: \"foo\"\n"
3693 "Accept-Ranges: bytes\n"
3694 "Content-Range: bytes 40-49/80\n";
3695 transaction.handler = NULL;
3696 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3698 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3699 EXPECT_EQ(0, cache.disk_cache()->open_count());
3700 EXPECT_EQ(1, cache.disk_cache()->create_count());
3702 // Now verify that there's no cached data.
3703 transaction.handler = &RangeTransactionServer::RangeHandler;
3704 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3705 &headers);
3707 Verify206Response(headers, 40, 49);
3708 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3709 EXPECT_EQ(1, cache.disk_cache()->open_count());
3710 EXPECT_EQ(1, cache.disk_cache()->create_count());
3712 RemoveMockTransaction(&transaction);
3715 // Tests that we can cache range requests and fetch random blocks from the
3716 // cache and the network.
3717 TEST(HttpCache, RangeGET_OK) {
3718 MockHttpCache cache;
3719 AddMockTransaction(&kRangeGET_TransactionOK);
3720 std::string headers;
3722 // Write to the cache (40-49).
3723 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3724 &headers);
3726 Verify206Response(headers, 40, 49);
3727 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3728 EXPECT_EQ(0, cache.disk_cache()->open_count());
3729 EXPECT_EQ(1, cache.disk_cache()->create_count());
3731 // Read from the cache (40-49).
3732 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3733 &headers);
3735 Verify206Response(headers, 40, 49);
3736 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3737 EXPECT_EQ(1, cache.disk_cache()->open_count());
3738 EXPECT_EQ(1, cache.disk_cache()->create_count());
3740 // Make sure we are done with the previous transaction.
3741 base::MessageLoop::current()->RunUntilIdle();
3743 // Write to the cache (30-39).
3744 MockTransaction transaction(kRangeGET_TransactionOK);
3745 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3746 transaction.data = "rg: 30-39 ";
3747 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3749 Verify206Response(headers, 30, 39);
3750 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3751 EXPECT_EQ(2, cache.disk_cache()->open_count());
3752 EXPECT_EQ(1, cache.disk_cache()->create_count());
3754 // Make sure we are done with the previous transaction.
3755 base::MessageLoop::current()->RunUntilIdle();
3757 // Write and read from the cache (20-59).
3758 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3759 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3760 net::CapturingBoundNetLog log;
3761 net::LoadTimingInfo load_timing_info;
3762 RunTransactionTestWithResponseAndGetTiming(
3763 cache.http_cache(), transaction, &headers, log.bound(),
3764 &load_timing_info);
3766 Verify206Response(headers, 20, 59);
3767 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3768 EXPECT_EQ(3, cache.disk_cache()->open_count());
3769 EXPECT_EQ(1, cache.disk_cache()->create_count());
3770 TestLoadTimingNetworkRequest(load_timing_info);
3772 RemoveMockTransaction(&kRangeGET_TransactionOK);
3775 // Checks that with a cache backend having Sparse IO unimplementes the cache
3776 // entry would be doomed after a range request.
3777 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3778 TEST(HttpCache, RangeGET_SparseNotImplemented) {
3779 MockHttpCache cache;
3780 cache.disk_cache()->set_fail_sparse_requests();
3782 // Run a cacheable request to prime the cache.
3783 MockTransaction transaction(kTypicalGET_Transaction);
3784 transaction.url = kRangeGET_TransactionOK.url;
3785 AddMockTransaction(&transaction);
3786 RunTransactionTest(cache.http_cache(), transaction);
3787 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3788 EXPECT_EQ(0, cache.disk_cache()->open_count());
3789 EXPECT_EQ(1, cache.disk_cache()->create_count());
3791 // Verify that we added the entry.
3792 disk_cache::Entry* entry;
3793 net::TestCompletionCallback cb;
3794 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3795 &entry,
3796 cb.callback());
3797 ASSERT_EQ(net::OK, cb.GetResult(rv));
3798 EXPECT_EQ(1, cache.disk_cache()->open_count());
3799 entry->Close();
3800 RemoveMockTransaction(&transaction);
3802 // Request the range with the backend that does not support it.
3803 MockTransaction transaction2(kRangeGET_TransactionOK);
3804 std::string headers;
3805 AddMockTransaction(&transaction2);
3806 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3807 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3808 EXPECT_EQ(2, cache.disk_cache()->open_count());
3809 EXPECT_EQ(2, cache.disk_cache()->create_count());
3811 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3812 // if it was re-created later, so this effectively checks that the old data is
3813 // gone.
3814 disk_cache::Entry* entry2;
3815 rv = cache.disk_cache()->OpenEntry(transaction2.url,
3816 &entry2,
3817 cb.callback());
3818 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3819 RemoveMockTransaction(&transaction2);
3822 TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3823 MockHttpCache cache;
3824 cache.disk_cache()->set_fail_sparse_requests();
3826 // Request the range with the backend that does not support it.
3827 MockTransaction transaction(kRangeGET_TransactionOK);
3828 std::string headers;
3829 AddMockTransaction(&transaction);
3830 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3831 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3832 EXPECT_EQ(0, cache.disk_cache()->open_count());
3833 EXPECT_EQ(1, cache.disk_cache()->create_count());
3835 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3836 // if it was re-created later, so this effectively checks that the old data is
3837 // gone as a result of a failed range write.
3838 disk_cache::Entry* entry;
3839 net::TestCompletionCallback cb;
3840 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3841 &entry,
3842 cb.callback());
3843 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3844 RemoveMockTransaction(&transaction);
3847 // Tests that we can cache range requests and fetch random blocks from the
3848 // cache and the network, with synchronous responses.
3849 TEST(HttpCache, RangeGET_SyncOK) {
3850 MockHttpCache cache;
3852 MockTransaction transaction(kRangeGET_TransactionOK);
3853 transaction.test_mode = TEST_MODE_SYNC_ALL;
3854 AddMockTransaction(&transaction);
3856 // Write to the cache (40-49).
3857 std::string headers;
3858 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3860 Verify206Response(headers, 40, 49);
3861 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3862 EXPECT_EQ(0, cache.disk_cache()->open_count());
3863 EXPECT_EQ(1, cache.disk_cache()->create_count());
3865 // Read from the cache (40-49).
3866 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3868 Verify206Response(headers, 40, 49);
3869 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3870 EXPECT_EQ(0, cache.disk_cache()->open_count());
3871 EXPECT_EQ(1, cache.disk_cache()->create_count());
3873 // Make sure we are done with the previous transaction.
3874 base::MessageLoop::current()->RunUntilIdle();
3876 // Write to the cache (30-39).
3877 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3878 transaction.data = "rg: 30-39 ";
3879 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3881 Verify206Response(headers, 30, 39);
3882 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3883 EXPECT_EQ(1, cache.disk_cache()->open_count());
3884 EXPECT_EQ(1, cache.disk_cache()->create_count());
3886 // Make sure we are done with the previous transaction.
3887 base::MessageLoop::current()->RunUntilIdle();
3889 // Write and read from the cache (20-59).
3890 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3891 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3892 net::CapturingBoundNetLog log;
3893 net::LoadTimingInfo load_timing_info;
3894 RunTransactionTestWithResponseAndGetTiming(
3895 cache.http_cache(), transaction, &headers, log.bound(),
3896 &load_timing_info);
3898 Verify206Response(headers, 20, 59);
3899 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3900 EXPECT_EQ(2, cache.disk_cache()->open_count());
3901 EXPECT_EQ(1, cache.disk_cache()->create_count());
3902 TestLoadTimingNetworkRequest(load_timing_info);
3904 RemoveMockTransaction(&transaction);
3907 // Tests that we don't revalidate an entry unless we are required to do so.
3908 TEST(HttpCache, RangeGET_Revalidate1) {
3909 MockHttpCache cache;
3910 std::string headers;
3912 // Write to the cache (40-49).
3913 MockTransaction transaction(kRangeGET_TransactionOK);
3914 transaction.response_headers =
3915 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3916 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3917 "ETag: \"foo\"\n"
3918 "Accept-Ranges: bytes\n"
3919 "Content-Length: 10\n";
3920 AddMockTransaction(&transaction);
3921 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3923 Verify206Response(headers, 40, 49);
3924 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3925 EXPECT_EQ(0, cache.disk_cache()->open_count());
3926 EXPECT_EQ(1, cache.disk_cache()->create_count());
3928 // Read from the cache (40-49).
3929 net::CapturingBoundNetLog log;
3930 net::LoadTimingInfo load_timing_info;
3931 RunTransactionTestWithResponseAndGetTiming(
3932 cache.http_cache(), transaction, &headers, log.bound(),
3933 &load_timing_info);
3935 Verify206Response(headers, 40, 49);
3936 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3937 EXPECT_EQ(1, cache.disk_cache()->open_count());
3938 EXPECT_EQ(1, cache.disk_cache()->create_count());
3939 TestLoadTimingCachedResponse(load_timing_info);
3941 // Read again forcing the revalidation.
3942 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3943 RunTransactionTestWithResponseAndGetTiming(
3944 cache.http_cache(), transaction, &headers, log.bound(),
3945 &load_timing_info);
3947 Verify206Response(headers, 40, 49);
3948 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3949 EXPECT_EQ(1, cache.disk_cache()->open_count());
3950 EXPECT_EQ(1, cache.disk_cache()->create_count());
3951 TestLoadTimingNetworkRequest(load_timing_info);
3953 RemoveMockTransaction(&transaction);
3956 // Checks that we revalidate an entry when the headers say so.
3957 TEST(HttpCache, RangeGET_Revalidate2) {
3958 MockHttpCache cache;
3959 std::string headers;
3961 // Write to the cache (40-49).
3962 MockTransaction transaction(kRangeGET_TransactionOK);
3963 transaction.response_headers =
3964 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3965 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
3966 "ETag: \"foo\"\n"
3967 "Accept-Ranges: bytes\n"
3968 "Content-Length: 10\n";
3969 AddMockTransaction(&transaction);
3970 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3972 Verify206Response(headers, 40, 49);
3973 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3974 EXPECT_EQ(0, cache.disk_cache()->open_count());
3975 EXPECT_EQ(1, cache.disk_cache()->create_count());
3977 // Read from the cache (40-49).
3978 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3979 Verify206Response(headers, 40, 49);
3981 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3982 EXPECT_EQ(1, cache.disk_cache()->open_count());
3983 EXPECT_EQ(1, cache.disk_cache()->create_count());
3985 RemoveMockTransaction(&transaction);
3988 // Tests that we deal with 304s for range requests.
3989 TEST(HttpCache, RangeGET_304) {
3990 MockHttpCache cache;
3991 AddMockTransaction(&kRangeGET_TransactionOK);
3992 std::string headers;
3994 // Write to the cache (40-49).
3995 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3996 &headers);
3998 Verify206Response(headers, 40, 49);
3999 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4000 EXPECT_EQ(0, cache.disk_cache()->open_count());
4001 EXPECT_EQ(1, cache.disk_cache()->create_count());
4003 // Read from the cache (40-49).
4004 RangeTransactionServer handler;
4005 handler.set_not_modified(true);
4006 MockTransaction transaction(kRangeGET_TransactionOK);
4007 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4008 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4010 Verify206Response(headers, 40, 49);
4011 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4012 EXPECT_EQ(1, cache.disk_cache()->open_count());
4013 EXPECT_EQ(1, cache.disk_cache()->create_count());
4015 RemoveMockTransaction(&kRangeGET_TransactionOK);
4018 // Tests that we deal with 206s when revalidating range requests.
4019 TEST(HttpCache, RangeGET_ModifiedResult) {
4020 MockHttpCache cache;
4021 AddMockTransaction(&kRangeGET_TransactionOK);
4022 std::string headers;
4024 // Write to the cache (40-49).
4025 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4026 &headers);
4028 Verify206Response(headers, 40, 49);
4029 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4030 EXPECT_EQ(0, cache.disk_cache()->open_count());
4031 EXPECT_EQ(1, cache.disk_cache()->create_count());
4033 // Attempt to read from the cache (40-49).
4034 RangeTransactionServer handler;
4035 handler.set_modified(true);
4036 MockTransaction transaction(kRangeGET_TransactionOK);
4037 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4038 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4040 Verify206Response(headers, 40, 49);
4041 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4042 EXPECT_EQ(1, cache.disk_cache()->open_count());
4043 EXPECT_EQ(1, cache.disk_cache()->create_count());
4045 // And the entry should be gone.
4046 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4047 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4048 EXPECT_EQ(1, cache.disk_cache()->open_count());
4049 EXPECT_EQ(2, cache.disk_cache()->create_count());
4051 RemoveMockTransaction(&kRangeGET_TransactionOK);
4054 // Tests that we cache 301s for range requests.
4055 TEST(HttpCache, RangeGET_301) {
4056 MockHttpCache cache;
4057 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4058 transaction.status = "HTTP/1.1 301 Moved Permanently";
4059 transaction.response_headers = "Location: http://www.bar.com/\n";
4060 transaction.data = "";
4061 transaction.handler = NULL;
4062 AddMockTransaction(&transaction);
4064 // Write to the cache.
4065 RunTransactionTest(cache.http_cache(), transaction);
4066 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4067 EXPECT_EQ(0, cache.disk_cache()->open_count());
4068 EXPECT_EQ(1, cache.disk_cache()->create_count());
4070 // Read from the cache.
4071 RunTransactionTest(cache.http_cache(), transaction);
4072 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4073 EXPECT_EQ(1, cache.disk_cache()->open_count());
4074 EXPECT_EQ(1, cache.disk_cache()->create_count());
4076 RemoveMockTransaction(&transaction);
4079 // Tests that we can cache range requests when the start or end is unknown.
4080 // We start with one suffix request, followed by a request from a given point.
4081 TEST(HttpCache, UnknownRangeGET_1) {
4082 MockHttpCache cache;
4083 AddMockTransaction(&kRangeGET_TransactionOK);
4084 std::string headers;
4086 // Write to the cache (70-79).
4087 MockTransaction transaction(kRangeGET_TransactionOK);
4088 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4089 transaction.data = "rg: 70-79 ";
4090 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4092 Verify206Response(headers, 70, 79);
4093 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4094 EXPECT_EQ(0, cache.disk_cache()->open_count());
4095 EXPECT_EQ(1, cache.disk_cache()->create_count());
4097 // Make sure we are done with the previous transaction.
4098 base::MessageLoop::current()->RunUntilIdle();
4100 // Write and read from the cache (60-79).
4101 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
4102 transaction.data = "rg: 60-69 rg: 70-79 ";
4103 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4105 Verify206Response(headers, 60, 79);
4106 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4107 EXPECT_EQ(1, cache.disk_cache()->open_count());
4108 EXPECT_EQ(1, cache.disk_cache()->create_count());
4110 RemoveMockTransaction(&kRangeGET_TransactionOK);
4113 // Tests that we can cache range requests when the start or end is unknown.
4114 // We start with one request from a given point, followed by a suffix request.
4115 // We'll also verify that synchronous cache responses work as intended.
4116 TEST(HttpCache, UnknownRangeGET_2) {
4117 MockHttpCache cache;
4118 std::string headers;
4120 MockTransaction transaction(kRangeGET_TransactionOK);
4121 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
4122 TEST_MODE_SYNC_CACHE_READ |
4123 TEST_MODE_SYNC_CACHE_WRITE;
4124 AddMockTransaction(&transaction);
4126 // Write to the cache (70-79).
4127 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4128 transaction.data = "rg: 70-79 ";
4129 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4131 Verify206Response(headers, 70, 79);
4132 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4133 EXPECT_EQ(0, cache.disk_cache()->open_count());
4134 EXPECT_EQ(1, cache.disk_cache()->create_count());
4136 // Make sure we are done with the previous transaction.
4137 base::MessageLoop::current()->RunUntilIdle();
4139 // Write and read from the cache (60-79).
4140 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
4141 transaction.data = "rg: 60-69 rg: 70-79 ";
4142 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4144 Verify206Response(headers, 60, 79);
4145 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4146 EXPECT_EQ(1, cache.disk_cache()->open_count());
4147 EXPECT_EQ(1, cache.disk_cache()->create_count());
4149 RemoveMockTransaction(&transaction);
4152 // Tests that receiving Not Modified when asking for an open range doesn't mess
4153 // up things.
4154 TEST(HttpCache, UnknownRangeGET_304) {
4155 MockHttpCache cache;
4156 std::string headers;
4158 MockTransaction transaction(kRangeGET_TransactionOK);
4159 AddMockTransaction(&transaction);
4161 RangeTransactionServer handler;
4162 handler.set_not_modified(true);
4164 // Ask for the end of the file, without knowing the length.
4165 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4166 transaction.data = "";
4167 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4169 // We just bypass the cache.
4170 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4171 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4172 EXPECT_EQ(0, cache.disk_cache()->open_count());
4173 EXPECT_EQ(1, cache.disk_cache()->create_count());
4175 RunTransactionTest(cache.http_cache(), transaction);
4176 EXPECT_EQ(2, cache.disk_cache()->create_count());
4178 RemoveMockTransaction(&transaction);
4181 // Tests that we can handle non-range requests when we have cached a range.
4182 TEST(HttpCache, GET_Previous206) {
4183 MockHttpCache cache;
4184 AddMockTransaction(&kRangeGET_TransactionOK);
4185 std::string headers;
4186 net::CapturingBoundNetLog log;
4187 net::LoadTimingInfo load_timing_info;
4189 // Write to the cache (40-49).
4190 RunTransactionTestWithResponseAndGetTiming(
4191 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4192 &load_timing_info);
4194 Verify206Response(headers, 40, 49);
4195 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4196 EXPECT_EQ(0, cache.disk_cache()->open_count());
4197 EXPECT_EQ(1, cache.disk_cache()->create_count());
4198 TestLoadTimingNetworkRequest(load_timing_info);
4200 // Write and read from the cache (0-79), when not asked for a range.
4201 MockTransaction transaction(kRangeGET_TransactionOK);
4202 transaction.request_headers = EXTRA_HEADER;
4203 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4204 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4205 RunTransactionTestWithResponseAndGetTiming(
4206 cache.http_cache(), transaction, &headers, log.bound(),
4207 &load_timing_info);
4209 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4210 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4211 EXPECT_EQ(1, cache.disk_cache()->open_count());
4212 EXPECT_EQ(1, cache.disk_cache()->create_count());
4213 TestLoadTimingNetworkRequest(load_timing_info);
4215 RemoveMockTransaction(&kRangeGET_TransactionOK);
4218 // Tests that we can handle non-range requests when we have cached the first
4219 // part of the object and the server replies with 304 (Not Modified).
4220 TEST(HttpCache, GET_Previous206_NotModified) {
4221 MockHttpCache cache;
4223 MockTransaction transaction(kRangeGET_TransactionOK);
4224 AddMockTransaction(&transaction);
4225 std::string headers;
4226 net::CapturingBoundNetLog log;
4227 net::LoadTimingInfo load_timing_info;
4229 // Write to the cache (0-9).
4230 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4231 transaction.data = "rg: 00-09 ";
4232 RunTransactionTestWithResponseAndGetTiming(
4233 cache.http_cache(), transaction, &headers, log.bound(),
4234 &load_timing_info);
4235 Verify206Response(headers, 0, 9);
4236 TestLoadTimingNetworkRequest(load_timing_info);
4238 // Write to the cache (70-79).
4239 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4240 transaction.data = "rg: 70-79 ";
4241 RunTransactionTestWithResponseAndGetTiming(
4242 cache.http_cache(), transaction, &headers, log.bound(),
4243 &load_timing_info);
4244 Verify206Response(headers, 70, 79);
4246 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4247 EXPECT_EQ(1, cache.disk_cache()->open_count());
4248 EXPECT_EQ(1, cache.disk_cache()->create_count());
4249 TestLoadTimingNetworkRequest(load_timing_info);
4251 // Read from the cache (0-9), write and read from cache (10 - 79).
4252 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4253 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
4254 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4255 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4256 RunTransactionTestWithResponseAndGetTiming(
4257 cache.http_cache(), transaction, &headers, log.bound(),
4258 &load_timing_info);
4260 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4261 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4262 EXPECT_EQ(2, cache.disk_cache()->open_count());
4263 EXPECT_EQ(1, cache.disk_cache()->create_count());
4264 TestLoadTimingNetworkRequest(load_timing_info);
4266 RemoveMockTransaction(&transaction);
4269 // Tests that we can handle a regular request to a sparse entry, that results in
4270 // new content provided by the server (206).
4271 TEST(HttpCache, GET_Previous206_NewContent) {
4272 MockHttpCache cache;
4273 AddMockTransaction(&kRangeGET_TransactionOK);
4274 std::string headers;
4276 // Write to the cache (0-9).
4277 MockTransaction transaction(kRangeGET_TransactionOK);
4278 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4279 transaction.data = "rg: 00-09 ";
4280 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4282 Verify206Response(headers, 0, 9);
4283 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4284 EXPECT_EQ(0, cache.disk_cache()->open_count());
4285 EXPECT_EQ(1, cache.disk_cache()->create_count());
4287 // Now we'll issue a request without any range that should result first in a
4288 // 206 (when revalidating), and then in a weird standard answer: the test
4289 // server will not modify the response so we'll get the default range... a
4290 // real server will answer with 200.
4291 MockTransaction transaction2(kRangeGET_TransactionOK);
4292 transaction2.request_headers = EXTRA_HEADER;
4293 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
4294 transaction2.data = "Not a range";
4295 RangeTransactionServer handler;
4296 handler.set_modified(true);
4297 net::CapturingBoundNetLog log;
4298 net::LoadTimingInfo load_timing_info;
4299 RunTransactionTestWithResponseAndGetTiming(
4300 cache.http_cache(), transaction2, &headers, log.bound(),
4301 &load_timing_info);
4303 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4304 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4305 EXPECT_EQ(1, cache.disk_cache()->open_count());
4306 EXPECT_EQ(1, cache.disk_cache()->create_count());
4307 TestLoadTimingNetworkRequest(load_timing_info);
4309 // Verify that the previous request deleted the entry.
4310 RunTransactionTest(cache.http_cache(), transaction);
4311 EXPECT_EQ(2, cache.disk_cache()->create_count());
4313 RemoveMockTransaction(&transaction);
4316 // Tests that we can handle cached 206 responses that are not sparse.
4317 TEST(HttpCache, GET_Previous206_NotSparse) {
4318 MockHttpCache cache;
4320 // Create a disk cache entry that stores 206 headers while not being sparse.
4321 disk_cache::Entry* entry;
4322 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4323 NULL));
4325 std::string raw_headers(kRangeGET_TransactionOK.status);
4326 raw_headers.append("\n");
4327 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4328 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4329 raw_headers.size());
4331 net::HttpResponseInfo response;
4332 response.headers = new net::HttpResponseHeaders(raw_headers);
4333 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4335 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4336 int len = static_cast<int>(base::strlcpy(buf->data(),
4337 kRangeGET_TransactionOK.data, 500));
4338 net::TestCompletionCallback cb;
4339 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4340 EXPECT_EQ(len, cb.GetResult(rv));
4341 entry->Close();
4343 // Now see that we don't use the stored entry.
4344 std::string headers;
4345 net::CapturingBoundNetLog log;
4346 net::LoadTimingInfo load_timing_info;
4347 RunTransactionTestWithResponseAndGetTiming(
4348 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4349 &load_timing_info);
4351 // We are expecting a 200.
4352 std::string expected_headers(kSimpleGET_Transaction.status);
4353 expected_headers.append("\n");
4354 expected_headers.append(kSimpleGET_Transaction.response_headers);
4355 EXPECT_EQ(expected_headers, headers);
4356 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4357 EXPECT_EQ(1, cache.disk_cache()->open_count());
4358 EXPECT_EQ(2, cache.disk_cache()->create_count());
4359 TestLoadTimingNetworkRequest(load_timing_info);
4362 // Tests that we can handle cached 206 responses that are not sparse. This time
4363 // we issue a range request and expect to receive a range.
4364 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4365 MockHttpCache cache;
4366 AddMockTransaction(&kRangeGET_TransactionOK);
4368 // Create a disk cache entry that stores 206 headers while not being sparse.
4369 disk_cache::Entry* entry;
4370 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.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 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4394 &headers);
4396 // We are expecting a 206.
4397 Verify206Response(headers, 40, 49);
4398 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4399 EXPECT_EQ(1, cache.disk_cache()->open_count());
4400 EXPECT_EQ(2, cache.disk_cache()->create_count());
4402 RemoveMockTransaction(&kRangeGET_TransactionOK);
4405 // Tests that we can handle cached 206 responses that can't be validated.
4406 TEST(HttpCache, GET_Previous206_NotValidation) {
4407 MockHttpCache cache;
4409 // Create a disk cache entry that stores 206 headers.
4410 disk_cache::Entry* entry;
4411 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4412 NULL));
4414 // Make sure that the headers cannot be validated with the server.
4415 std::string raw_headers(kRangeGET_TransactionOK.status);
4416 raw_headers.append("\n");
4417 raw_headers.append("Content-Length: 80\n");
4418 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4419 raw_headers.size());
4421 net::HttpResponseInfo response;
4422 response.headers = new net::HttpResponseHeaders(raw_headers);
4423 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4425 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4426 int len = static_cast<int>(base::strlcpy(buf->data(),
4427 kRangeGET_TransactionOK.data, 500));
4428 net::TestCompletionCallback cb;
4429 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4430 EXPECT_EQ(len, cb.GetResult(rv));
4431 entry->Close();
4433 // Now see that we don't use the stored entry.
4434 std::string headers;
4435 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4436 &headers);
4438 // We are expecting a 200.
4439 std::string expected_headers(kSimpleGET_Transaction.status);
4440 expected_headers.append("\n");
4441 expected_headers.append(kSimpleGET_Transaction.response_headers);
4442 EXPECT_EQ(expected_headers, headers);
4443 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4444 EXPECT_EQ(1, cache.disk_cache()->open_count());
4445 EXPECT_EQ(2, cache.disk_cache()->create_count());
4448 // Tests that we can handle range requests with cached 200 responses.
4449 TEST(HttpCache, RangeGET_Previous200) {
4450 MockHttpCache cache;
4452 // Store the whole thing with status 200.
4453 MockTransaction transaction(kTypicalGET_Transaction);
4454 transaction.url = kRangeGET_TransactionOK.url;
4455 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4456 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4457 AddMockTransaction(&transaction);
4458 RunTransactionTest(cache.http_cache(), transaction);
4459 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4460 EXPECT_EQ(0, cache.disk_cache()->open_count());
4461 EXPECT_EQ(1, cache.disk_cache()->create_count());
4463 RemoveMockTransaction(&transaction);
4464 AddMockTransaction(&kRangeGET_TransactionOK);
4466 // Now see that we use the stored entry.
4467 std::string headers;
4468 MockTransaction transaction2(kRangeGET_TransactionOK);
4469 RangeTransactionServer handler;
4470 handler.set_not_modified(true);
4471 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4473 // We are expecting a 206.
4474 Verify206Response(headers, 40, 49);
4475 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4476 EXPECT_EQ(1, cache.disk_cache()->open_count());
4477 EXPECT_EQ(1, cache.disk_cache()->create_count());
4479 // The last transaction has finished so make sure the entry is deactivated.
4480 base::MessageLoop::current()->RunUntilIdle();
4482 // Make a request for an invalid range.
4483 MockTransaction transaction3(kRangeGET_TransactionOK);
4484 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4485 transaction3.data = transaction.data;
4486 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4487 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4488 EXPECT_EQ(2, cache.disk_cache()->open_count());
4489 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4490 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4491 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4493 // Make sure the entry is deactivated.
4494 base::MessageLoop::current()->RunUntilIdle();
4496 // Even though the request was invalid, we should have the entry.
4497 RunTransactionTest(cache.http_cache(), transaction2);
4498 EXPECT_EQ(3, cache.disk_cache()->open_count());
4500 // Make sure the entry is deactivated.
4501 base::MessageLoop::current()->RunUntilIdle();
4503 // Now we should receive a range from the server and drop the stored entry.
4504 handler.set_not_modified(false);
4505 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4506 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4507 Verify206Response(headers, 40, 49);
4508 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4509 EXPECT_EQ(4, cache.disk_cache()->open_count());
4510 EXPECT_EQ(1, cache.disk_cache()->create_count());
4512 RunTransactionTest(cache.http_cache(), transaction2);
4513 EXPECT_EQ(2, cache.disk_cache()->create_count());
4515 RemoveMockTransaction(&kRangeGET_TransactionOK);
4518 // Tests that we can handle a 200 response when dealing with sparse entries.
4519 TEST(HttpCache, RangeRequestResultsIn200) {
4520 MockHttpCache cache;
4521 AddMockTransaction(&kRangeGET_TransactionOK);
4522 std::string headers;
4524 // Write to the cache (70-79).
4525 MockTransaction transaction(kRangeGET_TransactionOK);
4526 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4527 transaction.data = "rg: 70-79 ";
4528 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4530 Verify206Response(headers, 70, 79);
4531 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4532 EXPECT_EQ(0, cache.disk_cache()->open_count());
4533 EXPECT_EQ(1, cache.disk_cache()->create_count());
4535 // Now we'll issue a request that results in a plain 200 response, but to
4536 // the to the same URL that we used to store sparse data, and making sure
4537 // that we ask for a range.
4538 RemoveMockTransaction(&kRangeGET_TransactionOK);
4539 MockTransaction transaction2(kSimpleGET_Transaction);
4540 transaction2.url = kRangeGET_TransactionOK.url;
4541 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4542 AddMockTransaction(&transaction2);
4544 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4546 std::string expected_headers(kSimpleGET_Transaction.status);
4547 expected_headers.append("\n");
4548 expected_headers.append(kSimpleGET_Transaction.response_headers);
4549 EXPECT_EQ(expected_headers, headers);
4550 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4551 EXPECT_EQ(1, cache.disk_cache()->open_count());
4552 EXPECT_EQ(1, cache.disk_cache()->create_count());
4554 RemoveMockTransaction(&transaction2);
4557 // Tests that a range request that falls outside of the size that we know about
4558 // only deletes the entry if the resource has indeed changed.
4559 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4560 MockHttpCache cache;
4561 AddMockTransaction(&kRangeGET_TransactionOK);
4562 std::string headers;
4564 // Write to the cache (40-49).
4565 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4566 &headers);
4568 Verify206Response(headers, 40, 49);
4569 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4570 EXPECT_EQ(0, cache.disk_cache()->open_count());
4571 EXPECT_EQ(1, cache.disk_cache()->create_count());
4573 // A weird request should not delete this entry. Ask for bytes 120-.
4574 MockTransaction transaction(kRangeGET_TransactionOK);
4575 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4576 transaction.data = "";
4577 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4579 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4580 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4581 EXPECT_EQ(1, cache.disk_cache()->open_count());
4582 EXPECT_EQ(1, cache.disk_cache()->create_count());
4584 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4585 EXPECT_EQ(2, cache.disk_cache()->open_count());
4586 EXPECT_EQ(1, cache.disk_cache()->create_count());
4588 RemoveMockTransaction(&kRangeGET_TransactionOK);
4591 // Tests that we don't delete a sparse entry when we cancel a request.
4592 TEST(HttpCache, RangeGET_Cancel) {
4593 MockHttpCache cache;
4594 AddMockTransaction(&kRangeGET_TransactionOK);
4596 MockHttpRequest request(kRangeGET_TransactionOK);
4598 Context* c = new Context();
4599 int rv = cache.CreateTransaction(&c->trans);
4600 ASSERT_EQ(net::OK, rv);
4602 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4603 if (rv == net::ERR_IO_PENDING)
4604 rv = c->callback.WaitForResult();
4606 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4607 EXPECT_EQ(0, cache.disk_cache()->open_count());
4608 EXPECT_EQ(1, cache.disk_cache()->create_count());
4610 // Make sure that the entry has some data stored.
4611 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4612 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4613 if (rv == net::ERR_IO_PENDING)
4614 rv = c->callback.WaitForResult();
4615 EXPECT_EQ(buf->size(), rv);
4617 // Destroy the transaction.
4618 delete c;
4620 // Verify that the entry has not been deleted.
4621 disk_cache::Entry* entry;
4622 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4623 entry->Close();
4624 RemoveMockTransaction(&kRangeGET_TransactionOK);
4627 // Tests that we don't delete a sparse entry when we start a new request after
4628 // cancelling the previous one.
4629 TEST(HttpCache, RangeGET_Cancel2) {
4630 MockHttpCache cache;
4631 AddMockTransaction(&kRangeGET_TransactionOK);
4633 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4634 MockHttpRequest request(kRangeGET_TransactionOK);
4635 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4637 Context* c = new Context();
4638 int rv = cache.CreateTransaction(&c->trans);
4639 ASSERT_EQ(net::OK, rv);
4641 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4642 if (rv == net::ERR_IO_PENDING)
4643 rv = c->callback.WaitForResult();
4645 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4646 EXPECT_EQ(1, cache.disk_cache()->open_count());
4647 EXPECT_EQ(1, cache.disk_cache()->create_count());
4649 // Make sure that we revalidate the entry and read from the cache (a single
4650 // read will return while waiting for the network).
4651 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4652 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4653 EXPECT_EQ(5, c->callback.GetResult(rv));
4654 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4655 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4657 // Destroy the transaction before completing the read.
4658 delete c;
4660 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4661 // message loop. This means that a new transaction will just reuse the same
4662 // active entry (no open or create).
4664 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4666 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4667 EXPECT_EQ(1, cache.disk_cache()->open_count());
4668 EXPECT_EQ(1, cache.disk_cache()->create_count());
4669 RemoveMockTransaction(&kRangeGET_TransactionOK);
4672 // A slight variation of the previous test, this time we cancel two requests in
4673 // a row, making sure that the second is waiting for the entry to be ready.
4674 TEST(HttpCache, RangeGET_Cancel3) {
4675 MockHttpCache cache;
4676 AddMockTransaction(&kRangeGET_TransactionOK);
4678 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4679 MockHttpRequest request(kRangeGET_TransactionOK);
4680 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4682 Context* c = new Context();
4683 int rv = cache.CreateTransaction(&c->trans);
4684 ASSERT_EQ(net::OK, rv);
4686 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4687 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4688 rv = c->callback.WaitForResult();
4690 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4691 EXPECT_EQ(1, cache.disk_cache()->open_count());
4692 EXPECT_EQ(1, cache.disk_cache()->create_count());
4694 // Make sure that we revalidate the entry and read from the cache (a single
4695 // read will return while waiting for the network).
4696 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4697 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4698 EXPECT_EQ(5, c->callback.GetResult(rv));
4699 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4700 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4702 // Destroy the transaction before completing the read.
4703 delete c;
4705 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4706 // message loop. This means that a new transaction will just reuse the same
4707 // active entry (no open or create).
4709 c = new Context();
4710 rv = cache.CreateTransaction(&c->trans);
4711 ASSERT_EQ(net::OK, rv);
4713 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4714 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4716 MockDiskEntry::IgnoreCallbacks(true);
4717 base::MessageLoop::current()->RunUntilIdle();
4718 MockDiskEntry::IgnoreCallbacks(false);
4720 // The new transaction is waiting for the query range callback.
4721 delete c;
4723 // And we should not crash when the callback is delivered.
4724 base::MessageLoop::current()->RunUntilIdle();
4726 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4727 EXPECT_EQ(1, cache.disk_cache()->open_count());
4728 EXPECT_EQ(1, cache.disk_cache()->create_count());
4729 RemoveMockTransaction(&kRangeGET_TransactionOK);
4732 // Tests that an invalid range response results in no cached entry.
4733 TEST(HttpCache, RangeGET_InvalidResponse1) {
4734 MockHttpCache cache;
4735 std::string headers;
4737 MockTransaction transaction(kRangeGET_TransactionOK);
4738 transaction.handler = NULL;
4739 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4740 "Content-Length: 10\n";
4741 AddMockTransaction(&transaction);
4742 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4744 std::string expected(transaction.status);
4745 expected.append("\n");
4746 expected.append(transaction.response_headers);
4747 EXPECT_EQ(expected, headers);
4749 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4750 EXPECT_EQ(0, cache.disk_cache()->open_count());
4751 EXPECT_EQ(1, cache.disk_cache()->create_count());
4753 // Verify that we don't have a cached entry.
4754 disk_cache::Entry* entry;
4755 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4757 RemoveMockTransaction(&kRangeGET_TransactionOK);
4760 // Tests that we reject a range that doesn't match the content-length.
4761 TEST(HttpCache, RangeGET_InvalidResponse2) {
4762 MockHttpCache cache;
4763 std::string headers;
4765 MockTransaction transaction(kRangeGET_TransactionOK);
4766 transaction.handler = NULL;
4767 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4768 "Content-Length: 20\n";
4769 AddMockTransaction(&transaction);
4770 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4772 std::string expected(transaction.status);
4773 expected.append("\n");
4774 expected.append(transaction.response_headers);
4775 EXPECT_EQ(expected, headers);
4777 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4778 EXPECT_EQ(0, cache.disk_cache()->open_count());
4779 EXPECT_EQ(1, cache.disk_cache()->create_count());
4781 // Verify that we don't have a cached entry.
4782 disk_cache::Entry* entry;
4783 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4785 RemoveMockTransaction(&kRangeGET_TransactionOK);
4788 // Tests that if a server tells us conflicting information about a resource we
4789 // ignore the response.
4790 TEST(HttpCache, RangeGET_InvalidResponse3) {
4791 MockHttpCache cache;
4792 std::string headers;
4794 MockTransaction transaction(kRangeGET_TransactionOK);
4795 transaction.handler = NULL;
4796 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4797 std::string response_headers(transaction.response_headers);
4798 response_headers.append("Content-Range: bytes 50-59/160\n");
4799 transaction.response_headers = response_headers.c_str();
4800 AddMockTransaction(&transaction);
4801 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4803 Verify206Response(headers, 50, 59);
4804 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4805 EXPECT_EQ(0, cache.disk_cache()->open_count());
4806 EXPECT_EQ(1, cache.disk_cache()->create_count());
4808 RemoveMockTransaction(&transaction);
4809 AddMockTransaction(&kRangeGET_TransactionOK);
4811 // This transaction will report a resource size of 80 bytes, and we think it's
4812 // 160 so we should ignore the response.
4813 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4814 &headers);
4816 Verify206Response(headers, 40, 49);
4817 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4818 EXPECT_EQ(1, cache.disk_cache()->open_count());
4819 EXPECT_EQ(1, cache.disk_cache()->create_count());
4821 // Verify that we cached the first response but not the second one.
4822 disk_cache::Entry* en;
4823 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4825 int64 cached_start = 0;
4826 net::TestCompletionCallback cb;
4827 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4828 EXPECT_EQ(10, cb.GetResult(rv));
4829 EXPECT_EQ(50, cached_start);
4830 en->Close();
4832 RemoveMockTransaction(&kRangeGET_TransactionOK);
4835 // Tests that we handle large range values properly.
4836 TEST(HttpCache, RangeGET_LargeValues) {
4837 // We need a real sparse cache for this test.
4838 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4839 std::string headers;
4841 MockTransaction transaction(kRangeGET_TransactionOK);
4842 transaction.handler = NULL;
4843 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4844 EXTRA_HEADER;
4845 transaction.response_headers =
4846 "ETag: \"foo\"\n"
4847 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4848 "Content-Length: 10\n";
4849 AddMockTransaction(&transaction);
4850 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4852 std::string expected(transaction.status);
4853 expected.append("\n");
4854 expected.append(transaction.response_headers);
4855 EXPECT_EQ(expected, headers);
4857 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4859 // Verify that we have a cached entry.
4860 disk_cache::Entry* en;
4861 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4862 en->Close();
4864 RemoveMockTransaction(&kRangeGET_TransactionOK);
4867 // Tests that we don't crash with a range request if the disk cache was not
4868 // initialized properly.
4869 TEST(HttpCache, RangeGET_NoDiskCache) {
4870 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4871 factory->set_fail(true);
4872 factory->FinishCreation(); // We'll complete synchronously.
4873 MockHttpCache cache(factory);
4875 AddMockTransaction(&kRangeGET_TransactionOK);
4877 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4878 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4880 RemoveMockTransaction(&kRangeGET_TransactionOK);
4883 // Tests that we handle byte range requests that skip the cache.
4884 TEST(HttpCache, RangeHEAD) {
4885 MockHttpCache cache;
4886 AddMockTransaction(&kRangeGET_TransactionOK);
4888 MockTransaction transaction(kRangeGET_TransactionOK);
4889 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4890 transaction.method = "HEAD";
4891 transaction.data = "rg: 70-79 ";
4893 std::string headers;
4894 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4896 Verify206Response(headers, 70, 79);
4897 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4898 EXPECT_EQ(0, cache.disk_cache()->open_count());
4899 EXPECT_EQ(0, cache.disk_cache()->create_count());
4901 RemoveMockTransaction(&kRangeGET_TransactionOK);
4904 // Tests that we don't crash when after reading from the cache we issue a
4905 // request for the next range and the server gives us a 200 synchronously.
4906 TEST(HttpCache, RangeGET_FastFlakyServer) {
4907 MockHttpCache cache;
4909 MockTransaction transaction(kRangeGET_TransactionOK);
4910 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4911 transaction.test_mode = TEST_MODE_SYNC_NET_START;
4912 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4913 AddMockTransaction(&transaction);
4915 // Write to the cache.
4916 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4918 // And now read from the cache and the network.
4919 RangeTransactionServer handler;
4920 handler.set_bad_200(true);
4921 transaction.data = "Not a range";
4922 RunTransactionTest(cache.http_cache(), transaction);
4924 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4925 EXPECT_EQ(1, cache.disk_cache()->open_count());
4926 EXPECT_EQ(1, cache.disk_cache()->create_count());
4928 RemoveMockTransaction(&transaction);
4931 // Tests that when the server gives us less data than expected, we don't keep
4932 // asking for more data.
4933 TEST(HttpCache, RangeGET_FastFlakyServer2) {
4934 MockHttpCache cache;
4936 // First, check with an empty cache (WRITE mode).
4937 MockTransaction transaction(kRangeGET_TransactionOK);
4938 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4939 transaction.data = "rg: 40-"; // Less than expected.
4940 transaction.handler = NULL;
4941 std::string headers(transaction.response_headers);
4942 headers.append("Content-Range: bytes 40-49/80\n");
4943 transaction.response_headers = headers.c_str();
4945 AddMockTransaction(&transaction);
4947 // Write to the cache.
4948 RunTransactionTest(cache.http_cache(), transaction);
4950 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4951 EXPECT_EQ(0, cache.disk_cache()->open_count());
4952 EXPECT_EQ(1, cache.disk_cache()->create_count());
4954 // Now verify that even in READ_WRITE mode, we forward the bad response to
4955 // the caller.
4956 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4957 transaction.data = "rg: 60-"; // Less than expected.
4958 headers = kRangeGET_TransactionOK.response_headers;
4959 headers.append("Content-Range: bytes 60-69/80\n");
4960 transaction.response_headers = headers.c_str();
4962 RunTransactionTest(cache.http_cache(), transaction);
4964 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4965 EXPECT_EQ(1, cache.disk_cache()->open_count());
4966 EXPECT_EQ(1, cache.disk_cache()->create_count());
4968 RemoveMockTransaction(&transaction);
4971 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
4972 // This test hits a NOTREACHED so it is a release mode only test.
4973 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
4974 MockHttpCache cache;
4975 AddMockTransaction(&kRangeGET_TransactionOK);
4977 // Write to the cache (40-49).
4978 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4979 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4980 EXPECT_EQ(0, cache.disk_cache()->open_count());
4981 EXPECT_EQ(1, cache.disk_cache()->create_count());
4983 // Force this transaction to read from the cache.
4984 MockTransaction transaction(kRangeGET_TransactionOK);
4985 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4987 MockHttpRequest request(transaction);
4988 net::TestCompletionCallback callback;
4990 scoped_ptr<net::HttpTransaction> trans;
4991 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
4992 EXPECT_EQ(net::OK, rv);
4993 ASSERT_TRUE(trans.get());
4995 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
4996 if (rv == net::ERR_IO_PENDING)
4997 rv = callback.WaitForResult();
4998 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5000 trans.reset();
5002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5003 EXPECT_EQ(1, cache.disk_cache()->open_count());
5004 EXPECT_EQ(1, cache.disk_cache()->create_count());
5006 RemoveMockTransaction(&kRangeGET_TransactionOK);
5008 #endif
5010 // Tests the handling of the "truncation" flag.
5011 TEST(HttpCache, WriteResponseInfo_Truncated) {
5012 MockHttpCache cache;
5013 disk_cache::Entry* entry;
5014 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5015 NULL));
5017 std::string headers("HTTP/1.1 200 OK");
5018 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5019 net::HttpResponseInfo response;
5020 response.headers = new net::HttpResponseHeaders(headers);
5022 // Set the last argument for this to be an incomplete request.
5023 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
5024 bool truncated = false;
5025 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5026 EXPECT_TRUE(truncated);
5028 // And now test the opposite case.
5029 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
5030 truncated = true;
5031 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5032 EXPECT_FALSE(truncated);
5033 entry->Close();
5036 // Tests basic pickling/unpickling of HttpResponseInfo.
5037 TEST(HttpCache, PersistHttpResponseInfo) {
5038 // Set some fields (add more if needed.)
5039 net::HttpResponseInfo response1;
5040 response1.was_cached = false;
5041 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
5042 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5044 // Pickle.
5045 Pickle pickle;
5046 response1.Persist(&pickle, false, false);
5048 // Unpickle.
5049 net::HttpResponseInfo response2;
5050 bool response_truncated;
5051 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5052 EXPECT_FALSE(response_truncated);
5054 // Verify fields.
5055 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5056 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5057 EXPECT_EQ(80, response2.socket_address.port());
5058 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5061 // Tests that we delete an entry when the request is cancelled before starting
5062 // to read from the network.
5063 TEST(HttpCache, DoomOnDestruction) {
5064 MockHttpCache cache;
5066 MockHttpRequest request(kSimpleGET_Transaction);
5068 Context* c = new Context();
5069 int rv = cache.CreateTransaction(&c->trans);
5070 ASSERT_EQ(net::OK, rv);
5072 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5073 if (rv == net::ERR_IO_PENDING)
5074 c->result = c->callback.WaitForResult();
5076 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5077 EXPECT_EQ(0, cache.disk_cache()->open_count());
5078 EXPECT_EQ(1, cache.disk_cache()->create_count());
5080 // Destroy the transaction. We only have the headers so we should delete this
5081 // entry.
5082 delete c;
5084 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5086 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5087 EXPECT_EQ(0, cache.disk_cache()->open_count());
5088 EXPECT_EQ(2, cache.disk_cache()->create_count());
5091 // Tests that we delete an entry when the request is cancelled if the response
5092 // does not have content-length and strong validators.
5093 TEST(HttpCache, DoomOnDestruction2) {
5094 MockHttpCache cache;
5096 MockHttpRequest request(kSimpleGET_Transaction);
5098 Context* c = new Context();
5099 int rv = cache.CreateTransaction(&c->trans);
5100 ASSERT_EQ(net::OK, rv);
5102 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5103 if (rv == net::ERR_IO_PENDING)
5104 rv = c->callback.WaitForResult();
5106 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5107 EXPECT_EQ(0, cache.disk_cache()->open_count());
5108 EXPECT_EQ(1, cache.disk_cache()->create_count());
5110 // Make sure that the entry has some data stored.
5111 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5112 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5113 if (rv == net::ERR_IO_PENDING)
5114 rv = c->callback.WaitForResult();
5115 EXPECT_EQ(buf->size(), rv);
5117 // Destroy the transaction.
5118 delete c;
5120 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5122 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5123 EXPECT_EQ(0, cache.disk_cache()->open_count());
5124 EXPECT_EQ(2, cache.disk_cache()->create_count());
5127 // Tests that we delete an entry when the request is cancelled if the response
5128 // has an "Accept-Ranges: none" header.
5129 TEST(HttpCache, DoomOnDestruction3) {
5130 MockHttpCache cache;
5132 MockTransaction transaction(kSimpleGET_Transaction);
5133 transaction.response_headers =
5134 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5135 "Content-Length: 22\n"
5136 "Accept-Ranges: none\n"
5137 "Etag: \"foopy\"\n";
5138 AddMockTransaction(&transaction);
5139 MockHttpRequest request(transaction);
5141 Context* c = new Context();
5142 int rv = cache.CreateTransaction(&c->trans);
5143 ASSERT_EQ(net::OK, rv);
5145 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5146 if (rv == net::ERR_IO_PENDING)
5147 rv = c->callback.WaitForResult();
5149 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5150 EXPECT_EQ(0, cache.disk_cache()->open_count());
5151 EXPECT_EQ(1, cache.disk_cache()->create_count());
5153 // Make sure that the entry has some data stored.
5154 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5155 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5156 if (rv == net::ERR_IO_PENDING)
5157 rv = c->callback.WaitForResult();
5158 EXPECT_EQ(buf->size(), rv);
5160 // Destroy the transaction.
5161 delete c;
5163 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5165 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5166 EXPECT_EQ(0, cache.disk_cache()->open_count());
5167 EXPECT_EQ(2, cache.disk_cache()->create_count());
5169 RemoveMockTransaction(&transaction);
5172 // Tests that we mark an entry as incomplete when the request is cancelled.
5173 TEST(HttpCache, SetTruncatedFlag) {
5174 MockHttpCache cache;
5176 MockTransaction transaction(kSimpleGET_Transaction);
5177 transaction.response_headers =
5178 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5179 "Content-Length: 22\n"
5180 "Etag: \"foopy\"\n";
5181 AddMockTransaction(&transaction);
5182 MockHttpRequest request(transaction);
5184 scoped_ptr<Context> c(new Context());
5186 int rv = cache.CreateTransaction(&c->trans);
5187 ASSERT_EQ(net::OK, rv);
5189 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5190 if (rv == net::ERR_IO_PENDING)
5191 rv = c->callback.WaitForResult();
5193 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5194 EXPECT_EQ(0, cache.disk_cache()->open_count());
5195 EXPECT_EQ(1, cache.disk_cache()->create_count());
5197 // Make sure that the entry has some data stored.
5198 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5199 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5200 if (rv == net::ERR_IO_PENDING)
5201 rv = c->callback.WaitForResult();
5202 EXPECT_EQ(buf->size(), rv);
5204 // We want to cancel the request when the transaction is busy.
5205 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5206 EXPECT_EQ(net::ERR_IO_PENDING, rv);
5207 EXPECT_FALSE(c->callback.have_result());
5209 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
5211 // Destroy the transaction.
5212 c->trans.reset();
5213 MockHttpCache::SetTestMode(0);
5216 // Make sure that we don't invoke the callback. We may have an issue if the
5217 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5218 // could end up with the transaction being deleted twice if we send any
5219 // notification from the transaction destructor (see http://crbug.com/31723).
5220 EXPECT_FALSE(c->callback.have_result());
5222 // Verify that the entry is marked as incomplete.
5223 disk_cache::Entry* entry;
5224 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5225 net::HttpResponseInfo response;
5226 bool truncated = false;
5227 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5228 EXPECT_TRUE(truncated);
5229 entry->Close();
5231 RemoveMockTransaction(&transaction);
5234 // Tests that we don't mark an entry as truncated when we read everything.
5235 TEST(HttpCache, DontSetTruncatedFlag) {
5236 MockHttpCache cache;
5238 MockTransaction transaction(kSimpleGET_Transaction);
5239 transaction.response_headers =
5240 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5241 "Content-Length: 22\n"
5242 "Etag: \"foopy\"\n";
5243 AddMockTransaction(&transaction);
5244 MockHttpRequest request(transaction);
5246 scoped_ptr<Context> c(new Context());
5247 int rv = cache.CreateTransaction(&c->trans);
5248 ASSERT_EQ(net::OK, rv);
5250 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5251 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5253 // Read everything.
5254 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
5255 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5256 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5258 // Destroy the transaction.
5259 c->trans.reset();
5261 // Verify that the entry is not marked as truncated.
5262 disk_cache::Entry* entry;
5263 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5264 net::HttpResponseInfo response;
5265 bool truncated = true;
5266 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5267 EXPECT_FALSE(truncated);
5268 entry->Close();
5270 RemoveMockTransaction(&transaction);
5273 // Tests that we can continue with a request that was interrupted.
5274 TEST(HttpCache, GET_IncompleteResource) {
5275 MockHttpCache cache;
5276 AddMockTransaction(&kRangeGET_TransactionOK);
5278 std::string raw_headers("HTTP/1.1 200 OK\n"
5279 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5280 "ETag: \"foo\"\n"
5281 "Accept-Ranges: bytes\n"
5282 "Content-Length: 80\n");
5283 CreateTruncatedEntry(raw_headers, &cache);
5285 // Now make a regular request.
5286 std::string headers;
5287 MockTransaction transaction(kRangeGET_TransactionOK);
5288 transaction.request_headers = EXTRA_HEADER;
5289 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5290 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5291 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5293 // We update the headers with the ones received while revalidating.
5294 std::string expected_headers(
5295 "HTTP/1.1 200 OK\n"
5296 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5297 "Accept-Ranges: bytes\n"
5298 "ETag: \"foo\"\n"
5299 "Content-Length: 80\n");
5301 EXPECT_EQ(expected_headers, headers);
5302 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5303 EXPECT_EQ(1, cache.disk_cache()->open_count());
5304 EXPECT_EQ(1, cache.disk_cache()->create_count());
5306 // Verify that the disk entry was updated.
5307 disk_cache::Entry* entry;
5308 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5309 EXPECT_EQ(80, entry->GetDataSize(1));
5310 bool truncated = true;
5311 net::HttpResponseInfo response;
5312 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5313 EXPECT_FALSE(truncated);
5314 entry->Close();
5316 RemoveMockTransaction(&kRangeGET_TransactionOK);
5319 // Tests the handling of no-store when revalidating a truncated entry.
5320 TEST(HttpCache, GET_IncompleteResource_NoStore) {
5321 MockHttpCache cache;
5322 AddMockTransaction(&kRangeGET_TransactionOK);
5324 std::string raw_headers("HTTP/1.1 200 OK\n"
5325 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5326 "ETag: \"foo\"\n"
5327 "Accept-Ranges: bytes\n"
5328 "Content-Length: 80\n");
5329 CreateTruncatedEntry(raw_headers, &cache);
5330 RemoveMockTransaction(&kRangeGET_TransactionOK);
5332 // Now make a regular request.
5333 MockTransaction transaction(kRangeGET_TransactionOK);
5334 transaction.request_headers = EXTRA_HEADER;
5335 std::string response_headers(transaction.response_headers);
5336 response_headers += ("Cache-Control: no-store\n");
5337 transaction.response_headers = response_headers.c_str();
5338 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5339 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5340 AddMockTransaction(&transaction);
5342 std::string headers;
5343 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5345 // We update the headers with the ones received while revalidating.
5346 std::string expected_headers(
5347 "HTTP/1.1 200 OK\n"
5348 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5349 "Accept-Ranges: bytes\n"
5350 "Cache-Control: no-store\n"
5351 "ETag: \"foo\"\n"
5352 "Content-Length: 80\n");
5354 EXPECT_EQ(expected_headers, headers);
5355 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5356 EXPECT_EQ(1, cache.disk_cache()->open_count());
5357 EXPECT_EQ(1, cache.disk_cache()->create_count());
5359 // Verify that the disk entry was deleted.
5360 disk_cache::Entry* entry;
5361 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5362 RemoveMockTransaction(&transaction);
5365 // Tests cancelling a request after the server sent no-store.
5366 TEST(HttpCache, GET_IncompleteResource_Cancel) {
5367 MockHttpCache cache;
5368 AddMockTransaction(&kRangeGET_TransactionOK);
5370 std::string raw_headers("HTTP/1.1 200 OK\n"
5371 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5372 "ETag: \"foo\"\n"
5373 "Accept-Ranges: bytes\n"
5374 "Content-Length: 80\n");
5375 CreateTruncatedEntry(raw_headers, &cache);
5376 RemoveMockTransaction(&kRangeGET_TransactionOK);
5378 // Now make a regular request.
5379 MockTransaction transaction(kRangeGET_TransactionOK);
5380 transaction.request_headers = EXTRA_HEADER;
5381 std::string response_headers(transaction.response_headers);
5382 response_headers += ("Cache-Control: no-store\n");
5383 transaction.response_headers = response_headers.c_str();
5384 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5385 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5386 AddMockTransaction(&transaction);
5388 MockHttpRequest request(transaction);
5389 Context* c = new Context();
5391 int rv = cache.CreateTransaction(&c->trans);
5392 ASSERT_EQ(net::OK, rv);
5394 // Queue another request to this transaction. We have to start this request
5395 // before the first one gets the response from the server and dooms the entry,
5396 // otherwise it will just create a new entry without being queued to the first
5397 // request.
5398 Context* pending = new Context();
5399 ASSERT_EQ(net::OK, cache.CreateTransaction(&pending->trans));
5401 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5402 EXPECT_EQ(net::ERR_IO_PENDING,
5403 pending->trans->Start(&request, pending->callback.callback(),
5404 net::BoundNetLog()));
5405 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5407 // Make sure that the entry has some data stored.
5408 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
5409 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5410 EXPECT_EQ(5, c->callback.GetResult(rv));
5412 // Cancel the requests.
5413 delete c;
5414 delete pending;
5416 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5417 EXPECT_EQ(1, cache.disk_cache()->open_count());
5418 EXPECT_EQ(2, cache.disk_cache()->create_count());
5420 base::MessageLoop::current()->RunUntilIdle();
5421 RemoveMockTransaction(&transaction);
5424 // Tests that we delete truncated entries if the server changes its mind midway.
5425 TEST(HttpCache, GET_IncompleteResource2) {
5426 MockHttpCache cache;
5427 AddMockTransaction(&kRangeGET_TransactionOK);
5429 // Content-length will be intentionally bad.
5430 std::string raw_headers("HTTP/1.1 200 OK\n"
5431 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5432 "ETag: \"foo\"\n"
5433 "Accept-Ranges: bytes\n"
5434 "Content-Length: 50\n");
5435 CreateTruncatedEntry(raw_headers, &cache);
5437 // Now make a regular request. We expect the code to fail the validation and
5438 // retry the request without using byte ranges.
5439 std::string headers;
5440 MockTransaction transaction(kRangeGET_TransactionOK);
5441 transaction.request_headers = EXTRA_HEADER;
5442 transaction.data = "Not a range";
5443 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5445 // The server will return 200 instead of a byte range.
5446 std::string expected_headers(
5447 "HTTP/1.1 200 OK\n"
5448 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5450 EXPECT_EQ(expected_headers, headers);
5451 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache.disk_cache()->open_count());
5453 EXPECT_EQ(1, cache.disk_cache()->create_count());
5455 // Verify that the disk entry was deleted.
5456 disk_cache::Entry* entry;
5457 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5458 RemoveMockTransaction(&kRangeGET_TransactionOK);
5461 // Tests that we always validate a truncated request.
5462 TEST(HttpCache, GET_IncompleteResource3) {
5463 MockHttpCache cache;
5464 AddMockTransaction(&kRangeGET_TransactionOK);
5466 // This should not require validation for 10 hours.
5467 std::string raw_headers("HTTP/1.1 200 OK\n"
5468 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5469 "ETag: \"foo\"\n"
5470 "Cache-Control: max-age= 36000\n"
5471 "Accept-Ranges: bytes\n"
5472 "Content-Length: 80\n");
5473 CreateTruncatedEntry(raw_headers, &cache);
5475 // Now make a regular request.
5476 std::string headers;
5477 MockTransaction transaction(kRangeGET_TransactionOK);
5478 transaction.request_headers = EXTRA_HEADER;
5479 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5480 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5482 scoped_ptr<Context> c(new Context);
5483 int rv = cache.CreateTransaction(&c->trans);
5484 ASSERT_EQ(net::OK, rv);
5486 MockHttpRequest request(transaction);
5487 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5488 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5490 // We should have checked with the server before finishing Start().
5491 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5492 EXPECT_EQ(1, cache.disk_cache()->open_count());
5493 EXPECT_EQ(1, cache.disk_cache()->create_count());
5495 RemoveMockTransaction(&kRangeGET_TransactionOK);
5498 // Tests that we handle 401s for truncated resources.
5499 TEST(HttpCache, GET_IncompleteResourceWithAuth) {
5500 MockHttpCache cache;
5501 AddMockTransaction(&kRangeGET_TransactionOK);
5503 std::string raw_headers("HTTP/1.1 200 OK\n"
5504 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5505 "ETag: \"foo\"\n"
5506 "Accept-Ranges: bytes\n"
5507 "Content-Length: 80\n");
5508 CreateTruncatedEntry(raw_headers, &cache);
5510 // Now make a regular request.
5511 MockTransaction transaction(kRangeGET_TransactionOK);
5512 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
5513 EXTRA_HEADER;
5514 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5515 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5516 RangeTransactionServer handler;
5518 scoped_ptr<Context> c(new Context);
5519 int rv = cache.CreateTransaction(&c->trans);
5520 ASSERT_EQ(net::OK, rv);
5522 MockHttpRequest request(transaction);
5523 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5524 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5526 const net::HttpResponseInfo* response = c->trans->GetResponseInfo();
5527 ASSERT_TRUE(response);
5528 ASSERT_EQ(401, response->headers->response_code());
5529 rv = c->trans->RestartWithAuth(net::AuthCredentials(),
5530 c->callback.callback());
5531 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5532 response = c->trans->GetResponseInfo();
5533 ASSERT_TRUE(response);
5534 ASSERT_EQ(200, response->headers->response_code());
5536 ReadAndVerifyTransaction(c->trans.get(), transaction);
5537 c.reset(); // The destructor could delete the entry.
5538 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5540 // Verify that the entry was not deleted.
5541 disk_cache::Entry* entry;
5542 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5543 entry->Close();
5545 RemoveMockTransaction(&kRangeGET_TransactionOK);
5548 // Tests that we cache a 200 response to the validation request.
5549 TEST(HttpCache, GET_IncompleteResource4) {
5550 MockHttpCache cache;
5551 AddMockTransaction(&kRangeGET_TransactionOK);
5553 std::string raw_headers("HTTP/1.1 200 OK\n"
5554 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5555 "ETag: \"foo\"\n"
5556 "Accept-Ranges: bytes\n"
5557 "Content-Length: 80\n");
5558 CreateTruncatedEntry(raw_headers, &cache);
5560 // Now make a regular request.
5561 std::string headers;
5562 MockTransaction transaction(kRangeGET_TransactionOK);
5563 transaction.request_headers = EXTRA_HEADER;
5564 transaction.data = "Not a range";
5565 RangeTransactionServer handler;
5566 handler.set_bad_200(true);
5567 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5569 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5570 EXPECT_EQ(1, cache.disk_cache()->open_count());
5571 EXPECT_EQ(1, cache.disk_cache()->create_count());
5573 // Verify that the disk entry was updated.
5574 disk_cache::Entry* entry;
5575 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5576 EXPECT_EQ(11, entry->GetDataSize(1));
5577 bool truncated = true;
5578 net::HttpResponseInfo response;
5579 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5580 EXPECT_FALSE(truncated);
5581 entry->Close();
5583 RemoveMockTransaction(&kRangeGET_TransactionOK);
5586 // Tests that when we cancel a request that was interrupted, we mark it again
5587 // as truncated.
5588 TEST(HttpCache, GET_CancelIncompleteResource) {
5589 MockHttpCache cache;
5590 AddMockTransaction(&kRangeGET_TransactionOK);
5592 std::string raw_headers("HTTP/1.1 200 OK\n"
5593 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5594 "ETag: \"foo\"\n"
5595 "Accept-Ranges: bytes\n"
5596 "Content-Length: 80\n");
5597 CreateTruncatedEntry(raw_headers, &cache);
5599 // Now make a regular request.
5600 MockTransaction transaction(kRangeGET_TransactionOK);
5601 transaction.request_headers = EXTRA_HEADER;
5603 MockHttpRequest request(transaction);
5604 Context* c = new Context();
5605 int rv = cache.CreateTransaction(&c->trans);
5606 ASSERT_EQ(net::OK, rv);
5608 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5609 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5611 // Read 20 bytes from the cache, and 10 from the net.
5612 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5613 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5614 EXPECT_EQ(20, c->callback.GetResult(rv));
5615 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5616 EXPECT_EQ(10, c->callback.GetResult(rv));
5618 // At this point, we are already reading so canceling the request should leave
5619 // a truncated one.
5620 delete c;
5622 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5623 EXPECT_EQ(1, cache.disk_cache()->open_count());
5624 EXPECT_EQ(1, cache.disk_cache()->create_count());
5626 // Verify that the disk entry was updated: now we have 30 bytes.
5627 disk_cache::Entry* entry;
5628 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5629 EXPECT_EQ(30, entry->GetDataSize(1));
5630 bool truncated = false;
5631 net::HttpResponseInfo response;
5632 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5633 EXPECT_TRUE(truncated);
5634 entry->Close();
5635 RemoveMockTransaction(&kRangeGET_TransactionOK);
5638 // Tests that we can handle range requests when we have a truncated entry.
5639 TEST(HttpCache, RangeGET_IncompleteResource) {
5640 MockHttpCache cache;
5641 AddMockTransaction(&kRangeGET_TransactionOK);
5643 // Content-length will be intentionally bogus.
5644 std::string raw_headers("HTTP/1.1 200 OK\n"
5645 "Last-Modified: something\n"
5646 "ETag: \"foo\"\n"
5647 "Accept-Ranges: bytes\n"
5648 "Content-Length: 10\n");
5649 CreateTruncatedEntry(raw_headers, &cache);
5651 // Now make a range request.
5652 std::string headers;
5653 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5654 &headers);
5656 Verify206Response(headers, 40, 49);
5657 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5658 EXPECT_EQ(1, cache.disk_cache()->open_count());
5659 EXPECT_EQ(2, cache.disk_cache()->create_count());
5661 RemoveMockTransaction(&kRangeGET_TransactionOK);
5664 TEST(HttpCache, SyncRead) {
5665 MockHttpCache cache;
5667 // This test ensures that a read that completes synchronously does not cause
5668 // any problems.
5670 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5671 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5672 TEST_MODE_SYNC_CACHE_READ |
5673 TEST_MODE_SYNC_CACHE_WRITE);
5675 MockHttpRequest r1(transaction),
5676 r2(transaction),
5677 r3(transaction);
5679 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5680 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5681 c3(net::DEFAULT_PRIORITY, cache.http_cache());
5683 c1.Start(&r1, net::BoundNetLog());
5685 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5686 c2.Start(&r2, net::BoundNetLog());
5688 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5689 c3.Start(&r3, net::BoundNetLog());
5691 base::MessageLoop::current()->Run();
5693 EXPECT_TRUE(c1.is_done());
5694 EXPECT_TRUE(c2.is_done());
5695 EXPECT_TRUE(c3.is_done());
5697 EXPECT_EQ(net::OK, c1.error());
5698 EXPECT_EQ(net::OK, c2.error());
5699 EXPECT_EQ(net::OK, c3.error());
5702 TEST(HttpCache, ValidationResultsIn200) {
5703 MockHttpCache cache;
5705 // This test ensures that a conditional request, which results in a 200
5706 // instead of a 304, properly truncates the existing response data.
5708 // write to the cache
5709 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5711 // force this transaction to validate the cache
5712 MockTransaction transaction(kETagGET_Transaction);
5713 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5714 RunTransactionTest(cache.http_cache(), transaction);
5716 // read from the cache
5717 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5720 TEST(HttpCache, CachedRedirect) {
5721 MockHttpCache cache;
5723 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5724 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5725 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5727 MockHttpRequest request(kTestTransaction);
5728 net::TestCompletionCallback callback;
5730 // Write to the cache.
5732 scoped_ptr<net::HttpTransaction> trans;
5733 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5735 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5736 if (rv == net::ERR_IO_PENDING)
5737 rv = callback.WaitForResult();
5738 ASSERT_EQ(net::OK, rv);
5740 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5741 ASSERT_TRUE(info);
5743 EXPECT_EQ(info->headers->response_code(), 301);
5745 std::string location;
5746 info->headers->EnumerateHeader(NULL, "Location", &location);
5747 EXPECT_EQ(location, "http://www.bar.com/");
5749 // Mark the transaction as completed so it is cached.
5750 trans->DoneReading();
5752 // Destroy transaction when going out of scope. We have not actually
5753 // read the response body -- want to test that it is still getting cached.
5755 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5756 EXPECT_EQ(0, cache.disk_cache()->open_count());
5757 EXPECT_EQ(1, cache.disk_cache()->create_count());
5759 // Active entries in the cache are not retired synchronously. Make
5760 // sure the next run hits the MockHttpCache and open_count is
5761 // correct.
5762 base::MessageLoop::current()->RunUntilIdle();
5764 // Read from the cache.
5766 scoped_ptr<net::HttpTransaction> trans;
5767 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5769 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5770 if (rv == net::ERR_IO_PENDING)
5771 rv = callback.WaitForResult();
5772 ASSERT_EQ(net::OK, rv);
5774 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5775 ASSERT_TRUE(info);
5777 EXPECT_EQ(info->headers->response_code(), 301);
5779 std::string location;
5780 info->headers->EnumerateHeader(NULL, "Location", &location);
5781 EXPECT_EQ(location, "http://www.bar.com/");
5783 // Mark the transaction as completed so it is cached.
5784 trans->DoneReading();
5786 // Destroy transaction when going out of scope. We have not actually
5787 // read the response body -- want to test that it is still getting cached.
5789 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5790 EXPECT_EQ(1, cache.disk_cache()->open_count());
5791 EXPECT_EQ(1, cache.disk_cache()->create_count());
5794 // Verify that no-cache resources are stored in cache, but are not fetched from
5795 // cache during normal loads.
5796 TEST(HttpCache, CacheControlNoCacheNormalLoad) {
5797 MockHttpCache cache;
5799 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5800 transaction.response_headers = "cache-control: no-cache\n";
5802 // Initial load.
5803 RunTransactionTest(cache.http_cache(), transaction);
5805 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5806 EXPECT_EQ(0, cache.disk_cache()->open_count());
5807 EXPECT_EQ(1, cache.disk_cache()->create_count());
5809 // Try loading again; it should result in a network fetch.
5810 RunTransactionTest(cache.http_cache(), transaction);
5812 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5813 EXPECT_EQ(1, cache.disk_cache()->open_count());
5814 EXPECT_EQ(1, cache.disk_cache()->create_count());
5816 disk_cache::Entry* entry;
5817 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5818 entry->Close();
5821 // Verify that no-cache resources are stored in cache and fetched from cache
5822 // when the LOAD_PREFERRING_CACHE flag is set.
5823 TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
5824 MockHttpCache cache;
5826 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5827 transaction.response_headers = "cache-control: no-cache\n";
5829 // Initial load.
5830 RunTransactionTest(cache.http_cache(), transaction);
5832 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5833 EXPECT_EQ(0, cache.disk_cache()->open_count());
5834 EXPECT_EQ(1, cache.disk_cache()->create_count());
5836 // Try loading again with LOAD_PREFERRING_CACHE.
5837 transaction.load_flags = net::LOAD_PREFERRING_CACHE;
5838 RunTransactionTest(cache.http_cache(), transaction);
5840 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5841 EXPECT_EQ(1, cache.disk_cache()->open_count());
5842 EXPECT_EQ(1, cache.disk_cache()->create_count());
5844 disk_cache::Entry* entry;
5845 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5846 entry->Close();
5849 TEST(HttpCache, CacheControlNoStore) {
5850 MockHttpCache cache;
5852 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5853 transaction.response_headers = "cache-control: no-store\n";
5855 // initial load
5856 RunTransactionTest(cache.http_cache(), transaction);
5858 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5859 EXPECT_EQ(0, cache.disk_cache()->open_count());
5860 EXPECT_EQ(1, cache.disk_cache()->create_count());
5862 // try loading again; it should result in a network fetch
5863 RunTransactionTest(cache.http_cache(), transaction);
5865 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5866 EXPECT_EQ(0, cache.disk_cache()->open_count());
5867 EXPECT_EQ(2, cache.disk_cache()->create_count());
5869 disk_cache::Entry* entry;
5870 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5873 TEST(HttpCache, CacheControlNoStore2) {
5874 // this test is similar to the above test, except that the initial response
5875 // is cachable, but when it is validated, no-store is received causing the
5876 // cached document to be deleted.
5877 MockHttpCache cache;
5879 ScopedMockTransaction transaction(kETagGET_Transaction);
5881 // initial load
5882 RunTransactionTest(cache.http_cache(), transaction);
5884 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5885 EXPECT_EQ(0, cache.disk_cache()->open_count());
5886 EXPECT_EQ(1, cache.disk_cache()->create_count());
5888 // try loading again; it should result in a network fetch
5889 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5890 transaction.response_headers = "cache-control: no-store\n";
5891 RunTransactionTest(cache.http_cache(), transaction);
5893 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5894 EXPECT_EQ(1, cache.disk_cache()->open_count());
5895 EXPECT_EQ(1, cache.disk_cache()->create_count());
5897 disk_cache::Entry* entry;
5898 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5901 TEST(HttpCache, CacheControlNoStore3) {
5902 // this test is similar to the above test, except that the response is a 304
5903 // instead of a 200. this should never happen in practice, but it seems like
5904 // a good thing to verify that we still destroy the cache entry.
5905 MockHttpCache cache;
5907 ScopedMockTransaction transaction(kETagGET_Transaction);
5909 // initial load
5910 RunTransactionTest(cache.http_cache(), transaction);
5912 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5913 EXPECT_EQ(0, cache.disk_cache()->open_count());
5914 EXPECT_EQ(1, cache.disk_cache()->create_count());
5916 // try loading again; it should result in a network fetch
5917 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5918 transaction.response_headers = "cache-control: no-store\n";
5919 transaction.status = "HTTP/1.1 304 Not Modified";
5920 RunTransactionTest(cache.http_cache(), transaction);
5922 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5923 EXPECT_EQ(1, cache.disk_cache()->open_count());
5924 EXPECT_EQ(1, cache.disk_cache()->create_count());
5926 disk_cache::Entry* entry;
5927 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5930 // Ensure that we don't cache requests served over bad HTTPS.
5931 TEST(HttpCache, SimpleGET_SSLError) {
5932 MockHttpCache cache;
5934 MockTransaction transaction = kSimpleGET_Transaction;
5935 transaction.cert_status = net::CERT_STATUS_REVOKED;
5936 ScopedMockTransaction scoped_transaction(transaction);
5938 // write to the cache
5939 RunTransactionTest(cache.http_cache(), transaction);
5941 // Test that it was not cached.
5942 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5944 MockHttpRequest request(transaction);
5945 net::TestCompletionCallback callback;
5947 scoped_ptr<net::HttpTransaction> trans;
5948 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5950 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5951 if (rv == net::ERR_IO_PENDING)
5952 rv = callback.WaitForResult();
5953 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5956 // Ensure that we don't crash by if left-behind transactions.
5957 TEST(HttpCache, OutlivedTransactions) {
5958 MockHttpCache* cache = new MockHttpCache;
5960 scoped_ptr<net::HttpTransaction> trans;
5961 EXPECT_EQ(net::OK, cache->CreateTransaction(&trans));
5963 delete cache;
5964 trans.reset();
5967 // Test that the disabled mode works.
5968 TEST(HttpCache, CacheDisabledMode) {
5969 MockHttpCache cache;
5971 // write to the cache
5972 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5974 // go into disabled mode
5975 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
5977 // force this transaction to write to the cache again
5978 MockTransaction transaction(kSimpleGET_Transaction);
5980 RunTransactionTest(cache.http_cache(), transaction);
5982 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5983 EXPECT_EQ(0, cache.disk_cache()->open_count());
5984 EXPECT_EQ(1, cache.disk_cache()->create_count());
5987 // Other tests check that the response headers of the cached response
5988 // get updated on 304. Here we specifically check that the
5989 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5990 // fields also gets updated.
5991 // http://crbug.com/20594.
5992 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
5993 MockHttpCache cache;
5995 const char* kUrl = "http://foobar";
5996 const char* kData = "body";
5998 MockTransaction mock_network_response = { 0 };
5999 mock_network_response.url = kUrl;
6001 AddMockTransaction(&mock_network_response);
6003 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6005 MockTransaction request = { 0 };
6006 request.url = kUrl;
6007 request.method = "GET";
6008 request.request_headers = "\r\n";
6009 request.data = kData;
6011 static const Response kNetResponse1 = {
6012 "HTTP/1.1 200 OK",
6013 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6014 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6015 kData
6018 kNetResponse1.AssignTo(&mock_network_response);
6020 RunTransactionTest(cache.http_cache(), request);
6022 // Request |kUrl| again, this time validating the cache and getting
6023 // a 304 back.
6025 request.load_flags = net::LOAD_VALIDATE_CACHE;
6027 static const Response kNetResponse2 = {
6028 "HTTP/1.1 304 Not Modified",
6029 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6033 kNetResponse2.AssignTo(&mock_network_response);
6035 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6036 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6038 mock_network_response.request_time = request_time;
6039 mock_network_response.response_time = response_time;
6041 net::HttpResponseInfo response;
6042 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6044 // The request and response times should have been updated.
6045 EXPECT_EQ(request_time.ToInternalValue(),
6046 response.request_time.ToInternalValue());
6047 EXPECT_EQ(response_time.ToInternalValue(),
6048 response.response_time.ToInternalValue());
6050 std::string headers;
6051 response.headers->GetNormalizedHeaders(&headers);
6053 EXPECT_EQ("HTTP/1.1 200 OK\n"
6054 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6055 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6056 headers);
6058 RemoveMockTransaction(&mock_network_response);
6061 // Tests that we can write metadata to an entry.
6062 TEST(HttpCache, WriteMetadata_OK) {
6063 MockHttpCache cache;
6065 // Write to the cache
6066 net::HttpResponseInfo response;
6067 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6068 &response);
6069 EXPECT_TRUE(response.metadata.get() == NULL);
6071 // Trivial call.
6072 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
6073 Time::Now(), NULL, 0);
6075 // Write meta data to the same entry.
6076 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6077 memset(buf->data(), 0, buf->size());
6078 base::strlcpy(buf->data(), "Hi there", buf->size());
6079 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6080 net::DEFAULT_PRIORITY,
6081 response.response_time,
6082 buf.get(),
6083 buf->size());
6085 // Release the buffer before the operation takes place.
6086 buf = NULL;
6088 // Makes sure we finish pending operations.
6089 base::MessageLoop::current()->RunUntilIdle();
6091 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6092 &response);
6093 ASSERT_TRUE(response.metadata.get() != NULL);
6094 EXPECT_EQ(50, response.metadata->size());
6095 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6097 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6098 EXPECT_EQ(2, cache.disk_cache()->open_count());
6099 EXPECT_EQ(1, cache.disk_cache()->create_count());
6102 // Tests that we only write metadata to an entry if the time stamp matches.
6103 TEST(HttpCache, WriteMetadata_Fail) {
6104 MockHttpCache cache;
6106 // Write to the cache
6107 net::HttpResponseInfo response;
6108 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6109 &response);
6110 EXPECT_TRUE(response.metadata.get() == NULL);
6112 // Attempt to write meta data to the same entry.
6113 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6114 memset(buf->data(), 0, buf->size());
6115 base::strlcpy(buf->data(), "Hi there", buf->size());
6116 base::Time expected_time = response.response_time -
6117 base::TimeDelta::FromMilliseconds(20);
6118 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6119 net::DEFAULT_PRIORITY,
6120 expected_time,
6121 buf.get(),
6122 buf->size());
6124 // Makes sure we finish pending operations.
6125 base::MessageLoop::current()->RunUntilIdle();
6127 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6128 &response);
6129 EXPECT_TRUE(response.metadata.get() == NULL);
6131 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6132 EXPECT_EQ(2, cache.disk_cache()->open_count());
6133 EXPECT_EQ(1, cache.disk_cache()->create_count());
6136 // Tests that we can read metadata after validating the entry and with READ mode
6137 // transactions.
6138 TEST(HttpCache, ReadMetadata) {
6139 MockHttpCache cache;
6141 // Write to the cache
6142 net::HttpResponseInfo response;
6143 RunTransactionTestWithResponseInfo(cache.http_cache(),
6144 kTypicalGET_Transaction, &response);
6145 EXPECT_TRUE(response.metadata.get() == NULL);
6147 // Write meta data to the same entry.
6148 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6149 memset(buf->data(), 0, buf->size());
6150 base::strlcpy(buf->data(), "Hi there", buf->size());
6151 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6152 net::DEFAULT_PRIORITY,
6153 response.response_time,
6154 buf.get(),
6155 buf->size());
6157 // Makes sure we finish pending operations.
6158 base::MessageLoop::current()->RunUntilIdle();
6160 // Start with a READ mode transaction.
6161 MockTransaction trans1(kTypicalGET_Transaction);
6162 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
6164 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6165 ASSERT_TRUE(response.metadata.get() != NULL);
6166 EXPECT_EQ(50, response.metadata->size());
6167 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6169 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6170 EXPECT_EQ(2, cache.disk_cache()->open_count());
6171 EXPECT_EQ(1, cache.disk_cache()->create_count());
6172 base::MessageLoop::current()->RunUntilIdle();
6174 // Now make sure that the entry is re-validated with the server.
6175 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
6176 trans1.status = "HTTP/1.1 304 Not Modified";
6177 AddMockTransaction(&trans1);
6179 response.metadata = NULL;
6180 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6181 EXPECT_TRUE(response.metadata.get() != NULL);
6183 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6184 EXPECT_EQ(3, cache.disk_cache()->open_count());
6185 EXPECT_EQ(1, cache.disk_cache()->create_count());
6186 base::MessageLoop::current()->RunUntilIdle();
6187 RemoveMockTransaction(&trans1);
6189 // Now return 200 when validating the entry so the metadata will be lost.
6190 MockTransaction trans2(kTypicalGET_Transaction);
6191 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
6192 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6193 EXPECT_TRUE(response.metadata.get() == NULL);
6195 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6196 EXPECT_EQ(4, cache.disk_cache()->open_count());
6197 EXPECT_EQ(1, cache.disk_cache()->create_count());
6200 // Tests that we don't mark entries as truncated when a filter detects the end
6201 // of the stream.
6202 TEST(HttpCache, FilterCompletion) {
6203 MockHttpCache cache;
6204 net::TestCompletionCallback callback;
6207 scoped_ptr<net::HttpTransaction> trans;
6208 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6210 MockHttpRequest request(kSimpleGET_Transaction);
6211 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6212 EXPECT_EQ(net::OK, callback.GetResult(rv));
6214 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6215 rv = trans->Read(buf.get(), 256, callback.callback());
6216 EXPECT_GT(callback.GetResult(rv), 0);
6218 // Now make sure that the entry is preserved.
6219 trans->DoneReading();
6222 // Make sure that the ActiveEntry is gone.
6223 base::MessageLoop::current()->RunUntilIdle();
6225 // Read from the cache.
6226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6228 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6229 EXPECT_EQ(1, cache.disk_cache()->open_count());
6230 EXPECT_EQ(1, cache.disk_cache()->create_count());
6233 // Tests that we don't mark entries as truncated and release the cache
6234 // entry when DoneReading() is called before any Read() calls, such as
6235 // for a redirect.
6236 TEST(HttpCache, DoneReading) {
6237 MockHttpCache cache;
6238 net::TestCompletionCallback callback;
6240 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6241 transaction.data = "";
6243 scoped_ptr<net::HttpTransaction> trans;
6244 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6246 MockHttpRequest request(transaction);
6247 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6248 EXPECT_EQ(net::OK, callback.GetResult(rv));
6250 trans->DoneReading();
6251 // Leave the transaction around.
6253 // Make sure that the ActiveEntry is gone.
6254 base::MessageLoop::current()->RunUntilIdle();
6256 // Read from the cache. This should not deadlock.
6257 RunTransactionTest(cache.http_cache(), transaction);
6259 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6260 EXPECT_EQ(1, cache.disk_cache()->open_count());
6261 EXPECT_EQ(1, cache.disk_cache()->create_count());
6264 // Tests that we stop caching when told.
6265 TEST(HttpCache, StopCachingDeletesEntry) {
6266 MockHttpCache cache;
6267 net::TestCompletionCallback callback;
6268 MockHttpRequest request(kSimpleGET_Transaction);
6271 scoped_ptr<net::HttpTransaction> trans;
6272 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6274 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6275 EXPECT_EQ(net::OK, callback.GetResult(rv));
6277 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6278 rv = trans->Read(buf.get(), 10, callback.callback());
6279 EXPECT_EQ(10, callback.GetResult(rv));
6281 trans->StopCaching();
6283 // We should be able to keep reading.
6284 rv = trans->Read(buf.get(), 256, callback.callback());
6285 EXPECT_GT(callback.GetResult(rv), 0);
6286 rv = trans->Read(buf.get(), 256, callback.callback());
6287 EXPECT_EQ(0, callback.GetResult(rv));
6290 // Make sure that the ActiveEntry is gone.
6291 base::MessageLoop::current()->RunUntilIdle();
6293 // Verify that the entry is gone.
6294 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6296 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6297 EXPECT_EQ(0, cache.disk_cache()->open_count());
6298 EXPECT_EQ(2, cache.disk_cache()->create_count());
6301 // Tests that we stop caching when told, even if DoneReading is called
6302 // after StopCaching.
6303 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6304 MockHttpCache cache;
6305 net::TestCompletionCallback callback;
6306 MockHttpRequest request(kSimpleGET_Transaction);
6309 scoped_ptr<net::HttpTransaction> trans;
6310 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6312 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6313 EXPECT_EQ(net::OK, callback.GetResult(rv));
6315 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6316 rv = trans->Read(buf.get(), 10, callback.callback());
6317 EXPECT_EQ(10, callback.GetResult(rv));
6319 trans->StopCaching();
6321 // We should be able to keep reading.
6322 rv = trans->Read(buf.get(), 256, callback.callback());
6323 EXPECT_GT(callback.GetResult(rv), 0);
6324 rv = trans->Read(buf.get(), 256, callback.callback());
6325 EXPECT_EQ(0, callback.GetResult(rv));
6327 // We should be able to call DoneReading.
6328 trans->DoneReading();
6331 // Make sure that the ActiveEntry is gone.
6332 base::MessageLoop::current()->RunUntilIdle();
6334 // Verify that the entry is gone.
6335 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6337 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6338 EXPECT_EQ(0, cache.disk_cache()->open_count());
6339 EXPECT_EQ(2, cache.disk_cache()->create_count());
6342 // Tests that we stop caching when told, when using auth.
6343 TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6344 MockHttpCache cache;
6345 net::TestCompletionCallback callback;
6346 MockTransaction mock_transaction(kSimpleGET_Transaction);
6347 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6348 AddMockTransaction(&mock_transaction);
6349 MockHttpRequest request(mock_transaction);
6352 scoped_ptr<net::HttpTransaction> trans;
6353 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6355 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6356 EXPECT_EQ(net::OK, callback.GetResult(rv));
6358 trans->StopCaching();
6360 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6361 rv = trans->Read(buf.get(), 10, callback.callback());
6362 EXPECT_EQ(callback.GetResult(rv), 10);
6364 RemoveMockTransaction(&mock_transaction);
6366 // Make sure that the ActiveEntry is gone.
6367 base::MessageLoop::current()->RunUntilIdle();
6369 // Verify that the entry is gone.
6370 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6372 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6373 EXPECT_EQ(0, cache.disk_cache()->open_count());
6374 EXPECT_EQ(2, cache.disk_cache()->create_count());
6377 // Tests that when we are told to stop caching we don't throw away valid data.
6378 TEST(HttpCache, StopCachingSavesEntry) {
6379 MockHttpCache cache;
6380 net::TestCompletionCallback callback;
6381 MockHttpRequest request(kSimpleGET_Transaction);
6384 scoped_ptr<net::HttpTransaction> trans;
6385 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6387 // Force a response that can be resumed.
6388 MockTransaction mock_transaction(kSimpleGET_Transaction);
6389 AddMockTransaction(&mock_transaction);
6390 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6391 "Content-Length: 42\n"
6392 "Etag: \"foo\"\n";
6394 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6395 EXPECT_EQ(net::OK, callback.GetResult(rv));
6397 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6398 rv = trans->Read(buf.get(), 10, callback.callback());
6399 EXPECT_EQ(callback.GetResult(rv), 10);
6401 trans->StopCaching();
6403 // We should be able to keep reading.
6404 rv = trans->Read(buf.get(), 256, callback.callback());
6405 EXPECT_GT(callback.GetResult(rv), 0);
6406 rv = trans->Read(buf.get(), 256, callback.callback());
6407 EXPECT_EQ(callback.GetResult(rv), 0);
6409 RemoveMockTransaction(&mock_transaction);
6412 // Verify that the entry is marked as incomplete.
6413 disk_cache::Entry* entry;
6414 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6415 net::HttpResponseInfo response;
6416 bool truncated = false;
6417 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6418 EXPECT_TRUE(truncated);
6419 entry->Close();
6422 // Tests that we handle truncated enries when StopCaching is called.
6423 TEST(HttpCache, StopCachingTruncatedEntry) {
6424 MockHttpCache cache;
6425 net::TestCompletionCallback callback;
6426 MockHttpRequest request(kRangeGET_TransactionOK);
6427 request.extra_headers.Clear();
6428 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6429 AddMockTransaction(&kRangeGET_TransactionOK);
6431 std::string raw_headers("HTTP/1.1 200 OK\n"
6432 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6433 "ETag: \"foo\"\n"
6434 "Accept-Ranges: bytes\n"
6435 "Content-Length: 80\n");
6436 CreateTruncatedEntry(raw_headers, &cache);
6439 // Now make a regular request.
6440 scoped_ptr<net::HttpTransaction> trans;
6441 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6443 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6444 EXPECT_EQ(net::OK, callback.GetResult(rv));
6446 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6447 rv = trans->Read(buf.get(), 10, callback.callback());
6448 EXPECT_EQ(callback.GetResult(rv), 10);
6450 // This is actually going to do nothing.
6451 trans->StopCaching();
6453 // We should be able to keep reading.
6454 rv = trans->Read(buf.get(), 256, callback.callback());
6455 EXPECT_GT(callback.GetResult(rv), 0);
6456 rv = trans->Read(buf.get(), 256, callback.callback());
6457 EXPECT_GT(callback.GetResult(rv), 0);
6458 rv = trans->Read(buf.get(), 256, callback.callback());
6459 EXPECT_EQ(callback.GetResult(rv), 0);
6462 // Verify that the disk entry was updated.
6463 disk_cache::Entry* entry;
6464 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6465 EXPECT_EQ(80, entry->GetDataSize(1));
6466 bool truncated = true;
6467 net::HttpResponseInfo response;
6468 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6469 EXPECT_FALSE(truncated);
6470 entry->Close();
6472 RemoveMockTransaction(&kRangeGET_TransactionOK);
6475 // Tests that we detect truncated resources from the net when there is
6476 // a Content-Length header.
6477 TEST(HttpCache, TruncatedByContentLength) {
6478 MockHttpCache cache;
6479 net::TestCompletionCallback callback;
6481 MockTransaction transaction(kSimpleGET_Transaction);
6482 AddMockTransaction(&transaction);
6483 transaction.response_headers = "Cache-Control: max-age=10000\n"
6484 "Content-Length: 100\n";
6485 RunTransactionTest(cache.http_cache(), transaction);
6486 RemoveMockTransaction(&transaction);
6488 // Read from the cache.
6489 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6491 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6492 EXPECT_EQ(0, cache.disk_cache()->open_count());
6493 EXPECT_EQ(2, cache.disk_cache()->create_count());
6496 // Tests that we actually flag entries as truncated when we detect an error
6497 // from the net.
6498 TEST(HttpCache, TruncatedByContentLength2) {
6499 MockHttpCache cache;
6500 net::TestCompletionCallback callback;
6502 MockTransaction transaction(kSimpleGET_Transaction);
6503 AddMockTransaction(&transaction);
6504 transaction.response_headers = "Cache-Control: max-age=10000\n"
6505 "Content-Length: 100\n"
6506 "Etag: \"foo\"\n";
6507 RunTransactionTest(cache.http_cache(), transaction);
6508 RemoveMockTransaction(&transaction);
6510 // Verify that the entry is marked as incomplete.
6511 disk_cache::Entry* entry;
6512 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6513 net::HttpResponseInfo response;
6514 bool truncated = false;
6515 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6516 EXPECT_TRUE(truncated);
6517 entry->Close();
6520 // Make sure that calling SetPriority on a cache transaction passes on
6521 // its priority updates to its underlying network transaction.
6522 TEST(HttpCache, SetPriority) {
6523 MockHttpCache cache;
6525 scoped_ptr<net::HttpTransaction> trans;
6526 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6528 // Shouldn't crash, but doesn't do anything either.
6529 trans->SetPriority(net::LOW);
6531 EXPECT_FALSE(cache.network_layer()->last_transaction());
6532 EXPECT_EQ(net::DEFAULT_PRIORITY,
6533 cache.network_layer()->last_create_transaction_priority());
6535 net::HttpRequestInfo info;
6536 info.url = GURL(kSimpleGET_Transaction.url);
6537 net::TestCompletionCallback callback;
6538 EXPECT_EQ(net::ERR_IO_PENDING,
6539 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6541 EXPECT_TRUE(cache.network_layer()->last_transaction());
6542 if (cache.network_layer()->last_transaction()) {
6543 EXPECT_EQ(net::LOW,
6544 cache.network_layer()->last_create_transaction_priority());
6545 EXPECT_EQ(net::LOW,
6546 cache.network_layer()->last_transaction()->priority());
6549 trans->SetPriority(net::HIGHEST);
6551 if (cache.network_layer()->last_transaction()) {
6552 EXPECT_EQ(net::LOW,
6553 cache.network_layer()->last_create_transaction_priority());
6554 EXPECT_EQ(net::HIGHEST,
6555 cache.network_layer()->last_transaction()->priority());
6558 EXPECT_EQ(net::OK, callback.WaitForResult());
6561 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6562 // transaction passes on its argument to the underlying network transaction.
6563 TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
6564 MockHttpCache cache;
6566 FakeWebSocketHandshakeStreamCreateHelper create_helper;
6567 scoped_ptr<net::HttpTransaction> trans;
6568 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6570 EXPECT_FALSE(cache.network_layer()->last_transaction());
6572 net::HttpRequestInfo info;
6573 info.url = GURL(kSimpleGET_Transaction.url);
6574 net::TestCompletionCallback callback;
6575 EXPECT_EQ(net::ERR_IO_PENDING,
6576 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6578 ASSERT_TRUE(cache.network_layer()->last_transaction());
6579 EXPECT_FALSE(cache.network_layer()->last_transaction()->
6580 websocket_handshake_stream_create_helper());
6581 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
6582 EXPECT_EQ(&create_helper,
6583 cache.network_layer()->last_transaction()->
6584 websocket_handshake_stream_create_helper());
6585 EXPECT_EQ(net::OK, callback.WaitForResult());
6588 // Make sure that a cache transaction passes on its priority to
6589 // newly-created network transactions.
6590 TEST(HttpCache, SetPriorityNewTransaction) {
6591 MockHttpCache cache;
6592 AddMockTransaction(&kRangeGET_TransactionOK);
6594 std::string raw_headers("HTTP/1.1 200 OK\n"
6595 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6596 "ETag: \"foo\"\n"
6597 "Accept-Ranges: bytes\n"
6598 "Content-Length: 80\n");
6599 CreateTruncatedEntry(raw_headers, &cache);
6601 // Now make a regular request.
6602 std::string headers;
6603 MockTransaction transaction(kRangeGET_TransactionOK);
6604 transaction.request_headers = EXTRA_HEADER;
6605 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6606 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6608 scoped_ptr<net::HttpTransaction> trans;
6609 ASSERT_EQ(net::OK,
6610 cache.http_cache()->CreateTransaction(net::MEDIUM, &trans));
6611 EXPECT_EQ(net::DEFAULT_PRIORITY,
6612 cache.network_layer()->last_create_transaction_priority());
6614 MockHttpRequest info(transaction);
6615 net::TestCompletionCallback callback;
6616 EXPECT_EQ(net::ERR_IO_PENDING,
6617 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6618 EXPECT_EQ(net::OK, callback.WaitForResult());
6620 EXPECT_EQ(net::MEDIUM,
6621 cache.network_layer()->last_create_transaction_priority());
6623 trans->SetPriority(net::HIGHEST);
6624 // Should trigger a new network transaction and pick up the new
6625 // priority.
6626 ReadAndVerifyTransaction(trans.get(), transaction);
6628 EXPECT_EQ(net::HIGHEST,
6629 cache.network_layer()->last_create_transaction_priority());
6631 RemoveMockTransaction(&kRangeGET_TransactionOK);
6634 int64 RunTransactionAndGetReceivedBytes(
6635 MockHttpCache& cache,
6636 const MockTransaction& trans_info) {
6637 int64 received_bytes = -1;
6638 RunTransactionTestBase(cache.http_cache(), trans_info,
6639 MockHttpRequest(trans_info), NULL, net::BoundNetLog(),
6640 NULL, &received_bytes);
6641 return received_bytes;
6644 int64 TransactionSize(const MockTransaction& transaction) {
6645 return strlen(transaction.status) + strlen(transaction.response_headers) +
6646 strlen(transaction.data);
6649 TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
6650 MockHttpCache cache;
6652 MockTransaction transaction(kSimpleGET_Transaction);
6653 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6654 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6656 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6657 EXPECT_EQ(0, received_bytes);
6660 TEST(HttpCache, ReceivedBytesConditionalRequest304) {
6661 MockHttpCache cache;
6663 ScopedMockTransaction transaction(kETagGET_Transaction);
6664 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6665 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6667 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
6668 transaction.handler = ETagGet_ConditionalRequest_Handler;
6669 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6670 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6673 TEST(HttpCache, ReceivedBytesConditionalRequest200) {
6674 MockHttpCache cache;
6676 MockTransaction transaction(kTypicalGET_Transaction);
6677 transaction.request_headers = "Foo: bar\r\n";
6678 transaction.response_headers =
6679 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6680 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6681 "Etag: \"foopy\"\n"
6682 "Cache-Control: max-age=0\n"
6683 "Vary: Foo\n";
6684 AddMockTransaction(&transaction);
6685 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6686 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6688 RevalidationServer server;
6689 transaction.handler = server.Handler;
6690 transaction.request_headers = "Foo: none\r\n";
6691 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6692 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6694 RemoveMockTransaction(&transaction);
6697 TEST(HttpCache, ReceivedBytesRange) {
6698 MockHttpCache cache;
6699 AddMockTransaction(&kRangeGET_TransactionOK);
6700 MockTransaction transaction(kRangeGET_TransactionOK);
6702 // Read bytes 40-49 from the network.
6703 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6704 int64 range_response_size = TransactionSize(transaction);
6705 EXPECT_EQ(range_response_size, received_bytes);
6707 // Read bytes 40-49 from the cache.
6708 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6709 EXPECT_EQ(0, received_bytes);
6710 base::MessageLoop::current()->RunUntilIdle();
6712 // Read bytes 30-39 from the network.
6713 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
6714 transaction.data = "rg: 30-39 ";
6715 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6716 EXPECT_EQ(range_response_size, received_bytes);
6717 base::MessageLoop::current()->RunUntilIdle();
6719 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6720 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
6721 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6722 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6723 EXPECT_EQ(range_response_size * 2, received_bytes);
6725 RemoveMockTransaction(&kRangeGET_TransactionOK);
6728 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request,
6729 std::string* response_status,
6730 std::string* response_headers,
6731 std::string* response_data) {
6732 std::string value;
6733 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
6734 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
6737 // Verify that the Resource-Freshness header is sent on a revalidation if the
6738 // stale-while-revalidate directive was on the response.
6739 TEST(HttpCache, ResourceFreshnessHeaderSent) {
6740 MockHttpCache cache;
6742 ScopedMockTransaction stale_while_revalidate_transaction(
6743 kSimpleGET_Transaction);
6744 stale_while_revalidate_transaction.response_headers =
6745 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6746 "Age: 10801\n"
6747 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
6749 // Write to the cache.
6750 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6752 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6754 // Send the request again and check that Resource-Freshness header is added.
6755 stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader;
6757 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6759 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6762 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request,
6763 std::string* response_status,
6764 std::string* response_headers,
6765 std::string* response_data) {
6766 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
6769 // Verify that the Resource-Freshness header is not sent when
6770 // stale-while-revalidate is 0.
6771 TEST(HttpCache, ResourceFreshnessHeaderNotSent) {
6772 MockHttpCache cache;
6774 ScopedMockTransaction stale_while_revalidate_transaction(
6775 kSimpleGET_Transaction);
6776 stale_while_revalidate_transaction.response_headers =
6777 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6778 "Age: 10801\n"
6779 "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
6781 // Write to the cache.
6782 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6784 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6786 // Send the request again and check that Resource-Freshness header is absent.
6787 stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent;
6789 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6791 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6794 // Tests that we allow multiple simultaneous, non-overlapping transactions to
6795 // take place on a sparse entry.
6796 TEST(HttpCache, RangeGET_MultipleRequests) {
6797 MockHttpCache cache;
6799 // Create a transaction for bytes 0-9.
6800 MockHttpRequest request(kRangeGET_TransactionOK);
6801 MockTransaction transaction(kRangeGET_TransactionOK);
6802 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
6803 transaction.data = "rg: 00-09 ";
6804 AddMockTransaction(&transaction);
6806 net::TestCompletionCallback callback;
6807 scoped_ptr<net::HttpTransaction> trans;
6808 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
6809 EXPECT_EQ(net::OK, rv);
6810 ASSERT_TRUE(trans.get());
6812 // Start our transaction.
6813 trans->Start(&request, callback.callback(), net::BoundNetLog());
6815 // A second transaction on a different part of the file (the default
6816 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
6817 // the already pending transaction.
6818 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
6820 // Let the first transaction complete.
6821 callback.WaitForResult();
6823 RemoveMockTransaction(&transaction);