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.
4
5#include "net/http/http_cache.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/memory/scoped_vector.h"
10#include "base/message_loop/message_loop.h"
11#include "base/strings/string_util.h"
12#include "base/strings/stringprintf.h"
13#include "net/base/cache_type.h"
14#include "net/base/host_port_pair.h"
15#include "net/base/load_flags.h"
16#include "net/base/load_timing_info.h"
17#include "net/base/load_timing_info_test_util.h"
18#include "net/base/net_errors.h"
19#include "net/base/net_log_unittest.h"
20#include "net/base/upload_bytes_element_reader.h"
21#include "net/base/upload_data_stream.h"
22#include "net/cert/cert_status_flags.h"
23#include "net/disk_cache/disk_cache.h"
24#include "net/http/http_byte_range.h"
25#include "net/http/http_request_headers.h"
26#include "net/http/http_request_info.h"
27#include "net/http/http_response_headers.h"
28#include "net/http/http_response_info.h"
29#include "net/http/http_transaction.h"
30#include "net/http/http_transaction_delegate.h"
31#include "net/http/http_transaction_unittest.h"
32#include "net/http/http_util.h"
33#include "net/http/mock_http_cache.h"
34#include "net/ssl/ssl_cert_request_info.h"
35#include "testing/gtest/include/gtest/gtest.h"
36
37using base::Time;
38
39namespace {
40
41// Tests the load timing values of a request that goes through a
42// MockNetworkTransaction.
43void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) {
44  EXPECT_FALSE(load_timing_info.socket_reused);
45  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
46
47  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
48  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
49
50  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
51                                   net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
52  EXPECT_LE(load_timing_info.connect_timing.connect_end,
53            load_timing_info.send_start);
54
55  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
56
57  // Set by URLRequest / URLRequestHttpJob, at a higher level.
58  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
59  EXPECT_TRUE(load_timing_info.request_start.is_null());
60  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
61}
62
63// Tests the load timing values of a request that receives a cached response.
64void TestLoadTimingCachedResponse(const net::LoadTimingInfo& load_timing_info) {
65  EXPECT_FALSE(load_timing_info.socket_reused);
66  EXPECT_EQ(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
67
68  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
69  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
70
71  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
72
73  // Only the send start / end times should be sent, and they should have the
74  // same value.
75  EXPECT_FALSE(load_timing_info.send_start.is_null());
76  EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
77
78  // Set by URLRequest / URLRequestHttpJob, at a higher level.
79  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
80  EXPECT_TRUE(load_timing_info.request_start.is_null());
81  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
82}
83
84class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
85 public:
86  explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
87      : cache_(cache),
88        callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
89                             base::Unretained(this))) {
90  }
91
92  const net::CompletionCallback& callback() const { return callback_; }
93
94 private:
95  void OnComplete(int result) {
96    delete cache_;
97    SetResult(result);
98  }
99
100  MockHttpCache* cache_;
101  net::CompletionCallback callback_;
102
103  DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
104};
105
106//-----------------------------------------------------------------------------
107// helpers
108
109class TestHttpTransactionDelegate : public net::HttpTransactionDelegate {
110 public:
111  TestHttpTransactionDelegate(int num_cache_actions_to_observe,
112                              int num_network_actions_to_observe)
113      : num_callbacks_observed_(0),
114        num_remaining_cache_actions_to_observe_(num_cache_actions_to_observe),
115        num_remaining_network_actions_to_observe_(
116            num_network_actions_to_observe),
117        cache_action_in_progress_(false),
118        network_action_in_progress_(false) {
119  }
120  virtual ~TestHttpTransactionDelegate() {
121    EXPECT_EQ(0, num_remaining_cache_actions_to_observe_);
122    EXPECT_EQ(0, num_remaining_network_actions_to_observe_);
123    EXPECT_FALSE(cache_action_in_progress_);
124    EXPECT_FALSE(network_action_in_progress_);
125  }
126  virtual void OnCacheActionStart() OVERRIDE {
127    num_callbacks_observed_++;
128    EXPECT_FALSE(cache_action_in_progress_);
129    EXPECT_FALSE(network_action_in_progress_);
130    EXPECT_GT(num_remaining_cache_actions_to_observe_, 0);
131    num_remaining_cache_actions_to_observe_--;
132    cache_action_in_progress_ = true;
133  }
134  virtual void OnCacheActionFinish() OVERRIDE {
135    num_callbacks_observed_++;
136    EXPECT_TRUE(cache_action_in_progress_);
137    cache_action_in_progress_ = false;
138  }
139  virtual void OnNetworkActionStart() OVERRIDE {
140    num_callbacks_observed_++;
141    EXPECT_FALSE(cache_action_in_progress_);
142    EXPECT_FALSE(network_action_in_progress_);
143    EXPECT_GT(num_remaining_network_actions_to_observe_, 0);
144    num_remaining_network_actions_to_observe_--;
145    network_action_in_progress_ = true;
146  }
147  virtual void OnNetworkActionFinish() OVERRIDE {
148    num_callbacks_observed_++;
149    EXPECT_TRUE(network_action_in_progress_);
150    network_action_in_progress_ = false;
151  }
152
153  int num_callbacks_observed() { return num_callbacks_observed_; }
154
155 private:
156  int num_callbacks_observed_;
157  int num_remaining_cache_actions_to_observe_;
158  int num_remaining_network_actions_to_observe_;
159  bool cache_action_in_progress_;
160  bool network_action_in_progress_;
161};
162
163void ReadAndVerifyTransaction(net::HttpTransaction* trans,
164                              const MockTransaction& trans_info) {
165  std::string content;
166  int rv = ReadTransaction(trans, &content);
167
168  EXPECT_EQ(net::OK, rv);
169  std::string expected(trans_info.data);
170  EXPECT_EQ(expected, content);
171}
172
173const int kNoDelegateTransactionCheck = -1;
174
175void RunTransactionTestWithRequestAndDelegateAndGetTiming(
176    net::HttpCache* cache,
177    const MockTransaction& trans_info,
178    const MockHttpRequest& request,
179    net::HttpResponseInfo* response_info,
180    int num_cache_delegate_actions,
181    int num_network_delegate_actions,
182    const net::BoundNetLog& net_log,
183    net::LoadTimingInfo* load_timing_info) {
184  net::TestCompletionCallback callback;
185
186  // write to the cache
187
188  scoped_ptr<TestHttpTransactionDelegate> delegate;
189  if (num_cache_delegate_actions != kNoDelegateTransactionCheck &&
190      num_network_delegate_actions != kNoDelegateTransactionCheck) {
191    delegate.reset(
192        new TestHttpTransactionDelegate(num_cache_delegate_actions,
193                                        num_network_delegate_actions));
194  }
195  scoped_ptr<net::HttpTransaction> trans;
196  int rv = cache->CreateTransaction(
197      net::DEFAULT_PRIORITY, &trans, delegate.get());
198  EXPECT_EQ(net::OK, rv);
199  ASSERT_TRUE(trans.get());
200
201  rv = trans->Start(&request, callback.callback(), net_log);
202  if (rv == net::ERR_IO_PENDING)
203    rv = callback.WaitForResult();
204  ASSERT_EQ(trans_info.return_code, rv);
205
206  if (net::OK != rv)
207    return;
208
209  const net::HttpResponseInfo* response = trans->GetResponseInfo();
210  ASSERT_TRUE(response);
211
212  if (response_info)
213    *response_info = *response;
214
215  if (load_timing_info) {
216    // If a fake network connection is used, need a NetLog to get a fake socket
217    // ID.
218    EXPECT_TRUE(net_log.net_log());
219    *load_timing_info = net::LoadTimingInfo();
220    trans->GetLoadTimingInfo(load_timing_info);
221  }
222
223  ReadAndVerifyTransaction(trans.get(), trans_info);
224}
225
226void RunTransactionTestWithRequestAndDelegate(
227    net::HttpCache* cache,
228    const MockTransaction& trans_info,
229    const MockHttpRequest& request,
230    net::HttpResponseInfo* response_info,
231    int num_cache_delegate_actions,
232    int num_network_delegate_actions) {
233  RunTransactionTestWithRequestAndDelegateAndGetTiming(
234      cache, trans_info, request, response_info, num_cache_delegate_actions,
235      num_network_delegate_actions, net::BoundNetLog(), NULL);
236}
237
238void RunTransactionTestWithRequest(net::HttpCache* cache,
239                                   const MockTransaction& trans_info,
240                                   const MockHttpRequest& request,
241                                   net::HttpResponseInfo* response_info) {
242  RunTransactionTestWithRequestAndDelegate(
243      cache, trans_info, request, response_info, kNoDelegateTransactionCheck,
244      kNoDelegateTransactionCheck);
245}
246
247void RunTransactionTestAndGetTiming(
248    net::HttpCache* cache,
249    const MockTransaction& trans_info,
250    const net::BoundNetLog& log,
251    net::LoadTimingInfo* load_timing_info) {
252  RunTransactionTestWithRequestAndDelegateAndGetTiming(
253      cache, trans_info, MockHttpRequest(trans_info), NULL,
254      kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log,
255      load_timing_info);
256}
257
258void RunTransactionTestWithDelegate(net::HttpCache* cache,
259                                    const MockTransaction& trans_info,
260                                    int num_cache_delegate_actions,
261                                    int num_network_delegate_actions) {
262  RunTransactionTestWithRequestAndDelegate(
263      cache, trans_info, MockHttpRequest(trans_info), NULL,
264      num_cache_delegate_actions, num_network_delegate_actions);
265}
266
267void RunTransactionTest(net::HttpCache* cache,
268                        const MockTransaction& trans_info) {
269  RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL);
270}
271
272void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
273                                        const MockTransaction& trans_info,
274                                        net::HttpResponseInfo* response) {
275  RunTransactionTestWithRequest(
276      cache, trans_info, MockHttpRequest(trans_info), response);
277}
278
279void RunTransactionTestWithResponseInfoAndGetTiming(
280    net::HttpCache* cache,
281    const MockTransaction& trans_info,
282    net::HttpResponseInfo* response,
283    const net::BoundNetLog& log,
284    net::LoadTimingInfo* load_timing_info) {
285  RunTransactionTestWithRequestAndDelegateAndGetTiming(
286      cache, trans_info, MockHttpRequest(trans_info), response,
287      kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log,
288      load_timing_info);
289}
290
291void RunTransactionTestWithResponse(net::HttpCache* cache,
292                                    const MockTransaction& trans_info,
293                                    std::string* response_headers) {
294  net::HttpResponseInfo response;
295  RunTransactionTestWithResponseInfo(cache, trans_info, &response);
296  response.headers->GetNormalizedHeaders(response_headers);
297}
298
299void RunTransactionTestWithResponseAndGetTiming(
300    net::HttpCache* cache,
301    const MockTransaction& trans_info,
302    std::string* response_headers,
303    const net::BoundNetLog& log,
304    net::LoadTimingInfo* load_timing_info) {
305  net::HttpResponseInfo response;
306  RunTransactionTestWithRequestAndDelegateAndGetTiming(
307      cache, trans_info, MockHttpRequest(trans_info), &response,
308      kNoDelegateTransactionCheck, kNoDelegateTransactionCheck,
309      log, load_timing_info);
310  response.headers->GetNormalizedHeaders(response_headers);
311}
312
313// This class provides a handler for kFastNoStoreGET_Transaction so that the
314// no-store header can be included on demand.
315class FastTransactionServer {
316 public:
317  FastTransactionServer() {
318    no_store = false;
319  }
320  ~FastTransactionServer() {}
321
322  void set_no_store(bool value) { no_store = value; }
323
324  static void FastNoStoreHandler(const net::HttpRequestInfo* request,
325                                 std::string* response_status,
326                                 std::string* response_headers,
327                                 std::string* response_data) {
328    if (no_store)
329      *response_headers = "Cache-Control: no-store\n";
330  }
331
332 private:
333  static bool no_store;
334  DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
335};
336bool FastTransactionServer::no_store;
337
338const MockTransaction kFastNoStoreGET_Transaction = {
339  "http://www.google.com/nostore",
340  "GET",
341  base::Time(),
342  "",
343  net::LOAD_VALIDATE_CACHE,
344  "HTTP/1.1 200 OK",
345  "Cache-Control: max-age=10000\n",
346  base::Time(),
347  "<html><body>Google Blah Blah</body></html>",
348  TEST_MODE_SYNC_NET_START,
349  &FastTransactionServer::FastNoStoreHandler,
350  0,
351  net::OK
352};
353
354// This class provides a handler for kRangeGET_TransactionOK so that the range
355// request can be served on demand.
356class RangeTransactionServer {
357 public:
358  RangeTransactionServer() {
359    not_modified_ = false;
360    modified_ = false;
361    bad_200_ = false;
362  }
363  ~RangeTransactionServer() {
364    not_modified_ = false;
365    modified_ = false;
366    bad_200_ = false;
367  }
368
369  // Returns only 416 or 304 when set.
370  void set_not_modified(bool value) { not_modified_ = value; }
371
372  // Returns 206 when revalidating a range (instead of 304).
373  void set_modified(bool value) { modified_ = value; }
374
375  // Returns 200 instead of 206 (a malformed response overall).
376  void set_bad_200(bool value) { bad_200_ = value; }
377
378  static void RangeHandler(const net::HttpRequestInfo* request,
379                           std::string* response_status,
380                           std::string* response_headers,
381                           std::string* response_data);
382
383 private:
384  static bool not_modified_;
385  static bool modified_;
386  static bool bad_200_;
387  DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
388};
389bool RangeTransactionServer::not_modified_ = false;
390bool RangeTransactionServer::modified_ = false;
391bool RangeTransactionServer::bad_200_ = false;
392
393// A dummy extra header that must be preserved on a given request.
394
395// EXTRA_HEADER_LINE doesn't include a line terminator because it
396// will be passed to AddHeaderFromString() which doesn't accept them.
397#define EXTRA_HEADER_LINE "Extra: header"
398
399// EXTRA_HEADER contains a line terminator, as expected by
400// AddHeadersFromString() (_not_ AddHeaderFromString()).
401#define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
402
403static const char kExtraHeaderKey[] = "Extra";
404
405// Static.
406void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
407                                          std::string* response_status,
408                                          std::string* response_headers,
409                                          std::string* response_data) {
410  if (request->extra_headers.IsEmpty()) {
411    response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
412    response_data->clear();
413    return;
414  }
415
416  // We want to make sure we don't delete extra headers.
417  EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
418
419  if (not_modified_) {
420    response_status->assign("HTTP/1.1 304 Not Modified");
421    response_data->clear();
422    return;
423  }
424
425  std::vector<net::HttpByteRange> ranges;
426  std::string range_header;
427  if (!request->extra_headers.GetHeader(
428          net::HttpRequestHeaders::kRange, &range_header) ||
429      !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
430      ranges.size() != 1) {
431    // This is not a byte range request. We return 200.
432    response_status->assign("HTTP/1.1 200 OK");
433    response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
434    response_data->assign("Not a range");
435    return;
436  }
437
438  // We can handle this range request.
439  net::HttpByteRange byte_range = ranges[0];
440  if (byte_range.first_byte_position() > 79) {
441    response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
442    response_data->clear();
443    return;
444  }
445
446  EXPECT_TRUE(byte_range.ComputeBounds(80));
447  int start = static_cast<int>(byte_range.first_byte_position());
448  int end = static_cast<int>(byte_range.last_byte_position());
449
450  EXPECT_LT(end, 80);
451
452  std::string content_range = base::StringPrintf(
453      "Content-Range: bytes %d-%d/80\n", start, end);
454  response_headers->append(content_range);
455
456  if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
457    std::string data;
458    if (end == start) {
459      EXPECT_EQ(0, end % 10);
460      data = "r";
461    } else {
462      EXPECT_EQ(9, (end - start) % 10);
463      for (int block_start = start; block_start < end; block_start += 10) {
464        base::StringAppendF(&data, "rg: %02d-%02d ",
465                            block_start, block_start + 9);
466      }
467    }
468    *response_data = data;
469
470    if (end - start != 9) {
471      // We also have to fix content-length.
472      int len = end - start + 1;
473      std::string content_length = base::StringPrintf("Content-Length: %d\n",
474                                                      len);
475      response_headers->replace(response_headers->find("Content-Length:"),
476                                content_length.size(), content_length);
477    }
478  } else {
479    response_status->assign("HTTP/1.1 304 Not Modified");
480    response_data->clear();
481  }
482}
483
484const MockTransaction kRangeGET_TransactionOK = {
485  "http://www.google.com/range",
486  "GET",
487  base::Time(),
488  "Range: bytes = 40-49\r\n"
489  EXTRA_HEADER,
490  net::LOAD_NORMAL,
491  "HTTP/1.1 206 Partial Content",
492  "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
493  "ETag: \"foo\"\n"
494  "Accept-Ranges: bytes\n"
495  "Content-Length: 10\n",
496  base::Time(),
497  "rg: 40-49 ",
498  TEST_MODE_NORMAL,
499  &RangeTransactionServer::RangeHandler,
500  0,
501  net::OK
502};
503
504// Verifies the response headers (|response|) match a partial content
505// response for the range starting at |start| and ending at |end|.
506void Verify206Response(std::string response, int start, int end) {
507  std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
508                                                            response.size()));
509  scoped_refptr<net::HttpResponseHeaders> headers(
510      new net::HttpResponseHeaders(raw_headers));
511
512  ASSERT_EQ(206, headers->response_code());
513
514  int64 range_start, range_end, object_size;
515  ASSERT_TRUE(
516      headers->GetContentRange(&range_start, &range_end, &object_size));
517  int64 content_length = headers->GetContentLength();
518
519  int length = end - start + 1;
520  ASSERT_EQ(length, content_length);
521  ASSERT_EQ(start, range_start);
522  ASSERT_EQ(end, range_end);
523}
524
525// Creates a truncated entry that can be resumed using byte ranges.
526void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
527  // Create a disk cache entry that stores an incomplete resource.
528  disk_cache::Entry* entry;
529  ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
530                                        NULL));
531
532  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
533                                                  raw_headers.size());
534
535  net::HttpResponseInfo response;
536  response.response_time = base::Time::Now();
537  response.request_time = base::Time::Now();
538  response.headers = new net::HttpResponseHeaders(raw_headers);
539  // Set the last argument for this to be an incomplete request.
540  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
541
542  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
543  int len = static_cast<int>(base::strlcpy(buf->data(),
544                                           "rg: 00-09 rg: 10-19 ", 100));
545  net::TestCompletionCallback cb;
546  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
547  EXPECT_EQ(len, cb.GetResult(rv));
548  entry->Close();
549}
550
551// Helper to represent a network HTTP response.
552struct Response {
553  // Set this response into |trans|.
554  void AssignTo(MockTransaction* trans) const {
555    trans->status = status;
556    trans->response_headers = headers;
557    trans->data = body;
558  }
559
560  std::string status_and_headers() const {
561    return std::string(status) + "\n" + std::string(headers);
562  }
563
564  const char* status;
565  const char* headers;
566  const char* body;
567};
568
569struct Context {
570  Context() : result(net::ERR_IO_PENDING) {}
571
572  int result;
573  net::TestCompletionCallback callback;
574  scoped_ptr<net::HttpTransaction> trans;
575};
576
577}  // namespace
578
579
580//-----------------------------------------------------------------------------
581// Tests.
582
583TEST(HttpCache, CreateThenDestroy) {
584  MockHttpCache cache;
585
586  scoped_ptr<net::HttpTransaction> trans;
587  int rv = cache.http_cache()->CreateTransaction(
588      net::DEFAULT_PRIORITY, &trans, NULL);
589  EXPECT_EQ(net::OK, rv);
590  ASSERT_TRUE(trans.get());
591}
592
593TEST(HttpCache, GetBackend) {
594  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
595
596  disk_cache::Backend* backend;
597  net::TestCompletionCallback cb;
598  // This will lazily initialize the backend.
599  int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
600  EXPECT_EQ(net::OK, cb.GetResult(rv));
601}
602
603TEST(HttpCache, SimpleGET) {
604  MockHttpCache cache;
605  net::CapturingBoundNetLog log;
606  net::LoadTimingInfo load_timing_info;
607
608  // Write to the cache.
609  RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
610                                 log.bound(), &load_timing_info);
611
612  EXPECT_EQ(1, cache.network_layer()->transaction_count());
613  EXPECT_EQ(0, cache.disk_cache()->open_count());
614  EXPECT_EQ(1, cache.disk_cache()->create_count());
615  TestLoadTimingNetworkRequest(load_timing_info);
616}
617
618TEST(HttpCache, SimpleGETNoDiskCache) {
619  MockHttpCache cache;
620
621  cache.disk_cache()->set_fail_requests();
622
623  net::CapturingBoundNetLog log;
624  log.SetLogLevel(net::NetLog::LOG_BASIC);
625  net::LoadTimingInfo load_timing_info;
626
627  // Read from the network, and don't use the cache.
628  RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
629                                 log.bound(), &load_timing_info);
630
631  // Check that the NetLog was filled as expected.
632  // (We attempted to both Open and Create entries, but both failed).
633  net::CapturingNetLog::CapturedEntryList entries;
634  log.GetEntries(&entries);
635
636  EXPECT_EQ(6u, entries.size());
637  EXPECT_TRUE(net::LogContainsBeginEvent(
638      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
639  EXPECT_TRUE(net::LogContainsEndEvent(
640      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
641  EXPECT_TRUE(net::LogContainsBeginEvent(
642      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
643  EXPECT_TRUE(net::LogContainsEndEvent(
644      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
645  EXPECT_TRUE(net::LogContainsBeginEvent(
646      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
647  EXPECT_TRUE(net::LogContainsEndEvent(
648      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
649
650  EXPECT_EQ(1, cache.network_layer()->transaction_count());
651  EXPECT_EQ(0, cache.disk_cache()->open_count());
652  EXPECT_EQ(0, cache.disk_cache()->create_count());
653  TestLoadTimingNetworkRequest(load_timing_info);
654}
655
656TEST(HttpCache, SimpleGETNoDiskCache2) {
657  // This will initialize a cache object with NULL backend.
658  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
659  factory->set_fail(true);
660  factory->FinishCreation();  // We'll complete synchronously.
661  MockHttpCache cache(factory);
662
663  // Read from the network, and don't use the cache.
664  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
665
666  EXPECT_EQ(1, cache.network_layer()->transaction_count());
667  EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
668}
669
670// Tests that IOBuffers are not referenced after IO completes.
671TEST(HttpCache, ReleaseBuffer) {
672  MockHttpCache cache;
673
674  // Write to the cache.
675  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
676
677  MockHttpRequest request(kSimpleGET_Transaction);
678  scoped_ptr<net::HttpTransaction> trans;
679  int rv = cache.http_cache()->CreateTransaction(
680      net::DEFAULT_PRIORITY, &trans, NULL);
681  ASSERT_EQ(net::OK, rv);
682
683  const int kBufferSize = 10;
684  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
685  net::ReleaseBufferCompletionCallback cb(buffer.get());
686
687  rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
688  EXPECT_EQ(net::OK, cb.GetResult(rv));
689
690  rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
691  EXPECT_EQ(kBufferSize, cb.GetResult(rv));
692}
693
694TEST(HttpCache, SimpleGETWithDiskFailures) {
695  MockHttpCache cache;
696
697  cache.disk_cache()->set_soft_failures(true);
698
699  // Read from the network, and fail to write to the cache.
700  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
701
702  EXPECT_EQ(1, cache.network_layer()->transaction_count());
703  EXPECT_EQ(0, cache.disk_cache()->open_count());
704  EXPECT_EQ(1, cache.disk_cache()->create_count());
705
706  // This one should see an empty cache again.
707  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
708
709  EXPECT_EQ(2, cache.network_layer()->transaction_count());
710  EXPECT_EQ(0, cache.disk_cache()->open_count());
711  EXPECT_EQ(2, cache.disk_cache()->create_count());
712}
713
714// Tests that disk failures after the transaction has started don't cause the
715// request to fail.
716TEST(HttpCache, SimpleGETWithDiskFailures2) {
717  MockHttpCache cache;
718
719  MockHttpRequest request(kSimpleGET_Transaction);
720
721  scoped_ptr<Context> c(new Context());
722  int rv = cache.http_cache()->CreateTransaction(
723      net::DEFAULT_PRIORITY, &c->trans, NULL);
724  EXPECT_EQ(net::OK, rv);
725
726  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
727  EXPECT_EQ(net::ERR_IO_PENDING, rv);
728  rv = c->callback.WaitForResult();
729
730  // Start failing request now.
731  cache.disk_cache()->set_soft_failures(true);
732
733  // We have to open the entry again to propagate the failure flag.
734  disk_cache::Entry* en;
735  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
736  en->Close();
737
738  ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
739  c.reset();
740
741  EXPECT_EQ(1, cache.network_layer()->transaction_count());
742  EXPECT_EQ(1, cache.disk_cache()->open_count());
743  EXPECT_EQ(1, cache.disk_cache()->create_count());
744
745  // This one should see an empty cache again.
746  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
747
748  EXPECT_EQ(2, cache.network_layer()->transaction_count());
749  EXPECT_EQ(1, cache.disk_cache()->open_count());
750  EXPECT_EQ(2, cache.disk_cache()->create_count());
751}
752
753// Tests that we handle failures to read from the cache.
754TEST(HttpCache, SimpleGETWithDiskFailures3) {
755  MockHttpCache cache;
756
757  // Read from the network, and write to the cache.
758  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
759
760  EXPECT_EQ(1, cache.network_layer()->transaction_count());
761  EXPECT_EQ(0, cache.disk_cache()->open_count());
762  EXPECT_EQ(1, cache.disk_cache()->create_count());
763
764  cache.disk_cache()->set_soft_failures(true);
765
766  // Now fail to read from the cache.
767  scoped_ptr<Context> c(new Context());
768  int rv = cache.http_cache()->CreateTransaction(
769      net::DEFAULT_PRIORITY, &c->trans, NULL);
770  EXPECT_EQ(net::OK, rv);
771
772  MockHttpRequest request(kSimpleGET_Transaction);
773  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
774  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
775
776  // Now verify that the entry was removed from the cache.
777  cache.disk_cache()->set_soft_failures(false);
778
779  EXPECT_EQ(2, cache.network_layer()->transaction_count());
780  EXPECT_EQ(1, cache.disk_cache()->open_count());
781  EXPECT_EQ(2, cache.disk_cache()->create_count());
782
783  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
784
785  EXPECT_EQ(3, cache.network_layer()->transaction_count());
786  EXPECT_EQ(1, cache.disk_cache()->open_count());
787  EXPECT_EQ(3, cache.disk_cache()->create_count());
788}
789
790TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
791  MockHttpCache cache;
792
793  net::CapturingBoundNetLog log;
794
795  // This prevents a number of write events from being logged.
796  log.SetLogLevel(net::NetLog::LOG_BASIC);
797
798  net::LoadTimingInfo load_timing_info;
799
800  // Write to the cache.
801  RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
802                                 log.bound(), &load_timing_info);
803
804  // Check that the NetLog was filled as expected.
805  net::CapturingNetLog::CapturedEntryList entries;
806  log.GetEntries(&entries);
807
808  EXPECT_EQ(8u, entries.size());
809  EXPECT_TRUE(net::LogContainsBeginEvent(
810      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
811  EXPECT_TRUE(net::LogContainsEndEvent(
812      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
813  EXPECT_TRUE(net::LogContainsBeginEvent(
814      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
815  EXPECT_TRUE(net::LogContainsEndEvent(
816      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
817  EXPECT_TRUE(net::LogContainsBeginEvent(
818      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
819  EXPECT_TRUE(net::LogContainsEndEvent(
820      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
821  EXPECT_TRUE(net::LogContainsBeginEvent(
822      entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
823  EXPECT_TRUE(net::LogContainsEndEvent(
824      entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
825
826  TestLoadTimingNetworkRequest(load_timing_info);
827
828  // Force this transaction to read from the cache.
829  MockTransaction transaction(kSimpleGET_Transaction);
830  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
831
832  log.Clear();
833
834  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
835                                 &load_timing_info);
836
837  // Check that the NetLog was filled as expected.
838  log.GetEntries(&entries);
839
840  EXPECT_EQ(8u, entries.size());
841  EXPECT_TRUE(net::LogContainsBeginEvent(
842      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
843  EXPECT_TRUE(net::LogContainsEndEvent(
844      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
845  EXPECT_TRUE(net::LogContainsBeginEvent(
846      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
847  EXPECT_TRUE(net::LogContainsEndEvent(
848      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
849  EXPECT_TRUE(net::LogContainsBeginEvent(
850      entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
851  EXPECT_TRUE(net::LogContainsEndEvent(
852      entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
853  EXPECT_TRUE(net::LogContainsBeginEvent(
854      entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
855  EXPECT_TRUE(net::LogContainsEndEvent(
856      entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
857
858  EXPECT_EQ(1, cache.network_layer()->transaction_count());
859  EXPECT_EQ(1, cache.disk_cache()->open_count());
860  EXPECT_EQ(1, cache.disk_cache()->create_count());
861  TestLoadTimingCachedResponse(load_timing_info);
862}
863
864TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
865  MockHttpCache cache;
866
867  // force this transaction to read from the cache
868  MockTransaction transaction(kSimpleGET_Transaction);
869  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
870
871  MockHttpRequest request(transaction);
872  net::TestCompletionCallback callback;
873
874  scoped_ptr<net::HttpTransaction> trans;
875  int rv = cache.http_cache()->CreateTransaction(
876      net::DEFAULT_PRIORITY, &trans, NULL);
877  EXPECT_EQ(net::OK, rv);
878  ASSERT_TRUE(trans.get());
879
880  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
881  if (rv == net::ERR_IO_PENDING)
882    rv = callback.WaitForResult();
883  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
884
885  trans.reset();
886
887  EXPECT_EQ(0, cache.network_layer()->transaction_count());
888  EXPECT_EQ(0, cache.disk_cache()->open_count());
889  EXPECT_EQ(0, cache.disk_cache()->create_count());
890}
891
892TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
893  MockHttpCache cache;
894
895  // write to the cache
896  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
897
898  // force this transaction to read from the cache if valid
899  MockTransaction transaction(kSimpleGET_Transaction);
900  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
901
902  RunTransactionTest(cache.http_cache(), transaction);
903
904  EXPECT_EQ(1, cache.network_layer()->transaction_count());
905  EXPECT_EQ(1, cache.disk_cache()->open_count());
906  EXPECT_EQ(1, cache.disk_cache()->create_count());
907}
908
909TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
910  MockHttpCache cache;
911
912  // force this transaction to read from the cache if valid
913  MockTransaction transaction(kSimpleGET_Transaction);
914  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
915
916  RunTransactionTest(cache.http_cache(), transaction);
917
918  EXPECT_EQ(1, cache.network_layer()->transaction_count());
919  EXPECT_EQ(0, cache.disk_cache()->open_count());
920  EXPECT_EQ(1, cache.disk_cache()->create_count());
921}
922
923// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
924TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
925  MockHttpCache cache;
926
927  // Write to the cache.
928  MockTransaction transaction(kSimpleGET_Transaction);
929  transaction.request_headers = "Foo: bar\r\n";
930  transaction.response_headers = "Cache-Control: max-age=10000\n"
931                                 "Vary: Foo\n";
932  AddMockTransaction(&transaction);
933  RunTransactionTest(cache.http_cache(), transaction);
934
935  // Read from the cache.
936  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
937  RunTransactionTest(cache.http_cache(), transaction);
938
939  EXPECT_EQ(1, cache.network_layer()->transaction_count());
940  EXPECT_EQ(1, cache.disk_cache()->open_count());
941  EXPECT_EQ(1, cache.disk_cache()->create_count());
942  RemoveMockTransaction(&transaction);
943}
944
945// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
946TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
947  MockHttpCache cache;
948
949  // Write to the cache.
950  MockTransaction transaction(kSimpleGET_Transaction);
951  transaction.request_headers = "Foo: bar\r\n";
952  transaction.response_headers = "Cache-Control: max-age=10000\n"
953                                 "Vary: Foo\n";
954  AddMockTransaction(&transaction);
955  RunTransactionTest(cache.http_cache(), transaction);
956
957  // Attempt to read from the cache... this is a vary mismatch that must reach
958  // the network again.
959  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
960  transaction.request_headers = "Foo: none\r\n";
961  net::CapturingBoundNetLog log;
962  net::LoadTimingInfo load_timing_info;
963  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
964                                 &load_timing_info);
965
966  EXPECT_EQ(2, cache.network_layer()->transaction_count());
967  EXPECT_EQ(1, cache.disk_cache()->open_count());
968  EXPECT_EQ(1, cache.disk_cache()->create_count());
969  TestLoadTimingNetworkRequest(load_timing_info);
970  RemoveMockTransaction(&transaction);
971}
972
973// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
974// network success
975TEST(HttpCache, SimpleGET_CacheOverride_Network) {
976  MockHttpCache cache;
977
978  // Prime cache.
979  MockTransaction transaction(kSimpleGET_Transaction);
980  transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
981  transaction.response_headers = "Cache-Control: no-cache\n";
982
983  AddMockTransaction(&transaction);
984  RunTransactionTest(cache.http_cache(), transaction);
985  EXPECT_EQ(1, cache.network_layer()->transaction_count());
986  EXPECT_EQ(1, cache.disk_cache()->create_count());
987  RemoveMockTransaction(&transaction);
988
989  // Re-run transaction; make sure the result came from the network,
990  // not the cache.
991  transaction.data = "Changed data.";
992  AddMockTransaction(&transaction);
993  net::HttpResponseInfo response_info;
994  RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
995                                     &response_info);
996
997  EXPECT_EQ(2, cache.network_layer()->transaction_count());
998  EXPECT_FALSE(response_info.server_data_unavailable);
999  EXPECT_TRUE(response_info.network_accessed);
1000
1001  RemoveMockTransaction(&transaction);
1002}
1003
1004// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1005// offline failure
1006TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
1007  MockHttpCache cache;
1008
1009  // Prime cache.
1010  MockTransaction transaction(kSimpleGET_Transaction);
1011  transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1012  transaction.response_headers = "Cache-Control: no-cache\n";
1013
1014  AddMockTransaction(&transaction);
1015  RunTransactionTest(cache.http_cache(), transaction);
1016  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1017  EXPECT_EQ(1, cache.disk_cache()->create_count());
1018  RemoveMockTransaction(&transaction);
1019
1020  // Network failure with offline error; should return cache entry above +
1021  // flag signalling stale data.
1022  transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
1023  AddMockTransaction(&transaction);
1024
1025  MockHttpRequest request(transaction);
1026  net::TestCompletionCallback callback;
1027  scoped_ptr<net::HttpTransaction> trans;
1028  int rv = cache.http_cache()->CreateTransaction(
1029      net::DEFAULT_PRIORITY, &trans, NULL);
1030  EXPECT_EQ(net::OK, rv);
1031  ASSERT_TRUE(trans.get());
1032  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1033  EXPECT_EQ(net::OK, callback.GetResult(rv));
1034
1035  const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1036  ASSERT_TRUE(response_info);
1037  EXPECT_TRUE(response_info->server_data_unavailable);
1038  EXPECT_TRUE(response_info->was_cached);
1039  EXPECT_FALSE(response_info->network_accessed);
1040  ReadAndVerifyTransaction(trans.get(), transaction);
1041  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1042
1043  RemoveMockTransaction(&transaction);
1044}
1045
1046// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1047// non-offline failure.
1048TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
1049  MockHttpCache cache;
1050
1051  // Prime cache.
1052  MockTransaction transaction(kSimpleGET_Transaction);
1053  transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1054  transaction.response_headers = "Cache-Control: no-cache\n";
1055
1056  AddMockTransaction(&transaction);
1057  RunTransactionTest(cache.http_cache(), transaction);
1058  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1059  EXPECT_EQ(1, cache.disk_cache()->create_count());
1060  RemoveMockTransaction(&transaction);
1061
1062  // Network failure with non-offline error; should fail with that error.
1063  transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1064  AddMockTransaction(&transaction);
1065
1066  net::HttpResponseInfo response_info2;
1067  RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1068                                     &response_info2);
1069
1070  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1071  EXPECT_FALSE(response_info2.server_data_unavailable);
1072
1073  RemoveMockTransaction(&transaction);
1074}
1075
1076// Confirm if we have an empty cache, a read is marked as network verified.
1077TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1078  MockHttpCache cache;
1079
1080  // write to the cache
1081  net::HttpResponseInfo response_info;
1082  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1083                                     &response_info);
1084
1085  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1086  EXPECT_EQ(0, cache.disk_cache()->open_count());
1087  EXPECT_EQ(1, cache.disk_cache()->create_count());
1088  EXPECT_TRUE(response_info.network_accessed);
1089}
1090
1091// Confirm if we have a fresh entry in cache, it isn't marked as
1092// network verified.
1093TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1094  MockHttpCache cache;
1095
1096  // Prime cache.
1097  MockTransaction transaction(kSimpleGET_Transaction);
1098
1099  RunTransactionTest(cache.http_cache(), transaction);
1100  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1101  EXPECT_EQ(1, cache.disk_cache()->create_count());
1102
1103  // Re-run transaction; make sure we don't mark the network as accessed.
1104  net::HttpResponseInfo response_info;
1105  RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1106                                     &response_info);
1107
1108  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1109  EXPECT_FALSE(response_info.server_data_unavailable);
1110  EXPECT_FALSE(response_info.network_accessed);
1111}
1112
1113TEST(HttpCache, SimpleGET_LoadBypassCache) {
1114  MockHttpCache cache;
1115
1116  // Write to the cache.
1117  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1118
1119  // Force this transaction to write to the cache again.
1120  MockTransaction transaction(kSimpleGET_Transaction);
1121  transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1122
1123  net::CapturingBoundNetLog log;
1124
1125  // This prevents a number of write events from being logged.
1126  log.SetLogLevel(net::NetLog::LOG_BASIC);
1127  net::LoadTimingInfo load_timing_info;
1128
1129  // Write to the cache.
1130  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1131                                 &load_timing_info);
1132
1133  // Check that the NetLog was filled as expected.
1134  net::CapturingNetLog::CapturedEntryList entries;
1135  log.GetEntries(&entries);
1136
1137  EXPECT_EQ(8u, entries.size());
1138  EXPECT_TRUE(net::LogContainsBeginEvent(
1139      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1140  EXPECT_TRUE(net::LogContainsEndEvent(
1141      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1142  EXPECT_TRUE(net::LogContainsBeginEvent(
1143      entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1144  EXPECT_TRUE(net::LogContainsEndEvent(
1145      entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1146  EXPECT_TRUE(net::LogContainsBeginEvent(
1147      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1148  EXPECT_TRUE(net::LogContainsEndEvent(
1149      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1150  EXPECT_TRUE(net::LogContainsBeginEvent(
1151      entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1152  EXPECT_TRUE(net::LogContainsEndEvent(
1153      entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1154
1155  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1156  EXPECT_EQ(0, cache.disk_cache()->open_count());
1157  EXPECT_EQ(2, cache.disk_cache()->create_count());
1158  TestLoadTimingNetworkRequest(load_timing_info);
1159}
1160
1161TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1162  MockHttpCache cache;
1163
1164  // write to the cache
1165  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1166
1167  // force this transaction to write to the cache again
1168  MockTransaction transaction(kSimpleGET_Transaction);
1169  transaction.request_headers = "pragma: no-cache\r\n";
1170
1171  RunTransactionTest(cache.http_cache(), transaction);
1172
1173  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1174  EXPECT_EQ(0, cache.disk_cache()->open_count());
1175  EXPECT_EQ(2, cache.disk_cache()->create_count());
1176}
1177
1178TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1179  MockHttpCache cache;
1180
1181  // write to the cache
1182  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1183
1184  // force this transaction to write to the cache again
1185  MockTransaction transaction(kSimpleGET_Transaction);
1186  transaction.request_headers = "cache-control: no-cache\r\n";
1187
1188  RunTransactionTest(cache.http_cache(), transaction);
1189
1190  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1191  EXPECT_EQ(0, cache.disk_cache()->open_count());
1192  EXPECT_EQ(2, cache.disk_cache()->create_count());
1193}
1194
1195TEST(HttpCache, SimpleGET_LoadValidateCache) {
1196  MockHttpCache cache;
1197
1198  // Write to the cache.
1199  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1200
1201  // Read from the cache.
1202  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1203
1204  // Force this transaction to validate the cache.
1205  MockTransaction transaction(kSimpleGET_Transaction);
1206  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1207
1208  net::HttpResponseInfo response_info;
1209  net::CapturingBoundNetLog log;
1210  net::LoadTimingInfo load_timing_info;
1211  RunTransactionTestWithResponseInfoAndGetTiming(
1212      cache.http_cache(), transaction, &response_info, log.bound(),
1213      &load_timing_info);
1214
1215  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1216  EXPECT_EQ(1, cache.disk_cache()->open_count());
1217  EXPECT_EQ(1, cache.disk_cache()->create_count());
1218  EXPECT_TRUE(response_info.network_accessed);
1219  TestLoadTimingNetworkRequest(load_timing_info);
1220}
1221
1222TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1223  MockHttpCache cache;
1224
1225  // write to the cache
1226  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1227
1228  // read from the cache
1229  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1230
1231  // force this transaction to validate the cache
1232  MockTransaction transaction(kSimpleGET_Transaction);
1233  transaction.request_headers = "cache-control: max-age=0\r\n";
1234
1235  RunTransactionTest(cache.http_cache(), transaction);
1236
1237  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1238  EXPECT_EQ(1, cache.disk_cache()->open_count());
1239  EXPECT_EQ(1, cache.disk_cache()->create_count());
1240}
1241
1242static void PreserveRequestHeaders_Handler(
1243    const net::HttpRequestInfo* request,
1244    std::string* response_status,
1245    std::string* response_headers,
1246    std::string* response_data) {
1247  EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1248}
1249
1250// Tests that we don't remove extra headers for simple requests.
1251TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1252  MockHttpCache cache;
1253
1254  MockTransaction transaction(kSimpleGET_Transaction);
1255  transaction.handler = PreserveRequestHeaders_Handler;
1256  transaction.request_headers = EXTRA_HEADER;
1257  transaction.response_headers = "Cache-Control: max-age=0\n";
1258  AddMockTransaction(&transaction);
1259
1260  // Write, then revalidate the entry.
1261  RunTransactionTest(cache.http_cache(), transaction);
1262  RunTransactionTest(cache.http_cache(), transaction);
1263
1264  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1265  EXPECT_EQ(1, cache.disk_cache()->open_count());
1266  EXPECT_EQ(1, cache.disk_cache()->create_count());
1267  RemoveMockTransaction(&transaction);
1268}
1269
1270// Tests that we don't remove extra headers for conditionalized requests.
1271TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1272  MockHttpCache cache;
1273
1274  // Write to the cache.
1275  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1276
1277  MockTransaction transaction(kETagGET_Transaction);
1278  transaction.handler = PreserveRequestHeaders_Handler;
1279  transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1280                                EXTRA_HEADER;
1281  AddMockTransaction(&transaction);
1282
1283  RunTransactionTest(cache.http_cache(), transaction);
1284
1285  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1286  EXPECT_EQ(1, cache.disk_cache()->open_count());
1287  EXPECT_EQ(1, cache.disk_cache()->create_count());
1288  RemoveMockTransaction(&transaction);
1289}
1290
1291TEST(HttpCache, SimpleGET_ManyReaders) {
1292  MockHttpCache cache;
1293
1294  MockHttpRequest request(kSimpleGET_Transaction);
1295
1296  std::vector<Context*> context_list;
1297  const int kNumTransactions = 5;
1298
1299  for (int i = 0; i < kNumTransactions; ++i) {
1300    context_list.push_back(new Context());
1301    Context* c = context_list[i];
1302
1303    c->result = cache.http_cache()->CreateTransaction(
1304        net::DEFAULT_PRIORITY, &c->trans, NULL);
1305    EXPECT_EQ(net::OK, c->result);
1306    EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1307
1308    c->result = c->trans->Start(
1309        &request, c->callback.callback(), net::BoundNetLog());
1310  }
1311
1312  // All requests are waiting for the active entry.
1313  for (int i = 0; i < kNumTransactions; ++i) {
1314    Context* c = context_list[i];
1315    EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1316  }
1317
1318  // Allow all requests to move from the Create queue to the active entry.
1319  base::MessageLoop::current()->RunUntilIdle();
1320
1321  // The first request should be a writer at this point, and the subsequent
1322  // requests should be pending.
1323
1324  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1325  EXPECT_EQ(0, cache.disk_cache()->open_count());
1326  EXPECT_EQ(1, cache.disk_cache()->create_count());
1327
1328  // All requests depend on the writer, and the writer is between Start and
1329  // Read, i.e. idle.
1330  for (int i = 0; i < kNumTransactions; ++i) {
1331    Context* c = context_list[i];
1332    EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1333  }
1334
1335  for (int i = 0; i < kNumTransactions; ++i) {
1336    Context* c = context_list[i];
1337    if (c->result == net::ERR_IO_PENDING)
1338      c->result = c->callback.WaitForResult();
1339    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1340  }
1341
1342  // We should not have had to re-open the disk entry
1343
1344  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1345  EXPECT_EQ(0, cache.disk_cache()->open_count());
1346  EXPECT_EQ(1, cache.disk_cache()->create_count());
1347
1348  for (int i = 0; i < kNumTransactions; ++i) {
1349    Context* c = context_list[i];
1350    delete c;
1351  }
1352}
1353
1354// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1355// If cancelling a request is racing with another request for the same resource
1356// finishing, we have to make sure that we remove both transactions from the
1357// entry.
1358TEST(HttpCache, SimpleGET_RacingReaders) {
1359  MockHttpCache cache;
1360
1361  MockHttpRequest request(kSimpleGET_Transaction);
1362  MockHttpRequest reader_request(kSimpleGET_Transaction);
1363  reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1364
1365  std::vector<Context*> context_list;
1366  const int kNumTransactions = 5;
1367
1368  for (int i = 0; i < kNumTransactions; ++i) {
1369    context_list.push_back(new Context());
1370    Context* c = context_list[i];
1371
1372    c->result = cache.http_cache()->CreateTransaction(
1373        net::DEFAULT_PRIORITY, &c->trans, NULL);
1374    EXPECT_EQ(net::OK, c->result);
1375
1376    MockHttpRequest* this_request = &request;
1377    if (i == 1 || i == 2)
1378      this_request = &reader_request;
1379
1380    c->result = c->trans->Start(
1381        this_request, c->callback.callback(), net::BoundNetLog());
1382  }
1383
1384  // Allow all requests to move from the Create queue to the active entry.
1385  base::MessageLoop::current()->RunUntilIdle();
1386
1387  // The first request should be a writer at this point, and the subsequent
1388  // requests should be pending.
1389
1390  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1391  EXPECT_EQ(0, cache.disk_cache()->open_count());
1392  EXPECT_EQ(1, cache.disk_cache()->create_count());
1393
1394  Context* c = context_list[0];
1395  ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1396  c->result = c->callback.WaitForResult();
1397  ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1398
1399  // Now we have 2 active readers and two queued transactions.
1400
1401  EXPECT_EQ(net::LOAD_STATE_IDLE,
1402            context_list[2]->trans->GetLoadState());
1403  EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1404            context_list[3]->trans->GetLoadState());
1405
1406  c = context_list[1];
1407  ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1408  c->result = c->callback.WaitForResult();
1409  if (c->result == net::OK)
1410    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1411
1412  // At this point we have one reader, two pending transactions and a task on
1413  // the queue to move to the next transaction. Now we cancel the request that
1414  // is the current reader, and expect the queued task to be able to start the
1415  // next request.
1416
1417  c = context_list[2];
1418  c->trans.reset();
1419
1420  for (int i = 3; i < kNumTransactions; ++i) {
1421    Context* c = context_list[i];
1422    if (c->result == net::ERR_IO_PENDING)
1423      c->result = c->callback.WaitForResult();
1424    if (c->result == net::OK)
1425      ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1426  }
1427
1428  // We should not have had to re-open the disk entry.
1429
1430  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1431  EXPECT_EQ(0, cache.disk_cache()->open_count());
1432  EXPECT_EQ(1, cache.disk_cache()->create_count());
1433
1434  for (int i = 0; i < kNumTransactions; ++i) {
1435    Context* c = context_list[i];
1436    delete c;
1437  }
1438}
1439
1440// Tests that we can doom an entry with pending transactions and delete one of
1441// the pending transactions before the first one completes.
1442// See http://code.google.com/p/chromium/issues/detail?id=25588
1443TEST(HttpCache, SimpleGET_DoomWithPending) {
1444  // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1445  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1446
1447  MockHttpRequest request(kSimpleGET_Transaction);
1448  MockHttpRequest writer_request(kSimpleGET_Transaction);
1449  writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1450
1451  ScopedVector<Context> context_list;
1452  const int kNumTransactions = 4;
1453
1454  for (int i = 0; i < kNumTransactions; ++i) {
1455    context_list.push_back(new Context());
1456    Context* c = context_list[i];
1457
1458    c->result = cache.http_cache()->CreateTransaction(
1459        net::DEFAULT_PRIORITY, &c->trans, NULL);
1460    EXPECT_EQ(net::OK, c->result);
1461
1462    MockHttpRequest* this_request = &request;
1463    if (i == 3)
1464      this_request = &writer_request;
1465
1466    c->result = c->trans->Start(
1467        this_request, c->callback.callback(), net::BoundNetLog());
1468  }
1469
1470  // The first request should be a writer at this point, and the two subsequent
1471  // requests should be pending. The last request doomed the first entry.
1472
1473  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1474
1475  // Cancel the first queued transaction.
1476  delete context_list[1];
1477  context_list.get()[1] = NULL;
1478
1479  for (int i = 0; i < kNumTransactions; ++i) {
1480    if (i == 1)
1481      continue;
1482    Context* c = context_list[i];
1483    ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1484    c->result = c->callback.WaitForResult();
1485    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1486  }
1487}
1488
1489// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1490// We may attempt to delete an entry synchronously with the act of adding a new
1491// transaction to said entry.
1492TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1493  MockHttpCache cache;
1494
1495  // The headers will be served right from the call to Start() the request.
1496  MockHttpRequest request(kFastNoStoreGET_Transaction);
1497  FastTransactionServer request_handler;
1498  AddMockTransaction(&kFastNoStoreGET_Transaction);
1499
1500  std::vector<Context*> context_list;
1501  const int kNumTransactions = 3;
1502
1503  for (int i = 0; i < kNumTransactions; ++i) {
1504    context_list.push_back(new Context());
1505    Context* c = context_list[i];
1506
1507    c->result = cache.http_cache()->CreateTransaction(
1508        net::DEFAULT_PRIORITY, &c->trans, NULL);
1509    EXPECT_EQ(net::OK, c->result);
1510
1511    c->result = c->trans->Start(
1512        &request, c->callback.callback(), net::BoundNetLog());
1513  }
1514
1515  // Allow all requests to move from the Create queue to the active entry.
1516  base::MessageLoop::current()->RunUntilIdle();
1517
1518  // The first request should be a writer at this point, and the subsequent
1519  // requests should be pending.
1520
1521  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1522  EXPECT_EQ(0, cache.disk_cache()->open_count());
1523  EXPECT_EQ(1, cache.disk_cache()->create_count());
1524
1525  // Now, make sure that the second request asks for the entry not to be stored.
1526  request_handler.set_no_store(true);
1527
1528  for (int i = 0; i < kNumTransactions; ++i) {
1529    Context* c = context_list[i];
1530    if (c->result == net::ERR_IO_PENDING)
1531      c->result = c->callback.WaitForResult();
1532    ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1533    delete c;
1534  }
1535
1536  EXPECT_EQ(3, cache.network_layer()->transaction_count());
1537  EXPECT_EQ(0, cache.disk_cache()->open_count());
1538  EXPECT_EQ(2, cache.disk_cache()->create_count());
1539
1540  RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1541}
1542
1543TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1544  MockHttpCache cache;
1545
1546  MockHttpRequest request(kSimpleGET_Transaction);
1547
1548  std::vector<Context*> context_list;
1549  const int kNumTransactions = 2;
1550
1551  for (int i = 0; i < kNumTransactions; ++i) {
1552    context_list.push_back(new Context());
1553    Context* c = context_list[i];
1554
1555    c->result = cache.http_cache()->CreateTransaction(
1556        net::DEFAULT_PRIORITY, &c->trans, NULL);
1557    EXPECT_EQ(net::OK, c->result);
1558
1559    c->result = c->trans->Start(
1560        &request, c->callback.callback(), net::BoundNetLog());
1561  }
1562
1563  // Allow all requests to move from the Create queue to the active entry.
1564  base::MessageLoop::current()->RunUntilIdle();
1565
1566  // The first request should be a writer at this point, and the subsequent
1567  // requests should be pending.
1568
1569  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1570  EXPECT_EQ(0, cache.disk_cache()->open_count());
1571  EXPECT_EQ(1, cache.disk_cache()->create_count());
1572
1573  for (int i = 0; i < kNumTransactions; ++i) {
1574    Context* c = context_list[i];
1575    if (c->result == net::ERR_IO_PENDING)
1576      c->result = c->callback.WaitForResult();
1577    // Destroy only the first transaction.
1578    if (i == 0) {
1579      delete c;
1580      context_list[i] = NULL;
1581    }
1582  }
1583
1584  // Complete the rest of the transactions.
1585  for (int i = 1; i < kNumTransactions; ++i) {
1586    Context* c = context_list[i];
1587    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1588  }
1589
1590  // We should have had to re-open the disk entry.
1591
1592  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1593  EXPECT_EQ(0, cache.disk_cache()->open_count());
1594  EXPECT_EQ(2, cache.disk_cache()->create_count());
1595
1596  for (int i = 1; i < kNumTransactions; ++i) {
1597    Context* c = context_list[i];
1598    delete c;
1599  }
1600}
1601
1602// Tests that we can cancel requests that are queued waiting to open the disk
1603// cache entry.
1604TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1605  MockHttpCache cache;
1606
1607  MockHttpRequest request(kSimpleGET_Transaction);
1608
1609  std::vector<Context*> context_list;
1610  const int kNumTransactions = 5;
1611
1612  for (int i = 0; i < kNumTransactions; i++) {
1613    context_list.push_back(new Context());
1614    Context* c = context_list[i];
1615
1616    c->result = cache.http_cache()->CreateTransaction(
1617        net::DEFAULT_PRIORITY, &c->trans, NULL);
1618    EXPECT_EQ(net::OK, c->result);
1619
1620    c->result = c->trans->Start(
1621        &request, c->callback.callback(), net::BoundNetLog());
1622  }
1623
1624  // The first request should be creating the disk cache entry and the others
1625  // should be pending.
1626
1627  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1628  EXPECT_EQ(0, cache.disk_cache()->open_count());
1629  EXPECT_EQ(1, cache.disk_cache()->create_count());
1630
1631  // Cancel a request from the pending queue.
1632  delete context_list[3];
1633  context_list[3] = NULL;
1634
1635  // Cancel the request that is creating the entry. This will force the pending
1636  // operations to restart.
1637  delete context_list[0];
1638  context_list[0] = NULL;
1639
1640  // Complete the rest of the transactions.
1641  for (int i = 1; i < kNumTransactions; i++) {
1642    Context* c = context_list[i];
1643    if (c) {
1644      c->result = c->callback.GetResult(c->result);
1645      ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1646    }
1647  }
1648
1649  // We should have had to re-create the disk entry.
1650
1651  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1652  EXPECT_EQ(0, cache.disk_cache()->open_count());
1653  EXPECT_EQ(2, cache.disk_cache()->create_count());
1654
1655  for (int i = 1; i < kNumTransactions; ++i) {
1656    delete context_list[i];
1657  }
1658}
1659
1660// Tests that we can cancel a single request to open a disk cache entry.
1661TEST(HttpCache, SimpleGET_CancelCreate) {
1662  MockHttpCache cache;
1663
1664  MockHttpRequest request(kSimpleGET_Transaction);
1665
1666  Context* c = new Context();
1667
1668  c->result = cache.http_cache()->CreateTransaction(
1669      net::DEFAULT_PRIORITY, &c->trans, NULL);
1670  EXPECT_EQ(net::OK, c->result);
1671
1672  c->result = c->trans->Start(
1673      &request, c->callback.callback(), net::BoundNetLog());
1674  EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1675
1676  // Release the reference that the mock disk cache keeps for this entry, so
1677  // that we test that the http cache handles the cancellation correctly.
1678  cache.disk_cache()->ReleaseAll();
1679  delete c;
1680
1681  base::MessageLoop::current()->RunUntilIdle();
1682  EXPECT_EQ(1, cache.disk_cache()->create_count());
1683}
1684
1685// Tests that we delete/create entries even if multiple requests are queued.
1686TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1687  MockHttpCache cache;
1688
1689  MockHttpRequest request(kSimpleGET_Transaction);
1690  request.load_flags = net::LOAD_BYPASS_CACHE;
1691
1692  std::vector<Context*> context_list;
1693  const int kNumTransactions = 5;
1694
1695  for (int i = 0; i < kNumTransactions; i++) {
1696    context_list.push_back(new Context());
1697    Context* c = context_list[i];
1698
1699    c->result = cache.http_cache()->CreateTransaction(
1700        net::DEFAULT_PRIORITY, &c->trans, NULL);
1701    EXPECT_EQ(net::OK, c->result);
1702
1703    c->result = c->trans->Start(
1704        &request, c->callback.callback(), net::BoundNetLog());
1705  }
1706
1707  // The first request should be deleting the disk cache entry and the others
1708  // should be pending.
1709
1710  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1711  EXPECT_EQ(0, cache.disk_cache()->open_count());
1712  EXPECT_EQ(0, cache.disk_cache()->create_count());
1713
1714  // Complete the transactions.
1715  for (int i = 0; i < kNumTransactions; i++) {
1716    Context* c = context_list[i];
1717    c->result = c->callback.GetResult(c->result);
1718    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1719  }
1720
1721  // We should have had to re-create the disk entry multiple times.
1722
1723  EXPECT_EQ(5, cache.network_layer()->transaction_count());
1724  EXPECT_EQ(0, cache.disk_cache()->open_count());
1725  EXPECT_EQ(5, cache.disk_cache()->create_count());
1726
1727  for (int i = 0; i < kNumTransactions; ++i) {
1728    delete context_list[i];
1729  }
1730}
1731
1732TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1733  MockHttpCache cache;
1734
1735  // write to the cache
1736  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1737
1738  MockHttpRequest request(kSimpleGET_Transaction);
1739  net::TestCompletionCallback callback;
1740
1741  scoped_ptr<net::HttpTransaction> trans;
1742  int rv = cache.http_cache()->CreateTransaction(
1743      net::DEFAULT_PRIORITY, &trans, NULL);
1744  EXPECT_EQ(net::OK, rv);
1745  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1746  if (rv == net::ERR_IO_PENDING)
1747    rv = callback.WaitForResult();
1748  ASSERT_EQ(net::OK, rv);
1749
1750  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1751  rv = trans->Read(buf.get(), 256, callback.callback());
1752  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1753
1754  // Test that destroying the transaction while it is reading from the cache
1755  // works properly.
1756  trans.reset();
1757
1758  // Make sure we pump any pending events, which should include a call to
1759  // HttpCache::Transaction::OnCacheReadCompleted.
1760  base::MessageLoop::current()->RunUntilIdle();
1761}
1762
1763// Tests that we can delete the HttpCache and deal with queued transactions
1764// ("waiting for the backend" as opposed to Active or Doomed entries).
1765TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1766  scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1767                                      new MockBackendNoCbFactory()));
1768
1769  MockHttpRequest request(kSimpleGET_Transaction);
1770
1771  std::vector<Context*> context_list;
1772  const int kNumTransactions = 5;
1773
1774  for (int i = 0; i < kNumTransactions; i++) {
1775    context_list.push_back(new Context());
1776    Context* c = context_list[i];
1777
1778    c->result = cache->http_cache()->CreateTransaction(
1779        net::DEFAULT_PRIORITY, &c->trans, NULL);
1780    EXPECT_EQ(net::OK, c->result);
1781
1782    c->result = c->trans->Start(
1783        &request, c->callback.callback(), net::BoundNetLog());
1784  }
1785
1786  // The first request should be creating the disk cache entry and the others
1787  // should be pending.
1788
1789  EXPECT_EQ(0, cache->network_layer()->transaction_count());
1790  EXPECT_EQ(0, cache->disk_cache()->open_count());
1791  EXPECT_EQ(0, cache->disk_cache()->create_count());
1792
1793  cache.reset();
1794
1795  // There is not much to do with the transactions at this point... they are
1796  // waiting for a callback that will not fire.
1797  for (int i = 0; i < kNumTransactions; ++i) {
1798    delete context_list[i];
1799  }
1800}
1801
1802// Tests that we queue requests when initializing the backend.
1803TEST(HttpCache, SimpleGET_WaitForBackend) {
1804  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1805  MockHttpCache cache(factory);
1806
1807  MockHttpRequest request0(kSimpleGET_Transaction);
1808  MockHttpRequest request1(kTypicalGET_Transaction);
1809  MockHttpRequest request2(kETagGET_Transaction);
1810
1811  std::vector<Context*> context_list;
1812  const int kNumTransactions = 3;
1813
1814  for (int i = 0; i < kNumTransactions; i++) {
1815    context_list.push_back(new Context());
1816    Context* c = context_list[i];
1817
1818    c->result = cache.http_cache()->CreateTransaction(
1819        net::DEFAULT_PRIORITY, &c->trans, NULL);
1820    EXPECT_EQ(net::OK, c->result);
1821  }
1822
1823  context_list[0]->result = context_list[0]->trans->Start(
1824      &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1825  context_list[1]->result = context_list[1]->trans->Start(
1826      &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1827  context_list[2]->result = context_list[2]->trans->Start(
1828      &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1829
1830  // Just to make sure that everything is still pending.
1831  base::MessageLoop::current()->RunUntilIdle();
1832
1833  // The first request should be creating the disk cache.
1834  EXPECT_FALSE(context_list[0]->callback.have_result());
1835
1836  factory->FinishCreation();
1837
1838  base::MessageLoop::current()->RunUntilIdle();
1839  EXPECT_EQ(3, cache.network_layer()->transaction_count());
1840  EXPECT_EQ(3, cache.disk_cache()->create_count());
1841
1842  for (int i = 0; i < kNumTransactions; ++i) {
1843    EXPECT_TRUE(context_list[i]->callback.have_result());
1844    delete context_list[i];
1845  }
1846}
1847
1848// Tests that we can cancel requests that are queued waiting for the backend
1849// to be initialized.
1850TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1851  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1852  MockHttpCache cache(factory);
1853
1854  MockHttpRequest request0(kSimpleGET_Transaction);
1855  MockHttpRequest request1(kTypicalGET_Transaction);
1856  MockHttpRequest request2(kETagGET_Transaction);
1857
1858  std::vector<Context*> context_list;
1859  const int kNumTransactions = 3;
1860
1861  for (int i = 0; i < kNumTransactions; i++) {
1862    context_list.push_back(new Context());
1863    Context* c = context_list[i];
1864
1865    c->result = cache.http_cache()->CreateTransaction(
1866        net::DEFAULT_PRIORITY, &c->trans, NULL);
1867    EXPECT_EQ(net::OK, c->result);
1868  }
1869
1870  context_list[0]->result = context_list[0]->trans->Start(
1871      &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1872  context_list[1]->result = context_list[1]->trans->Start(
1873      &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1874  context_list[2]->result = context_list[2]->trans->Start(
1875      &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1876
1877  // Just to make sure that everything is still pending.
1878  base::MessageLoop::current()->RunUntilIdle();
1879
1880  // The first request should be creating the disk cache.
1881  EXPECT_FALSE(context_list[0]->callback.have_result());
1882
1883  // Cancel a request from the pending queue.
1884  delete context_list[1];
1885  context_list[1] = NULL;
1886
1887  // Cancel the request that is creating the entry.
1888  delete context_list[0];
1889  context_list[0] = NULL;
1890
1891  // Complete the last transaction.
1892  factory->FinishCreation();
1893
1894  context_list[2]->result =
1895      context_list[2]->callback.GetResult(context_list[2]->result);
1896  ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1897
1898  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1899  EXPECT_EQ(1, cache.disk_cache()->create_count());
1900
1901  delete context_list[2];
1902}
1903
1904// Tests that we can delete the cache while creating the backend.
1905TEST(HttpCache, DeleteCacheWaitingForBackend) {
1906  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1907  scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1908
1909  MockHttpRequest request(kSimpleGET_Transaction);
1910
1911  scoped_ptr<Context> c(new Context());
1912  c->result = cache->http_cache()->CreateTransaction(
1913      net::DEFAULT_PRIORITY, &c->trans, NULL);
1914  EXPECT_EQ(net::OK, c->result);
1915
1916  c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1917
1918  // Just to make sure that everything is still pending.
1919  base::MessageLoop::current()->RunUntilIdle();
1920
1921  // The request should be creating the disk cache.
1922  EXPECT_FALSE(c->callback.have_result());
1923
1924  // We cannot call FinishCreation because the factory itself will go away with
1925  // the cache, so grab the callback and attempt to use it.
1926  net::CompletionCallback callback = factory->callback();
1927  scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1928
1929  cache.reset();
1930  base::MessageLoop::current()->RunUntilIdle();
1931
1932  backend->reset();
1933  callback.Run(net::ERR_ABORTED);
1934}
1935
1936// Tests that we can delete the cache while creating the backend, from within
1937// one of the callbacks.
1938TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1939  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1940  MockHttpCache* cache = new MockHttpCache(factory);
1941
1942  DeleteCacheCompletionCallback cb(cache);
1943  disk_cache::Backend* backend;
1944  int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1945  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1946
1947  // Now let's queue a regular transaction
1948  MockHttpRequest request(kSimpleGET_Transaction);
1949
1950  scoped_ptr<Context> c(new Context());
1951  c->result = cache->http_cache()->CreateTransaction(
1952      net::DEFAULT_PRIORITY, &c->trans, NULL);
1953  EXPECT_EQ(net::OK, c->result);
1954
1955  c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1956
1957  // And another direct backend request.
1958  net::TestCompletionCallback cb2;
1959  rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1960  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1961
1962  // Just to make sure that everything is still pending.
1963  base::MessageLoop::current()->RunUntilIdle();
1964
1965  // The request should be queued.
1966  EXPECT_FALSE(c->callback.have_result());
1967
1968  // Generate the callback.
1969  factory->FinishCreation();
1970  rv = cb.WaitForResult();
1971
1972  // The cache should be gone by now.
1973  base::MessageLoop::current()->RunUntilIdle();
1974  EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1975  EXPECT_FALSE(cb2.have_result());
1976}
1977
1978TEST(HttpCache, TypicalGET_ConditionalRequest) {
1979  MockHttpCache cache;
1980
1981  // write to the cache
1982  RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1983
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());
1987
1988  // Get the same URL again, but this time we expect it to result
1989  // in a conditional request.
1990  net::CapturingBoundNetLog log;
1991  net::LoadTimingInfo load_timing_info;
1992  RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1993                                 log.bound(), &load_timing_info);
1994
1995  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1996  EXPECT_EQ(1, cache.disk_cache()->open_count());
1997  EXPECT_EQ(1, cache.disk_cache()->create_count());
1998  TestLoadTimingNetworkRequest(load_timing_info);
1999}
2000
2001static void ETagGet_ConditionalRequest_Handler(
2002    const net::HttpRequestInfo* request,
2003    std::string* response_status,
2004    std::string* response_headers,
2005    std::string* response_data) {
2006  EXPECT_TRUE(
2007      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2008  response_status->assign("HTTP/1.1 304 Not Modified");
2009  response_headers->assign(kETagGET_Transaction.response_headers);
2010  response_data->clear();
2011}
2012
2013TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2014  MockHttpCache cache;
2015
2016  ScopedMockTransaction transaction(kETagGET_Transaction);
2017
2018  // write to the cache
2019  RunTransactionTest(cache.http_cache(), transaction);
2020
2021  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2022  EXPECT_EQ(0, cache.disk_cache()->open_count());
2023  EXPECT_EQ(1, cache.disk_cache()->create_count());
2024
2025  // Get the same URL again, but this time we expect it to result
2026  // in a conditional request.
2027  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2028  transaction.handler = ETagGet_ConditionalRequest_Handler;
2029  net::CapturingBoundNetLog log;
2030  net::LoadTimingInfo load_timing_info;
2031  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2032                                 &load_timing_info);
2033
2034  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2035  EXPECT_EQ(1, cache.disk_cache()->open_count());
2036  EXPECT_EQ(1, cache.disk_cache()->create_count());
2037  TestLoadTimingNetworkRequest(load_timing_info);
2038}
2039
2040class RevalidationServer {
2041 public:
2042  RevalidationServer() {
2043    s_etag_used_ = false;
2044    s_last_modified_used_ = false;
2045  }
2046
2047  bool EtagUsed() { return s_etag_used_; }
2048  bool LastModifiedUsed() { return s_last_modified_used_; }
2049
2050  static void Handler(const net::HttpRequestInfo* request,
2051                      std::string* response_status,
2052                      std::string* response_headers,
2053                      std::string* response_data);
2054
2055 private:
2056  static bool s_etag_used_;
2057  static bool s_last_modified_used_;
2058};
2059bool RevalidationServer::s_etag_used_ = false;
2060bool RevalidationServer::s_last_modified_used_ = false;
2061
2062void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2063                                 std::string* response_status,
2064                                 std::string* response_headers,
2065                                 std::string* response_data) {
2066  if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2067      s_etag_used_ = true;
2068
2069  if (request->extra_headers.HasHeader(
2070          net::HttpRequestHeaders::kIfModifiedSince)) {
2071      s_last_modified_used_ = true;
2072  }
2073
2074  if (s_etag_used_ || s_last_modified_used_) {
2075    response_status->assign("HTTP/1.1 304 Not Modified");
2076    response_headers->assign(kTypicalGET_Transaction.response_headers);
2077    response_data->clear();
2078  } else {
2079    response_status->assign(kTypicalGET_Transaction.status);
2080    response_headers->assign(kTypicalGET_Transaction.response_headers);
2081    response_data->assign(kTypicalGET_Transaction.data);
2082  }
2083}
2084
2085// Tests revalidation after a vary match.
2086TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2087  MockHttpCache cache;
2088
2089  // Write to the cache.
2090  MockTransaction transaction(kTypicalGET_Transaction);
2091  transaction.request_headers = "Foo: bar\r\n";
2092  transaction.response_headers =
2093      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2094      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2095      "Etag: \"foopy\"\n"
2096      "Cache-Control: max-age=0\n"
2097      "Vary: Foo\n";
2098  AddMockTransaction(&transaction);
2099  RunTransactionTest(cache.http_cache(), transaction);
2100
2101  // Read from the cache.
2102  RevalidationServer server;
2103  transaction.handler = server.Handler;
2104  net::CapturingBoundNetLog log;
2105  net::LoadTimingInfo load_timing_info;
2106  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2107                                 &load_timing_info);
2108
2109  EXPECT_TRUE(server.EtagUsed());
2110  EXPECT_TRUE(server.LastModifiedUsed());
2111  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2112  EXPECT_EQ(1, cache.disk_cache()->open_count());
2113  EXPECT_EQ(1, cache.disk_cache()->create_count());
2114  TestLoadTimingNetworkRequest(load_timing_info);
2115  RemoveMockTransaction(&transaction);
2116}
2117
2118// Tests revalidation after a vary mismatch if etag is present.
2119TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2120  MockHttpCache cache;
2121
2122  // Write to the cache.
2123  MockTransaction transaction(kTypicalGET_Transaction);
2124  transaction.request_headers = "Foo: bar\r\n";
2125  transaction.response_headers =
2126      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2127      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2128      "Etag: \"foopy\"\n"
2129      "Cache-Control: max-age=0\n"
2130      "Vary: Foo\n";
2131  AddMockTransaction(&transaction);
2132  RunTransactionTest(cache.http_cache(), transaction);
2133
2134  // Read from the cache and revalidate the entry.
2135  RevalidationServer server;
2136  transaction.handler = server.Handler;
2137  transaction.request_headers = "Foo: none\r\n";
2138  net::CapturingBoundNetLog log;
2139  net::LoadTimingInfo load_timing_info;
2140  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2141                                 &load_timing_info);
2142
2143  EXPECT_TRUE(server.EtagUsed());
2144  EXPECT_FALSE(server.LastModifiedUsed());
2145  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2146  EXPECT_EQ(1, cache.disk_cache()->open_count());
2147  EXPECT_EQ(1, cache.disk_cache()->create_count());
2148  TestLoadTimingNetworkRequest(load_timing_info);
2149  RemoveMockTransaction(&transaction);
2150}
2151
2152// Tests lack of revalidation after a vary mismatch and no etag.
2153TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2154  MockHttpCache cache;
2155
2156  // Write to the cache.
2157  MockTransaction transaction(kTypicalGET_Transaction);
2158  transaction.request_headers = "Foo: bar\r\n";
2159  transaction.response_headers =
2160      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2161      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2162      "Cache-Control: max-age=0\n"
2163      "Vary: Foo\n";
2164  AddMockTransaction(&transaction);
2165  RunTransactionTest(cache.http_cache(), transaction);
2166
2167  // Read from the cache and don't revalidate the entry.
2168  RevalidationServer server;
2169  transaction.handler = server.Handler;
2170  transaction.request_headers = "Foo: none\r\n";
2171  net::CapturingBoundNetLog log;
2172  net::LoadTimingInfo load_timing_info;
2173  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2174                                 &load_timing_info);
2175
2176  EXPECT_FALSE(server.EtagUsed());
2177  EXPECT_FALSE(server.LastModifiedUsed());
2178  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2179  EXPECT_EQ(1, cache.disk_cache()->open_count());
2180  EXPECT_EQ(1, cache.disk_cache()->create_count());
2181  TestLoadTimingNetworkRequest(load_timing_info);
2182  RemoveMockTransaction(&transaction);
2183}
2184
2185static void ETagGet_UnconditionalRequest_Handler(
2186    const net::HttpRequestInfo* request,
2187    std::string* response_status,
2188    std::string* response_headers,
2189    std::string* response_data) {
2190  EXPECT_FALSE(
2191      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2192}
2193
2194TEST(HttpCache, ETagGET_Http10) {
2195  MockHttpCache cache;
2196
2197  ScopedMockTransaction transaction(kETagGET_Transaction);
2198  transaction.status = "HTTP/1.0 200 OK";
2199
2200  // Write to the cache.
2201  RunTransactionTest(cache.http_cache(), transaction);
2202
2203  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2204  EXPECT_EQ(0, cache.disk_cache()->open_count());
2205  EXPECT_EQ(1, cache.disk_cache()->create_count());
2206
2207  // Get the same URL again, without generating a conditional request.
2208  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2209  transaction.handler = ETagGet_UnconditionalRequest_Handler;
2210  RunTransactionTest(cache.http_cache(), transaction);
2211
2212  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2213  EXPECT_EQ(1, cache.disk_cache()->open_count());
2214  EXPECT_EQ(1, cache.disk_cache()->create_count());
2215}
2216
2217TEST(HttpCache, ETagGET_Http10_Range) {
2218  MockHttpCache cache;
2219
2220  ScopedMockTransaction transaction(kETagGET_Transaction);
2221  transaction.status = "HTTP/1.0 200 OK";
2222
2223  // Write to the cache.
2224  RunTransactionTest(cache.http_cache(), transaction);
2225
2226  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2227  EXPECT_EQ(0, cache.disk_cache()->open_count());
2228  EXPECT_EQ(1, cache.disk_cache()->create_count());
2229
2230  // Get the same URL again, but use a byte range request.
2231  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2232  transaction.handler = ETagGet_UnconditionalRequest_Handler;
2233  transaction.request_headers = "Range: bytes = 5-\r\n";
2234  RunTransactionTest(cache.http_cache(), transaction);
2235
2236  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2237  EXPECT_EQ(1, cache.disk_cache()->open_count());
2238  EXPECT_EQ(2, cache.disk_cache()->create_count());
2239}
2240
2241static void ETagGet_ConditionalRequest_NoStore_Handler(
2242    const net::HttpRequestInfo* request,
2243    std::string* response_status,
2244    std::string* response_headers,
2245    std::string* response_data) {
2246  EXPECT_TRUE(
2247      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2248  response_status->assign("HTTP/1.1 304 Not Modified");
2249  response_headers->assign("Cache-Control: no-store\n");
2250  response_data->clear();
2251}
2252
2253TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2254  MockHttpCache cache;
2255
2256  ScopedMockTransaction transaction(kETagGET_Transaction);
2257
2258  // Write to the cache.
2259  RunTransactionTest(cache.http_cache(), transaction);
2260
2261  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2262  EXPECT_EQ(0, cache.disk_cache()->open_count());
2263  EXPECT_EQ(1, cache.disk_cache()->create_count());
2264
2265  // Get the same URL again, but this time we expect it to result
2266  // in a conditional request.
2267  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2268  transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2269  RunTransactionTest(cache.http_cache(), transaction);
2270
2271  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2272  EXPECT_EQ(1, cache.disk_cache()->open_count());
2273  EXPECT_EQ(1, cache.disk_cache()->create_count());
2274
2275  ScopedMockTransaction transaction2(kETagGET_Transaction);
2276
2277  // Write to the cache again. This should create a new entry.
2278  RunTransactionTest(cache.http_cache(), transaction2);
2279
2280  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2281  EXPECT_EQ(1, cache.disk_cache()->open_count());
2282  EXPECT_EQ(2, cache.disk_cache()->create_count());
2283}
2284
2285// Helper that does 4 requests using HttpCache:
2286//
2287// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2288// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2289// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2290//     be returned.
2291// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2292//     returned.
2293static void ConditionalizedRequestUpdatesCacheHelper(
2294    const Response& net_response_1,
2295    const Response& net_response_2,
2296    const Response& cached_response_2,
2297    const char* extra_request_headers) {
2298  MockHttpCache cache;
2299
2300  // The URL we will be requesting.
2301  const char* kUrl = "http://foobar.com/main.css";
2302
2303  // Junk network response.
2304  static const Response kUnexpectedResponse = {
2305    "HTTP/1.1 500 Unexpected",
2306    "Server: unexpected_header",
2307    "unexpected body"
2308  };
2309
2310  // We will control the network layer's responses for |kUrl| using
2311  // |mock_network_response|.
2312  MockTransaction mock_network_response = { 0 };
2313  mock_network_response.url = kUrl;
2314  AddMockTransaction(&mock_network_response);
2315
2316  // Request |kUrl| for the first time. It should hit the network and
2317  // receive |kNetResponse1|, which it saves into the HTTP cache.
2318
2319  MockTransaction request = { 0 };
2320  request.url = kUrl;
2321  request.method = "GET";
2322  request.request_headers = "";
2323
2324  net_response_1.AssignTo(&mock_network_response);  // Network mock.
2325  net_response_1.AssignTo(&request);                // Expected result.
2326
2327  std::string response_headers;
2328  RunTransactionTestWithResponse(
2329      cache.http_cache(), request, &response_headers);
2330
2331  EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2332  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2333  EXPECT_EQ(0, cache.disk_cache()->open_count());
2334  EXPECT_EQ(1, cache.disk_cache()->create_count());
2335
2336  // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2337  // cache, so we don't hit the network.
2338
2339  request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2340
2341  kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2342  net_response_1.AssignTo(&request);                     // Expected result.
2343
2344  RunTransactionTestWithResponse(
2345      cache.http_cache(), request, &response_headers);
2346
2347  EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2348  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2349  EXPECT_EQ(1, cache.disk_cache()->open_count());
2350  EXPECT_EQ(1, cache.disk_cache()->create_count());
2351
2352  // Request |kUrl| yet again, but this time give the request an
2353  // "If-Modified-Since" header. This will cause the request to re-hit the
2354  // network. However now the network response is going to be
2355  // different -- this simulates a change made to the CSS file.
2356
2357  request.request_headers = extra_request_headers;
2358  request.load_flags = net::LOAD_NORMAL;
2359
2360  net_response_2.AssignTo(&mock_network_response);  // Network mock.
2361  net_response_2.AssignTo(&request);                // Expected result.
2362
2363  RunTransactionTestWithResponse(
2364      cache.http_cache(), request, &response_headers);
2365
2366  EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2367  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2368  EXPECT_EQ(1, cache.disk_cache()->open_count());
2369  EXPECT_EQ(1, cache.disk_cache()->create_count());
2370
2371  // Finally, request |kUrl| again. This request should be serviced from
2372  // the cache. Moreover, the value in the cache should be |kNetResponse2|
2373  // and NOT |kNetResponse1|. The previous step should have replaced the
2374  // value in the cache with the modified response.
2375
2376  request.request_headers = "";
2377  request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2378
2379  kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2380  cached_response_2.AssignTo(&request);                  // Expected result.
2381
2382  RunTransactionTestWithResponse(
2383      cache.http_cache(), request, &response_headers);
2384
2385  EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2386  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2387  EXPECT_EQ(2, cache.disk_cache()->open_count());
2388  EXPECT_EQ(1, cache.disk_cache()->create_count());
2389
2390  RemoveMockTransaction(&mock_network_response);
2391}
2392
2393// Check that when an "if-modified-since" header is attached
2394// to the request, the result still updates the cached entry.
2395TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2396  // First network response for |kUrl|.
2397  static const Response kNetResponse1 = {
2398    "HTTP/1.1 200 OK",
2399    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2400    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2401    "body1"
2402  };
2403
2404  // Second network response for |kUrl|.
2405  static const Response kNetResponse2 = {
2406    "HTTP/1.1 200 OK",
2407    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2408    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2409    "body2"
2410  };
2411
2412  const char* extra_headers =
2413      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2414
2415  ConditionalizedRequestUpdatesCacheHelper(
2416      kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2417}
2418
2419// Check that when an "if-none-match" header is attached
2420// to the request, the result updates the cached entry.
2421TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2422  // First network response for |kUrl|.
2423  static const Response kNetResponse1 = {
2424    "HTTP/1.1 200 OK",
2425    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2426    "Etag: \"ETAG1\"\n"
2427    "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2428    "body1"
2429  };
2430
2431  // Second network response for |kUrl|.
2432  static const Response kNetResponse2 = {
2433    "HTTP/1.1 200 OK",
2434    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2435    "Etag: \"ETAG2\"\n"
2436    "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2437    "body2"
2438  };
2439
2440  const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
2441
2442  ConditionalizedRequestUpdatesCacheHelper(
2443      kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2444}
2445
2446// Check that when an "if-modified-since" header is attached
2447// to a request, the 304 (not modified result) result updates the cached
2448// headers, and the 304 response is returned rather than the cached response.
2449TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2450  // First network response for |kUrl|.
2451  static const Response kNetResponse1 = {
2452    "HTTP/1.1 200 OK",
2453    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2454    "Server: server1\n"
2455    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2456    "body1"
2457  };
2458
2459  // Second network response for |kUrl|.
2460  static const Response kNetResponse2 = {
2461    "HTTP/1.1 304 Not Modified",
2462    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2463    "Server: server2\n"
2464    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2465    ""
2466  };
2467
2468  static const Response kCachedResponse2 = {
2469    "HTTP/1.1 200 OK",
2470    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2471    "Server: server2\n"
2472    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2473    "body1"
2474  };
2475
2476  const char* extra_headers =
2477      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2478
2479  ConditionalizedRequestUpdatesCacheHelper(
2480      kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2481}
2482
2483// Test that when doing an externally conditionalized if-modified-since
2484// and there is no corresponding cache entry, a new cache entry is NOT
2485// created (304 response).
2486TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2487  MockHttpCache cache;
2488
2489  const char* kUrl = "http://foobar.com/main.css";
2490
2491  static const Response kNetResponse = {
2492    "HTTP/1.1 304 Not Modified",
2493    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2494    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2495    ""
2496  };
2497
2498  const char* kExtraRequestHeaders =
2499      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2500
2501  // We will control the network layer's responses for |kUrl| using
2502  // |mock_network_response|.
2503  MockTransaction mock_network_response = { 0 };
2504  mock_network_response.url = kUrl;
2505  AddMockTransaction(&mock_network_response);
2506
2507  MockTransaction request = { 0 };
2508  request.url = kUrl;
2509  request.method = "GET";
2510  request.request_headers = kExtraRequestHeaders;
2511
2512  kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2513  kNetResponse.AssignTo(&request);                // Expected result.
2514
2515  std::string response_headers;
2516  RunTransactionTestWithResponse(
2517      cache.http_cache(), request, &response_headers);
2518
2519  EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2520  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2521  EXPECT_EQ(0, cache.disk_cache()->open_count());
2522  EXPECT_EQ(0, cache.disk_cache()->create_count());
2523
2524  RemoveMockTransaction(&mock_network_response);
2525}
2526
2527// Test that when doing an externally conditionalized if-modified-since
2528// and there is no corresponding cache entry, a new cache entry is NOT
2529// created (200 response).
2530TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2531  MockHttpCache cache;
2532
2533  const char* kUrl = "http://foobar.com/main.css";
2534
2535  static const Response kNetResponse = {
2536    "HTTP/1.1 200 OK",
2537    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2538    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2539    "foobar!!!"
2540  };
2541
2542  const char* kExtraRequestHeaders =
2543      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2544
2545  // We will control the network layer's responses for |kUrl| using
2546  // |mock_network_response|.
2547  MockTransaction mock_network_response = { 0 };
2548  mock_network_response.url = kUrl;
2549  AddMockTransaction(&mock_network_response);
2550
2551  MockTransaction request = { 0 };
2552  request.url = kUrl;
2553  request.method = "GET";
2554  request.request_headers = kExtraRequestHeaders;
2555
2556  kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2557  kNetResponse.AssignTo(&request);                // Expected result.
2558
2559  std::string response_headers;
2560  RunTransactionTestWithResponse(
2561      cache.http_cache(), request, &response_headers);
2562
2563  EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2564  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2565  EXPECT_EQ(0, cache.disk_cache()->open_count());
2566  EXPECT_EQ(0, cache.disk_cache()->create_count());
2567
2568  RemoveMockTransaction(&mock_network_response);
2569}
2570
2571// Test that when doing an externally conditionalized if-modified-since
2572// if the date does not match the cache entry's last-modified date,
2573// then we do NOT use the response (304) to update the cache.
2574// (the if-modified-since date is 2 days AFTER the cache's modification date).
2575TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2576  static const Response kNetResponse1 = {
2577    "HTTP/1.1 200 OK",
2578    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2579    "Server: server1\n"
2580    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2581    "body1"
2582  };
2583
2584  // Second network response for |kUrl|.
2585  static const Response kNetResponse2 = {
2586    "HTTP/1.1 304 Not Modified",
2587    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2588    "Server: server2\n"
2589    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2590    ""
2591  };
2592
2593  // This is two days in the future from the original response's last-modified
2594  // date!
2595  const char* kExtraRequestHeaders =
2596      "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2597
2598  ConditionalizedRequestUpdatesCacheHelper(
2599      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2600}
2601
2602// Test that when doing an externally conditionalized if-none-match
2603// if the etag does not match the cache entry's etag, then we do not use the
2604// response (304) to update the cache.
2605TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2606  static const Response kNetResponse1 = {
2607    "HTTP/1.1 200 OK",
2608    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2609    "Etag: \"Foo1\"\n"
2610    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2611    "body1"
2612  };
2613
2614  // Second network response for |kUrl|.
2615  static const Response kNetResponse2 = {
2616    "HTTP/1.1 304 Not Modified",
2617    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2618    "Etag: \"Foo2\"\n"
2619    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2620    ""
2621  };
2622
2623  // Different etag from original response.
2624  const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
2625
2626  ConditionalizedRequestUpdatesCacheHelper(
2627      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2628}
2629
2630// Test that doing an externally conditionalized request with both if-none-match
2631// and if-modified-since updates the cache.
2632TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2633  static const Response kNetResponse1 = {
2634    "HTTP/1.1 200 OK",
2635    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2636    "Etag: \"Foo1\"\n"
2637    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2638    "body1"
2639  };
2640
2641  // Second network response for |kUrl|.
2642  static const Response kNetResponse2 = {
2643    "HTTP/1.1 200 OK",
2644    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2645    "Etag: \"Foo2\"\n"
2646    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2647    "body2"
2648  };
2649
2650  const char* kExtraRequestHeaders =
2651      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2652      "If-None-Match: \"Foo1\"\r\n";
2653
2654  ConditionalizedRequestUpdatesCacheHelper(
2655      kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2656}
2657
2658// Test that doing an externally conditionalized request with both if-none-match
2659// and if-modified-since does not update the cache with only one match.
2660TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2661  static const Response kNetResponse1 = {
2662    "HTTP/1.1 200 OK",
2663    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2664    "Etag: \"Foo1\"\n"
2665    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2666    "body1"
2667  };
2668
2669  // Second network response for |kUrl|.
2670  static const Response kNetResponse2 = {
2671    "HTTP/1.1 200 OK",
2672    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2673    "Etag: \"Foo2\"\n"
2674    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2675    "body2"
2676  };
2677
2678  // The etag doesn't match what we have stored.
2679  const char* kExtraRequestHeaders =
2680      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2681      "If-None-Match: \"Foo2\"\r\n";
2682
2683  ConditionalizedRequestUpdatesCacheHelper(
2684      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2685}
2686
2687// Test that doing an externally conditionalized request with both if-none-match
2688// and if-modified-since does not update the cache with only one match.
2689TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2690  static const Response kNetResponse1 = {
2691    "HTTP/1.1 200 OK",
2692    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2693    "Etag: \"Foo1\"\n"
2694    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2695    "body1"
2696  };
2697
2698  // Second network response for |kUrl|.
2699  static const Response kNetResponse2 = {
2700    "HTTP/1.1 200 OK",
2701    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2702    "Etag: \"Foo2\"\n"
2703    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2704    "body2"
2705  };
2706
2707  // The modification date doesn't match what we have stored.
2708  const char* kExtraRequestHeaders =
2709      "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2710      "If-None-Match: \"Foo1\"\r\n";
2711
2712  ConditionalizedRequestUpdatesCacheHelper(
2713      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2714}
2715
2716TEST(HttpCache, UrlContainingHash) {
2717  MockHttpCache cache;
2718
2719  // Do a typical GET request -- should write an entry into our cache.
2720  MockTransaction trans(kTypicalGET_Transaction);
2721  RunTransactionTest(cache.http_cache(), trans);
2722
2723  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2724  EXPECT_EQ(0, cache.disk_cache()->open_count());
2725  EXPECT_EQ(1, cache.disk_cache()->create_count());
2726
2727  // Request the same URL, but this time with a reference section (hash).
2728  // Since the cache key strips the hash sections, this should be a cache hit.
2729  std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2730  trans.url = url_with_hash.c_str();
2731  trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2732
2733  RunTransactionTest(cache.http_cache(), trans);
2734
2735  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2736  EXPECT_EQ(1, cache.disk_cache()->open_count());
2737  EXPECT_EQ(1, cache.disk_cache()->create_count());
2738}
2739
2740// Tests that we skip the cache for POST requests that do not have an upload
2741// identifier.
2742TEST(HttpCache, SimplePOST_SkipsCache) {
2743  MockHttpCache cache;
2744
2745  RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2746
2747  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2748  EXPECT_EQ(0, cache.disk_cache()->open_count());
2749  EXPECT_EQ(0, cache.disk_cache()->create_count());
2750}
2751
2752TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2753  MockHttpCache cache;
2754
2755  MockTransaction transaction(kSimplePOST_Transaction);
2756  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2757
2758  MockHttpRequest request(transaction);
2759  net::TestCompletionCallback callback;
2760
2761  scoped_ptr<net::HttpTransaction> trans;
2762  int rv = cache.http_cache()->CreateTransaction(
2763      net::DEFAULT_PRIORITY, &trans, NULL);
2764  EXPECT_EQ(net::OK, rv);
2765  ASSERT_TRUE(trans.get());
2766
2767  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
2768  ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
2769
2770  trans.reset();
2771
2772  EXPECT_EQ(0, cache.network_layer()->transaction_count());
2773  EXPECT_EQ(0, cache.disk_cache()->open_count());
2774  EXPECT_EQ(0, cache.disk_cache()->create_count());
2775}
2776
2777TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2778  MockHttpCache cache;
2779
2780  // Test that we hit the cache for POST requests.
2781
2782  MockTransaction transaction(kSimplePOST_Transaction);
2783
2784  const int64 kUploadId = 1;  // Just a dummy value.
2785
2786  ScopedVector<net::UploadElementReader> element_readers;
2787  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2788  net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
2789  MockHttpRequest request(transaction);
2790  request.upload_data_stream = &upload_data_stream;
2791
2792  // Populate the cache.
2793  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2794
2795  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2796  EXPECT_EQ(0, cache.disk_cache()->open_count());
2797  EXPECT_EQ(1, cache.disk_cache()->create_count());
2798
2799  // Load from cache.
2800  request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2801  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2802
2803  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2804  EXPECT_EQ(1, cache.disk_cache()->open_count());
2805  EXPECT_EQ(1, cache.disk_cache()->create_count());
2806}
2807
2808// Test that we don't hit the cache for POST requests if there is a byte range.
2809TEST(HttpCache, SimplePOST_WithRanges) {
2810  MockHttpCache cache;
2811
2812  MockTransaction transaction(kSimplePOST_Transaction);
2813  transaction.request_headers = "Range: bytes = 0-4\r\n";
2814
2815  const int64 kUploadId = 1;  // Just a dummy value.
2816
2817  ScopedVector<net::UploadElementReader> element_readers;
2818  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2819  net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
2820
2821  MockHttpRequest request(transaction);
2822  request.upload_data_stream = &upload_data_stream;
2823
2824  // Attempt to populate the cache.
2825  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2826
2827  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2828  EXPECT_EQ(0, cache.disk_cache()->open_count());
2829  EXPECT_EQ(0, cache.disk_cache()->create_count());
2830}
2831
2832// Tests that a POST is cached separately from a previously cached GET.
2833TEST(HttpCache, SimplePOST_SeparateCache) {
2834  MockHttpCache cache;
2835
2836  ScopedVector<net::UploadElementReader> element_readers;
2837  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2838  net::UploadDataStream upload_data_stream(&element_readers, 1);
2839
2840  MockTransaction transaction(kSimplePOST_Transaction);
2841  MockHttpRequest req1(transaction);
2842  req1.upload_data_stream = &upload_data_stream;
2843
2844  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2845
2846  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2847  EXPECT_EQ(0, cache.disk_cache()->open_count());
2848  EXPECT_EQ(1, cache.disk_cache()->create_count());
2849
2850  transaction.method = "GET";
2851  MockHttpRequest req2(transaction);
2852
2853  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2854
2855  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2856  EXPECT_EQ(0, cache.disk_cache()->open_count());
2857  EXPECT_EQ(2, cache.disk_cache()->create_count());
2858}
2859
2860// Tests that a successful POST invalidates a previously cached GET.
2861TEST(HttpCache, SimplePOST_Invalidate_205) {
2862  MockHttpCache cache;
2863
2864  MockTransaction transaction(kSimpleGET_Transaction);
2865  AddMockTransaction(&transaction);
2866  MockHttpRequest req1(transaction);
2867
2868  // Attempt to populate the cache.
2869  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2870
2871  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2872  EXPECT_EQ(0, cache.disk_cache()->open_count());
2873  EXPECT_EQ(1, cache.disk_cache()->create_count());
2874
2875  ScopedVector<net::UploadElementReader> element_readers;
2876  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2877  net::UploadDataStream upload_data_stream(&element_readers, 1);
2878
2879  transaction.method = "POST";
2880  transaction.status = "HTTP/1.1 205 No Content";
2881  MockHttpRequest req2(transaction);
2882  req2.upload_data_stream = &upload_data_stream;
2883
2884  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2885
2886  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2887  EXPECT_EQ(0, cache.disk_cache()->open_count());
2888  EXPECT_EQ(2, cache.disk_cache()->create_count());
2889
2890  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2891
2892  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2893  EXPECT_EQ(0, cache.disk_cache()->open_count());
2894  EXPECT_EQ(3, cache.disk_cache()->create_count());
2895  RemoveMockTransaction(&transaction);
2896}
2897
2898// Tests that we don't invalidate entries as a result of a failed POST.
2899TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2900  MockHttpCache cache;
2901
2902  MockTransaction transaction(kSimpleGET_Transaction);
2903  AddMockTransaction(&transaction);
2904  MockHttpRequest req1(transaction);
2905
2906  // Attempt to populate the cache.
2907  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2908
2909  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2910  EXPECT_EQ(0, cache.disk_cache()->open_count());
2911  EXPECT_EQ(1, cache.disk_cache()->create_count());
2912
2913  ScopedVector<net::UploadElementReader> element_readers;
2914  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2915  net::UploadDataStream upload_data_stream(&element_readers, 1);
2916
2917  transaction.method = "POST";
2918  transaction.status = "HTTP/1.1 100 Continue";
2919  MockHttpRequest req2(transaction);
2920  req2.upload_data_stream = &upload_data_stream;
2921
2922  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2923
2924  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2925  EXPECT_EQ(0, cache.disk_cache()->open_count());
2926  EXPECT_EQ(2, cache.disk_cache()->create_count());
2927
2928  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2929
2930  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2931  EXPECT_EQ(1, cache.disk_cache()->open_count());
2932  EXPECT_EQ(2, cache.disk_cache()->create_count());
2933  RemoveMockTransaction(&transaction);
2934}
2935
2936// Tests that we do not cache the response of a PUT.
2937TEST(HttpCache, SimplePUT_Miss) {
2938  MockHttpCache cache;
2939
2940  MockTransaction transaction(kSimplePOST_Transaction);
2941  transaction.method = "PUT";
2942
2943  ScopedVector<net::UploadElementReader> element_readers;
2944  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2945  net::UploadDataStream upload_data_stream(&element_readers, 0);
2946
2947  MockHttpRequest request(transaction);
2948  request.upload_data_stream = &upload_data_stream;
2949
2950  // Attempt to populate the cache.
2951  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2952
2953  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2954  EXPECT_EQ(0, cache.disk_cache()->open_count());
2955  EXPECT_EQ(0, cache.disk_cache()->create_count());
2956}
2957
2958// Tests that we invalidate entries as a result of a PUT.
2959TEST(HttpCache, SimplePUT_Invalidate) {
2960  MockHttpCache cache;
2961
2962  MockTransaction transaction(kSimpleGET_Transaction);
2963  MockHttpRequest req1(transaction);
2964
2965  // Attempt to populate the cache.
2966  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2967
2968  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2969  EXPECT_EQ(0, cache.disk_cache()->open_count());
2970  EXPECT_EQ(1, cache.disk_cache()->create_count());
2971
2972  ScopedVector<net::UploadElementReader> element_readers;
2973  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2974  net::UploadDataStream upload_data_stream(&element_readers, 0);
2975
2976  transaction.method = "PUT";
2977  MockHttpRequest req2(transaction);
2978  req2.upload_data_stream = &upload_data_stream;
2979
2980  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2981
2982  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2983  EXPECT_EQ(1, cache.disk_cache()->open_count());
2984  EXPECT_EQ(1, cache.disk_cache()->create_count());
2985
2986  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2987
2988  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2989  EXPECT_EQ(1, cache.disk_cache()->open_count());
2990  EXPECT_EQ(2, cache.disk_cache()->create_count());
2991}
2992
2993// Tests that we invalidate entries as a result of a PUT.
2994TEST(HttpCache, SimplePUT_Invalidate_305) {
2995  MockHttpCache cache;
2996
2997  MockTransaction transaction(kSimpleGET_Transaction);
2998  AddMockTransaction(&transaction);
2999  MockHttpRequest req1(transaction);
3000
3001  // Attempt to populate the cache.
3002  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3003
3004  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3005  EXPECT_EQ(0, cache.disk_cache()->open_count());
3006  EXPECT_EQ(1, cache.disk_cache()->create_count());
3007
3008  ScopedVector<net::UploadElementReader> element_readers;
3009  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3010  net::UploadDataStream upload_data_stream(&element_readers, 0);
3011
3012  transaction.method = "PUT";
3013  transaction.status = "HTTP/1.1 305 Use Proxy";
3014  MockHttpRequest req2(transaction);
3015  req2.upload_data_stream = &upload_data_stream;
3016
3017  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3018
3019  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3020  EXPECT_EQ(1, cache.disk_cache()->open_count());
3021  EXPECT_EQ(1, cache.disk_cache()->create_count());
3022
3023  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3024
3025  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3026  EXPECT_EQ(1, cache.disk_cache()->open_count());
3027  EXPECT_EQ(2, cache.disk_cache()->create_count());
3028  RemoveMockTransaction(&transaction);
3029}
3030
3031// Tests that we don't invalidate entries as a result of a failed PUT.
3032TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3033  MockHttpCache cache;
3034
3035  MockTransaction transaction(kSimpleGET_Transaction);
3036  AddMockTransaction(&transaction);
3037  MockHttpRequest req1(transaction);
3038
3039  // Attempt to populate the cache.
3040  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3041
3042  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3043  EXPECT_EQ(0, cache.disk_cache()->open_count());
3044  EXPECT_EQ(1, cache.disk_cache()->create_count());
3045
3046  ScopedVector<net::UploadElementReader> element_readers;
3047  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3048  net::UploadDataStream upload_data_stream(&element_readers, 0);
3049
3050  transaction.method = "PUT";
3051  transaction.status = "HTTP/1.1 404 Not Found";
3052  MockHttpRequest req2(transaction);
3053  req2.upload_data_stream = &upload_data_stream;
3054
3055  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3056
3057  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3058  EXPECT_EQ(1, cache.disk_cache()->open_count());
3059  EXPECT_EQ(1, cache.disk_cache()->create_count());
3060
3061  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3062
3063  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3064  EXPECT_EQ(2, cache.disk_cache()->open_count());
3065  EXPECT_EQ(1, cache.disk_cache()->create_count());
3066  RemoveMockTransaction(&transaction);
3067}
3068
3069// Tests that we do not cache the response of a DELETE.
3070TEST(HttpCache, SimpleDELETE_Miss) {
3071  MockHttpCache cache;
3072
3073  MockTransaction transaction(kSimplePOST_Transaction);
3074  transaction.method = "DELETE";
3075
3076  ScopedVector<net::UploadElementReader> element_readers;
3077  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3078  net::UploadDataStream upload_data_stream(&element_readers, 0);
3079
3080  MockHttpRequest request(transaction);
3081  request.upload_data_stream = &upload_data_stream;
3082
3083  // Attempt to populate the cache.
3084  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3085
3086  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3087  EXPECT_EQ(0, cache.disk_cache()->open_count());
3088  EXPECT_EQ(0, cache.disk_cache()->create_count());
3089}
3090
3091// Tests that we invalidate entries as a result of a DELETE.
3092TEST(HttpCache, SimpleDELETE_Invalidate) {
3093  MockHttpCache cache;
3094
3095  MockTransaction transaction(kSimpleGET_Transaction);
3096  MockHttpRequest req1(transaction);
3097
3098  // Attempt to populate the cache.
3099  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3100
3101  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3102  EXPECT_EQ(0, cache.disk_cache()->open_count());
3103  EXPECT_EQ(1, cache.disk_cache()->create_count());
3104
3105  ScopedVector<net::UploadElementReader> element_readers;
3106  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3107  net::UploadDataStream upload_data_stream(&element_readers, 0);
3108
3109  transaction.method = "DELETE";
3110  MockHttpRequest req2(transaction);
3111  req2.upload_data_stream = &upload_data_stream;
3112
3113  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3114
3115  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3116  EXPECT_EQ(1, cache.disk_cache()->open_count());
3117  EXPECT_EQ(1, cache.disk_cache()->create_count());
3118
3119  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3120
3121  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3122  EXPECT_EQ(1, cache.disk_cache()->open_count());
3123  EXPECT_EQ(2, cache.disk_cache()->create_count());
3124}
3125
3126// Tests that we invalidate entries as a result of a DELETE.
3127TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3128  MockHttpCache cache;
3129
3130  MockTransaction transaction(kSimpleGET_Transaction);
3131  AddMockTransaction(&transaction);
3132
3133  // Attempt to populate the cache.
3134  RunTransactionTest(cache.http_cache(), transaction);
3135
3136  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3137  EXPECT_EQ(0, cache.disk_cache()->open_count());
3138  EXPECT_EQ(1, cache.disk_cache()->create_count());
3139
3140  transaction.method = "DELETE";
3141  transaction.status = "HTTP/1.1 301 Moved Permanently ";
3142
3143  RunTransactionTest(cache.http_cache(), transaction);
3144
3145  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3146  EXPECT_EQ(1, cache.disk_cache()->open_count());
3147  EXPECT_EQ(1, cache.disk_cache()->create_count());
3148
3149  transaction.method = "GET";
3150  RunTransactionTest(cache.http_cache(), transaction);
3151
3152  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3153  EXPECT_EQ(1, cache.disk_cache()->open_count());
3154  EXPECT_EQ(2, cache.disk_cache()->create_count());
3155  RemoveMockTransaction(&transaction);
3156}
3157
3158// Tests that we don't invalidate entries as a result of a failed DELETE.
3159TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3160  MockHttpCache cache;
3161
3162  MockTransaction transaction(kSimpleGET_Transaction);
3163  AddMockTransaction(&transaction);
3164
3165  // Attempt to populate the cache.
3166  RunTransactionTest(cache.http_cache(), transaction);
3167
3168  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3169  EXPECT_EQ(0, cache.disk_cache()->open_count());
3170  EXPECT_EQ(1, cache.disk_cache()->create_count());
3171
3172  transaction.method = "DELETE";
3173  transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3174
3175  RunTransactionTest(cache.http_cache(), transaction);
3176
3177  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3178  EXPECT_EQ(1, cache.disk_cache()->open_count());
3179  EXPECT_EQ(1, cache.disk_cache()->create_count());
3180
3181  transaction.method = "GET";
3182  transaction.status = "HTTP/1.1 200 OK";
3183  RunTransactionTest(cache.http_cache(), transaction);
3184
3185  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3186  EXPECT_EQ(2, cache.disk_cache()->open_count());
3187  EXPECT_EQ(1, cache.disk_cache()->create_count());
3188  RemoveMockTransaction(&transaction);
3189}
3190
3191// Tests that we don't invalidate entries after a failed network transaction.
3192TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3193  MockHttpCache cache;
3194
3195  // Populate the cache.
3196  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3197  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3198
3199  // Fail the network request.
3200  MockTransaction transaction(kSimpleGET_Transaction);
3201  transaction.return_code = net::ERR_FAILED;
3202  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3203
3204  AddMockTransaction(&transaction);
3205  RunTransactionTest(cache.http_cache(), transaction);
3206  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3207  RemoveMockTransaction(&transaction);
3208
3209  transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3210  transaction.return_code = net::OK;
3211  AddMockTransaction(&transaction);
3212  RunTransactionTest(cache.http_cache(), transaction);
3213
3214  // Make sure the transaction didn't reach the network.
3215  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3216  RemoveMockTransaction(&transaction);
3217}
3218
3219TEST(HttpCache, RangeGET_SkipsCache) {
3220  MockHttpCache cache;
3221
3222  // Test that we skip the cache for range GET requests.  Eventually, we will
3223  // want to cache these, but we'll still have cases where skipping the cache
3224  // makes sense, so we want to make sure that it works properly.
3225
3226  RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3227
3228  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3229  EXPECT_EQ(0, cache.disk_cache()->open_count());
3230  EXPECT_EQ(0, cache.disk_cache()->create_count());
3231
3232  MockTransaction transaction(kSimpleGET_Transaction);
3233  transaction.request_headers = "If-None-Match: foo\r\n";
3234  RunTransactionTest(cache.http_cache(), transaction);
3235
3236  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3237  EXPECT_EQ(0, cache.disk_cache()->open_count());
3238  EXPECT_EQ(0, cache.disk_cache()->create_count());
3239
3240  transaction.request_headers =
3241      "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3242  RunTransactionTest(cache.http_cache(), transaction);
3243
3244  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3245  EXPECT_EQ(0, cache.disk_cache()->open_count());
3246  EXPECT_EQ(0, cache.disk_cache()->create_count());
3247}
3248
3249// Test that we skip the cache for range requests that include a validation
3250// header.
3251TEST(HttpCache, RangeGET_SkipsCache2) {
3252  MockHttpCache cache;
3253
3254  MockTransaction transaction(kRangeGET_Transaction);
3255  transaction.request_headers = "If-None-Match: foo\r\n"
3256                                EXTRA_HEADER
3257                                "Range: bytes = 40-49\r\n";
3258  RunTransactionTest(cache.http_cache(), transaction);
3259
3260  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3261  EXPECT_EQ(0, cache.disk_cache()->open_count());
3262  EXPECT_EQ(0, cache.disk_cache()->create_count());
3263
3264  transaction.request_headers =
3265      "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3266      EXTRA_HEADER
3267      "Range: bytes = 40-49\r\n";
3268  RunTransactionTest(cache.http_cache(), transaction);
3269
3270  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3271  EXPECT_EQ(0, cache.disk_cache()->open_count());
3272  EXPECT_EQ(0, cache.disk_cache()->create_count());
3273
3274  transaction.request_headers = "If-Range: bla\r\n"
3275                                EXTRA_HEADER
3276                                "Range: bytes = 40-49\r\n";
3277  RunTransactionTest(cache.http_cache(), transaction);
3278
3279  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3280  EXPECT_EQ(0, cache.disk_cache()->open_count());
3281  EXPECT_EQ(0, cache.disk_cache()->create_count());
3282}
3283
3284// Tests that receiving 206 for a regular request is handled correctly.
3285TEST(HttpCache, GET_Crazy206) {
3286  MockHttpCache cache;
3287
3288  // Write to the cache.
3289  MockTransaction transaction(kRangeGET_TransactionOK);
3290  AddMockTransaction(&transaction);
3291  transaction.request_headers = EXTRA_HEADER;
3292  transaction.handler = NULL;
3293  RunTransactionTest(cache.http_cache(), transaction);
3294
3295  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3296  EXPECT_EQ(0, cache.disk_cache()->open_count());
3297  EXPECT_EQ(1, cache.disk_cache()->create_count());
3298
3299  // This should read again from the net.
3300  RunTransactionTest(cache.http_cache(), transaction);
3301
3302  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3303  EXPECT_EQ(0, cache.disk_cache()->open_count());
3304  EXPECT_EQ(2, cache.disk_cache()->create_count());
3305  RemoveMockTransaction(&transaction);
3306}
3307
3308// Tests that we don't cache partial responses that can't be validated.
3309TEST(HttpCache, RangeGET_NoStrongValidators) {
3310  MockHttpCache cache;
3311  std::string headers;
3312
3313  // Attempt to write to the cache (40-49).
3314  MockTransaction transaction(kRangeGET_TransactionOK);
3315  AddMockTransaction(&transaction);
3316  transaction.response_headers = "Content-Length: 10\n"
3317                                 "ETag: w/\"foo\"\n";
3318  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3319
3320  Verify206Response(headers, 40, 49);
3321  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3322  EXPECT_EQ(0, cache.disk_cache()->open_count());
3323  EXPECT_EQ(1, cache.disk_cache()->create_count());
3324
3325  // Now verify that there's no cached data.
3326  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3327                                 &headers);
3328
3329  Verify206Response(headers, 40, 49);
3330  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3331  EXPECT_EQ(0, cache.disk_cache()->open_count());
3332  EXPECT_EQ(2, cache.disk_cache()->create_count());
3333
3334  RemoveMockTransaction(&transaction);
3335}
3336
3337// Tests that we can cache range requests and fetch random blocks from the
3338// cache and the network.
3339TEST(HttpCache, RangeGET_OK) {
3340  MockHttpCache cache;
3341  AddMockTransaction(&kRangeGET_TransactionOK);
3342  std::string headers;
3343
3344  // Write to the cache (40-49).
3345  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3346                                 &headers);
3347
3348  Verify206Response(headers, 40, 49);
3349  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3350  EXPECT_EQ(0, cache.disk_cache()->open_count());
3351  EXPECT_EQ(1, cache.disk_cache()->create_count());
3352
3353  // Read from the cache (40-49).
3354  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3355                                 &headers);
3356
3357  Verify206Response(headers, 40, 49);
3358  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3359  EXPECT_EQ(1, cache.disk_cache()->open_count());
3360  EXPECT_EQ(1, cache.disk_cache()->create_count());
3361
3362  // Make sure we are done with the previous transaction.
3363  base::MessageLoop::current()->RunUntilIdle();
3364
3365  // Write to the cache (30-39).
3366  MockTransaction transaction(kRangeGET_TransactionOK);
3367  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3368  transaction.data = "rg: 30-39 ";
3369  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3370
3371  Verify206Response(headers, 30, 39);
3372  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3373  EXPECT_EQ(2, cache.disk_cache()->open_count());
3374  EXPECT_EQ(1, cache.disk_cache()->create_count());
3375
3376  // Make sure we are done with the previous transaction.
3377  base::MessageLoop::current()->RunUntilIdle();
3378
3379  // Write and read from the cache (20-59).
3380  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3381  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3382  net::CapturingBoundNetLog log;
3383  net::LoadTimingInfo load_timing_info;
3384  RunTransactionTestWithResponseAndGetTiming(
3385      cache.http_cache(), transaction, &headers, log.bound(),
3386      &load_timing_info);
3387
3388  Verify206Response(headers, 20, 59);
3389  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3390  EXPECT_EQ(3, cache.disk_cache()->open_count());
3391  EXPECT_EQ(1, cache.disk_cache()->create_count());
3392  TestLoadTimingNetworkRequest(load_timing_info);
3393
3394  RemoveMockTransaction(&kRangeGET_TransactionOK);
3395}
3396
3397#if defined(OS_ANDROID)
3398
3399// Checks that with a cache backend having Sparse IO unimplementes the cache
3400// entry would be doomed after a range request.
3401// TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3402TEST(HttpCache, RangeGET_SparseNotImplemented) {
3403  MockHttpCache cache;
3404  cache.disk_cache()->set_fail_sparse_requests();
3405
3406  // Run a cacheable request to prime the cache.
3407  MockTransaction transaction(kTypicalGET_Transaction);
3408  transaction.url = kRangeGET_TransactionOK.url;
3409  AddMockTransaction(&transaction);
3410  RunTransactionTest(cache.http_cache(), transaction);
3411  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3412  EXPECT_EQ(0, cache.disk_cache()->open_count());
3413  EXPECT_EQ(1, cache.disk_cache()->create_count());
3414
3415  // Verify that we added the entry.
3416  disk_cache::Entry* entry;
3417  net::TestCompletionCallback cb;
3418  int rv = cache.disk_cache()->OpenEntry(transaction.url,
3419                                         &entry,
3420                                         cb.callback());
3421  ASSERT_EQ(net::OK, cb.GetResult(rv));
3422  EXPECT_EQ(1, cache.disk_cache()->open_count());
3423  entry->Close();
3424  RemoveMockTransaction(&transaction);
3425
3426  // Request the range with the backend that does not support it.
3427  MockTransaction transaction2(kRangeGET_TransactionOK);
3428  std::string headers;
3429  AddMockTransaction(&transaction2);
3430  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3431  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3432  EXPECT_EQ(2, cache.disk_cache()->open_count());
3433  EXPECT_EQ(2, cache.disk_cache()->create_count());
3434
3435  // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3436  // if it was re-created later, so this effectively checks that the old data is
3437  // gone.
3438  disk_cache::Entry* entry2;
3439  rv = cache.disk_cache()->OpenEntry(transaction2.url,
3440                                     &entry2,
3441                                     cb.callback());
3442  ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3443  RemoveMockTransaction(&transaction2);
3444}
3445
3446TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3447  MockHttpCache cache;
3448  cache.disk_cache()->set_fail_sparse_requests();
3449
3450  // Request the range with the backend that does not support it.
3451  MockTransaction transaction(kRangeGET_TransactionOK);
3452  std::string headers;
3453  AddMockTransaction(&transaction);
3454  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3455  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3456  EXPECT_EQ(0, cache.disk_cache()->open_count());
3457  EXPECT_EQ(1, cache.disk_cache()->create_count());
3458
3459  // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3460  // if it was re-created later, so this effectively checks that the old data is
3461  // gone as a result of a failed range write.
3462  disk_cache::Entry* entry;
3463  net::TestCompletionCallback cb;
3464  int rv = cache.disk_cache()->OpenEntry(transaction.url,
3465                                         &entry,
3466                                         cb.callback());
3467  ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3468  RemoveMockTransaction(&transaction);
3469}
3470
3471#endif  // OS_ANDROID
3472
3473// Tests that we can cache range requests and fetch random blocks from the
3474// cache and the network, with synchronous responses.
3475TEST(HttpCache, RangeGET_SyncOK) {
3476  MockHttpCache cache;
3477
3478  MockTransaction transaction(kRangeGET_TransactionOK);
3479  transaction.test_mode = TEST_MODE_SYNC_ALL;
3480  AddMockTransaction(&transaction);
3481
3482  // Write to the cache (40-49).
3483  std::string headers;
3484  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3485
3486  Verify206Response(headers, 40, 49);
3487  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3488  EXPECT_EQ(0, cache.disk_cache()->open_count());
3489  EXPECT_EQ(1, cache.disk_cache()->create_count());
3490
3491  // Read from the cache (40-49).
3492  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3493
3494  Verify206Response(headers, 40, 49);
3495  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3496  EXPECT_EQ(0, cache.disk_cache()->open_count());
3497  EXPECT_EQ(1, cache.disk_cache()->create_count());
3498
3499  // Make sure we are done with the previous transaction.
3500  base::MessageLoop::current()->RunUntilIdle();
3501
3502  // Write to the cache (30-39).
3503  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3504  transaction.data = "rg: 30-39 ";
3505  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3506
3507  Verify206Response(headers, 30, 39);
3508  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3509  EXPECT_EQ(1, cache.disk_cache()->open_count());
3510  EXPECT_EQ(1, cache.disk_cache()->create_count());
3511
3512  // Make sure we are done with the previous transaction.
3513  base::MessageLoop::current()->RunUntilIdle();
3514
3515  // Write and read from the cache (20-59).
3516  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3517  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3518  net::CapturingBoundNetLog log;
3519  net::LoadTimingInfo load_timing_info;
3520  RunTransactionTestWithResponseAndGetTiming(
3521      cache.http_cache(), transaction, &headers, log.bound(),
3522      &load_timing_info);
3523
3524  Verify206Response(headers, 20, 59);
3525  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3526  EXPECT_EQ(2, cache.disk_cache()->open_count());
3527  EXPECT_EQ(1, cache.disk_cache()->create_count());
3528  TestLoadTimingNetworkRequest(load_timing_info);
3529
3530  RemoveMockTransaction(&transaction);
3531}
3532
3533// Tests that we don't revalidate an entry unless we are required to do so.
3534TEST(HttpCache, RangeGET_Revalidate1) {
3535  MockHttpCache cache;
3536  std::string headers;
3537
3538  // Write to the cache (40-49).
3539  MockTransaction transaction(kRangeGET_TransactionOK);
3540  transaction.response_headers =
3541      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3542      "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
3543      "ETag: \"foo\"\n"
3544      "Accept-Ranges: bytes\n"
3545      "Content-Length: 10\n";
3546  AddMockTransaction(&transaction);
3547  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3548
3549  Verify206Response(headers, 40, 49);
3550  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3551  EXPECT_EQ(0, cache.disk_cache()->open_count());
3552  EXPECT_EQ(1, cache.disk_cache()->create_count());
3553
3554  // Read from the cache (40-49).
3555  net::CapturingBoundNetLog log;
3556  net::LoadTimingInfo load_timing_info;
3557  RunTransactionTestWithResponseAndGetTiming(
3558      cache.http_cache(), transaction, &headers, log.bound(),
3559      &load_timing_info);
3560
3561  Verify206Response(headers, 40, 49);
3562  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3563  EXPECT_EQ(1, cache.disk_cache()->open_count());
3564  EXPECT_EQ(1, cache.disk_cache()->create_count());
3565  TestLoadTimingCachedResponse(load_timing_info);
3566
3567  // Read again forcing the revalidation.
3568  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3569  RunTransactionTestWithResponseAndGetTiming(
3570      cache.http_cache(), transaction, &headers, log.bound(),
3571      &load_timing_info);
3572
3573  Verify206Response(headers, 40, 49);
3574  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3575  EXPECT_EQ(1, cache.disk_cache()->open_count());
3576  EXPECT_EQ(1, cache.disk_cache()->create_count());
3577  TestLoadTimingNetworkRequest(load_timing_info);
3578
3579  RemoveMockTransaction(&transaction);
3580}
3581
3582// Checks that we revalidate an entry when the headers say so.
3583TEST(HttpCache, RangeGET_Revalidate2) {
3584  MockHttpCache cache;
3585  std::string headers;
3586
3587  // Write to the cache (40-49).
3588  MockTransaction transaction(kRangeGET_TransactionOK);
3589  transaction.response_headers =
3590      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3591      "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
3592      "ETag: \"foo\"\n"
3593      "Accept-Ranges: bytes\n"
3594      "Content-Length: 10\n";
3595  AddMockTransaction(&transaction);
3596  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3597
3598  Verify206Response(headers, 40, 49);
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());
3602
3603  // Read from the cache (40-49).
3604  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3605  Verify206Response(headers, 40, 49);
3606
3607  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3608  EXPECT_EQ(1, cache.disk_cache()->open_count());
3609  EXPECT_EQ(1, cache.disk_cache()->create_count());
3610
3611  RemoveMockTransaction(&transaction);
3612}
3613
3614// Tests that we deal with 304s for range requests.
3615TEST(HttpCache, RangeGET_304) {
3616  MockHttpCache cache;
3617  AddMockTransaction(&kRangeGET_TransactionOK);
3618  std::string headers;
3619
3620  // Write to the cache (40-49).
3621  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3622                                 &headers);
3623
3624  Verify206Response(headers, 40, 49);
3625  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3626  EXPECT_EQ(0, cache.disk_cache()->open_count());
3627  EXPECT_EQ(1, cache.disk_cache()->create_count());
3628
3629  // Read from the cache (40-49).
3630  RangeTransactionServer handler;
3631  handler.set_not_modified(true);
3632  MockTransaction transaction(kRangeGET_TransactionOK);
3633  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3634  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3635
3636  Verify206Response(headers, 40, 49);
3637  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3638  EXPECT_EQ(1, cache.disk_cache()->open_count());
3639  EXPECT_EQ(1, cache.disk_cache()->create_count());
3640
3641  RemoveMockTransaction(&kRangeGET_TransactionOK);
3642}
3643
3644// Tests that we deal with 206s when revalidating range requests.
3645TEST(HttpCache, RangeGET_ModifiedResult) {
3646  MockHttpCache cache;
3647  AddMockTransaction(&kRangeGET_TransactionOK);
3648  std::string headers;
3649
3650  // Write to the cache (40-49).
3651  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3652                                 &headers);
3653
3654  Verify206Response(headers, 40, 49);
3655  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3656  EXPECT_EQ(0, cache.disk_cache()->open_count());
3657  EXPECT_EQ(1, cache.disk_cache()->create_count());
3658
3659  // Attempt to read from the cache (40-49).
3660  RangeTransactionServer handler;
3661  handler.set_modified(true);
3662  MockTransaction transaction(kRangeGET_TransactionOK);
3663  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3664  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3665
3666  Verify206Response(headers, 40, 49);
3667  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3668  EXPECT_EQ(1, cache.disk_cache()->open_count());
3669  EXPECT_EQ(1, cache.disk_cache()->create_count());
3670
3671  // And the entry should be gone.
3672  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3673  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3674  EXPECT_EQ(1, cache.disk_cache()->open_count());
3675  EXPECT_EQ(2, cache.disk_cache()->create_count());
3676
3677  RemoveMockTransaction(&kRangeGET_TransactionOK);
3678}
3679
3680// Tests that we cache 301s for range requests.
3681TEST(HttpCache, RangeGET_301) {
3682  MockHttpCache cache;
3683  ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3684  transaction.status = "HTTP/1.1 301 Moved Permanently";
3685  transaction.response_headers = "Location: http://www.bar.com/\n";
3686  transaction.data = "";
3687  transaction.handler = NULL;
3688  AddMockTransaction(&transaction);
3689
3690  // Write to the cache.
3691  RunTransactionTest(cache.http_cache(), transaction);
3692  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3693  EXPECT_EQ(0, cache.disk_cache()->open_count());
3694  EXPECT_EQ(1, cache.disk_cache()->create_count());
3695
3696  // Read from the cache.
3697  RunTransactionTest(cache.http_cache(), transaction);
3698  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3699  EXPECT_EQ(1, cache.disk_cache()->open_count());
3700  EXPECT_EQ(1, cache.disk_cache()->create_count());
3701
3702  RemoveMockTransaction(&transaction);
3703}
3704
3705// Tests that we can cache range requests when the start or end is unknown.
3706// We start with one suffix request, followed by a request from a given point.
3707TEST(HttpCache, UnknownRangeGET_1) {
3708  MockHttpCache cache;
3709  AddMockTransaction(&kRangeGET_TransactionOK);
3710  std::string headers;
3711
3712  // Write to the cache (70-79).
3713  MockTransaction transaction(kRangeGET_TransactionOK);
3714  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3715  transaction.data = "rg: 70-79 ";
3716  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3717
3718  Verify206Response(headers, 70, 79);
3719  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3720  EXPECT_EQ(0, cache.disk_cache()->open_count());
3721  EXPECT_EQ(1, cache.disk_cache()->create_count());
3722
3723  // Make sure we are done with the previous transaction.
3724  base::MessageLoop::current()->RunUntilIdle();
3725
3726  // Write and read from the cache (60-79).
3727  transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
3728  transaction.data = "rg: 60-69 rg: 70-79 ";
3729  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3730
3731  Verify206Response(headers, 60, 79);
3732  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3733  EXPECT_EQ(1, cache.disk_cache()->open_count());
3734  EXPECT_EQ(1, cache.disk_cache()->create_count());
3735
3736  RemoveMockTransaction(&kRangeGET_TransactionOK);
3737}
3738
3739// Tests that we can cache range requests when the start or end is unknown.
3740// We start with one request from a given point, followed by a suffix request.
3741// We'll also verify that synchronous cache responses work as intended.
3742TEST(HttpCache, UnknownRangeGET_2) {
3743  MockHttpCache cache;
3744  std::string headers;
3745
3746  MockTransaction transaction(kRangeGET_TransactionOK);
3747  transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
3748                          TEST_MODE_SYNC_CACHE_READ |
3749                          TEST_MODE_SYNC_CACHE_WRITE;
3750  AddMockTransaction(&transaction);
3751
3752  // Write to the cache (70-79).
3753  transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3754  transaction.data = "rg: 70-79 ";
3755  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3756
3757  Verify206Response(headers, 70, 79);
3758  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3759  EXPECT_EQ(0, cache.disk_cache()->open_count());
3760  EXPECT_EQ(1, cache.disk_cache()->create_count());
3761
3762  // Make sure we are done with the previous transaction.
3763  base::MessageLoop::current()->RunUntilIdle();
3764
3765  // Write and read from the cache (60-79).
3766  transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
3767  transaction.data = "rg: 60-69 rg: 70-79 ";
3768  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3769
3770  Verify206Response(headers, 60, 79);
3771  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3772  EXPECT_EQ(1, cache.disk_cache()->open_count());
3773  EXPECT_EQ(1, cache.disk_cache()->create_count());
3774
3775  RemoveMockTransaction(&transaction);
3776}
3777
3778// Tests that receiving Not Modified when asking for an open range doesn't mess
3779// up things.
3780TEST(HttpCache, UnknownRangeGET_304) {
3781  MockHttpCache cache;
3782  std::string headers;
3783
3784  MockTransaction transaction(kRangeGET_TransactionOK);
3785  AddMockTransaction(&transaction);
3786
3787  RangeTransactionServer handler;
3788  handler.set_not_modified(true);
3789
3790  // Ask for the end of the file, without knowing the length.
3791  transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3792  transaction.data = "";
3793  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3794
3795  // We just bypass the cache.
3796  EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3797  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3798  EXPECT_EQ(0, cache.disk_cache()->open_count());
3799  EXPECT_EQ(1, cache.disk_cache()->create_count());
3800
3801  RunTransactionTest(cache.http_cache(), transaction);
3802  EXPECT_EQ(2, cache.disk_cache()->create_count());
3803
3804  RemoveMockTransaction(&transaction);
3805}
3806
3807// Tests that we can handle non-range requests when we have cached a range.
3808TEST(HttpCache, GET_Previous206) {
3809  MockHttpCache cache;
3810  AddMockTransaction(&kRangeGET_TransactionOK);
3811  std::string headers;
3812  net::CapturingBoundNetLog log;
3813  net::LoadTimingInfo load_timing_info;
3814
3815  // Write to the cache (40-49).
3816  RunTransactionTestWithResponseAndGetTiming(
3817      cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
3818      &load_timing_info);
3819
3820  Verify206Response(headers, 40, 49);
3821  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3822  EXPECT_EQ(0, cache.disk_cache()->open_count());
3823  EXPECT_EQ(1, cache.disk_cache()->create_count());
3824  TestLoadTimingNetworkRequest(load_timing_info);
3825
3826  // Write and read from the cache (0-79), when not asked for a range.
3827  MockTransaction transaction(kRangeGET_TransactionOK);
3828  transaction.request_headers = EXTRA_HEADER;
3829  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3830                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
3831  RunTransactionTestWithResponseAndGetTiming(
3832      cache.http_cache(), transaction, &headers, log.bound(),
3833      &load_timing_info);
3834
3835  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3836  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3837  EXPECT_EQ(1, cache.disk_cache()->open_count());
3838  EXPECT_EQ(1, cache.disk_cache()->create_count());
3839  TestLoadTimingNetworkRequest(load_timing_info);
3840
3841  RemoveMockTransaction(&kRangeGET_TransactionOK);
3842}
3843
3844// Tests that we can handle non-range requests when we have cached the first
3845// part of the object and the server replies with 304 (Not Modified).
3846TEST(HttpCache, GET_Previous206_NotModified) {
3847  MockHttpCache cache;
3848
3849  MockTransaction transaction(kRangeGET_TransactionOK);
3850  AddMockTransaction(&transaction);
3851  std::string headers;
3852  net::CapturingBoundNetLog log;
3853  net::LoadTimingInfo load_timing_info;
3854
3855  // Write to the cache (0-9).
3856  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3857  transaction.data = "rg: 00-09 ";
3858  RunTransactionTestWithResponseAndGetTiming(
3859      cache.http_cache(), transaction, &headers, log.bound(),
3860      &load_timing_info);
3861  Verify206Response(headers, 0, 9);
3862  TestLoadTimingNetworkRequest(load_timing_info);
3863
3864  // Write to the cache (70-79).
3865  transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3866  transaction.data = "rg: 70-79 ";
3867  RunTransactionTestWithResponseAndGetTiming(
3868      cache.http_cache(), transaction, &headers, log.bound(),
3869      &load_timing_info);
3870  Verify206Response(headers, 70, 79);
3871
3872  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3873  EXPECT_EQ(1, cache.disk_cache()->open_count());
3874  EXPECT_EQ(1, cache.disk_cache()->create_count());
3875  TestLoadTimingNetworkRequest(load_timing_info);
3876
3877  // Read from the cache (0-9), write and read from cache (10 - 79).
3878  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3879  transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3880  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3881                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
3882  RunTransactionTestWithResponseAndGetTiming(
3883      cache.http_cache(), transaction, &headers, log.bound(),
3884      &load_timing_info);
3885
3886  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3887  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3888  EXPECT_EQ(2, cache.disk_cache()->open_count());
3889  EXPECT_EQ(1, cache.disk_cache()->create_count());
3890  TestLoadTimingNetworkRequest(load_timing_info);
3891
3892  RemoveMockTransaction(&transaction);
3893}
3894
3895// Tests that we can handle a regular request to a sparse entry, that results in
3896// new content provided by the server (206).
3897TEST(HttpCache, GET_Previous206_NewContent) {
3898  MockHttpCache cache;
3899  AddMockTransaction(&kRangeGET_TransactionOK);
3900  std::string headers;
3901
3902  // Write to the cache (0-9).
3903  MockTransaction transaction(kRangeGET_TransactionOK);
3904  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3905  transaction.data = "rg: 00-09 ";
3906  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3907
3908  Verify206Response(headers, 0, 9);
3909  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3910  EXPECT_EQ(0, cache.disk_cache()->open_count());
3911  EXPECT_EQ(1, cache.disk_cache()->create_count());
3912
3913  // Now we'll issue a request without any range that should result first in a
3914  // 206 (when revalidating), and then in a weird standard answer: the test
3915  // server will not modify the response so we'll get the default range... a
3916  // real server will answer with 200.
3917  MockTransaction transaction2(kRangeGET_TransactionOK);
3918  transaction2.request_headers = EXTRA_HEADER;
3919  transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
3920  transaction2.data = "Not a range";
3921  RangeTransactionServer handler;
3922  handler.set_modified(true);
3923  net::CapturingBoundNetLog log;
3924  net::LoadTimingInfo load_timing_info;
3925  RunTransactionTestWithResponseAndGetTiming(
3926      cache.http_cache(), transaction2, &headers, log.bound(),
3927      &load_timing_info);
3928
3929  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3930  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3931  EXPECT_EQ(1, cache.disk_cache()->open_count());
3932  EXPECT_EQ(1, cache.disk_cache()->create_count());
3933  TestLoadTimingNetworkRequest(load_timing_info);
3934
3935  // Verify that the previous request deleted the entry.
3936  RunTransactionTest(cache.http_cache(), transaction);
3937  EXPECT_EQ(2, cache.disk_cache()->create_count());
3938
3939  RemoveMockTransaction(&transaction);
3940}
3941
3942// Tests that we can handle cached 206 responses that are not sparse.
3943TEST(HttpCache, GET_Previous206_NotSparse) {
3944  MockHttpCache cache;
3945
3946  // Create a disk cache entry that stores 206 headers while not being sparse.
3947  disk_cache::Entry* entry;
3948  ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3949                                       NULL));
3950
3951  std::string raw_headers(kRangeGET_TransactionOK.status);
3952  raw_headers.append("\n");
3953  raw_headers.append(kRangeGET_TransactionOK.response_headers);
3954  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3955                                                  raw_headers.size());
3956
3957  net::HttpResponseInfo response;
3958  response.headers = new net::HttpResponseHeaders(raw_headers);
3959  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3960
3961  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3962  int len = static_cast<int>(base::strlcpy(buf->data(),
3963                                           kRangeGET_TransactionOK.data, 500));
3964  net::TestCompletionCallback cb;
3965  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
3966  EXPECT_EQ(len, cb.GetResult(rv));
3967  entry->Close();
3968
3969  // Now see that we don't use the stored entry.
3970  std::string headers;
3971  net::CapturingBoundNetLog log;
3972  net::LoadTimingInfo load_timing_info;
3973  RunTransactionTestWithResponseAndGetTiming(
3974      cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
3975      &load_timing_info);
3976
3977  // We are expecting a 200.
3978  std::string expected_headers(kSimpleGET_Transaction.status);
3979  expected_headers.append("\n");
3980  expected_headers.append(kSimpleGET_Transaction.response_headers);
3981  EXPECT_EQ(expected_headers, headers);
3982  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3983  EXPECT_EQ(1, cache.disk_cache()->open_count());
3984  EXPECT_EQ(2, cache.disk_cache()->create_count());
3985  TestLoadTimingNetworkRequest(load_timing_info);
3986}
3987
3988// Tests that we can handle cached 206 responses that are not sparse. This time
3989// we issue a range request and expect to receive a range.
3990TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
3991  MockHttpCache cache;
3992  AddMockTransaction(&kRangeGET_TransactionOK);
3993
3994  // Create a disk cache entry that stores 206 headers while not being sparse.
3995  disk_cache::Entry* entry;
3996  ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
3997                                       NULL));
3998
3999  std::string raw_headers(kRangeGET_TransactionOK.status);
4000  raw_headers.append("\n");
4001  raw_headers.append(kRangeGET_TransactionOK.response_headers);
4002  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4003                                                  raw_headers.size());
4004
4005  net::HttpResponseInfo response;
4006  response.headers = new net::HttpResponseHeaders(raw_headers);
4007  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4008
4009  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4010  int len = static_cast<int>(base::strlcpy(buf->data(),
4011                                           kRangeGET_TransactionOK.data, 500));
4012  net::TestCompletionCallback cb;
4013  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4014  EXPECT_EQ(len, cb.GetResult(rv));
4015  entry->Close();
4016
4017  // Now see that we don't use the stored entry.
4018  std::string headers;
4019  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4020                                 &headers);
4021
4022  // We are expecting a 206.
4023  Verify206Response(headers, 40, 49);
4024  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4025  EXPECT_EQ(1, cache.disk_cache()->open_count());
4026  EXPECT_EQ(2, cache.disk_cache()->create_count());
4027
4028  RemoveMockTransaction(&kRangeGET_TransactionOK);
4029}
4030
4031// Tests that we can handle cached 206 responses that can't be validated.
4032TEST(HttpCache, GET_Previous206_NotValidation) {
4033  MockHttpCache cache;
4034
4035  // Create a disk cache entry that stores 206 headers.
4036  disk_cache::Entry* entry;
4037  ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4038                                       NULL));
4039
4040  // Make sure that the headers cannot be validated with the server.
4041  std::string raw_headers(kRangeGET_TransactionOK.status);
4042  raw_headers.append("\n");
4043  raw_headers.append("Content-Length: 80\n");
4044  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4045                                                  raw_headers.size());
4046
4047  net::HttpResponseInfo response;
4048  response.headers = new net::HttpResponseHeaders(raw_headers);
4049  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4050
4051  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4052  int len = static_cast<int>(base::strlcpy(buf->data(),
4053                                           kRangeGET_TransactionOK.data, 500));
4054  net::TestCompletionCallback cb;
4055  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4056  EXPECT_EQ(len, cb.GetResult(rv));
4057  entry->Close();
4058
4059  // Now see that we don't use the stored entry.
4060  std::string headers;
4061  RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4062                                 &headers);
4063
4064  // We are expecting a 200.
4065  std::string expected_headers(kSimpleGET_Transaction.status);
4066  expected_headers.append("\n");
4067  expected_headers.append(kSimpleGET_Transaction.response_headers);
4068  EXPECT_EQ(expected_headers, headers);
4069  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4070  EXPECT_EQ(1, cache.disk_cache()->open_count());
4071  EXPECT_EQ(2, cache.disk_cache()->create_count());
4072}
4073
4074// Tests that we can handle range requests with cached 200 responses.
4075TEST(HttpCache, RangeGET_Previous200) {
4076  MockHttpCache cache;
4077
4078  // Store the whole thing with status 200.
4079  MockTransaction transaction(kTypicalGET_Transaction);
4080  transaction.url = kRangeGET_TransactionOK.url;
4081  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4082                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4083  AddMockTransaction(&transaction);
4084  RunTransactionTest(cache.http_cache(), transaction);
4085  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4086  EXPECT_EQ(0, cache.disk_cache()->open_count());
4087  EXPECT_EQ(1, cache.disk_cache()->create_count());
4088
4089  RemoveMockTransaction(&transaction);
4090  AddMockTransaction(&kRangeGET_TransactionOK);
4091
4092  // Now see that we use the stored entry.
4093  std::string headers;
4094  MockTransaction transaction2(kRangeGET_TransactionOK);
4095  RangeTransactionServer handler;
4096  handler.set_not_modified(true);
4097  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4098
4099  // We are expecting a 206.
4100  Verify206Response(headers, 40, 49);
4101  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4102  EXPECT_EQ(1, cache.disk_cache()->open_count());
4103  EXPECT_EQ(1, cache.disk_cache()->create_count());
4104
4105  // The last transaction has finished so make sure the entry is deactivated.
4106  base::MessageLoop::current()->RunUntilIdle();
4107
4108  // Make a request for an invalid range.
4109  MockTransaction transaction3(kRangeGET_TransactionOK);
4110  transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4111  transaction3.data = transaction.data;
4112  transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4113  RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4114  EXPECT_EQ(2, cache.disk_cache()->open_count());
4115  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4116  EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4117  EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4118
4119  // Make sure the entry is deactivated.
4120  base::MessageLoop::current()->RunUntilIdle();
4121
4122  // Even though the request was invalid, we should have the entry.
4123  RunTransactionTest(cache.http_cache(), transaction2);
4124  EXPECT_EQ(3, cache.disk_cache()->open_count());
4125
4126  // Make sure the entry is deactivated.
4127  base::MessageLoop::current()->RunUntilIdle();
4128
4129  // Now we should receive a range from the server and drop the stored entry.
4130  handler.set_not_modified(false);
4131  transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4132  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4133  Verify206Response(headers, 40, 49);
4134  EXPECT_EQ(4, cache.network_layer()->transaction_count());
4135  EXPECT_EQ(4, cache.disk_cache()->open_count());
4136  EXPECT_EQ(1, cache.disk_cache()->create_count());
4137
4138  RunTransactionTest(cache.http_cache(), transaction2);
4139  EXPECT_EQ(2, cache.disk_cache()->create_count());
4140
4141  RemoveMockTransaction(&kRangeGET_TransactionOK);
4142}
4143
4144// Tests that we can handle a 200 response when dealing with sparse entries.
4145TEST(HttpCache, RangeRequestResultsIn200) {
4146  MockHttpCache cache;
4147  AddMockTransaction(&kRangeGET_TransactionOK);
4148  std::string headers;
4149
4150  // Write to the cache (70-79).
4151  MockTransaction transaction(kRangeGET_TransactionOK);
4152  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4153  transaction.data = "rg: 70-79 ";
4154  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4155
4156  Verify206Response(headers, 70, 79);
4157  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4158  EXPECT_EQ(0, cache.disk_cache()->open_count());
4159  EXPECT_EQ(1, cache.disk_cache()->create_count());
4160
4161  // Now we'll issue a request that results in a plain 200 response, but to
4162  // the to the same URL that we used to store sparse data, and making sure
4163  // that we ask for a range.
4164  RemoveMockTransaction(&kRangeGET_TransactionOK);
4165  MockTransaction transaction2(kSimpleGET_Transaction);
4166  transaction2.url = kRangeGET_TransactionOK.url;
4167  transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4168  AddMockTransaction(&transaction2);
4169
4170  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4171
4172  std::string expected_headers(kSimpleGET_Transaction.status);
4173  expected_headers.append("\n");
4174  expected_headers.append(kSimpleGET_Transaction.response_headers);
4175  EXPECT_EQ(expected_headers, headers);
4176  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4177  EXPECT_EQ(1, cache.disk_cache()->open_count());
4178  EXPECT_EQ(1, cache.disk_cache()->create_count());
4179
4180  RemoveMockTransaction(&transaction2);
4181}
4182
4183// Tests that a range request that falls outside of the size that we know about
4184// only deletes the entry if the resource has indeed changed.
4185TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4186  MockHttpCache cache;
4187  AddMockTransaction(&kRangeGET_TransactionOK);
4188  std::string headers;
4189
4190  // Write to the cache (40-49).
4191  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4192                                 &headers);
4193
4194  Verify206Response(headers, 40, 49);
4195  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4196  EXPECT_EQ(0, cache.disk_cache()->open_count());
4197  EXPECT_EQ(1, cache.disk_cache()->create_count());
4198
4199  // A weird request should not delete this entry. Ask for bytes 120-.
4200  MockTransaction transaction(kRangeGET_TransactionOK);
4201  transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4202  transaction.data = "";
4203  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4204
4205  EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4206  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4207  EXPECT_EQ(1, cache.disk_cache()->open_count());
4208  EXPECT_EQ(1, cache.disk_cache()->create_count());
4209
4210  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4211  EXPECT_EQ(2, cache.disk_cache()->open_count());
4212  EXPECT_EQ(1, cache.disk_cache()->create_count());
4213
4214  RemoveMockTransaction(&kRangeGET_TransactionOK);
4215}
4216
4217// Tests that we don't delete a sparse entry when we cancel a request.
4218TEST(HttpCache, RangeGET_Cancel) {
4219  MockHttpCache cache;
4220  AddMockTransaction(&kRangeGET_TransactionOK);
4221
4222  MockHttpRequest request(kRangeGET_TransactionOK);
4223
4224  Context* c = new Context();
4225  int rv = cache.http_cache()->CreateTransaction(
4226      net::DEFAULT_PRIORITY, &c->trans, NULL);
4227  EXPECT_EQ(net::OK, rv);
4228
4229  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4230  if (rv == net::ERR_IO_PENDING)
4231    rv = c->callback.WaitForResult();
4232
4233  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4234  EXPECT_EQ(0, cache.disk_cache()->open_count());
4235  EXPECT_EQ(1, cache.disk_cache()->create_count());
4236
4237  // Make sure that the entry has some data stored.
4238  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4239  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4240  if (rv == net::ERR_IO_PENDING)
4241    rv = c->callback.WaitForResult();
4242  EXPECT_EQ(buf->size(), rv);
4243
4244  // Destroy the transaction.
4245  delete c;
4246
4247  // Verify that the entry has not been deleted.
4248  disk_cache::Entry* entry;
4249  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4250  entry->Close();
4251  RemoveMockTransaction(&kRangeGET_TransactionOK);
4252}
4253
4254// Tests that we don't delete a sparse entry when we start a new request after
4255// cancelling the previous one.
4256TEST(HttpCache, RangeGET_Cancel2) {
4257  MockHttpCache cache;
4258  AddMockTransaction(&kRangeGET_TransactionOK);
4259
4260  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4261  MockHttpRequest request(kRangeGET_TransactionOK);
4262  request.load_flags |= net::LOAD_VALIDATE_CACHE;
4263
4264  Context* c = new Context();
4265  int rv = cache.http_cache()->CreateTransaction(
4266      net::DEFAULT_PRIORITY, &c->trans, NULL);
4267  EXPECT_EQ(net::OK, rv);
4268
4269  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4270  if (rv == net::ERR_IO_PENDING)
4271    rv = c->callback.WaitForResult();
4272
4273  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4274  EXPECT_EQ(1, cache.disk_cache()->open_count());
4275  EXPECT_EQ(1, cache.disk_cache()->create_count());
4276
4277  // Make sure that we revalidate the entry and read from the cache (a single
4278  // read will return while waiting for the network).
4279  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4280  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4281  EXPECT_EQ(5, c->callback.GetResult(rv));
4282  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4283  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4284
4285  // Destroy the transaction before completing the read.
4286  delete c;
4287
4288  // We have the read and the delete (OnProcessPendingQueue) waiting on the
4289  // message loop. This means that a new transaction will just reuse the same
4290  // active entry (no open or create).
4291
4292  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4293
4294  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4295  EXPECT_EQ(1, cache.disk_cache()->open_count());
4296  EXPECT_EQ(1, cache.disk_cache()->create_count());
4297  RemoveMockTransaction(&kRangeGET_TransactionOK);
4298}
4299
4300// A slight variation of the previous test, this time we cancel two requests in
4301// a row, making sure that the second is waiting for the entry to be ready.
4302TEST(HttpCache, RangeGET_Cancel3) {
4303  MockHttpCache cache;
4304  AddMockTransaction(&kRangeGET_TransactionOK);
4305
4306  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4307  MockHttpRequest request(kRangeGET_TransactionOK);
4308  request.load_flags |= net::LOAD_VALIDATE_CACHE;
4309
4310  Context* c = new Context();
4311  int rv = cache.http_cache()->CreateTransaction(
4312      net::DEFAULT_PRIORITY, &c->trans, NULL);
4313  EXPECT_EQ(net::OK, rv);
4314
4315  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4316  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4317  rv = c->callback.WaitForResult();
4318
4319  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4320  EXPECT_EQ(1, cache.disk_cache()->open_count());
4321  EXPECT_EQ(1, cache.disk_cache()->create_count());
4322
4323  // Make sure that we revalidate the entry and read from the cache (a single
4324  // read will return while waiting for the network).
4325  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4326  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4327  EXPECT_EQ(5, c->callback.GetResult(rv));
4328  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4329  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4330
4331  // Destroy the transaction before completing the read.
4332  delete c;
4333
4334  // We have the read and the delete (OnProcessPendingQueue) waiting on the
4335  // message loop. This means that a new transaction will just reuse the same
4336  // active entry (no open or create).
4337
4338  c = new Context();
4339  rv = cache.http_cache()->CreateTransaction(
4340      net::DEFAULT_PRIORITY, &c->trans, NULL);
4341  EXPECT_EQ(net::OK, rv);
4342
4343  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4344  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4345
4346  MockDiskEntry::IgnoreCallbacks(true);
4347  base::MessageLoop::current()->RunUntilIdle();
4348  MockDiskEntry::IgnoreCallbacks(false);
4349
4350  // The new transaction is waiting for the query range callback.
4351  delete c;
4352
4353  // And we should not crash when the callback is delivered.
4354  base::MessageLoop::current()->RunUntilIdle();
4355
4356  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4357  EXPECT_EQ(1, cache.disk_cache()->open_count());
4358  EXPECT_EQ(1, cache.disk_cache()->create_count());
4359  RemoveMockTransaction(&kRangeGET_TransactionOK);
4360}
4361
4362// Tests that an invalid range response results in no cached entry.
4363TEST(HttpCache, RangeGET_InvalidResponse1) {
4364  MockHttpCache cache;
4365  std::string headers;
4366
4367  MockTransaction transaction(kRangeGET_TransactionOK);
4368  transaction.handler = NULL;
4369  transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4370                                 "Content-Length: 10\n";
4371  AddMockTransaction(&transaction);
4372  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4373
4374  std::string expected(transaction.status);
4375  expected.append("\n");
4376  expected.append(transaction.response_headers);
4377  EXPECT_EQ(expected, headers);
4378
4379  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4380  EXPECT_EQ(0, cache.disk_cache()->open_count());
4381  EXPECT_EQ(1, cache.disk_cache()->create_count());
4382
4383  // Verify that we don't have a cached entry.
4384  disk_cache::Entry* entry;
4385  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4386
4387  RemoveMockTransaction(&kRangeGET_TransactionOK);
4388}
4389
4390// Tests that we reject a range that doesn't match the content-length.
4391TEST(HttpCache, RangeGET_InvalidResponse2) {
4392  MockHttpCache cache;
4393  std::string headers;
4394
4395  MockTransaction transaction(kRangeGET_TransactionOK);
4396  transaction.handler = NULL;
4397  transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4398                                 "Content-Length: 20\n";
4399  AddMockTransaction(&transaction);
4400  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4401
4402  std::string expected(transaction.status);
4403  expected.append("\n");
4404  expected.append(transaction.response_headers);
4405  EXPECT_EQ(expected, headers);
4406
4407  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4408  EXPECT_EQ(0, cache.disk_cache()->open_count());
4409  EXPECT_EQ(1, cache.disk_cache()->create_count());
4410
4411  // Verify that we don't have a cached entry.
4412  disk_cache::Entry* entry;
4413  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4414
4415  RemoveMockTransaction(&kRangeGET_TransactionOK);
4416}
4417
4418// Tests that if a server tells us conflicting information about a resource we
4419// ignore the response.
4420TEST(HttpCache, RangeGET_InvalidResponse3) {
4421  MockHttpCache cache;
4422  std::string headers;
4423
4424  MockTransaction transaction(kRangeGET_TransactionOK);
4425  transaction.handler = NULL;
4426  transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4427  std::string response_headers(transaction.response_headers);
4428  response_headers.append("Content-Range: bytes 50-59/160\n");
4429  transaction.response_headers = response_headers.c_str();
4430  AddMockTransaction(&transaction);
4431  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4432
4433  Verify206Response(headers, 50, 59);
4434  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4435  EXPECT_EQ(0, cache.disk_cache()->open_count());
4436  EXPECT_EQ(1, cache.disk_cache()->create_count());
4437
4438  RemoveMockTransaction(&transaction);
4439  AddMockTransaction(&kRangeGET_TransactionOK);
4440
4441  // This transaction will report a resource size of 80 bytes, and we think it's
4442  // 160 so we should ignore the response.
4443  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4444                                 &headers);
4445
4446  Verify206Response(headers, 40, 49);
4447  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4448  EXPECT_EQ(1, cache.disk_cache()->open_count());
4449  EXPECT_EQ(1, cache.disk_cache()->create_count());
4450
4451  // Verify that we cached the first response but not the second one.
4452  disk_cache::Entry* en;
4453  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4454
4455  int64 cached_start = 0;
4456  net::TestCompletionCallback cb;
4457  int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4458  EXPECT_EQ(10, cb.GetResult(rv));
4459  EXPECT_EQ(50, cached_start);
4460  en->Close();
4461
4462  RemoveMockTransaction(&kRangeGET_TransactionOK);
4463}
4464
4465// Tests that we handle large range values properly.
4466TEST(HttpCache, RangeGET_LargeValues) {
4467  // We need a real sparse cache for this test.
4468  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4469  std::string headers;
4470
4471  MockTransaction transaction(kRangeGET_TransactionOK);
4472  transaction.handler = NULL;
4473  transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4474                                EXTRA_HEADER;
4475  transaction.response_headers =
4476      "ETag: \"foo\"\n"
4477      "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4478      "Content-Length: 10\n";
4479  AddMockTransaction(&transaction);
4480  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4481
4482  std::string expected(transaction.status);
4483  expected.append("\n");
4484  expected.append(transaction.response_headers);
4485  EXPECT_EQ(expected, headers);
4486
4487  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4488
4489  // Verify that we have a cached entry.
4490  disk_cache::Entry* en;
4491  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4492  en->Close();
4493
4494  RemoveMockTransaction(&kRangeGET_TransactionOK);
4495}
4496
4497// Tests that we don't crash with a range request if the disk cache was not
4498// initialized properly.
4499TEST(HttpCache, RangeGET_NoDiskCache) {
4500  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4501  factory->set_fail(true);
4502  factory->FinishCreation();  // We'll complete synchronously.
4503  MockHttpCache cache(factory);
4504
4505  AddMockTransaction(&kRangeGET_TransactionOK);
4506
4507  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4508  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4509
4510  RemoveMockTransaction(&kRangeGET_TransactionOK);
4511}
4512
4513// Tests that we handle byte range requests that skip the cache.
4514TEST(HttpCache, RangeHEAD) {
4515  MockHttpCache cache;
4516  AddMockTransaction(&kRangeGET_TransactionOK);
4517
4518  MockTransaction transaction(kRangeGET_TransactionOK);
4519  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4520  transaction.method = "HEAD";
4521  transaction.data = "rg: 70-79 ";
4522
4523  std::string headers;
4524  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4525
4526  Verify206Response(headers, 70, 79);
4527  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4528  EXPECT_EQ(0, cache.disk_cache()->open_count());
4529  EXPECT_EQ(0, cache.disk_cache()->create_count());
4530
4531  RemoveMockTransaction(&kRangeGET_TransactionOK);
4532}
4533
4534// Tests that we don't crash when after reading from the cache we issue a
4535// request for the next range and the server gives us a 200 synchronously.
4536TEST(HttpCache, RangeGET_FastFlakyServer) {
4537  MockHttpCache cache;
4538
4539  MockTransaction transaction(kRangeGET_TransactionOK);
4540  transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4541  transaction.test_mode = TEST_MODE_SYNC_NET_START;
4542  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4543  AddMockTransaction(&transaction);
4544
4545  // Write to the cache.
4546  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4547
4548  // And now read from the cache and the network.
4549  RangeTransactionServer handler;
4550  handler.set_bad_200(true);
4551  transaction.data = "Not a range";
4552  RunTransactionTest(cache.http_cache(), transaction);
4553
4554  EXPECT_EQ(3, cache.network_layer()->transaction_count());
4555  EXPECT_EQ(1, cache.disk_cache()->open_count());
4556  EXPECT_EQ(1, cache.disk_cache()->create_count());
4557
4558  RemoveMockTransaction(&transaction);
4559}
4560
4561// Tests that when the server gives us less data than expected, we don't keep
4562// asking for more data.
4563TEST(HttpCache, RangeGET_FastFlakyServer2) {
4564  MockHttpCache cache;
4565
4566  // First, check with an empty cache (WRITE mode).
4567  MockTransaction transaction(kRangeGET_TransactionOK);
4568  transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4569  transaction.data = "rg: 40-";  // Less than expected.
4570  transaction.handler = NULL;
4571  std::string headers(transaction.response_headers);
4572  headers.append("Content-Range: bytes 40-49/80\n");
4573  transaction.response_headers = headers.c_str();
4574
4575  AddMockTransaction(&transaction);
4576
4577  // Write to the cache.
4578  RunTransactionTest(cache.http_cache(), transaction);
4579
4580  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4581  EXPECT_EQ(0, cache.disk_cache()->open_count());
4582  EXPECT_EQ(1, cache.disk_cache()->create_count());
4583
4584  // Now verify that even in READ_WRITE mode, we forward the bad response to
4585  // the caller.
4586  transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4587  transaction.data = "rg: 60-";  // Less than expected.
4588  headers = kRangeGET_TransactionOK.response_headers;
4589  headers.append("Content-Range: bytes 60-69/80\n");
4590  transaction.response_headers = headers.c_str();
4591
4592  RunTransactionTest(cache.http_cache(), transaction);
4593
4594  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4595  EXPECT_EQ(1, cache.disk_cache()->open_count());
4596  EXPECT_EQ(1, cache.disk_cache()->create_count());
4597
4598  RemoveMockTransaction(&transaction);
4599}
4600
4601#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
4602// This test hits a NOTREACHED so it is a release mode only test.
4603TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
4604  MockHttpCache cache;
4605  AddMockTransaction(&kRangeGET_TransactionOK);
4606
4607  // Write to the cache (40-49).
4608  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4609  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4610  EXPECT_EQ(0, cache.disk_cache()->open_count());
4611  EXPECT_EQ(1, cache.disk_cache()->create_count());
4612
4613  // Force this transaction to read from the cache.
4614  MockTransaction transaction(kRangeGET_TransactionOK);
4615  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4616
4617  MockHttpRequest request(transaction);
4618  net::TestCompletionCallback callback;
4619
4620  scoped_ptr<net::HttpTransaction> trans;
4621  int rv = cache.http_cache()->CreateTransaction(
4622      net::DEFAULT_PRIORITY, &trans, NULL);
4623  EXPECT_EQ(net::OK, rv);
4624  ASSERT_TRUE(trans.get());
4625
4626  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
4627  if (rv == net::ERR_IO_PENDING)
4628    rv = callback.WaitForResult();
4629  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4630
4631  trans.reset();
4632
4633  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4634  EXPECT_EQ(1, cache.disk_cache()->open_count());
4635  EXPECT_EQ(1, cache.disk_cache()->create_count());
4636
4637  RemoveMockTransaction(&kRangeGET_TransactionOK);
4638}
4639#endif
4640
4641// Tests the handling of the "truncation" flag.
4642TEST(HttpCache, WriteResponseInfo_Truncated) {
4643  MockHttpCache cache;
4644  disk_cache::Entry* entry;
4645  ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
4646                                       NULL));
4647
4648  std::string headers("HTTP/1.1 200 OK");
4649  headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4650  net::HttpResponseInfo response;
4651  response.headers = new net::HttpResponseHeaders(headers);
4652
4653  // Set the last argument for this to be an incomplete request.
4654  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
4655  bool truncated = false;
4656  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4657  EXPECT_TRUE(truncated);
4658
4659  // And now test the opposite case.
4660  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4661  truncated = true;
4662  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4663  EXPECT_FALSE(truncated);
4664  entry->Close();
4665}
4666
4667// Tests basic pickling/unpickling of HttpResponseInfo.
4668TEST(HttpCache, PersistHttpResponseInfo) {
4669  // Set some fields (add more if needed.)
4670  net::HttpResponseInfo response1;
4671  response1.was_cached = false;
4672  response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4673  response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4674
4675  // Pickle.
4676  Pickle pickle;
4677  response1.Persist(&pickle, false, false);
4678
4679  // Unpickle.
4680  net::HttpResponseInfo response2;
4681  bool response_truncated;
4682  EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4683  EXPECT_FALSE(response_truncated);
4684
4685  // Verify fields.
4686  EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
4687  EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4688  EXPECT_EQ(80, response2.socket_address.port());
4689  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4690}
4691
4692// Tests that we delete an entry when the request is cancelled before starting
4693// to read from the network.
4694TEST(HttpCache, DoomOnDestruction) {
4695  MockHttpCache cache;
4696
4697  MockHttpRequest request(kSimpleGET_Transaction);
4698
4699  Context* c = new Context();
4700  int rv = cache.http_cache()->CreateTransaction(
4701      net::DEFAULT_PRIORITY, &c->trans, NULL);
4702  EXPECT_EQ(net::OK, rv);
4703
4704  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4705  if (rv == net::ERR_IO_PENDING)
4706    c->result = c->callback.WaitForResult();
4707
4708  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4709  EXPECT_EQ(0, cache.disk_cache()->open_count());
4710  EXPECT_EQ(1, cache.disk_cache()->create_count());
4711
4712  // Destroy the transaction. We only have the headers so we should delete this
4713  // entry.
4714  delete c;
4715
4716  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4717
4718  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4719  EXPECT_EQ(0, cache.disk_cache()->open_count());
4720  EXPECT_EQ(2, cache.disk_cache()->create_count());
4721}
4722
4723// Tests that we delete an entry when the request is cancelled if the response
4724// does not have content-length and strong validators.
4725TEST(HttpCache, DoomOnDestruction2) {
4726  MockHttpCache cache;
4727
4728  MockHttpRequest request(kSimpleGET_Transaction);
4729
4730  Context* c = new Context();
4731  int rv = cache.http_cache()->CreateTransaction(
4732      net::DEFAULT_PRIORITY, &c->trans, NULL);
4733  EXPECT_EQ(net::OK, rv);
4734
4735  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4736  if (rv == net::ERR_IO_PENDING)
4737    rv = c->callback.WaitForResult();
4738
4739  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4740  EXPECT_EQ(0, cache.disk_cache()->open_count());
4741  EXPECT_EQ(1, cache.disk_cache()->create_count());
4742
4743  // Make sure that the entry has some data stored.
4744  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4745  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4746  if (rv == net::ERR_IO_PENDING)
4747    rv = c->callback.WaitForResult();
4748  EXPECT_EQ(buf->size(), rv);
4749
4750  // Destroy the transaction.
4751  delete c;
4752
4753  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4754
4755  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4756  EXPECT_EQ(0, cache.disk_cache()->open_count());
4757  EXPECT_EQ(2, cache.disk_cache()->create_count());
4758}
4759
4760// Tests that we delete an entry when the request is cancelled if the response
4761// has an "Accept-Ranges: none" header.
4762TEST(HttpCache, DoomOnDestruction3) {
4763  MockHttpCache cache;
4764
4765  MockTransaction transaction(kSimpleGET_Transaction);
4766  transaction.response_headers =
4767      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4768      "Content-Length: 22\n"
4769      "Accept-Ranges: none\n"
4770      "Etag: \"foopy\"\n";
4771  AddMockTransaction(&transaction);
4772  MockHttpRequest request(transaction);
4773
4774  Context* c = new Context();
4775  int rv = cache.http_cache()->CreateTransaction(
4776      net::DEFAULT_PRIORITY, &c->trans, NULL);
4777  EXPECT_EQ(net::OK, rv);
4778
4779  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4780  if (rv == net::ERR_IO_PENDING)
4781    rv = c->callback.WaitForResult();
4782
4783  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4784  EXPECT_EQ(0, cache.disk_cache()->open_count());
4785  EXPECT_EQ(1, cache.disk_cache()->create_count());
4786
4787  // Make sure that the entry has some data stored.
4788  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4789  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4790  if (rv == net::ERR_IO_PENDING)
4791    rv = c->callback.WaitForResult();
4792  EXPECT_EQ(buf->size(), rv);
4793
4794  // Destroy the transaction.
4795  delete c;
4796
4797  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4798
4799  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4800  EXPECT_EQ(0, cache.disk_cache()->open_count());
4801  EXPECT_EQ(2, cache.disk_cache()->create_count());
4802
4803  RemoveMockTransaction(&transaction);
4804}
4805
4806// Tests that we mark an entry as incomplete when the request is cancelled.
4807TEST(HttpCache, SetTruncatedFlag) {
4808  MockHttpCache cache;
4809
4810  MockTransaction transaction(kSimpleGET_Transaction);
4811  transaction.response_headers =
4812      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4813      "Content-Length: 22\n"
4814      "Etag: \"foopy\"\n";
4815  AddMockTransaction(&transaction);
4816  MockHttpRequest request(transaction);
4817
4818  scoped_ptr<Context> c(new Context());
4819  // We use a test delegate to ensure that after initiating destruction
4820  // of the transaction, no further delegate callbacks happen.
4821  // We initialize the TestHttpTransactionDelegate with the correct number of
4822  // cache actions and network actions to be reported.
4823  scoped_ptr<TestHttpTransactionDelegate> delegate(
4824      new TestHttpTransactionDelegate(7, 3));
4825  int rv = cache.http_cache()->CreateTransaction(
4826      net::DEFAULT_PRIORITY, &c->trans, delegate.get());
4827  EXPECT_EQ(net::OK, rv);
4828
4829  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4830  if (rv == net::ERR_IO_PENDING)
4831    rv = c->callback.WaitForResult();
4832
4833  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4834  EXPECT_EQ(0, cache.disk_cache()->open_count());
4835  EXPECT_EQ(1, cache.disk_cache()->create_count());
4836
4837  // Make sure that the entry has some data stored.
4838  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4839  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4840  if (rv == net::ERR_IO_PENDING)
4841    rv = c->callback.WaitForResult();
4842  EXPECT_EQ(buf->size(), rv);
4843
4844  // We want to cancel the request when the transaction is busy.
4845  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4846  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4847  EXPECT_FALSE(c->callback.have_result());
4848
4849  MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
4850  int num_delegate_callbacks_before_destruction =
4851      delegate->num_callbacks_observed();
4852
4853  // Destroy the transaction.
4854  c->trans.reset();
4855  MockHttpCache::SetTestMode(0);
4856
4857  // Ensure the delegate received no callbacks during destruction.
4858  EXPECT_EQ(num_delegate_callbacks_before_destruction,
4859            delegate->num_callbacks_observed());
4860
4861  // Since the transaction was aborted in the middle of network I/O, we will
4862  // manually call the delegate so that its pending I/O operation will be
4863  // closed (which is what the test delegate is expecting).
4864  delegate->OnNetworkActionFinish();
4865
4866  // Make sure that we don't invoke the callback. We may have an issue if the
4867  // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4868  // could end up with the transaction being deleted twice if we send any
4869  // notification from the transaction destructor (see http://crbug.com/31723).
4870  EXPECT_FALSE(c->callback.have_result());
4871
4872  // Verify that the entry is marked as incomplete.
4873  disk_cache::Entry* entry;
4874  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4875  net::HttpResponseInfo response;
4876  bool truncated = false;
4877  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4878  EXPECT_TRUE(truncated);
4879  entry->Close();
4880
4881  RemoveMockTransaction(&transaction);
4882}
4883
4884// Tests that we don't mark an entry as truncated when we read everything.
4885TEST(HttpCache, DontSetTruncatedFlag) {
4886  MockHttpCache cache;
4887
4888  MockTransaction transaction(kSimpleGET_Transaction);
4889  transaction.response_headers =
4890      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4891      "Content-Length: 22\n"
4892      "Etag: \"foopy\"\n";
4893  AddMockTransaction(&transaction);
4894  MockHttpRequest request(transaction);
4895
4896  scoped_ptr<Context> c(new Context());
4897  int rv = cache.http_cache()->CreateTransaction(
4898      net::DEFAULT_PRIORITY, &c->trans, NULL);
4899  EXPECT_EQ(net::OK, rv);
4900
4901  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4902  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4903
4904  // Read everything.
4905  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
4906  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4907  EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
4908
4909  // Destroy the transaction.
4910  c->trans.reset();
4911
4912  // Verify that the entry is not marked as truncated.
4913  disk_cache::Entry* entry;
4914  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4915  net::HttpResponseInfo response;
4916  bool truncated = true;
4917  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4918  EXPECT_FALSE(truncated);
4919  entry->Close();
4920
4921  RemoveMockTransaction(&transaction);
4922}
4923
4924// Tests that we can continue with a request that was interrupted.
4925TEST(HttpCache, GET_IncompleteResource) {
4926  MockHttpCache cache;
4927  AddMockTransaction(&kRangeGET_TransactionOK);
4928
4929  std::string raw_headers("HTTP/1.1 200 OK\n"
4930                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4931                          "ETag: \"foo\"\n"
4932                          "Accept-Ranges: bytes\n"
4933                          "Content-Length: 80\n");
4934  CreateTruncatedEntry(raw_headers, &cache);
4935
4936  // Now make a regular request.
4937  std::string headers;
4938  MockTransaction transaction(kRangeGET_TransactionOK);
4939  transaction.request_headers = EXTRA_HEADER;
4940  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4941                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4942  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4943
4944  // We update the headers with the ones received while revalidating.
4945  std::string expected_headers(
4946      "HTTP/1.1 200 OK\n"
4947      "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4948      "Accept-Ranges: bytes\n"
4949      "ETag: \"foo\"\n"
4950      "Content-Length: 80\n");
4951
4952  EXPECT_EQ(expected_headers, headers);
4953  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4954  EXPECT_EQ(1, cache.disk_cache()->open_count());
4955  EXPECT_EQ(1, cache.disk_cache()->create_count());
4956
4957  // Verify that the disk entry was updated.
4958  disk_cache::Entry* entry;
4959  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4960  EXPECT_EQ(80, entry->GetDataSize(1));
4961  bool truncated = true;
4962  net::HttpResponseInfo response;
4963  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4964  EXPECT_FALSE(truncated);
4965  entry->Close();
4966
4967  RemoveMockTransaction(&kRangeGET_TransactionOK);
4968}
4969
4970// Tests the handling of no-store when revalidating a truncated entry.
4971TEST(HttpCache, GET_IncompleteResource_NoStore) {
4972  MockHttpCache cache;
4973  AddMockTransaction(&kRangeGET_TransactionOK);
4974
4975  std::string raw_headers("HTTP/1.1 200 OK\n"
4976                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4977                          "ETag: \"foo\"\n"
4978                          "Accept-Ranges: bytes\n"
4979                          "Content-Length: 80\n");
4980  CreateTruncatedEntry(raw_headers, &cache);
4981  RemoveMockTransaction(&kRangeGET_TransactionOK);
4982
4983  // Now make a regular request.
4984  MockTransaction transaction(kRangeGET_TransactionOK);
4985  transaction.request_headers = EXTRA_HEADER;
4986  std::string response_headers(transaction.response_headers);
4987  response_headers += ("Cache-Control: no-store\n");
4988  transaction.response_headers = response_headers.c_str();
4989  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4990                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4991  AddMockTransaction(&transaction);
4992
4993  std::string headers;
4994  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4995
4996  // We update the headers with the ones received while revalidating.
4997  std::string expected_headers(
4998      "HTTP/1.1 200 OK\n"
4999      "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5000      "Accept-Ranges: bytes\n"
5001      "Cache-Control: no-store\n"
5002      "ETag: \"foo\"\n"
5003      "Content-Length: 80\n");
5004
5005  EXPECT_EQ(expected_headers, headers);
5006  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5007  EXPECT_EQ(1, cache.disk_cache()->open_count());
5008  EXPECT_EQ(1, cache.disk_cache()->create_count());
5009
5010  // Verify that the disk entry was deleted.
5011  disk_cache::Entry* entry;
5012  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5013  RemoveMockTransaction(&transaction);
5014}
5015
5016// Tests cancelling a request after the server sent no-store.
5017TEST(HttpCache, GET_IncompleteResource_Cancel) {
5018  MockHttpCache cache;
5019  AddMockTransaction(&kRangeGET_TransactionOK);
5020
5021  std::string raw_headers("HTTP/1.1 200 OK\n"
5022                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5023                          "ETag: \"foo\"\n"
5024                          "Accept-Ranges: bytes\n"
5025                          "Content-Length: 80\n");
5026  CreateTruncatedEntry(raw_headers, &cache);
5027  RemoveMockTransaction(&kRangeGET_TransactionOK);
5028
5029  // Now make a regular request.
5030  MockTransaction transaction(kRangeGET_TransactionOK);
5031  transaction.request_headers = EXTRA_HEADER;
5032  std::string response_headers(transaction.response_headers);
5033  response_headers += ("Cache-Control: no-store\n");
5034  transaction.response_headers = response_headers.c_str();
5035  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5036                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5037  AddMockTransaction(&transaction);
5038
5039  MockHttpRequest request(transaction);
5040  Context* c = new Context();
5041
5042  int rv = cache.http_cache()->CreateTransaction(
5043      net::DEFAULT_PRIORITY, &c->trans, NULL);
5044  EXPECT_EQ(net::OK, rv);
5045
5046  // Queue another request to this transaction. We have to start this request
5047  // before the first one gets the response from the server and dooms the entry,
5048  // otherwise it will just create a new entry without being queued to the first
5049  // request.
5050  Context* pending = new Context();
5051  EXPECT_EQ(net::OK,
5052            cache.http_cache()->CreateTransaction(
5053                net::DEFAULT_PRIORITY, &pending->trans, NULL));
5054
5055  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5056  EXPECT_EQ(net::ERR_IO_PENDING,
5057            pending->trans->Start(&request, pending->callback.callback(),
5058                                  net::BoundNetLog()));
5059  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5060
5061  // Make sure that the entry has some data stored.
5062  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
5063  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5064  EXPECT_EQ(5, c->callback.GetResult(rv));
5065
5066  // Cancel the requests.
5067  delete c;
5068  delete pending;
5069
5070  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5071  EXPECT_EQ(1, cache.disk_cache()->open_count());
5072  EXPECT_EQ(2, cache.disk_cache()->create_count());
5073
5074  base::MessageLoop::current()->RunUntilIdle();
5075  RemoveMockTransaction(&transaction);
5076}
5077
5078// Tests that we delete truncated entries if the server changes its mind midway.
5079TEST(HttpCache, GET_IncompleteResource2) {
5080  MockHttpCache cache;
5081  AddMockTransaction(&kRangeGET_TransactionOK);
5082
5083  // Content-length will be intentionally bad.
5084  std::string raw_headers("HTTP/1.1 200 OK\n"
5085                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5086                          "ETag: \"foo\"\n"
5087                          "Accept-Ranges: bytes\n"
5088                          "Content-Length: 50\n");
5089  CreateTruncatedEntry(raw_headers, &cache);
5090
5091  // Now make a regular request. We expect the code to fail the validation and
5092  // retry the request without using byte ranges.
5093  std::string headers;
5094  MockTransaction transaction(kRangeGET_TransactionOK);
5095  transaction.request_headers = EXTRA_HEADER;
5096  transaction.data = "Not a range";
5097  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5098
5099  // The server will return 200 instead of a byte range.
5100  std::string expected_headers(
5101      "HTTP/1.1 200 OK\n"
5102      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5103
5104  EXPECT_EQ(expected_headers, headers);
5105  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5106  EXPECT_EQ(1, cache.disk_cache()->open_count());
5107  EXPECT_EQ(1, cache.disk_cache()->create_count());
5108
5109  // Verify that the disk entry was deleted.
5110  disk_cache::Entry* entry;
5111  ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5112  RemoveMockTransaction(&kRangeGET_TransactionOK);
5113}
5114
5115// Tests that we always validate a truncated request.
5116TEST(HttpCache, GET_IncompleteResource3) {
5117  MockHttpCache cache;
5118  AddMockTransaction(&kRangeGET_TransactionOK);
5119
5120  // This should not require validation for 10 hours.
5121  std::string raw_headers("HTTP/1.1 200 OK\n"
5122                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5123                          "ETag: \"foo\"\n"
5124                          "Cache-Control: max-age= 36000\n"
5125                          "Accept-Ranges: bytes\n"
5126                          "Content-Length: 80\n");
5127  CreateTruncatedEntry(raw_headers, &cache);
5128
5129  // Now make a regular request.
5130  std::string headers;
5131  MockTransaction transaction(kRangeGET_TransactionOK);
5132  transaction.request_headers = EXTRA_HEADER;
5133  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5134                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5135
5136  scoped_ptr<Context> c(new Context);
5137  EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5138      net::DEFAULT_PRIORITY, &c->trans, NULL));
5139
5140  MockHttpRequest request(transaction);
5141  int rv = c->trans->Start(
5142      &request, c->callback.callback(), net::BoundNetLog());
5143  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5144
5145  // We should have checked with the server before finishing Start().
5146  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5147  EXPECT_EQ(1, cache.disk_cache()->open_count());
5148  EXPECT_EQ(1, cache.disk_cache()->create_count());
5149
5150  RemoveMockTransaction(&kRangeGET_TransactionOK);
5151}
5152
5153// Tests that we cache a 200 response to the validation request.
5154TEST(HttpCache, GET_IncompleteResource4) {
5155  MockHttpCache cache;
5156  AddMockTransaction(&kRangeGET_TransactionOK);
5157
5158  std::string raw_headers("HTTP/1.1 200 OK\n"
5159                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5160                          "ETag: \"foo\"\n"
5161                          "Accept-Ranges: bytes\n"
5162                          "Content-Length: 80\n");
5163  CreateTruncatedEntry(raw_headers, &cache);
5164
5165  // Now make a regular request.
5166  std::string headers;
5167  MockTransaction transaction(kRangeGET_TransactionOK);
5168  transaction.request_headers = EXTRA_HEADER;
5169  transaction.data = "Not a range";
5170  RangeTransactionServer handler;
5171  handler.set_bad_200(true);
5172  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5173
5174  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5175  EXPECT_EQ(1, cache.disk_cache()->open_count());
5176  EXPECT_EQ(1, cache.disk_cache()->create_count());
5177
5178  // Verify that the disk entry was updated.
5179  disk_cache::Entry* entry;
5180  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5181  EXPECT_EQ(11, entry->GetDataSize(1));
5182  bool truncated = true;
5183  net::HttpResponseInfo response;
5184  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5185  EXPECT_FALSE(truncated);
5186  entry->Close();
5187
5188  RemoveMockTransaction(&kRangeGET_TransactionOK);
5189}
5190
5191// Tests that when we cancel a request that was interrupted, we mark it again
5192// as truncated.
5193TEST(HttpCache, GET_CancelIncompleteResource) {
5194  MockHttpCache cache;
5195  AddMockTransaction(&kRangeGET_TransactionOK);
5196
5197  std::string raw_headers("HTTP/1.1 200 OK\n"
5198                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5199                          "ETag: \"foo\"\n"
5200                          "Accept-Ranges: bytes\n"
5201                          "Content-Length: 80\n");
5202  CreateTruncatedEntry(raw_headers, &cache);
5203
5204  // Now make a regular request.
5205  MockTransaction transaction(kRangeGET_TransactionOK);
5206  transaction.request_headers = EXTRA_HEADER;
5207
5208  MockHttpRequest request(transaction);
5209  Context* c = new Context();
5210  EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5211      net::DEFAULT_PRIORITY, &c->trans, NULL));
5212
5213  int rv = c->trans->Start(
5214      &request, c->callback.callback(), net::BoundNetLog());
5215  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5216
5217  // Read 20 bytes from the cache, and 10 from the net.
5218  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5219  rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5220  EXPECT_EQ(20, c->callback.GetResult(rv));
5221  rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5222  EXPECT_EQ(10, c->callback.GetResult(rv));
5223
5224  // At this point, we are already reading so canceling the request should leave
5225  // a truncated one.
5226  delete c;
5227
5228  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5229  EXPECT_EQ(1, cache.disk_cache()->open_count());
5230  EXPECT_EQ(1, cache.disk_cache()->create_count());
5231
5232  // Verify that the disk entry was updated: now we have 30 bytes.
5233  disk_cache::Entry* entry;
5234  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5235  EXPECT_EQ(30, entry->GetDataSize(1));
5236  bool truncated = false;
5237  net::HttpResponseInfo response;
5238  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5239  EXPECT_TRUE(truncated);
5240  entry->Close();
5241  RemoveMockTransaction(&kRangeGET_TransactionOK);
5242}
5243
5244// Tests that we can handle range requests when we have a truncated entry.
5245TEST(HttpCache, RangeGET_IncompleteResource) {
5246  MockHttpCache cache;
5247  AddMockTransaction(&kRangeGET_TransactionOK);
5248
5249  // Content-length will be intentionally bogus.
5250  std::string raw_headers("HTTP/1.1 200 OK\n"
5251                          "Last-Modified: something\n"
5252                          "ETag: \"foo\"\n"
5253                          "Accept-Ranges: bytes\n"
5254                          "Content-Length: 10\n");
5255  CreateTruncatedEntry(raw_headers, &cache);
5256
5257  // Now make a range request.
5258  std::string headers;
5259  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5260                                 &headers);
5261
5262  Verify206Response(headers, 40, 49);
5263  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5264  EXPECT_EQ(1, cache.disk_cache()->open_count());
5265  EXPECT_EQ(2, cache.disk_cache()->create_count());
5266
5267  RemoveMockTransaction(&kRangeGET_TransactionOK);
5268}
5269
5270TEST(HttpCache, SyncRead) {
5271  MockHttpCache cache;
5272
5273  // This test ensures that a read that completes synchronously does not cause
5274  // any problems.
5275
5276  ScopedMockTransaction transaction(kSimpleGET_Transaction);
5277  transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5278                            TEST_MODE_SYNC_CACHE_READ |
5279                            TEST_MODE_SYNC_CACHE_WRITE);
5280
5281  MockHttpRequest r1(transaction),
5282                  r2(transaction),
5283                  r3(transaction);
5284
5285  TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5286                          c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5287                          c3(net::DEFAULT_PRIORITY, cache.http_cache());
5288
5289  c1.Start(&r1, net::BoundNetLog());
5290
5291  r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5292  c2.Start(&r2, net::BoundNetLog());
5293
5294  r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5295  c3.Start(&r3, net::BoundNetLog());
5296
5297  base::MessageLoop::current()->Run();
5298
5299  EXPECT_TRUE(c1.is_done());
5300  EXPECT_TRUE(c2.is_done());
5301  EXPECT_TRUE(c3.is_done());
5302
5303  EXPECT_EQ(net::OK, c1.error());
5304  EXPECT_EQ(net::OK, c2.error());
5305  EXPECT_EQ(net::OK, c3.error());
5306}
5307
5308TEST(HttpCache, ValidationResultsIn200) {
5309  MockHttpCache cache;
5310
5311  // This test ensures that a conditional request, which results in a 200
5312  // instead of a 304, properly truncates the existing response data.
5313
5314  // write to the cache
5315  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5316
5317  // force this transaction to validate the cache
5318  MockTransaction transaction(kETagGET_Transaction);
5319  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5320  RunTransactionTest(cache.http_cache(), transaction);
5321
5322  // read from the cache
5323  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5324}
5325
5326TEST(HttpCache, CachedRedirect) {
5327  MockHttpCache cache;
5328
5329  ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5330  kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5331  kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5332
5333  MockHttpRequest request(kTestTransaction);
5334  net::TestCompletionCallback callback;
5335
5336  // write to the cache
5337  {
5338    scoped_ptr<net::HttpTransaction> trans;
5339    int rv = cache.http_cache()->CreateTransaction(
5340        net::DEFAULT_PRIORITY, &trans, NULL);
5341    EXPECT_EQ(net::OK, rv);
5342    ASSERT_TRUE(trans.get());
5343
5344    rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5345    if (rv == net::ERR_IO_PENDING)
5346      rv = callback.WaitForResult();
5347    ASSERT_EQ(net::OK, rv);
5348
5349    const net::HttpResponseInfo* info = trans->GetResponseInfo();
5350    ASSERT_TRUE(info);
5351
5352    EXPECT_EQ(info->headers->response_code(), 301);
5353
5354    std::string location;
5355    info->headers->EnumerateHeader(NULL, "Location", &location);
5356    EXPECT_EQ(location, "http://www.bar.com/");
5357
5358    // Destroy transaction when going out of scope. We have not actually
5359    // read the response body -- want to test that it is still getting cached.
5360  }
5361  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5362  EXPECT_EQ(0, cache.disk_cache()->open_count());
5363  EXPECT_EQ(1, cache.disk_cache()->create_count());
5364
5365  // read from the cache
5366  {
5367    scoped_ptr<net::HttpTransaction> trans;
5368    int rv = cache.http_cache()->CreateTransaction(
5369        net::DEFAULT_PRIORITY, &trans, NULL);
5370    EXPECT_EQ(net::OK, rv);
5371    ASSERT_TRUE(trans.get());
5372
5373    rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5374    if (rv == net::ERR_IO_PENDING)
5375      rv = callback.WaitForResult();
5376    ASSERT_EQ(net::OK, rv);
5377
5378    const net::HttpResponseInfo* info = trans->GetResponseInfo();
5379    ASSERT_TRUE(info);
5380
5381    EXPECT_EQ(info->headers->response_code(), 301);
5382
5383    std::string location;
5384    info->headers->EnumerateHeader(NULL, "Location", &location);
5385    EXPECT_EQ(location, "http://www.bar.com/");
5386
5387    // Destroy transaction when going out of scope. We have not actually
5388    // read the response body -- want to test that it is still getting cached.
5389  }
5390  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5391  EXPECT_EQ(1, cache.disk_cache()->open_count());
5392  EXPECT_EQ(1, cache.disk_cache()->create_count());
5393}
5394
5395TEST(HttpCache, CacheControlNoStore) {
5396  MockHttpCache cache;
5397
5398  ScopedMockTransaction transaction(kSimpleGET_Transaction);
5399  transaction.response_headers = "cache-control: no-store\n";
5400
5401  // initial load
5402  RunTransactionTest(cache.http_cache(), transaction);
5403
5404  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5405  EXPECT_EQ(0, cache.disk_cache()->open_count());
5406  EXPECT_EQ(1, cache.disk_cache()->create_count());
5407
5408  // try loading again; it should result in a network fetch
5409  RunTransactionTest(cache.http_cache(), transaction);
5410
5411  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5412  EXPECT_EQ(0, cache.disk_cache()->open_count());
5413  EXPECT_EQ(2, cache.disk_cache()->create_count());
5414
5415  disk_cache::Entry* entry;
5416  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5417}
5418
5419TEST(HttpCache, CacheControlNoStore2) {
5420  // this test is similar to the above test, except that the initial response
5421  // is cachable, but when it is validated, no-store is received causing the
5422  // cached document to be deleted.
5423  MockHttpCache cache;
5424
5425  ScopedMockTransaction transaction(kETagGET_Transaction);
5426
5427  // initial load
5428  RunTransactionTest(cache.http_cache(), transaction);
5429
5430  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5431  EXPECT_EQ(0, cache.disk_cache()->open_count());
5432  EXPECT_EQ(1, cache.disk_cache()->create_count());
5433
5434  // try loading again; it should result in a network fetch
5435  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5436  transaction.response_headers = "cache-control: no-store\n";
5437  RunTransactionTest(cache.http_cache(), transaction);
5438
5439  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5440  EXPECT_EQ(1, cache.disk_cache()->open_count());
5441  EXPECT_EQ(1, cache.disk_cache()->create_count());
5442
5443  disk_cache::Entry* entry;
5444  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5445}
5446
5447TEST(HttpCache, CacheControlNoStore3) {
5448  // this test is similar to the above test, except that the response is a 304
5449  // instead of a 200.  this should never happen in practice, but it seems like
5450  // a good thing to verify that we still destroy the cache entry.
5451  MockHttpCache cache;
5452
5453  ScopedMockTransaction transaction(kETagGET_Transaction);
5454
5455  // initial load
5456  RunTransactionTest(cache.http_cache(), transaction);
5457
5458  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5459  EXPECT_EQ(0, cache.disk_cache()->open_count());
5460  EXPECT_EQ(1, cache.disk_cache()->create_count());
5461
5462  // try loading again; it should result in a network fetch
5463  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5464  transaction.response_headers = "cache-control: no-store\n";
5465  transaction.status = "HTTP/1.1 304 Not Modified";
5466  RunTransactionTest(cache.http_cache(), transaction);
5467
5468  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5469  EXPECT_EQ(1, cache.disk_cache()->open_count());
5470  EXPECT_EQ(1, cache.disk_cache()->create_count());
5471
5472  disk_cache::Entry* entry;
5473  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5474}
5475
5476// Ensure that we don't cache requests served over bad HTTPS.
5477TEST(HttpCache, SimpleGET_SSLError) {
5478  MockHttpCache cache;
5479
5480  MockTransaction transaction = kSimpleGET_Transaction;
5481  transaction.cert_status = net::CERT_STATUS_REVOKED;
5482  ScopedMockTransaction scoped_transaction(transaction);
5483
5484  // write to the cache
5485  RunTransactionTest(cache.http_cache(), transaction);
5486
5487  // Test that it was not cached.
5488  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5489
5490  MockHttpRequest request(transaction);
5491  net::TestCompletionCallback callback;
5492
5493  scoped_ptr<net::HttpTransaction> trans;
5494  int rv = cache.http_cache()->CreateTransaction(
5495      net::DEFAULT_PRIORITY, &trans, NULL);
5496  EXPECT_EQ(net::OK, rv);
5497  ASSERT_TRUE(trans.get());
5498
5499  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5500  if (rv == net::ERR_IO_PENDING)
5501    rv = callback.WaitForResult();
5502  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5503}
5504
5505// Ensure that we don't crash by if left-behind transactions.
5506TEST(HttpCache, OutlivedTransactions) {
5507  MockHttpCache* cache = new MockHttpCache;
5508
5509  scoped_ptr<net::HttpTransaction> trans;
5510  int rv = cache->http_cache()->CreateTransaction(
5511      net::DEFAULT_PRIORITY, &trans, NULL);
5512  EXPECT_EQ(net::OK, rv);
5513
5514  delete cache;
5515  trans.reset();
5516}
5517
5518// Test that the disabled mode works.
5519TEST(HttpCache, CacheDisabledMode) {
5520  MockHttpCache cache;
5521
5522  // write to the cache
5523  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5524
5525  // go into disabled mode
5526  cache.http_cache()->set_mode(net::HttpCache::DISABLE);
5527
5528  // force this transaction to write to the cache again
5529  MockTransaction transaction(kSimpleGET_Transaction);
5530
5531  RunTransactionTest(cache.http_cache(), transaction);
5532
5533  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5534  EXPECT_EQ(0, cache.disk_cache()->open_count());
5535  EXPECT_EQ(1, cache.disk_cache()->create_count());
5536}
5537
5538// Other tests check that the response headers of the cached response
5539// get updated on 304. Here we specifically check that the
5540// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5541// fields also gets updated.
5542// http://crbug.com/20594.
5543TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
5544  MockHttpCache cache;
5545
5546  const char* kUrl = "http://foobar";
5547  const char* kData = "body";
5548
5549  MockTransaction mock_network_response = { 0 };
5550  mock_network_response.url = kUrl;
5551
5552  AddMockTransaction(&mock_network_response);
5553
5554  // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
5555
5556  MockTransaction request = { 0 };
5557  request.url = kUrl;
5558  request.method = "GET";
5559  request.request_headers = "\r\n";
5560  request.data = kData;
5561
5562  static const Response kNetResponse1 = {
5563    "HTTP/1.1 200 OK",
5564    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
5565    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5566    kData
5567  };
5568
5569  kNetResponse1.AssignTo(&mock_network_response);
5570
5571  RunTransactionTest(cache.http_cache(), request);
5572
5573  // Request |kUrl| again, this time validating the cache and getting
5574  // a 304 back.
5575
5576  request.load_flags = net::LOAD_VALIDATE_CACHE;
5577
5578  static const Response kNetResponse2 = {
5579    "HTTP/1.1 304 Not Modified",
5580    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
5581    ""
5582  };
5583
5584  kNetResponse2.AssignTo(&mock_network_response);
5585
5586  base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
5587  base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
5588
5589  mock_network_response.request_time = request_time;
5590  mock_network_response.response_time = response_time;
5591
5592  net::HttpResponseInfo response;
5593  RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
5594
5595  // The request and response times should have been updated.
5596  EXPECT_EQ(request_time.ToInternalValue(),
5597            response.request_time.ToInternalValue());
5598  EXPECT_EQ(response_time.ToInternalValue(),
5599            response.response_time.ToInternalValue());
5600
5601  std::string headers;
5602  response.headers->GetNormalizedHeaders(&headers);
5603
5604  EXPECT_EQ("HTTP/1.1 200 OK\n"
5605            "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
5606            "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5607            headers);
5608
5609  RemoveMockTransaction(&mock_network_response);
5610}
5611
5612// Tests that we can write metadata to an entry.
5613TEST(HttpCache, WriteMetadata_OK) {
5614  MockHttpCache cache;
5615
5616  // Write to the cache
5617  net::HttpResponseInfo response;
5618  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5619                                     &response);
5620  EXPECT_TRUE(response.metadata.get() == NULL);
5621
5622  // Trivial call.
5623  cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
5624                                    Time::Now(), NULL, 0);
5625
5626  // Write meta data to the same entry.
5627  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5628  memset(buf->data(), 0, buf->size());
5629  base::strlcpy(buf->data(), "Hi there", buf->size());
5630  cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
5631                                    net::DEFAULT_PRIORITY,
5632                                    response.response_time,
5633                                    buf.get(),
5634                                    buf->size());
5635
5636  // Release the buffer before the operation takes place.
5637  buf = NULL;
5638
5639  // Makes sure we finish pending operations.
5640  base::MessageLoop::current()->RunUntilIdle();
5641
5642  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5643                                     &response);
5644  ASSERT_TRUE(response.metadata.get() != NULL);
5645  EXPECT_EQ(50, response.metadata->size());
5646  EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5647
5648  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5649  EXPECT_EQ(2, cache.disk_cache()->open_count());
5650  EXPECT_EQ(1, cache.disk_cache()->create_count());
5651}
5652
5653// Tests that we only write metadata to an entry if the time stamp matches.
5654TEST(HttpCache, WriteMetadata_Fail) {
5655  MockHttpCache cache;
5656
5657  // Write to the cache
5658  net::HttpResponseInfo response;
5659  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5660                                     &response);
5661  EXPECT_TRUE(response.metadata.get() == NULL);
5662
5663  // Attempt to write meta data to the same entry.
5664  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5665  memset(buf->data(), 0, buf->size());
5666  base::strlcpy(buf->data(), "Hi there", buf->size());
5667  base::Time expected_time = response.response_time -
5668                             base::TimeDelta::FromMilliseconds(20);
5669  cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
5670                                    net::DEFAULT_PRIORITY,
5671                                    expected_time,
5672                                    buf.get(),
5673                                    buf->size());
5674
5675  // Makes sure we finish pending operations.
5676  base::MessageLoop::current()->RunUntilIdle();
5677
5678  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5679                                     &response);
5680  EXPECT_TRUE(response.metadata.get() == NULL);
5681
5682  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5683  EXPECT_EQ(2, cache.disk_cache()->open_count());
5684  EXPECT_EQ(1, cache.disk_cache()->create_count());
5685}
5686
5687// Tests that we can read metadata after validating the entry and with READ mode
5688// transactions.
5689TEST(HttpCache, ReadMetadata) {
5690  MockHttpCache cache;
5691
5692  // Write to the cache
5693  net::HttpResponseInfo response;
5694  RunTransactionTestWithResponseInfo(cache.http_cache(),
5695                                     kTypicalGET_Transaction, &response);
5696  EXPECT_TRUE(response.metadata.get() == NULL);
5697
5698  // Write meta data to the same entry.
5699  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5700  memset(buf->data(), 0, buf->size());
5701  base::strlcpy(buf->data(), "Hi there", buf->size());
5702  cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
5703                                    net::DEFAULT_PRIORITY,
5704                                    response.response_time,
5705                                    buf.get(),
5706                                    buf->size());
5707
5708  // Makes sure we finish pending operations.
5709  base::MessageLoop::current()->RunUntilIdle();
5710
5711  // Start with a READ mode transaction.
5712  MockTransaction trans1(kTypicalGET_Transaction);
5713  trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
5714
5715  RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5716  ASSERT_TRUE(response.metadata.get() != NULL);
5717  EXPECT_EQ(50, response.metadata->size());
5718  EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5719
5720  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5721  EXPECT_EQ(2, cache.disk_cache()->open_count());
5722  EXPECT_EQ(1, cache.disk_cache()->create_count());
5723  base::MessageLoop::current()->RunUntilIdle();
5724
5725  // Now make sure that the entry is re-validated with the server.
5726  trans1.load_flags = net::LOAD_VALIDATE_CACHE;
5727  trans1.status = "HTTP/1.1 304 Not Modified";
5728  AddMockTransaction(&trans1);
5729
5730  response.metadata = NULL;
5731  RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5732  EXPECT_TRUE(response.metadata.get() != NULL);
5733
5734  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5735  EXPECT_EQ(3, cache.disk_cache()->open_count());
5736  EXPECT_EQ(1, cache.disk_cache()->create_count());
5737  base::MessageLoop::current()->RunUntilIdle();
5738  RemoveMockTransaction(&trans1);
5739
5740  // Now return 200 when validating the entry so the metadata will be lost.
5741  MockTransaction trans2(kTypicalGET_Transaction);
5742  trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5743  RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5744  EXPECT_TRUE(response.metadata.get() == NULL);
5745
5746  EXPECT_EQ(3, cache.network_layer()->transaction_count());
5747  EXPECT_EQ(4, cache.disk_cache()->open_count());
5748  EXPECT_EQ(1, cache.disk_cache()->create_count());
5749}
5750
5751// Tests that we don't mark entries as truncated when a filter detects the end
5752// of the stream.
5753TEST(HttpCache, FilterCompletion) {
5754  MockHttpCache cache;
5755  net::TestCompletionCallback callback;
5756
5757  {
5758    scoped_ptr<net::HttpTransaction> trans;
5759    int rv = cache.http_cache()->CreateTransaction(
5760        net::DEFAULT_PRIORITY, &trans, NULL);
5761    EXPECT_EQ(net::OK, rv);
5762
5763    MockHttpRequest request(kSimpleGET_Transaction);
5764    rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5765    EXPECT_EQ(net::OK, callback.GetResult(rv));
5766
5767    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5768    rv = trans->Read(buf.get(), 256, callback.callback());
5769    EXPECT_GT(callback.GetResult(rv), 0);
5770
5771    // Now make sure that the entry is preserved.
5772    trans->DoneReading();
5773  }
5774
5775  // Make sure that the ActiveEntry is gone.
5776  base::MessageLoop::current()->RunUntilIdle();
5777
5778  // Read from the cache.
5779  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5780
5781  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5782  EXPECT_EQ(1, cache.disk_cache()->open_count());
5783  EXPECT_EQ(1, cache.disk_cache()->create_count());
5784}
5785
5786// Tests that we stop cachining when told.
5787TEST(HttpCache, StopCachingDeletesEntry) {
5788  MockHttpCache cache;
5789  net::TestCompletionCallback callback;
5790  MockHttpRequest request(kSimpleGET_Transaction);
5791
5792  {
5793    scoped_ptr<net::HttpTransaction> trans;
5794    int rv = cache.http_cache()->CreateTransaction(
5795        net::DEFAULT_PRIORITY, &trans, NULL);
5796    EXPECT_EQ(net::OK, rv);
5797
5798    rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5799    EXPECT_EQ(net::OK, callback.GetResult(rv));
5800
5801    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5802    rv = trans->Read(buf.get(), 10, callback.callback());
5803    EXPECT_EQ(callback.GetResult(rv), 10);
5804
5805    trans->StopCaching();
5806
5807    // We should be able to keep reading.
5808    rv = trans->Read(buf.get(), 256, callback.callback());
5809    EXPECT_GT(callback.GetResult(rv), 0);
5810    rv = trans->Read(buf.get(), 256, callback.callback());
5811    EXPECT_EQ(callback.GetResult(rv), 0);
5812  }
5813
5814  // Make sure that the ActiveEntry is gone.
5815  base::MessageLoop::current()->RunUntilIdle();
5816
5817  // Verify that the entry is gone.
5818  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5819
5820  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5821  EXPECT_EQ(0, cache.disk_cache()->open_count());
5822  EXPECT_EQ(2, cache.disk_cache()->create_count());
5823}
5824
5825// Tests that when we are told to stop caching we don't throw away valid data.
5826TEST(HttpCache, StopCachingSavesEntry) {
5827  MockHttpCache cache;
5828  net::TestCompletionCallback callback;
5829  MockHttpRequest request(kSimpleGET_Transaction);
5830
5831  {
5832    scoped_ptr<net::HttpTransaction> trans;
5833    int rv = cache.http_cache()->CreateTransaction(
5834        net::DEFAULT_PRIORITY, &trans, NULL);
5835    EXPECT_EQ(net::OK, rv);
5836
5837    // Force a response that can be resumed.
5838    MockTransaction mock_transaction(kSimpleGET_Transaction);
5839    AddMockTransaction(&mock_transaction);
5840    mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
5841                                        "Content-Length: 42\n"
5842                                        "Etag: \"foo\"\n";
5843
5844    rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5845    EXPECT_EQ(net::OK, callback.GetResult(rv));
5846
5847    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5848    rv = trans->Read(buf.get(), 10, callback.callback());
5849    EXPECT_EQ(callback.GetResult(rv), 10);
5850
5851    trans->StopCaching();
5852
5853    // We should be able to keep reading.
5854    rv = trans->Read(buf.get(), 256, callback.callback());
5855    EXPECT_GT(callback.GetResult(rv), 0);
5856    rv = trans->Read(buf.get(), 256, callback.callback());
5857    EXPECT_EQ(callback.GetResult(rv), 0);
5858
5859    RemoveMockTransaction(&mock_transaction);
5860  }
5861
5862  // Verify that the entry is marked as incomplete.
5863  disk_cache::Entry* entry;
5864  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5865  net::HttpResponseInfo response;
5866  bool truncated = false;
5867  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5868  EXPECT_TRUE(truncated);
5869  entry->Close();
5870}
5871
5872// Tests that we handle truncated enries when StopCaching is called.
5873TEST(HttpCache, StopCachingTruncatedEntry) {
5874  MockHttpCache cache;
5875  net::TestCompletionCallback callback;
5876  MockHttpRequest request(kRangeGET_TransactionOK);
5877  request.extra_headers.Clear();
5878  request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
5879  AddMockTransaction(&kRangeGET_TransactionOK);
5880
5881  std::string raw_headers("HTTP/1.1 200 OK\n"
5882                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5883                          "ETag: \"foo\"\n"
5884                          "Accept-Ranges: bytes\n"
5885                          "Content-Length: 80\n");
5886  CreateTruncatedEntry(raw_headers, &cache);
5887
5888  {
5889    // Now make a regular request.
5890    scoped_ptr<net::HttpTransaction> trans;
5891    int rv = cache.http_cache()->CreateTransaction(
5892        net::DEFAULT_PRIORITY, &trans, NULL);
5893    EXPECT_EQ(net::OK, rv);
5894
5895    rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5896    EXPECT_EQ(net::OK, callback.GetResult(rv));
5897
5898    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5899    rv = trans->Read(buf.get(), 10, callback.callback());
5900    EXPECT_EQ(callback.GetResult(rv), 10);
5901
5902    // This is actually going to do nothing.
5903    trans->StopCaching();
5904
5905    // We should be able to keep reading.
5906    rv = trans->Read(buf.get(), 256, callback.callback());
5907    EXPECT_GT(callback.GetResult(rv), 0);
5908    rv = trans->Read(buf.get(), 256, callback.callback());
5909    EXPECT_GT(callback.GetResult(rv), 0);
5910    rv = trans->Read(buf.get(), 256, callback.callback());
5911    EXPECT_EQ(callback.GetResult(rv), 0);
5912  }
5913
5914  // Verify that the disk entry was updated.
5915  disk_cache::Entry* entry;
5916  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5917  EXPECT_EQ(80, entry->GetDataSize(1));
5918  bool truncated = true;
5919  net::HttpResponseInfo response;
5920  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5921  EXPECT_FALSE(truncated);
5922  entry->Close();
5923
5924  RemoveMockTransaction(&kRangeGET_TransactionOK);
5925}
5926
5927// Tests that we detect truncated resources from the net when there is
5928// a Content-Length header.
5929TEST(HttpCache, TruncatedByContentLength) {
5930  MockHttpCache cache;
5931  net::TestCompletionCallback callback;
5932
5933  MockTransaction transaction(kSimpleGET_Transaction);
5934  AddMockTransaction(&transaction);
5935  transaction.response_headers = "Cache-Control: max-age=10000\n"
5936                                 "Content-Length: 100\n";
5937  RunTransactionTest(cache.http_cache(), transaction);
5938  RemoveMockTransaction(&transaction);
5939
5940  // Read from the cache.
5941  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5942
5943  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5944  EXPECT_EQ(0, cache.disk_cache()->open_count());
5945  EXPECT_EQ(2, cache.disk_cache()->create_count());
5946}
5947
5948// Tests that we actually flag entries as truncated when we detect an error
5949// from the net.
5950TEST(HttpCache, TruncatedByContentLength2) {
5951  MockHttpCache cache;
5952  net::TestCompletionCallback callback;
5953
5954  MockTransaction transaction(kSimpleGET_Transaction);
5955  AddMockTransaction(&transaction);
5956  transaction.response_headers = "Cache-Control: max-age=10000\n"
5957                                 "Content-Length: 100\n"
5958                                 "Etag: \"foo\"\n";
5959  RunTransactionTest(cache.http_cache(), transaction);
5960  RemoveMockTransaction(&transaction);
5961
5962  // Verify that the entry is marked as incomplete.
5963  disk_cache::Entry* entry;
5964  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5965  net::HttpResponseInfo response;
5966  bool truncated = false;
5967  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5968  EXPECT_TRUE(truncated);
5969  entry->Close();
5970}
5971
5972TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit_TransactionDelegate) {
5973  MockHttpCache cache;
5974
5975  // Write to the cache.
5976  RunTransactionTestWithDelegate(cache.http_cache(),
5977                                 kSimpleGET_Transaction,
5978                                 8,
5979                                 3);
5980
5981  // Force this transaction to read from the cache.
5982  MockTransaction transaction(kSimpleGET_Transaction);
5983  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5984
5985  RunTransactionTestWithDelegate(cache.http_cache(),
5986                                 kSimpleGET_Transaction,
5987                                 5,
5988                                 0);
5989}
5990
5991// Make sure that calling SetPriority on a cache transaction passes on
5992// its priority updates to its underlying network transaction.
5993TEST(HttpCache, SetPriority) {
5994  MockHttpCache cache;
5995
5996  scoped_ptr<net::HttpTransaction> trans;
5997  EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5998      net::IDLE, &trans, NULL));
5999  ASSERT_TRUE(trans.get());
6000
6001  // Shouldn't crash, but doesn't do anything either.
6002  trans->SetPriority(net::LOW);
6003
6004  EXPECT_FALSE(cache.network_layer()->last_transaction());
6005  EXPECT_EQ(net::DEFAULT_PRIORITY,
6006            cache.network_layer()->last_create_transaction_priority());
6007
6008  net::HttpRequestInfo info;
6009  info.url = GURL(kSimpleGET_Transaction.url);
6010  net::TestCompletionCallback callback;
6011  EXPECT_EQ(net::ERR_IO_PENDING,
6012            trans->Start(&info, callback.callback(), net::BoundNetLog()));
6013
6014  EXPECT_TRUE(cache.network_layer()->last_transaction());
6015  if (cache.network_layer()->last_transaction()) {
6016    EXPECT_EQ(net::LOW,
6017              cache.network_layer()->last_create_transaction_priority());
6018    EXPECT_EQ(net::LOW,
6019              cache.network_layer()->last_transaction()->priority());
6020  }
6021
6022  trans->SetPriority(net::HIGHEST);
6023
6024  if (cache.network_layer()->last_transaction()) {
6025    EXPECT_EQ(net::LOW,
6026              cache.network_layer()->last_create_transaction_priority());
6027    EXPECT_EQ(net::HIGHEST,
6028              cache.network_layer()->last_transaction()->priority());
6029  }
6030
6031  EXPECT_EQ(net::OK, callback.WaitForResult());
6032}
6033
6034// Make sure that a cache transaction passes on its priority to
6035// newly-created network transactions.
6036TEST(HttpCache, SetPriorityNewTransaction) {
6037  MockHttpCache cache;
6038  AddMockTransaction(&kRangeGET_TransactionOK);
6039
6040  std::string raw_headers("HTTP/1.1 200 OK\n"
6041                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6042                          "ETag: \"foo\"\n"
6043                          "Accept-Ranges: bytes\n"
6044                          "Content-Length: 80\n");
6045  CreateTruncatedEntry(raw_headers, &cache);
6046
6047  // Now make a regular request.
6048  std::string headers;
6049  MockTransaction transaction(kRangeGET_TransactionOK);
6050  transaction.request_headers = EXTRA_HEADER;
6051  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6052                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
6053
6054  scoped_ptr<net::HttpTransaction> trans;
6055  EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
6056      net::MEDIUM, &trans, NULL));
6057  ASSERT_TRUE(trans.get());
6058  EXPECT_EQ(net::DEFAULT_PRIORITY,
6059            cache.network_layer()->last_create_transaction_priority());
6060
6061  MockHttpRequest info(transaction);
6062  net::TestCompletionCallback callback;
6063  EXPECT_EQ(net::ERR_IO_PENDING,
6064            trans->Start(&info, callback.callback(), net::BoundNetLog()));
6065  EXPECT_EQ(net::OK, callback.WaitForResult());
6066
6067  EXPECT_EQ(net::MEDIUM,
6068            cache.network_layer()->last_create_transaction_priority());
6069
6070  trans->SetPriority(net::HIGHEST);
6071  // Should trigger a new network transaction and pick up the new
6072  // priority.
6073  ReadAndVerifyTransaction(trans.get(), transaction);
6074
6075  EXPECT_EQ(net::HIGHEST,
6076            cache.network_layer()->last_create_transaction_priority());
6077
6078  RemoveMockTransaction(&kRangeGET_TransactionOK);
6079}
6080