Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / net / http / http_cache_unittest.cc
blob12a849c027ce663887f893036a4bc519b01f337b
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 <stdint.h>
9 #include <algorithm>
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/test/simple_test_clock.h"
19 #include "net/base/cache_type.h"
20 #include "net/base/elements_upload_data_stream.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/load_flags.h"
23 #include "net/base/load_timing_info.h"
24 #include "net/base/load_timing_info_test_util.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/test_data_directory.h"
27 #include "net/base/upload_bytes_element_reader.h"
28 #include "net/cert/cert_status_flags.h"
29 #include "net/cert/x509_certificate.h"
30 #include "net/disk_cache/disk_cache.h"
31 #include "net/http/http_byte_range.h"
32 #include "net/http/http_cache_transaction.h"
33 #include "net/http/http_request_headers.h"
34 #include "net/http/http_request_info.h"
35 #include "net/http/http_response_headers.h"
36 #include "net/http/http_response_info.h"
37 #include "net/http/http_transaction.h"
38 #include "net/http/http_transaction_test_util.h"
39 #include "net/http/http_util.h"
40 #include "net/http/mock_http_cache.h"
41 #include "net/log/test_net_log.h"
42 #include "net/log/test_net_log_entry.h"
43 #include "net/log/test_net_log_util.h"
44 #include "net/socket/client_socket_handle.h"
45 #include "net/ssl/ssl_cert_request_info.h"
46 #include "net/ssl/ssl_connection_status_flags.h"
47 #include "net/test/cert_test_util.h"
48 #include "net/websockets/websocket_handshake_stream_base.h"
49 #include "testing/gtest/include/gtest/gtest.h"
51 using base::Time;
53 namespace net {
55 namespace {
57 // Tests the load timing values of a request that goes through a
58 // MockNetworkTransaction.
59 void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
60 EXPECT_FALSE(load_timing_info.socket_reused);
61 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
63 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
64 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
66 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
67 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
68 EXPECT_LE(load_timing_info.connect_timing.connect_end,
69 load_timing_info.send_start);
71 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
73 // Set by URLRequest / URLRequestHttpJob, at a higher level.
74 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
75 EXPECT_TRUE(load_timing_info.request_start.is_null());
76 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
79 // Tests the load timing values of a request that receives a cached response.
80 void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
81 EXPECT_FALSE(load_timing_info.socket_reused);
82 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
84 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
85 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
87 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
89 // Only the send start / end times should be sent, and they should have the
90 // same value.
91 EXPECT_FALSE(load_timing_info.send_start.is_null());
92 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
94 // Set by URLRequest / URLRequestHttpJob, at a higher level.
95 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
96 EXPECT_TRUE(load_timing_info.request_start.is_null());
97 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
100 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
101 public:
102 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
103 : cache_(cache),
104 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
105 base::Unretained(this))) {
108 const CompletionCallback& callback() const { return callback_; }
110 private:
111 void OnComplete(int result) {
112 delete cache_;
113 SetResult(result);
116 MockHttpCache* cache_;
117 CompletionCallback callback_;
119 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
122 //-----------------------------------------------------------------------------
123 // helpers
125 void ReadAndVerifyTransaction(HttpTransaction* trans,
126 const MockTransaction& trans_info) {
127 std::string content;
128 int rv = ReadTransaction(trans, &content);
130 EXPECT_EQ(OK, rv);
131 std::string expected(trans_info.data);
132 EXPECT_EQ(expected, content);
135 void RunTransactionTestBase(HttpCache* cache,
136 const MockTransaction& trans_info,
137 const MockHttpRequest& request,
138 HttpResponseInfo* response_info,
139 const BoundNetLog& net_log,
140 LoadTimingInfo* load_timing_info,
141 int64_t* sent_bytes,
142 int64_t* received_bytes) {
143 TestCompletionCallback callback;
145 // write to the cache
147 scoped_ptr<HttpTransaction> trans;
148 int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
149 EXPECT_EQ(OK, rv);
150 ASSERT_TRUE(trans.get());
152 rv = trans->Start(&request, callback.callback(), net_log);
153 if (rv == ERR_IO_PENDING)
154 rv = callback.WaitForResult();
155 ASSERT_EQ(trans_info.return_code, rv);
157 if (OK != rv)
158 return;
160 const HttpResponseInfo* response = trans->GetResponseInfo();
161 ASSERT_TRUE(response);
163 if (response_info)
164 *response_info = *response;
166 if (load_timing_info) {
167 // If a fake network connection is used, need a NetLog to get a fake socket
168 // ID.
169 EXPECT_TRUE(net_log.net_log());
170 *load_timing_info = LoadTimingInfo();
171 trans->GetLoadTimingInfo(load_timing_info);
174 ReadAndVerifyTransaction(trans.get(), trans_info);
176 if (sent_bytes)
177 *sent_bytes = trans->GetTotalSentBytes();
178 if (received_bytes)
179 *received_bytes = trans->GetTotalReceivedBytes();
182 void RunTransactionTestWithRequest(HttpCache* cache,
183 const MockTransaction& trans_info,
184 const MockHttpRequest& request,
185 HttpResponseInfo* response_info) {
186 RunTransactionTestBase(cache, trans_info, request, response_info,
187 BoundNetLog(), nullptr, nullptr, nullptr);
190 void RunTransactionTestAndGetTiming(HttpCache* cache,
191 const MockTransaction& trans_info,
192 const BoundNetLog& log,
193 LoadTimingInfo* load_timing_info) {
194 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
195 nullptr, log, load_timing_info, nullptr, nullptr);
198 void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
199 RunTransactionTestAndGetTiming(cache, trans_info, BoundNetLog(), nullptr);
202 void RunTransactionTestWithLog(HttpCache* cache,
203 const MockTransaction& trans_info,
204 const BoundNetLog& log) {
205 RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
208 void RunTransactionTestWithResponseInfo(HttpCache* cache,
209 const MockTransaction& trans_info,
210 HttpResponseInfo* response) {
211 RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
212 response);
215 void RunTransactionTestWithResponseInfoAndGetTiming(
216 HttpCache* cache,
217 const MockTransaction& trans_info,
218 HttpResponseInfo* response,
219 const BoundNetLog& log,
220 LoadTimingInfo* load_timing_info) {
221 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
222 response, log, load_timing_info, nullptr, nullptr);
225 void RunTransactionTestWithResponse(HttpCache* cache,
226 const MockTransaction& trans_info,
227 std::string* response_headers) {
228 HttpResponseInfo response;
229 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
230 response.headers->GetNormalizedHeaders(response_headers);
233 void RunTransactionTestWithResponseAndGetTiming(
234 HttpCache* cache,
235 const MockTransaction& trans_info,
236 std::string* response_headers,
237 const BoundNetLog& log,
238 LoadTimingInfo* load_timing_info) {
239 HttpResponseInfo response;
240 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
241 &response, log, load_timing_info, nullptr, nullptr);
242 response.headers->GetNormalizedHeaders(response_headers);
245 // This class provides a handler for kFastNoStoreGET_Transaction so that the
246 // no-store header can be included on demand.
247 class FastTransactionServer {
248 public:
249 FastTransactionServer() {
250 no_store = false;
252 ~FastTransactionServer() {}
254 void set_no_store(bool value) { no_store = value; }
256 static void FastNoStoreHandler(const HttpRequestInfo* request,
257 std::string* response_status,
258 std::string* response_headers,
259 std::string* response_data) {
260 if (no_store)
261 *response_headers = "Cache-Control: no-store\n";
264 private:
265 static bool no_store;
266 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
268 bool FastTransactionServer::no_store;
270 const MockTransaction kFastNoStoreGET_Transaction = {
271 "http://www.google.com/nostore",
272 "GET",
273 base::Time(),
275 LOAD_VALIDATE_CACHE,
276 "HTTP/1.1 200 OK",
277 "Cache-Control: max-age=10000\n",
278 base::Time(),
279 "<html><body>Google Blah Blah</body></html>",
280 TEST_MODE_SYNC_NET_START,
281 &FastTransactionServer::FastNoStoreHandler,
282 nullptr,
285 OK};
287 // This class provides a handler for kRangeGET_TransactionOK so that the range
288 // request can be served on demand.
289 class RangeTransactionServer {
290 public:
291 RangeTransactionServer() {
292 not_modified_ = false;
293 modified_ = false;
294 bad_200_ = false;
296 ~RangeTransactionServer() {
297 not_modified_ = false;
298 modified_ = false;
299 bad_200_ = false;
302 // Returns only 416 or 304 when set.
303 void set_not_modified(bool value) { not_modified_ = value; }
305 // Returns 206 when revalidating a range (instead of 304).
306 void set_modified(bool value) { modified_ = value; }
308 // Returns 200 instead of 206 (a malformed response overall).
309 void set_bad_200(bool value) { bad_200_ = value; }
311 // Other than regular range related behavior (and the flags mentioned above),
312 // the server reacts to requests headers like so:
313 // X-Require-Mock-Auth -> return 401.
314 // X-Require-Mock-Auth-Alt -> return 401.
315 // X-Return-Default-Range -> assume 40-49 was requested.
316 // The -Alt variant doesn't cause the MockNetworkTransaction to
317 // report that it IsReadyToRestartForAuth().
318 static void RangeHandler(const HttpRequestInfo* request,
319 std::string* response_status,
320 std::string* response_headers,
321 std::string* response_data);
323 private:
324 static bool not_modified_;
325 static bool modified_;
326 static bool bad_200_;
327 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
329 bool RangeTransactionServer::not_modified_ = false;
330 bool RangeTransactionServer::modified_ = false;
331 bool RangeTransactionServer::bad_200_ = false;
333 // A dummy extra header that must be preserved on a given request.
335 // EXTRA_HEADER_LINE doesn't include a line terminator because it
336 // will be passed to AddHeaderFromString() which doesn't accept them.
337 #define EXTRA_HEADER_LINE "Extra: header"
339 // EXTRA_HEADER contains a line terminator, as expected by
340 // AddHeadersFromString() (_not_ AddHeaderFromString()).
341 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
343 static const char kExtraHeaderKey[] = "Extra";
345 // Static.
346 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
347 std::string* response_status,
348 std::string* response_headers,
349 std::string* response_data) {
350 if (request->extra_headers.IsEmpty()) {
351 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
352 response_data->clear();
353 return;
356 // We want to make sure we don't delete extra headers.
357 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
359 bool require_auth =
360 request->extra_headers.HasHeader("X-Require-Mock-Auth") ||
361 request->extra_headers.HasHeader("X-Require-Mock-Auth-Alt");
363 if (require_auth && !request->extra_headers.HasHeader("Authorization")) {
364 response_status->assign("HTTP/1.1 401 Unauthorized");
365 response_data->assign("WWW-Authenticate: Foo\n");
366 return;
369 if (not_modified_) {
370 response_status->assign("HTTP/1.1 304 Not Modified");
371 response_data->clear();
372 return;
375 std::vector<HttpByteRange> ranges;
376 std::string range_header;
377 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
378 &range_header) ||
379 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
380 ranges.size() != 1) {
381 // This is not a byte range request. We return 200.
382 response_status->assign("HTTP/1.1 200 OK");
383 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
384 response_data->assign("Not a range");
385 return;
388 // We can handle this range request.
389 HttpByteRange byte_range = ranges[0];
391 if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
392 byte_range.set_first_byte_position(40);
393 byte_range.set_last_byte_position(49);
396 if (byte_range.first_byte_position() > 79) {
397 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
398 response_data->clear();
399 return;
402 EXPECT_TRUE(byte_range.ComputeBounds(80));
403 int start = static_cast<int>(byte_range.first_byte_position());
404 int end = static_cast<int>(byte_range.last_byte_position());
406 EXPECT_LT(end, 80);
408 std::string content_range = base::StringPrintf(
409 "Content-Range: bytes %d-%d/80\n", start, end);
410 response_headers->append(content_range);
412 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
413 std::string data;
414 if (end == start) {
415 EXPECT_EQ(0, end % 10);
416 data = "r";
417 } else {
418 EXPECT_EQ(9, (end - start) % 10);
419 for (int block_start = start; block_start < end; block_start += 10) {
420 base::StringAppendF(&data, "rg: %02d-%02d ",
421 block_start, block_start + 9);
424 *response_data = data;
426 if (end - start != 9) {
427 // We also have to fix content-length.
428 int len = end - start + 1;
429 std::string content_length = base::StringPrintf("Content-Length: %d\n",
430 len);
431 response_headers->replace(response_headers->find("Content-Length:"),
432 content_length.size(), content_length);
434 } else {
435 response_status->assign("HTTP/1.1 304 Not Modified");
436 response_data->clear();
440 const MockTransaction kRangeGET_TransactionOK = {
441 "http://www.google.com/range",
442 "GET",
443 base::Time(),
444 "Range: bytes = 40-49\r\n" EXTRA_HEADER,
445 LOAD_NORMAL,
446 "HTTP/1.1 206 Partial Content",
447 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
448 "ETag: \"foo\"\n"
449 "Accept-Ranges: bytes\n"
450 "Content-Length: 10\n",
451 base::Time(),
452 "rg: 40-49 ",
453 TEST_MODE_NORMAL,
454 &RangeTransactionServer::RangeHandler,
455 nullptr,
458 OK};
460 const char kFullRangeData[] =
461 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
462 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
464 // Verifies the response headers (|response|) match a partial content
465 // response for the range starting at |start| and ending at |end|.
466 void Verify206Response(std::string response, int start, int end) {
467 std::string raw_headers(
468 HttpUtil::AssembleRawHeaders(response.data(), response.size()));
469 scoped_refptr<HttpResponseHeaders> headers(
470 new HttpResponseHeaders(raw_headers));
472 ASSERT_EQ(206, headers->response_code());
474 int64 range_start, range_end, object_size;
475 ASSERT_TRUE(
476 headers->GetContentRange(&range_start, &range_end, &object_size));
477 int64 content_length = headers->GetContentLength();
479 int length = end - start + 1;
480 ASSERT_EQ(length, content_length);
481 ASSERT_EQ(start, range_start);
482 ASSERT_EQ(end, range_end);
485 // Creates a truncated entry that can be resumed using byte ranges.
486 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
487 // Create a disk cache entry that stores an incomplete resource.
488 disk_cache::Entry* entry;
489 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
490 NULL));
492 raw_headers =
493 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
495 HttpResponseInfo response;
496 response.response_time = base::Time::Now();
497 response.request_time = base::Time::Now();
498 response.headers = new HttpResponseHeaders(raw_headers);
499 // Set the last argument for this to be an incomplete request.
500 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
502 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
503 int len = static_cast<int>(base::strlcpy(buf->data(),
504 "rg: 00-09 rg: 10-19 ", 100));
505 TestCompletionCallback cb;
506 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
507 EXPECT_EQ(len, cb.GetResult(rv));
508 entry->Close();
511 // Verifies that there's an entry with this |key| with the truncated flag set to
512 // |flag_value|, and with an optional |data_size| (if not zero).
513 void VerifyTruncatedFlag(MockHttpCache* cache,
514 const std::string& key,
515 bool flag_value,
516 int data_size) {
517 disk_cache::Entry* entry;
518 ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
519 disk_cache::ScopedEntryPtr closer(entry);
521 HttpResponseInfo response;
522 bool truncated = !flag_value;
523 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
524 EXPECT_EQ(flag_value, truncated);
525 if (data_size)
526 EXPECT_EQ(data_size, entry->GetDataSize(1));
529 // Helper to represent a network HTTP response.
530 struct Response {
531 // Set this response into |trans|.
532 void AssignTo(MockTransaction* trans) const {
533 trans->status = status;
534 trans->response_headers = headers;
535 trans->data = body;
538 std::string status_and_headers() const {
539 return std::string(status) + "\n" + std::string(headers);
542 const char* status;
543 const char* headers;
544 const char* body;
547 struct Context {
548 Context() : result(ERR_IO_PENDING) {}
550 int result;
551 TestCompletionCallback callback;
552 scoped_ptr<HttpTransaction> trans;
555 class FakeWebSocketHandshakeStreamCreateHelper
556 : public WebSocketHandshakeStreamBase::CreateHelper {
557 public:
558 ~FakeWebSocketHandshakeStreamCreateHelper() override {}
559 WebSocketHandshakeStreamBase* CreateBasicStream(
560 scoped_ptr<ClientSocketHandle> connect,
561 bool using_proxy) override {
562 return NULL;
564 WebSocketHandshakeStreamBase* CreateSpdyStream(
565 const base::WeakPtr<SpdySession>& session,
566 bool use_relative_url) override {
567 return NULL;
571 // Returns true if |entry| is not one of the log types paid attention to in this
572 // test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
573 // ignored.
574 bool ShouldIgnoreLogEntry(const TestNetLogEntry& entry) {
575 switch (entry.type) {
576 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
577 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
578 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
579 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
580 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
581 case NetLog::TYPE_HTTP_CACHE_READ_INFO:
582 return false;
583 default:
584 return true;
588 // Modifies |entries| to only include log entries created by the cache layer and
589 // asserted on in these tests.
590 void FilterLogEntries(TestNetLogEntry::List* entries) {
591 entries->erase(std::remove_if(entries->begin(), entries->end(),
592 &ShouldIgnoreLogEntry),
593 entries->end());
596 bool LogContainsEventType(const BoundTestNetLog& log,
597 NetLog::EventType expected) {
598 TestNetLogEntry::List entries;
599 log.GetEntries(&entries);
600 for (size_t i = 0; i < entries.size(); i++) {
601 if (entries[i].type == expected)
602 return true;
604 return false;
607 } // namespace
610 //-----------------------------------------------------------------------------
611 // Tests.
613 TEST(HttpCache, CreateThenDestroy) {
614 MockHttpCache cache;
616 scoped_ptr<HttpTransaction> trans;
617 EXPECT_EQ(OK, cache.CreateTransaction(&trans));
618 ASSERT_TRUE(trans.get());
621 TEST(HttpCache, GetBackend) {
622 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
624 disk_cache::Backend* backend;
625 TestCompletionCallback cb;
626 // This will lazily initialize the backend.
627 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
628 EXPECT_EQ(OK, cb.GetResult(rv));
631 TEST(HttpCache, SimpleGET) {
632 MockHttpCache cache;
633 BoundTestNetLog log;
634 LoadTimingInfo load_timing_info;
636 // Write to the cache.
637 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
638 log.bound(), &load_timing_info);
640 EXPECT_EQ(1, cache.network_layer()->transaction_count());
641 EXPECT_EQ(0, cache.disk_cache()->open_count());
642 EXPECT_EQ(1, cache.disk_cache()->create_count());
643 TestLoadTimingNetworkRequest(load_timing_info);
646 TEST(HttpCache, SimpleGETNoDiskCache) {
647 MockHttpCache cache;
649 cache.disk_cache()->set_fail_requests();
651 BoundTestNetLog log;
652 LoadTimingInfo load_timing_info;
654 // Read from the network, and don't use the cache.
655 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
656 log.bound(), &load_timing_info);
658 // Check that the NetLog was filled as expected.
659 // (We attempted to both Open and Create entries, but both failed).
660 TestNetLogEntry::List entries;
661 log.GetEntries(&entries);
662 FilterLogEntries(&entries);
664 EXPECT_EQ(6u, entries.size());
665 EXPECT_TRUE(
666 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
667 EXPECT_TRUE(
668 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
669 EXPECT_TRUE(
670 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
671 EXPECT_TRUE(
672 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
673 EXPECT_TRUE(
674 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
675 EXPECT_TRUE(
676 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
678 EXPECT_EQ(1, cache.network_layer()->transaction_count());
679 EXPECT_EQ(0, cache.disk_cache()->open_count());
680 EXPECT_EQ(0, cache.disk_cache()->create_count());
681 TestLoadTimingNetworkRequest(load_timing_info);
684 TEST(HttpCache, SimpleGETNoDiskCache2) {
685 // This will initialize a cache object with NULL backend.
686 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
687 factory->set_fail(true);
688 factory->FinishCreation(); // We'll complete synchronously.
689 MockHttpCache cache(factory);
691 // Read from the network, and don't use the cache.
692 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
694 EXPECT_EQ(1, cache.network_layer()->transaction_count());
695 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
698 // Tests that IOBuffers are not referenced after IO completes.
699 TEST(HttpCache, ReleaseBuffer) {
700 MockHttpCache cache;
702 // Write to the cache.
703 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
705 MockHttpRequest request(kSimpleGET_Transaction);
706 scoped_ptr<HttpTransaction> trans;
707 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
709 const int kBufferSize = 10;
710 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
711 ReleaseBufferCompletionCallback cb(buffer.get());
713 int rv = trans->Start(&request, cb.callback(), BoundNetLog());
714 EXPECT_EQ(OK, cb.GetResult(rv));
716 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
717 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
720 TEST(HttpCache, SimpleGETWithDiskFailures) {
721 MockHttpCache cache;
723 cache.disk_cache()->set_soft_failures(true);
725 // Read from the network, and fail to write to the cache.
726 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
728 EXPECT_EQ(1, cache.network_layer()->transaction_count());
729 EXPECT_EQ(0, cache.disk_cache()->open_count());
730 EXPECT_EQ(1, cache.disk_cache()->create_count());
732 // This one should see an empty cache again.
733 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
735 EXPECT_EQ(2, cache.network_layer()->transaction_count());
736 EXPECT_EQ(0, cache.disk_cache()->open_count());
737 EXPECT_EQ(2, cache.disk_cache()->create_count());
740 // Tests that disk failures after the transaction has started don't cause the
741 // request to fail.
742 TEST(HttpCache, SimpleGETWithDiskFailures2) {
743 MockHttpCache cache;
745 MockHttpRequest request(kSimpleGET_Transaction);
747 scoped_ptr<Context> c(new Context());
748 int rv = cache.CreateTransaction(&c->trans);
749 ASSERT_EQ(OK, rv);
751 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
752 EXPECT_EQ(ERR_IO_PENDING, rv);
753 rv = c->callback.WaitForResult();
755 // Start failing request now.
756 cache.disk_cache()->set_soft_failures(true);
758 // We have to open the entry again to propagate the failure flag.
759 disk_cache::Entry* en;
760 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
761 en->Close();
763 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
764 c.reset();
766 EXPECT_EQ(1, cache.network_layer()->transaction_count());
767 EXPECT_EQ(1, cache.disk_cache()->open_count());
768 EXPECT_EQ(1, cache.disk_cache()->create_count());
770 // This one should see an empty cache again.
771 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
773 EXPECT_EQ(2, cache.network_layer()->transaction_count());
774 EXPECT_EQ(1, cache.disk_cache()->open_count());
775 EXPECT_EQ(2, cache.disk_cache()->create_count());
778 // Tests that we handle failures to read from the cache.
779 TEST(HttpCache, SimpleGETWithDiskFailures3) {
780 MockHttpCache cache;
782 // Read from the network, and write to the cache.
783 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
785 EXPECT_EQ(1, cache.network_layer()->transaction_count());
786 EXPECT_EQ(0, cache.disk_cache()->open_count());
787 EXPECT_EQ(1, cache.disk_cache()->create_count());
789 cache.disk_cache()->set_soft_failures(true);
791 // Now fail to read from the cache.
792 scoped_ptr<Context> c(new Context());
793 int rv = cache.CreateTransaction(&c->trans);
794 ASSERT_EQ(OK, rv);
796 MockHttpRequest request(kSimpleGET_Transaction);
797 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
798 EXPECT_EQ(OK, c->callback.GetResult(rv));
800 // Now verify that the entry was removed from the cache.
801 cache.disk_cache()->set_soft_failures(false);
803 EXPECT_EQ(2, cache.network_layer()->transaction_count());
804 EXPECT_EQ(1, cache.disk_cache()->open_count());
805 EXPECT_EQ(2, cache.disk_cache()->create_count());
807 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
809 EXPECT_EQ(3, cache.network_layer()->transaction_count());
810 EXPECT_EQ(1, cache.disk_cache()->open_count());
811 EXPECT_EQ(3, cache.disk_cache()->create_count());
814 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
815 MockHttpCache cache;
817 BoundTestNetLog log;
818 LoadTimingInfo load_timing_info;
820 // Write to the cache.
821 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
822 log.bound(), &load_timing_info);
824 // Check that the NetLog was filled as expected.
825 TestNetLogEntry::List entries;
826 log.GetEntries(&entries);
827 FilterLogEntries(&entries);
829 EXPECT_EQ(8u, entries.size());
830 EXPECT_TRUE(
831 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
832 EXPECT_TRUE(
833 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
834 EXPECT_TRUE(
835 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
836 EXPECT_TRUE(
837 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
838 EXPECT_TRUE(
839 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
840 EXPECT_TRUE(
841 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
842 EXPECT_TRUE(
843 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
844 EXPECT_TRUE(
845 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
847 TestLoadTimingNetworkRequest(load_timing_info);
849 // Force this transaction to read from the cache.
850 MockTransaction transaction(kSimpleGET_Transaction);
851 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
853 log.Clear();
855 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
856 &load_timing_info);
858 // Check that the NetLog was filled as expected.
859 log.GetEntries(&entries);
860 FilterLogEntries(&entries);
862 EXPECT_EQ(8u, entries.size());
863 EXPECT_TRUE(
864 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
865 EXPECT_TRUE(
866 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
867 EXPECT_TRUE(
868 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
869 EXPECT_TRUE(
870 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
871 EXPECT_TRUE(
872 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
873 EXPECT_TRUE(
874 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
875 EXPECT_TRUE(
876 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO));
877 EXPECT_TRUE(
878 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO));
880 EXPECT_EQ(1, cache.network_layer()->transaction_count());
881 EXPECT_EQ(1, cache.disk_cache()->open_count());
882 EXPECT_EQ(1, cache.disk_cache()->create_count());
883 TestLoadTimingCachedResponse(load_timing_info);
886 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
887 MockHttpCache cache;
889 // force this transaction to read from the cache
890 MockTransaction transaction(kSimpleGET_Transaction);
891 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
893 MockHttpRequest request(transaction);
894 TestCompletionCallback callback;
896 scoped_ptr<HttpTransaction> trans;
897 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
899 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
900 if (rv == ERR_IO_PENDING)
901 rv = callback.WaitForResult();
902 ASSERT_EQ(ERR_CACHE_MISS, rv);
904 trans.reset();
906 EXPECT_EQ(0, cache.network_layer()->transaction_count());
907 EXPECT_EQ(0, cache.disk_cache()->open_count());
908 EXPECT_EQ(0, cache.disk_cache()->create_count());
911 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
912 MockHttpCache cache;
914 // write to the cache
915 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
917 // force this transaction to read from the cache if valid
918 MockTransaction transaction(kSimpleGET_Transaction);
919 transaction.load_flags |= LOAD_PREFERRING_CACHE;
921 RunTransactionTest(cache.http_cache(), transaction);
923 EXPECT_EQ(1, cache.network_layer()->transaction_count());
924 EXPECT_EQ(1, cache.disk_cache()->open_count());
925 EXPECT_EQ(1, cache.disk_cache()->create_count());
928 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
929 MockHttpCache cache;
931 // force this transaction to read from the cache if valid
932 MockTransaction transaction(kSimpleGET_Transaction);
933 transaction.load_flags |= LOAD_PREFERRING_CACHE;
935 RunTransactionTest(cache.http_cache(), transaction);
937 EXPECT_EQ(1, cache.network_layer()->transaction_count());
938 EXPECT_EQ(0, cache.disk_cache()->open_count());
939 EXPECT_EQ(1, cache.disk_cache()->create_count());
942 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
943 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
944 MockHttpCache cache;
946 // Write to the cache.
947 MockTransaction transaction(kSimpleGET_Transaction);
948 transaction.request_headers = "Foo: bar\r\n";
949 transaction.response_headers = "Cache-Control: max-age=10000\n"
950 "Vary: Foo\n";
951 AddMockTransaction(&transaction);
952 RunTransactionTest(cache.http_cache(), transaction);
954 // Read from the cache.
955 transaction.load_flags |= LOAD_PREFERRING_CACHE;
956 RunTransactionTest(cache.http_cache(), transaction);
958 EXPECT_EQ(1, cache.network_layer()->transaction_count());
959 EXPECT_EQ(1, cache.disk_cache()->open_count());
960 EXPECT_EQ(1, cache.disk_cache()->create_count());
961 RemoveMockTransaction(&transaction);
964 // Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
965 TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
966 MockHttpCache cache;
968 // Write to the cache.
969 MockTransaction transaction(kSimpleGET_Transaction);
970 transaction.request_headers = "Foo: bar\r\n";
971 transaction.response_headers = "Cache-Control: max-age=10000\n"
972 "Vary: Foo\n";
973 AddMockTransaction(&transaction);
974 RunTransactionTest(cache.http_cache(), transaction);
976 // Attempt to read from the cache... this is a vary mismatch that must reach
977 // the network again.
978 transaction.load_flags |= LOAD_PREFERRING_CACHE;
979 transaction.request_headers = "Foo: none\r\n";
980 BoundTestNetLog log;
981 LoadTimingInfo load_timing_info;
982 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
983 &load_timing_info);
985 EXPECT_EQ(2, cache.network_layer()->transaction_count());
986 EXPECT_EQ(1, cache.disk_cache()->open_count());
987 EXPECT_EQ(1, cache.disk_cache()->create_count());
988 TestLoadTimingNetworkRequest(load_timing_info);
989 RemoveMockTransaction(&transaction);
992 // Tests that was_cached was set properly on a failure, even if the cached
993 // response wasn't returned.
994 TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
995 MockHttpCache cache;
997 // Prime cache.
998 MockTransaction transaction(kSimpleGET_Transaction);
999 transaction.response_headers = "Cache-Control: no-cache\n";
1001 AddMockTransaction(&transaction);
1002 RunTransactionTest(cache.http_cache(), transaction);
1003 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1004 EXPECT_EQ(1, cache.disk_cache()->create_count());
1005 RemoveMockTransaction(&transaction);
1007 // Network failure with error; should fail but have was_cached set.
1008 transaction.return_code = ERR_FAILED;
1009 AddMockTransaction(&transaction);
1011 MockHttpRequest request(transaction);
1012 TestCompletionCallback callback;
1013 scoped_ptr<HttpTransaction> trans;
1014 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1015 EXPECT_EQ(OK, rv);
1016 ASSERT_TRUE(trans.get());
1017 rv = trans->Start(&request, callback.callback(), BoundNetLog());
1018 EXPECT_EQ(ERR_FAILED, callback.GetResult(rv));
1020 const HttpResponseInfo* response_info = trans->GetResponseInfo();
1021 ASSERT_TRUE(response_info);
1022 EXPECT_TRUE(response_info->was_cached);
1023 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1025 RemoveMockTransaction(&transaction);
1028 // Confirm if we have an empty cache, a read is marked as network verified.
1029 TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1030 MockHttpCache cache;
1032 // write to the cache
1033 HttpResponseInfo response_info;
1034 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1035 &response_info);
1037 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1038 EXPECT_EQ(0, cache.disk_cache()->open_count());
1039 EXPECT_EQ(1, cache.disk_cache()->create_count());
1040 EXPECT_TRUE(response_info.network_accessed);
1043 // Confirm if we have a fresh entry in cache, it isn't marked as
1044 // network verified.
1045 TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1046 MockHttpCache cache;
1048 // Prime cache.
1049 MockTransaction transaction(kSimpleGET_Transaction);
1051 RunTransactionTest(cache.http_cache(), transaction);
1052 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1053 EXPECT_EQ(1, cache.disk_cache()->create_count());
1055 // Re-run transaction; make sure we don't mark the network as accessed.
1056 HttpResponseInfo response_info;
1057 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1058 &response_info);
1060 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1061 EXPECT_FALSE(response_info.server_data_unavailable);
1062 EXPECT_FALSE(response_info.network_accessed);
1065 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1066 MockHttpCache cache;
1068 // Write to the cache.
1069 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1071 // Force this transaction to write to the cache again.
1072 MockTransaction transaction(kSimpleGET_Transaction);
1073 transaction.load_flags |= LOAD_BYPASS_CACHE;
1075 BoundTestNetLog log;
1076 LoadTimingInfo load_timing_info;
1078 // Write to the cache.
1079 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1080 &load_timing_info);
1082 // Check that the NetLog was filled as expected.
1083 TestNetLogEntry::List entries;
1084 log.GetEntries(&entries);
1085 FilterLogEntries(&entries);
1087 EXPECT_EQ(8u, entries.size());
1088 EXPECT_TRUE(
1089 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1090 EXPECT_TRUE(
1091 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1092 EXPECT_TRUE(
1093 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1094 EXPECT_TRUE(
1095 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1096 EXPECT_TRUE(
1097 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1098 EXPECT_TRUE(
1099 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1100 EXPECT_TRUE(
1101 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1102 EXPECT_TRUE(
1103 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1105 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1106 EXPECT_EQ(0, cache.disk_cache()->open_count());
1107 EXPECT_EQ(2, cache.disk_cache()->create_count());
1108 TestLoadTimingNetworkRequest(load_timing_info);
1111 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1112 MockHttpCache cache;
1114 // write to the cache
1115 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1117 // force this transaction to write to the cache again
1118 MockTransaction transaction(kSimpleGET_Transaction);
1119 transaction.request_headers = "pragma: no-cache\r\n";
1121 RunTransactionTest(cache.http_cache(), transaction);
1123 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1124 EXPECT_EQ(0, cache.disk_cache()->open_count());
1125 EXPECT_EQ(2, cache.disk_cache()->create_count());
1128 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1129 MockHttpCache cache;
1131 // write to the cache
1132 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1134 // force this transaction to write to the cache again
1135 MockTransaction transaction(kSimpleGET_Transaction);
1136 transaction.request_headers = "cache-control: no-cache\r\n";
1138 RunTransactionTest(cache.http_cache(), transaction);
1140 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1141 EXPECT_EQ(0, cache.disk_cache()->open_count());
1142 EXPECT_EQ(2, cache.disk_cache()->create_count());
1145 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1146 MockHttpCache cache;
1148 // Write to the cache.
1149 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1151 // Read from the cache.
1152 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1154 // Force this transaction to validate the cache.
1155 MockTransaction transaction(kSimpleGET_Transaction);
1156 transaction.load_flags |= LOAD_VALIDATE_CACHE;
1158 HttpResponseInfo response_info;
1159 BoundTestNetLog log;
1160 LoadTimingInfo load_timing_info;
1161 RunTransactionTestWithResponseInfoAndGetTiming(
1162 cache.http_cache(), transaction, &response_info, log.bound(),
1163 &load_timing_info);
1165 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1166 EXPECT_EQ(1, cache.disk_cache()->open_count());
1167 EXPECT_EQ(1, cache.disk_cache()->create_count());
1168 EXPECT_TRUE(response_info.network_accessed);
1169 TestLoadTimingNetworkRequest(load_timing_info);
1172 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1173 MockHttpCache cache;
1175 // write to the cache
1176 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1178 // read from the cache
1179 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1181 // force this transaction to validate the cache
1182 MockTransaction transaction(kSimpleGET_Transaction);
1183 transaction.request_headers = "cache-control: max-age=0\r\n";
1185 RunTransactionTest(cache.http_cache(), transaction);
1187 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1188 EXPECT_EQ(1, cache.disk_cache()->open_count());
1189 EXPECT_EQ(1, cache.disk_cache()->create_count());
1192 static void PreserveRequestHeaders_Handler(const HttpRequestInfo* request,
1193 std::string* response_status,
1194 std::string* response_headers,
1195 std::string* response_data) {
1196 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1199 // Tests that we don't remove extra headers for simple requests.
1200 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1201 MockHttpCache cache;
1203 MockTransaction transaction(kSimpleGET_Transaction);
1204 transaction.handler = PreserveRequestHeaders_Handler;
1205 transaction.request_headers = EXTRA_HEADER;
1206 transaction.response_headers = "Cache-Control: max-age=0\n";
1207 AddMockTransaction(&transaction);
1209 // Write, then revalidate the entry.
1210 RunTransactionTest(cache.http_cache(), transaction);
1211 RunTransactionTest(cache.http_cache(), transaction);
1213 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1214 EXPECT_EQ(1, cache.disk_cache()->open_count());
1215 EXPECT_EQ(1, cache.disk_cache()->create_count());
1216 RemoveMockTransaction(&transaction);
1219 // Tests that we don't remove extra headers for conditionalized requests.
1220 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1221 MockHttpCache cache;
1223 // Write to the cache.
1224 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1226 MockTransaction transaction(kETagGET_Transaction);
1227 transaction.handler = PreserveRequestHeaders_Handler;
1228 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1229 EXTRA_HEADER;
1230 AddMockTransaction(&transaction);
1232 RunTransactionTest(cache.http_cache(), transaction);
1234 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1235 EXPECT_EQ(1, cache.disk_cache()->open_count());
1236 EXPECT_EQ(1, cache.disk_cache()->create_count());
1237 RemoveMockTransaction(&transaction);
1240 TEST(HttpCache, SimpleGET_ManyReaders) {
1241 MockHttpCache cache;
1243 MockHttpRequest request(kSimpleGET_Transaction);
1245 std::vector<Context*> context_list;
1246 const int kNumTransactions = 5;
1248 for (int i = 0; i < kNumTransactions; ++i) {
1249 context_list.push_back(new Context());
1250 Context* c = context_list[i];
1252 c->result = cache.CreateTransaction(&c->trans);
1253 ASSERT_EQ(OK, c->result);
1254 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1256 c->result =
1257 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1260 // All requests are waiting for the active entry.
1261 for (int i = 0; i < kNumTransactions; ++i) {
1262 Context* c = context_list[i];
1263 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1266 // Allow all requests to move from the Create queue to the active entry.
1267 base::MessageLoop::current()->RunUntilIdle();
1269 // The first request should be a writer at this point, and the subsequent
1270 // requests should be pending.
1272 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1273 EXPECT_EQ(0, cache.disk_cache()->open_count());
1274 EXPECT_EQ(1, cache.disk_cache()->create_count());
1276 // All requests depend on the writer, and the writer is between Start and
1277 // Read, i.e. idle.
1278 for (int i = 0; i < kNumTransactions; ++i) {
1279 Context* c = context_list[i];
1280 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1283 for (int i = 0; i < kNumTransactions; ++i) {
1284 Context* c = context_list[i];
1285 if (c->result == ERR_IO_PENDING)
1286 c->result = c->callback.WaitForResult();
1287 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1290 // We should not have had to re-open the disk entry
1292 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1293 EXPECT_EQ(0, cache.disk_cache()->open_count());
1294 EXPECT_EQ(1, cache.disk_cache()->create_count());
1296 for (int i = 0; i < kNumTransactions; ++i) {
1297 Context* c = context_list[i];
1298 delete c;
1302 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1303 // If cancelling a request is racing with another request for the same resource
1304 // finishing, we have to make sure that we remove both transactions from the
1305 // entry.
1306 TEST(HttpCache, SimpleGET_RacingReaders) {
1307 MockHttpCache cache;
1309 MockHttpRequest request(kSimpleGET_Transaction);
1310 MockHttpRequest reader_request(kSimpleGET_Transaction);
1311 reader_request.load_flags = LOAD_ONLY_FROM_CACHE;
1313 std::vector<Context*> context_list;
1314 const int kNumTransactions = 5;
1316 for (int i = 0; i < kNumTransactions; ++i) {
1317 context_list.push_back(new Context());
1318 Context* c = context_list[i];
1320 c->result = cache.CreateTransaction(&c->trans);
1321 ASSERT_EQ(OK, c->result);
1323 MockHttpRequest* this_request = &request;
1324 if (i == 1 || i == 2)
1325 this_request = &reader_request;
1327 c->result =
1328 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
1331 // Allow all requests to move from the Create queue to the active entry.
1332 base::MessageLoop::current()->RunUntilIdle();
1334 // The first request should be a writer at this point, and the subsequent
1335 // requests should be pending.
1337 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1338 EXPECT_EQ(0, cache.disk_cache()->open_count());
1339 EXPECT_EQ(1, cache.disk_cache()->create_count());
1341 Context* c = context_list[0];
1342 ASSERT_EQ(ERR_IO_PENDING, c->result);
1343 c->result = c->callback.WaitForResult();
1344 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1346 // Now we have 2 active readers and two queued transactions.
1348 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1349 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE,
1350 context_list[3]->trans->GetLoadState());
1352 c = context_list[1];
1353 ASSERT_EQ(ERR_IO_PENDING, c->result);
1354 c->result = c->callback.WaitForResult();
1355 if (c->result == OK)
1356 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1358 // At this point we have one reader, two pending transactions and a task on
1359 // the queue to move to the next transaction. Now we cancel the request that
1360 // is the current reader, and expect the queued task to be able to start the
1361 // next request.
1363 c = context_list[2];
1364 c->trans.reset();
1366 for (int i = 3; i < kNumTransactions; ++i) {
1367 Context* c = context_list[i];
1368 if (c->result == ERR_IO_PENDING)
1369 c->result = c->callback.WaitForResult();
1370 if (c->result == OK)
1371 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1374 // We should not have had to re-open the disk entry.
1376 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1377 EXPECT_EQ(0, cache.disk_cache()->open_count());
1378 EXPECT_EQ(1, cache.disk_cache()->create_count());
1380 for (int i = 0; i < kNumTransactions; ++i) {
1381 Context* c = context_list[i];
1382 delete c;
1386 // Tests that we can doom an entry with pending transactions and delete one of
1387 // the pending transactions before the first one completes.
1388 // See http://code.google.com/p/chromium/issues/detail?id=25588
1389 TEST(HttpCache, SimpleGET_DoomWithPending) {
1390 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1391 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
1393 MockHttpRequest request(kSimpleGET_Transaction);
1394 MockHttpRequest writer_request(kSimpleGET_Transaction);
1395 writer_request.load_flags = LOAD_BYPASS_CACHE;
1397 ScopedVector<Context> context_list;
1398 const int kNumTransactions = 4;
1400 for (int i = 0; i < kNumTransactions; ++i) {
1401 context_list.push_back(new Context());
1402 Context* c = context_list[i];
1404 c->result = cache.CreateTransaction(&c->trans);
1405 ASSERT_EQ(OK, c->result);
1407 MockHttpRequest* this_request = &request;
1408 if (i == 3)
1409 this_request = &writer_request;
1411 c->result =
1412 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
1415 // The first request should be a writer at this point, and the two subsequent
1416 // requests should be pending. The last request doomed the first entry.
1418 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1420 // Cancel the first queued transaction.
1421 delete context_list[1];
1422 context_list.get()[1] = NULL;
1424 for (int i = 0; i < kNumTransactions; ++i) {
1425 if (i == 1)
1426 continue;
1427 Context* c = context_list[i];
1428 ASSERT_EQ(ERR_IO_PENDING, c->result);
1429 c->result = c->callback.WaitForResult();
1430 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1434 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1435 // We may attempt to delete an entry synchronously with the act of adding a new
1436 // transaction to said entry.
1437 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1438 MockHttpCache cache;
1440 // The headers will be served right from the call to Start() the request.
1441 MockHttpRequest request(kFastNoStoreGET_Transaction);
1442 FastTransactionServer request_handler;
1443 AddMockTransaction(&kFastNoStoreGET_Transaction);
1445 std::vector<Context*> context_list;
1446 const int kNumTransactions = 3;
1448 for (int i = 0; i < kNumTransactions; ++i) {
1449 context_list.push_back(new Context());
1450 Context* c = context_list[i];
1452 c->result = cache.CreateTransaction(&c->trans);
1453 ASSERT_EQ(OK, c->result);
1455 c->result =
1456 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1459 // Allow all requests to move from the Create queue to the active entry.
1460 base::MessageLoop::current()->RunUntilIdle();
1462 // The first request should be a writer at this point, and the subsequent
1463 // requests should be pending.
1465 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1466 EXPECT_EQ(0, cache.disk_cache()->open_count());
1467 EXPECT_EQ(1, cache.disk_cache()->create_count());
1469 // Now, make sure that the second request asks for the entry not to be stored.
1470 request_handler.set_no_store(true);
1472 for (int i = 0; i < kNumTransactions; ++i) {
1473 Context* c = context_list[i];
1474 if (c->result == ERR_IO_PENDING)
1475 c->result = c->callback.WaitForResult();
1476 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1477 delete c;
1480 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1481 EXPECT_EQ(0, cache.disk_cache()->open_count());
1482 EXPECT_EQ(2, cache.disk_cache()->create_count());
1484 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1487 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1488 MockHttpCache cache;
1490 MockHttpRequest request(kSimpleGET_Transaction);
1492 std::vector<Context*> context_list;
1493 const int kNumTransactions = 2;
1495 for (int i = 0; i < kNumTransactions; ++i) {
1496 context_list.push_back(new Context());
1497 Context* c = context_list[i];
1499 c->result = cache.CreateTransaction(&c->trans);
1500 ASSERT_EQ(OK, c->result);
1502 c->result =
1503 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1506 // Allow all requests to move from the Create queue to the active entry.
1507 base::MessageLoop::current()->RunUntilIdle();
1509 // The first request should be a writer at this point, and the subsequent
1510 // requests should be pending.
1512 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1513 EXPECT_EQ(0, cache.disk_cache()->open_count());
1514 EXPECT_EQ(1, cache.disk_cache()->create_count());
1516 for (int i = 0; i < kNumTransactions; ++i) {
1517 Context* c = context_list[i];
1518 if (c->result == ERR_IO_PENDING)
1519 c->result = c->callback.WaitForResult();
1520 // Destroy only the first transaction.
1521 if (i == 0) {
1522 delete c;
1523 context_list[i] = NULL;
1527 // Complete the rest of the transactions.
1528 for (int i = 1; i < kNumTransactions; ++i) {
1529 Context* c = context_list[i];
1530 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1533 // We should have had to re-open the disk entry.
1535 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1536 EXPECT_EQ(0, cache.disk_cache()->open_count());
1537 EXPECT_EQ(2, cache.disk_cache()->create_count());
1539 for (int i = 1; i < kNumTransactions; ++i) {
1540 Context* c = context_list[i];
1541 delete c;
1545 // Tests that we can cancel requests that are queued waiting to open the disk
1546 // cache entry.
1547 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1548 MockHttpCache cache;
1550 MockHttpRequest request(kSimpleGET_Transaction);
1552 std::vector<Context*> context_list;
1553 const int kNumTransactions = 5;
1555 for (int i = 0; i < kNumTransactions; i++) {
1556 context_list.push_back(new Context());
1557 Context* c = context_list[i];
1559 c->result = cache.CreateTransaction(&c->trans);
1560 ASSERT_EQ(OK, c->result);
1562 c->result =
1563 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1566 // The first request should be creating the disk cache entry and the others
1567 // should be pending.
1569 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1570 EXPECT_EQ(0, cache.disk_cache()->open_count());
1571 EXPECT_EQ(1, cache.disk_cache()->create_count());
1573 // Cancel a request from the pending queue.
1574 delete context_list[3];
1575 context_list[3] = NULL;
1577 // Cancel the request that is creating the entry. This will force the pending
1578 // operations to restart.
1579 delete context_list[0];
1580 context_list[0] = NULL;
1582 // Complete the rest of the transactions.
1583 for (int i = 1; i < kNumTransactions; i++) {
1584 Context* c = context_list[i];
1585 if (c) {
1586 c->result = c->callback.GetResult(c->result);
1587 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1591 // We should have had to re-create the disk entry.
1593 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1594 EXPECT_EQ(0, cache.disk_cache()->open_count());
1595 EXPECT_EQ(2, cache.disk_cache()->create_count());
1597 for (int i = 1; i < kNumTransactions; ++i) {
1598 delete context_list[i];
1602 // Tests that we can cancel a single request to open a disk cache entry.
1603 TEST(HttpCache, SimpleGET_CancelCreate) {
1604 MockHttpCache cache;
1606 MockHttpRequest request(kSimpleGET_Transaction);
1608 Context* c = new Context();
1610 c->result = cache.CreateTransaction(&c->trans);
1611 ASSERT_EQ(OK, c->result);
1613 c->result = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1614 EXPECT_EQ(ERR_IO_PENDING, c->result);
1616 // Release the reference that the mock disk cache keeps for this entry, so
1617 // that we test that the http cache handles the cancellation correctly.
1618 cache.disk_cache()->ReleaseAll();
1619 delete c;
1621 base::MessageLoop::current()->RunUntilIdle();
1622 EXPECT_EQ(1, cache.disk_cache()->create_count());
1625 // Tests that we delete/create entries even if multiple requests are queued.
1626 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1627 MockHttpCache cache;
1629 MockHttpRequest request(kSimpleGET_Transaction);
1630 request.load_flags = LOAD_BYPASS_CACHE;
1632 std::vector<Context*> context_list;
1633 const int kNumTransactions = 5;
1635 for (int i = 0; i < kNumTransactions; i++) {
1636 context_list.push_back(new Context());
1637 Context* c = context_list[i];
1639 c->result = cache.CreateTransaction(&c->trans);
1640 ASSERT_EQ(OK, c->result);
1642 c->result =
1643 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1646 // The first request should be deleting the disk cache entry and the others
1647 // should be pending.
1649 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1650 EXPECT_EQ(0, cache.disk_cache()->open_count());
1651 EXPECT_EQ(0, cache.disk_cache()->create_count());
1653 // Complete the transactions.
1654 for (int i = 0; i < kNumTransactions; i++) {
1655 Context* c = context_list[i];
1656 c->result = c->callback.GetResult(c->result);
1657 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1660 // We should have had to re-create the disk entry multiple times.
1662 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1663 EXPECT_EQ(0, cache.disk_cache()->open_count());
1664 EXPECT_EQ(5, cache.disk_cache()->create_count());
1666 for (int i = 0; i < kNumTransactions; ++i) {
1667 delete context_list[i];
1671 // Tests that a (simulated) timeout allows transactions waiting on the cache
1672 // lock to continue.
1673 TEST(HttpCache, SimpleGET_WriterTimeout) {
1674 MockHttpCache cache;
1675 cache.BypassCacheLock();
1677 MockHttpRequest request(kSimpleGET_Transaction);
1678 Context c1, c2;
1679 ASSERT_EQ(OK, cache.CreateTransaction(&c1.trans));
1680 ASSERT_EQ(ERR_IO_PENDING,
1681 c1.trans->Start(&request, c1.callback.callback(), BoundNetLog()));
1682 ASSERT_EQ(OK, cache.CreateTransaction(&c2.trans));
1683 ASSERT_EQ(ERR_IO_PENDING,
1684 c2.trans->Start(&request, c2.callback.callback(), BoundNetLog()));
1686 // The second request is queued after the first one.
1688 c2.callback.WaitForResult();
1689 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1691 // Complete the first transaction.
1692 c1.callback.WaitForResult();
1693 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1696 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1697 MockHttpCache cache;
1699 // write to the cache
1700 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1702 MockHttpRequest request(kSimpleGET_Transaction);
1703 TestCompletionCallback callback;
1705 scoped_ptr<HttpTransaction> trans;
1706 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
1707 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1708 if (rv == ERR_IO_PENDING)
1709 rv = callback.WaitForResult();
1710 ASSERT_EQ(OK, rv);
1712 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
1713 rv = trans->Read(buf.get(), 256, callback.callback());
1714 EXPECT_EQ(ERR_IO_PENDING, rv);
1716 // Test that destroying the transaction while it is reading from the cache
1717 // works properly.
1718 trans.reset();
1720 // Make sure we pump any pending events, which should include a call to
1721 // HttpCache::Transaction::OnCacheReadCompleted.
1722 base::MessageLoop::current()->RunUntilIdle();
1725 // Tests that we can delete the HttpCache and deal with queued transactions
1726 // ("waiting for the backend" as opposed to Active or Doomed entries).
1727 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1728 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1729 new MockBackendNoCbFactory()));
1731 MockHttpRequest request(kSimpleGET_Transaction);
1733 std::vector<Context*> context_list;
1734 const int kNumTransactions = 5;
1736 for (int i = 0; i < kNumTransactions; i++) {
1737 context_list.push_back(new Context());
1738 Context* c = context_list[i];
1740 c->result = cache->CreateTransaction(&c->trans);
1741 ASSERT_EQ(OK, c->result);
1743 c->result =
1744 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1747 // The first request should be creating the disk cache entry and the others
1748 // should be pending.
1750 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1751 EXPECT_EQ(0, cache->disk_cache()->open_count());
1752 EXPECT_EQ(0, cache->disk_cache()->create_count());
1754 cache.reset();
1756 // There is not much to do with the transactions at this point... they are
1757 // waiting for a callback that will not fire.
1758 for (int i = 0; i < kNumTransactions; ++i) {
1759 delete context_list[i];
1763 // Tests that we queue requests when initializing the backend.
1764 TEST(HttpCache, SimpleGET_WaitForBackend) {
1765 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1766 MockHttpCache cache(factory);
1768 MockHttpRequest request0(kSimpleGET_Transaction);
1769 MockHttpRequest request1(kTypicalGET_Transaction);
1770 MockHttpRequest request2(kETagGET_Transaction);
1772 std::vector<Context*> context_list;
1773 const int kNumTransactions = 3;
1775 for (int i = 0; i < kNumTransactions; i++) {
1776 context_list.push_back(new Context());
1777 Context* c = context_list[i];
1779 c->result = cache.CreateTransaction(&c->trans);
1780 ASSERT_EQ(OK, c->result);
1783 context_list[0]->result = context_list[0]->trans->Start(
1784 &request0, context_list[0]->callback.callback(), BoundNetLog());
1785 context_list[1]->result = context_list[1]->trans->Start(
1786 &request1, context_list[1]->callback.callback(), BoundNetLog());
1787 context_list[2]->result = context_list[2]->trans->Start(
1788 &request2, context_list[2]->callback.callback(), BoundNetLog());
1790 // Just to make sure that everything is still pending.
1791 base::MessageLoop::current()->RunUntilIdle();
1793 // The first request should be creating the disk cache.
1794 EXPECT_FALSE(context_list[0]->callback.have_result());
1796 factory->FinishCreation();
1798 base::MessageLoop::current()->RunUntilIdle();
1799 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1800 EXPECT_EQ(3, cache.disk_cache()->create_count());
1802 for (int i = 0; i < kNumTransactions; ++i) {
1803 EXPECT_TRUE(context_list[i]->callback.have_result());
1804 delete context_list[i];
1808 // Tests that we can cancel requests that are queued waiting for the backend
1809 // to be initialized.
1810 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1811 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1812 MockHttpCache cache(factory);
1814 MockHttpRequest request0(kSimpleGET_Transaction);
1815 MockHttpRequest request1(kTypicalGET_Transaction);
1816 MockHttpRequest request2(kETagGET_Transaction);
1818 std::vector<Context*> context_list;
1819 const int kNumTransactions = 3;
1821 for (int i = 0; i < kNumTransactions; i++) {
1822 context_list.push_back(new Context());
1823 Context* c = context_list[i];
1825 c->result = cache.CreateTransaction(&c->trans);
1826 ASSERT_EQ(OK, c->result);
1829 context_list[0]->result = context_list[0]->trans->Start(
1830 &request0, context_list[0]->callback.callback(), BoundNetLog());
1831 context_list[1]->result = context_list[1]->trans->Start(
1832 &request1, context_list[1]->callback.callback(), BoundNetLog());
1833 context_list[2]->result = context_list[2]->trans->Start(
1834 &request2, context_list[2]->callback.callback(), BoundNetLog());
1836 // Just to make sure that everything is still pending.
1837 base::MessageLoop::current()->RunUntilIdle();
1839 // The first request should be creating the disk cache.
1840 EXPECT_FALSE(context_list[0]->callback.have_result());
1842 // Cancel a request from the pending queue.
1843 delete context_list[1];
1844 context_list[1] = NULL;
1846 // Cancel the request that is creating the entry.
1847 delete context_list[0];
1848 context_list[0] = NULL;
1850 // Complete the last transaction.
1851 factory->FinishCreation();
1853 context_list[2]->result =
1854 context_list[2]->callback.GetResult(context_list[2]->result);
1855 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1857 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1858 EXPECT_EQ(1, cache.disk_cache()->create_count());
1860 delete context_list[2];
1863 // Tests that we can delete the cache while creating the backend.
1864 TEST(HttpCache, DeleteCacheWaitingForBackend) {
1865 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1866 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1868 MockHttpRequest request(kSimpleGET_Transaction);
1870 scoped_ptr<Context> c(new Context());
1871 c->result = cache->CreateTransaction(&c->trans);
1872 ASSERT_EQ(OK, c->result);
1874 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1876 // Just to make sure that everything is still pending.
1877 base::MessageLoop::current()->RunUntilIdle();
1879 // The request should be creating the disk cache.
1880 EXPECT_FALSE(c->callback.have_result());
1882 // We cannot call FinishCreation because the factory itself will go away with
1883 // the cache, so grab the callback and attempt to use it.
1884 CompletionCallback callback = factory->callback();
1885 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1887 cache.reset();
1888 base::MessageLoop::current()->RunUntilIdle();
1890 backend->reset();
1891 callback.Run(ERR_ABORTED);
1894 // Tests that we can delete the cache while creating the backend, from within
1895 // one of the callbacks.
1896 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1897 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1898 MockHttpCache* cache = new MockHttpCache(factory);
1900 DeleteCacheCompletionCallback cb(cache);
1901 disk_cache::Backend* backend;
1902 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1903 EXPECT_EQ(ERR_IO_PENDING, rv);
1905 // Now let's queue a regular transaction
1906 MockHttpRequest request(kSimpleGET_Transaction);
1908 scoped_ptr<Context> c(new Context());
1909 c->result = cache->CreateTransaction(&c->trans);
1910 ASSERT_EQ(OK, c->result);
1912 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1914 // And another direct backend request.
1915 TestCompletionCallback cb2;
1916 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1917 EXPECT_EQ(ERR_IO_PENDING, rv);
1919 // Just to make sure that everything is still pending.
1920 base::MessageLoop::current()->RunUntilIdle();
1922 // The request should be queued.
1923 EXPECT_FALSE(c->callback.have_result());
1925 // Generate the callback.
1926 factory->FinishCreation();
1927 rv = cb.WaitForResult();
1929 // The cache should be gone by now.
1930 base::MessageLoop::current()->RunUntilIdle();
1931 EXPECT_EQ(OK, c->callback.GetResult(c->result));
1932 EXPECT_FALSE(cb2.have_result());
1935 // Fails only on bots. crbug.com/533640
1936 #if defined(OS_ANDROID)
1937 #define MAYBE_TypicalGET_ConditionalRequest \
1938 DISABLED_TypicalGET_ConditionalRequest
1939 #else
1940 #define MAYBE_TypicalGET_ConditionalRequest TypicalGET_ConditionalRequest
1941 #endif
1942 TEST(HttpCache, MAYBE_TypicalGET_ConditionalRequest) {
1943 MockHttpCache cache;
1945 // write to the cache
1946 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1948 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1949 EXPECT_EQ(0, cache.disk_cache()->open_count());
1950 EXPECT_EQ(1, cache.disk_cache()->create_count());
1952 // Get the same URL again, but this time we expect it to result
1953 // in a conditional request.
1954 BoundTestNetLog log;
1955 LoadTimingInfo load_timing_info;
1956 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1957 log.bound(), &load_timing_info);
1959 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1960 EXPECT_EQ(1, cache.disk_cache()->open_count());
1961 EXPECT_EQ(1, cache.disk_cache()->create_count());
1962 TestLoadTimingNetworkRequest(load_timing_info);
1965 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo* request,
1966 std::string* response_status,
1967 std::string* response_headers,
1968 std::string* response_data) {
1969 EXPECT_TRUE(
1970 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
1971 response_status->assign("HTTP/1.1 304 Not Modified");
1972 response_headers->assign(kETagGET_Transaction.response_headers);
1973 response_data->clear();
1976 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
1977 MockHttpCache cache;
1979 ScopedMockTransaction transaction(kETagGET_Transaction);
1981 // write to the cache
1982 RunTransactionTest(cache.http_cache(), transaction);
1984 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1985 EXPECT_EQ(0, cache.disk_cache()->open_count());
1986 EXPECT_EQ(1, cache.disk_cache()->create_count());
1988 // Get the same URL again, but this time we expect it to result
1989 // in a conditional request.
1990 transaction.load_flags = LOAD_VALIDATE_CACHE;
1991 transaction.handler = ETagGet_ConditionalRequest_Handler;
1992 BoundTestNetLog log;
1993 LoadTimingInfo load_timing_info;
1994 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1995 &load_timing_info);
1997 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1998 EXPECT_EQ(1, cache.disk_cache()->open_count());
1999 EXPECT_EQ(1, cache.disk_cache()->create_count());
2000 TestLoadTimingNetworkRequest(load_timing_info);
2003 class RevalidationServer {
2004 public:
2005 RevalidationServer() {
2006 s_etag_used_ = false;
2007 s_last_modified_used_ = false;
2010 bool EtagUsed() { return s_etag_used_; }
2011 bool LastModifiedUsed() { return s_last_modified_used_; }
2013 static void Handler(const HttpRequestInfo* request,
2014 std::string* response_status,
2015 std::string* response_headers,
2016 std::string* response_data);
2018 private:
2019 static bool s_etag_used_;
2020 static bool s_last_modified_used_;
2022 bool RevalidationServer::s_etag_used_ = false;
2023 bool RevalidationServer::s_last_modified_used_ = false;
2025 void RevalidationServer::Handler(const HttpRequestInfo* request,
2026 std::string* response_status,
2027 std::string* response_headers,
2028 std::string* response_data) {
2029 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch))
2030 s_etag_used_ = true;
2032 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfModifiedSince)) {
2033 s_last_modified_used_ = true;
2036 if (s_etag_used_ || s_last_modified_used_) {
2037 response_status->assign("HTTP/1.1 304 Not Modified");
2038 response_headers->assign(kTypicalGET_Transaction.response_headers);
2039 response_data->clear();
2040 } else {
2041 response_status->assign(kTypicalGET_Transaction.status);
2042 response_headers->assign(kTypicalGET_Transaction.response_headers);
2043 response_data->assign(kTypicalGET_Transaction.data);
2047 // Tests revalidation after a vary match.
2048 TEST(HttpCache, GET_ValidateCache_VaryMatch) {
2049 MockHttpCache cache;
2051 // Write to the cache.
2052 MockTransaction transaction(kTypicalGET_Transaction);
2053 transaction.request_headers = "Foo: bar\r\n";
2054 transaction.response_headers =
2055 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2056 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2057 "Etag: \"foopy\"\n"
2058 "Cache-Control: max-age=0\n"
2059 "Vary: Foo\n";
2060 AddMockTransaction(&transaction);
2061 RunTransactionTest(cache.http_cache(), transaction);
2063 // Read from the cache.
2064 RevalidationServer server;
2065 transaction.handler = server.Handler;
2066 BoundTestNetLog log;
2067 LoadTimingInfo load_timing_info;
2068 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2069 &load_timing_info);
2071 EXPECT_TRUE(server.EtagUsed());
2072 EXPECT_TRUE(server.LastModifiedUsed());
2073 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2074 EXPECT_EQ(1, cache.disk_cache()->open_count());
2075 EXPECT_EQ(1, cache.disk_cache()->create_count());
2076 TestLoadTimingNetworkRequest(load_timing_info);
2077 RemoveMockTransaction(&transaction);
2080 // Tests revalidation after a vary mismatch if etag is present.
2081 TEST(HttpCache, GET_ValidateCache_VaryMismatch) {
2082 MockHttpCache cache;
2084 // Write to the cache.
2085 MockTransaction transaction(kTypicalGET_Transaction);
2086 transaction.request_headers = "Foo: bar\r\n";
2087 transaction.response_headers =
2088 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2089 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2090 "Etag: \"foopy\"\n"
2091 "Cache-Control: max-age=0\n"
2092 "Vary: Foo\n";
2093 AddMockTransaction(&transaction);
2094 RunTransactionTest(cache.http_cache(), transaction);
2096 // Read from the cache and revalidate the entry.
2097 RevalidationServer server;
2098 transaction.handler = server.Handler;
2099 transaction.request_headers = "Foo: none\r\n";
2100 BoundTestNetLog log;
2101 LoadTimingInfo load_timing_info;
2102 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2103 &load_timing_info);
2105 EXPECT_TRUE(server.EtagUsed());
2106 EXPECT_FALSE(server.LastModifiedUsed());
2107 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2108 EXPECT_EQ(1, cache.disk_cache()->open_count());
2109 EXPECT_EQ(1, cache.disk_cache()->create_count());
2110 TestLoadTimingNetworkRequest(load_timing_info);
2111 RemoveMockTransaction(&transaction);
2114 // Tests lack of revalidation after a vary mismatch and no etag.
2115 TEST(HttpCache, GET_DontValidateCache_VaryMismatch) {
2116 MockHttpCache cache;
2118 // Write to the cache.
2119 MockTransaction transaction(kTypicalGET_Transaction);
2120 transaction.request_headers = "Foo: bar\r\n";
2121 transaction.response_headers =
2122 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2123 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2124 "Cache-Control: max-age=0\n"
2125 "Vary: Foo\n";
2126 AddMockTransaction(&transaction);
2127 RunTransactionTest(cache.http_cache(), transaction);
2129 // Read from the cache and don't revalidate the entry.
2130 RevalidationServer server;
2131 transaction.handler = server.Handler;
2132 transaction.request_headers = "Foo: none\r\n";
2133 BoundTestNetLog log;
2134 LoadTimingInfo load_timing_info;
2135 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2136 &load_timing_info);
2138 EXPECT_FALSE(server.EtagUsed());
2139 EXPECT_FALSE(server.LastModifiedUsed());
2140 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2141 EXPECT_EQ(1, cache.disk_cache()->open_count());
2142 EXPECT_EQ(1, cache.disk_cache()->create_count());
2143 TestLoadTimingNetworkRequest(load_timing_info);
2144 RemoveMockTransaction(&transaction);
2147 // Tests that a new vary header provided when revalidating an entry is saved.
2148 TEST(HttpCache, GET_ValidateCache_VaryMatch_UpdateVary) {
2149 MockHttpCache cache;
2151 // Write to the cache.
2152 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2153 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2154 transaction.response_headers =
2155 "Etag: \"foopy\"\n"
2156 "Cache-Control: max-age=0\n"
2157 "Vary: Foo\n";
2158 RunTransactionTest(cache.http_cache(), transaction);
2160 // Validate the entry and change the vary field in the response.
2161 transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
2162 transaction.status = "HTTP/1.1 304 Not Modified";
2163 transaction.response_headers =
2164 "Etag: \"foopy\"\n"
2165 "Cache-Control: max-age=3600\n"
2166 "Vary: Name\n";
2167 RunTransactionTest(cache.http_cache(), transaction);
2169 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2170 EXPECT_EQ(1, cache.disk_cache()->open_count());
2171 EXPECT_EQ(1, cache.disk_cache()->create_count());
2173 // Make sure that the ActiveEntry is gone.
2174 base::RunLoop().RunUntilIdle();
2176 // Generate a vary mismatch.
2177 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2178 RunTransactionTest(cache.http_cache(), transaction);
2180 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2181 EXPECT_EQ(2, cache.disk_cache()->open_count());
2182 EXPECT_EQ(1, cache.disk_cache()->create_count());
2185 // Tests that new request headers causing a vary mismatch are paired with the
2186 // new response when the server says the old response can be used.
2187 TEST(HttpCache, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
2188 MockHttpCache cache;
2190 // Write to the cache.
2191 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2192 transaction.request_headers = "Foo: bar\r\n";
2193 transaction.response_headers =
2194 "Etag: \"foopy\"\n"
2195 "Cache-Control: max-age=3600\n"
2196 "Vary: Foo\n";
2197 RunTransactionTest(cache.http_cache(), transaction);
2199 // Vary-mismatch validation receives 304.
2200 transaction.request_headers = "Foo: none\r\n";
2201 transaction.status = "HTTP/1.1 304 Not Modified";
2202 RunTransactionTest(cache.http_cache(), transaction);
2204 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2205 EXPECT_EQ(1, cache.disk_cache()->open_count());
2206 EXPECT_EQ(1, cache.disk_cache()->create_count());
2208 // Make sure that the ActiveEntry is gone.
2209 base::RunLoop().RunUntilIdle();
2211 // Generate a vary mismatch.
2212 transaction.request_headers = "Foo: bar\r\n";
2213 RunTransactionTest(cache.http_cache(), transaction);
2215 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2216 EXPECT_EQ(2, cache.disk_cache()->open_count());
2217 EXPECT_EQ(1, cache.disk_cache()->create_count());
2220 // Tests that a 304 without vary headers doesn't delete the previously stored
2221 // vary data after a vary match revalidation.
2222 TEST(HttpCache, GET_ValidateCache_VaryMatch_DontDeleteVary) {
2223 MockHttpCache cache;
2225 // Write to the cache.
2226 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2227 transaction.request_headers = "Foo: bar\r\n";
2228 transaction.response_headers =
2229 "Etag: \"foopy\"\n"
2230 "Cache-Control: max-age=0\n"
2231 "Vary: Foo\n";
2232 RunTransactionTest(cache.http_cache(), transaction);
2234 // Validate the entry and remove the vary field in the response.
2235 transaction.status = "HTTP/1.1 304 Not Modified";
2236 transaction.response_headers =
2237 "Etag: \"foopy\"\n"
2238 "Cache-Control: max-age=3600\n";
2239 RunTransactionTest(cache.http_cache(), transaction);
2241 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2242 EXPECT_EQ(1, cache.disk_cache()->open_count());
2243 EXPECT_EQ(1, cache.disk_cache()->create_count());
2245 // Make sure that the ActiveEntry is gone.
2246 base::RunLoop().RunUntilIdle();
2248 // Generate a vary mismatch.
2249 transaction.request_headers = "Foo: none\r\n";
2250 RunTransactionTest(cache.http_cache(), transaction);
2252 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2253 EXPECT_EQ(2, cache.disk_cache()->open_count());
2254 EXPECT_EQ(1, cache.disk_cache()->create_count());
2257 // Tests that a 304 without vary headers doesn't delete the previously stored
2258 // vary data after a vary mismatch.
2259 TEST(HttpCache, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
2260 MockHttpCache cache;
2262 // Write to the cache.
2263 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2264 transaction.request_headers = "Foo: bar\r\n";
2265 transaction.response_headers =
2266 "Etag: \"foopy\"\n"
2267 "Cache-Control: max-age=3600\n"
2268 "Vary: Foo\n";
2269 RunTransactionTest(cache.http_cache(), transaction);
2271 // Vary-mismatch validation receives 304 and no vary header.
2272 transaction.request_headers = "Foo: none\r\n";
2273 transaction.status = "HTTP/1.1 304 Not Modified";
2274 transaction.response_headers =
2275 "Etag: \"foopy\"\n"
2276 "Cache-Control: max-age=3600\n";
2277 RunTransactionTest(cache.http_cache(), transaction);
2279 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2280 EXPECT_EQ(1, cache.disk_cache()->open_count());
2281 EXPECT_EQ(1, cache.disk_cache()->create_count());
2283 // Make sure that the ActiveEntry is gone.
2284 base::RunLoop().RunUntilIdle();
2286 // Generate a vary mismatch.
2287 transaction.request_headers = "Foo: bar\r\n";
2288 RunTransactionTest(cache.http_cache(), transaction);
2290 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2291 EXPECT_EQ(2, cache.disk_cache()->open_count());
2292 EXPECT_EQ(1, cache.disk_cache()->create_count());
2295 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
2296 std::string* response_status,
2297 std::string* response_headers,
2298 std::string* response_data) {
2299 EXPECT_FALSE(
2300 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
2303 TEST(HttpCache, ETagGET_Http10) {
2304 MockHttpCache cache;
2306 ScopedMockTransaction transaction(kETagGET_Transaction);
2307 transaction.status = "HTTP/1.0 200 OK";
2309 // Write to the cache.
2310 RunTransactionTest(cache.http_cache(), transaction);
2312 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2313 EXPECT_EQ(0, cache.disk_cache()->open_count());
2314 EXPECT_EQ(1, cache.disk_cache()->create_count());
2316 // Get the same URL again, without generating a conditional request.
2317 transaction.load_flags = LOAD_VALIDATE_CACHE;
2318 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2319 RunTransactionTest(cache.http_cache(), transaction);
2321 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2322 EXPECT_EQ(1, cache.disk_cache()->open_count());
2323 EXPECT_EQ(1, cache.disk_cache()->create_count());
2326 TEST(HttpCache, ETagGET_Http10_Range) {
2327 MockHttpCache cache;
2329 ScopedMockTransaction transaction(kETagGET_Transaction);
2330 transaction.status = "HTTP/1.0 200 OK";
2332 // Write to the cache.
2333 RunTransactionTest(cache.http_cache(), transaction);
2335 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2336 EXPECT_EQ(0, cache.disk_cache()->open_count());
2337 EXPECT_EQ(1, cache.disk_cache()->create_count());
2339 // Get the same URL again, but use a byte range request.
2340 transaction.load_flags = LOAD_VALIDATE_CACHE;
2341 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2342 transaction.request_headers = "Range: bytes = 5-\r\n";
2343 RunTransactionTest(cache.http_cache(), transaction);
2345 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2346 EXPECT_EQ(1, cache.disk_cache()->open_count());
2347 EXPECT_EQ(2, cache.disk_cache()->create_count());
2350 static void ETagGet_ConditionalRequest_NoStore_Handler(
2351 const HttpRequestInfo* request,
2352 std::string* response_status,
2353 std::string* response_headers,
2354 std::string* response_data) {
2355 EXPECT_TRUE(
2356 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
2357 response_status->assign("HTTP/1.1 304 Not Modified");
2358 response_headers->assign("Cache-Control: no-store\n");
2359 response_data->clear();
2362 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2363 MockHttpCache cache;
2365 ScopedMockTransaction transaction(kETagGET_Transaction);
2367 // Write to the cache.
2368 RunTransactionTest(cache.http_cache(), transaction);
2370 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2371 EXPECT_EQ(0, cache.disk_cache()->open_count());
2372 EXPECT_EQ(1, cache.disk_cache()->create_count());
2374 // Get the same URL again, but this time we expect it to result
2375 // in a conditional request.
2376 transaction.load_flags = LOAD_VALIDATE_CACHE;
2377 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2378 RunTransactionTest(cache.http_cache(), transaction);
2380 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2381 EXPECT_EQ(1, cache.disk_cache()->open_count());
2382 EXPECT_EQ(1, cache.disk_cache()->create_count());
2384 ScopedMockTransaction transaction2(kETagGET_Transaction);
2386 // Write to the cache again. This should create a new entry.
2387 RunTransactionTest(cache.http_cache(), transaction2);
2389 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2390 EXPECT_EQ(1, cache.disk_cache()->open_count());
2391 EXPECT_EQ(2, cache.disk_cache()->create_count());
2394 // Helper that does 4 requests using HttpCache:
2396 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2397 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2398 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2399 // be returned.
2400 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2401 // returned.
2402 static void ConditionalizedRequestUpdatesCacheHelper(
2403 const Response& net_response_1,
2404 const Response& net_response_2,
2405 const Response& cached_response_2,
2406 const char* extra_request_headers) {
2407 MockHttpCache cache;
2409 // The URL we will be requesting.
2410 const char kUrl[] = "http://foobar.com/main.css";
2412 // Junk network response.
2413 static const Response kUnexpectedResponse = {
2414 "HTTP/1.1 500 Unexpected",
2415 "Server: unexpected_header",
2416 "unexpected body"
2419 // We will control the network layer's responses for |kUrl| using
2420 // |mock_network_response|.
2421 MockTransaction mock_network_response = { 0 };
2422 mock_network_response.url = kUrl;
2423 AddMockTransaction(&mock_network_response);
2425 // Request |kUrl| for the first time. It should hit the network and
2426 // receive |kNetResponse1|, which it saves into the HTTP cache.
2428 MockTransaction request = { 0 };
2429 request.url = kUrl;
2430 request.method = "GET";
2431 request.request_headers = "";
2433 net_response_1.AssignTo(&mock_network_response); // Network mock.
2434 net_response_1.AssignTo(&request); // Expected result.
2436 std::string response_headers;
2437 RunTransactionTestWithResponse(
2438 cache.http_cache(), request, &response_headers);
2440 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2441 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2442 EXPECT_EQ(0, cache.disk_cache()->open_count());
2443 EXPECT_EQ(1, cache.disk_cache()->create_count());
2445 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2446 // cache, so we don't hit the network.
2448 request.load_flags = LOAD_ONLY_FROM_CACHE;
2450 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2451 net_response_1.AssignTo(&request); // Expected result.
2453 RunTransactionTestWithResponse(
2454 cache.http_cache(), request, &response_headers);
2456 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2457 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2458 EXPECT_EQ(1, cache.disk_cache()->open_count());
2459 EXPECT_EQ(1, cache.disk_cache()->create_count());
2461 // Request |kUrl| yet again, but this time give the request an
2462 // "If-Modified-Since" header. This will cause the request to re-hit the
2463 // network. However now the network response is going to be
2464 // different -- this simulates a change made to the CSS file.
2466 request.request_headers = extra_request_headers;
2467 request.load_flags = LOAD_NORMAL;
2469 net_response_2.AssignTo(&mock_network_response); // Network mock.
2470 net_response_2.AssignTo(&request); // Expected result.
2472 RunTransactionTestWithResponse(
2473 cache.http_cache(), request, &response_headers);
2475 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2476 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2477 EXPECT_EQ(1, cache.disk_cache()->open_count());
2478 EXPECT_EQ(1, cache.disk_cache()->create_count());
2480 // Finally, request |kUrl| again. This request should be serviced from
2481 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2482 // and NOT |kNetResponse1|. The previous step should have replaced the
2483 // value in the cache with the modified response.
2485 request.request_headers = "";
2486 request.load_flags = LOAD_ONLY_FROM_CACHE;
2488 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
2489 cached_response_2.AssignTo(&request); // Expected result.
2491 RunTransactionTestWithResponse(
2492 cache.http_cache(), request, &response_headers);
2494 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2495 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2496 EXPECT_EQ(2, cache.disk_cache()->open_count());
2497 EXPECT_EQ(1, cache.disk_cache()->create_count());
2499 RemoveMockTransaction(&mock_network_response);
2502 // Check that when an "if-modified-since" header is attached
2503 // to the request, the result still updates the cached entry.
2504 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2505 // First network response for |kUrl|.
2506 static const Response kNetResponse1 = {
2507 "HTTP/1.1 200 OK",
2508 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2509 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2510 "body1"
2513 // Second network response for |kUrl|.
2514 static const Response kNetResponse2 = {
2515 "HTTP/1.1 200 OK",
2516 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2517 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2518 "body2"
2521 const char extra_headers[] =
2522 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2524 ConditionalizedRequestUpdatesCacheHelper(
2525 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2528 // Check that when an "if-none-match" header is attached
2529 // to the request, the result updates the cached entry.
2530 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2531 // First network response for |kUrl|.
2532 static const Response kNetResponse1 = {
2533 "HTTP/1.1 200 OK",
2534 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2535 "Etag: \"ETAG1\"\n"
2536 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2537 "body1"
2540 // Second network response for |kUrl|.
2541 static const Response kNetResponse2 = {
2542 "HTTP/1.1 200 OK",
2543 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2544 "Etag: \"ETAG2\"\n"
2545 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2546 "body2"
2549 const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
2551 ConditionalizedRequestUpdatesCacheHelper(
2552 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2555 // Check that when an "if-modified-since" header is attached
2556 // to a request, the 304 (not modified result) result updates the cached
2557 // headers, and the 304 response is returned rather than the cached response.
2558 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2559 // First network response for |kUrl|.
2560 static const Response kNetResponse1 = {
2561 "HTTP/1.1 200 OK",
2562 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2563 "Server: server1\n"
2564 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2565 "body1"
2568 // Second network response for |kUrl|.
2569 static const Response kNetResponse2 = {
2570 "HTTP/1.1 304 Not Modified",
2571 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2572 "Server: server2\n"
2573 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2577 static const Response kCachedResponse2 = {
2578 "HTTP/1.1 200 OK",
2579 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2580 "Server: server2\n"
2581 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2582 "body1"
2585 const char extra_headers[] =
2586 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2588 ConditionalizedRequestUpdatesCacheHelper(
2589 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2592 // Test that when doing an externally conditionalized if-modified-since
2593 // and there is no corresponding cache entry, a new cache entry is NOT
2594 // created (304 response).
2595 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2596 MockHttpCache cache;
2598 const char kUrl[] = "http://foobar.com/main.css";
2600 static const Response kNetResponse = {
2601 "HTTP/1.1 304 Not Modified",
2602 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2603 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2607 const char kExtraRequestHeaders[] =
2608 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2610 // We will control the network layer's responses for |kUrl| using
2611 // |mock_network_response|.
2612 MockTransaction mock_network_response = { 0 };
2613 mock_network_response.url = kUrl;
2614 AddMockTransaction(&mock_network_response);
2616 MockTransaction request = { 0 };
2617 request.url = kUrl;
2618 request.method = "GET";
2619 request.request_headers = kExtraRequestHeaders;
2621 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2622 kNetResponse.AssignTo(&request); // Expected result.
2624 std::string response_headers;
2625 RunTransactionTestWithResponse(
2626 cache.http_cache(), request, &response_headers);
2628 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2629 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2630 EXPECT_EQ(0, cache.disk_cache()->open_count());
2631 EXPECT_EQ(0, cache.disk_cache()->create_count());
2633 RemoveMockTransaction(&mock_network_response);
2636 // Test that when doing an externally conditionalized if-modified-since
2637 // and there is no corresponding cache entry, a new cache entry is NOT
2638 // created (200 response).
2639 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2640 MockHttpCache cache;
2642 const char kUrl[] = "http://foobar.com/main.css";
2644 static const Response kNetResponse = {
2645 "HTTP/1.1 200 OK",
2646 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2647 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2648 "foobar!!!"
2651 const char kExtraRequestHeaders[] =
2652 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2654 // We will control the network layer's responses for |kUrl| using
2655 // |mock_network_response|.
2656 MockTransaction mock_network_response = { 0 };
2657 mock_network_response.url = kUrl;
2658 AddMockTransaction(&mock_network_response);
2660 MockTransaction request = { 0 };
2661 request.url = kUrl;
2662 request.method = "GET";
2663 request.request_headers = kExtraRequestHeaders;
2665 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2666 kNetResponse.AssignTo(&request); // Expected result.
2668 std::string response_headers;
2669 RunTransactionTestWithResponse(
2670 cache.http_cache(), request, &response_headers);
2672 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2673 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2674 EXPECT_EQ(0, cache.disk_cache()->open_count());
2675 EXPECT_EQ(0, cache.disk_cache()->create_count());
2677 RemoveMockTransaction(&mock_network_response);
2680 // Test that when doing an externally conditionalized if-modified-since
2681 // if the date does not match the cache entry's last-modified date,
2682 // then we do NOT use the response (304) to update the cache.
2683 // (the if-modified-since date is 2 days AFTER the cache's modification date).
2684 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2685 static const Response kNetResponse1 = {
2686 "HTTP/1.1 200 OK",
2687 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2688 "Server: server1\n"
2689 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2690 "body1"
2693 // Second network response for |kUrl|.
2694 static const Response kNetResponse2 = {
2695 "HTTP/1.1 304 Not Modified",
2696 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2697 "Server: server2\n"
2698 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2702 // This is two days in the future from the original response's last-modified
2703 // date!
2704 const char kExtraRequestHeaders[] =
2705 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2707 ConditionalizedRequestUpdatesCacheHelper(
2708 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2711 // Test that when doing an externally conditionalized if-none-match
2712 // if the etag does not match the cache entry's etag, then we do not use the
2713 // response (304) to update the cache.
2714 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2715 static const Response kNetResponse1 = {
2716 "HTTP/1.1 200 OK",
2717 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2718 "Etag: \"Foo1\"\n"
2719 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2720 "body1"
2723 // Second network response for |kUrl|.
2724 static const Response kNetResponse2 = {
2725 "HTTP/1.1 304 Not Modified",
2726 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2727 "Etag: \"Foo2\"\n"
2728 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2732 // Different etag from original response.
2733 const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
2735 ConditionalizedRequestUpdatesCacheHelper(
2736 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2739 // Test that doing an externally conditionalized request with both if-none-match
2740 // and if-modified-since updates the cache.
2741 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2742 static const Response kNetResponse1 = {
2743 "HTTP/1.1 200 OK",
2744 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2745 "Etag: \"Foo1\"\n"
2746 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2747 "body1"
2750 // Second network response for |kUrl|.
2751 static const Response kNetResponse2 = {
2752 "HTTP/1.1 200 OK",
2753 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2754 "Etag: \"Foo2\"\n"
2755 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2756 "body2"
2759 const char kExtraRequestHeaders[] =
2760 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2761 "If-None-Match: \"Foo1\"\r\n";
2763 ConditionalizedRequestUpdatesCacheHelper(
2764 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2767 // Test that doing an externally conditionalized request with both if-none-match
2768 // and if-modified-since does not update the cache with only one match.
2769 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2770 static const Response kNetResponse1 = {
2771 "HTTP/1.1 200 OK",
2772 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2773 "Etag: \"Foo1\"\n"
2774 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2775 "body1"
2778 // Second network response for |kUrl|.
2779 static const Response kNetResponse2 = {
2780 "HTTP/1.1 200 OK",
2781 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2782 "Etag: \"Foo2\"\n"
2783 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2784 "body2"
2787 // The etag doesn't match what we have stored.
2788 const char kExtraRequestHeaders[] =
2789 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2790 "If-None-Match: \"Foo2\"\r\n";
2792 ConditionalizedRequestUpdatesCacheHelper(
2793 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2796 // Test that doing an externally conditionalized request with both if-none-match
2797 // and if-modified-since does not update the cache with only one match.
2798 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2799 static const Response kNetResponse1 = {
2800 "HTTP/1.1 200 OK",
2801 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2802 "Etag: \"Foo1\"\n"
2803 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2804 "body1"
2807 // Second network response for |kUrl|.
2808 static const Response kNetResponse2 = {
2809 "HTTP/1.1 200 OK",
2810 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2811 "Etag: \"Foo2\"\n"
2812 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2813 "body2"
2816 // The modification date doesn't match what we have stored.
2817 const char kExtraRequestHeaders[] =
2818 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2819 "If-None-Match: \"Foo1\"\r\n";
2821 ConditionalizedRequestUpdatesCacheHelper(
2822 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2825 TEST(HttpCache, UrlContainingHash) {
2826 MockHttpCache cache;
2828 // Do a typical GET request -- should write an entry into our cache.
2829 MockTransaction trans(kTypicalGET_Transaction);
2830 RunTransactionTest(cache.http_cache(), trans);
2832 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2833 EXPECT_EQ(0, cache.disk_cache()->open_count());
2834 EXPECT_EQ(1, cache.disk_cache()->create_count());
2836 // Request the same URL, but this time with a reference section (hash).
2837 // Since the cache key strips the hash sections, this should be a cache hit.
2838 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2839 trans.url = url_with_hash.c_str();
2840 trans.load_flags = LOAD_ONLY_FROM_CACHE;
2842 RunTransactionTest(cache.http_cache(), trans);
2844 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2845 EXPECT_EQ(1, cache.disk_cache()->open_count());
2846 EXPECT_EQ(1, cache.disk_cache()->create_count());
2849 // Tests that we skip the cache for POST requests that do not have an upload
2850 // identifier.
2851 TEST(HttpCache, SimplePOST_SkipsCache) {
2852 MockHttpCache cache;
2854 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2856 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2857 EXPECT_EQ(0, cache.disk_cache()->open_count());
2858 EXPECT_EQ(0, cache.disk_cache()->create_count());
2861 // Tests POST handling with a disabled cache (no DCHECK).
2862 TEST(HttpCache, SimplePOST_DisabledCache) {
2863 MockHttpCache cache;
2864 cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
2866 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2868 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2869 EXPECT_EQ(0, cache.disk_cache()->open_count());
2870 EXPECT_EQ(0, cache.disk_cache()->create_count());
2873 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2874 MockHttpCache cache;
2876 MockTransaction transaction(kSimplePOST_Transaction);
2877 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
2879 MockHttpRequest request(transaction);
2880 TestCompletionCallback callback;
2882 scoped_ptr<HttpTransaction> trans;
2883 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
2884 ASSERT_TRUE(trans.get());
2886 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2887 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
2889 trans.reset();
2891 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2892 EXPECT_EQ(0, cache.disk_cache()->open_count());
2893 EXPECT_EQ(0, cache.disk_cache()->create_count());
2896 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2897 MockHttpCache cache;
2899 // Test that we hit the cache for POST requests.
2901 MockTransaction transaction(kSimplePOST_Transaction);
2903 const int64 kUploadId = 1; // Just a dummy value.
2905 ScopedVector<UploadElementReader> element_readers;
2906 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2907 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2908 kUploadId);
2909 MockHttpRequest request(transaction);
2910 request.upload_data_stream = &upload_data_stream;
2912 // Populate the cache.
2913 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2915 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2916 EXPECT_EQ(0, cache.disk_cache()->open_count());
2917 EXPECT_EQ(1, cache.disk_cache()->create_count());
2919 // Load from cache.
2920 request.load_flags |= LOAD_ONLY_FROM_CACHE;
2921 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2923 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2924 EXPECT_EQ(1, cache.disk_cache()->open_count());
2925 EXPECT_EQ(1, cache.disk_cache()->create_count());
2928 // Test that we don't hit the cache for POST requests if there is a byte range.
2929 TEST(HttpCache, SimplePOST_WithRanges) {
2930 MockHttpCache cache;
2932 MockTransaction transaction(kSimplePOST_Transaction);
2933 transaction.request_headers = "Range: bytes = 0-4\r\n";
2935 const int64 kUploadId = 1; // Just a dummy value.
2937 ScopedVector<UploadElementReader> element_readers;
2938 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2939 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2940 kUploadId);
2942 MockHttpRequest request(transaction);
2943 request.upload_data_stream = &upload_data_stream;
2945 // Attempt to populate the cache.
2946 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2948 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2949 EXPECT_EQ(0, cache.disk_cache()->open_count());
2950 EXPECT_EQ(0, cache.disk_cache()->create_count());
2953 // Tests that a POST is cached separately from a previously cached GET.
2954 TEST(HttpCache, SimplePOST_SeparateCache) {
2955 MockHttpCache cache;
2957 ScopedVector<UploadElementReader> element_readers;
2958 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2959 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
2961 MockTransaction transaction(kSimplePOST_Transaction);
2962 MockHttpRequest req1(transaction);
2963 req1.upload_data_stream = &upload_data_stream;
2965 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2967 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2968 EXPECT_EQ(0, cache.disk_cache()->open_count());
2969 EXPECT_EQ(1, cache.disk_cache()->create_count());
2971 transaction.method = "GET";
2972 MockHttpRequest req2(transaction);
2974 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2976 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2977 EXPECT_EQ(0, cache.disk_cache()->open_count());
2978 EXPECT_EQ(2, cache.disk_cache()->create_count());
2981 // Tests that a successful POST invalidates a previously cached GET.
2982 TEST(HttpCache, SimplePOST_Invalidate_205) {
2983 MockHttpCache cache;
2985 MockTransaction transaction(kSimpleGET_Transaction);
2986 AddMockTransaction(&transaction);
2987 MockHttpRequest req1(transaction);
2989 // Attempt to populate the cache.
2990 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2992 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2993 EXPECT_EQ(0, cache.disk_cache()->open_count());
2994 EXPECT_EQ(1, cache.disk_cache()->create_count());
2996 ScopedVector<UploadElementReader> element_readers;
2997 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2998 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
3000 transaction.method = "POST";
3001 transaction.status = "HTTP/1.1 205 No Content";
3002 MockHttpRequest req2(transaction);
3003 req2.upload_data_stream = &upload_data_stream;
3005 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3007 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3008 EXPECT_EQ(0, cache.disk_cache()->open_count());
3009 EXPECT_EQ(2, cache.disk_cache()->create_count());
3011 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3013 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3014 EXPECT_EQ(0, cache.disk_cache()->open_count());
3015 EXPECT_EQ(3, cache.disk_cache()->create_count());
3016 RemoveMockTransaction(&transaction);
3019 // Tests that a successful POST invalidates a previously cached GET, even when
3020 // there is no upload identifier.
3021 TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
3022 MockHttpCache cache;
3024 MockTransaction transaction(kSimpleGET_Transaction);
3025 AddMockTransaction(&transaction);
3026 MockHttpRequest req1(transaction);
3028 // Attempt to populate the cache.
3029 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3031 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3032 EXPECT_EQ(0, cache.disk_cache()->open_count());
3033 EXPECT_EQ(1, cache.disk_cache()->create_count());
3035 ScopedVector<UploadElementReader> element_readers;
3036 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3037 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3039 transaction.method = "POST";
3040 transaction.status = "HTTP/1.1 205 No Content";
3041 MockHttpRequest req2(transaction);
3042 req2.upload_data_stream = &upload_data_stream;
3044 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3046 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3047 EXPECT_EQ(0, cache.disk_cache()->open_count());
3048 EXPECT_EQ(1, cache.disk_cache()->create_count());
3050 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3052 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3053 EXPECT_EQ(0, cache.disk_cache()->open_count());
3054 EXPECT_EQ(2, cache.disk_cache()->create_count());
3055 RemoveMockTransaction(&transaction);
3058 // Tests that processing a POST before creating the backend doesn't crash.
3059 TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
3060 // This will initialize a cache object with NULL backend.
3061 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
3062 factory->set_fail(true);
3063 factory->FinishCreation();
3064 MockHttpCache cache(factory);
3066 ScopedVector<UploadElementReader> element_readers;
3067 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3068 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3070 MockTransaction transaction(kSimplePOST_Transaction);
3071 AddMockTransaction(&transaction);
3072 MockHttpRequest req(transaction);
3073 req.upload_data_stream = &upload_data_stream;
3075 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
3077 RemoveMockTransaction(&transaction);
3080 // Tests that we don't invalidate entries as a result of a failed POST.
3081 TEST(HttpCache, SimplePOST_DontInvalidate_100) {
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<UploadElementReader> element_readers;
3096 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3097 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
3099 transaction.method = "POST";
3100 transaction.status = "HTTP/1.1 100 Continue";
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(0, cache.disk_cache()->open_count());
3108 EXPECT_EQ(2, 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(1, cache.disk_cache()->open_count());
3114 EXPECT_EQ(2, cache.disk_cache()->create_count());
3115 RemoveMockTransaction(&transaction);
3118 // Tests that a HEAD request is not cached by itself.
3119 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
3120 MockHttpCache cache;
3121 MockTransaction transaction(kSimplePOST_Transaction);
3122 AddMockTransaction(&transaction);
3123 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3124 transaction.method = "HEAD";
3126 MockHttpRequest request(transaction);
3127 TestCompletionCallback callback;
3129 scoped_ptr<HttpTransaction> trans;
3130 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
3131 ASSERT_TRUE(trans.get());
3133 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3134 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
3136 trans.reset();
3138 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3139 EXPECT_EQ(0, cache.disk_cache()->open_count());
3140 EXPECT_EQ(0, cache.disk_cache()->create_count());
3141 RemoveMockTransaction(&transaction);
3144 // Tests that a HEAD request is served from a cached GET.
3145 TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3146 MockHttpCache cache;
3147 MockTransaction transaction(kSimpleGET_Transaction);
3148 AddMockTransaction(&transaction);
3150 // Populate the cache.
3151 RunTransactionTest(cache.http_cache(), transaction);
3153 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3154 EXPECT_EQ(0, cache.disk_cache()->open_count());
3155 EXPECT_EQ(1, cache.disk_cache()->create_count());
3157 // Load from cache.
3158 transaction.method = "HEAD";
3159 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3160 transaction.data = "";
3161 RunTransactionTest(cache.http_cache(), transaction);
3163 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3164 EXPECT_EQ(1, cache.disk_cache()->open_count());
3165 EXPECT_EQ(1, cache.disk_cache()->create_count());
3166 RemoveMockTransaction(&transaction);
3169 // Tests that a read-only request served from the cache preserves CL.
3170 TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3171 MockHttpCache cache;
3172 MockTransaction transaction(kSimpleGET_Transaction);
3173 AddMockTransaction(&transaction);
3174 transaction.response_headers = "Content-Length: 42\n";
3176 // Populate the cache.
3177 RunTransactionTest(cache.http_cache(), transaction);
3179 // Load from cache.
3180 transaction.method = "HEAD";
3181 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3182 transaction.data = "";
3183 std::string headers;
3185 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3187 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3188 RemoveMockTransaction(&transaction);
3191 // Tests that a read-write request served from the cache preserves CL.
3192 TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3193 MockHttpCache cache;
3194 MockTransaction transaction(kETagGET_Transaction);
3195 AddMockTransaction(&transaction);
3196 std::string server_headers(kETagGET_Transaction.response_headers);
3197 server_headers.append("Content-Length: 42\n");
3198 transaction.response_headers = server_headers.data();
3200 // Populate the cache.
3201 RunTransactionTest(cache.http_cache(), transaction);
3203 // Load from cache.
3204 transaction.method = "HEAD";
3205 transaction.data = "";
3206 std::string headers;
3208 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3210 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3211 RemoveMockTransaction(&transaction);
3214 // Tests that a HEAD request that includes byte ranges bypasses the cache.
3215 TEST(HttpCache, SimpleHEAD_WithRanges) {
3216 MockHttpCache cache;
3217 MockTransaction transaction(kSimpleGET_Transaction);
3218 AddMockTransaction(&transaction);
3220 // Populate the cache.
3221 RunTransactionTest(cache.http_cache(), transaction);
3223 // Load from cache.
3224 transaction.method = "HEAD";
3225 transaction.request_headers = "Range: bytes = 0-4\r\n";
3226 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3227 transaction.return_code = ERR_CACHE_MISS;
3228 RunTransactionTest(cache.http_cache(), transaction);
3230 EXPECT_EQ(0, cache.disk_cache()->open_count());
3231 EXPECT_EQ(1, cache.disk_cache()->create_count());
3232 RemoveMockTransaction(&transaction);
3235 // Tests that a HEAD request can be served from a partialy cached resource.
3236 TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3237 MockHttpCache cache;
3238 AddMockTransaction(&kRangeGET_TransactionOK);
3240 // Write to the cache (40-49).
3241 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3242 RemoveMockTransaction(&kRangeGET_TransactionOK);
3244 MockTransaction transaction(kSimpleGET_Transaction);
3246 transaction.url = kRangeGET_TransactionOK.url;
3247 transaction.method = "HEAD";
3248 transaction.data = "";
3249 AddMockTransaction(&transaction);
3250 std::string headers;
3252 // Load from cache.
3253 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3255 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3256 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3257 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3258 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3259 EXPECT_EQ(1, cache.disk_cache()->open_count());
3260 EXPECT_EQ(1, cache.disk_cache()->create_count());
3261 RemoveMockTransaction(&transaction);
3264 // Tests that a HEAD request can be served from a truncated resource.
3265 TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3266 MockHttpCache cache;
3267 AddMockTransaction(&kRangeGET_TransactionOK);
3269 std::string raw_headers("HTTP/1.1 200 OK\n"
3270 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3271 "ETag: \"foo\"\n"
3272 "Accept-Ranges: bytes\n"
3273 "Content-Length: 80\n");
3274 CreateTruncatedEntry(raw_headers, &cache);
3275 RemoveMockTransaction(&kRangeGET_TransactionOK);
3277 MockTransaction transaction(kSimpleGET_Transaction);
3279 transaction.url = kRangeGET_TransactionOK.url;
3280 transaction.method = "HEAD";
3281 transaction.data = "";
3282 AddMockTransaction(&transaction);
3283 std::string headers;
3285 // Load from cache.
3286 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3288 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3289 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3290 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3291 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3292 EXPECT_EQ(1, cache.disk_cache()->open_count());
3293 EXPECT_EQ(1, cache.disk_cache()->create_count());
3294 RemoveMockTransaction(&transaction);
3297 // Tests that a HEAD request updates the cached response.
3298 TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3299 MockHttpCache cache;
3300 MockTransaction transaction(kTypicalGET_Transaction);
3301 AddMockTransaction(&transaction);
3303 // Populate the cache.
3304 RunTransactionTest(cache.http_cache(), transaction);
3306 // Update the cache.
3307 transaction.method = "HEAD";
3308 transaction.response_headers = "Foo: bar\n";
3309 transaction.data = "";
3310 transaction.status = "HTTP/1.1 304 Not Modified\n";
3311 std::string headers;
3312 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3313 RemoveMockTransaction(&transaction);
3315 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3316 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3318 MockTransaction transaction2(kTypicalGET_Transaction);
3319 AddMockTransaction(&transaction2);
3321 // Make sure we are done with the previous transaction.
3322 base::MessageLoop::current()->RunUntilIdle();
3324 // Load from the cache.
3325 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
3326 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3328 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3329 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3330 EXPECT_EQ(2, cache.disk_cache()->open_count());
3331 EXPECT_EQ(1, cache.disk_cache()->create_count());
3332 RemoveMockTransaction(&transaction2);
3335 // Tests that an externally conditionalized HEAD request updates the cache.
3336 TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3337 MockHttpCache cache;
3338 MockTransaction transaction(kTypicalGET_Transaction);
3339 AddMockTransaction(&transaction);
3341 // Populate the cache.
3342 RunTransactionTest(cache.http_cache(), transaction);
3344 // Update the cache.
3345 transaction.method = "HEAD";
3346 transaction.request_headers =
3347 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3348 transaction.response_headers = "Foo: bar\n";
3349 transaction.data = "";
3350 transaction.status = "HTTP/1.1 304 Not Modified\n";
3351 std::string headers;
3352 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3353 RemoveMockTransaction(&transaction);
3355 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3356 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3358 MockTransaction transaction2(kTypicalGET_Transaction);
3359 AddMockTransaction(&transaction2);
3361 // Make sure we are done with the previous transaction.
3362 base::MessageLoop::current()->RunUntilIdle();
3364 // Load from the cache.
3365 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
3366 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3368 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3369 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3370 EXPECT_EQ(2, cache.disk_cache()->open_count());
3371 EXPECT_EQ(1, cache.disk_cache()->create_count());
3372 RemoveMockTransaction(&transaction2);
3375 // Tests that a HEAD request invalidates an old cached entry.
3376 TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3377 MockHttpCache cache;
3378 MockTransaction transaction(kTypicalGET_Transaction);
3379 AddMockTransaction(&transaction);
3381 // Populate the cache.
3382 RunTransactionTest(cache.http_cache(), transaction);
3384 // Update the cache.
3385 transaction.method = "HEAD";
3386 transaction.data = "";
3387 RunTransactionTest(cache.http_cache(), transaction);
3388 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3390 // Load from the cache.
3391 transaction.method = "GET";
3392 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3393 transaction.return_code = ERR_CACHE_MISS;
3394 RunTransactionTest(cache.http_cache(), transaction);
3396 RemoveMockTransaction(&transaction);
3399 // Tests that we do not cache the response of a PUT.
3400 TEST(HttpCache, SimplePUT_Miss) {
3401 MockHttpCache cache;
3403 MockTransaction transaction(kSimplePOST_Transaction);
3404 transaction.method = "PUT";
3406 ScopedVector<UploadElementReader> element_readers;
3407 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3408 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3410 MockHttpRequest request(transaction);
3411 request.upload_data_stream = &upload_data_stream;
3413 // Attempt to populate the cache.
3414 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3416 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3417 EXPECT_EQ(0, cache.disk_cache()->open_count());
3418 EXPECT_EQ(0, cache.disk_cache()->create_count());
3421 // Tests that we invalidate entries as a result of a PUT.
3422 TEST(HttpCache, SimplePUT_Invalidate) {
3423 MockHttpCache cache;
3425 MockTransaction transaction(kSimpleGET_Transaction);
3426 MockHttpRequest req1(transaction);
3428 // Attempt to populate the cache.
3429 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3431 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3432 EXPECT_EQ(0, cache.disk_cache()->open_count());
3433 EXPECT_EQ(1, cache.disk_cache()->create_count());
3435 ScopedVector<UploadElementReader> element_readers;
3436 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3437 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3439 transaction.method = "PUT";
3440 MockHttpRequest req2(transaction);
3441 req2.upload_data_stream = &upload_data_stream;
3443 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3445 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3446 EXPECT_EQ(1, cache.disk_cache()->open_count());
3447 EXPECT_EQ(1, cache.disk_cache()->create_count());
3449 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3451 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3452 EXPECT_EQ(1, cache.disk_cache()->open_count());
3453 EXPECT_EQ(2, cache.disk_cache()->create_count());
3456 // Tests that we invalidate entries as a result of a PUT.
3457 TEST(HttpCache, SimplePUT_Invalidate_305) {
3458 MockHttpCache cache;
3460 MockTransaction transaction(kSimpleGET_Transaction);
3461 AddMockTransaction(&transaction);
3462 MockHttpRequest req1(transaction);
3464 // Attempt to populate the cache.
3465 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3467 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3468 EXPECT_EQ(0, cache.disk_cache()->open_count());
3469 EXPECT_EQ(1, cache.disk_cache()->create_count());
3471 ScopedVector<UploadElementReader> element_readers;
3472 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3473 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3475 transaction.method = "PUT";
3476 transaction.status = "HTTP/1.1 305 Use Proxy";
3477 MockHttpRequest req2(transaction);
3478 req2.upload_data_stream = &upload_data_stream;
3480 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3482 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3483 EXPECT_EQ(1, cache.disk_cache()->open_count());
3484 EXPECT_EQ(1, cache.disk_cache()->create_count());
3486 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3488 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3489 EXPECT_EQ(1, cache.disk_cache()->open_count());
3490 EXPECT_EQ(2, cache.disk_cache()->create_count());
3491 RemoveMockTransaction(&transaction);
3494 // Tests that we don't invalidate entries as a result of a failed PUT.
3495 TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3496 MockHttpCache cache;
3498 MockTransaction transaction(kSimpleGET_Transaction);
3499 AddMockTransaction(&transaction);
3500 MockHttpRequest req1(transaction);
3502 // Attempt to populate the cache.
3503 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3505 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3506 EXPECT_EQ(0, cache.disk_cache()->open_count());
3507 EXPECT_EQ(1, cache.disk_cache()->create_count());
3509 ScopedVector<UploadElementReader> element_readers;
3510 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3511 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3513 transaction.method = "PUT";
3514 transaction.status = "HTTP/1.1 404 Not Found";
3515 MockHttpRequest req2(transaction);
3516 req2.upload_data_stream = &upload_data_stream;
3518 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3520 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3521 EXPECT_EQ(1, cache.disk_cache()->open_count());
3522 EXPECT_EQ(1, cache.disk_cache()->create_count());
3524 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3526 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3527 EXPECT_EQ(2, cache.disk_cache()->open_count());
3528 EXPECT_EQ(1, cache.disk_cache()->create_count());
3529 RemoveMockTransaction(&transaction);
3532 // Tests that we do not cache the response of a DELETE.
3533 TEST(HttpCache, SimpleDELETE_Miss) {
3534 MockHttpCache cache;
3536 MockTransaction transaction(kSimplePOST_Transaction);
3537 transaction.method = "DELETE";
3539 ScopedVector<UploadElementReader> element_readers;
3540 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3541 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3543 MockHttpRequest request(transaction);
3544 request.upload_data_stream = &upload_data_stream;
3546 // Attempt to populate the cache.
3547 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3549 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3550 EXPECT_EQ(0, cache.disk_cache()->open_count());
3551 EXPECT_EQ(0, cache.disk_cache()->create_count());
3554 // Tests that we invalidate entries as a result of a DELETE.
3555 TEST(HttpCache, SimpleDELETE_Invalidate) {
3556 MockHttpCache cache;
3558 MockTransaction transaction(kSimpleGET_Transaction);
3559 MockHttpRequest req1(transaction);
3561 // Attempt to populate the cache.
3562 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3564 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3565 EXPECT_EQ(0, cache.disk_cache()->open_count());
3566 EXPECT_EQ(1, cache.disk_cache()->create_count());
3568 ScopedVector<UploadElementReader> element_readers;
3569 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3570 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
3572 transaction.method = "DELETE";
3573 MockHttpRequest req2(transaction);
3574 req2.upload_data_stream = &upload_data_stream;
3576 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3578 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3579 EXPECT_EQ(1, cache.disk_cache()->open_count());
3580 EXPECT_EQ(1, cache.disk_cache()->create_count());
3582 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3584 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3585 EXPECT_EQ(1, cache.disk_cache()->open_count());
3586 EXPECT_EQ(2, cache.disk_cache()->create_count());
3589 // Tests that we invalidate entries as a result of a DELETE.
3590 TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3591 MockHttpCache cache;
3593 MockTransaction transaction(kSimpleGET_Transaction);
3594 AddMockTransaction(&transaction);
3596 // Attempt to populate the cache.
3597 RunTransactionTest(cache.http_cache(), transaction);
3599 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3600 EXPECT_EQ(0, cache.disk_cache()->open_count());
3601 EXPECT_EQ(1, cache.disk_cache()->create_count());
3603 transaction.method = "DELETE";
3604 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3606 RunTransactionTest(cache.http_cache(), transaction);
3608 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3609 EXPECT_EQ(1, cache.disk_cache()->open_count());
3610 EXPECT_EQ(1, cache.disk_cache()->create_count());
3612 transaction.method = "GET";
3613 RunTransactionTest(cache.http_cache(), transaction);
3615 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3616 EXPECT_EQ(1, cache.disk_cache()->open_count());
3617 EXPECT_EQ(2, cache.disk_cache()->create_count());
3618 RemoveMockTransaction(&transaction);
3621 // Tests that we don't invalidate entries as a result of a failed DELETE.
3622 TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3623 MockHttpCache cache;
3625 MockTransaction transaction(kSimpleGET_Transaction);
3626 AddMockTransaction(&transaction);
3628 // Attempt to populate the cache.
3629 RunTransactionTest(cache.http_cache(), transaction);
3631 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3632 EXPECT_EQ(0, cache.disk_cache()->open_count());
3633 EXPECT_EQ(1, cache.disk_cache()->create_count());
3635 transaction.method = "DELETE";
3636 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3638 RunTransactionTest(cache.http_cache(), transaction);
3640 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3641 EXPECT_EQ(1, cache.disk_cache()->open_count());
3642 EXPECT_EQ(1, cache.disk_cache()->create_count());
3644 transaction.method = "GET";
3645 transaction.status = "HTTP/1.1 200 OK";
3646 RunTransactionTest(cache.http_cache(), transaction);
3648 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3649 EXPECT_EQ(2, cache.disk_cache()->open_count());
3650 EXPECT_EQ(1, cache.disk_cache()->create_count());
3651 RemoveMockTransaction(&transaction);
3654 // Tests that we don't invalidate entries after a failed network transaction.
3655 TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3656 MockHttpCache cache;
3658 // Populate the cache.
3659 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3660 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3662 // Fail the network request.
3663 MockTransaction transaction(kSimpleGET_Transaction);
3664 transaction.return_code = ERR_FAILED;
3665 transaction.load_flags |= LOAD_VALIDATE_CACHE;
3667 AddMockTransaction(&transaction);
3668 RunTransactionTest(cache.http_cache(), transaction);
3669 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3670 RemoveMockTransaction(&transaction);
3672 transaction.load_flags = LOAD_ONLY_FROM_CACHE;
3673 transaction.return_code = OK;
3674 AddMockTransaction(&transaction);
3675 RunTransactionTest(cache.http_cache(), transaction);
3677 // Make sure the transaction didn't reach the network.
3678 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3679 RemoveMockTransaction(&transaction);
3682 TEST(HttpCache, RangeGET_SkipsCache) {
3683 MockHttpCache cache;
3685 // Test that we skip the cache for range GET requests. Eventually, we will
3686 // want to cache these, but we'll still have cases where skipping the cache
3687 // makes sense, so we want to make sure that it works properly.
3689 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3691 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3692 EXPECT_EQ(0, cache.disk_cache()->open_count());
3693 EXPECT_EQ(0, cache.disk_cache()->create_count());
3695 MockTransaction transaction(kSimpleGET_Transaction);
3696 transaction.request_headers = "If-None-Match: foo\r\n";
3697 RunTransactionTest(cache.http_cache(), transaction);
3699 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3700 EXPECT_EQ(0, cache.disk_cache()->open_count());
3701 EXPECT_EQ(0, cache.disk_cache()->create_count());
3703 transaction.request_headers =
3704 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3705 RunTransactionTest(cache.http_cache(), transaction);
3707 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3708 EXPECT_EQ(0, cache.disk_cache()->open_count());
3709 EXPECT_EQ(0, cache.disk_cache()->create_count());
3712 // Test that we skip the cache for range requests that include a validation
3713 // header.
3714 TEST(HttpCache, RangeGET_SkipsCache2) {
3715 MockHttpCache cache;
3717 MockTransaction transaction(kRangeGET_Transaction);
3718 transaction.request_headers = "If-None-Match: foo\r\n"
3719 EXTRA_HEADER
3720 "Range: bytes = 40-49\r\n";
3721 RunTransactionTest(cache.http_cache(), transaction);
3723 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3724 EXPECT_EQ(0, cache.disk_cache()->open_count());
3725 EXPECT_EQ(0, cache.disk_cache()->create_count());
3727 transaction.request_headers =
3728 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3729 EXTRA_HEADER
3730 "Range: bytes = 40-49\r\n";
3731 RunTransactionTest(cache.http_cache(), transaction);
3733 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3734 EXPECT_EQ(0, cache.disk_cache()->open_count());
3735 EXPECT_EQ(0, cache.disk_cache()->create_count());
3737 transaction.request_headers = "If-Range: bla\r\n"
3738 EXTRA_HEADER
3739 "Range: bytes = 40-49\r\n";
3740 RunTransactionTest(cache.http_cache(), transaction);
3742 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3743 EXPECT_EQ(0, cache.disk_cache()->open_count());
3744 EXPECT_EQ(0, cache.disk_cache()->create_count());
3747 TEST(HttpCache, SimpleGET_DoesntLogHeaders) {
3748 MockHttpCache cache;
3750 BoundTestNetLog log;
3751 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
3752 log.bound());
3754 EXPECT_FALSE(LogContainsEventType(
3755 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3758 TEST(HttpCache, RangeGET_LogsHeaders) {
3759 MockHttpCache cache;
3761 BoundTestNetLog log;
3762 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
3763 log.bound());
3765 EXPECT_TRUE(LogContainsEventType(
3766 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3769 TEST(HttpCache, ExternalValidation_LogsHeaders) {
3770 MockHttpCache cache;
3772 BoundTestNetLog log;
3773 MockTransaction transaction(kSimpleGET_Transaction);
3774 transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
3775 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3777 EXPECT_TRUE(LogContainsEventType(
3778 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3781 TEST(HttpCache, SpecialHeaders_LogsHeaders) {
3782 MockHttpCache cache;
3784 BoundTestNetLog log;
3785 MockTransaction transaction(kSimpleGET_Transaction);
3786 transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
3787 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3789 EXPECT_TRUE(LogContainsEventType(
3790 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
3793 // Tests that receiving 206 for a regular request is handled correctly.
3794 TEST(HttpCache, GET_Crazy206) {
3795 MockHttpCache cache;
3797 // Write to the cache.
3798 MockTransaction transaction(kRangeGET_TransactionOK);
3799 AddMockTransaction(&transaction);
3800 transaction.request_headers = EXTRA_HEADER;
3801 transaction.handler = NULL;
3802 RunTransactionTest(cache.http_cache(), transaction);
3804 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3805 EXPECT_EQ(0, cache.disk_cache()->open_count());
3806 EXPECT_EQ(1, cache.disk_cache()->create_count());
3808 // This should read again from the net.
3809 RunTransactionTest(cache.http_cache(), transaction);
3811 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3812 EXPECT_EQ(0, cache.disk_cache()->open_count());
3813 EXPECT_EQ(2, cache.disk_cache()->create_count());
3814 RemoveMockTransaction(&transaction);
3817 // Tests that receiving 416 for a regular request is handled correctly.
3818 TEST(HttpCache, GET_Crazy416) {
3819 MockHttpCache cache;
3821 // Write to the cache.
3822 MockTransaction transaction(kSimpleGET_Transaction);
3823 AddMockTransaction(&transaction);
3824 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3825 RunTransactionTest(cache.http_cache(), transaction);
3827 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3828 EXPECT_EQ(0, cache.disk_cache()->open_count());
3829 EXPECT_EQ(1, cache.disk_cache()->create_count());
3831 RemoveMockTransaction(&transaction);
3834 // Tests that we don't store partial responses that can't be validated.
3835 TEST(HttpCache, RangeGET_NoStrongValidators) {
3836 MockHttpCache cache;
3837 std::string headers;
3839 // Attempt to write to the cache (40-49).
3840 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3841 transaction.response_headers = "Content-Length: 10\n"
3842 "Cache-Control: max-age=3600\n"
3843 "ETag: w/\"foo\"\n";
3844 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3846 Verify206Response(headers, 40, 49);
3847 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3848 EXPECT_EQ(0, cache.disk_cache()->open_count());
3849 EXPECT_EQ(1, cache.disk_cache()->create_count());
3851 // Now verify that there's no cached data.
3852 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3853 &headers);
3855 Verify206Response(headers, 40, 49);
3856 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3857 EXPECT_EQ(0, cache.disk_cache()->open_count());
3858 EXPECT_EQ(2, cache.disk_cache()->create_count());
3861 // Tests failures to conditionalize byte range requests.
3862 TEST(HttpCache, RangeGET_NoConditionalization) {
3863 MockHttpCache cache;
3864 cache.FailConditionalizations();
3865 std::string headers;
3867 // Write to the cache (40-49).
3868 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3869 transaction.response_headers = "Content-Length: 10\n"
3870 "ETag: \"foo\"\n";
3871 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3873 Verify206Response(headers, 40, 49);
3874 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3875 EXPECT_EQ(0, cache.disk_cache()->open_count());
3876 EXPECT_EQ(1, cache.disk_cache()->create_count());
3878 // Now verify that the cached data is not used.
3879 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3880 &headers);
3882 Verify206Response(headers, 40, 49);
3883 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3884 EXPECT_EQ(1, cache.disk_cache()->open_count());
3885 EXPECT_EQ(2, cache.disk_cache()->create_count());
3888 // Tests that restarting a partial request when the cached data cannot be
3889 // revalidated logs an event.
3890 TEST(HttpCache, RangeGET_NoValidation_LogsRestart) {
3891 MockHttpCache cache;
3892 cache.FailConditionalizations();
3894 // Write to the cache (40-49).
3895 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3896 transaction.response_headers = "Content-Length: 10\n"
3897 "ETag: \"foo\"\n";
3898 RunTransactionTest(cache.http_cache(), transaction);
3900 // Now verify that the cached data is not used.
3901 BoundTestNetLog log;
3902 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
3903 log.bound());
3905 EXPECT_TRUE(LogContainsEventType(
3906 log, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST));
3909 // Tests that a failure to conditionalize a regular request (no range) with a
3910 // sparse entry results in a full response.
3911 TEST(HttpCache, GET_NoConditionalization) {
3912 MockHttpCache cache;
3913 cache.FailConditionalizations();
3914 std::string headers;
3916 // Write to the cache (40-49).
3917 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3918 transaction.response_headers = "Content-Length: 10\n"
3919 "ETag: \"foo\"\n";
3920 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3922 Verify206Response(headers, 40, 49);
3923 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3924 EXPECT_EQ(0, cache.disk_cache()->open_count());
3925 EXPECT_EQ(1, cache.disk_cache()->create_count());
3927 // Now verify that the cached data is not used.
3928 // Don't ask for a range. The cache will attempt to use the cached data but
3929 // should discard it as it cannot be validated. A regular request should go
3930 // to the server and a new entry should be created.
3931 transaction.request_headers = EXTRA_HEADER;
3932 transaction.data = "Not a range";
3933 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3935 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3936 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3937 EXPECT_EQ(1, cache.disk_cache()->open_count());
3938 EXPECT_EQ(2, cache.disk_cache()->create_count());
3940 // The last response was saved.
3941 RunTransactionTest(cache.http_cache(), transaction);
3942 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3943 EXPECT_EQ(2, cache.disk_cache()->open_count());
3944 EXPECT_EQ(2, cache.disk_cache()->create_count());
3947 // Verifies that conditionalization failures when asking for a range that would
3948 // require the cache to modify the range to ask, result in a network request
3949 // that matches the user's one.
3950 TEST(HttpCache, RangeGET_NoConditionalization2) {
3951 MockHttpCache cache;
3952 cache.FailConditionalizations();
3953 std::string headers;
3955 // Write to the cache (40-49).
3956 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3957 transaction.response_headers = "Content-Length: 10\n"
3958 "ETag: \"foo\"\n";
3959 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3961 Verify206Response(headers, 40, 49);
3962 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3963 EXPECT_EQ(0, cache.disk_cache()->open_count());
3964 EXPECT_EQ(1, cache.disk_cache()->create_count());
3966 // Now verify that the cached data is not used.
3967 // Ask for a range that extends before and after the cached data so that the
3968 // cache would normally mix data from three sources. After deleting the entry,
3969 // the response will come from a single network request.
3970 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3971 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3972 transaction.response_headers = kRangeGET_TransactionOK.response_headers;
3973 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3975 Verify206Response(headers, 20, 59);
3976 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3977 EXPECT_EQ(1, cache.disk_cache()->open_count());
3978 EXPECT_EQ(2, cache.disk_cache()->create_count());
3980 // The last response was saved.
3981 RunTransactionTest(cache.http_cache(), transaction);
3982 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3983 EXPECT_EQ(2, cache.disk_cache()->open_count());
3984 EXPECT_EQ(2, cache.disk_cache()->create_count());
3987 // Tests that we cache partial responses that lack content-length.
3988 TEST(HttpCache, RangeGET_NoContentLength) {
3989 MockHttpCache cache;
3990 std::string headers;
3992 // Attempt to write to the cache (40-49).
3993 MockTransaction transaction(kRangeGET_TransactionOK);
3994 AddMockTransaction(&transaction);
3995 transaction.response_headers = "ETag: \"foo\"\n"
3996 "Accept-Ranges: bytes\n"
3997 "Content-Range: bytes 40-49/80\n";
3998 transaction.handler = NULL;
3999 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4001 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4002 EXPECT_EQ(0, cache.disk_cache()->open_count());
4003 EXPECT_EQ(1, cache.disk_cache()->create_count());
4005 // Now verify that there's no cached data.
4006 transaction.handler = &RangeTransactionServer::RangeHandler;
4007 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4008 &headers);
4010 Verify206Response(headers, 40, 49);
4011 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4012 EXPECT_EQ(1, cache.disk_cache()->open_count());
4013 EXPECT_EQ(1, cache.disk_cache()->create_count());
4015 RemoveMockTransaction(&transaction);
4018 // Fails only on bots. crbug.com/533640
4019 #if defined(OS_ANDROID)
4020 #define MAYBE_RangeGET_OK DISABLED_RangeGET_OK
4021 #else
4022 #define MAYBE_RangeGET_OK RangeGET_OK
4023 #endif
4024 // Tests that we can cache range requests and fetch random blocks from the
4025 // cache and the network.
4026 TEST(HttpCache, MAYBE_RangeGET_OK) {
4027 MockHttpCache cache;
4028 AddMockTransaction(&kRangeGET_TransactionOK);
4029 std::string headers;
4031 // Write to the cache (40-49).
4032 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4033 &headers);
4035 Verify206Response(headers, 40, 49);
4036 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4037 EXPECT_EQ(0, cache.disk_cache()->open_count());
4038 EXPECT_EQ(1, cache.disk_cache()->create_count());
4040 // Read from the cache (40-49).
4041 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4042 &headers);
4044 Verify206Response(headers, 40, 49);
4045 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4046 EXPECT_EQ(1, cache.disk_cache()->open_count());
4047 EXPECT_EQ(1, cache.disk_cache()->create_count());
4049 // Make sure we are done with the previous transaction.
4050 base::MessageLoop::current()->RunUntilIdle();
4052 // Write to the cache (30-39).
4053 MockTransaction transaction(kRangeGET_TransactionOK);
4054 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
4055 transaction.data = "rg: 30-39 ";
4056 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4058 Verify206Response(headers, 30, 39);
4059 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4060 EXPECT_EQ(2, cache.disk_cache()->open_count());
4061 EXPECT_EQ(1, cache.disk_cache()->create_count());
4063 // Make sure we are done with the previous transaction.
4064 base::MessageLoop::current()->RunUntilIdle();
4066 // Write and read from the cache (20-59).
4067 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4068 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4069 BoundTestNetLog log;
4070 LoadTimingInfo load_timing_info;
4071 RunTransactionTestWithResponseAndGetTiming(
4072 cache.http_cache(), transaction, &headers, log.bound(),
4073 &load_timing_info);
4075 Verify206Response(headers, 20, 59);
4076 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4077 EXPECT_EQ(3, cache.disk_cache()->open_count());
4078 EXPECT_EQ(1, cache.disk_cache()->create_count());
4079 TestLoadTimingNetworkRequest(load_timing_info);
4081 RemoveMockTransaction(&kRangeGET_TransactionOK);
4084 // Fails only on bots. crbug.com/533640
4085 #if defined(OS_ANDROID)
4086 #define MAYBE_RangeGET_SyncOK DISABLED_RangeGET_SyncOK
4087 #else
4088 #define MAYBE_RangeGET_SyncOK RangeGET_SyncOK
4089 #endif
4090 // Tests that we can cache range requests and fetch random blocks from the
4091 // cache and the network, with synchronous responses.
4092 TEST(HttpCache, MAYBE_RangeGET_SyncOK) {
4093 MockHttpCache cache;
4095 MockTransaction transaction(kRangeGET_TransactionOK);
4096 transaction.test_mode = TEST_MODE_SYNC_ALL;
4097 AddMockTransaction(&transaction);
4099 // Write to the cache (40-49).
4100 std::string headers;
4101 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4103 Verify206Response(headers, 40, 49);
4104 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4105 EXPECT_EQ(0, cache.disk_cache()->open_count());
4106 EXPECT_EQ(1, cache.disk_cache()->create_count());
4108 // Read from the cache (40-49).
4109 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4111 Verify206Response(headers, 40, 49);
4112 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4113 EXPECT_EQ(0, cache.disk_cache()->open_count());
4114 EXPECT_EQ(1, cache.disk_cache()->create_count());
4116 // Make sure we are done with the previous transaction.
4117 base::MessageLoop::current()->RunUntilIdle();
4119 // Write to the cache (30-39).
4120 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
4121 transaction.data = "rg: 30-39 ";
4122 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4124 Verify206Response(headers, 30, 39);
4125 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4126 EXPECT_EQ(1, cache.disk_cache()->open_count());
4127 EXPECT_EQ(1, cache.disk_cache()->create_count());
4129 // Make sure we are done with the previous transaction.
4130 base::MessageLoop::current()->RunUntilIdle();
4132 // Write and read from the cache (20-59).
4133 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4134 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
4135 BoundTestNetLog log;
4136 LoadTimingInfo load_timing_info;
4137 RunTransactionTestWithResponseAndGetTiming(
4138 cache.http_cache(), transaction, &headers, log.bound(),
4139 &load_timing_info);
4141 Verify206Response(headers, 20, 59);
4142 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4143 EXPECT_EQ(2, cache.disk_cache()->open_count());
4144 EXPECT_EQ(1, cache.disk_cache()->create_count());
4145 TestLoadTimingNetworkRequest(load_timing_info);
4147 RemoveMockTransaction(&transaction);
4150 // Tests that if the previous transaction is cancelled while busy (doing sparse
4151 // IO), a new transaction (that reuses that same ActiveEntry) waits until the
4152 // entry is ready again.
4153 TEST(HttpCache, Sparse_WaitForEntry) {
4154 MockHttpCache cache;
4156 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4158 // Create a sparse entry.
4159 RunTransactionTest(cache.http_cache(), transaction);
4161 // Simulate a previous transaction being cancelled.
4162 disk_cache::Entry* entry;
4163 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4164 entry->CancelSparseIO();
4166 // Test with a range request.
4167 RunTransactionTest(cache.http_cache(), transaction);
4169 // Now test with a regular request.
4170 entry->CancelSparseIO();
4171 transaction.request_headers = EXTRA_HEADER;
4172 transaction.data = kFullRangeData;
4173 RunTransactionTest(cache.http_cache(), transaction);
4175 entry->Close();
4178 // Tests that we don't revalidate an entry unless we are required to do so.
4179 TEST(HttpCache, RangeGET_Revalidate1) {
4180 MockHttpCache cache;
4181 std::string headers;
4183 // Write to the cache (40-49).
4184 MockTransaction transaction(kRangeGET_TransactionOK);
4185 transaction.response_headers =
4186 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4187 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4188 "ETag: \"foo\"\n"
4189 "Accept-Ranges: bytes\n"
4190 "Content-Length: 10\n";
4191 AddMockTransaction(&transaction);
4192 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4194 Verify206Response(headers, 40, 49);
4195 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4196 EXPECT_EQ(0, cache.disk_cache()->open_count());
4197 EXPECT_EQ(1, cache.disk_cache()->create_count());
4199 // Read from the cache (40-49).
4200 BoundTestNetLog log;
4201 LoadTimingInfo load_timing_info;
4202 RunTransactionTestWithResponseAndGetTiming(
4203 cache.http_cache(), transaction, &headers, log.bound(),
4204 &load_timing_info);
4206 Verify206Response(headers, 40, 49);
4207 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4208 EXPECT_EQ(1, cache.disk_cache()->open_count());
4209 EXPECT_EQ(1, cache.disk_cache()->create_count());
4210 TestLoadTimingCachedResponse(load_timing_info);
4212 // Read again forcing the revalidation.
4213 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4214 RunTransactionTestWithResponseAndGetTiming(
4215 cache.http_cache(), transaction, &headers, log.bound(),
4216 &load_timing_info);
4218 Verify206Response(headers, 40, 49);
4219 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4220 EXPECT_EQ(1, cache.disk_cache()->open_count());
4221 EXPECT_EQ(1, cache.disk_cache()->create_count());
4222 TestLoadTimingNetworkRequest(load_timing_info);
4224 RemoveMockTransaction(&transaction);
4227 // Fails only on bots. crbug.com/533640
4228 #if defined(OS_ANDROID)
4229 #define MAYBE_RangeGET_Revalidate2 DISABLED_RangeGET_Revalidate2
4230 #else
4231 #define MAYBE_RangeGET_Revalidate2 RangeGET_Revalidate2
4232 #endif
4233 // Checks that we revalidate an entry when the headers say so.
4234 TEST(HttpCache, MAYBE_RangeGET_Revalidate2) {
4235 MockHttpCache cache;
4236 std::string headers;
4238 // Write to the cache (40-49).
4239 MockTransaction transaction(kRangeGET_TransactionOK);
4240 transaction.response_headers =
4241 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4242 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4243 "ETag: \"foo\"\n"
4244 "Accept-Ranges: bytes\n"
4245 "Content-Length: 10\n";
4246 AddMockTransaction(&transaction);
4247 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4249 Verify206Response(headers, 40, 49);
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 // Read from the cache (40-49).
4255 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4256 Verify206Response(headers, 40, 49);
4258 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4259 EXPECT_EQ(1, cache.disk_cache()->open_count());
4260 EXPECT_EQ(1, cache.disk_cache()->create_count());
4262 RemoveMockTransaction(&transaction);
4265 // Tests that we deal with 304s for range requests.
4266 TEST(HttpCache, RangeGET_304) {
4267 MockHttpCache cache;
4268 AddMockTransaction(&kRangeGET_TransactionOK);
4269 std::string headers;
4271 // Write to the cache (40-49).
4272 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4273 &headers);
4275 Verify206Response(headers, 40, 49);
4276 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4277 EXPECT_EQ(0, cache.disk_cache()->open_count());
4278 EXPECT_EQ(1, cache.disk_cache()->create_count());
4280 // Read from the cache (40-49).
4281 RangeTransactionServer handler;
4282 handler.set_not_modified(true);
4283 MockTransaction transaction(kRangeGET_TransactionOK);
4284 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4285 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4287 Verify206Response(headers, 40, 49);
4288 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4289 EXPECT_EQ(1, cache.disk_cache()->open_count());
4290 EXPECT_EQ(1, cache.disk_cache()->create_count());
4292 RemoveMockTransaction(&kRangeGET_TransactionOK);
4295 // Tests that we deal with 206s when revalidating range requests.
4296 TEST(HttpCache, RangeGET_ModifiedResult) {
4297 MockHttpCache cache;
4298 AddMockTransaction(&kRangeGET_TransactionOK);
4299 std::string headers;
4301 // Write to the cache (40-49).
4302 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4303 &headers);
4305 Verify206Response(headers, 40, 49);
4306 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4307 EXPECT_EQ(0, cache.disk_cache()->open_count());
4308 EXPECT_EQ(1, cache.disk_cache()->create_count());
4310 // Attempt to read from the cache (40-49).
4311 RangeTransactionServer handler;
4312 handler.set_modified(true);
4313 MockTransaction transaction(kRangeGET_TransactionOK);
4314 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4315 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4317 Verify206Response(headers, 40, 49);
4318 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4319 EXPECT_EQ(1, cache.disk_cache()->open_count());
4320 EXPECT_EQ(1, cache.disk_cache()->create_count());
4322 // And the entry should be gone.
4323 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4324 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4325 EXPECT_EQ(1, cache.disk_cache()->open_count());
4326 EXPECT_EQ(2, cache.disk_cache()->create_count());
4328 RemoveMockTransaction(&kRangeGET_TransactionOK);
4331 // Tests that when a server returns 206 with a sub-range of the requested range,
4332 // and there is nothing stored in the cache, the returned response is passed to
4333 // the caller as is. In this context, a subrange means a response that starts
4334 // with the same byte that was requested, but that is not the whole range that
4335 // was requested.
4336 TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
4337 MockHttpCache cache;
4338 std::string headers;
4340 // Request a large range (40-59). The server sends 40-49.
4341 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4342 transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
4343 transaction.response_headers =
4344 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4345 "ETag: \"foo\"\n"
4346 "Accept-Ranges: bytes\n"
4347 "Content-Length: 10\n"
4348 "Content-Range: bytes 40-49/80\n";
4349 transaction.handler = nullptr;
4350 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4352 Verify206Response(headers, 40, 49);
4353 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4354 EXPECT_EQ(0, cache.disk_cache()->open_count());
4355 EXPECT_EQ(1, cache.disk_cache()->create_count());
4358 // Tests that when a server returns 206 with a sub-range of the requested range,
4359 // and there was an entry stored in the cache, the cache gets out of the way.
4360 TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_CachedContent) {
4361 MockHttpCache cache;
4362 std::string headers;
4364 // Write to the cache (70-79).
4365 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4366 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4367 transaction.data = "rg: 70-79 ";
4368 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4369 Verify206Response(headers, 70, 79);
4371 // Request a large range (40-79). The cache will ask the server for 40-59.
4372 // The server returns 40-49. The cache should consider the server confused and
4373 // abort caching, restarting the request without caching.
4374 transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
4375 transaction.response_headers =
4376 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4377 "ETag: \"foo\"\n"
4378 "Accept-Ranges: bytes\n"
4379 "Content-Length: 10\n"
4380 "Content-Range: bytes 40-49/80\n";
4381 transaction.handler = nullptr;
4382 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4384 // Two new network requests were issued, one from the cache and another after
4385 // deleting the entry.
4386 Verify206Response(headers, 40, 49);
4387 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4388 EXPECT_EQ(1, cache.disk_cache()->open_count());
4389 EXPECT_EQ(1, cache.disk_cache()->create_count());
4391 // The entry was deleted.
4392 RunTransactionTest(cache.http_cache(), transaction);
4393 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4394 EXPECT_EQ(1, cache.disk_cache()->open_count());
4395 EXPECT_EQ(2, cache.disk_cache()->create_count());
4398 // Tests that when a server returns 206 with a sub-range of the requested range,
4399 // and there was an entry stored in the cache, the cache gets out of the way,
4400 // when the caller is not using ranges.
4401 TEST(HttpCache, GET_206ReturnsSubrangeRange_CachedContent) {
4402 MockHttpCache cache;
4403 std::string headers;
4405 // Write to the cache (70-79).
4406 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4407 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4408 transaction.data = "rg: 70-79 ";
4409 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4410 Verify206Response(headers, 70, 79);
4412 // Don't ask for a range. The cache will ask the server for 0-69.
4413 // The server returns 40-49. The cache should consider the server confused and
4414 // abort caching, restarting the request.
4415 // The second network request should not be a byte range request so the server
4416 // should return 200 + "Not a range"
4417 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
4418 transaction.data = "Not a range";
4419 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4421 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4422 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4423 EXPECT_EQ(1, cache.disk_cache()->open_count());
4424 EXPECT_EQ(1, cache.disk_cache()->create_count());
4426 // The entry was deleted.
4427 RunTransactionTest(cache.http_cache(), transaction);
4428 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4429 EXPECT_EQ(1, cache.disk_cache()->open_count());
4430 EXPECT_EQ(2, cache.disk_cache()->create_count());
4433 // Tests that when a server returns 206 with a random range and there is
4434 // nothing stored in the cache, the returned response is passed to the caller
4435 // as is. In this context, a WrongRange means that the returned range may or may
4436 // not have any relationship with the requested range (may or may not be
4437 // contained). The important part is that the first byte doesn't match the first
4438 // requested byte.
4439 TEST(HttpCache, RangeGET_206ReturnsWrongRange_NoCachedContent) {
4440 MockHttpCache cache;
4441 std::string headers;
4443 // Request a large range (30-59). The server sends (40-49).
4444 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4445 transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
4446 transaction.response_headers =
4447 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4448 "ETag: \"foo\"\n"
4449 "Accept-Ranges: bytes\n"
4450 "Content-Length: 10\n"
4451 "Content-Range: bytes 40-49/80\n";
4452 transaction.handler = nullptr;
4453 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4455 Verify206Response(headers, 40, 49);
4456 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4457 EXPECT_EQ(0, cache.disk_cache()->open_count());
4458 EXPECT_EQ(1, cache.disk_cache()->create_count());
4460 // The entry was deleted.
4461 RunTransactionTest(cache.http_cache(), transaction);
4462 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4463 EXPECT_EQ(0, cache.disk_cache()->open_count());
4464 EXPECT_EQ(2, cache.disk_cache()->create_count());
4467 // Tests that when a server returns 206 with a random range and there is
4468 // an entry stored in the cache, the cache gets out of the way.
4469 TEST(HttpCache, RangeGET_206ReturnsWrongRange_CachedContent) {
4470 MockHttpCache cache;
4471 std::string headers;
4473 // Write to the cache (70-79).
4474 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4475 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4476 transaction.data = "rg: 70-79 ";
4477 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4478 Verify206Response(headers, 70, 79);
4480 // Request a large range (30-79). The cache will ask the server for 30-69.
4481 // The server returns 40-49. The cache should consider the server confused and
4482 // abort caching, returning the weird range to the caller.
4483 transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
4484 transaction.response_headers =
4485 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4486 "ETag: \"foo\"\n"
4487 "Accept-Ranges: bytes\n"
4488 "Content-Length: 10\n"
4489 "Content-Range: bytes 40-49/80\n";
4490 transaction.handler = nullptr;
4491 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4493 Verify206Response(headers, 40, 49);
4494 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4495 EXPECT_EQ(1, cache.disk_cache()->open_count());
4496 EXPECT_EQ(1, cache.disk_cache()->create_count());
4498 // The entry was deleted.
4499 RunTransactionTest(cache.http_cache(), transaction);
4500 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4501 EXPECT_EQ(1, cache.disk_cache()->open_count());
4502 EXPECT_EQ(2, cache.disk_cache()->create_count());
4505 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
4506 // the response matches the one provided by the server.
4507 TEST(HttpCache, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
4508 MockHttpCache cache;
4509 std::string headers;
4511 // Request a large range (70-99). The server sends 70-79.
4512 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4513 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4514 transaction.data = "rg: 70-79 ";
4515 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4517 Verify206Response(headers, 70, 79);
4518 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4519 EXPECT_EQ(0, cache.disk_cache()->open_count());
4520 EXPECT_EQ(1, cache.disk_cache()->create_count());
4522 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4523 EXPECT_EQ(1, cache.disk_cache()->open_count());
4526 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
4527 // the cache automatically fixes the request.
4528 TEST(HttpCache, RangeGET_206ReturnsSmallerFile_CachedContent) {
4529 MockHttpCache cache;
4530 std::string headers;
4532 // Write to the cache (40-49).
4533 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4534 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4536 // Request a large range (70-99). The server sends 70-79.
4537 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4538 transaction.data = "rg: 70-79 ";
4539 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4541 Verify206Response(headers, 70, 79);
4542 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4543 EXPECT_EQ(1, cache.disk_cache()->open_count());
4544 EXPECT_EQ(1, cache.disk_cache()->create_count());
4546 // The entry was not deleted (the range was automatically fixed).
4547 RunTransactionTest(cache.http_cache(), transaction);
4548 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4549 EXPECT_EQ(2, cache.disk_cache()->open_count());
4550 EXPECT_EQ(1, cache.disk_cache()->create_count());
4553 // Tests that when a caller asks for a not-satisfiable range, the server's
4554 // response is forwarded to the caller.
4555 TEST(HttpCache, RangeGET_416_NoCachedContent) {
4556 MockHttpCache cache;
4557 std::string headers;
4559 // Request a range beyond EOF (80-99).
4560 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4561 transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
4562 transaction.data = "";
4563 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
4564 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4566 EXPECT_EQ(0U, headers.find(transaction.status));
4567 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4568 EXPECT_EQ(0, cache.disk_cache()->open_count());
4569 EXPECT_EQ(1, cache.disk_cache()->create_count());
4571 // The entry was deleted.
4572 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4573 EXPECT_EQ(2, cache.disk_cache()->create_count());
4576 // Tests that we cache 301s for range requests.
4577 TEST(HttpCache, RangeGET_301) {
4578 MockHttpCache cache;
4579 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4580 transaction.status = "HTTP/1.1 301 Moved Permanently";
4581 transaction.response_headers = "Location: http://www.bar.com/\n";
4582 transaction.data = "";
4583 transaction.handler = NULL;
4585 // Write to the cache.
4586 RunTransactionTest(cache.http_cache(), transaction);
4587 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4588 EXPECT_EQ(0, cache.disk_cache()->open_count());
4589 EXPECT_EQ(1, cache.disk_cache()->create_count());
4591 // Read from the cache.
4592 RunTransactionTest(cache.http_cache(), transaction);
4593 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4594 EXPECT_EQ(1, cache.disk_cache()->open_count());
4595 EXPECT_EQ(1, cache.disk_cache()->create_count());
4598 // Tests that we can cache range requests when the start or end is unknown.
4599 // We start with one suffix request, followed by a request from a given point.
4600 TEST(HttpCache, UnknownRangeGET_1) {
4601 MockHttpCache cache;
4602 AddMockTransaction(&kRangeGET_TransactionOK);
4603 std::string headers;
4605 // Write to the cache (70-79).
4606 MockTransaction transaction(kRangeGET_TransactionOK);
4607 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4608 transaction.data = "rg: 70-79 ";
4609 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4611 Verify206Response(headers, 70, 79);
4612 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4613 EXPECT_EQ(0, cache.disk_cache()->open_count());
4614 EXPECT_EQ(1, cache.disk_cache()->create_count());
4616 // Make sure we are done with the previous transaction.
4617 base::MessageLoop::current()->RunUntilIdle();
4619 // Write and read from the cache (60-79).
4620 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
4621 transaction.data = "rg: 60-69 rg: 70-79 ";
4622 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4624 Verify206Response(headers, 60, 79);
4625 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4626 EXPECT_EQ(1, cache.disk_cache()->open_count());
4627 EXPECT_EQ(1, cache.disk_cache()->create_count());
4629 RemoveMockTransaction(&kRangeGET_TransactionOK);
4632 // Tests that we can cache range requests when the start or end is unknown.
4633 // We start with one request from a given point, followed by a suffix request.
4634 // We'll also verify that synchronous cache responses work as intended.
4635 TEST(HttpCache, UnknownRangeGET_2) {
4636 MockHttpCache cache;
4637 std::string headers;
4639 MockTransaction transaction(kRangeGET_TransactionOK);
4640 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
4641 TEST_MODE_SYNC_CACHE_READ |
4642 TEST_MODE_SYNC_CACHE_WRITE;
4643 AddMockTransaction(&transaction);
4645 // Write to the cache (70-79).
4646 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4647 transaction.data = "rg: 70-79 ";
4648 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4650 Verify206Response(headers, 70, 79);
4651 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4652 EXPECT_EQ(0, cache.disk_cache()->open_count());
4653 EXPECT_EQ(1, cache.disk_cache()->create_count());
4655 // Make sure we are done with the previous transaction.
4656 base::MessageLoop::current()->RunUntilIdle();
4658 // Write and read from the cache (60-79).
4659 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
4660 transaction.data = "rg: 60-69 rg: 70-79 ";
4661 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4663 Verify206Response(headers, 60, 79);
4664 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4665 EXPECT_EQ(1, cache.disk_cache()->open_count());
4666 EXPECT_EQ(1, cache.disk_cache()->create_count());
4668 RemoveMockTransaction(&transaction);
4671 // Tests that receiving Not Modified when asking for an open range doesn't mess
4672 // up things.
4673 TEST(HttpCache, UnknownRangeGET_304) {
4674 MockHttpCache cache;
4675 std::string headers;
4677 MockTransaction transaction(kRangeGET_TransactionOK);
4678 AddMockTransaction(&transaction);
4680 RangeTransactionServer handler;
4681 handler.set_not_modified(true);
4683 // Ask for the end of the file, without knowing the length.
4684 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4685 transaction.data = "";
4686 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4688 // We just bypass the cache.
4689 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4690 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4691 EXPECT_EQ(0, cache.disk_cache()->open_count());
4692 EXPECT_EQ(1, cache.disk_cache()->create_count());
4694 RunTransactionTest(cache.http_cache(), transaction);
4695 EXPECT_EQ(2, cache.disk_cache()->create_count());
4697 RemoveMockTransaction(&transaction);
4700 // Tests that we can handle non-range requests when we have cached a range.
4701 TEST(HttpCache, GET_Previous206) {
4702 MockHttpCache cache;
4703 AddMockTransaction(&kRangeGET_TransactionOK);
4704 std::string headers;
4705 BoundTestNetLog log;
4706 LoadTimingInfo load_timing_info;
4708 // Write to the cache (40-49).
4709 RunTransactionTestWithResponseAndGetTiming(
4710 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4711 &load_timing_info);
4713 Verify206Response(headers, 40, 49);
4714 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4715 EXPECT_EQ(0, cache.disk_cache()->open_count());
4716 EXPECT_EQ(1, cache.disk_cache()->create_count());
4717 TestLoadTimingNetworkRequest(load_timing_info);
4719 // Write and read from the cache (0-79), when not asked for a range.
4720 MockTransaction transaction(kRangeGET_TransactionOK);
4721 transaction.request_headers = EXTRA_HEADER;
4722 transaction.data = kFullRangeData;
4723 RunTransactionTestWithResponseAndGetTiming(
4724 cache.http_cache(), transaction, &headers, log.bound(),
4725 &load_timing_info);
4727 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4728 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4729 EXPECT_EQ(1, cache.disk_cache()->open_count());
4730 EXPECT_EQ(1, cache.disk_cache()->create_count());
4731 TestLoadTimingNetworkRequest(load_timing_info);
4733 RemoveMockTransaction(&kRangeGET_TransactionOK);
4736 // Tests that we can handle non-range requests when we have cached the first
4737 // part of the object and the server replies with 304 (Not Modified).
4738 TEST(HttpCache, GET_Previous206_NotModified) {
4739 MockHttpCache cache;
4741 MockTransaction transaction(kRangeGET_TransactionOK);
4742 AddMockTransaction(&transaction);
4743 std::string headers;
4744 BoundTestNetLog log;
4745 LoadTimingInfo load_timing_info;
4747 // Write to the cache (0-9).
4748 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4749 transaction.data = "rg: 00-09 ";
4750 RunTransactionTestWithResponseAndGetTiming(
4751 cache.http_cache(), transaction, &headers, log.bound(),
4752 &load_timing_info);
4753 Verify206Response(headers, 0, 9);
4754 TestLoadTimingNetworkRequest(load_timing_info);
4756 // Write to the cache (70-79).
4757 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4758 transaction.data = "rg: 70-79 ";
4759 RunTransactionTestWithResponseAndGetTiming(
4760 cache.http_cache(), transaction, &headers, log.bound(),
4761 &load_timing_info);
4762 Verify206Response(headers, 70, 79);
4764 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4765 EXPECT_EQ(1, cache.disk_cache()->open_count());
4766 EXPECT_EQ(1, cache.disk_cache()->create_count());
4767 TestLoadTimingNetworkRequest(load_timing_info);
4769 // Read from the cache (0-9), write and read from cache (10 - 79).
4770 transaction.load_flags |= LOAD_VALIDATE_CACHE;
4771 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
4772 transaction.data = kFullRangeData;
4773 RunTransactionTestWithResponseAndGetTiming(
4774 cache.http_cache(), transaction, &headers, log.bound(),
4775 &load_timing_info);
4777 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4778 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4779 EXPECT_EQ(2, cache.disk_cache()->open_count());
4780 EXPECT_EQ(1, cache.disk_cache()->create_count());
4781 TestLoadTimingNetworkRequest(load_timing_info);
4783 RemoveMockTransaction(&transaction);
4786 // Tests that we can handle a regular request to a sparse entry, that results in
4787 // new content provided by the server (206).
4788 TEST(HttpCache, GET_Previous206_NewContent) {
4789 MockHttpCache cache;
4790 AddMockTransaction(&kRangeGET_TransactionOK);
4791 std::string headers;
4793 // Write to the cache (0-9).
4794 MockTransaction transaction(kRangeGET_TransactionOK);
4795 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4796 transaction.data = "rg: 00-09 ";
4797 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4799 Verify206Response(headers, 0, 9);
4800 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4801 EXPECT_EQ(0, cache.disk_cache()->open_count());
4802 EXPECT_EQ(1, cache.disk_cache()->create_count());
4804 // Now we'll issue a request without any range that should result first in a
4805 // 206 (when revalidating), and then in a weird standard answer: the test
4806 // server will not modify the response so we'll get the default range... a
4807 // real server will answer with 200.
4808 MockTransaction transaction2(kRangeGET_TransactionOK);
4809 transaction2.request_headers = EXTRA_HEADER;
4810 transaction2.load_flags |= LOAD_VALIDATE_CACHE;
4811 transaction2.data = "Not a range";
4812 RangeTransactionServer handler;
4813 handler.set_modified(true);
4814 BoundTestNetLog log;
4815 LoadTimingInfo load_timing_info;
4816 RunTransactionTestWithResponseAndGetTiming(
4817 cache.http_cache(), transaction2, &headers, log.bound(),
4818 &load_timing_info);
4820 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4821 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4822 EXPECT_EQ(1, cache.disk_cache()->open_count());
4823 EXPECT_EQ(1, cache.disk_cache()->create_count());
4824 TestLoadTimingNetworkRequest(load_timing_info);
4826 // Verify that the previous request deleted the entry.
4827 RunTransactionTest(cache.http_cache(), transaction);
4828 EXPECT_EQ(2, cache.disk_cache()->create_count());
4830 RemoveMockTransaction(&transaction);
4833 // Tests that we can handle cached 206 responses that are not sparse.
4834 TEST(HttpCache, GET_Previous206_NotSparse) {
4835 MockHttpCache cache;
4837 // Create a disk cache entry that stores 206 headers while not being sparse.
4838 disk_cache::Entry* entry;
4839 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4840 NULL));
4842 std::string raw_headers(kRangeGET_TransactionOK.status);
4843 raw_headers.append("\n");
4844 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4845 raw_headers =
4846 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
4848 HttpResponseInfo response;
4849 response.headers = new HttpResponseHeaders(raw_headers);
4850 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4852 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
4853 int len = static_cast<int>(base::strlcpy(buf->data(),
4854 kRangeGET_TransactionOK.data, 500));
4855 TestCompletionCallback cb;
4856 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4857 EXPECT_EQ(len, cb.GetResult(rv));
4858 entry->Close();
4860 // Now see that we don't use the stored entry.
4861 std::string headers;
4862 BoundTestNetLog log;
4863 LoadTimingInfo load_timing_info;
4864 RunTransactionTestWithResponseAndGetTiming(
4865 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4866 &load_timing_info);
4868 // We are expecting a 200.
4869 std::string expected_headers(kSimpleGET_Transaction.status);
4870 expected_headers.append("\n");
4871 expected_headers.append(kSimpleGET_Transaction.response_headers);
4872 EXPECT_EQ(expected_headers, headers);
4873 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4874 EXPECT_EQ(1, cache.disk_cache()->open_count());
4875 EXPECT_EQ(2, cache.disk_cache()->create_count());
4876 TestLoadTimingNetworkRequest(load_timing_info);
4879 // Tests that we can handle cached 206 responses that are not sparse. This time
4880 // we issue a range request and expect to receive a range.
4881 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4882 MockHttpCache cache;
4883 AddMockTransaction(&kRangeGET_TransactionOK);
4885 // Create a disk cache entry that stores 206 headers while not being sparse.
4886 disk_cache::Entry* entry;
4887 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4888 NULL));
4890 std::string raw_headers(kRangeGET_TransactionOK.status);
4891 raw_headers.append("\n");
4892 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4893 raw_headers =
4894 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
4896 HttpResponseInfo response;
4897 response.headers = new HttpResponseHeaders(raw_headers);
4898 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4900 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
4901 int len = static_cast<int>(base::strlcpy(buf->data(),
4902 kRangeGET_TransactionOK.data, 500));
4903 TestCompletionCallback cb;
4904 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4905 EXPECT_EQ(len, cb.GetResult(rv));
4906 entry->Close();
4908 // Now see that we don't use the stored entry.
4909 std::string headers;
4910 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4911 &headers);
4913 // We are expecting a 206.
4914 Verify206Response(headers, 40, 49);
4915 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4916 EXPECT_EQ(1, cache.disk_cache()->open_count());
4917 EXPECT_EQ(2, cache.disk_cache()->create_count());
4919 RemoveMockTransaction(&kRangeGET_TransactionOK);
4922 // Tests that we can handle cached 206 responses that can't be validated.
4923 TEST(HttpCache, GET_Previous206_NotValidation) {
4924 MockHttpCache cache;
4926 // Create a disk cache entry that stores 206 headers.
4927 disk_cache::Entry* entry;
4928 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4929 NULL));
4931 // Make sure that the headers cannot be validated with the server.
4932 std::string raw_headers(kRangeGET_TransactionOK.status);
4933 raw_headers.append("\n");
4934 raw_headers.append("Content-Length: 80\n");
4935 raw_headers =
4936 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
4938 HttpResponseInfo response;
4939 response.headers = new HttpResponseHeaders(raw_headers);
4940 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4942 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
4943 int len = static_cast<int>(base::strlcpy(buf->data(),
4944 kRangeGET_TransactionOK.data, 500));
4945 TestCompletionCallback cb;
4946 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4947 EXPECT_EQ(len, cb.GetResult(rv));
4948 entry->Close();
4950 // Now see that we don't use the stored entry.
4951 std::string headers;
4952 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4953 &headers);
4955 // We are expecting a 200.
4956 std::string expected_headers(kSimpleGET_Transaction.status);
4957 expected_headers.append("\n");
4958 expected_headers.append(kSimpleGET_Transaction.response_headers);
4959 EXPECT_EQ(expected_headers, headers);
4960 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4961 EXPECT_EQ(1, cache.disk_cache()->open_count());
4962 EXPECT_EQ(2, cache.disk_cache()->create_count());
4965 // Fails only on bots. crbug.com/533640
4966 #if defined(OS_ANDROID)
4967 #define MAYBE_RangeGET_Previous200 DISABLED_RangeGET_Previous200
4968 #else
4969 #define MAYBE_RangeGET_Previous200 RangeGET_Previous200
4970 #endif
4971 // Tests that we can handle range requests with cached 200 responses.
4972 TEST(HttpCache, MAYBE_RangeGET_Previous200) {
4973 MockHttpCache cache;
4975 // Store the whole thing with status 200.
4976 MockTransaction transaction(kTypicalGET_Transaction);
4977 transaction.url = kRangeGET_TransactionOK.url;
4978 transaction.data = kFullRangeData;
4979 AddMockTransaction(&transaction);
4980 RunTransactionTest(cache.http_cache(), transaction);
4981 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4982 EXPECT_EQ(0, cache.disk_cache()->open_count());
4983 EXPECT_EQ(1, cache.disk_cache()->create_count());
4985 RemoveMockTransaction(&transaction);
4986 AddMockTransaction(&kRangeGET_TransactionOK);
4988 // Now see that we use the stored entry.
4989 std::string headers;
4990 MockTransaction transaction2(kRangeGET_TransactionOK);
4991 RangeTransactionServer handler;
4992 handler.set_not_modified(true);
4993 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4995 // We are expecting a 206.
4996 Verify206Response(headers, 40, 49);
4997 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4998 EXPECT_EQ(1, cache.disk_cache()->open_count());
4999 EXPECT_EQ(1, cache.disk_cache()->create_count());
5001 // The last transaction has finished so make sure the entry is deactivated.
5002 base::MessageLoop::current()->RunUntilIdle();
5004 // Make a request for an invalid range.
5005 MockTransaction transaction3(kRangeGET_TransactionOK);
5006 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
5007 transaction3.data = transaction.data;
5008 transaction3.load_flags = LOAD_PREFERRING_CACHE;
5009 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
5010 EXPECT_EQ(2, cache.disk_cache()->open_count());
5011 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
5012 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
5013 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
5015 // Make sure the entry is deactivated.
5016 base::MessageLoop::current()->RunUntilIdle();
5018 // Even though the request was invalid, we should have the entry.
5019 RunTransactionTest(cache.http_cache(), transaction2);
5020 EXPECT_EQ(3, cache.disk_cache()->open_count());
5022 // Make sure the entry is deactivated.
5023 base::MessageLoop::current()->RunUntilIdle();
5025 // Now we should receive a range from the server and drop the stored entry.
5026 handler.set_not_modified(false);
5027 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
5028 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
5029 Verify206Response(headers, 40, 49);
5030 EXPECT_EQ(4, cache.network_layer()->transaction_count());
5031 EXPECT_EQ(4, cache.disk_cache()->open_count());
5032 EXPECT_EQ(1, cache.disk_cache()->create_count());
5034 RunTransactionTest(cache.http_cache(), transaction2);
5035 EXPECT_EQ(2, cache.disk_cache()->create_count());
5037 RemoveMockTransaction(&kRangeGET_TransactionOK);
5040 // Tests that we can handle a 200 response when dealing with sparse entries.
5041 TEST(HttpCache, RangeRequestResultsIn200) {
5042 MockHttpCache cache;
5043 AddMockTransaction(&kRangeGET_TransactionOK);
5044 std::string headers;
5046 // Write to the cache (70-79).
5047 MockTransaction transaction(kRangeGET_TransactionOK);
5048 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
5049 transaction.data = "rg: 70-79 ";
5050 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5052 Verify206Response(headers, 70, 79);
5053 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5054 EXPECT_EQ(0, cache.disk_cache()->open_count());
5055 EXPECT_EQ(1, cache.disk_cache()->create_count());
5057 // Now we'll issue a request that results in a plain 200 response, but to
5058 // the to the same URL that we used to store sparse data, and making sure
5059 // that we ask for a range.
5060 RemoveMockTransaction(&kRangeGET_TransactionOK);
5061 MockTransaction transaction2(kSimpleGET_Transaction);
5062 transaction2.url = kRangeGET_TransactionOK.url;
5063 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
5064 AddMockTransaction(&transaction2);
5066 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
5068 std::string expected_headers(kSimpleGET_Transaction.status);
5069 expected_headers.append("\n");
5070 expected_headers.append(kSimpleGET_Transaction.response_headers);
5071 EXPECT_EQ(expected_headers, headers);
5072 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5073 EXPECT_EQ(1, cache.disk_cache()->open_count());
5074 EXPECT_EQ(1, cache.disk_cache()->create_count());
5076 RemoveMockTransaction(&transaction2);
5079 // Tests that a range request that falls outside of the size that we know about
5080 // only deletes the entry if the resource has indeed changed.
5081 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
5082 MockHttpCache cache;
5083 AddMockTransaction(&kRangeGET_TransactionOK);
5084 std::string headers;
5086 // Write to the cache (40-49).
5087 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5088 &headers);
5090 Verify206Response(headers, 40, 49);
5091 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5092 EXPECT_EQ(0, cache.disk_cache()->open_count());
5093 EXPECT_EQ(1, cache.disk_cache()->create_count());
5095 // A weird request should not delete this entry. Ask for bytes 120-.
5096 MockTransaction transaction(kRangeGET_TransactionOK);
5097 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
5098 transaction.data = "";
5099 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5101 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
5102 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5103 EXPECT_EQ(1, cache.disk_cache()->open_count());
5104 EXPECT_EQ(1, cache.disk_cache()->create_count());
5106 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5107 EXPECT_EQ(2, cache.disk_cache()->open_count());
5108 EXPECT_EQ(1, cache.disk_cache()->create_count());
5110 RemoveMockTransaction(&kRangeGET_TransactionOK);
5113 // Fails only on bots. crbug.com/533640
5114 #if defined(OS_ANDROID)
5115 #define MAYBE_RangeGET_Cancel DISABLED_RangeGET_Cancel
5116 #else
5117 #define MAYBE_RangeGET_Cancel RangeGET_Cancel
5118 #endif
5119 // Tests that we don't delete a sparse entry when we cancel a request.
5120 TEST(HttpCache, MAYBE_RangeGET_Cancel) {
5121 MockHttpCache cache;
5122 AddMockTransaction(&kRangeGET_TransactionOK);
5124 MockHttpRequest request(kRangeGET_TransactionOK);
5126 Context* c = new Context();
5127 int rv = cache.CreateTransaction(&c->trans);
5128 ASSERT_EQ(OK, rv);
5130 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5131 if (rv == ERR_IO_PENDING)
5132 rv = c->callback.WaitForResult();
5134 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5135 EXPECT_EQ(0, cache.disk_cache()->open_count());
5136 EXPECT_EQ(1, cache.disk_cache()->create_count());
5138 // Make sure that the entry has some data stored.
5139 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5140 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5141 if (rv == ERR_IO_PENDING)
5142 rv = c->callback.WaitForResult();
5143 EXPECT_EQ(buf->size(), rv);
5145 // Destroy the transaction.
5146 delete c;
5148 // Verify that the entry has not been deleted.
5149 disk_cache::Entry* entry;
5150 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5151 entry->Close();
5152 RemoveMockTransaction(&kRangeGET_TransactionOK);
5155 // Fails only on bots. crbug.com/533640
5156 #if defined(OS_ANDROID)
5157 #define MAYBE_RangeGET_Cancel2 DISABLED_RangeGET_Cancel2
5158 #else
5159 #define MAYBE_RangeGET_Cancel2 RangeGET_Cancel2
5160 #endif
5161 // Tests that we don't delete a sparse entry when we start a new request after
5162 // cancelling the previous one.
5163 TEST(HttpCache, MAYBE_RangeGET_Cancel2) {
5164 MockHttpCache cache;
5165 AddMockTransaction(&kRangeGET_TransactionOK);
5167 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5168 MockHttpRequest request(kRangeGET_TransactionOK);
5169 request.load_flags |= LOAD_VALIDATE_CACHE;
5171 Context* c = new Context();
5172 int rv = cache.CreateTransaction(&c->trans);
5173 ASSERT_EQ(OK, rv);
5175 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5176 if (rv == ERR_IO_PENDING)
5177 rv = c->callback.WaitForResult();
5179 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5180 EXPECT_EQ(1, cache.disk_cache()->open_count());
5181 EXPECT_EQ(1, cache.disk_cache()->create_count());
5183 // Make sure that we revalidate the entry and read from the cache (a single
5184 // read will return while waiting for the network).
5185 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
5186 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5187 EXPECT_EQ(5, c->callback.GetResult(rv));
5188 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5189 EXPECT_EQ(ERR_IO_PENDING, rv);
5191 // Destroy the transaction before completing the read.
5192 delete c;
5194 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5195 // message loop. This means that a new transaction will just reuse the same
5196 // active entry (no open or create).
5198 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5200 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5201 EXPECT_EQ(1, cache.disk_cache()->open_count());
5202 EXPECT_EQ(1, cache.disk_cache()->create_count());
5203 RemoveMockTransaction(&kRangeGET_TransactionOK);
5206 // A slight variation of the previous test, this time we cancel two requests in
5207 // a row, making sure that the second is waiting for the entry to be ready.
5208 TEST(HttpCache, RangeGET_Cancel3) {
5209 MockHttpCache cache;
5210 AddMockTransaction(&kRangeGET_TransactionOK);
5212 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5213 MockHttpRequest request(kRangeGET_TransactionOK);
5214 request.load_flags |= LOAD_VALIDATE_CACHE;
5216 Context* c = new Context();
5217 int rv = cache.CreateTransaction(&c->trans);
5218 ASSERT_EQ(OK, rv);
5220 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5221 EXPECT_EQ(ERR_IO_PENDING, rv);
5222 rv = c->callback.WaitForResult();
5224 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5225 EXPECT_EQ(1, cache.disk_cache()->open_count());
5226 EXPECT_EQ(1, cache.disk_cache()->create_count());
5228 // Make sure that we revalidate the entry and read from the cache (a single
5229 // read will return while waiting for the network).
5230 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
5231 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5232 EXPECT_EQ(5, c->callback.GetResult(rv));
5233 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5234 EXPECT_EQ(ERR_IO_PENDING, rv);
5236 // Destroy the transaction before completing the read.
5237 delete c;
5239 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5240 // message loop. This means that a new transaction will just reuse the same
5241 // active entry (no open or create).
5243 c = new Context();
5244 rv = cache.CreateTransaction(&c->trans);
5245 ASSERT_EQ(OK, rv);
5247 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5248 EXPECT_EQ(ERR_IO_PENDING, rv);
5250 MockDiskEntry::IgnoreCallbacks(true);
5251 base::MessageLoop::current()->RunUntilIdle();
5252 MockDiskEntry::IgnoreCallbacks(false);
5254 // The new transaction is waiting for the query range callback.
5255 delete c;
5257 // And we should not crash when the callback is delivered.
5258 base::MessageLoop::current()->RunUntilIdle();
5260 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5261 EXPECT_EQ(1, cache.disk_cache()->open_count());
5262 EXPECT_EQ(1, cache.disk_cache()->create_count());
5263 RemoveMockTransaction(&kRangeGET_TransactionOK);
5266 // Tests that an invalid range response results in no cached entry.
5267 TEST(HttpCache, RangeGET_InvalidResponse1) {
5268 MockHttpCache cache;
5269 std::string headers;
5271 MockTransaction transaction(kRangeGET_TransactionOK);
5272 transaction.handler = NULL;
5273 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
5274 "Content-Length: 10\n";
5275 AddMockTransaction(&transaction);
5276 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5278 std::string expected(transaction.status);
5279 expected.append("\n");
5280 expected.append(transaction.response_headers);
5281 EXPECT_EQ(expected, headers);
5283 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5284 EXPECT_EQ(0, cache.disk_cache()->open_count());
5285 EXPECT_EQ(1, cache.disk_cache()->create_count());
5287 // Verify that we don't have a cached entry.
5288 disk_cache::Entry* entry;
5289 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5291 RemoveMockTransaction(&kRangeGET_TransactionOK);
5294 // Tests that we reject a range that doesn't match the content-length.
5295 TEST(HttpCache, RangeGET_InvalidResponse2) {
5296 MockHttpCache cache;
5297 std::string headers;
5299 MockTransaction transaction(kRangeGET_TransactionOK);
5300 transaction.handler = NULL;
5301 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
5302 "Content-Length: 20\n";
5303 AddMockTransaction(&transaction);
5304 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5306 std::string expected(transaction.status);
5307 expected.append("\n");
5308 expected.append(transaction.response_headers);
5309 EXPECT_EQ(expected, headers);
5311 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5312 EXPECT_EQ(0, cache.disk_cache()->open_count());
5313 EXPECT_EQ(1, cache.disk_cache()->create_count());
5315 // Verify that we don't have a cached entry.
5316 disk_cache::Entry* entry;
5317 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5319 RemoveMockTransaction(&kRangeGET_TransactionOK);
5322 // Tests that if a server tells us conflicting information about a resource we
5323 // drop the entry.
5324 TEST(HttpCache, RangeGET_InvalidResponse3) {
5325 MockHttpCache cache;
5326 std::string headers;
5328 MockTransaction transaction(kRangeGET_TransactionOK);
5329 transaction.handler = NULL;
5330 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
5331 std::string response_headers(transaction.response_headers);
5332 response_headers.append("Content-Range: bytes 50-59/160\n");
5333 transaction.response_headers = response_headers.c_str();
5334 AddMockTransaction(&transaction);
5335 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5337 Verify206Response(headers, 50, 59);
5338 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5339 EXPECT_EQ(0, cache.disk_cache()->open_count());
5340 EXPECT_EQ(1, cache.disk_cache()->create_count());
5342 RemoveMockTransaction(&transaction);
5343 AddMockTransaction(&kRangeGET_TransactionOK);
5345 // This transaction will report a resource size of 80 bytes, and we think it's
5346 // 160 so we should ignore the response.
5347 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5348 &headers);
5350 Verify206Response(headers, 40, 49);
5351 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5352 EXPECT_EQ(1, cache.disk_cache()->open_count());
5353 EXPECT_EQ(1, cache.disk_cache()->create_count());
5355 // Verify that the entry is gone.
5356 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5357 EXPECT_EQ(1, cache.disk_cache()->open_count());
5358 EXPECT_EQ(2, cache.disk_cache()->create_count());
5359 RemoveMockTransaction(&kRangeGET_TransactionOK);
5362 // Tests that we handle large range values properly.
5363 TEST(HttpCache, RangeGET_LargeValues) {
5364 // We need a real sparse cache for this test.
5365 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5366 std::string headers;
5368 MockTransaction transaction(kRangeGET_TransactionOK);
5369 transaction.handler = NULL;
5370 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
5371 EXTRA_HEADER;
5372 transaction.response_headers =
5373 "ETag: \"foo\"\n"
5374 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5375 "Content-Length: 10\n";
5376 AddMockTransaction(&transaction);
5377 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5379 std::string expected(transaction.status);
5380 expected.append("\n");
5381 expected.append(transaction.response_headers);
5382 EXPECT_EQ(expected, headers);
5384 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5386 // Verify that we have a cached entry.
5387 disk_cache::Entry* en;
5388 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
5389 en->Close();
5391 RemoveMockTransaction(&kRangeGET_TransactionOK);
5394 // Tests that we don't crash with a range request if the disk cache was not
5395 // initialized properly.
5396 TEST(HttpCache, RangeGET_NoDiskCache) {
5397 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
5398 factory->set_fail(true);
5399 factory->FinishCreation(); // We'll complete synchronously.
5400 MockHttpCache cache(factory);
5402 AddMockTransaction(&kRangeGET_TransactionOK);
5404 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5405 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5407 RemoveMockTransaction(&kRangeGET_TransactionOK);
5410 // Tests that we handle byte range requests that skip the cache.
5411 TEST(HttpCache, RangeHEAD) {
5412 MockHttpCache cache;
5413 AddMockTransaction(&kRangeGET_TransactionOK);
5415 MockTransaction transaction(kRangeGET_TransactionOK);
5416 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
5417 transaction.method = "HEAD";
5418 transaction.data = "rg: 70-79 ";
5420 std::string headers;
5421 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5423 Verify206Response(headers, 70, 79);
5424 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5425 EXPECT_EQ(0, cache.disk_cache()->open_count());
5426 EXPECT_EQ(0, cache.disk_cache()->create_count());
5428 RemoveMockTransaction(&kRangeGET_TransactionOK);
5431 // Tests that we don't crash when after reading from the cache we issue a
5432 // request for the next range and the server gives us a 200 synchronously.
5433 TEST(HttpCache, RangeGET_FastFlakyServer) {
5434 MockHttpCache cache;
5436 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5437 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
5438 transaction.test_mode = TEST_MODE_SYNC_NET_START;
5439 transaction.load_flags |= LOAD_VALIDATE_CACHE;
5441 // Write to the cache.
5442 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5444 // And now read from the cache and the network.
5445 RangeTransactionServer handler;
5446 handler.set_bad_200(true);
5447 transaction.data = "Not a range";
5448 BoundTestNetLog log;
5449 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
5451 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5452 EXPECT_EQ(1, cache.disk_cache()->open_count());
5453 EXPECT_EQ(1, cache.disk_cache()->create_count());
5454 EXPECT_TRUE(LogContainsEventType(
5455 log, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
5458 // Tests that when the server gives us less data than expected, we don't keep
5459 // asking for more data.
5460 TEST(HttpCache, RangeGET_FastFlakyServer2) {
5461 MockHttpCache cache;
5463 // First, check with an empty cache (WRITE mode).
5464 MockTransaction transaction(kRangeGET_TransactionOK);
5465 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
5466 transaction.data = "rg: 40-"; // Less than expected.
5467 transaction.handler = NULL;
5468 std::string headers(transaction.response_headers);
5469 headers.append("Content-Range: bytes 40-49/80\n");
5470 transaction.response_headers = headers.c_str();
5472 AddMockTransaction(&transaction);
5474 // Write to the cache.
5475 RunTransactionTest(cache.http_cache(), transaction);
5477 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5478 EXPECT_EQ(0, cache.disk_cache()->open_count());
5479 EXPECT_EQ(1, cache.disk_cache()->create_count());
5481 // Now verify that even in READ_WRITE mode, we forward the bad response to
5482 // the caller.
5483 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
5484 transaction.data = "rg: 60-"; // Less than expected.
5485 headers = kRangeGET_TransactionOK.response_headers;
5486 headers.append("Content-Range: bytes 60-69/80\n");
5487 transaction.response_headers = headers.c_str();
5489 RunTransactionTest(cache.http_cache(), transaction);
5491 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5492 EXPECT_EQ(1, cache.disk_cache()->open_count());
5493 EXPECT_EQ(1, cache.disk_cache()->create_count());
5495 RemoveMockTransaction(&transaction);
5498 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5499 // This test hits a NOTREACHED so it is a release mode only test.
5500 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
5501 MockHttpCache cache;
5502 AddMockTransaction(&kRangeGET_TransactionOK);
5504 // Write to the cache (40-49).
5505 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5506 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5507 EXPECT_EQ(0, cache.disk_cache()->open_count());
5508 EXPECT_EQ(1, cache.disk_cache()->create_count());
5510 // Force this transaction to read from the cache.
5511 MockTransaction transaction(kRangeGET_TransactionOK);
5512 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
5514 MockHttpRequest request(transaction);
5515 TestCompletionCallback callback;
5517 scoped_ptr<HttpTransaction> trans;
5518 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5519 EXPECT_EQ(OK, rv);
5520 ASSERT_TRUE(trans.get());
5522 rv = trans->Start(&request, callback.callback(), BoundNetLog());
5523 if (rv == ERR_IO_PENDING)
5524 rv = callback.WaitForResult();
5525 ASSERT_EQ(ERR_CACHE_MISS, rv);
5527 trans.reset();
5529 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5530 EXPECT_EQ(1, cache.disk_cache()->open_count());
5531 EXPECT_EQ(1, cache.disk_cache()->create_count());
5533 RemoveMockTransaction(&kRangeGET_TransactionOK);
5535 #endif
5537 // Tests the handling of the "truncation" flag.
5538 TEST(HttpCache, WriteResponseInfo_Truncated) {
5539 MockHttpCache cache;
5540 disk_cache::Entry* entry;
5541 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5542 NULL));
5544 std::string headers("HTTP/1.1 200 OK");
5545 headers = HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5546 HttpResponseInfo response;
5547 response.headers = new HttpResponseHeaders(headers);
5549 // Set the last argument for this to be an incomplete request.
5550 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
5551 bool truncated = false;
5552 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5553 EXPECT_TRUE(truncated);
5555 // And now test the opposite case.
5556 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
5557 truncated = true;
5558 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5559 EXPECT_FALSE(truncated);
5560 entry->Close();
5563 // Tests basic pickling/unpickling of HttpResponseInfo.
5564 TEST(HttpCache, PersistHttpResponseInfo) {
5565 // Set some fields (add more if needed.)
5566 HttpResponseInfo response1;
5567 response1.was_cached = false;
5568 response1.socket_address = HostPortPair("1.2.3.4", 80);
5569 response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK");
5571 // Pickle.
5572 base::Pickle pickle;
5573 response1.Persist(&pickle, false, false);
5575 // Unpickle.
5576 HttpResponseInfo response2;
5577 bool response_truncated;
5578 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5579 EXPECT_FALSE(response_truncated);
5581 // Verify fields.
5582 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5583 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5584 EXPECT_EQ(80, response2.socket_address.port());
5585 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5588 // Tests that we delete an entry when the request is cancelled before starting
5589 // to read from the network.
5590 TEST(HttpCache, DoomOnDestruction) {
5591 MockHttpCache cache;
5593 MockHttpRequest request(kSimpleGET_Transaction);
5595 Context* c = new Context();
5596 int rv = cache.CreateTransaction(&c->trans);
5597 ASSERT_EQ(OK, rv);
5599 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5600 if (rv == ERR_IO_PENDING)
5601 c->result = c->callback.WaitForResult();
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 // Destroy the transaction. We only have the headers so we should delete this
5608 // entry.
5609 delete c;
5611 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5613 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5614 EXPECT_EQ(0, cache.disk_cache()->open_count());
5615 EXPECT_EQ(2, cache.disk_cache()->create_count());
5618 // Tests that we delete an entry when the request is cancelled if the response
5619 // does not have content-length and strong validators.
5620 TEST(HttpCache, DoomOnDestruction2) {
5621 MockHttpCache cache;
5623 MockHttpRequest request(kSimpleGET_Transaction);
5625 Context* c = new Context();
5626 int rv = cache.CreateTransaction(&c->trans);
5627 ASSERT_EQ(OK, rv);
5629 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5630 if (rv == ERR_IO_PENDING)
5631 rv = c->callback.WaitForResult();
5633 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5634 EXPECT_EQ(0, cache.disk_cache()->open_count());
5635 EXPECT_EQ(1, cache.disk_cache()->create_count());
5637 // Make sure that the entry has some data stored.
5638 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5639 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5640 if (rv == ERR_IO_PENDING)
5641 rv = c->callback.WaitForResult();
5642 EXPECT_EQ(buf->size(), rv);
5644 // Destroy the transaction.
5645 delete c;
5647 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5649 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5650 EXPECT_EQ(0, cache.disk_cache()->open_count());
5651 EXPECT_EQ(2, cache.disk_cache()->create_count());
5654 // Tests that we delete an entry when the request is cancelled if the response
5655 // has an "Accept-Ranges: none" header.
5656 TEST(HttpCache, DoomOnDestruction3) {
5657 MockHttpCache cache;
5659 MockTransaction transaction(kSimpleGET_Transaction);
5660 transaction.response_headers =
5661 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5662 "Content-Length: 22\n"
5663 "Accept-Ranges: none\n"
5664 "Etag: \"foopy\"\n";
5665 AddMockTransaction(&transaction);
5666 MockHttpRequest request(transaction);
5668 Context* c = new Context();
5669 int rv = cache.CreateTransaction(&c->trans);
5670 ASSERT_EQ(OK, rv);
5672 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5673 if (rv == ERR_IO_PENDING)
5674 rv = c->callback.WaitForResult();
5676 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5677 EXPECT_EQ(0, cache.disk_cache()->open_count());
5678 EXPECT_EQ(1, cache.disk_cache()->create_count());
5680 // Make sure that the entry has some data stored.
5681 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5682 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5683 if (rv == ERR_IO_PENDING)
5684 rv = c->callback.WaitForResult();
5685 EXPECT_EQ(buf->size(), rv);
5687 // Destroy the transaction.
5688 delete c;
5690 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5692 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5693 EXPECT_EQ(0, cache.disk_cache()->open_count());
5694 EXPECT_EQ(2, cache.disk_cache()->create_count());
5696 RemoveMockTransaction(&transaction);
5699 // Tests that we mark an entry as incomplete when the request is cancelled.
5700 TEST(HttpCache, SetTruncatedFlag) {
5701 MockHttpCache cache;
5703 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5704 transaction.response_headers =
5705 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5706 "Content-Length: 22\n"
5707 "Etag: \"foopy\"\n";
5708 MockHttpRequest request(transaction);
5710 scoped_ptr<Context> c(new Context());
5712 int rv = cache.CreateTransaction(&c->trans);
5713 ASSERT_EQ(OK, rv);
5715 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5716 if (rv == ERR_IO_PENDING)
5717 rv = c->callback.WaitForResult();
5719 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5720 EXPECT_EQ(0, cache.disk_cache()->open_count());
5721 EXPECT_EQ(1, cache.disk_cache()->create_count());
5723 // Make sure that the entry has some data stored.
5724 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
5725 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5726 if (rv == ERR_IO_PENDING)
5727 rv = c->callback.WaitForResult();
5728 EXPECT_EQ(buf->size(), rv);
5730 // We want to cancel the request when the transaction is busy.
5731 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5732 EXPECT_EQ(ERR_IO_PENDING, rv);
5733 EXPECT_FALSE(c->callback.have_result());
5735 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
5737 // Destroy the transaction.
5738 c->trans.reset();
5739 MockHttpCache::SetTestMode(0);
5742 // Make sure that we don't invoke the callback. We may have an issue if the
5743 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5744 // could end up with the transaction being deleted twice if we send any
5745 // notification from the transaction destructor (see http://crbug.com/31723).
5746 EXPECT_FALSE(c->callback.have_result());
5748 // Verify that the entry is marked as incomplete.
5749 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
5752 // Tests that we don't mark an entry as truncated when we read everything.
5753 TEST(HttpCache, DontSetTruncatedFlag) {
5754 MockHttpCache cache;
5756 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5757 transaction.response_headers =
5758 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5759 "Content-Length: 22\n"
5760 "Etag: \"foopy\"\n";
5761 MockHttpRequest request(transaction);
5763 scoped_ptr<Context> c(new Context());
5764 int rv = cache.CreateTransaction(&c->trans);
5765 ASSERT_EQ(OK, rv);
5767 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5768 EXPECT_EQ(OK, c->callback.GetResult(rv));
5770 // Read everything.
5771 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(22));
5772 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5773 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5775 // Destroy the transaction.
5776 c->trans.reset();
5778 // Verify that the entry is not marked as truncated.
5779 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, false, 0);
5782 // Tests that sparse entries don't set the truncate flag.
5783 TEST(HttpCache, RangeGET_DontTruncate) {
5784 MockHttpCache cache;
5786 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5787 transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
5789 scoped_ptr<MockHttpRequest> request(new MockHttpRequest(transaction));
5790 scoped_ptr<HttpTransaction> trans;
5792 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5793 EXPECT_EQ(OK, rv);
5795 TestCompletionCallback cb;
5796 rv = trans->Start(request.get(), cb.callback(), BoundNetLog());
5797 EXPECT_EQ(0, cb.GetResult(rv));
5799 scoped_refptr<IOBuffer> buf(new IOBuffer(10));
5800 rv = trans->Read(buf.get(), 10, cb.callback());
5801 EXPECT_EQ(10, cb.GetResult(rv));
5803 // Should not trigger any DCHECK.
5804 trans.reset();
5805 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 0);
5808 // Tests that sparse entries don't set the truncate flag (when the byte range
5809 // starts after 0).
5810 TEST(HttpCache, RangeGET_DontTruncate2) {
5811 MockHttpCache cache;
5813 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5814 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
5816 scoped_ptr<MockHttpRequest> request(new MockHttpRequest(transaction));
5817 scoped_ptr<HttpTransaction> trans;
5819 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5820 EXPECT_EQ(OK, rv);
5822 TestCompletionCallback cb;
5823 rv = trans->Start(request.get(), cb.callback(), BoundNetLog());
5824 EXPECT_EQ(0, cb.GetResult(rv));
5826 scoped_refptr<IOBuffer> buf(new IOBuffer(10));
5827 rv = trans->Read(buf.get(), 10, cb.callback());
5828 EXPECT_EQ(10, cb.GetResult(rv));
5830 // Should not trigger any DCHECK.
5831 trans.reset();
5832 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 0);
5835 // Tests that we can continue with a request that was interrupted.
5836 TEST(HttpCache, GET_IncompleteResource) {
5837 MockHttpCache cache;
5838 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5840 std::string raw_headers("HTTP/1.1 200 OK\n"
5841 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5842 "ETag: \"foo\"\n"
5843 "Accept-Ranges: bytes\n"
5844 "Content-Length: 80\n");
5845 CreateTruncatedEntry(raw_headers, &cache);
5847 // Now make a regular request.
5848 std::string headers;
5849 transaction.request_headers = EXTRA_HEADER;
5850 transaction.data = kFullRangeData;
5851 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5853 // We update the headers with the ones received while revalidating.
5854 std::string expected_headers(
5855 "HTTP/1.1 200 OK\n"
5856 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5857 "Accept-Ranges: bytes\n"
5858 "ETag: \"foo\"\n"
5859 "Content-Length: 80\n");
5861 EXPECT_EQ(expected_headers, headers);
5862 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5863 EXPECT_EQ(1, cache.disk_cache()->open_count());
5864 EXPECT_EQ(1, cache.disk_cache()->create_count());
5866 // Verify that the disk entry was updated.
5867 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80);
5870 // Tests the handling of no-store when revalidating a truncated entry.
5871 TEST(HttpCache, GET_IncompleteResource_NoStore) {
5872 MockHttpCache cache;
5873 AddMockTransaction(&kRangeGET_TransactionOK);
5875 std::string raw_headers("HTTP/1.1 200 OK\n"
5876 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5877 "ETag: \"foo\"\n"
5878 "Accept-Ranges: bytes\n"
5879 "Content-Length: 80\n");
5880 CreateTruncatedEntry(raw_headers, &cache);
5881 RemoveMockTransaction(&kRangeGET_TransactionOK);
5883 // Now make a regular request.
5884 MockTransaction transaction(kRangeGET_TransactionOK);
5885 transaction.request_headers = EXTRA_HEADER;
5886 std::string response_headers(transaction.response_headers);
5887 response_headers += ("Cache-Control: no-store\n");
5888 transaction.response_headers = response_headers.c_str();
5889 transaction.data = kFullRangeData;
5890 AddMockTransaction(&transaction);
5892 std::string headers;
5893 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5895 // We update the headers with the ones received while revalidating.
5896 std::string expected_headers(
5897 "HTTP/1.1 200 OK\n"
5898 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5899 "Accept-Ranges: bytes\n"
5900 "Cache-Control: no-store\n"
5901 "ETag: \"foo\"\n"
5902 "Content-Length: 80\n");
5904 EXPECT_EQ(expected_headers, headers);
5905 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5906 EXPECT_EQ(1, cache.disk_cache()->open_count());
5907 EXPECT_EQ(1, cache.disk_cache()->create_count());
5909 // Verify that the disk entry was deleted.
5910 disk_cache::Entry* entry;
5911 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5912 RemoveMockTransaction(&transaction);
5915 // Tests cancelling a request after the server sent no-store.
5916 TEST(HttpCache, GET_IncompleteResource_Cancel) {
5917 MockHttpCache cache;
5918 AddMockTransaction(&kRangeGET_TransactionOK);
5920 std::string raw_headers("HTTP/1.1 200 OK\n"
5921 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5922 "ETag: \"foo\"\n"
5923 "Accept-Ranges: bytes\n"
5924 "Content-Length: 80\n");
5925 CreateTruncatedEntry(raw_headers, &cache);
5926 RemoveMockTransaction(&kRangeGET_TransactionOK);
5928 // Now make a regular request.
5929 MockTransaction transaction(kRangeGET_TransactionOK);
5930 transaction.request_headers = EXTRA_HEADER;
5931 std::string response_headers(transaction.response_headers);
5932 response_headers += ("Cache-Control: no-store\n");
5933 transaction.response_headers = response_headers.c_str();
5934 transaction.data = kFullRangeData;
5935 AddMockTransaction(&transaction);
5937 MockHttpRequest request(transaction);
5938 Context* c = new Context();
5940 int rv = cache.CreateTransaction(&c->trans);
5941 ASSERT_EQ(OK, rv);
5943 // Queue another request to this transaction. We have to start this request
5944 // before the first one gets the response from the server and dooms the entry,
5945 // otherwise it will just create a new entry without being queued to the first
5946 // request.
5947 Context* pending = new Context();
5948 ASSERT_EQ(OK, cache.CreateTransaction(&pending->trans));
5950 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5951 EXPECT_EQ(ERR_IO_PENDING,
5952 pending->trans->Start(&request, pending->callback.callback(),
5953 BoundNetLog()));
5954 EXPECT_EQ(OK, c->callback.GetResult(rv));
5956 // Make sure that the entry has some data stored.
5957 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
5958 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5959 EXPECT_EQ(5, c->callback.GetResult(rv));
5961 // Cancel the requests.
5962 delete c;
5963 delete pending;
5965 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5966 EXPECT_EQ(1, cache.disk_cache()->open_count());
5967 EXPECT_EQ(2, cache.disk_cache()->create_count());
5969 base::MessageLoop::current()->RunUntilIdle();
5970 RemoveMockTransaction(&transaction);
5973 // Tests that we delete truncated entries if the server changes its mind midway.
5974 TEST(HttpCache, GET_IncompleteResource2) {
5975 MockHttpCache cache;
5976 AddMockTransaction(&kRangeGET_TransactionOK);
5978 // Content-length will be intentionally bad.
5979 std::string raw_headers("HTTP/1.1 200 OK\n"
5980 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5981 "ETag: \"foo\"\n"
5982 "Accept-Ranges: bytes\n"
5983 "Content-Length: 50\n");
5984 CreateTruncatedEntry(raw_headers, &cache);
5986 // Now make a regular request. We expect the code to fail the validation and
5987 // retry the request without using byte ranges.
5988 std::string headers;
5989 MockTransaction transaction(kRangeGET_TransactionOK);
5990 transaction.request_headers = EXTRA_HEADER;
5991 transaction.data = "Not a range";
5992 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5994 // The server will return 200 instead of a byte range.
5995 std::string expected_headers(
5996 "HTTP/1.1 200 OK\n"
5997 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5999 EXPECT_EQ(expected_headers, headers);
6000 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6001 EXPECT_EQ(1, cache.disk_cache()->open_count());
6002 EXPECT_EQ(1, cache.disk_cache()->create_count());
6004 // Verify that the disk entry was deleted.
6005 disk_cache::Entry* entry;
6006 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6007 RemoveMockTransaction(&kRangeGET_TransactionOK);
6010 // Tests that we always validate a truncated request.
6011 TEST(HttpCache, GET_IncompleteResource3) {
6012 MockHttpCache cache;
6013 AddMockTransaction(&kRangeGET_TransactionOK);
6015 // This should not require validation for 10 hours.
6016 std::string raw_headers("HTTP/1.1 200 OK\n"
6017 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6018 "ETag: \"foo\"\n"
6019 "Cache-Control: max-age= 36000\n"
6020 "Accept-Ranges: bytes\n"
6021 "Content-Length: 80\n");
6022 CreateTruncatedEntry(raw_headers, &cache);
6024 // Now make a regular request.
6025 std::string headers;
6026 MockTransaction transaction(kRangeGET_TransactionOK);
6027 transaction.request_headers = EXTRA_HEADER;
6028 transaction.data = kFullRangeData;
6030 scoped_ptr<Context> c(new Context);
6031 int rv = cache.CreateTransaction(&c->trans);
6032 ASSERT_EQ(OK, rv);
6034 MockHttpRequest request(transaction);
6035 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6036 EXPECT_EQ(OK, c->callback.GetResult(rv));
6038 // We should have checked with the server before finishing Start().
6039 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6040 EXPECT_EQ(1, cache.disk_cache()->open_count());
6041 EXPECT_EQ(1, cache.disk_cache()->create_count());
6043 RemoveMockTransaction(&kRangeGET_TransactionOK);
6046 // Tests that we handle 401s for truncated resources.
6047 TEST(HttpCache, GET_IncompleteResourceWithAuth) {
6048 MockHttpCache cache;
6049 AddMockTransaction(&kRangeGET_TransactionOK);
6051 std::string raw_headers("HTTP/1.1 200 OK\n"
6052 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6053 "ETag: \"foo\"\n"
6054 "Accept-Ranges: bytes\n"
6055 "Content-Length: 80\n");
6056 CreateTruncatedEntry(raw_headers, &cache);
6058 // Now make a regular request.
6059 MockTransaction transaction(kRangeGET_TransactionOK);
6060 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
6061 EXTRA_HEADER;
6062 transaction.data = kFullRangeData;
6063 RangeTransactionServer handler;
6065 scoped_ptr<Context> c(new Context);
6066 int rv = cache.CreateTransaction(&c->trans);
6067 ASSERT_EQ(OK, rv);
6069 MockHttpRequest request(transaction);
6070 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6071 EXPECT_EQ(OK, c->callback.GetResult(rv));
6073 const HttpResponseInfo* response = c->trans->GetResponseInfo();
6074 ASSERT_TRUE(response);
6075 ASSERT_EQ(401, response->headers->response_code());
6076 rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
6077 EXPECT_EQ(OK, c->callback.GetResult(rv));
6078 response = c->trans->GetResponseInfo();
6079 ASSERT_TRUE(response);
6080 ASSERT_EQ(200, response->headers->response_code());
6082 ReadAndVerifyTransaction(c->trans.get(), transaction);
6083 c.reset(); // The destructor could delete the entry.
6084 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6086 // Verify that the entry was not deleted.
6087 disk_cache::Entry* entry;
6088 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6089 entry->Close();
6091 RemoveMockTransaction(&kRangeGET_TransactionOK);
6094 // Test that the transaction won't retry failed partial requests
6095 // after it starts reading data. http://crbug.com/474835
6096 TEST(HttpCache, TransactionRetryLimit) {
6097 MockHttpCache cache;
6099 // Cache 0-9, so that we have data to read before failing.
6100 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
6101 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
6102 transaction.data = "rg: 00-09 ";
6104 // Write to the cache.
6105 RunTransactionTest(cache.http_cache(), transaction);
6106 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6108 // And now read from the cache and the network. 10-19 will get a
6109 // 401, but will have already returned 0-9.
6110 // We do not set X-Require-Mock-Auth because that causes the mock
6111 // network transaction to become IsReadyToRestartForAuth().
6112 transaction.request_headers =
6113 "Range: bytes = 0-79\r\n"
6114 "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER;
6116 scoped_ptr<Context> c(new Context);
6117 int rv = cache.CreateTransaction(&c->trans);
6118 ASSERT_EQ(OK, rv);
6120 MockHttpRequest request(transaction);
6122 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6123 if (rv == ERR_IO_PENDING)
6124 rv = c->callback.WaitForResult();
6125 std::string content;
6126 rv = ReadTransaction(c->trans.get(), &content);
6127 EXPECT_EQ(ERR_CACHE_AUTH_FAILURE_AFTER_READ, rv);
6130 // Tests that we cache a 200 response to the validation request.
6131 TEST(HttpCache, GET_IncompleteResource4) {
6132 MockHttpCache cache;
6133 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
6135 std::string raw_headers("HTTP/1.1 200 OK\n"
6136 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6137 "ETag: \"foo\"\n"
6138 "Accept-Ranges: bytes\n"
6139 "Content-Length: 80\n");
6140 CreateTruncatedEntry(raw_headers, &cache);
6142 // Now make a regular request.
6143 std::string headers;
6144 transaction.request_headers = EXTRA_HEADER;
6145 transaction.data = "Not a range";
6146 RangeTransactionServer handler;
6147 handler.set_bad_200(true);
6148 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
6150 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6151 EXPECT_EQ(1, cache.disk_cache()->open_count());
6152 EXPECT_EQ(1, cache.disk_cache()->create_count());
6154 // Verify that the disk entry was updated.
6155 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 11);
6158 // Tests that when we cancel a request that was interrupted, we mark it again
6159 // as truncated.
6160 TEST(HttpCache, GET_CancelIncompleteResource) {
6161 MockHttpCache cache;
6162 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
6164 std::string raw_headers("HTTP/1.1 200 OK\n"
6165 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6166 "ETag: \"foo\"\n"
6167 "Accept-Ranges: bytes\n"
6168 "Content-Length: 80\n");
6169 CreateTruncatedEntry(raw_headers, &cache);
6171 // Now make a regular request.
6172 transaction.request_headers = EXTRA_HEADER;
6174 MockHttpRequest request(transaction);
6175 Context* c = new Context();
6176 int rv = cache.CreateTransaction(&c->trans);
6177 ASSERT_EQ(OK, rv);
6179 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6180 EXPECT_EQ(OK, c->callback.GetResult(rv));
6182 // Read 20 bytes from the cache, and 10 from the net.
6183 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
6184 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
6185 EXPECT_EQ(20, c->callback.GetResult(rv));
6186 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
6187 EXPECT_EQ(10, c->callback.GetResult(rv));
6189 // At this point, we are already reading so canceling the request should leave
6190 // a truncated one.
6191 delete c;
6193 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6194 EXPECT_EQ(1, cache.disk_cache()->open_count());
6195 EXPECT_EQ(1, cache.disk_cache()->create_count());
6197 // Verify that the disk entry was updated: now we have 30 bytes.
6198 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, true, 30);
6201 // Tests that we can handle range requests when we have a truncated entry.
6202 TEST(HttpCache, RangeGET_IncompleteResource) {
6203 MockHttpCache cache;
6204 AddMockTransaction(&kRangeGET_TransactionOK);
6206 // Content-length will be intentionally bogus.
6207 std::string raw_headers("HTTP/1.1 200 OK\n"
6208 "Last-Modified: something\n"
6209 "ETag: \"foo\"\n"
6210 "Accept-Ranges: bytes\n"
6211 "Content-Length: 10\n");
6212 CreateTruncatedEntry(raw_headers, &cache);
6214 // Now make a range request.
6215 std::string headers;
6216 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
6217 &headers);
6219 Verify206Response(headers, 40, 49);
6220 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6221 EXPECT_EQ(1, cache.disk_cache()->open_count());
6222 EXPECT_EQ(2, cache.disk_cache()->create_count());
6224 RemoveMockTransaction(&kRangeGET_TransactionOK);
6227 TEST(HttpCache, SyncRead) {
6228 MockHttpCache cache;
6230 // This test ensures that a read that completes synchronously does not cause
6231 // any problems.
6233 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6234 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
6235 TEST_MODE_SYNC_CACHE_READ |
6236 TEST_MODE_SYNC_CACHE_WRITE);
6238 MockHttpRequest r1(transaction),
6239 r2(transaction),
6240 r3(transaction);
6242 TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
6243 c2(DEFAULT_PRIORITY, cache.http_cache()),
6244 c3(DEFAULT_PRIORITY, cache.http_cache());
6246 c1.Start(&r1, BoundNetLog());
6248 r2.load_flags |= LOAD_ONLY_FROM_CACHE;
6249 c2.Start(&r2, BoundNetLog());
6251 r3.load_flags |= LOAD_ONLY_FROM_CACHE;
6252 c3.Start(&r3, BoundNetLog());
6254 base::MessageLoop::current()->Run();
6256 EXPECT_TRUE(c1.is_done());
6257 EXPECT_TRUE(c2.is_done());
6258 EXPECT_TRUE(c3.is_done());
6260 EXPECT_EQ(OK, c1.error());
6261 EXPECT_EQ(OK, c2.error());
6262 EXPECT_EQ(OK, c3.error());
6265 TEST(HttpCache, ValidationResultsIn200) {
6266 MockHttpCache cache;
6268 // This test ensures that a conditional request, which results in a 200
6269 // instead of a 304, properly truncates the existing response data.
6271 // write to the cache
6272 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6274 // force this transaction to validate the cache
6275 MockTransaction transaction(kETagGET_Transaction);
6276 transaction.load_flags |= LOAD_VALIDATE_CACHE;
6277 RunTransactionTest(cache.http_cache(), transaction);
6279 // read from the cache
6280 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6283 TEST(HttpCache, CachedRedirect) {
6284 MockHttpCache cache;
6286 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
6287 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
6288 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
6290 MockHttpRequest request(kTestTransaction);
6291 TestCompletionCallback callback;
6293 // Write to the cache.
6295 scoped_ptr<HttpTransaction> trans;
6296 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6298 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6299 if (rv == ERR_IO_PENDING)
6300 rv = callback.WaitForResult();
6301 ASSERT_EQ(OK, rv);
6303 const HttpResponseInfo* info = trans->GetResponseInfo();
6304 ASSERT_TRUE(info);
6306 EXPECT_EQ(info->headers->response_code(), 301);
6308 std::string location;
6309 info->headers->EnumerateHeader(NULL, "Location", &location);
6310 EXPECT_EQ(location, "http://www.bar.com/");
6312 // Mark the transaction as completed so it is cached.
6313 trans->DoneReading();
6315 // Destroy transaction when going out of scope. We have not actually
6316 // read the response body -- want to test that it is still getting cached.
6318 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6319 EXPECT_EQ(0, cache.disk_cache()->open_count());
6320 EXPECT_EQ(1, cache.disk_cache()->create_count());
6322 // Active entries in the cache are not retired synchronously. Make
6323 // sure the next run hits the MockHttpCache and open_count is
6324 // correct.
6325 base::MessageLoop::current()->RunUntilIdle();
6327 // Read from the cache.
6329 scoped_ptr<HttpTransaction> trans;
6330 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6332 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6333 if (rv == ERR_IO_PENDING)
6334 rv = callback.WaitForResult();
6335 ASSERT_EQ(OK, rv);
6337 const HttpResponseInfo* info = trans->GetResponseInfo();
6338 ASSERT_TRUE(info);
6340 EXPECT_EQ(info->headers->response_code(), 301);
6342 std::string location;
6343 info->headers->EnumerateHeader(NULL, "Location", &location);
6344 EXPECT_EQ(location, "http://www.bar.com/");
6346 // Mark the transaction as completed so it is cached.
6347 trans->DoneReading();
6349 // Destroy transaction when going out of scope. We have not actually
6350 // read the response body -- want to test that it is still getting cached.
6352 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6353 EXPECT_EQ(1, cache.disk_cache()->open_count());
6354 EXPECT_EQ(1, cache.disk_cache()->create_count());
6357 // Verify that no-cache resources are stored in cache, but are not fetched from
6358 // cache during normal loads.
6359 TEST(HttpCache, CacheControlNoCacheNormalLoad) {
6360 MockHttpCache cache;
6362 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6363 transaction.response_headers = "cache-control: no-cache\n";
6365 // Initial load.
6366 RunTransactionTest(cache.http_cache(), transaction);
6368 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6369 EXPECT_EQ(0, cache.disk_cache()->open_count());
6370 EXPECT_EQ(1, cache.disk_cache()->create_count());
6372 // Try loading again; it should result in a network fetch.
6373 RunTransactionTest(cache.http_cache(), transaction);
6375 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6376 EXPECT_EQ(1, cache.disk_cache()->open_count());
6377 EXPECT_EQ(1, cache.disk_cache()->create_count());
6379 disk_cache::Entry* entry;
6380 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6381 entry->Close();
6384 // Verify that no-cache resources are stored in cache and fetched from cache
6385 // when the LOAD_PREFERRING_CACHE flag is set.
6386 TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
6387 MockHttpCache cache;
6389 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6390 transaction.response_headers = "cache-control: no-cache\n";
6392 // Initial load.
6393 RunTransactionTest(cache.http_cache(), transaction);
6395 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6396 EXPECT_EQ(0, cache.disk_cache()->open_count());
6397 EXPECT_EQ(1, cache.disk_cache()->create_count());
6399 // Try loading again with LOAD_PREFERRING_CACHE.
6400 transaction.load_flags = LOAD_PREFERRING_CACHE;
6401 RunTransactionTest(cache.http_cache(), transaction);
6403 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6404 EXPECT_EQ(1, cache.disk_cache()->open_count());
6405 EXPECT_EQ(1, cache.disk_cache()->create_count());
6407 disk_cache::Entry* entry;
6408 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6409 entry->Close();
6412 TEST(HttpCache, CacheControlNoStore) {
6413 MockHttpCache cache;
6415 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6416 transaction.response_headers = "cache-control: no-store\n";
6418 // initial load
6419 RunTransactionTest(cache.http_cache(), transaction);
6421 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6422 EXPECT_EQ(0, cache.disk_cache()->open_count());
6423 EXPECT_EQ(1, cache.disk_cache()->create_count());
6425 // try loading again; it should result in a network fetch
6426 RunTransactionTest(cache.http_cache(), transaction);
6428 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6429 EXPECT_EQ(0, cache.disk_cache()->open_count());
6430 EXPECT_EQ(2, cache.disk_cache()->create_count());
6432 disk_cache::Entry* entry;
6433 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
6436 TEST(HttpCache, CacheControlNoStore2) {
6437 // this test is similar to the above test, except that the initial response
6438 // is cachable, but when it is validated, no-store is received causing the
6439 // cached document to be deleted.
6440 MockHttpCache cache;
6442 ScopedMockTransaction transaction(kETagGET_Transaction);
6444 // initial load
6445 RunTransactionTest(cache.http_cache(), transaction);
6447 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6448 EXPECT_EQ(0, cache.disk_cache()->open_count());
6449 EXPECT_EQ(1, cache.disk_cache()->create_count());
6451 // try loading again; it should result in a network fetch
6452 transaction.load_flags = LOAD_VALIDATE_CACHE;
6453 transaction.response_headers = "cache-control: no-store\n";
6454 RunTransactionTest(cache.http_cache(), transaction);
6456 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6457 EXPECT_EQ(1, cache.disk_cache()->open_count());
6458 EXPECT_EQ(1, cache.disk_cache()->create_count());
6460 disk_cache::Entry* entry;
6461 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
6464 TEST(HttpCache, CacheControlNoStore3) {
6465 // this test is similar to the above test, except that the response is a 304
6466 // instead of a 200. this should never happen in practice, but it seems like
6467 // a good thing to verify that we still destroy the cache entry.
6468 MockHttpCache cache;
6470 ScopedMockTransaction transaction(kETagGET_Transaction);
6472 // initial load
6473 RunTransactionTest(cache.http_cache(), transaction);
6475 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6476 EXPECT_EQ(0, cache.disk_cache()->open_count());
6477 EXPECT_EQ(1, cache.disk_cache()->create_count());
6479 // try loading again; it should result in a network fetch
6480 transaction.load_flags = LOAD_VALIDATE_CACHE;
6481 transaction.response_headers = "cache-control: no-store\n";
6482 transaction.status = "HTTP/1.1 304 Not Modified";
6483 RunTransactionTest(cache.http_cache(), transaction);
6485 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6486 EXPECT_EQ(1, cache.disk_cache()->open_count());
6487 EXPECT_EQ(1, cache.disk_cache()->create_count());
6489 disk_cache::Entry* entry;
6490 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
6493 // Ensure that we don't cache requests served over bad HTTPS.
6494 TEST(HttpCache, SimpleGET_SSLError) {
6495 MockHttpCache cache;
6497 MockTransaction transaction = kSimpleGET_Transaction;
6498 transaction.cert_status = CERT_STATUS_REVOKED;
6499 ScopedMockTransaction scoped_transaction(transaction);
6501 // write to the cache
6502 RunTransactionTest(cache.http_cache(), transaction);
6504 // Test that it was not cached.
6505 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
6507 MockHttpRequest request(transaction);
6508 TestCompletionCallback callback;
6510 scoped_ptr<HttpTransaction> trans;
6511 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6513 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6514 if (rv == ERR_IO_PENDING)
6515 rv = callback.WaitForResult();
6516 ASSERT_EQ(ERR_CACHE_MISS, rv);
6519 // Ensure that we don't crash by if left-behind transactions.
6520 TEST(HttpCache, OutlivedTransactions) {
6521 MockHttpCache* cache = new MockHttpCache;
6523 scoped_ptr<HttpTransaction> trans;
6524 EXPECT_EQ(OK, cache->CreateTransaction(&trans));
6526 delete cache;
6527 trans.reset();
6530 // Test that the disabled mode works.
6531 TEST(HttpCache, CacheDisabledMode) {
6532 MockHttpCache cache;
6534 // write to the cache
6535 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6537 // go into disabled mode
6538 cache.http_cache()->set_mode(HttpCache::DISABLE);
6540 // force this transaction to write to the cache again
6541 MockTransaction transaction(kSimpleGET_Transaction);
6543 RunTransactionTest(cache.http_cache(), transaction);
6545 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6546 EXPECT_EQ(0, cache.disk_cache()->open_count());
6547 EXPECT_EQ(1, cache.disk_cache()->create_count());
6550 // Other tests check that the response headers of the cached response
6551 // get updated on 304. Here we specifically check that the
6552 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6553 // fields also gets updated.
6554 // http://crbug.com/20594.
6555 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
6556 MockHttpCache cache;
6558 const char kUrl[] = "http://foobar";
6559 const char kData[] = "body";
6561 MockTransaction mock_network_response = { 0 };
6562 mock_network_response.url = kUrl;
6564 AddMockTransaction(&mock_network_response);
6566 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6568 MockTransaction request = { 0 };
6569 request.url = kUrl;
6570 request.method = "GET";
6571 request.request_headers = "\r\n";
6572 request.data = kData;
6574 static const Response kNetResponse1 = {
6575 "HTTP/1.1 200 OK",
6576 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6577 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6578 kData
6581 kNetResponse1.AssignTo(&mock_network_response);
6583 RunTransactionTest(cache.http_cache(), request);
6585 // Request |kUrl| again, this time validating the cache and getting
6586 // a 304 back.
6588 request.load_flags = LOAD_VALIDATE_CACHE;
6590 static const Response kNetResponse2 = {
6591 "HTTP/1.1 304 Not Modified",
6592 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6596 kNetResponse2.AssignTo(&mock_network_response);
6598 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6599 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6601 mock_network_response.request_time = request_time;
6602 mock_network_response.response_time = response_time;
6604 HttpResponseInfo response;
6605 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6607 // The request and response times should have been updated.
6608 EXPECT_EQ(request_time.ToInternalValue(),
6609 response.request_time.ToInternalValue());
6610 EXPECT_EQ(response_time.ToInternalValue(),
6611 response.response_time.ToInternalValue());
6613 std::string headers;
6614 response.headers->GetNormalizedHeaders(&headers);
6616 EXPECT_EQ("HTTP/1.1 200 OK\n"
6617 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6618 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6619 headers);
6621 RemoveMockTransaction(&mock_network_response);
6624 // Tests that we can write metadata to an entry.
6625 TEST(HttpCache, WriteMetadata_OK) {
6626 MockHttpCache cache;
6628 // Write to the cache
6629 HttpResponseInfo response;
6630 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6631 &response);
6632 EXPECT_TRUE(response.metadata.get() == NULL);
6634 // Trivial call.
6635 cache.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY, Time::Now(),
6636 NULL, 0);
6638 // Write meta data to the same entry.
6639 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6640 memset(buf->data(), 0, buf->size());
6641 base::strlcpy(buf->data(), "Hi there", buf->size());
6642 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6643 DEFAULT_PRIORITY, response.response_time,
6644 buf.get(), buf->size());
6646 // Release the buffer before the operation takes place.
6647 buf = NULL;
6649 // Makes sure we finish pending operations.
6650 base::MessageLoop::current()->RunUntilIdle();
6652 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6653 &response);
6654 ASSERT_TRUE(response.metadata.get() != NULL);
6655 EXPECT_EQ(50, response.metadata->size());
6656 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6658 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6659 EXPECT_EQ(2, cache.disk_cache()->open_count());
6660 EXPECT_EQ(1, cache.disk_cache()->create_count());
6663 // Tests that we only write metadata to an entry if the time stamp matches.
6664 TEST(HttpCache, WriteMetadata_Fail) {
6665 MockHttpCache cache;
6667 // Write to the cache
6668 HttpResponseInfo response;
6669 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6670 &response);
6671 EXPECT_TRUE(response.metadata.get() == NULL);
6673 // Attempt to write meta data to the same entry.
6674 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6675 memset(buf->data(), 0, buf->size());
6676 base::strlcpy(buf->data(), "Hi there", buf->size());
6677 base::Time expected_time = response.response_time -
6678 base::TimeDelta::FromMilliseconds(20);
6679 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6680 DEFAULT_PRIORITY, expected_time, buf.get(),
6681 buf->size());
6683 // Makes sure we finish pending operations.
6684 base::MessageLoop::current()->RunUntilIdle();
6686 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6687 &response);
6688 EXPECT_TRUE(response.metadata.get() == NULL);
6690 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6691 EXPECT_EQ(2, cache.disk_cache()->open_count());
6692 EXPECT_EQ(1, cache.disk_cache()->create_count());
6695 // Tests that we can read metadata after validating the entry and with READ mode
6696 // transactions.
6697 TEST(HttpCache, ReadMetadata) {
6698 MockHttpCache cache;
6700 // Write to the cache
6701 HttpResponseInfo response;
6702 RunTransactionTestWithResponseInfo(cache.http_cache(),
6703 kTypicalGET_Transaction, &response);
6704 EXPECT_TRUE(response.metadata.get() == NULL);
6706 // Write meta data to the same entry.
6707 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
6708 memset(buf->data(), 0, buf->size());
6709 base::strlcpy(buf->data(), "Hi there", buf->size());
6710 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6711 DEFAULT_PRIORITY, response.response_time,
6712 buf.get(), buf->size());
6714 // Makes sure we finish pending operations.
6715 base::MessageLoop::current()->RunUntilIdle();
6717 // Start with a READ mode transaction.
6718 MockTransaction trans1(kTypicalGET_Transaction);
6719 trans1.load_flags = LOAD_ONLY_FROM_CACHE;
6721 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6722 ASSERT_TRUE(response.metadata.get() != NULL);
6723 EXPECT_EQ(50, response.metadata->size());
6724 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6726 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6727 EXPECT_EQ(2, cache.disk_cache()->open_count());
6728 EXPECT_EQ(1, cache.disk_cache()->create_count());
6729 base::MessageLoop::current()->RunUntilIdle();
6731 // Now make sure that the entry is re-validated with the server.
6732 trans1.load_flags = LOAD_VALIDATE_CACHE;
6733 trans1.status = "HTTP/1.1 304 Not Modified";
6734 AddMockTransaction(&trans1);
6736 response.metadata = NULL;
6737 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6738 EXPECT_TRUE(response.metadata.get() != NULL);
6740 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6741 EXPECT_EQ(3, cache.disk_cache()->open_count());
6742 EXPECT_EQ(1, cache.disk_cache()->create_count());
6743 base::MessageLoop::current()->RunUntilIdle();
6744 RemoveMockTransaction(&trans1);
6746 // Now return 200 when validating the entry so the metadata will be lost.
6747 MockTransaction trans2(kTypicalGET_Transaction);
6748 trans2.load_flags = LOAD_VALIDATE_CACHE;
6749 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6750 EXPECT_TRUE(response.metadata.get() == NULL);
6752 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6753 EXPECT_EQ(4, cache.disk_cache()->open_count());
6754 EXPECT_EQ(1, cache.disk_cache()->create_count());
6757 // Tests that we don't mark entries as truncated when a filter detects the end
6758 // of the stream.
6759 TEST(HttpCache, FilterCompletion) {
6760 MockHttpCache cache;
6761 TestCompletionCallback callback;
6764 scoped_ptr<HttpTransaction> trans;
6765 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6767 MockHttpRequest request(kSimpleGET_Transaction);
6768 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6769 EXPECT_EQ(OK, callback.GetResult(rv));
6771 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6772 rv = trans->Read(buf.get(), 256, callback.callback());
6773 EXPECT_GT(callback.GetResult(rv), 0);
6775 // Now make sure that the entry is preserved.
6776 trans->DoneReading();
6779 // Make sure that the ActiveEntry is gone.
6780 base::MessageLoop::current()->RunUntilIdle();
6782 // Read from the cache.
6783 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6785 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6786 EXPECT_EQ(1, cache.disk_cache()->open_count());
6787 EXPECT_EQ(1, cache.disk_cache()->create_count());
6790 // Tests that we don't mark entries as truncated and release the cache
6791 // entry when DoneReading() is called before any Read() calls, such as
6792 // for a redirect.
6793 TEST(HttpCache, DoneReading) {
6794 MockHttpCache cache;
6795 TestCompletionCallback callback;
6797 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6798 transaction.data = "";
6800 scoped_ptr<HttpTransaction> trans;
6801 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6803 MockHttpRequest request(transaction);
6804 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6805 EXPECT_EQ(OK, callback.GetResult(rv));
6807 trans->DoneReading();
6808 // Leave the transaction around.
6810 // Make sure that the ActiveEntry is gone.
6811 base::MessageLoop::current()->RunUntilIdle();
6813 // Read from the cache. This should not deadlock.
6814 RunTransactionTest(cache.http_cache(), transaction);
6816 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6817 EXPECT_EQ(1, cache.disk_cache()->open_count());
6818 EXPECT_EQ(1, cache.disk_cache()->create_count());
6821 // Tests that we stop caching when told.
6822 TEST(HttpCache, StopCachingDeletesEntry) {
6823 MockHttpCache cache;
6824 TestCompletionCallback callback;
6825 MockHttpRequest request(kSimpleGET_Transaction);
6828 scoped_ptr<HttpTransaction> trans;
6829 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6831 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6832 EXPECT_EQ(OK, callback.GetResult(rv));
6834 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6835 rv = trans->Read(buf.get(), 10, callback.callback());
6836 EXPECT_EQ(10, callback.GetResult(rv));
6838 trans->StopCaching();
6840 // We should be able to keep reading.
6841 rv = trans->Read(buf.get(), 256, callback.callback());
6842 EXPECT_GT(callback.GetResult(rv), 0);
6843 rv = trans->Read(buf.get(), 256, callback.callback());
6844 EXPECT_EQ(0, callback.GetResult(rv));
6847 // Make sure that the ActiveEntry is gone.
6848 base::MessageLoop::current()->RunUntilIdle();
6850 // Verify that the entry is gone.
6851 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6853 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6854 EXPECT_EQ(0, cache.disk_cache()->open_count());
6855 EXPECT_EQ(2, cache.disk_cache()->create_count());
6858 // Tests that we stop caching when told, even if DoneReading is called
6859 // after StopCaching.
6860 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6861 MockHttpCache cache;
6862 TestCompletionCallback callback;
6863 MockHttpRequest request(kSimpleGET_Transaction);
6866 scoped_ptr<HttpTransaction> trans;
6867 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6869 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6870 EXPECT_EQ(OK, callback.GetResult(rv));
6872 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6873 rv = trans->Read(buf.get(), 10, callback.callback());
6874 EXPECT_EQ(10, callback.GetResult(rv));
6876 trans->StopCaching();
6878 // We should be able to keep reading.
6879 rv = trans->Read(buf.get(), 256, callback.callback());
6880 EXPECT_GT(callback.GetResult(rv), 0);
6881 rv = trans->Read(buf.get(), 256, callback.callback());
6882 EXPECT_EQ(0, callback.GetResult(rv));
6884 // We should be able to call DoneReading.
6885 trans->DoneReading();
6888 // Make sure that the ActiveEntry is gone.
6889 base::MessageLoop::current()->RunUntilIdle();
6891 // Verify that the entry is gone.
6892 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6894 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6895 EXPECT_EQ(0, cache.disk_cache()->open_count());
6896 EXPECT_EQ(2, cache.disk_cache()->create_count());
6899 // Tests that we stop caching when told, when using auth.
6900 TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6901 MockHttpCache cache;
6902 TestCompletionCallback callback;
6903 MockTransaction mock_transaction(kSimpleGET_Transaction);
6904 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6905 AddMockTransaction(&mock_transaction);
6906 MockHttpRequest request(mock_transaction);
6909 scoped_ptr<HttpTransaction> trans;
6910 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6912 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6913 EXPECT_EQ(OK, callback.GetResult(rv));
6915 trans->StopCaching();
6917 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6918 rv = trans->Read(buf.get(), 10, callback.callback());
6919 EXPECT_EQ(callback.GetResult(rv), 10);
6921 RemoveMockTransaction(&mock_transaction);
6923 // Make sure that the ActiveEntry is gone.
6924 base::MessageLoop::current()->RunUntilIdle();
6926 // Verify that the entry is gone.
6927 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6929 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6930 EXPECT_EQ(0, cache.disk_cache()->open_count());
6931 EXPECT_EQ(2, cache.disk_cache()->create_count());
6934 // Tests that when we are told to stop caching we don't throw away valid data.
6935 TEST(HttpCache, StopCachingSavesEntry) {
6936 MockHttpCache cache;
6937 TestCompletionCallback callback;
6938 MockHttpRequest request(kSimpleGET_Transaction);
6941 scoped_ptr<HttpTransaction> trans;
6942 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6944 // Force a response that can be resumed.
6945 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
6946 AddMockTransaction(&mock_transaction);
6947 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6948 "Content-Length: 42\n"
6949 "Etag: \"foo\"\n";
6951 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6952 EXPECT_EQ(OK, callback.GetResult(rv));
6954 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6955 rv = trans->Read(buf.get(), 10, callback.callback());
6956 EXPECT_EQ(callback.GetResult(rv), 10);
6958 trans->StopCaching();
6960 // We should be able to keep reading.
6961 rv = trans->Read(buf.get(), 256, callback.callback());
6962 EXPECT_GT(callback.GetResult(rv), 0);
6963 rv = trans->Read(buf.get(), 256, callback.callback());
6964 EXPECT_EQ(callback.GetResult(rv), 0);
6967 // Verify that the entry is marked as incomplete.
6968 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
6971 // Tests that we handle truncated enries when StopCaching is called.
6972 TEST(HttpCache, StopCachingTruncatedEntry) {
6973 MockHttpCache cache;
6974 TestCompletionCallback callback;
6975 MockHttpRequest request(kRangeGET_TransactionOK);
6976 request.extra_headers.Clear();
6977 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6978 AddMockTransaction(&kRangeGET_TransactionOK);
6980 std::string raw_headers("HTTP/1.1 200 OK\n"
6981 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6982 "ETag: \"foo\"\n"
6983 "Accept-Ranges: bytes\n"
6984 "Content-Length: 80\n");
6985 CreateTruncatedEntry(raw_headers, &cache);
6988 // Now make a regular request.
6989 scoped_ptr<HttpTransaction> trans;
6990 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6993 EXPECT_EQ(OK, callback.GetResult(rv));
6995 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6996 rv = trans->Read(buf.get(), 10, callback.callback());
6997 EXPECT_EQ(callback.GetResult(rv), 10);
6999 // This is actually going to do nothing.
7000 trans->StopCaching();
7002 // We should be able to keep reading.
7003 rv = trans->Read(buf.get(), 256, callback.callback());
7004 EXPECT_GT(callback.GetResult(rv), 0);
7005 rv = trans->Read(buf.get(), 256, callback.callback());
7006 EXPECT_GT(callback.GetResult(rv), 0);
7007 rv = trans->Read(buf.get(), 256, callback.callback());
7008 EXPECT_EQ(callback.GetResult(rv), 0);
7011 // Verify that the disk entry was updated.
7012 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80);
7013 RemoveMockTransaction(&kRangeGET_TransactionOK);
7016 // Tests that we detect truncated resources from the net when there is
7017 // a Content-Length header.
7018 TEST(HttpCache, TruncatedByContentLength) {
7019 MockHttpCache cache;
7020 TestCompletionCallback callback;
7022 MockTransaction transaction(kSimpleGET_Transaction);
7023 AddMockTransaction(&transaction);
7024 transaction.response_headers = "Cache-Control: max-age=10000\n"
7025 "Content-Length: 100\n";
7026 RunTransactionTest(cache.http_cache(), transaction);
7027 RemoveMockTransaction(&transaction);
7029 // Read from the cache.
7030 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7032 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7033 EXPECT_EQ(0, cache.disk_cache()->open_count());
7034 EXPECT_EQ(2, cache.disk_cache()->create_count());
7037 // Tests that we actually flag entries as truncated when we detect an error
7038 // from the net.
7039 TEST(HttpCache, TruncatedByContentLength2) {
7040 MockHttpCache cache;
7041 TestCompletionCallback callback;
7043 MockTransaction transaction(kSimpleGET_Transaction);
7044 AddMockTransaction(&transaction);
7045 transaction.response_headers = "Cache-Control: max-age=10000\n"
7046 "Content-Length: 100\n"
7047 "Etag: \"foo\"\n";
7048 RunTransactionTest(cache.http_cache(), transaction);
7049 RemoveMockTransaction(&transaction);
7051 // Verify that the entry is marked as incomplete.
7052 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
7055 // Make sure that calling SetPriority on a cache transaction passes on
7056 // its priority updates to its underlying network transaction.
7057 TEST(HttpCache, SetPriority) {
7058 MockHttpCache cache;
7060 scoped_ptr<HttpTransaction> trans;
7061 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
7063 // Shouldn't crash, but doesn't do anything either.
7064 trans->SetPriority(LOW);
7066 EXPECT_FALSE(cache.network_layer()->last_transaction());
7067 EXPECT_EQ(DEFAULT_PRIORITY,
7068 cache.network_layer()->last_create_transaction_priority());
7070 HttpRequestInfo info;
7071 info.url = GURL(kSimpleGET_Transaction.url);
7072 TestCompletionCallback callback;
7073 EXPECT_EQ(ERR_IO_PENDING,
7074 trans->Start(&info, callback.callback(), BoundNetLog()));
7076 EXPECT_TRUE(cache.network_layer()->last_transaction());
7077 if (cache.network_layer()->last_transaction()) {
7078 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
7079 EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
7082 trans->SetPriority(HIGHEST);
7084 if (cache.network_layer()->last_transaction()) {
7085 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
7086 EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
7089 EXPECT_EQ(OK, callback.WaitForResult());
7092 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7093 // transaction passes on its argument to the underlying network transaction.
7094 TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
7095 MockHttpCache cache;
7097 FakeWebSocketHandshakeStreamCreateHelper create_helper;
7098 scoped_ptr<HttpTransaction> trans;
7099 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
7101 EXPECT_FALSE(cache.network_layer()->last_transaction());
7103 HttpRequestInfo info;
7104 info.url = GURL(kSimpleGET_Transaction.url);
7105 TestCompletionCallback callback;
7106 EXPECT_EQ(ERR_IO_PENDING,
7107 trans->Start(&info, callback.callback(), BoundNetLog()));
7109 ASSERT_TRUE(cache.network_layer()->last_transaction());
7110 EXPECT_FALSE(cache.network_layer()->last_transaction()->
7111 websocket_handshake_stream_create_helper());
7112 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
7113 EXPECT_EQ(&create_helper,
7114 cache.network_layer()->last_transaction()->
7115 websocket_handshake_stream_create_helper());
7116 EXPECT_EQ(OK, callback.WaitForResult());
7119 // Make sure that a cache transaction passes on its priority to
7120 // newly-created network transactions.
7121 TEST(HttpCache, SetPriorityNewTransaction) {
7122 MockHttpCache cache;
7123 AddMockTransaction(&kRangeGET_TransactionOK);
7125 std::string raw_headers("HTTP/1.1 200 OK\n"
7126 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7127 "ETag: \"foo\"\n"
7128 "Accept-Ranges: bytes\n"
7129 "Content-Length: 80\n");
7130 CreateTruncatedEntry(raw_headers, &cache);
7132 // Now make a regular request.
7133 std::string headers;
7134 MockTransaction transaction(kRangeGET_TransactionOK);
7135 transaction.request_headers = EXTRA_HEADER;
7136 transaction.data = kFullRangeData;
7138 scoped_ptr<HttpTransaction> trans;
7139 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(MEDIUM, &trans));
7140 EXPECT_EQ(DEFAULT_PRIORITY,
7141 cache.network_layer()->last_create_transaction_priority());
7143 MockHttpRequest info(transaction);
7144 TestCompletionCallback callback;
7145 EXPECT_EQ(ERR_IO_PENDING,
7146 trans->Start(&info, callback.callback(), BoundNetLog()));
7147 EXPECT_EQ(OK, callback.WaitForResult());
7149 EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
7151 trans->SetPriority(HIGHEST);
7152 // Should trigger a new network transaction and pick up the new
7153 // priority.
7154 ReadAndVerifyTransaction(trans.get(), transaction);
7156 EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
7158 RemoveMockTransaction(&kRangeGET_TransactionOK);
7161 namespace {
7163 void RunTransactionAndGetNetworkBytes(MockHttpCache& cache,
7164 const MockTransaction& trans_info,
7165 int64_t* sent_bytes,
7166 int64_t* received_bytes) {
7167 RunTransactionTestBase(cache.http_cache(), trans_info,
7168 MockHttpRequest(trans_info), nullptr, BoundNetLog(),
7169 nullptr, sent_bytes, received_bytes);
7172 } // namespace
7174 TEST(HttpCache, NetworkBytesCacheMissAndThenHit) {
7175 MockHttpCache cache;
7177 MockTransaction transaction(kSimpleGET_Transaction);
7178 int64_t sent, received;
7179 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7180 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7181 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7183 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7184 EXPECT_EQ(0, sent);
7185 EXPECT_EQ(0, received);
7188 TEST(HttpCache, NetworkBytesConditionalRequest304) {
7189 MockHttpCache cache;
7191 ScopedMockTransaction transaction(kETagGET_Transaction);
7192 int64_t sent, received;
7193 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7194 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7195 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7197 transaction.load_flags = LOAD_VALIDATE_CACHE;
7198 transaction.handler = ETagGet_ConditionalRequest_Handler;
7199 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7200 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7201 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7204 TEST(HttpCache, NetworkBytesConditionalRequest200) {
7205 MockHttpCache cache;
7207 MockTransaction transaction(kTypicalGET_Transaction);
7208 transaction.request_headers = "Foo: bar\r\n";
7209 transaction.response_headers =
7210 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7211 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7212 "Etag: \"foopy\"\n"
7213 "Cache-Control: max-age=0\n"
7214 "Vary: Foo\n";
7215 AddMockTransaction(&transaction);
7216 int64_t sent, received;
7217 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7218 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7219 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7221 RevalidationServer server;
7222 transaction.handler = server.Handler;
7223 transaction.request_headers = "Foo: none\r\n";
7224 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7225 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7226 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7228 RemoveMockTransaction(&transaction);
7231 TEST(HttpCache, NetworkBytesRange) {
7232 MockHttpCache cache;
7233 AddMockTransaction(&kRangeGET_TransactionOK);
7234 MockTransaction transaction(kRangeGET_TransactionOK);
7236 // Read bytes 40-49 from the network.
7237 int64_t sent, received;
7238 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7239 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7240 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7242 // Read bytes 40-49 from the cache.
7243 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7244 EXPECT_EQ(0, sent);
7245 EXPECT_EQ(0, received);
7246 base::MessageLoop::current()->RunUntilIdle();
7248 // Read bytes 30-39 from the network.
7249 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
7250 transaction.data = "rg: 30-39 ";
7251 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7252 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7253 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
7254 base::MessageLoop::current()->RunUntilIdle();
7256 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7257 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
7258 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7259 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7260 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
7261 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
7263 RemoveMockTransaction(&kRangeGET_TransactionOK);
7266 class HttpCachePrefetchValidationTest : public ::testing::Test {
7267 protected:
7268 static const int kMaxAgeSecs = 100;
7269 static const int kRequireValidationSecs = kMaxAgeSecs + 1;
7271 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
7272 DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
7274 clock_ = new base::SimpleTestClock();
7275 cache_.http_cache()->SetClockForTesting(make_scoped_ptr(clock_));
7276 cache_.network_layer()->SetClock(clock_);
7278 transaction_.response_headers = "Cache-Control: max-age=100\n";
7281 bool TransactionRequiredNetwork(int load_flags) {
7282 int pre_transaction_count = transaction_count();
7283 transaction_.load_flags = load_flags;
7284 RunTransactionTest(cache_.http_cache(), transaction_);
7285 return pre_transaction_count != transaction_count();
7288 void AdvanceTime(int seconds) {
7289 clock_->Advance(base::TimeDelta::FromSeconds(seconds));
7292 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
7294 // How many times this test has sent requests to the (fake) origin
7295 // server. Every test case needs to make at least one request to initialise
7296 // the cache.
7297 int transaction_count() {
7298 return cache_.network_layer()->transaction_count();
7301 MockHttpCache cache_;
7302 ScopedMockTransaction transaction_;
7303 std::string response_headers_;
7304 base::SimpleTestClock* clock_;
7307 TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
7308 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7309 AdvanceTime(kRequireValidationSecs);
7310 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7313 TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
7314 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7315 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
7316 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7319 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
7320 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7321 AdvanceTime(kRequireValidationSecs);
7322 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7323 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7326 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
7327 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7328 AdvanceTime(kRequireValidationSecs);
7329 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE));
7330 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7333 TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
7334 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7335 AdvanceTime(kRequireValidationSecs);
7336 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
7337 AdvanceTime(kRequireValidationSecs);
7338 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7341 TEST_F(HttpCachePrefetchValidationTest,
7342 SkipValidationOnExistingEntryThatNeedsValidation) {
7343 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7344 AdvanceTime(kRequireValidationSecs);
7345 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7346 AdvanceTime(kRequireValidationSecs);
7347 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7348 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7351 TEST_F(HttpCachePrefetchValidationTest,
7352 SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
7353 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7354 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
7355 AdvanceTime(kRequireValidationSecs);
7356 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7357 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7360 TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
7361 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7362 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
7363 AdvanceTime(kRequireValidationSecs);
7364 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7367 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
7368 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7369 AdvanceTime(kRequireValidationSecs);
7370 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7371 AdvanceTime(kRequireValidationSecs);
7372 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7375 static void CheckResourceFreshnessHeader(const HttpRequestInfo* request,
7376 std::string* response_status,
7377 std::string* response_headers,
7378 std::string* response_data) {
7379 std::string value;
7380 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
7381 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
7384 // Verify that the Resource-Freshness header is sent on a revalidation if the
7385 // stale-while-revalidate directive was on the response.
7386 TEST(HttpCache, ResourceFreshnessHeaderSent) {
7387 MockHttpCache cache;
7389 ScopedMockTransaction stale_while_revalidate_transaction(
7390 kSimpleGET_Transaction);
7391 stale_while_revalidate_transaction.response_headers =
7392 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7393 "Age: 10801\n"
7394 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
7396 // Write to the cache.
7397 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7399 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7401 // Send the request again and check that Resource-Freshness header is added.
7402 stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader;
7404 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7406 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7409 static void CheckResourceFreshnessAbsent(const HttpRequestInfo* request,
7410 std::string* response_status,
7411 std::string* response_headers,
7412 std::string* response_data) {
7413 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
7416 // Verify that the Resource-Freshness header is not sent when
7417 // stale-while-revalidate is 0.
7418 TEST(HttpCache, ResourceFreshnessHeaderNotSent) {
7419 MockHttpCache cache;
7421 ScopedMockTransaction stale_while_revalidate_transaction(
7422 kSimpleGET_Transaction);
7423 stale_while_revalidate_transaction.response_headers =
7424 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7425 "Age: 10801\n"
7426 "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
7428 // Write to the cache.
7429 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7431 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7433 // Send the request again and check that Resource-Freshness header is absent.
7434 stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent;
7436 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7438 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7441 TEST(HttpCache, StaleContentNotUsedWhenLoadFlagNotSet) {
7442 MockHttpCache cache;
7444 ScopedMockTransaction stale_while_revalidate_transaction(
7445 kSimpleGET_Transaction);
7447 stale_while_revalidate_transaction.response_headers =
7448 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7449 "Age: 10801\n"
7450 "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
7452 // Write to the cache.
7453 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7455 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7457 // Send the request again and check that it is sent to the network again.
7458 HttpResponseInfo response_info;
7459 RunTransactionTestWithResponseInfo(
7460 cache.http_cache(), stale_while_revalidate_transaction, &response_info);
7462 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7463 EXPECT_FALSE(response_info.async_revalidation_required);
7466 TEST(HttpCache, StaleContentUsedWhenLoadFlagSetAndUsable) {
7467 MockHttpCache cache;
7469 ScopedMockTransaction stale_while_revalidate_transaction(
7470 kSimpleGET_Transaction);
7471 stale_while_revalidate_transaction.load_flags |=
7472 LOAD_SUPPORT_ASYNC_REVALIDATION;
7473 stale_while_revalidate_transaction.response_headers =
7474 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7475 "Age: 10801\n"
7476 "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
7478 // Write to the cache.
7479 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7481 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7483 // Send the request again and check that it is not sent to the network again.
7484 HttpResponseInfo response_info;
7485 RunTransactionTestWithResponseInfo(
7486 cache.http_cache(), stale_while_revalidate_transaction, &response_info);
7488 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7489 EXPECT_TRUE(response_info.async_revalidation_required);
7492 TEST(HttpCache, StaleContentNotUsedWhenUnusable) {
7493 MockHttpCache cache;
7495 ScopedMockTransaction stale_while_revalidate_transaction(
7496 kSimpleGET_Transaction);
7497 stale_while_revalidate_transaction.load_flags |=
7498 LOAD_SUPPORT_ASYNC_REVALIDATION;
7499 stale_while_revalidate_transaction.response_headers =
7500 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7501 "Age: 10801\n"
7502 "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
7504 // Write to the cache.
7505 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7507 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7509 // Send the request again and check that it is sent to the network again.
7510 HttpResponseInfo response_info;
7511 RunTransactionTestWithResponseInfo(
7512 cache.http_cache(), stale_while_revalidate_transaction, &response_info);
7514 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7515 EXPECT_FALSE(response_info.async_revalidation_required);
7518 // Tests that we allow multiple simultaneous, non-overlapping transactions to
7519 // take place on a sparse entry.
7520 TEST(HttpCache, RangeGET_MultipleRequests) {
7521 MockHttpCache cache;
7523 // Create a transaction for bytes 0-9.
7524 MockHttpRequest request(kRangeGET_TransactionOK);
7525 MockTransaction transaction(kRangeGET_TransactionOK);
7526 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7527 transaction.data = "rg: 00-09 ";
7528 AddMockTransaction(&transaction);
7530 TestCompletionCallback callback;
7531 scoped_ptr<HttpTransaction> trans;
7532 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
7533 EXPECT_EQ(OK, rv);
7534 ASSERT_TRUE(trans.get());
7536 // Start our transaction.
7537 trans->Start(&request, callback.callback(), BoundNetLog());
7539 // A second transaction on a different part of the file (the default
7540 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7541 // the already pending transaction.
7542 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7544 // Let the first transaction complete.
7545 callback.WaitForResult();
7547 RemoveMockTransaction(&transaction);
7550 // Makes sure that a request stops using the cache when the response headers
7551 // with "Cache-Control: no-store" arrives. That means that another request for
7552 // the same URL can be processed before the response body of the original
7553 // request arrives.
7554 TEST(HttpCache, NoStoreResponseShouldNotBlockFollowingRequests) {
7555 MockHttpCache cache;
7556 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
7557 mock_transaction.response_headers = "Cache-Control: no-store\n";
7558 MockHttpRequest request(mock_transaction);
7560 scoped_ptr<Context> first(new Context);
7561 first->result = cache.CreateTransaction(&first->trans);
7562 ASSERT_EQ(OK, first->result);
7563 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
7564 first->result =
7565 first->trans->Start(&request, first->callback.callback(), BoundNetLog());
7566 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
7568 base::MessageLoop::current()->RunUntilIdle();
7569 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
7570 ASSERT_TRUE(first->trans->GetResponseInfo());
7571 EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
7572 "Cache-Control", "no-store"));
7573 // Here we have read the response header but not read the response body yet.
7575 // Let us create the second (read) transaction.
7576 scoped_ptr<Context> second(new Context);
7577 second->result = cache.CreateTransaction(&second->trans);
7578 ASSERT_EQ(OK, second->result);
7579 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
7580 second->result = second->trans->Start(&request, second->callback.callback(),
7581 BoundNetLog());
7583 // Here the second transaction proceeds without reading the first body.
7584 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
7585 base::MessageLoop::current()->RunUntilIdle();
7586 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
7587 ASSERT_TRUE(second->trans->GetResponseInfo());
7588 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
7589 "Cache-Control", "no-store"));
7590 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
7593 // Tests that serving a response entirely from cache replays the previous
7594 // SSLInfo.
7595 TEST(HttpCache, CachePreservesSSLInfo) {
7596 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
7597 int status = 0;
7598 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
7599 &status);
7600 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status);
7602 scoped_refptr<X509Certificate> cert =
7603 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7605 MockHttpCache cache;
7607 ScopedMockTransaction transaction(kSimpleGET_Transaction);
7608 transaction.cert = cert;
7609 transaction.ssl_connection_status = status;
7611 // Fetch the resource.
7612 HttpResponseInfo response_info;
7613 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7614 &response_info);
7616 // The request should have hit the network and a cache entry created.
7617 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7618 EXPECT_EQ(0, cache.disk_cache()->open_count());
7619 EXPECT_EQ(1, cache.disk_cache()->create_count());
7621 // The expected SSL state was reported.
7622 EXPECT_EQ(transaction.ssl_connection_status,
7623 response_info.ssl_info.connection_status);
7624 EXPECT_TRUE(cert->Equals(response_info.ssl_info.cert.get()));
7626 // Fetch the resource again.
7627 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7628 &response_info);
7630 // The request should have been reused without hitting the network.
7631 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7632 EXPECT_EQ(1, cache.disk_cache()->open_count());
7633 EXPECT_EQ(1, cache.disk_cache()->create_count());
7635 // The SSL state was preserved.
7636 EXPECT_EQ(status, response_info.ssl_info.connection_status);
7637 EXPECT_TRUE(cert->Equals(response_info.ssl_info.cert.get()));
7640 // Tests that SSLInfo gets updated when revalidating a cached response.
7641 TEST(HttpCache, RevalidationUpdatesSSLInfo) {
7642 static const uint16_t kTLS_RSA_WITH_RC4_128_MD5 = 0x0004;
7643 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
7645 int status1 = 0;
7646 SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5, &status1);
7647 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1, &status1);
7648 int status2 = 0;
7649 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
7650 &status2);
7651 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status2);
7653 scoped_refptr<X509Certificate> cert1 =
7654 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
7655 scoped_refptr<X509Certificate> cert2 =
7656 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7658 MockHttpCache cache;
7660 ScopedMockTransaction transaction(kTypicalGET_Transaction);
7661 transaction.cert = cert1;
7662 transaction.ssl_connection_status = status1;
7664 // Fetch the resource.
7665 HttpResponseInfo response_info;
7666 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7667 &response_info);
7669 // The request should have hit the network and a cache entry created.
7670 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7671 EXPECT_EQ(0, cache.disk_cache()->open_count());
7672 EXPECT_EQ(1, cache.disk_cache()->create_count());
7673 EXPECT_FALSE(response_info.was_cached);
7675 // The expected SSL state was reported.
7676 EXPECT_EQ(status1, response_info.ssl_info.connection_status);
7677 EXPECT_TRUE(cert1->Equals(response_info.ssl_info.cert.get()));
7679 // The server deploys a more modern configuration but reports 304 on the
7680 // revalidation attempt.
7681 transaction.status = "HTTP/1.1 304 Not Modified";
7682 transaction.cert = cert2;
7683 transaction.ssl_connection_status = status2;
7685 // Fetch the resource again, forcing a revalidation.
7686 transaction.request_headers = "Cache-Control: max-age=0\r\n";
7687 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7688 &response_info);
7690 // The request should have been successfully revalidated.
7691 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7692 EXPECT_EQ(1, cache.disk_cache()->open_count());
7693 EXPECT_EQ(1, cache.disk_cache()->create_count());
7694 EXPECT_TRUE(response_info.was_cached);
7696 // The new SSL state is reported.
7697 EXPECT_EQ(status2, response_info.ssl_info.connection_status);
7698 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get()));
7701 } // namespace net