Probably broke Win7 Tests (dbg)(6). http://build.chromium.org/p/chromium.win/builders...
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blob83241ab301e441665f6acf3f1b794fa7e5f9f183
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 we do not cache the response of a PUT.
2986 TEST(HttpCache, SimplePUT_Miss) {
2987 MockHttpCache cache;
2989 MockTransaction transaction(kSimplePOST_Transaction);
2990 transaction.method = "PUT";
2992 ScopedVector<net::UploadElementReader> element_readers;
2993 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2994 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
2996 MockHttpRequest request(transaction);
2997 request.upload_data_stream = &upload_data_stream;
2999 // Attempt to populate the cache.
3000 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3003 EXPECT_EQ(0, cache.disk_cache()->open_count());
3004 EXPECT_EQ(0, cache.disk_cache()->create_count());
3007 // Tests that we invalidate entries as a result of a PUT.
3008 TEST(HttpCache, SimplePUT_Invalidate) {
3009 MockHttpCache cache;
3011 MockTransaction transaction(kSimpleGET_Transaction);
3012 MockHttpRequest req1(transaction);
3014 // Attempt to populate the cache.
3015 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3017 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3018 EXPECT_EQ(0, cache.disk_cache()->open_count());
3019 EXPECT_EQ(1, cache.disk_cache()->create_count());
3021 ScopedVector<net::UploadElementReader> element_readers;
3022 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3023 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3025 transaction.method = "PUT";
3026 MockHttpRequest req2(transaction);
3027 req2.upload_data_stream = &upload_data_stream;
3029 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3031 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3032 EXPECT_EQ(1, cache.disk_cache()->open_count());
3033 EXPECT_EQ(1, cache.disk_cache()->create_count());
3035 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3037 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3038 EXPECT_EQ(1, cache.disk_cache()->open_count());
3039 EXPECT_EQ(2, cache.disk_cache()->create_count());
3042 // Tests that we invalidate entries as a result of a PUT.
3043 TEST(HttpCache, SimplePUT_Invalidate_305) {
3044 MockHttpCache cache;
3046 MockTransaction transaction(kSimpleGET_Transaction);
3047 AddMockTransaction(&transaction);
3048 MockHttpRequest req1(transaction);
3050 // Attempt to populate the cache.
3051 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3053 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3054 EXPECT_EQ(0, cache.disk_cache()->open_count());
3055 EXPECT_EQ(1, cache.disk_cache()->create_count());
3057 ScopedVector<net::UploadElementReader> element_readers;
3058 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3059 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3061 transaction.method = "PUT";
3062 transaction.status = "HTTP/1.1 305 Use Proxy";
3063 MockHttpRequest req2(transaction);
3064 req2.upload_data_stream = &upload_data_stream;
3066 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3068 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3069 EXPECT_EQ(1, cache.disk_cache()->open_count());
3070 EXPECT_EQ(1, cache.disk_cache()->create_count());
3072 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3074 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3075 EXPECT_EQ(1, cache.disk_cache()->open_count());
3076 EXPECT_EQ(2, cache.disk_cache()->create_count());
3077 RemoveMockTransaction(&transaction);
3080 // Tests that we don't invalidate entries as a result of a failed PUT.
3081 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3082 MockHttpCache cache;
3084 MockTransaction transaction(kSimpleGET_Transaction);
3085 AddMockTransaction(&transaction);
3086 MockHttpRequest req1(transaction);
3088 // Attempt to populate the cache.
3089 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3091 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3092 EXPECT_EQ(0, cache.disk_cache()->open_count());
3093 EXPECT_EQ(1, cache.disk_cache()->create_count());
3095 ScopedVector<net::UploadElementReader> element_readers;
3096 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3097 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3099 transaction.method = "PUT";
3100 transaction.status = "HTTP/1.1 404 Not Found";
3101 MockHttpRequest req2(transaction);
3102 req2.upload_data_stream = &upload_data_stream;
3104 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3106 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3107 EXPECT_EQ(1, cache.disk_cache()->open_count());
3108 EXPECT_EQ(1, cache.disk_cache()->create_count());
3110 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3112 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3113 EXPECT_EQ(2, cache.disk_cache()->open_count());
3114 EXPECT_EQ(1, cache.disk_cache()->create_count());
3115 RemoveMockTransaction(&transaction);
3118 // Tests that we do not cache the response of a DELETE.
3119 TEST(HttpCache, SimpleDELETE_Miss) {
3120 MockHttpCache cache;
3122 MockTransaction transaction(kSimplePOST_Transaction);
3123 transaction.method = "DELETE";
3125 ScopedVector<net::UploadElementReader> element_readers;
3126 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3127 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3129 MockHttpRequest request(transaction);
3130 request.upload_data_stream = &upload_data_stream;
3132 // Attempt to populate the cache.
3133 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3135 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3136 EXPECT_EQ(0, cache.disk_cache()->open_count());
3137 EXPECT_EQ(0, cache.disk_cache()->create_count());
3140 // Tests that we invalidate entries as a result of a DELETE.
3141 TEST(HttpCache, SimpleDELETE_Invalidate) {
3142 MockHttpCache cache;
3144 MockTransaction transaction(kSimpleGET_Transaction);
3145 MockHttpRequest req1(transaction);
3147 // Attempt to populate the cache.
3148 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3150 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3151 EXPECT_EQ(0, cache.disk_cache()->open_count());
3152 EXPECT_EQ(1, cache.disk_cache()->create_count());
3154 ScopedVector<net::UploadElementReader> element_readers;
3155 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3156 net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3158 transaction.method = "DELETE";
3159 MockHttpRequest req2(transaction);
3160 req2.upload_data_stream = &upload_data_stream;
3162 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3164 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3165 EXPECT_EQ(1, cache.disk_cache()->open_count());
3166 EXPECT_EQ(1, cache.disk_cache()->create_count());
3168 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3170 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3171 EXPECT_EQ(1, cache.disk_cache()->open_count());
3172 EXPECT_EQ(2, cache.disk_cache()->create_count());
3175 // Tests that we invalidate entries as a result of a DELETE.
3176 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3177 MockHttpCache cache;
3179 MockTransaction transaction(kSimpleGET_Transaction);
3180 AddMockTransaction(&transaction);
3182 // Attempt to populate the cache.
3183 RunTransactionTest(cache.http_cache(), transaction);
3185 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3186 EXPECT_EQ(0, cache.disk_cache()->open_count());
3187 EXPECT_EQ(1, cache.disk_cache()->create_count());
3189 transaction.method = "DELETE";
3190 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3192 RunTransactionTest(cache.http_cache(), transaction);
3194 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3195 EXPECT_EQ(1, cache.disk_cache()->open_count());
3196 EXPECT_EQ(1, cache.disk_cache()->create_count());
3198 transaction.method = "GET";
3199 RunTransactionTest(cache.http_cache(), transaction);
3201 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3202 EXPECT_EQ(1, cache.disk_cache()->open_count());
3203 EXPECT_EQ(2, cache.disk_cache()->create_count());
3204 RemoveMockTransaction(&transaction);
3207 // Tests that we don't invalidate entries as a result of a failed DELETE.
3208 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3209 MockHttpCache cache;
3211 MockTransaction transaction(kSimpleGET_Transaction);
3212 AddMockTransaction(&transaction);
3214 // Attempt to populate the cache.
3215 RunTransactionTest(cache.http_cache(), transaction);
3217 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3218 EXPECT_EQ(0, cache.disk_cache()->open_count());
3219 EXPECT_EQ(1, cache.disk_cache()->create_count());
3221 transaction.method = "DELETE";
3222 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3224 RunTransactionTest(cache.http_cache(), transaction);
3226 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3227 EXPECT_EQ(1, cache.disk_cache()->open_count());
3228 EXPECT_EQ(1, cache.disk_cache()->create_count());
3230 transaction.method = "GET";
3231 transaction.status = "HTTP/1.1 200 OK";
3232 RunTransactionTest(cache.http_cache(), transaction);
3234 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3235 EXPECT_EQ(2, cache.disk_cache()->open_count());
3236 EXPECT_EQ(1, cache.disk_cache()->create_count());
3237 RemoveMockTransaction(&transaction);
3240 // Tests that we don't invalidate entries after a failed network transaction.
3241 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3242 MockHttpCache cache;
3244 // Populate the cache.
3245 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3246 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3248 // Fail the network request.
3249 MockTransaction transaction(kSimpleGET_Transaction);
3250 transaction.return_code = net::ERR_FAILED;
3251 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3253 AddMockTransaction(&transaction);
3254 RunTransactionTest(cache.http_cache(), transaction);
3255 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3256 RemoveMockTransaction(&transaction);
3258 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3259 transaction.return_code = net::OK;
3260 AddMockTransaction(&transaction);
3261 RunTransactionTest(cache.http_cache(), transaction);
3263 // Make sure the transaction didn't reach the network.
3264 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3265 RemoveMockTransaction(&transaction);
3268 TEST(HttpCache, RangeGET_SkipsCache) {
3269 MockHttpCache cache;
3271 // Test that we skip the cache for range GET requests. Eventually, we will
3272 // want to cache these, but we'll still have cases where skipping the cache
3273 // makes sense, so we want to make sure that it works properly.
3275 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3277 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3278 EXPECT_EQ(0, cache.disk_cache()->open_count());
3279 EXPECT_EQ(0, cache.disk_cache()->create_count());
3281 MockTransaction transaction(kSimpleGET_Transaction);
3282 transaction.request_headers = "If-None-Match: foo\r\n";
3283 RunTransactionTest(cache.http_cache(), transaction);
3285 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3286 EXPECT_EQ(0, cache.disk_cache()->open_count());
3287 EXPECT_EQ(0, cache.disk_cache()->create_count());
3289 transaction.request_headers =
3290 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3291 RunTransactionTest(cache.http_cache(), transaction);
3293 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3294 EXPECT_EQ(0, cache.disk_cache()->open_count());
3295 EXPECT_EQ(0, cache.disk_cache()->create_count());
3298 // Test that we skip the cache for range requests that include a validation
3299 // header.
3300 TEST(HttpCache, RangeGET_SkipsCache2) {
3301 MockHttpCache cache;
3303 MockTransaction transaction(kRangeGET_Transaction);
3304 transaction.request_headers = "If-None-Match: foo\r\n"
3305 EXTRA_HEADER
3306 "Range: bytes = 40-49\r\n";
3307 RunTransactionTest(cache.http_cache(), transaction);
3309 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3310 EXPECT_EQ(0, cache.disk_cache()->open_count());
3311 EXPECT_EQ(0, cache.disk_cache()->create_count());
3313 transaction.request_headers =
3314 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3315 EXTRA_HEADER
3316 "Range: bytes = 40-49\r\n";
3317 RunTransactionTest(cache.http_cache(), transaction);
3319 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3320 EXPECT_EQ(0, cache.disk_cache()->open_count());
3321 EXPECT_EQ(0, cache.disk_cache()->create_count());
3323 transaction.request_headers = "If-Range: bla\r\n"
3324 EXTRA_HEADER
3325 "Range: bytes = 40-49\r\n";
3326 RunTransactionTest(cache.http_cache(), transaction);
3328 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3329 EXPECT_EQ(0, cache.disk_cache()->open_count());
3330 EXPECT_EQ(0, cache.disk_cache()->create_count());
3333 // Tests that receiving 206 for a regular request is handled correctly.
3334 TEST(HttpCache, GET_Crazy206) {
3335 MockHttpCache cache;
3337 // Write to the cache.
3338 MockTransaction transaction(kRangeGET_TransactionOK);
3339 AddMockTransaction(&transaction);
3340 transaction.request_headers = EXTRA_HEADER;
3341 transaction.handler = NULL;
3342 RunTransactionTest(cache.http_cache(), transaction);
3344 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3345 EXPECT_EQ(0, cache.disk_cache()->open_count());
3346 EXPECT_EQ(1, cache.disk_cache()->create_count());
3348 // This should read again from the net.
3349 RunTransactionTest(cache.http_cache(), transaction);
3351 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3352 EXPECT_EQ(0, cache.disk_cache()->open_count());
3353 EXPECT_EQ(2, cache.disk_cache()->create_count());
3354 RemoveMockTransaction(&transaction);
3357 // Tests that receiving 416 for a regular request is handled correctly.
3358 TEST(HttpCache, GET_Crazy416) {
3359 MockHttpCache cache;
3361 // Write to the cache.
3362 MockTransaction transaction(kSimpleGET_Transaction);
3363 AddMockTransaction(&transaction);
3364 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3365 RunTransactionTest(cache.http_cache(), transaction);
3367 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3368 EXPECT_EQ(0, cache.disk_cache()->open_count());
3369 EXPECT_EQ(1, cache.disk_cache()->create_count());
3371 RemoveMockTransaction(&transaction);
3374 // Tests that we don't cache partial responses that can't be validated.
3375 TEST(HttpCache, RangeGET_NoStrongValidators) {
3376 MockHttpCache cache;
3377 std::string headers;
3379 // Attempt to write to the cache (40-49).
3380 MockTransaction transaction(kRangeGET_TransactionOK);
3381 AddMockTransaction(&transaction);
3382 transaction.response_headers = "Content-Length: 10\n"
3383 "ETag: w/\"foo\"\n";
3384 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3386 Verify206Response(headers, 40, 49);
3387 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3388 EXPECT_EQ(0, cache.disk_cache()->open_count());
3389 EXPECT_EQ(1, cache.disk_cache()->create_count());
3391 // Now verify that there's no cached data.
3392 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3393 &headers);
3395 Verify206Response(headers, 40, 49);
3396 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3397 EXPECT_EQ(0, cache.disk_cache()->open_count());
3398 EXPECT_EQ(2, cache.disk_cache()->create_count());
3400 RemoveMockTransaction(&transaction);
3403 // Tests that we cache partial responses that lack content-length.
3404 TEST(HttpCache, RangeGET_NoContentLength) {
3405 MockHttpCache cache;
3406 std::string headers;
3408 // Attempt to write to the cache (40-49).
3409 MockTransaction transaction(kRangeGET_TransactionOK);
3410 AddMockTransaction(&transaction);
3411 transaction.response_headers = "ETag: \"foo\"\n"
3412 "Accept-Ranges: bytes\n"
3413 "Content-Range: bytes 40-49/80\n";
3414 transaction.handler = NULL;
3415 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3417 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3418 EXPECT_EQ(0, cache.disk_cache()->open_count());
3419 EXPECT_EQ(1, cache.disk_cache()->create_count());
3421 // Now verify that there's no cached data.
3422 transaction.handler = &RangeTransactionServer::RangeHandler;
3423 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3424 &headers);
3426 Verify206Response(headers, 40, 49);
3427 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3428 EXPECT_EQ(1, cache.disk_cache()->open_count());
3429 EXPECT_EQ(1, cache.disk_cache()->create_count());
3431 RemoveMockTransaction(&transaction);
3434 // Tests that we can cache range requests and fetch random blocks from the
3435 // cache and the network.
3436 TEST(HttpCache, RangeGET_OK) {
3437 MockHttpCache cache;
3438 AddMockTransaction(&kRangeGET_TransactionOK);
3439 std::string headers;
3441 // Write to the cache (40-49).
3442 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3443 &headers);
3445 Verify206Response(headers, 40, 49);
3446 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3447 EXPECT_EQ(0, cache.disk_cache()->open_count());
3448 EXPECT_EQ(1, cache.disk_cache()->create_count());
3450 // Read from the cache (40-49).
3451 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3452 &headers);
3454 Verify206Response(headers, 40, 49);
3455 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3456 EXPECT_EQ(1, cache.disk_cache()->open_count());
3457 EXPECT_EQ(1, cache.disk_cache()->create_count());
3459 // Make sure we are done with the previous transaction.
3460 base::MessageLoop::current()->RunUntilIdle();
3462 // Write to the cache (30-39).
3463 MockTransaction transaction(kRangeGET_TransactionOK);
3464 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3465 transaction.data = "rg: 30-39 ";
3466 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3468 Verify206Response(headers, 30, 39);
3469 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3470 EXPECT_EQ(2, cache.disk_cache()->open_count());
3471 EXPECT_EQ(1, cache.disk_cache()->create_count());
3473 // Make sure we are done with the previous transaction.
3474 base::MessageLoop::current()->RunUntilIdle();
3476 // Write and read from the cache (20-59).
3477 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3478 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3479 net::CapturingBoundNetLog log;
3480 net::LoadTimingInfo load_timing_info;
3481 RunTransactionTestWithResponseAndGetTiming(
3482 cache.http_cache(), transaction, &headers, log.bound(),
3483 &load_timing_info);
3485 Verify206Response(headers, 20, 59);
3486 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3487 EXPECT_EQ(3, cache.disk_cache()->open_count());
3488 EXPECT_EQ(1, cache.disk_cache()->create_count());
3489 TestLoadTimingNetworkRequest(load_timing_info);
3491 RemoveMockTransaction(&kRangeGET_TransactionOK);
3494 // Checks that with a cache backend having Sparse IO unimplementes the cache
3495 // entry would be doomed after a range request.
3496 // TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3497 TEST(HttpCache, RangeGET_SparseNotImplemented) {
3498 MockHttpCache cache;
3499 cache.disk_cache()->set_fail_sparse_requests();
3501 // Run a cacheable request to prime the cache.
3502 MockTransaction transaction(kTypicalGET_Transaction);
3503 transaction.url = kRangeGET_TransactionOK.url;
3504 AddMockTransaction(&transaction);
3505 RunTransactionTest(cache.http_cache(), transaction);
3506 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3507 EXPECT_EQ(0, cache.disk_cache()->open_count());
3508 EXPECT_EQ(1, cache.disk_cache()->create_count());
3510 // Verify that we added the entry.
3511 disk_cache::Entry* entry;
3512 net::TestCompletionCallback cb;
3513 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3514 &entry,
3515 cb.callback());
3516 ASSERT_EQ(net::OK, cb.GetResult(rv));
3517 EXPECT_EQ(1, cache.disk_cache()->open_count());
3518 entry->Close();
3519 RemoveMockTransaction(&transaction);
3521 // Request the range with the backend that does not support it.
3522 MockTransaction transaction2(kRangeGET_TransactionOK);
3523 std::string headers;
3524 AddMockTransaction(&transaction2);
3525 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3526 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3527 EXPECT_EQ(2, cache.disk_cache()->open_count());
3528 EXPECT_EQ(2, cache.disk_cache()->create_count());
3530 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3531 // if it was re-created later, so this effectively checks that the old data is
3532 // gone.
3533 disk_cache::Entry* entry2;
3534 rv = cache.disk_cache()->OpenEntry(transaction2.url,
3535 &entry2,
3536 cb.callback());
3537 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3538 RemoveMockTransaction(&transaction2);
3541 TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3542 MockHttpCache cache;
3543 cache.disk_cache()->set_fail_sparse_requests();
3545 // Request the range with the backend that does not support it.
3546 MockTransaction transaction(kRangeGET_TransactionOK);
3547 std::string headers;
3548 AddMockTransaction(&transaction);
3549 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3550 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3551 EXPECT_EQ(0, cache.disk_cache()->open_count());
3552 EXPECT_EQ(1, cache.disk_cache()->create_count());
3554 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3555 // if it was re-created later, so this effectively checks that the old data is
3556 // gone as a result of a failed range write.
3557 disk_cache::Entry* entry;
3558 net::TestCompletionCallback cb;
3559 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3560 &entry,
3561 cb.callback());
3562 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3563 RemoveMockTransaction(&transaction);
3566 // Tests that we can cache range requests and fetch random blocks from the
3567 // cache and the network, with synchronous responses.
3568 TEST(HttpCache, RangeGET_SyncOK) {
3569 MockHttpCache cache;
3571 MockTransaction transaction(kRangeGET_TransactionOK);
3572 transaction.test_mode = TEST_MODE_SYNC_ALL;
3573 AddMockTransaction(&transaction);
3575 // Write to the cache (40-49).
3576 std::string headers;
3577 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3579 Verify206Response(headers, 40, 49);
3580 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3581 EXPECT_EQ(0, cache.disk_cache()->open_count());
3582 EXPECT_EQ(1, cache.disk_cache()->create_count());
3584 // Read from the cache (40-49).
3585 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3587 Verify206Response(headers, 40, 49);
3588 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3589 EXPECT_EQ(0, cache.disk_cache()->open_count());
3590 EXPECT_EQ(1, cache.disk_cache()->create_count());
3592 // Make sure we are done with the previous transaction.
3593 base::MessageLoop::current()->RunUntilIdle();
3595 // Write to the cache (30-39).
3596 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3597 transaction.data = "rg: 30-39 ";
3598 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3600 Verify206Response(headers, 30, 39);
3601 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3602 EXPECT_EQ(1, cache.disk_cache()->open_count());
3603 EXPECT_EQ(1, cache.disk_cache()->create_count());
3605 // Make sure we are done with the previous transaction.
3606 base::MessageLoop::current()->RunUntilIdle();
3608 // Write and read from the cache (20-59).
3609 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3610 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3611 net::CapturingBoundNetLog log;
3612 net::LoadTimingInfo load_timing_info;
3613 RunTransactionTestWithResponseAndGetTiming(
3614 cache.http_cache(), transaction, &headers, log.bound(),
3615 &load_timing_info);
3617 Verify206Response(headers, 20, 59);
3618 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3619 EXPECT_EQ(2, cache.disk_cache()->open_count());
3620 EXPECT_EQ(1, cache.disk_cache()->create_count());
3621 TestLoadTimingNetworkRequest(load_timing_info);
3623 RemoveMockTransaction(&transaction);
3626 // Tests that we don't revalidate an entry unless we are required to do so.
3627 TEST(HttpCache, RangeGET_Revalidate1) {
3628 MockHttpCache cache;
3629 std::string headers;
3631 // Write to the cache (40-49).
3632 MockTransaction transaction(kRangeGET_TransactionOK);
3633 transaction.response_headers =
3634 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3635 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3636 "ETag: \"foo\"\n"
3637 "Accept-Ranges: bytes\n"
3638 "Content-Length: 10\n";
3639 AddMockTransaction(&transaction);
3640 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3642 Verify206Response(headers, 40, 49);
3643 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3644 EXPECT_EQ(0, cache.disk_cache()->open_count());
3645 EXPECT_EQ(1, cache.disk_cache()->create_count());
3647 // Read from the cache (40-49).
3648 net::CapturingBoundNetLog log;
3649 net::LoadTimingInfo load_timing_info;
3650 RunTransactionTestWithResponseAndGetTiming(
3651 cache.http_cache(), transaction, &headers, log.bound(),
3652 &load_timing_info);
3654 Verify206Response(headers, 40, 49);
3655 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3656 EXPECT_EQ(1, cache.disk_cache()->open_count());
3657 EXPECT_EQ(1, cache.disk_cache()->create_count());
3658 TestLoadTimingCachedResponse(load_timing_info);
3660 // Read again forcing the revalidation.
3661 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3662 RunTransactionTestWithResponseAndGetTiming(
3663 cache.http_cache(), transaction, &headers, log.bound(),
3664 &load_timing_info);
3666 Verify206Response(headers, 40, 49);
3667 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3668 EXPECT_EQ(1, cache.disk_cache()->open_count());
3669 EXPECT_EQ(1, cache.disk_cache()->create_count());
3670 TestLoadTimingNetworkRequest(load_timing_info);
3672 RemoveMockTransaction(&transaction);
3675 // Checks that we revalidate an entry when the headers say so.
3676 TEST(HttpCache, RangeGET_Revalidate2) {
3677 MockHttpCache cache;
3678 std::string headers;
3680 // Write to the cache (40-49).
3681 MockTransaction transaction(kRangeGET_TransactionOK);
3682 transaction.response_headers =
3683 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3684 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
3685 "ETag: \"foo\"\n"
3686 "Accept-Ranges: bytes\n"
3687 "Content-Length: 10\n";
3688 AddMockTransaction(&transaction);
3689 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3691 Verify206Response(headers, 40, 49);
3692 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3693 EXPECT_EQ(0, cache.disk_cache()->open_count());
3694 EXPECT_EQ(1, cache.disk_cache()->create_count());
3696 // Read from the cache (40-49).
3697 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3698 Verify206Response(headers, 40, 49);
3700 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3701 EXPECT_EQ(1, cache.disk_cache()->open_count());
3702 EXPECT_EQ(1, cache.disk_cache()->create_count());
3704 RemoveMockTransaction(&transaction);
3707 // Tests that we deal with 304s for range requests.
3708 TEST(HttpCache, RangeGET_304) {
3709 MockHttpCache cache;
3710 AddMockTransaction(&kRangeGET_TransactionOK);
3711 std::string headers;
3713 // Write to the cache (40-49).
3714 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3715 &headers);
3717 Verify206Response(headers, 40, 49);
3718 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3719 EXPECT_EQ(0, cache.disk_cache()->open_count());
3720 EXPECT_EQ(1, cache.disk_cache()->create_count());
3722 // Read from the cache (40-49).
3723 RangeTransactionServer handler;
3724 handler.set_not_modified(true);
3725 MockTransaction transaction(kRangeGET_TransactionOK);
3726 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3727 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3729 Verify206Response(headers, 40, 49);
3730 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3731 EXPECT_EQ(1, cache.disk_cache()->open_count());
3732 EXPECT_EQ(1, cache.disk_cache()->create_count());
3734 RemoveMockTransaction(&kRangeGET_TransactionOK);
3737 // Tests that we deal with 206s when revalidating range requests.
3738 TEST(HttpCache, RangeGET_ModifiedResult) {
3739 MockHttpCache cache;
3740 AddMockTransaction(&kRangeGET_TransactionOK);
3741 std::string headers;
3743 // Write to the cache (40-49).
3744 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3745 &headers);
3747 Verify206Response(headers, 40, 49);
3748 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3749 EXPECT_EQ(0, cache.disk_cache()->open_count());
3750 EXPECT_EQ(1, cache.disk_cache()->create_count());
3752 // Attempt to read from the cache (40-49).
3753 RangeTransactionServer handler;
3754 handler.set_modified(true);
3755 MockTransaction transaction(kRangeGET_TransactionOK);
3756 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3757 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3759 Verify206Response(headers, 40, 49);
3760 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3761 EXPECT_EQ(1, cache.disk_cache()->open_count());
3762 EXPECT_EQ(1, cache.disk_cache()->create_count());
3764 // And the entry should be gone.
3765 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3766 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3767 EXPECT_EQ(1, cache.disk_cache()->open_count());
3768 EXPECT_EQ(2, cache.disk_cache()->create_count());
3770 RemoveMockTransaction(&kRangeGET_TransactionOK);
3773 // Tests that we cache 301s for range requests.
3774 TEST(HttpCache, RangeGET_301) {
3775 MockHttpCache cache;
3776 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3777 transaction.status = "HTTP/1.1 301 Moved Permanently";
3778 transaction.response_headers = "Location: http://www.bar.com/\n";
3779 transaction.data = "";
3780 transaction.handler = NULL;
3781 AddMockTransaction(&transaction);
3783 // Write to the cache.
3784 RunTransactionTest(cache.http_cache(), transaction);
3785 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3786 EXPECT_EQ(0, cache.disk_cache()->open_count());
3787 EXPECT_EQ(1, cache.disk_cache()->create_count());
3789 // Read from the cache.
3790 RunTransactionTest(cache.http_cache(), transaction);
3791 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3792 EXPECT_EQ(1, cache.disk_cache()->open_count());
3793 EXPECT_EQ(1, cache.disk_cache()->create_count());
3795 RemoveMockTransaction(&transaction);
3798 // Tests that we can cache range requests when the start or end is unknown.
3799 // We start with one suffix request, followed by a request from a given point.
3800 TEST(HttpCache, UnknownRangeGET_1) {
3801 MockHttpCache cache;
3802 AddMockTransaction(&kRangeGET_TransactionOK);
3803 std::string headers;
3805 // Write to the cache (70-79).
3806 MockTransaction transaction(kRangeGET_TransactionOK);
3807 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3808 transaction.data = "rg: 70-79 ";
3809 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3811 Verify206Response(headers, 70, 79);
3812 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3813 EXPECT_EQ(0, cache.disk_cache()->open_count());
3814 EXPECT_EQ(1, cache.disk_cache()->create_count());
3816 // Make sure we are done with the previous transaction.
3817 base::MessageLoop::current()->RunUntilIdle();
3819 // Write and read from the cache (60-79).
3820 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
3821 transaction.data = "rg: 60-69 rg: 70-79 ";
3822 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3824 Verify206Response(headers, 60, 79);
3825 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3826 EXPECT_EQ(1, cache.disk_cache()->open_count());
3827 EXPECT_EQ(1, cache.disk_cache()->create_count());
3829 RemoveMockTransaction(&kRangeGET_TransactionOK);
3832 // Tests that we can cache range requests when the start or end is unknown.
3833 // We start with one request from a given point, followed by a suffix request.
3834 // We'll also verify that synchronous cache responses work as intended.
3835 TEST(HttpCache, UnknownRangeGET_2) {
3836 MockHttpCache cache;
3837 std::string headers;
3839 MockTransaction transaction(kRangeGET_TransactionOK);
3840 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
3841 TEST_MODE_SYNC_CACHE_READ |
3842 TEST_MODE_SYNC_CACHE_WRITE;
3843 AddMockTransaction(&transaction);
3845 // Write to the cache (70-79).
3846 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3847 transaction.data = "rg: 70-79 ";
3848 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3850 Verify206Response(headers, 70, 79);
3851 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3852 EXPECT_EQ(0, cache.disk_cache()->open_count());
3853 EXPECT_EQ(1, cache.disk_cache()->create_count());
3855 // Make sure we are done with the previous transaction.
3856 base::MessageLoop::current()->RunUntilIdle();
3858 // Write and read from the cache (60-79).
3859 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
3860 transaction.data = "rg: 60-69 rg: 70-79 ";
3861 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3863 Verify206Response(headers, 60, 79);
3864 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3865 EXPECT_EQ(1, cache.disk_cache()->open_count());
3866 EXPECT_EQ(1, cache.disk_cache()->create_count());
3868 RemoveMockTransaction(&transaction);
3871 // Tests that receiving Not Modified when asking for an open range doesn't mess
3872 // up things.
3873 TEST(HttpCache, UnknownRangeGET_304) {
3874 MockHttpCache cache;
3875 std::string headers;
3877 MockTransaction transaction(kRangeGET_TransactionOK);
3878 AddMockTransaction(&transaction);
3880 RangeTransactionServer handler;
3881 handler.set_not_modified(true);
3883 // Ask for the end of the file, without knowing the length.
3884 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3885 transaction.data = "";
3886 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3888 // We just bypass the cache.
3889 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3890 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3891 EXPECT_EQ(0, cache.disk_cache()->open_count());
3892 EXPECT_EQ(1, cache.disk_cache()->create_count());
3894 RunTransactionTest(cache.http_cache(), transaction);
3895 EXPECT_EQ(2, cache.disk_cache()->create_count());
3897 RemoveMockTransaction(&transaction);
3900 // Tests that we can handle non-range requests when we have cached a range.
3901 TEST(HttpCache, GET_Previous206) {
3902 MockHttpCache cache;
3903 AddMockTransaction(&kRangeGET_TransactionOK);
3904 std::string headers;
3905 net::CapturingBoundNetLog log;
3906 net::LoadTimingInfo load_timing_info;
3908 // Write to the cache (40-49).
3909 RunTransactionTestWithResponseAndGetTiming(
3910 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
3911 &load_timing_info);
3913 Verify206Response(headers, 40, 49);
3914 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3915 EXPECT_EQ(0, cache.disk_cache()->open_count());
3916 EXPECT_EQ(1, cache.disk_cache()->create_count());
3917 TestLoadTimingNetworkRequest(load_timing_info);
3919 // Write and read from the cache (0-79), when not asked for a range.
3920 MockTransaction transaction(kRangeGET_TransactionOK);
3921 transaction.request_headers = EXTRA_HEADER;
3922 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3923 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3924 RunTransactionTestWithResponseAndGetTiming(
3925 cache.http_cache(), transaction, &headers, log.bound(),
3926 &load_timing_info);
3928 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3929 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3930 EXPECT_EQ(1, cache.disk_cache()->open_count());
3931 EXPECT_EQ(1, cache.disk_cache()->create_count());
3932 TestLoadTimingNetworkRequest(load_timing_info);
3934 RemoveMockTransaction(&kRangeGET_TransactionOK);
3937 // Tests that we can handle non-range requests when we have cached the first
3938 // part of the object and the server replies with 304 (Not Modified).
3939 TEST(HttpCache, GET_Previous206_NotModified) {
3940 MockHttpCache cache;
3942 MockTransaction transaction(kRangeGET_TransactionOK);
3943 AddMockTransaction(&transaction);
3944 std::string headers;
3945 net::CapturingBoundNetLog log;
3946 net::LoadTimingInfo load_timing_info;
3948 // Write to the cache (0-9).
3949 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3950 transaction.data = "rg: 00-09 ";
3951 RunTransactionTestWithResponseAndGetTiming(
3952 cache.http_cache(), transaction, &headers, log.bound(),
3953 &load_timing_info);
3954 Verify206Response(headers, 0, 9);
3955 TestLoadTimingNetworkRequest(load_timing_info);
3957 // Write to the cache (70-79).
3958 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3959 transaction.data = "rg: 70-79 ";
3960 RunTransactionTestWithResponseAndGetTiming(
3961 cache.http_cache(), transaction, &headers, log.bound(),
3962 &load_timing_info);
3963 Verify206Response(headers, 70, 79);
3965 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3966 EXPECT_EQ(1, cache.disk_cache()->open_count());
3967 EXPECT_EQ(1, cache.disk_cache()->create_count());
3968 TestLoadTimingNetworkRequest(load_timing_info);
3970 // Read from the cache (0-9), write and read from cache (10 - 79).
3971 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3972 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3973 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3974 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3975 RunTransactionTestWithResponseAndGetTiming(
3976 cache.http_cache(), transaction, &headers, log.bound(),
3977 &load_timing_info);
3979 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3980 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3981 EXPECT_EQ(2, cache.disk_cache()->open_count());
3982 EXPECT_EQ(1, cache.disk_cache()->create_count());
3983 TestLoadTimingNetworkRequest(load_timing_info);
3985 RemoveMockTransaction(&transaction);
3988 // Tests that we can handle a regular request to a sparse entry, that results in
3989 // new content provided by the server (206).
3990 TEST(HttpCache, GET_Previous206_NewContent) {
3991 MockHttpCache cache;
3992 AddMockTransaction(&kRangeGET_TransactionOK);
3993 std::string headers;
3995 // Write to the cache (0-9).
3996 MockTransaction transaction(kRangeGET_TransactionOK);
3997 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3998 transaction.data = "rg: 00-09 ";
3999 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4001 Verify206Response(headers, 0, 9);
4002 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4003 EXPECT_EQ(0, cache.disk_cache()->open_count());
4004 EXPECT_EQ(1, cache.disk_cache()->create_count());
4006 // Now we'll issue a request without any range that should result first in a
4007 // 206 (when revalidating), and then in a weird standard answer: the test
4008 // server will not modify the response so we'll get the default range... a
4009 // real server will answer with 200.
4010 MockTransaction transaction2(kRangeGET_TransactionOK);
4011 transaction2.request_headers = EXTRA_HEADER;
4012 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
4013 transaction2.data = "Not a range";
4014 RangeTransactionServer handler;
4015 handler.set_modified(true);
4016 net::CapturingBoundNetLog log;
4017 net::LoadTimingInfo load_timing_info;
4018 RunTransactionTestWithResponseAndGetTiming(
4019 cache.http_cache(), transaction2, &headers, log.bound(),
4020 &load_timing_info);
4022 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4023 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4024 EXPECT_EQ(1, cache.disk_cache()->open_count());
4025 EXPECT_EQ(1, cache.disk_cache()->create_count());
4026 TestLoadTimingNetworkRequest(load_timing_info);
4028 // Verify that the previous request deleted the entry.
4029 RunTransactionTest(cache.http_cache(), transaction);
4030 EXPECT_EQ(2, cache.disk_cache()->create_count());
4032 RemoveMockTransaction(&transaction);
4035 // Tests that we can handle cached 206 responses that are not sparse.
4036 TEST(HttpCache, GET_Previous206_NotSparse) {
4037 MockHttpCache cache;
4039 // Create a disk cache entry that stores 206 headers while not being sparse.
4040 disk_cache::Entry* entry;
4041 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4042 NULL));
4044 std::string raw_headers(kRangeGET_TransactionOK.status);
4045 raw_headers.append("\n");
4046 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4047 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4048 raw_headers.size());
4050 net::HttpResponseInfo response;
4051 response.headers = new net::HttpResponseHeaders(raw_headers);
4052 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4054 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4055 int len = static_cast<int>(base::strlcpy(buf->data(),
4056 kRangeGET_TransactionOK.data, 500));
4057 net::TestCompletionCallback cb;
4058 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4059 EXPECT_EQ(len, cb.GetResult(rv));
4060 entry->Close();
4062 // Now see that we don't use the stored entry.
4063 std::string headers;
4064 net::CapturingBoundNetLog log;
4065 net::LoadTimingInfo load_timing_info;
4066 RunTransactionTestWithResponseAndGetTiming(
4067 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4068 &load_timing_info);
4070 // We are expecting a 200.
4071 std::string expected_headers(kSimpleGET_Transaction.status);
4072 expected_headers.append("\n");
4073 expected_headers.append(kSimpleGET_Transaction.response_headers);
4074 EXPECT_EQ(expected_headers, headers);
4075 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4076 EXPECT_EQ(1, cache.disk_cache()->open_count());
4077 EXPECT_EQ(2, cache.disk_cache()->create_count());
4078 TestLoadTimingNetworkRequest(load_timing_info);
4081 // Tests that we can handle cached 206 responses that are not sparse. This time
4082 // we issue a range request and expect to receive a range.
4083 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4084 MockHttpCache cache;
4085 AddMockTransaction(&kRangeGET_TransactionOK);
4087 // Create a disk cache entry that stores 206 headers while not being sparse.
4088 disk_cache::Entry* entry;
4089 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4090 NULL));
4092 std::string raw_headers(kRangeGET_TransactionOK.status);
4093 raw_headers.append("\n");
4094 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4095 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4096 raw_headers.size());
4098 net::HttpResponseInfo response;
4099 response.headers = new net::HttpResponseHeaders(raw_headers);
4100 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4102 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4103 int len = static_cast<int>(base::strlcpy(buf->data(),
4104 kRangeGET_TransactionOK.data, 500));
4105 net::TestCompletionCallback cb;
4106 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4107 EXPECT_EQ(len, cb.GetResult(rv));
4108 entry->Close();
4110 // Now see that we don't use the stored entry.
4111 std::string headers;
4112 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4113 &headers);
4115 // We are expecting a 206.
4116 Verify206Response(headers, 40, 49);
4117 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4118 EXPECT_EQ(1, cache.disk_cache()->open_count());
4119 EXPECT_EQ(2, cache.disk_cache()->create_count());
4121 RemoveMockTransaction(&kRangeGET_TransactionOK);
4124 // Tests that we can handle cached 206 responses that can't be validated.
4125 TEST(HttpCache, GET_Previous206_NotValidation) {
4126 MockHttpCache cache;
4128 // Create a disk cache entry that stores 206 headers.
4129 disk_cache::Entry* entry;
4130 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4131 NULL));
4133 // Make sure that the headers cannot be validated with the server.
4134 std::string raw_headers(kRangeGET_TransactionOK.status);
4135 raw_headers.append("\n");
4136 raw_headers.append("Content-Length: 80\n");
4137 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4138 raw_headers.size());
4140 net::HttpResponseInfo response;
4141 response.headers = new net::HttpResponseHeaders(raw_headers);
4142 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4144 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4145 int len = static_cast<int>(base::strlcpy(buf->data(),
4146 kRangeGET_TransactionOK.data, 500));
4147 net::TestCompletionCallback cb;
4148 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4149 EXPECT_EQ(len, cb.GetResult(rv));
4150 entry->Close();
4152 // Now see that we don't use the stored entry.
4153 std::string headers;
4154 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4155 &headers);
4157 // We are expecting a 200.
4158 std::string expected_headers(kSimpleGET_Transaction.status);
4159 expected_headers.append("\n");
4160 expected_headers.append(kSimpleGET_Transaction.response_headers);
4161 EXPECT_EQ(expected_headers, headers);
4162 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4163 EXPECT_EQ(1, cache.disk_cache()->open_count());
4164 EXPECT_EQ(2, cache.disk_cache()->create_count());
4167 // Tests that we can handle range requests with cached 200 responses.
4168 TEST(HttpCache, RangeGET_Previous200) {
4169 MockHttpCache cache;
4171 // Store the whole thing with status 200.
4172 MockTransaction transaction(kTypicalGET_Transaction);
4173 transaction.url = kRangeGET_TransactionOK.url;
4174 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4175 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4176 AddMockTransaction(&transaction);
4177 RunTransactionTest(cache.http_cache(), transaction);
4178 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4179 EXPECT_EQ(0, cache.disk_cache()->open_count());
4180 EXPECT_EQ(1, cache.disk_cache()->create_count());
4182 RemoveMockTransaction(&transaction);
4183 AddMockTransaction(&kRangeGET_TransactionOK);
4185 // Now see that we use the stored entry.
4186 std::string headers;
4187 MockTransaction transaction2(kRangeGET_TransactionOK);
4188 RangeTransactionServer handler;
4189 handler.set_not_modified(true);
4190 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4192 // We are expecting a 206.
4193 Verify206Response(headers, 40, 49);
4194 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4195 EXPECT_EQ(1, cache.disk_cache()->open_count());
4196 EXPECT_EQ(1, cache.disk_cache()->create_count());
4198 // The last transaction has finished so make sure the entry is deactivated.
4199 base::MessageLoop::current()->RunUntilIdle();
4201 // Make a request for an invalid range.
4202 MockTransaction transaction3(kRangeGET_TransactionOK);
4203 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4204 transaction3.data = transaction.data;
4205 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4206 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4207 EXPECT_EQ(2, cache.disk_cache()->open_count());
4208 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4209 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4210 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4212 // Make sure the entry is deactivated.
4213 base::MessageLoop::current()->RunUntilIdle();
4215 // Even though the request was invalid, we should have the entry.
4216 RunTransactionTest(cache.http_cache(), transaction2);
4217 EXPECT_EQ(3, cache.disk_cache()->open_count());
4219 // Make sure the entry is deactivated.
4220 base::MessageLoop::current()->RunUntilIdle();
4222 // Now we should receive a range from the server and drop the stored entry.
4223 handler.set_not_modified(false);
4224 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4225 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4226 Verify206Response(headers, 40, 49);
4227 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4228 EXPECT_EQ(4, cache.disk_cache()->open_count());
4229 EXPECT_EQ(1, cache.disk_cache()->create_count());
4231 RunTransactionTest(cache.http_cache(), transaction2);
4232 EXPECT_EQ(2, cache.disk_cache()->create_count());
4234 RemoveMockTransaction(&kRangeGET_TransactionOK);
4237 // Tests that we can handle a 200 response when dealing with sparse entries.
4238 TEST(HttpCache, RangeRequestResultsIn200) {
4239 MockHttpCache cache;
4240 AddMockTransaction(&kRangeGET_TransactionOK);
4241 std::string headers;
4243 // Write to the cache (70-79).
4244 MockTransaction transaction(kRangeGET_TransactionOK);
4245 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4246 transaction.data = "rg: 70-79 ";
4247 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4249 Verify206Response(headers, 70, 79);
4250 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4251 EXPECT_EQ(0, cache.disk_cache()->open_count());
4252 EXPECT_EQ(1, cache.disk_cache()->create_count());
4254 // Now we'll issue a request that results in a plain 200 response, but to
4255 // the to the same URL that we used to store sparse data, and making sure
4256 // that we ask for a range.
4257 RemoveMockTransaction(&kRangeGET_TransactionOK);
4258 MockTransaction transaction2(kSimpleGET_Transaction);
4259 transaction2.url = kRangeGET_TransactionOK.url;
4260 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4261 AddMockTransaction(&transaction2);
4263 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4265 std::string expected_headers(kSimpleGET_Transaction.status);
4266 expected_headers.append("\n");
4267 expected_headers.append(kSimpleGET_Transaction.response_headers);
4268 EXPECT_EQ(expected_headers, headers);
4269 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4270 EXPECT_EQ(1, cache.disk_cache()->open_count());
4271 EXPECT_EQ(1, cache.disk_cache()->create_count());
4273 RemoveMockTransaction(&transaction2);
4276 // Tests that a range request that falls outside of the size that we know about
4277 // only deletes the entry if the resource has indeed changed.
4278 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4279 MockHttpCache cache;
4280 AddMockTransaction(&kRangeGET_TransactionOK);
4281 std::string headers;
4283 // Write to the cache (40-49).
4284 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4285 &headers);
4287 Verify206Response(headers, 40, 49);
4288 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4289 EXPECT_EQ(0, cache.disk_cache()->open_count());
4290 EXPECT_EQ(1, cache.disk_cache()->create_count());
4292 // A weird request should not delete this entry. Ask for bytes 120-.
4293 MockTransaction transaction(kRangeGET_TransactionOK);
4294 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4295 transaction.data = "";
4296 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4298 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4299 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4300 EXPECT_EQ(1, cache.disk_cache()->open_count());
4301 EXPECT_EQ(1, cache.disk_cache()->create_count());
4303 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4304 EXPECT_EQ(2, cache.disk_cache()->open_count());
4305 EXPECT_EQ(1, cache.disk_cache()->create_count());
4307 RemoveMockTransaction(&kRangeGET_TransactionOK);
4310 // Tests that we don't delete a sparse entry when we cancel a request.
4311 TEST(HttpCache, RangeGET_Cancel) {
4312 MockHttpCache cache;
4313 AddMockTransaction(&kRangeGET_TransactionOK);
4315 MockHttpRequest request(kRangeGET_TransactionOK);
4317 Context* c = new Context();
4318 int rv = cache.CreateTransaction(&c->trans);
4319 ASSERT_EQ(net::OK, rv);
4321 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4322 if (rv == net::ERR_IO_PENDING)
4323 rv = c->callback.WaitForResult();
4325 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4326 EXPECT_EQ(0, cache.disk_cache()->open_count());
4327 EXPECT_EQ(1, cache.disk_cache()->create_count());
4329 // Make sure that the entry has some data stored.
4330 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4331 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4332 if (rv == net::ERR_IO_PENDING)
4333 rv = c->callback.WaitForResult();
4334 EXPECT_EQ(buf->size(), rv);
4336 // Destroy the transaction.
4337 delete c;
4339 // Verify that the entry has not been deleted.
4340 disk_cache::Entry* entry;
4341 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4342 entry->Close();
4343 RemoveMockTransaction(&kRangeGET_TransactionOK);
4346 // Tests that we don't delete a sparse entry when we start a new request after
4347 // cancelling the previous one.
4348 TEST(HttpCache, RangeGET_Cancel2) {
4349 MockHttpCache cache;
4350 AddMockTransaction(&kRangeGET_TransactionOK);
4352 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4353 MockHttpRequest request(kRangeGET_TransactionOK);
4354 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4356 Context* c = new Context();
4357 int rv = cache.CreateTransaction(&c->trans);
4358 ASSERT_EQ(net::OK, rv);
4360 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4361 if (rv == net::ERR_IO_PENDING)
4362 rv = c->callback.WaitForResult();
4364 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4365 EXPECT_EQ(1, cache.disk_cache()->open_count());
4366 EXPECT_EQ(1, cache.disk_cache()->create_count());
4368 // Make sure that we revalidate the entry and read from the cache (a single
4369 // read will return while waiting for the network).
4370 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4371 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4372 EXPECT_EQ(5, c->callback.GetResult(rv));
4373 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4374 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4376 // Destroy the transaction before completing the read.
4377 delete c;
4379 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4380 // message loop. This means that a new transaction will just reuse the same
4381 // active entry (no open or create).
4383 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4385 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4386 EXPECT_EQ(1, cache.disk_cache()->open_count());
4387 EXPECT_EQ(1, cache.disk_cache()->create_count());
4388 RemoveMockTransaction(&kRangeGET_TransactionOK);
4391 // A slight variation of the previous test, this time we cancel two requests in
4392 // a row, making sure that the second is waiting for the entry to be ready.
4393 TEST(HttpCache, RangeGET_Cancel3) {
4394 MockHttpCache cache;
4395 AddMockTransaction(&kRangeGET_TransactionOK);
4397 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4398 MockHttpRequest request(kRangeGET_TransactionOK);
4399 request.load_flags |= net::LOAD_VALIDATE_CACHE;
4401 Context* c = new Context();
4402 int rv = cache.CreateTransaction(&c->trans);
4403 ASSERT_EQ(net::OK, rv);
4405 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4406 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4407 rv = c->callback.WaitForResult();
4409 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4410 EXPECT_EQ(1, cache.disk_cache()->open_count());
4411 EXPECT_EQ(1, cache.disk_cache()->create_count());
4413 // Make sure that we revalidate the entry and read from the cache (a single
4414 // read will return while waiting for the network).
4415 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4416 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4417 EXPECT_EQ(5, c->callback.GetResult(rv));
4418 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4419 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4421 // Destroy the transaction before completing the read.
4422 delete c;
4424 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4425 // message loop. This means that a new transaction will just reuse the same
4426 // active entry (no open or create).
4428 c = new Context();
4429 rv = cache.CreateTransaction(&c->trans);
4430 ASSERT_EQ(net::OK, rv);
4432 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4433 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4435 MockDiskEntry::IgnoreCallbacks(true);
4436 base::MessageLoop::current()->RunUntilIdle();
4437 MockDiskEntry::IgnoreCallbacks(false);
4439 // The new transaction is waiting for the query range callback.
4440 delete c;
4442 // And we should not crash when the callback is delivered.
4443 base::MessageLoop::current()->RunUntilIdle();
4445 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4446 EXPECT_EQ(1, cache.disk_cache()->open_count());
4447 EXPECT_EQ(1, cache.disk_cache()->create_count());
4448 RemoveMockTransaction(&kRangeGET_TransactionOK);
4451 // Tests that an invalid range response results in no cached entry.
4452 TEST(HttpCache, RangeGET_InvalidResponse1) {
4453 MockHttpCache cache;
4454 std::string headers;
4456 MockTransaction transaction(kRangeGET_TransactionOK);
4457 transaction.handler = NULL;
4458 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4459 "Content-Length: 10\n";
4460 AddMockTransaction(&transaction);
4461 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4463 std::string expected(transaction.status);
4464 expected.append("\n");
4465 expected.append(transaction.response_headers);
4466 EXPECT_EQ(expected, headers);
4468 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4469 EXPECT_EQ(0, cache.disk_cache()->open_count());
4470 EXPECT_EQ(1, cache.disk_cache()->create_count());
4472 // Verify that we don't have a cached entry.
4473 disk_cache::Entry* entry;
4474 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4476 RemoveMockTransaction(&kRangeGET_TransactionOK);
4479 // Tests that we reject a range that doesn't match the content-length.
4480 TEST(HttpCache, RangeGET_InvalidResponse2) {
4481 MockHttpCache cache;
4482 std::string headers;
4484 MockTransaction transaction(kRangeGET_TransactionOK);
4485 transaction.handler = NULL;
4486 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4487 "Content-Length: 20\n";
4488 AddMockTransaction(&transaction);
4489 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4491 std::string expected(transaction.status);
4492 expected.append("\n");
4493 expected.append(transaction.response_headers);
4494 EXPECT_EQ(expected, headers);
4496 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4497 EXPECT_EQ(0, cache.disk_cache()->open_count());
4498 EXPECT_EQ(1, cache.disk_cache()->create_count());
4500 // Verify that we don't have a cached entry.
4501 disk_cache::Entry* entry;
4502 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4504 RemoveMockTransaction(&kRangeGET_TransactionOK);
4507 // Tests that if a server tells us conflicting information about a resource we
4508 // ignore the response.
4509 TEST(HttpCache, RangeGET_InvalidResponse3) {
4510 MockHttpCache cache;
4511 std::string headers;
4513 MockTransaction transaction(kRangeGET_TransactionOK);
4514 transaction.handler = NULL;
4515 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4516 std::string response_headers(transaction.response_headers);
4517 response_headers.append("Content-Range: bytes 50-59/160\n");
4518 transaction.response_headers = response_headers.c_str();
4519 AddMockTransaction(&transaction);
4520 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4522 Verify206Response(headers, 50, 59);
4523 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4524 EXPECT_EQ(0, cache.disk_cache()->open_count());
4525 EXPECT_EQ(1, cache.disk_cache()->create_count());
4527 RemoveMockTransaction(&transaction);
4528 AddMockTransaction(&kRangeGET_TransactionOK);
4530 // This transaction will report a resource size of 80 bytes, and we think it's
4531 // 160 so we should ignore the response.
4532 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4533 &headers);
4535 Verify206Response(headers, 40, 49);
4536 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4537 EXPECT_EQ(1, cache.disk_cache()->open_count());
4538 EXPECT_EQ(1, cache.disk_cache()->create_count());
4540 // Verify that we cached the first response but not the second one.
4541 disk_cache::Entry* en;
4542 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4544 int64 cached_start = 0;
4545 net::TestCompletionCallback cb;
4546 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4547 EXPECT_EQ(10, cb.GetResult(rv));
4548 EXPECT_EQ(50, cached_start);
4549 en->Close();
4551 RemoveMockTransaction(&kRangeGET_TransactionOK);
4554 // Tests that we handle large range values properly.
4555 TEST(HttpCache, RangeGET_LargeValues) {
4556 // We need a real sparse cache for this test.
4557 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4558 std::string headers;
4560 MockTransaction transaction(kRangeGET_TransactionOK);
4561 transaction.handler = NULL;
4562 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4563 EXTRA_HEADER;
4564 transaction.response_headers =
4565 "ETag: \"foo\"\n"
4566 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4567 "Content-Length: 10\n";
4568 AddMockTransaction(&transaction);
4569 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4571 std::string expected(transaction.status);
4572 expected.append("\n");
4573 expected.append(transaction.response_headers);
4574 EXPECT_EQ(expected, headers);
4576 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4578 // Verify that we have a cached entry.
4579 disk_cache::Entry* en;
4580 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4581 en->Close();
4583 RemoveMockTransaction(&kRangeGET_TransactionOK);
4586 // Tests that we don't crash with a range request if the disk cache was not
4587 // initialized properly.
4588 TEST(HttpCache, RangeGET_NoDiskCache) {
4589 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4590 factory->set_fail(true);
4591 factory->FinishCreation(); // We'll complete synchronously.
4592 MockHttpCache cache(factory);
4594 AddMockTransaction(&kRangeGET_TransactionOK);
4596 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4597 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4599 RemoveMockTransaction(&kRangeGET_TransactionOK);
4602 // Tests that we handle byte range requests that skip the cache.
4603 TEST(HttpCache, RangeHEAD) {
4604 MockHttpCache cache;
4605 AddMockTransaction(&kRangeGET_TransactionOK);
4607 MockTransaction transaction(kRangeGET_TransactionOK);
4608 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4609 transaction.method = "HEAD";
4610 transaction.data = "rg: 70-79 ";
4612 std::string headers;
4613 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4615 Verify206Response(headers, 70, 79);
4616 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4617 EXPECT_EQ(0, cache.disk_cache()->open_count());
4618 EXPECT_EQ(0, cache.disk_cache()->create_count());
4620 RemoveMockTransaction(&kRangeGET_TransactionOK);
4623 // Tests that we don't crash when after reading from the cache we issue a
4624 // request for the next range and the server gives us a 200 synchronously.
4625 TEST(HttpCache, RangeGET_FastFlakyServer) {
4626 MockHttpCache cache;
4628 MockTransaction transaction(kRangeGET_TransactionOK);
4629 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4630 transaction.test_mode = TEST_MODE_SYNC_NET_START;
4631 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4632 AddMockTransaction(&transaction);
4634 // Write to the cache.
4635 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4637 // And now read from the cache and the network.
4638 RangeTransactionServer handler;
4639 handler.set_bad_200(true);
4640 transaction.data = "Not a range";
4641 RunTransactionTest(cache.http_cache(), transaction);
4643 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4644 EXPECT_EQ(1, cache.disk_cache()->open_count());
4645 EXPECT_EQ(1, cache.disk_cache()->create_count());
4647 RemoveMockTransaction(&transaction);
4650 // Tests that when the server gives us less data than expected, we don't keep
4651 // asking for more data.
4652 TEST(HttpCache, RangeGET_FastFlakyServer2) {
4653 MockHttpCache cache;
4655 // First, check with an empty cache (WRITE mode).
4656 MockTransaction transaction(kRangeGET_TransactionOK);
4657 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4658 transaction.data = "rg: 40-"; // Less than expected.
4659 transaction.handler = NULL;
4660 std::string headers(transaction.response_headers);
4661 headers.append("Content-Range: bytes 40-49/80\n");
4662 transaction.response_headers = headers.c_str();
4664 AddMockTransaction(&transaction);
4666 // Write to the cache.
4667 RunTransactionTest(cache.http_cache(), transaction);
4669 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4670 EXPECT_EQ(0, cache.disk_cache()->open_count());
4671 EXPECT_EQ(1, cache.disk_cache()->create_count());
4673 // Now verify that even in READ_WRITE mode, we forward the bad response to
4674 // the caller.
4675 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4676 transaction.data = "rg: 60-"; // Less than expected.
4677 headers = kRangeGET_TransactionOK.response_headers;
4678 headers.append("Content-Range: bytes 60-69/80\n");
4679 transaction.response_headers = headers.c_str();
4681 RunTransactionTest(cache.http_cache(), transaction);
4683 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4684 EXPECT_EQ(1, cache.disk_cache()->open_count());
4685 EXPECT_EQ(1, cache.disk_cache()->create_count());
4687 RemoveMockTransaction(&transaction);
4690 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
4691 // This test hits a NOTREACHED so it is a release mode only test.
4692 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
4693 MockHttpCache cache;
4694 AddMockTransaction(&kRangeGET_TransactionOK);
4696 // Write to the cache (40-49).
4697 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4698 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4699 EXPECT_EQ(0, cache.disk_cache()->open_count());
4700 EXPECT_EQ(1, cache.disk_cache()->create_count());
4702 // Force this transaction to read from the cache.
4703 MockTransaction transaction(kRangeGET_TransactionOK);
4704 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4706 MockHttpRequest request(transaction);
4707 net::TestCompletionCallback callback;
4709 scoped_ptr<net::HttpTransaction> trans;
4710 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
4711 EXPECT_EQ(net::OK, rv);
4712 ASSERT_TRUE(trans.get());
4714 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
4715 if (rv == net::ERR_IO_PENDING)
4716 rv = callback.WaitForResult();
4717 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4719 trans.reset();
4721 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4722 EXPECT_EQ(1, cache.disk_cache()->open_count());
4723 EXPECT_EQ(1, cache.disk_cache()->create_count());
4725 RemoveMockTransaction(&kRangeGET_TransactionOK);
4727 #endif
4729 // Tests the handling of the "truncation" flag.
4730 TEST(HttpCache, WriteResponseInfo_Truncated) {
4731 MockHttpCache cache;
4732 disk_cache::Entry* entry;
4733 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
4734 NULL));
4736 std::string headers("HTTP/1.1 200 OK");
4737 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4738 net::HttpResponseInfo response;
4739 response.headers = new net::HttpResponseHeaders(headers);
4741 // Set the last argument for this to be an incomplete request.
4742 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
4743 bool truncated = false;
4744 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4745 EXPECT_TRUE(truncated);
4747 // And now test the opposite case.
4748 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4749 truncated = true;
4750 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4751 EXPECT_FALSE(truncated);
4752 entry->Close();
4755 // Tests basic pickling/unpickling of HttpResponseInfo.
4756 TEST(HttpCache, PersistHttpResponseInfo) {
4757 // Set some fields (add more if needed.)
4758 net::HttpResponseInfo response1;
4759 response1.was_cached = false;
4760 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4761 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4763 // Pickle.
4764 Pickle pickle;
4765 response1.Persist(&pickle, false, false);
4767 // Unpickle.
4768 net::HttpResponseInfo response2;
4769 bool response_truncated;
4770 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4771 EXPECT_FALSE(response_truncated);
4773 // Verify fields.
4774 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
4775 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4776 EXPECT_EQ(80, response2.socket_address.port());
4777 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4780 // Tests that we delete an entry when the request is cancelled before starting
4781 // to read from the network.
4782 TEST(HttpCache, DoomOnDestruction) {
4783 MockHttpCache cache;
4785 MockHttpRequest request(kSimpleGET_Transaction);
4787 Context* c = new Context();
4788 int rv = cache.CreateTransaction(&c->trans);
4789 ASSERT_EQ(net::OK, rv);
4791 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4792 if (rv == net::ERR_IO_PENDING)
4793 c->result = c->callback.WaitForResult();
4795 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4796 EXPECT_EQ(0, cache.disk_cache()->open_count());
4797 EXPECT_EQ(1, cache.disk_cache()->create_count());
4799 // Destroy the transaction. We only have the headers so we should delete this
4800 // entry.
4801 delete c;
4803 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4805 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4806 EXPECT_EQ(0, cache.disk_cache()->open_count());
4807 EXPECT_EQ(2, cache.disk_cache()->create_count());
4810 // Tests that we delete an entry when the request is cancelled if the response
4811 // does not have content-length and strong validators.
4812 TEST(HttpCache, DoomOnDestruction2) {
4813 MockHttpCache cache;
4815 MockHttpRequest request(kSimpleGET_Transaction);
4817 Context* c = new Context();
4818 int rv = cache.CreateTransaction(&c->trans);
4819 ASSERT_EQ(net::OK, rv);
4821 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4822 if (rv == net::ERR_IO_PENDING)
4823 rv = c->callback.WaitForResult();
4825 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4826 EXPECT_EQ(0, cache.disk_cache()->open_count());
4827 EXPECT_EQ(1, cache.disk_cache()->create_count());
4829 // Make sure that the entry has some data stored.
4830 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4831 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4832 if (rv == net::ERR_IO_PENDING)
4833 rv = c->callback.WaitForResult();
4834 EXPECT_EQ(buf->size(), rv);
4836 // Destroy the transaction.
4837 delete c;
4839 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4841 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4842 EXPECT_EQ(0, cache.disk_cache()->open_count());
4843 EXPECT_EQ(2, cache.disk_cache()->create_count());
4846 // Tests that we delete an entry when the request is cancelled if the response
4847 // has an "Accept-Ranges: none" header.
4848 TEST(HttpCache, DoomOnDestruction3) {
4849 MockHttpCache cache;
4851 MockTransaction transaction(kSimpleGET_Transaction);
4852 transaction.response_headers =
4853 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4854 "Content-Length: 22\n"
4855 "Accept-Ranges: none\n"
4856 "Etag: \"foopy\"\n";
4857 AddMockTransaction(&transaction);
4858 MockHttpRequest request(transaction);
4860 Context* c = new Context();
4861 int rv = cache.CreateTransaction(&c->trans);
4862 ASSERT_EQ(net::OK, rv);
4864 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4865 if (rv == net::ERR_IO_PENDING)
4866 rv = c->callback.WaitForResult();
4868 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4869 EXPECT_EQ(0, cache.disk_cache()->open_count());
4870 EXPECT_EQ(1, cache.disk_cache()->create_count());
4872 // Make sure that the entry has some data stored.
4873 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4874 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4875 if (rv == net::ERR_IO_PENDING)
4876 rv = c->callback.WaitForResult();
4877 EXPECT_EQ(buf->size(), rv);
4879 // Destroy the transaction.
4880 delete c;
4882 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4884 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4885 EXPECT_EQ(0, cache.disk_cache()->open_count());
4886 EXPECT_EQ(2, cache.disk_cache()->create_count());
4888 RemoveMockTransaction(&transaction);
4891 // Tests that we mark an entry as incomplete when the request is cancelled.
4892 TEST(HttpCache, SetTruncatedFlag) {
4893 MockHttpCache cache;
4895 MockTransaction transaction(kSimpleGET_Transaction);
4896 transaction.response_headers =
4897 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4898 "Content-Length: 22\n"
4899 "Etag: \"foopy\"\n";
4900 AddMockTransaction(&transaction);
4901 MockHttpRequest request(transaction);
4903 scoped_ptr<Context> c(new Context());
4905 int rv = cache.CreateTransaction(&c->trans);
4906 ASSERT_EQ(net::OK, rv);
4908 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4909 if (rv == net::ERR_IO_PENDING)
4910 rv = c->callback.WaitForResult();
4912 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4913 EXPECT_EQ(0, cache.disk_cache()->open_count());
4914 EXPECT_EQ(1, cache.disk_cache()->create_count());
4916 // Make sure that the entry has some data stored.
4917 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4918 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4919 if (rv == net::ERR_IO_PENDING)
4920 rv = c->callback.WaitForResult();
4921 EXPECT_EQ(buf->size(), rv);
4923 // We want to cancel the request when the transaction is busy.
4924 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4925 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4926 EXPECT_FALSE(c->callback.have_result());
4928 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
4930 // Destroy the transaction.
4931 c->trans.reset();
4932 MockHttpCache::SetTestMode(0);
4935 // Make sure that we don't invoke the callback. We may have an issue if the
4936 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4937 // could end up with the transaction being deleted twice if we send any
4938 // notification from the transaction destructor (see http://crbug.com/31723).
4939 EXPECT_FALSE(c->callback.have_result());
4941 // Verify that the entry is marked as incomplete.
4942 disk_cache::Entry* entry;
4943 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4944 net::HttpResponseInfo response;
4945 bool truncated = false;
4946 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4947 EXPECT_TRUE(truncated);
4948 entry->Close();
4950 RemoveMockTransaction(&transaction);
4953 // Tests that we don't mark an entry as truncated when we read everything.
4954 TEST(HttpCache, DontSetTruncatedFlag) {
4955 MockHttpCache cache;
4957 MockTransaction transaction(kSimpleGET_Transaction);
4958 transaction.response_headers =
4959 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4960 "Content-Length: 22\n"
4961 "Etag: \"foopy\"\n";
4962 AddMockTransaction(&transaction);
4963 MockHttpRequest request(transaction);
4965 scoped_ptr<Context> c(new Context());
4966 int rv = cache.CreateTransaction(&c->trans);
4967 ASSERT_EQ(net::OK, rv);
4969 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4970 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4972 // Read everything.
4973 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
4974 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4975 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
4977 // Destroy the transaction.
4978 c->trans.reset();
4980 // Verify that the entry is not marked as truncated.
4981 disk_cache::Entry* entry;
4982 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4983 net::HttpResponseInfo response;
4984 bool truncated = true;
4985 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4986 EXPECT_FALSE(truncated);
4987 entry->Close();
4989 RemoveMockTransaction(&transaction);
4992 // Tests that we can continue with a request that was interrupted.
4993 TEST(HttpCache, GET_IncompleteResource) {
4994 MockHttpCache cache;
4995 AddMockTransaction(&kRangeGET_TransactionOK);
4997 std::string raw_headers("HTTP/1.1 200 OK\n"
4998 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4999 "ETag: \"foo\"\n"
5000 "Accept-Ranges: bytes\n"
5001 "Content-Length: 80\n");
5002 CreateTruncatedEntry(raw_headers, &cache);
5004 // Now make a regular request.
5005 std::string headers;
5006 MockTransaction transaction(kRangeGET_TransactionOK);
5007 transaction.request_headers = EXTRA_HEADER;
5008 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5009 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5010 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5012 // We update the headers with the ones received while revalidating.
5013 std::string expected_headers(
5014 "HTTP/1.1 200 OK\n"
5015 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5016 "Accept-Ranges: bytes\n"
5017 "ETag: \"foo\"\n"
5018 "Content-Length: 80\n");
5020 EXPECT_EQ(expected_headers, headers);
5021 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5022 EXPECT_EQ(1, cache.disk_cache()->open_count());
5023 EXPECT_EQ(1, cache.disk_cache()->create_count());
5025 // Verify that the disk entry was updated.
5026 disk_cache::Entry* entry;
5027 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5028 EXPECT_EQ(80, entry->GetDataSize(1));
5029 bool truncated = true;
5030 net::HttpResponseInfo response;
5031 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5032 EXPECT_FALSE(truncated);
5033 entry->Close();
5035 RemoveMockTransaction(&kRangeGET_TransactionOK);
5038 // Tests the handling of no-store when revalidating a truncated entry.
5039 TEST(HttpCache, GET_IncompleteResource_NoStore) {
5040 MockHttpCache cache;
5041 AddMockTransaction(&kRangeGET_TransactionOK);
5043 std::string raw_headers("HTTP/1.1 200 OK\n"
5044 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5045 "ETag: \"foo\"\n"
5046 "Accept-Ranges: bytes\n"
5047 "Content-Length: 80\n");
5048 CreateTruncatedEntry(raw_headers, &cache);
5049 RemoveMockTransaction(&kRangeGET_TransactionOK);
5051 // Now make a regular request.
5052 MockTransaction transaction(kRangeGET_TransactionOK);
5053 transaction.request_headers = EXTRA_HEADER;
5054 std::string response_headers(transaction.response_headers);
5055 response_headers += ("Cache-Control: no-store\n");
5056 transaction.response_headers = response_headers.c_str();
5057 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5058 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5059 AddMockTransaction(&transaction);
5061 std::string headers;
5062 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5064 // We update the headers with the ones received while revalidating.
5065 std::string expected_headers(
5066 "HTTP/1.1 200 OK\n"
5067 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5068 "Accept-Ranges: bytes\n"
5069 "Cache-Control: no-store\n"
5070 "ETag: \"foo\"\n"
5071 "Content-Length: 80\n");
5073 EXPECT_EQ(expected_headers, headers);
5074 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5075 EXPECT_EQ(1, cache.disk_cache()->open_count());
5076 EXPECT_EQ(1, cache.disk_cache()->create_count());
5078 // Verify that the disk entry was deleted.
5079 disk_cache::Entry* entry;
5080 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5081 RemoveMockTransaction(&transaction);
5084 // Tests cancelling a request after the server sent no-store.
5085 TEST(HttpCache, GET_IncompleteResource_Cancel) {
5086 MockHttpCache cache;
5087 AddMockTransaction(&kRangeGET_TransactionOK);
5089 std::string raw_headers("HTTP/1.1 200 OK\n"
5090 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5091 "ETag: \"foo\"\n"
5092 "Accept-Ranges: bytes\n"
5093 "Content-Length: 80\n");
5094 CreateTruncatedEntry(raw_headers, &cache);
5095 RemoveMockTransaction(&kRangeGET_TransactionOK);
5097 // Now make a regular request.
5098 MockTransaction transaction(kRangeGET_TransactionOK);
5099 transaction.request_headers = EXTRA_HEADER;
5100 std::string response_headers(transaction.response_headers);
5101 response_headers += ("Cache-Control: no-store\n");
5102 transaction.response_headers = response_headers.c_str();
5103 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5104 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5105 AddMockTransaction(&transaction);
5107 MockHttpRequest request(transaction);
5108 Context* c = new Context();
5110 int rv = cache.CreateTransaction(&c->trans);
5111 ASSERT_EQ(net::OK, rv);
5113 // Queue another request to this transaction. We have to start this request
5114 // before the first one gets the response from the server and dooms the entry,
5115 // otherwise it will just create a new entry without being queued to the first
5116 // request.
5117 Context* pending = new Context();
5118 ASSERT_EQ(net::OK, cache.CreateTransaction(&pending->trans));
5120 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5121 EXPECT_EQ(net::ERR_IO_PENDING,
5122 pending->trans->Start(&request, pending->callback.callback(),
5123 net::BoundNetLog()));
5124 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5126 // Make sure that the entry has some data stored.
5127 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
5128 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5129 EXPECT_EQ(5, c->callback.GetResult(rv));
5131 // Cancel the requests.
5132 delete c;
5133 delete pending;
5135 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5136 EXPECT_EQ(1, cache.disk_cache()->open_count());
5137 EXPECT_EQ(2, cache.disk_cache()->create_count());
5139 base::MessageLoop::current()->RunUntilIdle();
5140 RemoveMockTransaction(&transaction);
5143 // Tests that we delete truncated entries if the server changes its mind midway.
5144 TEST(HttpCache, GET_IncompleteResource2) {
5145 MockHttpCache cache;
5146 AddMockTransaction(&kRangeGET_TransactionOK);
5148 // Content-length will be intentionally bad.
5149 std::string raw_headers("HTTP/1.1 200 OK\n"
5150 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5151 "ETag: \"foo\"\n"
5152 "Accept-Ranges: bytes\n"
5153 "Content-Length: 50\n");
5154 CreateTruncatedEntry(raw_headers, &cache);
5156 // Now make a regular request. We expect the code to fail the validation and
5157 // retry the request without using byte ranges.
5158 std::string headers;
5159 MockTransaction transaction(kRangeGET_TransactionOK);
5160 transaction.request_headers = EXTRA_HEADER;
5161 transaction.data = "Not a range";
5162 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5164 // The server will return 200 instead of a byte range.
5165 std::string expected_headers(
5166 "HTTP/1.1 200 OK\n"
5167 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5169 EXPECT_EQ(expected_headers, headers);
5170 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5171 EXPECT_EQ(1, cache.disk_cache()->open_count());
5172 EXPECT_EQ(1, cache.disk_cache()->create_count());
5174 // Verify that the disk entry was deleted.
5175 disk_cache::Entry* entry;
5176 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5177 RemoveMockTransaction(&kRangeGET_TransactionOK);
5180 // Tests that we always validate a truncated request.
5181 TEST(HttpCache, GET_IncompleteResource3) {
5182 MockHttpCache cache;
5183 AddMockTransaction(&kRangeGET_TransactionOK);
5185 // This should not require validation for 10 hours.
5186 std::string raw_headers("HTTP/1.1 200 OK\n"
5187 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5188 "ETag: \"foo\"\n"
5189 "Cache-Control: max-age= 36000\n"
5190 "Accept-Ranges: bytes\n"
5191 "Content-Length: 80\n");
5192 CreateTruncatedEntry(raw_headers, &cache);
5194 // Now make a regular request.
5195 std::string headers;
5196 MockTransaction transaction(kRangeGET_TransactionOK);
5197 transaction.request_headers = EXTRA_HEADER;
5198 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5199 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5201 scoped_ptr<Context> c(new Context);
5202 int rv = cache.CreateTransaction(&c->trans);
5203 ASSERT_EQ(net::OK, rv);
5205 MockHttpRequest request(transaction);
5206 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5207 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5209 // We should have checked with the server before finishing Start().
5210 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5211 EXPECT_EQ(1, cache.disk_cache()->open_count());
5212 EXPECT_EQ(1, cache.disk_cache()->create_count());
5214 RemoveMockTransaction(&kRangeGET_TransactionOK);
5217 // Tests that we handle 401s for truncated resources.
5218 TEST(HttpCache, GET_IncompleteResourceWithAuth) {
5219 MockHttpCache cache;
5220 AddMockTransaction(&kRangeGET_TransactionOK);
5222 std::string raw_headers("HTTP/1.1 200 OK\n"
5223 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5224 "ETag: \"foo\"\n"
5225 "Accept-Ranges: bytes\n"
5226 "Content-Length: 80\n");
5227 CreateTruncatedEntry(raw_headers, &cache);
5229 // Now make a regular request.
5230 MockTransaction transaction(kRangeGET_TransactionOK);
5231 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
5232 EXTRA_HEADER;
5233 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5234 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5235 RangeTransactionServer handler;
5237 scoped_ptr<Context> c(new Context);
5238 int rv = cache.CreateTransaction(&c->trans);
5239 ASSERT_EQ(net::OK, rv);
5241 MockHttpRequest request(transaction);
5242 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5243 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5245 const net::HttpResponseInfo* response = c->trans->GetResponseInfo();
5246 ASSERT_TRUE(response);
5247 ASSERT_EQ(401, response->headers->response_code());
5248 rv = c->trans->RestartWithAuth(net::AuthCredentials(),
5249 c->callback.callback());
5250 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5251 response = c->trans->GetResponseInfo();
5252 ASSERT_TRUE(response);
5253 ASSERT_EQ(200, response->headers->response_code());
5255 ReadAndVerifyTransaction(c->trans.get(), transaction);
5256 c.reset(); // The destructor could delete the entry.
5257 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5259 // Verify that the entry was not deleted.
5260 disk_cache::Entry* entry;
5261 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5262 entry->Close();
5264 RemoveMockTransaction(&kRangeGET_TransactionOK);
5267 // Tests that we cache a 200 response to the validation request.
5268 TEST(HttpCache, GET_IncompleteResource4) {
5269 MockHttpCache cache;
5270 AddMockTransaction(&kRangeGET_TransactionOK);
5272 std::string raw_headers("HTTP/1.1 200 OK\n"
5273 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5274 "ETag: \"foo\"\n"
5275 "Accept-Ranges: bytes\n"
5276 "Content-Length: 80\n");
5277 CreateTruncatedEntry(raw_headers, &cache);
5279 // Now make a regular request.
5280 std::string headers;
5281 MockTransaction transaction(kRangeGET_TransactionOK);
5282 transaction.request_headers = EXTRA_HEADER;
5283 transaction.data = "Not a range";
5284 RangeTransactionServer handler;
5285 handler.set_bad_200(true);
5286 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5288 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5289 EXPECT_EQ(1, cache.disk_cache()->open_count());
5290 EXPECT_EQ(1, cache.disk_cache()->create_count());
5292 // Verify that the disk entry was updated.
5293 disk_cache::Entry* entry;
5294 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5295 EXPECT_EQ(11, entry->GetDataSize(1));
5296 bool truncated = true;
5297 net::HttpResponseInfo response;
5298 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5299 EXPECT_FALSE(truncated);
5300 entry->Close();
5302 RemoveMockTransaction(&kRangeGET_TransactionOK);
5305 // Tests that when we cancel a request that was interrupted, we mark it again
5306 // as truncated.
5307 TEST(HttpCache, GET_CancelIncompleteResource) {
5308 MockHttpCache cache;
5309 AddMockTransaction(&kRangeGET_TransactionOK);
5311 std::string raw_headers("HTTP/1.1 200 OK\n"
5312 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5313 "ETag: \"foo\"\n"
5314 "Accept-Ranges: bytes\n"
5315 "Content-Length: 80\n");
5316 CreateTruncatedEntry(raw_headers, &cache);
5318 // Now make a regular request.
5319 MockTransaction transaction(kRangeGET_TransactionOK);
5320 transaction.request_headers = EXTRA_HEADER;
5322 MockHttpRequest request(transaction);
5323 Context* c = new Context();
5324 int rv = cache.CreateTransaction(&c->trans);
5325 ASSERT_EQ(net::OK, rv);
5327 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5328 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5330 // Read 20 bytes from the cache, and 10 from the net.
5331 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5332 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5333 EXPECT_EQ(20, c->callback.GetResult(rv));
5334 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5335 EXPECT_EQ(10, c->callback.GetResult(rv));
5337 // At this point, we are already reading so canceling the request should leave
5338 // a truncated one.
5339 delete c;
5341 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5342 EXPECT_EQ(1, cache.disk_cache()->open_count());
5343 EXPECT_EQ(1, cache.disk_cache()->create_count());
5345 // Verify that the disk entry was updated: now we have 30 bytes.
5346 disk_cache::Entry* entry;
5347 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5348 EXPECT_EQ(30, entry->GetDataSize(1));
5349 bool truncated = false;
5350 net::HttpResponseInfo response;
5351 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5352 EXPECT_TRUE(truncated);
5353 entry->Close();
5354 RemoveMockTransaction(&kRangeGET_TransactionOK);
5357 // Tests that we can handle range requests when we have a truncated entry.
5358 TEST(HttpCache, RangeGET_IncompleteResource) {
5359 MockHttpCache cache;
5360 AddMockTransaction(&kRangeGET_TransactionOK);
5362 // Content-length will be intentionally bogus.
5363 std::string raw_headers("HTTP/1.1 200 OK\n"
5364 "Last-Modified: something\n"
5365 "ETag: \"foo\"\n"
5366 "Accept-Ranges: bytes\n"
5367 "Content-Length: 10\n");
5368 CreateTruncatedEntry(raw_headers, &cache);
5370 // Now make a range request.
5371 std::string headers;
5372 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5373 &headers);
5375 Verify206Response(headers, 40, 49);
5376 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5377 EXPECT_EQ(1, cache.disk_cache()->open_count());
5378 EXPECT_EQ(2, cache.disk_cache()->create_count());
5380 RemoveMockTransaction(&kRangeGET_TransactionOK);
5383 TEST(HttpCache, SyncRead) {
5384 MockHttpCache cache;
5386 // This test ensures that a read that completes synchronously does not cause
5387 // any problems.
5389 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5390 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5391 TEST_MODE_SYNC_CACHE_READ |
5392 TEST_MODE_SYNC_CACHE_WRITE);
5394 MockHttpRequest r1(transaction),
5395 r2(transaction),
5396 r3(transaction);
5398 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5399 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5400 c3(net::DEFAULT_PRIORITY, cache.http_cache());
5402 c1.Start(&r1, net::BoundNetLog());
5404 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5405 c2.Start(&r2, net::BoundNetLog());
5407 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5408 c3.Start(&r3, net::BoundNetLog());
5410 base::MessageLoop::current()->Run();
5412 EXPECT_TRUE(c1.is_done());
5413 EXPECT_TRUE(c2.is_done());
5414 EXPECT_TRUE(c3.is_done());
5416 EXPECT_EQ(net::OK, c1.error());
5417 EXPECT_EQ(net::OK, c2.error());
5418 EXPECT_EQ(net::OK, c3.error());
5421 TEST(HttpCache, ValidationResultsIn200) {
5422 MockHttpCache cache;
5424 // This test ensures that a conditional request, which results in a 200
5425 // instead of a 304, properly truncates the existing response data.
5427 // write to the cache
5428 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5430 // force this transaction to validate the cache
5431 MockTransaction transaction(kETagGET_Transaction);
5432 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5433 RunTransactionTest(cache.http_cache(), transaction);
5435 // read from the cache
5436 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5439 TEST(HttpCache, CachedRedirect) {
5440 MockHttpCache cache;
5442 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5443 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5444 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5446 MockHttpRequest request(kTestTransaction);
5447 net::TestCompletionCallback callback;
5449 // Write to the cache.
5451 scoped_ptr<net::HttpTransaction> trans;
5452 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5454 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5455 if (rv == net::ERR_IO_PENDING)
5456 rv = callback.WaitForResult();
5457 ASSERT_EQ(net::OK, rv);
5459 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5460 ASSERT_TRUE(info);
5462 EXPECT_EQ(info->headers->response_code(), 301);
5464 std::string location;
5465 info->headers->EnumerateHeader(NULL, "Location", &location);
5466 EXPECT_EQ(location, "http://www.bar.com/");
5468 // Mark the transaction as completed so it is cached.
5469 trans->DoneReading();
5471 // Destroy transaction when going out of scope. We have not actually
5472 // read the response body -- want to test that it is still getting cached.
5474 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5475 EXPECT_EQ(0, cache.disk_cache()->open_count());
5476 EXPECT_EQ(1, cache.disk_cache()->create_count());
5478 // Active entries in the cache are not retired synchronously. Make
5479 // sure the next run hits the MockHttpCache and open_count is
5480 // correct.
5481 base::MessageLoop::current()->RunUntilIdle();
5483 // Read from the cache.
5485 scoped_ptr<net::HttpTransaction> trans;
5486 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5488 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5489 if (rv == net::ERR_IO_PENDING)
5490 rv = callback.WaitForResult();
5491 ASSERT_EQ(net::OK, rv);
5493 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5494 ASSERT_TRUE(info);
5496 EXPECT_EQ(info->headers->response_code(), 301);
5498 std::string location;
5499 info->headers->EnumerateHeader(NULL, "Location", &location);
5500 EXPECT_EQ(location, "http://www.bar.com/");
5502 // Mark the transaction as completed so it is cached.
5503 trans->DoneReading();
5505 // Destroy transaction when going out of scope. We have not actually
5506 // read the response body -- want to test that it is still getting cached.
5508 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5509 EXPECT_EQ(1, cache.disk_cache()->open_count());
5510 EXPECT_EQ(1, cache.disk_cache()->create_count());
5513 // Verify that no-cache resources are stored in cache, but are not fetched from
5514 // cache during normal loads.
5515 TEST(HttpCache, CacheControlNoCacheNormalLoad) {
5516 MockHttpCache cache;
5518 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5519 transaction.response_headers = "cache-control: no-cache\n";
5521 // Initial load.
5522 RunTransactionTest(cache.http_cache(), transaction);
5524 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5525 EXPECT_EQ(0, cache.disk_cache()->open_count());
5526 EXPECT_EQ(1, cache.disk_cache()->create_count());
5528 // Try loading again; it should result in a network fetch.
5529 RunTransactionTest(cache.http_cache(), transaction);
5531 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5532 EXPECT_EQ(1, cache.disk_cache()->open_count());
5533 EXPECT_EQ(1, cache.disk_cache()->create_count());
5535 disk_cache::Entry* entry;
5536 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5537 entry->Close();
5540 // Verify that no-cache resources are stored in cache and fetched from cache
5541 // when the LOAD_PREFERRING_CACHE flag is set.
5542 TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
5543 MockHttpCache cache;
5545 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5546 transaction.response_headers = "cache-control: no-cache\n";
5548 // Initial load.
5549 RunTransactionTest(cache.http_cache(), transaction);
5551 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5552 EXPECT_EQ(0, cache.disk_cache()->open_count());
5553 EXPECT_EQ(1, cache.disk_cache()->create_count());
5555 // Try loading again with LOAD_PREFERRING_CACHE.
5556 transaction.load_flags = net::LOAD_PREFERRING_CACHE;
5557 RunTransactionTest(cache.http_cache(), transaction);
5559 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5560 EXPECT_EQ(1, cache.disk_cache()->open_count());
5561 EXPECT_EQ(1, cache.disk_cache()->create_count());
5563 disk_cache::Entry* entry;
5564 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5565 entry->Close();
5568 TEST(HttpCache, CacheControlNoStore) {
5569 MockHttpCache cache;
5571 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5572 transaction.response_headers = "cache-control: no-store\n";
5574 // initial load
5575 RunTransactionTest(cache.http_cache(), transaction);
5577 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5578 EXPECT_EQ(0, cache.disk_cache()->open_count());
5579 EXPECT_EQ(1, cache.disk_cache()->create_count());
5581 // try loading again; it should result in a network fetch
5582 RunTransactionTest(cache.http_cache(), transaction);
5584 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5585 EXPECT_EQ(0, cache.disk_cache()->open_count());
5586 EXPECT_EQ(2, cache.disk_cache()->create_count());
5588 disk_cache::Entry* entry;
5589 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5592 TEST(HttpCache, CacheControlNoStore2) {
5593 // this test is similar to the above test, except that the initial response
5594 // is cachable, but when it is validated, no-store is received causing the
5595 // cached document to be deleted.
5596 MockHttpCache cache;
5598 ScopedMockTransaction transaction(kETagGET_Transaction);
5600 // initial load
5601 RunTransactionTest(cache.http_cache(), transaction);
5603 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5604 EXPECT_EQ(0, cache.disk_cache()->open_count());
5605 EXPECT_EQ(1, cache.disk_cache()->create_count());
5607 // try loading again; it should result in a network fetch
5608 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5609 transaction.response_headers = "cache-control: no-store\n";
5610 RunTransactionTest(cache.http_cache(), transaction);
5612 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5613 EXPECT_EQ(1, cache.disk_cache()->open_count());
5614 EXPECT_EQ(1, cache.disk_cache()->create_count());
5616 disk_cache::Entry* entry;
5617 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5620 TEST(HttpCache, CacheControlNoStore3) {
5621 // this test is similar to the above test, except that the response is a 304
5622 // instead of a 200. this should never happen in practice, but it seems like
5623 // a good thing to verify that we still destroy the cache entry.
5624 MockHttpCache cache;
5626 ScopedMockTransaction transaction(kETagGET_Transaction);
5628 // initial load
5629 RunTransactionTest(cache.http_cache(), transaction);
5631 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5632 EXPECT_EQ(0, cache.disk_cache()->open_count());
5633 EXPECT_EQ(1, cache.disk_cache()->create_count());
5635 // try loading again; it should result in a network fetch
5636 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5637 transaction.response_headers = "cache-control: no-store\n";
5638 transaction.status = "HTTP/1.1 304 Not Modified";
5639 RunTransactionTest(cache.http_cache(), transaction);
5641 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5642 EXPECT_EQ(1, cache.disk_cache()->open_count());
5643 EXPECT_EQ(1, cache.disk_cache()->create_count());
5645 disk_cache::Entry* entry;
5646 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5649 // Ensure that we don't cache requests served over bad HTTPS.
5650 TEST(HttpCache, SimpleGET_SSLError) {
5651 MockHttpCache cache;
5653 MockTransaction transaction = kSimpleGET_Transaction;
5654 transaction.cert_status = net::CERT_STATUS_REVOKED;
5655 ScopedMockTransaction scoped_transaction(transaction);
5657 // write to the cache
5658 RunTransactionTest(cache.http_cache(), transaction);
5660 // Test that it was not cached.
5661 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5663 MockHttpRequest request(transaction);
5664 net::TestCompletionCallback callback;
5666 scoped_ptr<net::HttpTransaction> trans;
5667 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5669 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5670 if (rv == net::ERR_IO_PENDING)
5671 rv = callback.WaitForResult();
5672 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5675 // Ensure that we don't crash by if left-behind transactions.
5676 TEST(HttpCache, OutlivedTransactions) {
5677 MockHttpCache* cache = new MockHttpCache;
5679 scoped_ptr<net::HttpTransaction> trans;
5680 EXPECT_EQ(net::OK, cache->CreateTransaction(&trans));
5682 delete cache;
5683 trans.reset();
5686 // Test that the disabled mode works.
5687 TEST(HttpCache, CacheDisabledMode) {
5688 MockHttpCache cache;
5690 // write to the cache
5691 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5693 // go into disabled mode
5694 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
5696 // force this transaction to write to the cache again
5697 MockTransaction transaction(kSimpleGET_Transaction);
5699 RunTransactionTest(cache.http_cache(), transaction);
5701 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5702 EXPECT_EQ(0, cache.disk_cache()->open_count());
5703 EXPECT_EQ(1, cache.disk_cache()->create_count());
5706 // Other tests check that the response headers of the cached response
5707 // get updated on 304. Here we specifically check that the
5708 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5709 // fields also gets updated.
5710 // http://crbug.com/20594.
5711 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
5712 MockHttpCache cache;
5714 const char* kUrl = "http://foobar";
5715 const char* kData = "body";
5717 MockTransaction mock_network_response = { 0 };
5718 mock_network_response.url = kUrl;
5720 AddMockTransaction(&mock_network_response);
5722 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
5724 MockTransaction request = { 0 };
5725 request.url = kUrl;
5726 request.method = "GET";
5727 request.request_headers = "\r\n";
5728 request.data = kData;
5730 static const Response kNetResponse1 = {
5731 "HTTP/1.1 200 OK",
5732 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
5733 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5734 kData
5737 kNetResponse1.AssignTo(&mock_network_response);
5739 RunTransactionTest(cache.http_cache(), request);
5741 // Request |kUrl| again, this time validating the cache and getting
5742 // a 304 back.
5744 request.load_flags = net::LOAD_VALIDATE_CACHE;
5746 static const Response kNetResponse2 = {
5747 "HTTP/1.1 304 Not Modified",
5748 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
5752 kNetResponse2.AssignTo(&mock_network_response);
5754 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
5755 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
5757 mock_network_response.request_time = request_time;
5758 mock_network_response.response_time = response_time;
5760 net::HttpResponseInfo response;
5761 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
5763 // The request and response times should have been updated.
5764 EXPECT_EQ(request_time.ToInternalValue(),
5765 response.request_time.ToInternalValue());
5766 EXPECT_EQ(response_time.ToInternalValue(),
5767 response.response_time.ToInternalValue());
5769 std::string headers;
5770 response.headers->GetNormalizedHeaders(&headers);
5772 EXPECT_EQ("HTTP/1.1 200 OK\n"
5773 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
5774 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5775 headers);
5777 RemoveMockTransaction(&mock_network_response);
5780 // Tests that we can write metadata to an entry.
5781 TEST(HttpCache, WriteMetadata_OK) {
5782 MockHttpCache cache;
5784 // Write to the cache
5785 net::HttpResponseInfo response;
5786 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5787 &response);
5788 EXPECT_TRUE(response.metadata.get() == NULL);
5790 // Trivial call.
5791 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
5792 Time::Now(), NULL, 0);
5794 // Write meta data to the same entry.
5795 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5796 memset(buf->data(), 0, buf->size());
5797 base::strlcpy(buf->data(), "Hi there", buf->size());
5798 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
5799 net::DEFAULT_PRIORITY,
5800 response.response_time,
5801 buf.get(),
5802 buf->size());
5804 // Release the buffer before the operation takes place.
5805 buf = NULL;
5807 // Makes sure we finish pending operations.
5808 base::MessageLoop::current()->RunUntilIdle();
5810 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5811 &response);
5812 ASSERT_TRUE(response.metadata.get() != NULL);
5813 EXPECT_EQ(50, response.metadata->size());
5814 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5816 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5817 EXPECT_EQ(2, cache.disk_cache()->open_count());
5818 EXPECT_EQ(1, cache.disk_cache()->create_count());
5821 // Tests that we only write metadata to an entry if the time stamp matches.
5822 TEST(HttpCache, WriteMetadata_Fail) {
5823 MockHttpCache cache;
5825 // Write to the cache
5826 net::HttpResponseInfo response;
5827 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5828 &response);
5829 EXPECT_TRUE(response.metadata.get() == NULL);
5831 // Attempt to write meta data to the same entry.
5832 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5833 memset(buf->data(), 0, buf->size());
5834 base::strlcpy(buf->data(), "Hi there", buf->size());
5835 base::Time expected_time = response.response_time -
5836 base::TimeDelta::FromMilliseconds(20);
5837 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
5838 net::DEFAULT_PRIORITY,
5839 expected_time,
5840 buf.get(),
5841 buf->size());
5843 // Makes sure we finish pending operations.
5844 base::MessageLoop::current()->RunUntilIdle();
5846 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5847 &response);
5848 EXPECT_TRUE(response.metadata.get() == NULL);
5850 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5851 EXPECT_EQ(2, cache.disk_cache()->open_count());
5852 EXPECT_EQ(1, cache.disk_cache()->create_count());
5855 // Tests that we can read metadata after validating the entry and with READ mode
5856 // transactions.
5857 TEST(HttpCache, ReadMetadata) {
5858 MockHttpCache cache;
5860 // Write to the cache
5861 net::HttpResponseInfo response;
5862 RunTransactionTestWithResponseInfo(cache.http_cache(),
5863 kTypicalGET_Transaction, &response);
5864 EXPECT_TRUE(response.metadata.get() == NULL);
5866 // Write meta data to the same entry.
5867 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5868 memset(buf->data(), 0, buf->size());
5869 base::strlcpy(buf->data(), "Hi there", buf->size());
5870 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
5871 net::DEFAULT_PRIORITY,
5872 response.response_time,
5873 buf.get(),
5874 buf->size());
5876 // Makes sure we finish pending operations.
5877 base::MessageLoop::current()->RunUntilIdle();
5879 // Start with a READ mode transaction.
5880 MockTransaction trans1(kTypicalGET_Transaction);
5881 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
5883 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5884 ASSERT_TRUE(response.metadata.get() != NULL);
5885 EXPECT_EQ(50, response.metadata->size());
5886 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5888 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5889 EXPECT_EQ(2, cache.disk_cache()->open_count());
5890 EXPECT_EQ(1, cache.disk_cache()->create_count());
5891 base::MessageLoop::current()->RunUntilIdle();
5893 // Now make sure that the entry is re-validated with the server.
5894 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
5895 trans1.status = "HTTP/1.1 304 Not Modified";
5896 AddMockTransaction(&trans1);
5898 response.metadata = NULL;
5899 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5900 EXPECT_TRUE(response.metadata.get() != NULL);
5902 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5903 EXPECT_EQ(3, cache.disk_cache()->open_count());
5904 EXPECT_EQ(1, cache.disk_cache()->create_count());
5905 base::MessageLoop::current()->RunUntilIdle();
5906 RemoveMockTransaction(&trans1);
5908 // Now return 200 when validating the entry so the metadata will be lost.
5909 MockTransaction trans2(kTypicalGET_Transaction);
5910 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5911 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5912 EXPECT_TRUE(response.metadata.get() == NULL);
5914 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5915 EXPECT_EQ(4, cache.disk_cache()->open_count());
5916 EXPECT_EQ(1, cache.disk_cache()->create_count());
5919 // Tests that we don't mark entries as truncated when a filter detects the end
5920 // of the stream.
5921 TEST(HttpCache, FilterCompletion) {
5922 MockHttpCache cache;
5923 net::TestCompletionCallback callback;
5926 scoped_ptr<net::HttpTransaction> trans;
5927 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5929 MockHttpRequest request(kSimpleGET_Transaction);
5930 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5931 EXPECT_EQ(net::OK, callback.GetResult(rv));
5933 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5934 rv = trans->Read(buf.get(), 256, callback.callback());
5935 EXPECT_GT(callback.GetResult(rv), 0);
5937 // Now make sure that the entry is preserved.
5938 trans->DoneReading();
5941 // Make sure that the ActiveEntry is gone.
5942 base::MessageLoop::current()->RunUntilIdle();
5944 // Read from the cache.
5945 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5947 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5948 EXPECT_EQ(1, cache.disk_cache()->open_count());
5949 EXPECT_EQ(1, cache.disk_cache()->create_count());
5952 // Tests that we don't mark entries as truncated and release the cache
5953 // entry when DoneReading() is called before any Read() calls, such as
5954 // for a redirect.
5955 TEST(HttpCache, DoneReading) {
5956 MockHttpCache cache;
5957 net::TestCompletionCallback callback;
5959 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5960 transaction.data = "";
5962 scoped_ptr<net::HttpTransaction> trans;
5963 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5965 MockHttpRequest request(transaction);
5966 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5967 EXPECT_EQ(net::OK, callback.GetResult(rv));
5969 trans->DoneReading();
5970 // Leave the transaction around.
5972 // Make sure that the ActiveEntry is gone.
5973 base::MessageLoop::current()->RunUntilIdle();
5975 // Read from the cache. This should not deadlock.
5976 RunTransactionTest(cache.http_cache(), transaction);
5978 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5979 EXPECT_EQ(1, cache.disk_cache()->open_count());
5980 EXPECT_EQ(1, cache.disk_cache()->create_count());
5983 // Tests that we stop caching when told.
5984 TEST(HttpCache, StopCachingDeletesEntry) {
5985 MockHttpCache cache;
5986 net::TestCompletionCallback callback;
5987 MockHttpRequest request(kSimpleGET_Transaction);
5990 scoped_ptr<net::HttpTransaction> trans;
5991 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5993 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5994 EXPECT_EQ(net::OK, callback.GetResult(rv));
5996 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5997 rv = trans->Read(buf.get(), 10, callback.callback());
5998 EXPECT_EQ(10, callback.GetResult(rv));
6000 trans->StopCaching();
6002 // We should be able to keep reading.
6003 rv = trans->Read(buf.get(), 256, callback.callback());
6004 EXPECT_GT(callback.GetResult(rv), 0);
6005 rv = trans->Read(buf.get(), 256, callback.callback());
6006 EXPECT_EQ(0, callback.GetResult(rv));
6009 // Make sure that the ActiveEntry is gone.
6010 base::MessageLoop::current()->RunUntilIdle();
6012 // Verify that the entry is gone.
6013 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6015 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6016 EXPECT_EQ(0, cache.disk_cache()->open_count());
6017 EXPECT_EQ(2, cache.disk_cache()->create_count());
6020 // Tests that we stop caching when told, even if DoneReading is called
6021 // after StopCaching.
6022 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6023 MockHttpCache cache;
6024 net::TestCompletionCallback callback;
6025 MockHttpRequest request(kSimpleGET_Transaction);
6028 scoped_ptr<net::HttpTransaction> trans;
6029 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6031 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6032 EXPECT_EQ(net::OK, callback.GetResult(rv));
6034 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6035 rv = trans->Read(buf.get(), 10, callback.callback());
6036 EXPECT_EQ(10, callback.GetResult(rv));
6038 trans->StopCaching();
6040 // We should be able to keep reading.
6041 rv = trans->Read(buf.get(), 256, callback.callback());
6042 EXPECT_GT(callback.GetResult(rv), 0);
6043 rv = trans->Read(buf.get(), 256, callback.callback());
6044 EXPECT_EQ(0, callback.GetResult(rv));
6046 // We should be able to call DoneReading.
6047 trans->DoneReading();
6050 // Make sure that the ActiveEntry is gone.
6051 base::MessageLoop::current()->RunUntilIdle();
6053 // Verify that the entry is gone.
6054 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6056 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6057 EXPECT_EQ(0, cache.disk_cache()->open_count());
6058 EXPECT_EQ(2, cache.disk_cache()->create_count());
6061 // Tests that we stop caching when told, when using auth.
6062 TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6063 MockHttpCache cache;
6064 net::TestCompletionCallback callback;
6065 MockTransaction mock_transaction(kSimpleGET_Transaction);
6066 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6067 AddMockTransaction(&mock_transaction);
6068 MockHttpRequest request(mock_transaction);
6071 scoped_ptr<net::HttpTransaction> trans;
6072 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6074 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6075 EXPECT_EQ(net::OK, callback.GetResult(rv));
6077 trans->StopCaching();
6079 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6080 rv = trans->Read(buf.get(), 10, callback.callback());
6081 EXPECT_EQ(callback.GetResult(rv), 10);
6083 RemoveMockTransaction(&mock_transaction);
6085 // Make sure that the ActiveEntry is gone.
6086 base::MessageLoop::current()->RunUntilIdle();
6088 // Verify that the entry is gone.
6089 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6091 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6092 EXPECT_EQ(0, cache.disk_cache()->open_count());
6093 EXPECT_EQ(2, cache.disk_cache()->create_count());
6096 // Tests that when we are told to stop caching we don't throw away valid data.
6097 TEST(HttpCache, StopCachingSavesEntry) {
6098 MockHttpCache cache;
6099 net::TestCompletionCallback callback;
6100 MockHttpRequest request(kSimpleGET_Transaction);
6103 scoped_ptr<net::HttpTransaction> trans;
6104 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6106 // Force a response that can be resumed.
6107 MockTransaction mock_transaction(kSimpleGET_Transaction);
6108 AddMockTransaction(&mock_transaction);
6109 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6110 "Content-Length: 42\n"
6111 "Etag: \"foo\"\n";
6113 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6114 EXPECT_EQ(net::OK, callback.GetResult(rv));
6116 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6117 rv = trans->Read(buf.get(), 10, callback.callback());
6118 EXPECT_EQ(callback.GetResult(rv), 10);
6120 trans->StopCaching();
6122 // We should be able to keep reading.
6123 rv = trans->Read(buf.get(), 256, callback.callback());
6124 EXPECT_GT(callback.GetResult(rv), 0);
6125 rv = trans->Read(buf.get(), 256, callback.callback());
6126 EXPECT_EQ(callback.GetResult(rv), 0);
6128 RemoveMockTransaction(&mock_transaction);
6131 // Verify that the entry is marked as incomplete.
6132 disk_cache::Entry* entry;
6133 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6134 net::HttpResponseInfo response;
6135 bool truncated = false;
6136 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6137 EXPECT_TRUE(truncated);
6138 entry->Close();
6141 // Tests that we handle truncated enries when StopCaching is called.
6142 TEST(HttpCache, StopCachingTruncatedEntry) {
6143 MockHttpCache cache;
6144 net::TestCompletionCallback callback;
6145 MockHttpRequest request(kRangeGET_TransactionOK);
6146 request.extra_headers.Clear();
6147 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6148 AddMockTransaction(&kRangeGET_TransactionOK);
6150 std::string raw_headers("HTTP/1.1 200 OK\n"
6151 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6152 "ETag: \"foo\"\n"
6153 "Accept-Ranges: bytes\n"
6154 "Content-Length: 80\n");
6155 CreateTruncatedEntry(raw_headers, &cache);
6158 // Now make a regular request.
6159 scoped_ptr<net::HttpTransaction> trans;
6160 ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6162 int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6163 EXPECT_EQ(net::OK, callback.GetResult(rv));
6165 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6166 rv = trans->Read(buf.get(), 10, callback.callback());
6167 EXPECT_EQ(callback.GetResult(rv), 10);
6169 // This is actually going to do nothing.
6170 trans->StopCaching();
6172 // We should be able to keep reading.
6173 rv = trans->Read(buf.get(), 256, callback.callback());
6174 EXPECT_GT(callback.GetResult(rv), 0);
6175 rv = trans->Read(buf.get(), 256, callback.callback());
6176 EXPECT_GT(callback.GetResult(rv), 0);
6177 rv = trans->Read(buf.get(), 256, callback.callback());
6178 EXPECT_EQ(callback.GetResult(rv), 0);
6181 // Verify that the disk entry was updated.
6182 disk_cache::Entry* entry;
6183 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6184 EXPECT_EQ(80, entry->GetDataSize(1));
6185 bool truncated = true;
6186 net::HttpResponseInfo response;
6187 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6188 EXPECT_FALSE(truncated);
6189 entry->Close();
6191 RemoveMockTransaction(&kRangeGET_TransactionOK);
6194 // Tests that we detect truncated resources from the net when there is
6195 // a Content-Length header.
6196 TEST(HttpCache, TruncatedByContentLength) {
6197 MockHttpCache cache;
6198 net::TestCompletionCallback callback;
6200 MockTransaction transaction(kSimpleGET_Transaction);
6201 AddMockTransaction(&transaction);
6202 transaction.response_headers = "Cache-Control: max-age=10000\n"
6203 "Content-Length: 100\n";
6204 RunTransactionTest(cache.http_cache(), transaction);
6205 RemoveMockTransaction(&transaction);
6207 // Read from the cache.
6208 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6210 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6211 EXPECT_EQ(0, cache.disk_cache()->open_count());
6212 EXPECT_EQ(2, cache.disk_cache()->create_count());
6215 // Tests that we actually flag entries as truncated when we detect an error
6216 // from the net.
6217 TEST(HttpCache, TruncatedByContentLength2) {
6218 MockHttpCache cache;
6219 net::TestCompletionCallback callback;
6221 MockTransaction transaction(kSimpleGET_Transaction);
6222 AddMockTransaction(&transaction);
6223 transaction.response_headers = "Cache-Control: max-age=10000\n"
6224 "Content-Length: 100\n"
6225 "Etag: \"foo\"\n";
6226 RunTransactionTest(cache.http_cache(), transaction);
6227 RemoveMockTransaction(&transaction);
6229 // Verify that the entry is marked as incomplete.
6230 disk_cache::Entry* entry;
6231 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6232 net::HttpResponseInfo response;
6233 bool truncated = false;
6234 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6235 EXPECT_TRUE(truncated);
6236 entry->Close();
6239 // Make sure that calling SetPriority on a cache transaction passes on
6240 // its priority updates to its underlying network transaction.
6241 TEST(HttpCache, SetPriority) {
6242 MockHttpCache cache;
6244 scoped_ptr<net::HttpTransaction> trans;
6245 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6247 // Shouldn't crash, but doesn't do anything either.
6248 trans->SetPriority(net::LOW);
6250 EXPECT_FALSE(cache.network_layer()->last_transaction());
6251 EXPECT_EQ(net::DEFAULT_PRIORITY,
6252 cache.network_layer()->last_create_transaction_priority());
6254 net::HttpRequestInfo info;
6255 info.url = GURL(kSimpleGET_Transaction.url);
6256 net::TestCompletionCallback callback;
6257 EXPECT_EQ(net::ERR_IO_PENDING,
6258 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6260 EXPECT_TRUE(cache.network_layer()->last_transaction());
6261 if (cache.network_layer()->last_transaction()) {
6262 EXPECT_EQ(net::LOW,
6263 cache.network_layer()->last_create_transaction_priority());
6264 EXPECT_EQ(net::LOW,
6265 cache.network_layer()->last_transaction()->priority());
6268 trans->SetPriority(net::HIGHEST);
6270 if (cache.network_layer()->last_transaction()) {
6271 EXPECT_EQ(net::LOW,
6272 cache.network_layer()->last_create_transaction_priority());
6273 EXPECT_EQ(net::HIGHEST,
6274 cache.network_layer()->last_transaction()->priority());
6277 EXPECT_EQ(net::OK, callback.WaitForResult());
6280 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6281 // transaction passes on its argument to the underlying network transaction.
6282 TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
6283 MockHttpCache cache;
6285 FakeWebSocketHandshakeStreamCreateHelper create_helper;
6286 scoped_ptr<net::HttpTransaction> trans;
6287 ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6289 EXPECT_FALSE(cache.network_layer()->last_transaction());
6291 net::HttpRequestInfo info;
6292 info.url = GURL(kSimpleGET_Transaction.url);
6293 net::TestCompletionCallback callback;
6294 EXPECT_EQ(net::ERR_IO_PENDING,
6295 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6297 ASSERT_TRUE(cache.network_layer()->last_transaction());
6298 EXPECT_FALSE(cache.network_layer()->last_transaction()->
6299 websocket_handshake_stream_create_helper());
6300 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
6301 EXPECT_EQ(&create_helper,
6302 cache.network_layer()->last_transaction()->
6303 websocket_handshake_stream_create_helper());
6304 EXPECT_EQ(net::OK, callback.WaitForResult());
6307 // Make sure that a cache transaction passes on its priority to
6308 // newly-created network transactions.
6309 TEST(HttpCache, SetPriorityNewTransaction) {
6310 MockHttpCache cache;
6311 AddMockTransaction(&kRangeGET_TransactionOK);
6313 std::string raw_headers("HTTP/1.1 200 OK\n"
6314 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6315 "ETag: \"foo\"\n"
6316 "Accept-Ranges: bytes\n"
6317 "Content-Length: 80\n");
6318 CreateTruncatedEntry(raw_headers, &cache);
6320 // Now make a regular request.
6321 std::string headers;
6322 MockTransaction transaction(kRangeGET_TransactionOK);
6323 transaction.request_headers = EXTRA_HEADER;
6324 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6325 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6327 scoped_ptr<net::HttpTransaction> trans;
6328 ASSERT_EQ(net::OK,
6329 cache.http_cache()->CreateTransaction(net::MEDIUM, &trans));
6330 EXPECT_EQ(net::DEFAULT_PRIORITY,
6331 cache.network_layer()->last_create_transaction_priority());
6333 MockHttpRequest info(transaction);
6334 net::TestCompletionCallback callback;
6335 EXPECT_EQ(net::ERR_IO_PENDING,
6336 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6337 EXPECT_EQ(net::OK, callback.WaitForResult());
6339 EXPECT_EQ(net::MEDIUM,
6340 cache.network_layer()->last_create_transaction_priority());
6342 trans->SetPriority(net::HIGHEST);
6343 // Should trigger a new network transaction and pick up the new
6344 // priority.
6345 ReadAndVerifyTransaction(trans.get(), transaction);
6347 EXPECT_EQ(net::HIGHEST,
6348 cache.network_layer()->last_create_transaction_priority());
6350 RemoveMockTransaction(&kRangeGET_TransactionOK);
6353 int64 RunTransactionAndGetReceivedBytes(
6354 MockHttpCache& cache,
6355 const MockTransaction& trans_info) {
6356 int64 received_bytes = -1;
6357 RunTransactionTestBase(cache.http_cache(), trans_info,
6358 MockHttpRequest(trans_info), NULL, net::BoundNetLog(),
6359 NULL, &received_bytes);
6360 return received_bytes;
6363 int64 TransactionSize(const MockTransaction& transaction) {
6364 return strlen(transaction.status) + strlen(transaction.response_headers) +
6365 strlen(transaction.data);
6368 TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
6369 MockHttpCache cache;
6371 MockTransaction transaction(kSimpleGET_Transaction);
6372 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6373 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6375 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6376 EXPECT_EQ(0, received_bytes);
6379 TEST(HttpCache, ReceivedBytesConditionalRequest304) {
6380 MockHttpCache cache;
6382 ScopedMockTransaction transaction(kETagGET_Transaction);
6383 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6384 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6386 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
6387 transaction.handler = ETagGet_ConditionalRequest_Handler;
6388 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6389 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6392 TEST(HttpCache, ReceivedBytesConditionalRequest200) {
6393 MockHttpCache cache;
6395 MockTransaction transaction(kTypicalGET_Transaction);
6396 transaction.request_headers = "Foo: bar\r\n";
6397 transaction.response_headers =
6398 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6399 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6400 "Etag: \"foopy\"\n"
6401 "Cache-Control: max-age=0\n"
6402 "Vary: Foo\n";
6403 AddMockTransaction(&transaction);
6404 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6405 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6407 RevalidationServer server;
6408 transaction.handler = server.Handler;
6409 transaction.request_headers = "Foo: none\r\n";
6410 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6411 EXPECT_EQ(TransactionSize(transaction), received_bytes);
6413 RemoveMockTransaction(&transaction);
6416 TEST(HttpCache, ReceivedBytesRange) {
6417 MockHttpCache cache;
6418 AddMockTransaction(&kRangeGET_TransactionOK);
6419 MockTransaction transaction(kRangeGET_TransactionOK);
6421 // Read bytes 40-49 from the network.
6422 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6423 int64 range_response_size = TransactionSize(transaction);
6424 EXPECT_EQ(range_response_size, received_bytes);
6426 // Read bytes 40-49 from the cache.
6427 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6428 EXPECT_EQ(0, received_bytes);
6429 base::MessageLoop::current()->RunUntilIdle();
6431 // Read bytes 30-39 from the network.
6432 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
6433 transaction.data = "rg: 30-39 ";
6434 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6435 EXPECT_EQ(range_response_size, received_bytes);
6436 base::MessageLoop::current()->RunUntilIdle();
6438 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6439 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
6440 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6441 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6442 EXPECT_EQ(range_response_size * 2, received_bytes);
6444 RemoveMockTransaction(&kRangeGET_TransactionOK);