1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_cache.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/hash_tables.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_vector.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h"
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/cache_type.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/cert_status_flags.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/base/host_port_pair.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/load_flags.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/net_errors.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h"
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_cert_request_info.h"
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache.h"
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_byte_range.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_request_headers.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_request_info.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_headers.h"
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_info.h"
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction.h"
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction_unittest.h"
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_util.h"
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::Time;
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint GetTestModeForEntry(const std::string& key) {
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // 'key' is prefixed with an identifier if it corresponds to a cached POST.
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Skip past that to locate the actual URL.
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // URL corresponding to a registered MockTransaction.  It would be good to
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // have another way to access the test_mode.
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url;
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (isdigit(key[0])) {
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    size_t slash = key.find('/');
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(slash != std::string::npos);
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    url = GURL(key.substr(slash + 1));
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    url = GURL(key);
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const MockTransaction* t = FindMockTransaction(url);
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(t);
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return t->test_mode;
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We can override the test mode for a given operation by setting this global
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// variable. Just remember to reset it after the test!.
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint g_test_mode = 0;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the test mode after considering the global override.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint GetEffectiveTestMode(int test_mode) {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!g_test_mode)
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return test_mode;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return g_test_mode;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// mock disk cache (a very basic memory cache implementation)
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kNumCacheEntryDataIndices = 3;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockDiskEntry : public disk_cache::Entry,
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                      public base::RefCounted<MockDiskEntry> {
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockDiskEntry()
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : test_mode_(0), doomed_(false), sparse_(false), fail_requests_(false),
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        busy_(false), delayed_(false) {
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit MockDiskEntry(const std::string& key)
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : key_(key), doomed_(false), sparse_(false), fail_requests_(false),
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        busy_(false), delayed_(false) {
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    test_mode_ = GetTestModeForEntry(key);
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool is_doomed() const { return doomed_; }
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Doom() {
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    doomed_ = true;
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Close() {
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Release();
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual std::string GetKey() const {
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return std::string();
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return key_;
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual Time GetLastUsed() const {
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return Time::FromInternalValue(0);
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual Time GetLastModified() const {
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return Time::FromInternalValue(0);
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int32 GetDataSize(int index) const {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<int32>(data_[index].size());
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len,
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       net::CompletionCallback* callback) {
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_READ_FAILURE;
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (offset < 0 || offset > static_cast<int>(data_[index].size()))
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_FAILED;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (static_cast<size_t>(offset) == data_[index].size())
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return 0;
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset);
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    memcpy(buf->data(), &data_[index][offset], num);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return num;
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackLater(callback, num);
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len,
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        net::CompletionCallback* callback, bool truncate) {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(truncate);
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (fail_requests_) {
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CallbackLater(callback, net::ERR_CACHE_READ_FAILURE);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return net::ERR_IO_PENDING;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (offset < 0 || offset > static_cast<int>(data_[index].size()))
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_FAILED;
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    data_[index].resize(offset + buf_len);
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (buf_len)
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      memcpy(&data_[index][offset], buf->data(), buf_len);
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return buf_len;
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackLater(callback, buf_len);
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             net::CompletionCallback* callback) {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!sparse_ || busy_)
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (offset < 0)
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_FAILED;
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_READ_FAILURE;
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(offset < kint32max);
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int real_offset = static_cast<int>(offset);
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!buf_len)
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return 0;
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int num = std::min(static_cast<int>(data_[1].size()) - real_offset,
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       buf_len);
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    memcpy(buf->data(), &data_[1][real_offset], num);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return num;
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallbackLater(callback, num);
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    busy_ = true;
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delayed_ = false;
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              net::CompletionCallback* callback) {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (busy_)
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!sparse_) {
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (data_[1].size())
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      sparse_ = true;
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (offset < 0)
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_FAILED;
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!buf_len)
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return 0;
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_READ_FAILURE;
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(offset < kint32max);
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int real_offset = static_cast<int>(offset);
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (static_cast<int>(data_[1].size()) < real_offset + buf_len)
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      data_[1].resize(real_offset + buf_len);
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    memcpy(&data_[1][real_offset], buf->data(), buf_len);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return buf_len;
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallbackLater(callback, buf_len);
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int GetAvailableRange(int64 offset, int len, int64* start,
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                net::CompletionCallback* callback) {
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!sparse_ || busy_)
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (offset < 0)
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_FAILED;
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_READ_FAILURE;
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *start = offset;
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(offset < kint32max);
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int real_offset = static_cast<int>(offset);
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (static_cast<int>(data_[1].size()) < real_offset)
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return 0;
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len);
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int count = 0;
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (; num > 0; num--, real_offset++) {
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (!count) {
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (data_[1][real_offset]) {
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          count++;
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          *start = real_offset;
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      } else {
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (!data_[1][real_offset])
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          break;
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        count++;
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return count;
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallbackLater(callback, count);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::ERR_IO_PENDING;
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool CouldBeSparse() const {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return sparse_;
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void CancelSparseIO() { cancel_ = true; }
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int ReadyForSparseIO(net::CompletionCallback* completion_callback) {
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!cancel_)
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::OK;
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cancel_ = false;
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(completion_callback);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::OK;
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // The pending operation is already in the message loop (and hopefuly
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // already in the second pass).  Just notify the caller that it finished.
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackLater(completion_callback, 0);
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fail most subsequent requests.
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_fail_requests() { fail_requests_ = true; }
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If |value| is true, don't deliver any completion callbacks until called
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // again with |value| set to false.  Caution: remember to enable callbacks
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // again or all subsequent tests will fail.
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void IgnoreCallbacks(bool value) {
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (ignore_callbacks_ == value)
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return;
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ignore_callbacks_ = value;
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!value)
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      StoreAndDeliverCallbacks(false, NULL, NULL, 0);
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  friend class base::RefCounted<MockDiskEntry>;
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  struct CallbackInfo {
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<MockDiskEntry> entry;
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    net::CompletionCallback* callback;
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int result;
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~MockDiskEntry() {}
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Unlike the callbacks for MockHttpTransaction, we want this one to run even
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // if the consumer called Close on the MockDiskEntry.  We achieve that by
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // leveraging the fact that this class is reference counted.
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void CallbackLater(net::CompletionCallback* callback, int result) {
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (ignore_callbacks_)
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return StoreAndDeliverCallbacks(true, this, callback, result);
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        this, &MockDiskEntry::RunCallback, callback, result));
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RunCallback(net::CompletionCallback* callback, int result) {
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (busy_) {
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // This is kind of hacky, but controlling the behavior of just this entry
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // from a test is sort of complicated.  What we really want to do is
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // delay the delivery of a sparse IO operation a little more so that the
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // request start operation (async) will finish without seeing the end of
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // this operation (already posted to the message loop)... and without
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // just delaying for n mS (which may cause trouble with slow bots).  So
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // we re-post this operation (all async sparse IO operations will take two
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // trips trhough the message loop instead of one).
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (!delayed_) {
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        delayed_ = true;
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return CallbackLater(callback, result);
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    busy_ = false;
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    callback->Run(result);
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // When |store| is true, stores the callback to be delivered later; otherwise
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // delivers any callback previously stored.
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry,
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                       net::CompletionCallback* callback,
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                       int result) {
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    static std::vector<CallbackInfo> callback_list;
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (store) {
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      CallbackInfo c = {entry, callback, result};
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      callback_list.push_back(c);
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      for (size_t i = 0; i < callback_list.size(); i++) {
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        CallbackInfo& c = callback_list[i];
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        c.entry->CallbackLater(c.callback, c.result);
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      callback_list.clear();
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string key_;
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<char> data_[kNumCacheEntryDataIndices];
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int test_mode_;
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool doomed_;
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool sparse_;
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool fail_requests_;
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool busy_;
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool delayed_;
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool cancel_;
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool ignore_callbacks_;
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Statics.
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MockDiskEntry::cancel_ = false;
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MockDiskEntry::ignore_callbacks_ = false;
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockDiskCache : public disk_cache::Backend {
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockDiskCache()
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : open_count_(0), create_count_(0), fail_requests_(false),
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        soft_failures_(false) {
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~MockDiskCache() {
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ReleaseAll();
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int32 GetEntryCount() const {
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<int32>(entries_.size());
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry,
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        net::CompletionCallback* callback) {
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_OPEN_FAILURE;
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EntryMap::iterator it = entries_.find(key);
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (it == entries_.end())
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_OPEN_FAILURE;
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (it->second->is_doomed()) {
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      it->second->Release();
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      entries_.erase(it);
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_OPEN_FAILURE;
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    open_count_++;
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    it->second->AddRef();
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *entry = it->second;
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (soft_failures_)
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      it->second->set_fail_requests();
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::OK;
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackLater(callback, net::OK);
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry,
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          net::CompletionCallback* callback) {
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (fail_requests_)
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::ERR_CACHE_CREATE_FAILURE;
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EntryMap::iterator it = entries_.find(key);
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (it != entries_.end()) {
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DCHECK(it->second->is_doomed());
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      it->second->Release();
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      entries_.erase(it);
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    create_count_++;
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MockDiskEntry* new_entry = new MockDiskEntry(key);
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    new_entry->AddRef();
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    entries_[key] = new_entry;
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    new_entry->AddRef();
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *entry = new_entry;
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (soft_failures_)
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new_entry->set_fail_requests();
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::OK;
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackLater(callback, net::OK);
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int DoomEntry(const std::string& key,
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        net::CompletionCallback* callback) {
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(callback);
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EntryMap::iterator it = entries_.find(key);
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (it != entries_.end()) {
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      it->second->Release();
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      entries_.erase(it);
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return net::OK;
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackLater(callback, net::OK);
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_IO_PENDING;
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int DoomAllEntries(net::CompletionCallback* callback) {
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_NOT_IMPLEMENTED;
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int DoomEntriesBetween(const base::Time initial_time,
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 const base::Time end_time,
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 net::CompletionCallback* callback) {
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_NOT_IMPLEMENTED;
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int DoomEntriesSince(const base::Time initial_time,
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                               net::CompletionCallback* callback) {
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_NOT_IMPLEMENTED;
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int OpenNextEntry(void** iter, disk_cache::Entry** next_entry,
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            net::CompletionCallback* callback) {
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return net::ERR_NOT_IMPLEMENTED;
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void EndEnumeration(void** iter) {}
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void GetStats(
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      std::vector<std::pair<std::string, std::string> >* stats) {
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // returns number of times a cache entry was successfully opened
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int open_count() const { return open_count_; }
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // returns number of times a cache entry was successfully created
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int create_count() const { return create_count_; }
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fail any subsequent CreateEntry and OpenEntry.
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_fail_requests() { fail_requests_ = true; }
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Return entries that fail some of their requests.
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_soft_failures(bool value) { soft_failures_ = value; }
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReleaseAll() {
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EntryMap::iterator it = entries_.begin();
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (; it != entries_.end(); ++it)
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      it->second->Release();
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entries_.clear();
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  typedef base::hash_map<std::string, MockDiskEntry*> EntryMap;
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  class CallbackRunner : public Task {
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CallbackRunner(net::CompletionCallback* callback, int result)
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        : callback_(callback), result_(result) {}
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    virtual void Run() {
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      callback_->Run(result_);
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   private:
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::CompletionCallback* callback_;
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int result_;
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DISALLOW_COPY_AND_ASSIGN(CallbackRunner);
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void CallbackLater(net::CompletionCallback* callback, int result) {
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop::current()->PostTask(FROM_HERE,
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                     new CallbackRunner(callback, result));
529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EntryMap entries_;
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int open_count_;
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int create_count_;
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool fail_requests_;
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool soft_failures_;
536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockBackendFactory : public net::HttpCache::BackendFactory {
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
5403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual int CreateBackend(net::NetLog*  /* net_log */,
5413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                            disk_cache::Backend** backend,
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::CompletionCallback* callback) {
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *backend = new MockDiskCache();
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::OK;
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockHttpCache {
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache()
5513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : http_cache_(new MockNetworkLayer(), NULL, new MockBackendFactory()) {
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory)
5553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : http_cache_(new MockNetworkLayer(), NULL, disk_cache_factory) {
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpCache* http_cache() { return &http_cache_; }
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockNetworkLayer* network_layer() {
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<MockNetworkLayer*>(http_cache_.network_layer());
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockDiskCache* disk_cache() {
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    disk_cache::Backend* backend;
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = http_cache_.GetBackend(&backend, &cb);
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rv = cb.GetResult(rv);
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return (rv == net::OK) ? static_cast<MockDiskCache*>(backend) : NULL;
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper function for reading response info from the disk cache.
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static bool ReadResponseInfo(disk_cache::Entry* disk_entry,
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               net::HttpResponseInfo* response_info,
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               bool* response_truncated) {
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int size = disk_entry->GetDataSize(0);
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
578513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size));
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = disk_entry->ReadData(0, 0, buffer, size, &cb);
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rv = cb.GetResult(rv);
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(size, rv);
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::HttpCache::ParseResponseInfo(buffer->data(), size,
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             response_info,
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             response_truncated);
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper function for writing response info into the disk cache.
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static bool WriteResponseInfo(disk_cache::Entry* disk_entry,
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const net::HttpResponseInfo* response_info,
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                bool skip_transient_headers,
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                bool response_truncated) {
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Pickle pickle;
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response_info->Persist(
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &pickle, skip_transient_headers, response_truncated);
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
598513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<net::WrappedIOBuffer> data(new net::WrappedIOBuffer(
599513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        reinterpret_cast<const char*>(pickle.data())));
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int len = static_cast<int>(pickle.size());
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv =  disk_entry->WriteData(0, 0, data, len, &cb, true);
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rv = cb.GetResult(rv);
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return (rv == len);
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper function to synchronously open a backend entry.
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry) {
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = disk_cache()->OpenEntry(key, entry, &cb);
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return (cb.GetResult(rv) == net::OK);
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper function to synchronously create a backend entry.
6153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool CreateBackendEntry(const std::string& key, disk_cache::Entry** entry,
6163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                          net::NetLog*  /* net_log */) {
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = disk_cache()->CreateEntry(key, entry, &cb);
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return (cb.GetResult(rv) == net::OK);
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpCache http_cache_;
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This version of the disk cache doesn't invoke CreateEntry callbacks.
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockDiskCacheNoCB : public MockDiskCache {
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry,
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::CompletionCallback* callback) {
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::ERR_IO_PENDING;
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockBackendNoCbFactory : public net::HttpCache::BackendFactory {
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
6363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual int CreateBackend(net::NetLog*  /* net_log */,
6373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                            disk_cache::Backend** backend,
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::CompletionCallback* callback) {
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *backend = new MockDiskCacheNoCB();
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::OK;
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This backend factory allows us to control the backend instantiation.
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockBlockingBackendFactory : public net::HttpCache::BackendFactory {
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockBlockingBackendFactory()
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : backend_(NULL), callback_(NULL), block_(true), fail_(false) {}
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual int CreateBackend(net::NetLog*  /* net_log */,
6513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                            disk_cache::Backend** backend,
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            net::CompletionCallback* callback) {
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!block_) {
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!fail_)
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *backend = new MockDiskCache();
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return Result();
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_ =  backend;
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_ = callback;
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::ERR_IO_PENDING;
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Completes the backend creation. Any blocked call will be notified via the
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // provided callback.
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FinishCreation() {
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    block_ = false;
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (callback_) {
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!fail_)
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *backend_ = new MockDiskCache();
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      net::CompletionCallback* cb = callback_;
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      callback_ = NULL;
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cb->Run(Result());  // This object can be deleted here.
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  disk_cache::Backend** backend() { return backend_; }
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_fail(bool fail) { fail_ = fail; }
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CompletionCallback* callback() { return callback_; }
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int Result() { return fail_ ? net::ERR_FAILED : net::OK; }
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  disk_cache::Backend** backend_;
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CompletionCallback* callback_;
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool block_;
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool fail_;
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
6913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass DeleteCacheCompletionCallback : public TestCompletionCallback {
6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : cache_(cache) {}
6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void RunWithParams(const Tuple1<int>& params) {
6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    delete cache_;
6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TestCompletionCallback::RunWithParams(params);
6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
7023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockHttpCache* cache_;
7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// helpers
707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ReadAndVerifyTransaction(net::HttpTransaction* trans,
709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              const MockTransaction& trans_info) {
710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string content;
711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = ReadTransaction(trans, &content);
712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected(trans_info.data);
715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected, content);
716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTransactionTestWithRequestAndLog(net::HttpCache* cache,
719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const MockTransaction& trans_info,
720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const MockHttpRequest& request,
721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         net::HttpResponseInfo* response_info,
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         const net::BoundNetLog& net_log) {
723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache->CreateTransaction(&trans);
729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(trans.get());
731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = trans->Start(&request, &callback, net_log);
733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = callback.WaitForResult();
735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::OK, rv);
736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const net::HttpResponseInfo* response = trans->GetResponseInfo();
738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(response);
739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (response_info)
741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *response_info = *response;
742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ReadAndVerifyTransaction(trans.get(), trans_info);
744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTransactionTestWithRequest(net::HttpCache* cache,
747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                   const MockTransaction& trans_info,
748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                   const MockHttpRequest& request,
749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                   net::HttpResponseInfo* response_info) {
750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithRequestAndLog(cache, trans_info, request,
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      response_info, net::BoundNetLog());
752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTransactionTestWithLog(net::HttpCache* cache,
755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                               const MockTransaction& trans_info,
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               const net::BoundNetLog& log) {
757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithRequestAndLog(
758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache, trans_info, MockHttpRequest(trans_info), NULL, log);
759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTransactionTest(net::HttpCache* cache,
762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        const MockTransaction& trans_info) {
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithLog(cache, trans_info, net::BoundNetLog());
764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTransactionTestWithResponseInfo(net::HttpCache* cache,
767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                        const MockTransaction& trans_info,
768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                        net::HttpResponseInfo* response) {
769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithRequest(
770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache, trans_info, MockHttpRequest(trans_info), response);
771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTransactionTestWithResponse(net::HttpCache* cache,
774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    const MockTransaction& trans_info,
775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    std::string* response_headers) {
776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponseInfo(cache, trans_info, &response);
778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response.headers->GetNormalizedHeaders(response_headers);
779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class provides a handler for kFastNoStoreGET_Transaction so that the
782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// no-store header can be included on demand.
783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass FastTransactionServer {
784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  FastTransactionServer() {
786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    no_store = false;
787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~FastTransactionServer() {}
789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_no_store(bool value) { no_store = value; }
791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void FastNoStoreHandler(const net::HttpRequestInfo* request,
793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 std::string* response_status,
794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 std::string* response_headers,
795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 std::string* response_data) {
796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (no_store)
797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      *response_headers = "Cache-Control: no-store\n";
798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool no_store;
802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FastTransactionServer::no_store;
805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst MockTransaction kFastNoStoreGET_Transaction = {
807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "http://www.google.com/nostore",
808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "GET",
809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::Time(),
810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "",
811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::LOAD_VALIDATE_CACHE,
812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "HTTP/1.1 200 OK",
813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "Cache-Control: max-age=10000\n",
814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::Time(),
815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "<html><body>Google Blah Blah</body></html>",
816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TEST_MODE_SYNC_NET_START,
817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  &FastTransactionServer::FastNoStoreHandler,
818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  0
819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class provides a handler for kRangeGET_TransactionOK so that the range
822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// request can be served on demand.
823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RangeTransactionServer {
824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer() {
826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    not_modified_ = false;
827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    modified_ = false;
828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bad_200_ = false;
829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~RangeTransactionServer() {
831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    not_modified_ = false;
832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    modified_ = false;
833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bad_200_ = false;
834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns only 416 or 304 when set.
837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_not_modified(bool value) { not_modified_ = value; }
838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns 206 when revalidating a range (instead of 304).
840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_modified(bool value) { modified_ = value; }
841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns 200 instead of 206 (a malformed response overall).
843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_bad_200(bool value) { bad_200_ = value; }
844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void RangeHandler(const net::HttpRequestInfo* request,
846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           std::string* response_status,
847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           std::string* response_headers,
848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           std::string* response_data);
849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool not_modified_;
852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool modified_;
853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool bad_200_;
854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RangeTransactionServer::not_modified_ = false;
857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RangeTransactionServer::modified_ = false;
858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RangeTransactionServer::bad_200_ = false;
859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A dummy extra header that must be preserved on a given request.
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define EXTRA_HEADER "Extra: header"
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kExtraHeaderKey[] = "Extra";
863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Static.
865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          std::string* response_status,
867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          std::string* response_headers,
868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          std::string* response_data) {
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (request->extra_headers.IsEmpty()) {
870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    response_data->clear();
872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We want to make sure we don't delete extra headers.
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (not_modified_) {
879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    response_status->assign("HTTP/1.1 304 Not Modified");
880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    response_data->clear();
881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<net::HttpByteRange> ranges;
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string range_header;
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!request->extra_headers.GetHeader(
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          net::HttpRequestHeaders::kRange, &range_header) ||
888dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
889dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ranges.size() != 1) {
890dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // This is not a byte range request. We return 200.
891dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    response_status->assign("HTTP/1.1 200 OK");
892dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
893dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    response_data->assign("Not a range");
894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
895dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
896dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We can handle this range request.
898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpByteRange byte_range = ranges[0];
899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (byte_range.first_byte_position() > 79) {
900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    response_data->clear();
902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(byte_range.ComputeBounds(80));
906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int start = static_cast<int>(byte_range.first_byte_position());
907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int end = static_cast<int>(byte_range.last_byte_position());
908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_LT(end, 80);
910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string content_range = base::StringPrintf(
9123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "Content-Range: bytes %d-%d/80\n", start, end);
913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_headers->append(content_range);
914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string data;
917dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (end == start) {
918dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      EXPECT_EQ(0, end % 10);
919dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      data = "r";
920dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    } else {
921dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      EXPECT_EQ(9, (end - start) % 10);
922dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      for (int block_start = start; block_start < end; block_start += 10) {
923dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        base::StringAppendF(&data, "rg: %02d-%02d ",
924dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                            block_start, block_start + 9);
925dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
9264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *response_data = data;
928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (end - start != 9) {
930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // We also have to fix content-length.
931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      int len = end - start + 1;
9323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      std::string content_length = base::StringPrintf("Content-Length: %d\n",
9333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                      len);
934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      response_headers->replace(response_headers->find("Content-Length:"),
935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                content_length.size(), content_length);
936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    response_status->assign("HTTP/1.1 304 Not Modified");
939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    response_data->clear();
940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst MockTransaction kRangeGET_TransactionOK = {
944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "http://www.google.com/range",
945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "GET",
946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::Time(),
947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "Range: bytes = 40-49\r\n"
948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXTRA_HEADER,
949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::LOAD_NORMAL,
950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "HTTP/1.1 206 Partial Content",
951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "ETag: \"foo\"\n"
953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "Accept-Ranges: bytes\n"
954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "Content-Length: 10\n",
955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::Time(),
956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  "rg: 40-49 ",
957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TEST_MODE_NORMAL,
958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  &RangeTransactionServer::RangeHandler,
959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  0
960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verifies the response headers (|response|) match a partial content
963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// response for the range starting at |start| and ending at |end|.
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Verify206Response(std::string response, int start, int end) {
965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                            response.size()));
967513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::HttpResponseHeaders> headers(
968513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      new net::HttpResponseHeaders(raw_headers));
969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(206, headers->response_code());
971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int64 range_start, range_end, object_size;
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      headers->GetContentRange(&range_start, &range_end, &object_size));
975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int64 content_length = headers->GetContentLength();
976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int length = end - start + 1;
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(length, content_length);
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(start, range_start);
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(end, range_end);
981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
983dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Creates a truncated entry that can be resumed using byte ranges.
984dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
985dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Create a disk cache entry that stores an incomplete resource.
986dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  disk_cache::Entry* entry;
987dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
988dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                        NULL));
989dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
990dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
991dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                  raw_headers.size());
992dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
993dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::HttpResponseInfo response;
994dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response.response_time = base::Time::Now();
995dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response.request_time = base::Time::Now();
996dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response.headers = new net::HttpResponseHeaders(raw_headers);
997dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Set the last argument for this to be an incomplete request.
998dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
999dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1000dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
1001dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int len = static_cast<int>(base::strlcpy(buf->data(),
1002dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                           "rg: 00-09 rg: 10-19 ", 100));
1003dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TestCompletionCallback cb;
1004dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int rv = entry->WriteData(1, 0, buf, len, &cb, true);
1005dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(len, cb.GetResult(rv));
1006dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  entry->Close();
1007dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1008dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Helper to represent a network HTTP response.
1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Response {
1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set this response into |trans|.
1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AssignTo(MockTransaction* trans) const {
1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    trans->status = status;
1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    trans->response_headers = headers;
1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    trans->data = body;
1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string status_and_headers() const {
1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return std::string(status) + "\n" + std::string(headers);
1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* status;
1023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* headers;
1024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* body;
1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Context {
1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context() : result(net::ERR_IO_PENDING) {}
1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result;
1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// tests
1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, CreateThenDestroy) {
1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&trans);
1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(trans.get());
1048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GetBackend) {
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  disk_cache::Backend* backend;
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback cb;
1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This will lazily initialize the backend.
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = cache.http_cache()->GetBackend(&backend, &cb);
1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::OK, cb.GetResult(rv));
1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET) {
1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGETNoDiskCache) {
1072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cache.disk_cache()->set_fail_requests();
1075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
10773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  log.SetLogLevel(net::NetLog::LOG_BASIC);
1078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Read from the network, and don't use the cache.
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            log.bound());
1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the NetLog was filled as expected.
1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (We attempted to both Open and Create entries, but both failed).
108521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
108621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
108721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
108821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(6u, entries.size());
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
10903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
10923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
109421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
109621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
109821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
110021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
1105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, SimpleGETNoDiskCache2) {
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This will initialize a cache object with NULL backend.
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  factory->set_fail(true);
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  factory->FinishCreation();  // We'll complete synchronously.
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(factory);
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Read from the network, and don't use the cache.
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGETWithDiskFailures) {
1122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cache.disk_cache()->set_soft_failures(true);
1125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Read from the network, and fail to write to the cache.
1127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This one should see an empty cache again.
1134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that disk failures after the transaction has started don't cause the
1142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// request to fail.
1143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGETWithDiskFailures2) {
1144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<Context> c(new Context());
1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->callback.WaitForResult();
1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start failing request now.
1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cache.disk_cache()->set_soft_failures(true);
1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We have to open the entry again to propagate the failure flag.
1160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* en;
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
1162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  en->Close();
1163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c.reset();
1166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This one should see an empty cache again.
1172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests that we don't crash after failures to read from the cache.
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST(HttpCache, SimpleGETWithDiskFailures3) {
1181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockHttpCache cache;
1182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Read from the network, and write to the cache.
1184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, cache.disk_cache()->open_count());
1188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, cache.disk_cache()->create_count());
1189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  cache.disk_cache()->set_soft_failures(true);
1191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now fail to read from the cache.
1193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<Context> c(new Context());
1194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int rv = cache.http_cache()->CreateTransaction(&c->trans);
1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(net::OK, rv);
1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockHttpRequest request(kSimpleGET_Transaction);
1198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(net::ERR_CACHE_READ_FAILURE, c->callback.GetResult(rv));
1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // This prevents a number of write events from being logged.
12083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  log.SetLogLevel(net::NetLog::LOG_BASIC);
12093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            log.bound());
1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the NetLog was filled as expected.
121521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
121621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
121721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
121821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(8u, entries.size());
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
12203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
12223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
122421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
122621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
122821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
123021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
12323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
12343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to read from the cache
1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
1239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  log.Clear();
1241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
1243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the NetLog was filled as expected.
124521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
124621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
124721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(8u, entries.size());
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
12493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
12513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
125321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
125521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
12573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
12593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsBeginEvent(
126121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(net::LogContainsEndEvent(
126321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to read from the cache
1274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
1276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
1278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
1279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
1281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&trans);
1282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
1283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(trans.get());
1284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = trans->Start(&request, &callback, net::BoundNetLog());
1286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
1287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = callback.WaitForResult();
1288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
1289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.reset();
1291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
1295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
1298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to read from the cache if valid
1304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
1306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
1315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to read from the cache if valid
1318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
1320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadBypassCache) {
1329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write to the cache.
1332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Force this transaction to write to the cache again.
1335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // This prevents a number of write events from being logged.
13413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  log.SetLogLevel(net::NetLog::LOG_BASIC);
13423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
1344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the NetLog was filled as expected.
134621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
134721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
134821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
134921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(8u, entries.size());
1350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
13513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
13533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
135521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
135721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
135921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
136121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsBeginEvent(
13633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(net::LogContainsEndEvent(
13653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to write to the cache again
1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "pragma: no-cache";
1381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to write to the cache again
1396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "cache-control: no-cache";
1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadValidateCache) {
1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // read from the cache
1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to validate the cache
1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // read from the cache
1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to validate the cache
1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "cache-control: max-age=0";
1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void PreserveRequestHeaders_Handler(
1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const net::HttpRequestInfo* request,
1448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_status,
1449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_headers,
1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_data) {
1451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we don't remove extra headers for simple requests.
1455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
1459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = PreserveRequestHeaders_Handler;
1460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = EXTRA_HEADER;
1461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = "Cache-Control: max-age=0\n";
1462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
1463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write, then revalidate the entry.
1465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
1472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we don't remove extra headers for conditionalized requests.
1475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache.
1479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kETagGET_Transaction);
1482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = PreserveRequestHeaders_Handler;
1483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                EXTRA_HEADER;
1485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
1486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
1488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
1491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
1493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_ManyReaders) {
1496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<Context*> context_list;
1501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 5;
1502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All requests are waiting for the active entry.
1515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; ++i) {
1516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Context* c = context_list[i];
1517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Allow all requests to move from the Create queue to the active entry.
1521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be a writer at this point, and the subsequent
1524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requests should be pending.
1525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All requests depend on the writer, and the writer is between Start and
1531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Read, i.e. idle.
1532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; ++i) {
1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Context* c = context_list[i];
1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (c->result == net::ERR_IO_PENDING)
1540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      c->result = c->callback.WaitForResult();
1541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We should not have had to re-open the disk entry
1545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete c;
1553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If cancelling a request is racing with another request for the same resource
1558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// finishing, we have to make sure that we remove both transactions from the
1559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// entry.
1560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_RacingReaders) {
1561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest reader_request(kSimpleGET_Transaction);
1565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<Context*> context_list;
1568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 5;
1569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MockHttpRequest* this_request = &request;
1578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (i == 1 || i == 2)
1579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      this_request = &reader_request;
1580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(this_request, &c->callback, net::BoundNetLog());
1582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Allow all requests to move from the Create queue to the active entry.
1585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be a writer at this point, and the subsequent
1588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requests should be pending.
1589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = context_list[0];
1595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c->result = c->callback.WaitForResult();
1597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now we have 2 active readers and two queued transactions.
1600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::LOAD_STATE_IDLE,
1602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            context_list[2]->trans->GetLoadState());
1603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            context_list[3]->trans->GetLoadState());
1605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c = context_list[1];
1607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c->result = c->callback.WaitForResult();
1609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (c->result == net::OK)
1610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point we have one reader, two pending transactions and a task on
1613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the queue to move to the next transaction. Now we cancel the request that
1614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is the current reader, and expect the queued task to be able to start the
1615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // next request.
1616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c = context_list[2];
1618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c->trans.reset();
1619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 3; i < kNumTransactions; ++i) {
1621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (c->result == net::ERR_IO_PENDING)
1623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      c->result = c->callback.WaitForResult();
1624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (c->result == net::OK)
1625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We should not have had to re-open the disk entry.
1629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete c;
1637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can doom an entry with pending transactions and delete one of
1641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the pending transactions before the first one completes.
1642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// See http://code.google.com/p/chromium/issues/detail?id=25588
1643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_DoomWithPending) {
1644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest writer_request(kSimpleGET_Transaction);
1649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedVector<Context> context_list;
1652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 4;
1653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MockHttpRequest* this_request = &request;
1662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (i == 3)
1663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      this_request = &writer_request;
1664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(this_request, &c->callback, net::BoundNetLog());
1666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be a writer at this point, and the two subsequent
1669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requests should be pending. The last request doomed the first entry.
1670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel the first queued transaction.
1674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete context_list[1];
1675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  context_list.get()[1] = NULL;
1676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (i == 1)
1679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      continue;
1680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = c->callback.WaitForResult();
1683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We may attempt to delete an entry synchronously with the act of adding a new
1689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// transaction to said entry.
1690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The headers will be served right from the call to Start() the request.
1694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kFastNoStoreGET_Transaction);
1695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  FastTransactionServer request_handler;
1696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kFastNoStoreGET_Transaction);
1697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<Context*> context_list;
1699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 3;
1700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Allow all requests to move from the Create queue to the active entry.
1712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be a writer at this point, and the subsequent
1715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requests should be pending.
1716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now, make sure that the second request asks for the entry not to be stored.
1722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request_handler.set_no_store(true);
1723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (c->result == net::ERR_IO_PENDING)
1727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      c->result = c->callback.WaitForResult();
1728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete c;
1730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
1733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<Context*> context_list;
1745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 2;
1746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Allow all requests to move from the Create queue to the active entry.
1758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be a writer at this point, and the subsequent
1761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requests should be pending.
1762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (c->result == net::ERR_IO_PENDING)
1770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      c->result = c->callback.WaitForResult();
1771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Destroy only the first transaction.
1772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (i == 0) {
1773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete c;
1774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      context_list[i] = NULL;
1775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the rest of the transactions.
1779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 1; i < kNumTransactions; ++i) {
1780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We should have had to re-open the disk entry.
1785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 1; i < kNumTransactions; ++i) {
1791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete c;
1793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can cancel requests that are queued waiting to open the disk
1797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cache entry.
1798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<Context*> context_list;
1804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 5;
1805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; i++) {
1807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be creating the disk cache entry and the others
1817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // should be pending.
1818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
1822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel a request from the pending queue.
1824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete context_list[3];
1825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  context_list[3] = NULL;
1826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel the request that is creating the entry. This will force the pending
1828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // operations to restart.
1829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete context_list[0];
1830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  context_list[0] = NULL;
1831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the rest of the transactions.
1833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 1; i < kNumTransactions; i++) {
1834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (c) {
1836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      c->result = c->callback.GetResult(c->result);
1837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We should have had to re-create the disk entry.
1842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
1846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 1; i < kNumTransactions; ++i) {
1848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete context_list[i];
1849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can cancel a single request to open a disk cache entry.
1853c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, SimpleGET_CancelCreate) {
1854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache;
1855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request(kSimpleGET_Transaction);
1857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Context* c = new Context();
1859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c->result = cache.http_cache()->CreateTransaction(&c->trans);
1861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::OK, c->result);
1862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Release the reference that the mock disk cache keeps for this entry, so
1867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that we test that the http cache handles the cancelation correctly.
1868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.disk_cache()->ReleaseAll();
1869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete c;
1870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
1872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
1873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we delete/create entries even if multiple requests are queued.
1876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.load_flags = net::LOAD_BYPASS_CACHE;
1881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<Context*> context_list;
1883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumTransactions = 5;
1884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; i++) {
1886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    context_list.push_back(new Context());
1887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = cache.http_cache()->CreateTransaction(&c->trans);
1890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, c->result);
1891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should be deleting the disk cache entry and the others
1896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // should be pending.
1897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
1901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the transactions.
1903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; i++) {
1904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Context* c = context_list[i];
1905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = c->callback.GetResult(c->result);
1906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We should have had to re-create the disk entry multiple times.
1910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, cache.network_layer()->transaction_count());
1912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
1913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, cache.disk_cache()->create_count());
1914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumTransactions; ++i) {
1916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete context_list[i];
1917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
1922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
1924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
1927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
1928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
1930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&trans);
1931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
1932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = trans->Start(&request, &callback, net::BoundNetLog());
1933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
1934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = callback.WaitForResult();
1935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::OK, rv);
1936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1937513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = trans->Read(buf, 256, &callback);
1939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test that destroying the transaction while it is reading from the cache
1942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // works properly.
1943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.reset();
1944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we pump any pending events, which should include a call to
1946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // HttpCache::Transaction::OnCacheReadCompleted.
1947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can delete the HttpCache and deal with queued transactions
1951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ("waiting for the backend" as opposed to Active or Doomed entries).
1952c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      new MockBackendNoCbFactory()));
1955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request(kSimpleGET_Transaction);
1957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<Context*> context_list;
1959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kNumTransactions = 5;
1960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; i++) {
1962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_list.push_back(new Context());
1963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Context* c = context_list[i];
1964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = cache->http_cache()->CreateTransaction(&c->trans);
1966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(net::OK, c->result);
1967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The first request should be creating the disk cache entry and the others
1972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be pending.
1973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, cache->network_layer()->transaction_count());
1975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, cache->disk_cache()->open_count());
1976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, cache->disk_cache()->create_count());
1977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.reset();
1979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There is not much to do with the transactions at this point... they are
1981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // waiting for a callback that will not fire.
1982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; ++i) {
1983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete context_list[i];
1984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we queue requests when initializing the backend.
1988c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, SimpleGET_WaitForBackend) {
1989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(factory);
1991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request0(kSimpleGET_Transaction);
1993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request1(kTypicalGET_Transaction);
1994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request2(kETagGET_Transaction);
1995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<Context*> context_list;
1997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kNumTransactions = 3;
1998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; i++) {
2000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_list.push_back(new Context());
2001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Context* c = context_list[i];
2002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = cache.http_cache()->CreateTransaction(&c->trans);
2004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(net::OK, c->result);
2005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[0]->result = context_list[0]->trans->Start(
2008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &request0, &context_list[0]->callback, net::BoundNetLog());
2009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[1]->result = context_list[1]->trans->Start(
2010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &request1, &context_list[1]->callback, net::BoundNetLog());
2011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[2]->result = context_list[2]->trans->Start(
2012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &request2, &context_list[2]->callback, net::BoundNetLog());
2013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Just to make sure that everything is still pending.
2015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The first request should be creating the disk cache.
2018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(context_list[0]->callback.have_result());
2019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  factory->FinishCreation();
2021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, cache.disk_cache()->create_count());
2025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; ++i) {
2027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(context_list[i]->callback.have_result());
2028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete context_list[i];
2029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can cancel requests that are queued waiting for the backend
2033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to be initialized.
2034c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
2035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(factory);
2037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request0(kSimpleGET_Transaction);
2039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request1(kTypicalGET_Transaction);
2040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request2(kETagGET_Transaction);
2041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<Context*> context_list;
2043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kNumTransactions = 3;
2044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kNumTransactions; i++) {
2046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_list.push_back(new Context());
2047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Context* c = context_list[i];
2048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    c->result = cache.http_cache()->CreateTransaction(&c->trans);
2050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(net::OK, c->result);
2051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[0]->result = context_list[0]->trans->Start(
2054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &request0, &context_list[0]->callback, net::BoundNetLog());
2055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[1]->result = context_list[1]->trans->Start(
2056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &request1, &context_list[1]->callback, net::BoundNetLog());
2057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[2]->result = context_list[2]->trans->Start(
2058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &request2, &context_list[2]->callback, net::BoundNetLog());
2059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Just to make sure that everything is still pending.
2061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The first request should be creating the disk cache.
2064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(context_list[0]->callback.have_result());
2065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel a request from the pending queue.
2067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete context_list[1];
2068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[1] = NULL;
2069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel the request that is creating the entry.
2071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete context_list[0];
2072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[0] = NULL;
2073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Complete the last transaction.
2075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  factory->FinishCreation();
2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_list[2]->result =
2078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      context_list[2]->callback.GetResult(context_list[2]->result);
2079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
2080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
2083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete context_list[2];
2085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can delete the cache while creating the backend.
2088c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, DeleteCacheWaitingForBackend) {
2089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
2091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpRequest request(kSimpleGET_Transaction);
2093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Context> c(new Context());
2095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c->result = cache->http_cache()->CreateTransaction(&c->trans);
2096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::OK, c->result);
2097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c->trans->Start(&request, &c->callback, net::BoundNetLog());
2099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Just to make sure that everything is still pending.
2101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The request should be creating the disk cache.
2104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(c->callback.have_result());
2105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We cannot call FinishCreation because the factory itself will go away with
2107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the cache, so grab the callback and attempt to use it.
2108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CompletionCallback* callback = factory->callback();
21093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  disk_cache::Backend** backend = factory->backend();
2110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.reset();
2112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  *backend = NULL;
2115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  callback->Run(net::ERR_ABORTED);
2116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Tests that we can delete the cache while creating the backend, from within
21193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// one of the callbacks.
21203345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST(HttpCache, DeleteCacheWaitingForBackend2) {
21213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
21223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockHttpCache* cache = new MockHttpCache(factory);
21233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DeleteCacheCompletionCallback cb(cache);
21253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  disk_cache::Backend* backend;
21263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = cache->http_cache()->GetBackend(&backend, &cb);
21273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(net::ERR_IO_PENDING, rv);
21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Now let's queue a regular transaction
21303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockHttpRequest request(kSimpleGET_Transaction);
21313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<Context> c(new Context());
21333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  c->result = cache->http_cache()->CreateTransaction(&c->trans);
21343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(net::OK, c->result);
21353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  c->trans->Start(&request, &c->callback, net::BoundNetLog());
21373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And another direct backend request.
21393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback cb2;
21403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = cache->http_cache()->GetBackend(&backend, &cb2);
21413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(net::ERR_IO_PENDING, rv);
21423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Just to make sure that everything is still pending.
21443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop::current()->RunAllPending();
21453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The request should be queued.
21473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(c->callback.have_result());
21483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Generate the callback.
21503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  factory->FinishCreation();
21513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = cb.WaitForResult();
21523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The cache should be gone by now.
21543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop::current()->RunAllPending();
21553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
21563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(cb2.have_result());
21573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
21583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, TypicalGET_ConditionalRequest) {
2160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
2163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
2164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // get the same URL again, but this time we expect it to result
2170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // in a conditional request.
2171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
2172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void ETagGet_ConditionalRequest_Handler(
2179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const net::HttpRequestInfo* request,
2180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_status,
2181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_headers,
2182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_data) {
2183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(
2184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_status->assign("HTTP/1.1 304 Not Modified");
2186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_headers->assign(kETagGET_Transaction.response_headers);
2187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_data->clear();
2188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ETagGET_ConditionalRequest_304) {
2191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction(kETagGET_Transaction);
2194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
2196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // get the same URL again, but this time we expect it to result
2203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // in a conditional request.
2204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = ETagGet_ConditionalRequest_Handler;
2206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void ETagGet_ConditionalRequest_NoStore_Handler(
2214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const net::HttpRequestInfo* request,
2215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_status,
2216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_headers,
2217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string* response_data) {
2218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(
2219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_status->assign("HTTP/1.1 304 Not Modified");
2221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_headers->assign("Cache-Control: no-store\n");
2222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_data->clear();
2223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction(kETagGET_Transaction);
2229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache.
2231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the same URL again, but this time we expect it to result
2238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // in a conditional request.
2239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction2(kETagGET_Transaction);
2248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache again. This should create a new entry.
2250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction2);
2251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
2255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimplePOST_SkipsCache) {
2258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test that we skip the cache for POST requests that do not have an upload
2261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // identifier.
2262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Helper that does 4 requests using HttpCache:
2271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
2272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     be returned.
2276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     returned.
2278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void ConditionalizedRequestUpdatesCacheHelper(
2279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const Response& net_response_1,
2280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const Response& net_response_2,
2281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const Response& cached_response_2,
2282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* extra_request_headers) {
2283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The URL we will be requesting.
2286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kUrl = "http://foobar.com/main.css";
2287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Junk network response.
2289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kUnexpectedResponse = {
2290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 500 Unexpected",
2291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Server: unexpected_header",
2292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "unexpected body"
2293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We will control the network layer's responses for |kUrl| using
2296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |mock_network_response|.
2297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction mock_network_response = { 0 };
2298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mock_network_response.url = kUrl;
2299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&mock_network_response);
2300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request |kUrl| for the first time. It should hit the network and
2302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // receive |kNetResponse1|, which it saves into the HTTP cache.
2303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction request = { 0 };
2305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.url = kUrl;
2306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.method = "GET";
2307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.request_headers = "";
2308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net_response_1.AssignTo(&mock_network_response);  // Network mock.
2310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net_response_1.AssignTo(&request);                // Expected result.
2311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string response_headers;
2313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(
2314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache.http_cache(), request, &response_headers);
2315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // cache, so we don't hit the network.
2323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net_response_1.AssignTo(&request);                     // Expected result.
2328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(
2330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache.http_cache(), request, &response_headers);
2331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request |kUrl| yet again, but this time give the request an
2338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // "If-Modified-Since" header. This will cause the request to re-hit the
2339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // network. However now the network response is going to be
2340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // different -- this simulates a change made to the CSS file.
2341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.request_headers = extra_request_headers;
2343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.load_flags = net::LOAD_NORMAL;
2344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net_response_2.AssignTo(&mock_network_response);  // Network mock.
2346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net_response_2.AssignTo(&request);                // Expected result.
2347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(
2349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache.http_cache(), request, &response_headers);
2350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Finally, request |kUrl| again. This request should be serviced from
2357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the cache. Moreover, the value in the cache should be |kNetResponse2|
2358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and NOT |kNetResponse1|. The previous step should have replaced the
2359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // value in the cache with the modified response.
2360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.request_headers = "";
2362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cached_response_2.AssignTo(&request);                  // Expected result.
2366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(
2368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache.http_cache(), request, &response_headers);
2369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->open_count());
2373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&mock_network_response);
2376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check that when an "if-modified-since" header is attached
2379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to the request, the result still updates the cached entry.
2380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First network response for |kUrl|.
2382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body2"
2395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* extra_headers =
2398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check that when an "if-none-match" header is attached
2405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to the request, the result updates the cached entry.
2406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First network response for |kUrl|.
2408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"ETAG1\"\n"
2412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"ETAG2\"\n"
2421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body2"
2423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* extra_headers = "If-None-Match: \"ETAG1\"\n";
2426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check that when an "if-modified-since" header is attached
2432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to a request, the 304 (not modified result) result updates the cached
2433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// headers, and the 304 response is returned rather than the cached response.
2434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First network response for |kUrl|.
2436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Server: server1\n"
2440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 304 Not Modified",
2447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Server: server2\n"
2449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ""
2451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kCachedResponse2 = {
2454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Server: server2\n"
2457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* extra_headers =
2462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that when doing an externally conditionalized if-modified-since
2469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and there is no corresponding cache entry, a new cache entry is NOT
2470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// created (304 response).
2471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kUrl = "http://foobar.com/main.css";
2475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse = {
2477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 304 Not Modified",
2478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ""
2481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
2485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We will control the network layer's responses for |kUrl| using
2487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |mock_network_response|.
2488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction mock_network_response = { 0 };
2489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mock_network_response.url = kUrl;
2490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&mock_network_response);
2491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction request = { 0 };
2493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.url = kUrl;
2494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.method = "GET";
2495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.request_headers = kExtraRequestHeaders;
2496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kNetResponse.AssignTo(&request);                // Expected result.
2499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string response_headers;
2501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(
2502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache.http_cache(), request, &response_headers);
2503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&mock_network_response);
2510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that when doing an externally conditionalized if-modified-since
2513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and there is no corresponding cache entry, a new cache entry is NOT
2514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// created (200 response).
2515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kUrl = "http://foobar.com/main.css";
2519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse = {
2521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "foobar!!!"
2525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
2529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We will control the network layer's responses for |kUrl| using
2531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |mock_network_response|.
2532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction mock_network_response = { 0 };
2533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mock_network_response.url = kUrl;
2534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&mock_network_response);
2535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction request = { 0 };
2537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.url = kUrl;
2538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.method = "GET";
2539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.request_headers = kExtraRequestHeaders;
2540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kNetResponse.AssignTo(&request);                // Expected result.
2543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string response_headers;
2545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(
2546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      cache.http_cache(), request, &response_headers);
2547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&mock_network_response);
2554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that when doing an externally conditionalized if-modified-since
2557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// if the date does not match the cache entry's last-modified date,
2558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// then we do NOT use the response (304) to update the cache.
2559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (the if-modified-since date is 2 days AFTER the cache's modification date).
2560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Server: server1\n"
2565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 304 Not Modified",
2572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Server: server2\n"
2574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ""
2576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This is two days in the future from the original response's last-modified
2579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // date!
2580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n";
2582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that when doing an externally conditionalized if-none-match
2588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// if the etag does not match the cache entry's etag, then we do not use the
2589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// response (304) to update the cache.
2590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo1\"\n"
2595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 304 Not Modified",
2602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo2\"\n"
2604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ""
2606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Different etag from original response.
2609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\n";
2610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that doing an externally conditionalized request with both if-none-match
2616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and if-modified-since updates the cache.
2617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo1\"\n"
2622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo2\"\n"
2631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body2"
2633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-None-Match: \"Foo1\"\r\n";
2638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that doing an externally conditionalized request with both if-none-match
2644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and if-modified-since does not update the cache with only one match.
2645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo1\"\n"
2650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo2\"\n"
2659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body2"
2661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The etag doesn't match what we have stored.
2664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"
2666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-None-Match: \"Foo2\"\n";
2667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that doing an externally conditionalized request with both if-none-match
2673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and if-modified-since does not update the cache with only one match.
2674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo1\"\n"
2679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo2\"\n"
2688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body2"
2690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The modification date doesn't match what we have stored.
2693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n"
2695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-None-Match: \"Foo1\"\n";
2696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that doing an externally conditionalized request with two conflicting
2702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// headers does not update the cache.
2703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ConditionalizedRequestUpdatesCache11) {
2704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
2705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo1\"\n"
2708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body1"
2710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Second network response for |kUrl|.
2713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
2714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
2715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Etag: \"Foo2\"\n"
2717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "body2"
2719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
2720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Two dates, the second matches what we have stored.
2722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kExtraRequestHeaders =
2723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Mon, 04 Feb 2008 22:38:21 GMT\n"
2724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ConditionalizedRequestUpdatesCacheHelper(
2727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, UrlContainingHash) {
2731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Do a typical GET request -- should write an entry into our cache.
2734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction trans(kTypicalGET_Transaction);
2735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), trans);
2736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request the same URL, but this time with a reference section (hash).
2742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Since the cache key strips the hash sections, this should be a cache hit.
2743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.url = url_with_hash.c_str();
2745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), trans);
2748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test that we skip the cache for POST requests.  Eventually, we will want
2758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to cache these, but we'll still have cases where skipping the cache makes
2759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // sense, so we want to make sure that it works properly.
2760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimplePOST_Transaction);
2762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
2765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
2766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
2768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&trans);
2769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
2770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(trans.get());
2771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = trans->Start(&request, &callback, net::BoundNetLog());
2773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
2774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = callback.WaitForResult();
2775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
2776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.reset();
2778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.network_layer()->transaction_count());
2780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test that we hit the cache for POST requests.
2788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimplePOST_Transaction);
2790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int64 kUploadId = 1;  // Just a dummy value.
2792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
2794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.upload_data = new net::UploadData();
2795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.upload_data->set_identifier(kUploadId);
2796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.upload_data->AppendBytes("hello", 5);
2797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Populate the cache.
2799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Load from cache.
2806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_SkipsCache) {
2815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test that we skip the cache for range GET requests.  Eventually, we will
2818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // want to cache these, but we'll still have cases where skipping the cache
2819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // makes sense, so we want to make sure that it works properly.
2820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
2822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
2828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "If-None-Match: foo";
2829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers =
2836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT";
2837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that we skip the cache for range requests that include a validation
2845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// header.
2846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_SkipsCache2) {
2847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_Transaction);
2850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.request_headers = "If-None-Match: foo\r\n"
2851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                EXTRA_HEADER
2852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                "\r\nRange: bytes = 40-49";
2853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers =
2860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
2861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      EXTRA_HEADER
2862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "\r\nRange: bytes = 40-49";
2863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.request_headers = "If-Range: bla\r\n"
2870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                EXTRA_HEADER
2871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                "\r\nRange: bytes = 40-49\n";
2872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
2877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that receiving 206 for a regular request is handled correctly.
2880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_Crazy206) {
2881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache.
2884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
2885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
2886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = EXTRA_HEADER;
2887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = NULL;
2888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This should read again from the net.
2895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
2896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
2900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
2901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests that we don't cache partial responses that can't be validated.
2904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST(HttpCache, RangeGET_NoStrongValidators) {
2905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockHttpCache cache;
2906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string headers;
2907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Attempt to write to the cache (40-49).
2909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockTransaction transaction(kRangeGET_TransactionOK);
2910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddMockTransaction(&transaction);
2911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  transaction.response_headers = "Content-Length: 10\n"
2912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 "ETag: w/\"foo\"\n";
2913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Verify206Response(headers, 40, 49);
2916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, cache.disk_cache()->open_count());
2918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, cache.disk_cache()->create_count());
2919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now verify that there's no cached data.
2921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 &headers);
2923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Verify206Response(headers, 40, 49);
2925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, cache.disk_cache()->open_count());
2927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, cache.disk_cache()->create_count());
2928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RemoveMockTransaction(&transaction);
2930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can cache range requests and fetch random blocks from the
2933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cache and the network.
2934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_OK) {
2935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
2937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
2938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
2940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
2942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
2944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
2946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Read from the cache (40-49).
2949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
2951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
2953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
2955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we are done with the previous transaction.
2958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
2959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (30-39).
2961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
2962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
2963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 30-39 ";
2964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 30, 39);
2967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->open_count());
2969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we are done with the previous transaction.
2972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
2973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write and read from the cache (20-59).
2975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
2976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
2977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 20, 59);
2980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, cache.network_layer()->transaction_count());
2981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.disk_cache()->open_count());
2982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
2983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
2985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can cache range requests and fetch random blocks from the
2988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cache and the network, with synchronous responses.
2989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_SyncOK) {
2990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
2991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
2993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.test_mode = TEST_MODE_SYNC_ALL;
2994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
2995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
2997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
2998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Read from the cache (40-49).
3006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we are done with the previous transaction.
3014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (30-39).
3017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 30-39 ";
3019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 30, 39);
3022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we are done with the previous transaction.
3027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write and read from the cache (20-59).
3030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 20, 59);
3035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->open_count());
3037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we don't revalidate an entry unless we are required to do so.
3043c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, RangeGET_Revalidate1) {
3044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache;
3045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string headers;
3046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write to the cache (40-49).
3048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTransaction transaction(kRangeGET_TransactionOK);
3049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.response_headers =
3050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
3052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "ETag: \"foo\"\n"
3053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Accept-Ranges: bytes\n"
3054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Content-Length: 10\n";
3055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMockTransaction(&transaction);
3056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, cache.disk_cache()->open_count());
3061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
3062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Read from the cache (40-49).
3064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->open_count());
3069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
3070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Read again forcing the revalidation.
3072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->open_count());
3078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
3079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RemoveMockTransaction(&transaction);
3081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Checks that we revalidate an entry when the headers say so.
3084c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, RangeGET_Revalidate2) {
3085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache;
3086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string headers;
3087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write to the cache (40-49).
3089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTransaction transaction(kRangeGET_TransactionOK);
3090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.response_headers =
3091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
3093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "ETag: \"foo\"\n"
3094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Accept-Ranges: bytes\n"
3095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Content-Length: 10\n";
3096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMockTransaction(&transaction);
3097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, cache.disk_cache()->open_count());
3102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
3103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Read from the cache (40-49).
3105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->open_count());
3110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
3111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RemoveMockTransaction(&transaction);
3113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we deal with 304s for range requests.
3116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_304) {
3117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
3122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Read from the cache (40-49).
3131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer handler;
3132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_not_modified(true);
3133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTransaction transaction(kRangeGET_TransactionOK);
3134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we deal with 206s when revalidating range requests.
3146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_ModifiedResult) {
3147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
3152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Attempt to read from the cache (40-49).
3161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer handler;
3162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_modified(true);
3163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTransaction transaction(kRangeGET_TransactionOK);
3164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // And the entry should be gone.
3173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
3177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can cache range requests when the start or end is unknown.
3182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We start with one suffix request, followed by a request from a given point.
3183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, UnknownRangeGET_1) {
3184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (70-79).
3189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 70-79 ";
3192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 70, 79);
3195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we are done with the previous transaction.
3200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write and read from the cache (60-79).
3203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
3204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 60-69 rg: 70-79 ";
3205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 60, 79);
3208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can cache range requests when the start or end is unknown.
3216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We start with one request from a given point, followed by a suffix request.
3217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We'll also verify that synchronous cache responses work as intended.
3218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, UnknownRangeGET_2) {
3219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
3224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          TEST_MODE_SYNC_CACHE_READ |
3225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          TEST_MODE_SYNC_CACHE_WRITE;
3226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (70-79).
3229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 70-79 ";
3231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 70, 79);
3234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we are done with the previous transaction.
3239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write and read from the cache (60-79).
3242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
3243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 60-69 rg: 70-79 ";
3244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 60, 79);
3247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that receiving Not Modified when asking for an open range doesn't mess
3255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// up things.
3256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, UnknownRangeGET_304) {
3257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer handler;
3264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_not_modified(true);
3265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Ask for the end of the file, without knowing the length.
3267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transaction.data = "";
3269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We just bypass the cache.
3272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
3278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
3279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle non-range requests when we have cached a range.
3284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_Previous206) {
3285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
3290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write and read from the cache (0-79), when not asked for a range.
3299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = EXTRA_HEADER;
3301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
3303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle non-range requests when we have cached the first
3314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// part of the object and the server replies with 304 (Not Modified).
3315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_Previous206_NotModified) {
3316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (0-9).
3323201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3324201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.data = "rg: 00-09 ";
3325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 0, 9);
3327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3328201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Write to the cache (70-79).
3329201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3330201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.data = "rg: 70-79 ";
3331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3332201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  Verify206Response(headers, 70, 79);
3333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, cache.disk_cache()->open_count());
3336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Read from the cache (0-9), write and read from cache (10 - 79).
3339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3340201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                      "rg: 50-59 rg: 60-69 rg: 70-79 ";
3343201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(2, cache.disk_cache()->open_count());
3348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle a regular request to a sparse entry, that results in
3354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// new content provided by the server (206).
3355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_Previous206_NewContent) {
3356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (0-9).
3361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 00-09 ";
3364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 0, 9);
3367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now we'll issue a request without any range that should result first in a
3372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // 206 (when revalidating), and then in a weird standard answer: the test
3373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // server will not modify the response so we'll get the default range... a
3374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // real server will answer with 200.
3375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction2(kRangeGET_TransactionOK);
3376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction2.request_headers = EXTRA_HEADER;
3377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
3378dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction2.data = "Not a range";
3379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer handler;
3380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_modified(true);
3381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3383dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that the previous request deleted the entry.
3389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
3390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
3391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle cached 206 responses that are not sparse.
3396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_Previous206_NotSparse) {
3397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Create a disk cache entry that stores 206 headers while not being sparse.
3400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
34013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
34023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                       NULL));
3403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers(kRangeGET_TransactionOK.status);
3405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  raw_headers.append("\n");
3406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  raw_headers.append(kRangeGET_TransactionOK.response_headers);
3407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                  raw_headers.size());
3409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
3411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response.headers = new net::HttpResponseHeaders(raw_headers);
3412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int len = static_cast<int>(base::strlcpy(buf->data(),
3416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           kRangeGET_TransactionOK.data, 500));
3417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback cb;
3418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = entry->WriteData(1, 0, buf, len, &cb, true);
3419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(len, cb.GetResult(rv));
3420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
3421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now see that we don't use the stored entry.
3423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We are expecting a 200.
3428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected_headers(kSimpleGET_Transaction.status);
3429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected_headers.append("\n");
3430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected_headers.append(kSimpleGET_Transaction.response_headers);
3431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected_headers, headers);
3432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
3435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle cached 206 responses that are not sparse. This time
3438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// we issue a range request and expect to receive a range.
3439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
3440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Create a disk cache entry that stores 206 headers while not being sparse.
3444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
34453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
34463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                       NULL));
3447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers(kRangeGET_TransactionOK.status);
3449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  raw_headers.append("\n");
3450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  raw_headers.append(kRangeGET_TransactionOK.response_headers);
3451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                  raw_headers.size());
3453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
3455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response.headers = new net::HttpResponseHeaders(raw_headers);
3456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int len = static_cast<int>(base::strlcpy(buf->data(),
3460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           kRangeGET_TransactionOK.data, 500));
3461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback cb;
3462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = entry->WriteData(1, 0, buf, len, &cb, true);
3463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(len, cb.GetResult(rv));
3464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
3465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now see that we don't use the stored entry.
3467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We are expecting a 206.
3472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
3476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests that we can handle cached 206 responses that can't be validated.
3481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST(HttpCache, GET_Previous206_NotValidation) {
3482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockHttpCache cache;
3483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create a disk cache entry that stores 206 headers.
3485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  disk_cache::Entry* entry;
3486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       NULL));
3488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Make sure that the headers cannot be validated with the server.
3490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string raw_headers(kRangeGET_TransactionOK.status);
3491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  raw_headers.append("\n");
3492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  raw_headers.append("Content-Length: 80\n");
3493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                  raw_headers.size());
3495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::HttpResponseInfo response;
3497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  response.headers = new net::HttpResponseHeaders(raw_headers);
3498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int len = static_cast<int>(base::strlcpy(buf->data(),
3502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           kRangeGET_TransactionOK.data, 500));
3503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TestCompletionCallback cb;
3504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int rv = entry->WriteData(1, 0, buf, len, &cb, true);
3505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(len, cb.GetResult(rv));
3506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  entry->Close();
3507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now see that we don't use the stored entry.
3509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string headers;
3510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 &headers);
3512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We are expecting a 200.
3514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string expected_headers(kSimpleGET_Transaction.status);
3515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  expected_headers.append("\n");
3516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  expected_headers.append(kSimpleGET_Transaction.response_headers);
3517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(expected_headers, headers);
3518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, cache.disk_cache()->open_count());
3520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, cache.disk_cache()->create_count());
3521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle range requests with cached 200 responses.
3524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_Previous200) {
3525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Store the whole thing with status 200.
3528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kTypicalGET_Transaction);
3529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.url = kRangeGET_TransactionOK.url;
3530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
3532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
3534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now see that we use the stored entry.
3542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction2(kRangeGET_TransactionOK);
3544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer handler;
3545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_not_modified(true);
3546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We are expecting a 206.
3549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The last transaction has finished so make sure the entry is deactivated.
3555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3557731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Make a request for an invalid range.
3558731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockTransaction transaction3(kRangeGET_TransactionOK);
3559731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
3560731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transaction3.data = "";
3561731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
3562731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
3563731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, cache.disk_cache()->open_count());
3564731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_NE(std::string::npos, headers.find("Content-Range: bytes 0-0/80"));
3566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_NE(std::string::npos, headers.find("Content-Length: 0"));
3567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Make sure the entry is deactivated.
3569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MessageLoop::current()->RunAllPending();
3570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3571731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Even though the request was invalid, we should have the entry.
3572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  RunTransactionTest(cache.http_cache(), transaction2);
3573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(3, cache.disk_cache()->open_count());
3574731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3575731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Make sure the entry is deactivated.
3576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MessageLoop::current()->RunAllPending();
3577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now we should receive a range from the server and drop the stored entry.
3579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_not_modified(false);
3580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(5, cache.network_layer()->transaction_count());
3584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(4, cache.disk_cache()->open_count());
3585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction2);
3588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
3589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle a 200 response when dealing with sparse entries.
3594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeRequestResultsIn200) {
3595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (70-79).
3600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 70-79 ";
3603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 70, 79);
3606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now we'll issue a request that results in a plain 200 response, but to
3611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the to the same URL that we used to store sparse data, and making sure
3612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // that we ask for a range.
3613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction2(kSimpleGET_Transaction);
3615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction2.url = kRangeGET_TransactionOK.url;
3616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction2);
3618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected_headers(kSimpleGET_Transaction.status);
3622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected_headers.append("\n");
3623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected_headers.append(kSimpleGET_Transaction.response_headers);
3624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected_headers, headers);
3625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction2);
3630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that a range request that falls outside of the size that we know about
3633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// only deletes the entry if the resource has indeed changed.
3634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_MoreThanCurrentSize) {
3635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
3640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A weird request should not delete this entry. Ask for bytes 120-.
3649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
3651731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transaction.data = "";
3652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->open_count());
3661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we don't delete a sparse entry when we cancel a request.
3667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_Cancel) {
3668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kRangeGET_TransactionOK);
3672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
3674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
3675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
3676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
3679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
3680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure that the entry has some data stored.
3686513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
3687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
3688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
3689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
3690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(buf->size(), rv);
3691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction.
3693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
3694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that the entry has not been deleted.
3696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
3697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
3698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
3699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we don't delete a sparse entry when we start a new request after
3703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cancelling the previous one.
3704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_Cancel2) {
3705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kRangeGET_TransactionOK);
3710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request.load_flags |= net::LOAD_VALIDATE_CACHE;
3711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
3713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
3714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
3715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
3718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
3719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure that we revalidate the entry and read from the cache (a single
3725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // read will return while waiting for the network).
3726513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
3727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
3728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, c->callback.GetResult(rv));
3729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
3730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::ERR_IO_PENDING, rv);
3731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction before completing the read.
3733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
3734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We have the read and the delete (OnProcessPendingQueue) waiting on the
3736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // message loop. This means that a new transaction will just reuse the same
3737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // active entry (no open or create).
3738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A slight variation of the previous test, this time we cancel two requests in
3748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a row, making sure that the second is waiting for the entry to be ready.
3749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_Cancel3) {
3750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kRangeGET_TransactionOK);
3755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request.load_flags |= net::LOAD_VALIDATE_CACHE;
3756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
3758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
3759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
3760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::ERR_IO_PENDING, rv);
3763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->callback.WaitForResult();
3764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure that we revalidate the entry and read from the cache (a single
3770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // read will return while waiting for the network).
3771513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
3772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
3773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, c->callback.GetResult(rv));
3774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
3775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::ERR_IO_PENDING, rv);
3776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction before completing the read.
3778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
3779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We have the read and the delete (OnProcessPendingQueue) waiting on the
3781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // message loop. This means that a new transaction will just reuse the same
3782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // active entry (no open or create).
3783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  c = new Context();
3785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = cache.http_cache()->CreateTransaction(&c->trans);
3786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
3787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::ERR_IO_PENDING, rv);
3790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockDiskEntry::IgnoreCallbacks(true);
3792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockDiskEntry::IgnoreCallbacks(false);
3794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The new transaction is waiting for the query range callback.
3796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
3797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // And we should not crash when the callback is delivered.
3799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
3800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that an invalid range response results in no cached entry.
3808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_InvalidResponse1) {
3809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = NULL;
3814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = "Content-Range: bytes 40-49/45\n"
3815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 "Content-Length: 10\n";
3816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected(transaction.status);
3820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected.append("\n");
3821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected.append(transaction.response_headers);
3822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected, headers);
3823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that we don't have a cached entry.
3829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
3830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
3831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we reject a range that doesn't match the content-length.
3836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_InvalidResponse2) {
3837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = NULL;
3842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = "Content-Range: bytes 40-49/80\n"
3843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 "Content-Length: 20\n";
3844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected(transaction.status);
3848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected.append("\n");
3849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected.append(transaction.response_headers);
3850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected, headers);
3851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that we don't have a cached entry.
3857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
3858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
3859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that if a server tells us conflicting information about a resource we
3864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ignore the response.
3865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_InvalidResponse3) {
3866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = NULL;
3871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
3872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string response_headers(transaction.response_headers);
3873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response_headers.append("Content-Range: bytes 50-59/160\n");
3874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = response_headers.c_str();
3875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 50, 59);
3879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
3884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This transaction will report a resource size of 80 bytes, and we think it's
3887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // 160 so we should ignore the response.
3888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
3890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
3892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
3894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
3895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that we cached the first response but not the second one.
3897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* en;
3898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
3899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int64 cached_start = 0;
3901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback cb;
3902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = en->GetAvailableRange(40, 20, &cached_start, &cb);
3903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(10, cb.GetResult(rv));
3904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(50, cached_start);
3905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  en->Close();
3906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we handle large range values properly.
3911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_LargeValues) {
3912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We need a real sparse cache for this test.
3913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
3914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = NULL;
3918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
3919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                EXTRA_HEADER;
3920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers =
3921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "ETag: \"foo\"\n"
3922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Content-Range: bytes 4294967288-4294967297/4294967299\n"
3923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Content-Length: 10\n";
3924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected(transaction.status);
3928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected.append("\n");
3929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  expected.append(transaction.response_headers);
3930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected, headers);
3931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that we have a cached entry.
3935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* en;
3936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
3937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  en->Close();
3938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we don't crash with a range request if the disk cache was not
3943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// initialized properly.
3944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_NoDiskCache) {
3945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
3946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  factory->set_fail(true);
3947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  factory->FinishCreation();  // We'll complete synchronously.
3948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache(factory);
3949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we handle byte range requests that skip the cache.
3959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeHEAD) {
3960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
3962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.method = "HEAD";
3966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 70-79 ";
3967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
3969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 70, 79);
3972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
3974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->create_count());
3975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
3977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we don't crash when after reading from the cache we issue a
3980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// request for the next range and the server gives us a 200 synchronously.
3981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_FastFlakyServer) {
3982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
3983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
3985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
3986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.test_mode = TEST_MODE_SYNC_NET_START;
3987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
3989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache.
3991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // And now read from the cache and the network.
3994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RangeTransactionServer handler;
3995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handler.set_bad_200(true);
3996dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction.data = "Not a range";
3997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
3998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, cache.network_layer()->transaction_count());
4000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
4004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that when the server gives us less data than expected, we don't keep
4007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// asking for more data.
4008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_FastFlakyServer2) {
4009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First, check with an empty cache (WRITE mode).
4012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
4013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 40-";  // Less than expected.
4015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.handler = NULL;
4016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers(transaction.response_headers);
4017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  headers.append("Content-Range: bytes 40-49/80\n");
4018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = headers.c_str();
4019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
4021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache.
4023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now verify that even in READ_WRITE mode, we forward the bad response to
4030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the caller.
4031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 60-";  // Less than expected.
4033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  headers = kRangeGET_TransactionOK.response_headers;
4034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  headers.append("Content-Range: bytes 60-69/80\n");
4035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = headers.c_str();
4036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
4044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef NDEBUG
4047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test hits a NOTREACHED so it is a release mode only test.
4048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
4049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
4051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write to the cache (40-49).
4053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Force this transaction to read from the cache.
4059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
4060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
4063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
4064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
4066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&trans);
4067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(trans.get());
4069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = trans->Start(&request, &callback, net::BoundNetLog());
4071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = callback.WaitForResult();
4073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.reset();
4076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
4082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
4084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests the handling of the "truncation" flag.
4086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, WriteResponseInfo_Truncated) {
4087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
40893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
40903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                       NULL));
4091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers("HTTP/1.1 200 OK");
4093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
4095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response.headers = new net::HttpResponseHeaders(headers);
4096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the last argument for this to be an incomplete request.
4098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
4099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool truncated = false;
4100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(truncated);
4102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // And now test the opposite case.
4104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  truncated = true;
4106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(truncated);
4108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
4109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Tests basic pickling/unpickling of HttpResponseInfo.
4112dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST(HttpCache, PersistHttpResponseInfo) {
4113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Set some fields (add more if needed.)
4114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::HttpResponseInfo response1;
4115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response1.was_cached = false;
4116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Pickle.
4120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  Pickle pickle;
4121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  response1.Persist(&pickle, false, false);
4122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Unpickle.
4124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::HttpResponseInfo response2;
4125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool response_truncated;
4126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(response_truncated);
4128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Verify fields.
4130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
4131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(80, response2.socket_address.port());
4133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
4135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we delete an entry when the request is cancelled before starting
4137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to read from the network.
4138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, DoomOnDestruction) {
4139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
4142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
4144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
4145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    c->result = c->callback.WaitForResult();
4150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction. We only have the headers so we should delete this
4156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // entry.
4157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
4158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
4164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we delete an entry when the request is cancelled if the response
4167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// does not have content-length and strong validators.
4168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, DoomOnDestruction2) {
4169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kSimpleGET_Transaction);
4172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
4174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
4175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
4180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure that the entry has some data stored.
4186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
4188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
4190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(buf->size(), rv);
4191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction.
4193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
4194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
4200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we delete an entry when the request is cancelled if the response
4203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// has an "Accept-Ranges: none" header.
4204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, DoomOnDestruction3) {
4205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
4208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers =
4209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Content-Length: 22\n"
4211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Accept-Ranges: none\n"
4212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Etag: foopy\n";
4213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
4214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
4215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
4217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
4218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
4223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure that the entry has some data stored.
4229513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
4231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
4233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(buf->size(), rv);
4234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction.
4236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
4237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
4243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
4245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we mark an entry as incomplete when the request is cancelled.
4248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, Set_Truncated_Flag) {
4249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
4252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers =
4253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Content-Length: 22\n"
4255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Etag: foopy\n";
4256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&transaction);
4257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
4258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Context> c(new Context());
4260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&c->trans);
4261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
4266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure that the entry has some data stored.
4272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, buf->size(), &c->callback);
4274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = c->callback.WaitForResult();
4276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(buf->size(), rv);
4277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We want to cancel the request when the transaction is busy.
4279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = c->trans->Read(buf, buf->size(), &c->callback);
4280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(c->callback.have_result());
4282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_test_mode = TEST_MODE_SYNC_ALL;
4284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroy the transaction.
4286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c->trans.reset();
4287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_test_mode = 0;
4288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure that we don't invoke the callback. We may have an issue if the
4290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // could end up with the transaction being deleted twice if we send any
4292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification from the transaction destructor (see http://crbug.com/31723).
4293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(c->callback.have_result());
4294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that the entry is marked as incomplete.
4296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
4297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
4299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool truncated = false;
4300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(truncated);
4302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
4303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&transaction);
4305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can continue with a request that was interrupted.
4308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_IncompleteResource) {
4309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
4311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers("HTTP/1.1 200 OK\n"
4313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "ETag: \"foo\"\n"
4315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Accept-Ranges: bytes\n"
4316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Content-Length: 80\n");
4317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CreateTruncatedEntry(raw_headers, &cache);
4318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now make a regular request.
4320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
4321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
4322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = EXTRA_HEADER;
4323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We update the headers with the ones received while revalidating.
4328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected_headers(
4329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "HTTP/1.1 200 OK\n"
4330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Accept-Ranges: bytes\n"
4332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "ETag: \"foo\"\n"
4333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "Content-Length: 80\n");
4334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected_headers, headers);
4336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that the disk entry was updated.
4341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  disk_cache::Entry* entry;
4342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(80, entry->GetDataSize(1));
4344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool truncated = true;
4345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::HttpResponseInfo response;
4346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(truncated);
4348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
4349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RemoveMockTransaction(&kRangeGET_TransactionOK);
4351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we delete truncated entries if the server changes its mind midway.
4354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, GET_IncompleteResource2) {
4355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
4357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Content-length will be intentionally bad.
4359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers("HTTP/1.1 200 OK\n"
4360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "ETag: \"foo\"\n"
4362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Accept-Ranges: bytes\n"
4363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Content-Length: 50\n");
4364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CreateTruncatedEntry(raw_headers, &cache);
4365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Now make a regular request. We expect the code to fail the validation and
4367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // retry the request without using byte ranges.
4368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
4369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
4370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = EXTRA_HEADER;
4371dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction.data = "Not a range";
4372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4374dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // The server will return 200 instead of a byte range.
4375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string expected_headers(
4376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "HTTP/1.1 200 OK\n"
4377dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
4378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected_headers, headers);
4380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that the disk entry was deleted.
4385dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  disk_cache::Entry* entry;
4386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RemoveMockTransaction(&kRangeGET_TransactionOK);
4388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4390dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Tests that we always validate a truncated request.
4391dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST(HttpCache, GET_IncompleteResource3) {
4392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
4394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4395dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This should not require validation for 10 hours.
4396dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string raw_headers("HTTP/1.1 200 OK\n"
4397dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "ETag: \"foo\"\n"
4399dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Cache-Control: max-age= 36000\n"
4400dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Accept-Ranges: bytes\n"
4401dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Content-Length: 80\n");
4402dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CreateTruncatedEntry(raw_headers, &cache);
4403dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4404dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Now make a regular request.
4405dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string headers;
4406dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockTransaction transaction(kRangeGET_TransactionOK);
4407dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction.request_headers = EXTRA_HEADER;
4408dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4409dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4410dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4411dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<Context> c(new Context);
4412dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans));
4413dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4414dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockHttpRequest request(transaction);
4415dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4416dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4417dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4418dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // We should have checked with the server before finishing Start().
4419dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4420dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1, cache.disk_cache()->open_count());
4421dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1, cache.disk_cache()->create_count());
4422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4423dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RemoveMockTransaction(&kRangeGET_TransactionOK);
4424dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
4425dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Tests that we cache a 200 response to the validation request.
4427dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST(HttpCache, GET_IncompleteResource4) {
4428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockHttpCache cache;
4429dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  AddMockTransaction(&kRangeGET_TransactionOK);
4430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers("HTTP/1.1 200 OK\n"
4432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "ETag: \"foo\"\n"
4434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Accept-Ranges: bytes\n"
4435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Content-Length: 80\n");
4436dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CreateTruncatedEntry(raw_headers, &cache);
4437dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4438dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Now make a regular request.
4439dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string headers;
4440dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockTransaction transaction(kRangeGET_TransactionOK);
4441dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction.request_headers = EXTRA_HEADER;
4442dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  transaction.data = "Not a range";
4443dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RangeTransactionServer handler;
4444dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  handler.set_bad_200(true);
4445dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4447dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4448dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1, cache.disk_cache()->open_count());
4449dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1, cache.disk_cache()->create_count());
4450dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4451dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Verify that the disk entry was updated.
4452dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  disk_cache::Entry* entry;
4453dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4454dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(11, entry->GetDataSize(1));
4455dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool truncated = true;
4456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
4457dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4458dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(truncated);
4459dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  entry->Close();
4460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4461dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RemoveMockTransaction(&kRangeGET_TransactionOK);
4462dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
4463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4464dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Tests that when we cancel a request that was interrupted, we mark it again
4465dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// as truncated.
4466dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST(HttpCache, GET_CancelIncompleteResource) {
4467dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockHttpCache cache;
4468dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  AddMockTransaction(&kRangeGET_TransactionOK);
4469dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4470dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string raw_headers("HTTP/1.1 200 OK\n"
4471dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4472dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "ETag: \"foo\"\n"
4473dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Accept-Ranges: bytes\n"
4474dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          "Content-Length: 80\n");
4475dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CreateTruncatedEntry(raw_headers, &cache);
4476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now make a regular request.
4478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kRangeGET_TransactionOK);
4479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.request_headers = EXTRA_HEADER;
4480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
4482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Context* c = new Context();
4483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans));
4484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4485dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Read 20 bytes from the cache, and 10 from the net.
4489dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
4490dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  rv = c->trans->Read(buf, 20, &c->callback);
4491dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(20, c->callback.GetResult(rv));
4492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = c->trans->Read(buf, 10, &c->callback);
4493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(10, c->callback.GetResult(rv));
4494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point, we are already reading so canceling the request should leave
4496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // a truncated one.
4497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete c;
4498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that the disk entry was updated: now we have 30 bytes.
4504dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  disk_cache::Entry* entry;
4505dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(30, entry->GetDataSize(1));
4507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool truncated = false;
4508dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  net::HttpResponseInfo response;
4509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(truncated);
4511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
4512dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  RemoveMockTransaction(&kRangeGET_TransactionOK);
4513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Tests that we can handle range requests when we have a truncated entry.
4516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, RangeGET_IncompleteResource) {
4517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&kRangeGET_TransactionOK);
4519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Content-length will be intentionally bogus.
4521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string raw_headers("HTTP/1.1 200 OK\n"
4522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Last-Modified: something\n"
4523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "ETag: \"foo\"\n"
4524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Accept-Ranges: bytes\n"
4525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          "Content-Length: 10\n");
4526dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CreateTruncatedEntry(raw_headers, &cache);
4527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now make a range request.
4529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
4530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &headers);
4532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Verify206Response(headers, 40, 49);
4534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
4537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&kRangeGET_TransactionOK);
4539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SyncRead) {
4542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This test ensures that a read that completes synchronously does not cause
4545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // any problems.
4546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction(kSimpleGET_Transaction);
4548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
4549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            TEST_MODE_SYNC_CACHE_READ |
4550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            TEST_MODE_SYNC_CACHE_WRITE);
4551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest r1(transaction),
4553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  r2(transaction),
4554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  r3(transaction);
4555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestTransactionConsumer c1(cache.http_cache()),
4557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          c2(cache.http_cache()),
4558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          c3(cache.http_cache());
4559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c1.Start(&r1, net::BoundNetLog());
4561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c2.Start(&r2, net::BoundNetLog());
4564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  c3.Start(&r3, net::BoundNetLog());
4567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
4569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(c1.is_done());
4571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(c2.is_done());
4572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(c3.is_done());
4573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, c1.error());
4575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, c2.error());
4576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, c3.error());
4577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, ValidationResultsIn200) {
4580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This test ensures that a conditional request, which results in a 200
4583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // instead of a 304, properly truncates the existing response data.
4584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
4586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
4587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to validate the cache
4589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kETagGET_Transaction);
4590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // read from the cache
4594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
4595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, CachedRedirect) {
4598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
4601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
4602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
4603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(kTestTransaction);
4605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
4606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
4608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
4609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_ptr<net::HttpTransaction> trans;
4610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int rv = cache.http_cache()->CreateTransaction(&trans);
4611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, rv);
4612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_TRUE(trans.get());
4613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rv = trans->Start(&request, &callback, net::BoundNetLog());
4615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (rv == net::ERR_IO_PENDING)
4616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      rv = callback.WaitForResult();
4617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_EQ(net::OK, rv);
4618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const net::HttpResponseInfo* info = trans->GetResponseInfo();
4620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_TRUE(info);
4621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(info->headers->response_code(), 301);
4623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string location;
4625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    info->headers->EnumerateHeader(NULL, "Location", &location);
4626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(location, "http://www.bar.com/");
4627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Destroy transaction when going out of scope. We have not actually
4629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // read the response body -- want to test that it is still getting cached.
4630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
4631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // read from the cache
4636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
4637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_ptr<net::HttpTransaction> trans;
4638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int rv = cache.http_cache()->CreateTransaction(&trans);
4639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(net::OK, rv);
4640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_TRUE(trans.get());
4641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rv = trans->Start(&request, &callback, net::BoundNetLog());
4643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (rv == net::ERR_IO_PENDING)
4644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      rv = callback.WaitForResult();
4645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_EQ(net::OK, rv);
4646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const net::HttpResponseInfo* info = trans->GetResponseInfo();
4648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_TRUE(info);
4649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(info->headers->response_code(), 301);
4651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string location;
4653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    info->headers->EnumerateHeader(NULL, "Location", &location);
4654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(location, "http://www.bar.com/");
4655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Destroy transaction when going out of scope. We have not actually
4657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // read the response body -- want to test that it is still getting cached.
4658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
4659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, CacheControlNoStore) {
4665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction(kSimpleGET_Transaction);
4668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = "cache-control: no-store\n";
4669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // initial load
4671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // try loading again; it should result in a network fetch
4678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.disk_cache()->create_count());
4683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
4685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
4686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, CacheControlNoStore2) {
4689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // this test is similar to the above test, except that the initial response
4690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is cachable, but when it is validated, no-store is received causing the
4691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // cached document to be deleted.
4692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction(kETagGET_Transaction);
4695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // initial load
4697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // try loading again; it should result in a network fetch
4704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
4705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = "cache-control: no-store\n";
4706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
4713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
4714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, CacheControlNoStore3) {
4717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // this test is similar to the above test, except that the response is a 304
4718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // instead of a 200.  this should never happen in practice, but it seems like
4719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // a good thing to verify that we still destroy the cache entry.
4720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction transaction(kETagGET_Transaction);
4723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // initial load
4725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // try loading again; it should result in a network fetch
4732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
4733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.response_headers = "cache-control: no-store\n";
4734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.status = "HTTP/1.1 304 Not Modified";
4735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->open_count());
4739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Entry* entry;
4742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
4743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Ensure that we don't cache requests served over bad HTTPS.
4746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, SimpleGET_SSLError) {
4747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction = kSimpleGET_Transaction;
4750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.cert_status = net::CERT_STATUS_REVOKED;
4751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedMockTransaction scoped_transaction(transaction);
4752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
4754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test that it was not cached.
4757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpRequest request(transaction);
4760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
4761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
4763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache.http_cache()->CreateTransaction(&trans);
4764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(trans.get());
4766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = trans->Start(&request, &callback, net::BoundNetLog());
4768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == net::ERR_IO_PENDING)
4769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    rv = callback.WaitForResult();
4770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Ensure that we don't crash by if left-behind transactions.
4774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, OutlivedTransactions) {
4775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache* cache = new MockHttpCache;
4776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<net::HttpTransaction> trans;
4778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = cache->http_cache()->CreateTransaction(&trans);
4779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(net::OK, rv);
4780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete cache;
4782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trans.reset();
4783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that the disabled mode works.
4786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, CacheDisabledMode) {
4787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // write to the cache
4790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // go into disabled mode
4793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cache.http_cache()->set_mode(net::HttpCache::DISABLE);
4794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // force this transaction to write to the cache again
4796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction transaction(kSimpleGET_Transaction);
4797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), transaction);
4799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache.disk_cache()->open_count());
4802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, cache.disk_cache()->create_count());
4803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Other tests check that the response headers of the cached response
4806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// get updated on 304. Here we specifically check that the
4807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
4808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// fields also gets updated.
4809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://crbug.com/20594.
4810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpCache, UpdatesRequestResponseTimeOn304) {
4811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockHttpCache cache;
4812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kUrl = "http://foobar";
4814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* kData = "body";
4815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction mock_network_response = { 0 };
4817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mock_network_response.url = kUrl;
4818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddMockTransaction(&mock_network_response);
4820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
4822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockTransaction request = { 0 };
4824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.url = kUrl;
4825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.method = "GET";
4826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.request_headers = "";
4827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.data = kData;
4828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse1 = {
4830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 200 OK",
4831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
4832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
4833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kData
4834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
4835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kNetResponse1.AssignTo(&mock_network_response);
4837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTest(cache.http_cache(), request);
4839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request |kUrl| again, this time validating the cache and getting
4841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // a 304 back.
4842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  request.load_flags = net::LOAD_VALIDATE_CACHE;
4844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const Response kNetResponse2 = {
4846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "HTTP/1.1 304 Not Modified",
4847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
4848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ""
4849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
4850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  kNetResponse2.AssignTo(&mock_network_response);
4852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
4854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
4855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mock_network_response.request_time = request_time;
4857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mock_network_response.response_time = response_time;
4858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpResponseInfo response;
4860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
4861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The request and response times should have been updated.
4863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(request_time.ToInternalValue(),
4864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            response.request_time.ToInternalValue());
4865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(response_time.ToInternalValue(),
4866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            response.response_time.ToInternalValue());
4867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string headers;
4869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  response.headers->GetNormalizedHeaders(&headers);
4870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("HTTP/1.1 200 OK\n"
4872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
4873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
4874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            headers);
4875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RemoveMockTransaction(&mock_network_response);
4877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
4878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can write metadata to an entry.
4880c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, WriteMetadata_OK) {
4881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache;
4882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write to the cache
4884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HttpResponseInfo response;
4885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &response);
4887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(response.metadata.get() == NULL);
4888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Trivial call.
4890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.http_cache()->WriteMetadata(GURL("foo"), Time::Now(), NULL, 0);
4891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write meta data to the same entry.
4893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  memset(buf->data(), 0, buf->size());
4895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::strlcpy(buf->data(), "Hi there", buf->size());
4896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
4897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    response.response_time, buf, buf->size());
4898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Release the buffer before the operation takes place.
4900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  buf = NULL;
4901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Makes sure we finish pending operations.
4903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
4904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &response);
4907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(response.metadata.get() != NULL);
4908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(50, response.metadata->size());
4909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
4910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.disk_cache()->open_count());
4913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
4914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we only write metadata to an entry if the time stamp matches.
4917c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, WriteMetadata_Fail) {
4918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache;
4919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write to the cache
4921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HttpResponseInfo response;
4922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &response);
4924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(response.metadata.get() == NULL);
4925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Attempt to write meta data to the same entry.
4927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  memset(buf->data(), 0, buf->size());
4929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::strlcpy(buf->data(), "Hi there", buf->size());
4930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Time expected_time = response.response_time -
4931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             base::TimeDelta::FromMilliseconds(20);
4932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
4933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    expected_time, buf, buf->size());
4934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Makes sure we finish pending operations.
4936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
4937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &response);
4940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(response.metadata.get() == NULL);
4941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.disk_cache()->open_count());
4944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
4945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can read metadata after validating the entry and with READ mode
4948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// transactions.
4949c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(HttpCache, ReadMetadata) {
4950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockHttpCache cache;
4951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write to the cache
4953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HttpResponseInfo response;
4954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(),
4955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     kTypicalGET_Transaction, &response);
4956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(response.metadata.get() == NULL);
4957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Write meta data to the same entry.
4959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  memset(buf->data(), 0, buf->size());
4961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::strlcpy(buf->data(), "Hi there", buf->size());
4962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
4963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    response.response_time, buf, buf->size());
4964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Makes sure we finish pending operations.
4966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
4967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start with a READ mode transaction.
4969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTransaction trans1(kTypicalGET_Transaction);
4970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
4971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
4973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(response.metadata.get() != NULL);
4974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(50, response.metadata->size());
4975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
4976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.disk_cache()->open_count());
4979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
4980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
4981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now make sure that the entry is re-validated with the server.
4983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  trans1.load_flags = net::LOAD_VALIDATE_CACHE;
4984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  trans1.status = "HTTP/1.1 304 Not Modified";
4985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMockTransaction(&trans1);
4986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.metadata = NULL;
4988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
4989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(response.metadata.get() != NULL);
4990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, cache.disk_cache()->open_count());
4993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
4994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
4995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RemoveMockTransaction(&trans1);
4996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now return 200 when validating the entry so the metadata will be lost.
4998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTransaction trans2(kTypicalGET_Transaction);
4999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(response.metadata.get() == NULL);
5002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, cache.network_layer()->transaction_count());
5004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, cache.disk_cache()->open_count());
5005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, cache.disk_cache()->create_count());
5006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
5007