OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_cache.h" | 5 #include "net/http/http_cache.h" |
6 | 6 |
7 #include "base/hash_tables.h" | 7 #include "base/hash_tables.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "net/base/load_flags.h" | 11 #include "net/base/load_flags.h" |
12 #include "net/disk_cache/disk_cache.h" | 12 #include "net/disk_cache/disk_cache.h" |
13 #include "net/http/http_request_info.h" | 13 #include "net/http/http_request_info.h" |
14 #include "net/http/http_response_info.h" | 14 #include "net/http/http_response_info.h" |
15 #include "net/http/http_transaction.h" | 15 #include "net/http/http_transaction.h" |
16 #include "net/http/http_transaction_unittest.h" | 16 #include "net/http/http_transaction_unittest.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 using base::Time; | 19 using base::Time; |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 //----------------------------------------------------------------------------- | 23 //----------------------------------------------------------------------------- |
24 // mock disk cache (a very basic memory cache implementation) | 24 // mock disk cache (a very basic memory cache implementation) |
25 | 25 |
26 class MockDiskEntry : public disk_cache::Entry, | 26 class MockDiskEntry : public disk_cache::Entry, |
27 public base::RefCounted<MockDiskEntry> { | 27 public base::RefCounted<MockDiskEntry> { |
28 public: | 28 public: |
29 MockDiskEntry() | 29 MockDiskEntry() |
30 : test_mode_(0), doomed_(false) { | 30 : test_mode_(0), doomed_(false), sparse_(false) { |
31 } | 31 } |
32 | 32 |
33 MockDiskEntry(const std::string& key) | 33 MockDiskEntry(const std::string& key) |
34 : key_(key), doomed_(false) { | 34 : key_(key), doomed_(false), sparse_(false) { |
35 // | 35 // |
36 // 'key' is prefixed with an identifier if it corresponds to a cached POST. | 36 // 'key' is prefixed with an identifier if it corresponds to a cached POST. |
37 // Skip past that to locate the actual URL. | 37 // Skip past that to locate the actual URL. |
38 // | 38 // |
39 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an | 39 // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an |
40 // URL corresponding to a registered MockTransaction. It would be good to | 40 // URL corresponding to a registered MockTransaction. It would be good to |
41 // have another way to access the test_mode. | 41 // have another way to access the test_mode. |
42 // | 42 // |
43 GURL url; | 43 GURL url; |
44 if (isdigit(key[0])) { | 44 if (isdigit(key[0])) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 109 |
110 if (offset < 0 || offset > static_cast<int>(data_[index].size())) | 110 if (offset < 0 || offset > static_cast<int>(data_[index].size())) |
111 return net::ERR_FAILED; | 111 return net::ERR_FAILED; |
112 | 112 |
113 data_[index].resize(offset + buf_len); | 113 data_[index].resize(offset + buf_len); |
114 if (buf_len) | 114 if (buf_len) |
115 memcpy(&data_[index][offset], buf->data(), buf_len); | 115 memcpy(&data_[index][offset], buf->data(), buf_len); |
116 return buf_len; | 116 return buf_len; |
117 } | 117 } |
118 | 118 |
| 119 virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| 120 net::CompletionCallback* completion_callback) { |
| 121 if (!sparse_) |
| 122 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 123 if (offset < 0) |
| 124 return net::ERR_FAILED; |
| 125 |
| 126 DCHECK(offset < kint32max); |
| 127 int real_offset = static_cast<int>(offset); |
| 128 if (!buf_len) |
| 129 return 0; |
| 130 |
| 131 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, |
| 132 buf_len); |
| 133 memcpy(buf->data(), &data_[1][real_offset], num); |
| 134 |
| 135 if (!completion_callback || (test_mode_ & TEST_MODE_SYNC_CACHE_READ)) |
| 136 return num; |
| 137 |
| 138 CallbackLater(completion_callback, num); |
| 139 return net::ERR_IO_PENDING; |
| 140 } |
| 141 |
| 142 virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| 143 net::CompletionCallback* completion_callback) { |
| 144 if (!sparse_) { |
| 145 if (data_[1].size()) |
| 146 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 147 sparse_ = true; |
| 148 } |
| 149 if (offset < 0) |
| 150 return net::ERR_FAILED; |
| 151 if (!buf_len) |
| 152 return 0; |
| 153 |
| 154 DCHECK(offset < kint32max); |
| 155 int real_offset = static_cast<int>(offset); |
| 156 |
| 157 if (static_cast<int>(data_[1].size()) < real_offset + buf_len) |
| 158 data_[1].resize(real_offset + buf_len); |
| 159 |
| 160 memcpy(&data_[1][real_offset], buf->data(), buf_len); |
| 161 return buf_len; |
| 162 } |
| 163 |
| 164 virtual int GetAvailableRange(int64 offset, int len, int64* start) { |
| 165 if (!sparse_) |
| 166 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 167 if (offset < 0) |
| 168 return net::ERR_FAILED; |
| 169 |
| 170 *start = offset; |
| 171 DCHECK(offset < kint32max); |
| 172 int real_offset = static_cast<int>(offset); |
| 173 if (static_cast<int>(data_[1].size()) < real_offset) |
| 174 return 0; |
| 175 |
| 176 int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len); |
| 177 int count = 0; |
| 178 for (; num > 0; num--, real_offset++) { |
| 179 if (!count) { |
| 180 if (data_[1][real_offset]) { |
| 181 count++; |
| 182 *start = real_offset; |
| 183 } |
| 184 } else { |
| 185 if (!data_[1][real_offset]) |
| 186 break; |
| 187 count++; |
| 188 } |
| 189 } |
| 190 return count; |
| 191 } |
| 192 |
119 private: | 193 private: |
120 // Unlike the callbacks for MockHttpTransaction, we want this one to run even | 194 // Unlike the callbacks for MockHttpTransaction, we want this one to run even |
121 // if the consumer called Close on the MockDiskEntry. We achieve that by | 195 // if the consumer called Close on the MockDiskEntry. We achieve that by |
122 // leveraging the fact that this class is reference counted. | 196 // leveraging the fact that this class is reference counted. |
123 void CallbackLater(net::CompletionCallback* callback, int result) { | 197 void CallbackLater(net::CompletionCallback* callback, int result) { |
124 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, | 198 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this, |
125 &MockDiskEntry::RunCallback, callback, result)); | 199 &MockDiskEntry::RunCallback, callback, result)); |
126 } | 200 } |
127 void RunCallback(net::CompletionCallback* callback, int result) { | 201 void RunCallback(net::CompletionCallback* callback, int result) { |
128 callback->Run(result); | 202 callback->Run(result); |
129 } | 203 } |
130 | 204 |
131 std::string key_; | 205 std::string key_; |
132 std::vector<char> data_[2]; | 206 std::vector<char> data_[2]; |
133 int test_mode_; | 207 int test_mode_; |
134 bool doomed_; | 208 bool doomed_; |
| 209 bool sparse_; |
135 }; | 210 }; |
136 | 211 |
137 class MockDiskCache : public disk_cache::Backend { | 212 class MockDiskCache : public disk_cache::Backend { |
138 public: | 213 public: |
139 MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(0) { | 214 MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(0) { |
140 } | 215 } |
141 | 216 |
142 ~MockDiskCache() { | 217 ~MockDiskCache() { |
143 EntryMap::iterator it = entries_.begin(); | 218 EntryMap::iterator it = entries_.begin(); |
144 for (; it != entries_.end(); ++it) | 219 for (; it != entries_.end(); ++it) |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 } | 1307 } |
1233 | 1308 |
1234 // Ensure that we don't crash by if left-behind transactions. | 1309 // Ensure that we don't crash by if left-behind transactions. |
1235 TEST(HttpCache, OutlivedTransactions) { | 1310 TEST(HttpCache, OutlivedTransactions) { |
1236 MockHttpCache* cache = new MockHttpCache; | 1311 MockHttpCache* cache = new MockHttpCache; |
1237 | 1312 |
1238 net::HttpTransaction* trans = cache->http_cache()->CreateTransaction(); | 1313 net::HttpTransaction* trans = cache->http_cache()->CreateTransaction(); |
1239 delete cache; | 1314 delete cache; |
1240 delete trans; | 1315 delete trans; |
1241 } | 1316 } |
OLD | NEW |