Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: content/browser/appcache/appcache_response.cc

Issue 932643002: Introduce AppCacheResponseMetadataWriter to support metadata caching. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: incorporated michaeln's comment Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 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 "content/browser/appcache/appcache_response.h" 5 #include "content/browser/appcache/appcache_response.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/pickle.h" 12 #include "base/pickle.h"
13 #include "base/profiler/scoped_tracker.h" 13 #include "base/profiler/scoped_tracker.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "content/browser/appcache/appcache_storage.h" 15 #include "content/browser/appcache/appcache_storage.h"
16 #include "net/base/completion_callback.h" 16 #include "net/base/completion_callback.h"
17 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 19
20 namespace content { 20 namespace content {
21 21
22 namespace { 22 namespace {
23 23
24 // Disk cache entry data indices. 24 // Disk cache entry data indices.
25 enum { 25 enum { kResponseInfoIndex, kResponseContentIndex, kResponseMetadataIndex };
26 kResponseInfoIndex,
27 kResponseContentIndex
28 };
29 26
30 // An IOBuffer that wraps a pickle's data. Ownership of the 27 // An IOBuffer that wraps a pickle's data. Ownership of the
31 // pickle is transfered to the WrappedPickleIOBuffer object. 28 // pickle is transfered to the WrappedPickleIOBuffer object.
32 class WrappedPickleIOBuffer : public net::WrappedIOBuffer { 29 class WrappedPickleIOBuffer : public net::WrappedIOBuffer {
33 public: 30 public:
34 explicit WrappedPickleIOBuffer(const Pickle* pickle) : 31 explicit WrappedPickleIOBuffer(const Pickle* pickle) :
35 net::WrappedIOBuffer(reinterpret_cast<const char*>(pickle->data())), 32 net::WrappedIOBuffer(reinterpret_cast<const char*>(pickle->data())),
36 pickle_(pickle) { 33 pickle_(pickle) {
37 DCHECK(pickle->data()); 34 DCHECK(pickle->data());
38 } 35 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 void AppCacheResponseIO::OnRawIOComplete(int result) { 129 void AppCacheResponseIO::OnRawIOComplete(int result) {
133 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 130 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
134 tracked_objects::ScopedTracker tracking_profile( 131 tracked_objects::ScopedTracker tracking_profile(
135 FROM_HERE_WITH_EXPLICIT_FUNCTION( 132 FROM_HERE_WITH_EXPLICIT_FUNCTION(
136 "422516 AppCacheResponseIO::OnRawIOComplete")); 133 "422516 AppCacheResponseIO::OnRawIOComplete"));
137 134
138 DCHECK_NE(net::ERR_IO_PENDING, result); 135 DCHECK_NE(net::ERR_IO_PENDING, result);
139 OnIOComplete(result); 136 OnIOComplete(result);
140 } 137 }
141 138
139 void AppCacheResponseIO::OpenEntryIfNeeded() {
140 int rv;
141 AppCacheDiskCacheInterface::Entry** entry_ptr = NULL;
142 if (entry_) {
143 rv = net::OK;
144 } else if (!disk_cache_) {
145 rv = net::ERR_FAILED;
146 } else {
147 entry_ptr = new AppCacheDiskCacheInterface::Entry*;
148 open_callback_ =
149 base::Bind(&AppCacheResponseIO::OpenEntryCallback,
150 weak_factory_.GetWeakPtr(), base::Owned(entry_ptr));
151 rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_);
152 }
153
154 if (rv != net::ERR_IO_PENDING)
155 OpenEntryCallback(entry_ptr, rv);
156 }
157
158 void AppCacheResponseIO::OpenEntryCallback(
159 AppCacheDiskCacheInterface::Entry** entry, int rv) {
160 DCHECK(info_buffer_.get() || buffer_.get());
161
162 if (!open_callback_.is_null()) {
163 if (rv == net::OK) {
164 DCHECK(entry);
165 entry_ = *entry;
166 }
167 open_callback_.Reset();
168 }
169 OnOpenEntryComplete();
170 }
171
142 172
143 // AppCacheResponseReader ---------------------------------------------- 173 // AppCacheResponseReader ----------------------------------------------
144 174
145 AppCacheResponseReader::AppCacheResponseReader( 175 AppCacheResponseReader::AppCacheResponseReader(
146 int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) 176 int64 response_id,
177 int64 group_id,
178 AppCacheDiskCacheInterface* disk_cache)
147 : AppCacheResponseIO(response_id, group_id, disk_cache), 179 : AppCacheResponseIO(response_id, group_id, disk_cache),
148 range_offset_(0), 180 range_offset_(0),
149 range_length_(kint32max), 181 range_length_(kint32max),
150 read_position_(0), 182 read_position_(0),
183 reading_metadata_size_(0),
151 weak_factory_(this) { 184 weak_factory_(this) {
152 } 185 }
153 186
154 AppCacheResponseReader::~AppCacheResponseReader() { 187 AppCacheResponseReader::~AppCacheResponseReader() {
155 } 188 }
156 189
157 void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, 190 void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf,
158 const net::CompletionCallback& callback) { 191 const net::CompletionCallback& callback) {
159 DCHECK(!callback.is_null()); 192 DCHECK(!callback.is_null());
160 DCHECK(!IsReadPending()); 193 DCHECK(!IsReadPending());
161 DCHECK(info_buf); 194 DCHECK(info_buf);
162 DCHECK(!info_buf->http_info.get()); 195 DCHECK(!info_buf->http_info.get());
163 DCHECK(!buffer_.get()); 196 DCHECK(!buffer_.get());
164 DCHECK(!info_buffer_.get()); 197 DCHECK(!info_buffer_.get());
165 198
166 info_buffer_ = info_buf; 199 info_buffer_ = info_buf;
167 callback_ = callback; // cleared on completion 200 callback_ = callback; // cleared on completion
168 OpenEntryIfNeededAndContinue(); 201 OpenEntryIfNeeded();
169 } 202 }
170 203
171 void AppCacheResponseReader::ContinueReadInfo() { 204 void AppCacheResponseReader::ContinueReadInfo() {
172 if (!entry_) {
173 ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
174 return;
175 }
176
177 int size = entry_->GetSize(kResponseInfoIndex); 205 int size = entry_->GetSize(kResponseInfoIndex);
178 if (size <= 0) { 206 if (size <= 0) {
179 ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); 207 ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
180 return; 208 return;
181 } 209 }
182 210
183 buffer_ = new net::IOBuffer(size); 211 buffer_ = new net::IOBuffer(size);
184 ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size); 212 ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size);
185 } 213 }
186 214
187 void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len, 215 void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len,
188 const net::CompletionCallback& callback) { 216 const net::CompletionCallback& callback) {
189 DCHECK(!callback.is_null()); 217 DCHECK(!callback.is_null());
190 DCHECK(!IsReadPending()); 218 DCHECK(!IsReadPending());
191 DCHECK(buf); 219 DCHECK(buf);
192 DCHECK(buf_len >= 0); 220 DCHECK(buf_len >= 0);
193 DCHECK(!buffer_.get()); 221 DCHECK(!buffer_.get());
194 DCHECK(!info_buffer_.get()); 222 DCHECK(!info_buffer_.get());
195 223
196 buffer_ = buf; 224 buffer_ = buf;
197 buffer_len_ = buf_len; 225 buffer_len_ = buf_len;
198 callback_ = callback; // cleared on completion 226 callback_ = callback; // cleared on completion
199 OpenEntryIfNeededAndContinue(); 227 OpenEntryIfNeeded();
200 } 228 }
201 229
202 void AppCacheResponseReader::ContinueReadData() { 230 void AppCacheResponseReader::ContinueReadData() {
203 if (!entry_) {
204 ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
205 return;
206 }
207
208 if (read_position_ + buffer_len_ > range_length_) { 231 if (read_position_ + buffer_len_ > range_length_) {
209 // TODO(michaeln): What about integer overflows? 232 // TODO(michaeln): What about integer overflows?
210 DCHECK(range_length_ >= read_position_); 233 DCHECK(range_length_ >= read_position_);
211 buffer_len_ = range_length_ - read_position_; 234 buffer_len_ = range_length_ - read_position_;
212 } 235 }
213 ReadRaw(kResponseContentIndex, 236 ReadRaw(kResponseContentIndex,
214 range_offset_ + read_position_, 237 range_offset_ + read_position_,
215 buffer_.get(), 238 buffer_.get(),
216 buffer_len_); 239 buffer_len_);
217 } 240 }
218 241
219 void AppCacheResponseReader::SetReadRange(int offset, int length) { 242 void AppCacheResponseReader::SetReadRange(int offset, int length) {
220 DCHECK(!IsReadPending() && !read_position_); 243 DCHECK(!IsReadPending() && !read_position_);
221 range_offset_ = offset; 244 range_offset_ = offset;
222 range_length_ = length; 245 range_length_ = length;
223 } 246 }
224 247
225 void AppCacheResponseReader::OnIOComplete(int result) { 248 void AppCacheResponseReader::OnIOComplete(int result) {
226 if (result >= 0) { 249 if (result >= 0) {
227 if (info_buffer_.get()) { 250 if (reading_metadata_size_) {
251 DCHECK(reading_metadata_size_ == result);
252 DCHECK(info_buffer_->http_info->metadata);
253 reading_metadata_size_ = 0;
254 } else if (info_buffer_.get()) {
228 // Deserialize the http info structure, ensuring we got headers. 255 // Deserialize the http info structure, ensuring we got headers.
229 Pickle pickle(buffer_->data(), result); 256 Pickle pickle(buffer_->data(), result);
230 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); 257 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
231 bool response_truncated = false; 258 bool response_truncated = false;
232 if (!info->InitFromPickle(pickle, &response_truncated) || 259 if (!info->InitFromPickle(pickle, &response_truncated) ||
233 !info->headers.get()) { 260 !info->headers.get()) {
234 InvokeUserCompletionCallback(net::ERR_FAILED); 261 InvokeUserCompletionCallback(net::ERR_FAILED);
235 return; 262 return;
236 } 263 }
237 DCHECK(!response_truncated); 264 DCHECK(!response_truncated);
238 info_buffer_->http_info.reset(info.release()); 265 info_buffer_->http_info.reset(info.release());
239 266
240 // Also return the size of the response body 267 // Also return the size of the response body
241 DCHECK(entry_); 268 DCHECK(entry_);
242 info_buffer_->response_data_size = 269 info_buffer_->response_data_size =
243 entry_->GetSize(kResponseContentIndex); 270 entry_->GetSize(kResponseContentIndex);
271
272 int64 metadata_size = entry_->GetSize(kResponseMetadataIndex);
273 if (metadata_size > 0) {
274 reading_metadata_size_ = metadata_size;
275 info_buffer_->http_info->metadata =
276 new net::IOBufferWithSize(metadata_size);
277 ReadRaw(kResponseMetadataIndex, 0,
278 info_buffer_->http_info->metadata.get(), metadata_size);
279 return;
280 }
244 } else { 281 } else {
245 read_position_ += result; 282 read_position_ += result;
246 } 283 }
247 } 284 }
248 InvokeUserCompletionCallback(result); 285 InvokeUserCompletionCallback(result);
249 } 286 }
250 287
251 void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { 288 void AppCacheResponseReader::OnOpenEntryComplete() {
252 int rv; 289 if (!entry_) {
253 AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; 290 ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
254 if (entry_) { 291 return;
255 rv = net::OK;
256 } else if (!disk_cache_) {
257 rv = net::ERR_FAILED;
258 } else {
259 entry_ptr = new AppCacheDiskCacheInterface::Entry*;
260 open_callback_ =
261 base::Bind(&AppCacheResponseReader::OnOpenEntryComplete,
262 weak_factory_.GetWeakPtr(), base::Owned(entry_ptr));
263 rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_);
264 } 292 }
265
266 if (rv != net::ERR_IO_PENDING)
267 OnOpenEntryComplete(entry_ptr, rv);
268 }
269
270 void AppCacheResponseReader::OnOpenEntryComplete(
271 AppCacheDiskCacheInterface::Entry** entry, int rv) {
272 DCHECK(info_buffer_.get() || buffer_.get());
273
274 if (!open_callback_.is_null()) {
275 if (rv == net::OK) {
276 DCHECK(entry);
277 entry_ = *entry;
278 }
279 open_callback_.Reset();
280 }
281
282 if (info_buffer_.get()) 293 if (info_buffer_.get())
283 ContinueReadInfo(); 294 ContinueReadInfo();
284 else 295 else
285 ContinueReadData(); 296 ContinueReadData();
286 } 297 }
287 298
288 // AppCacheResponseWriter ---------------------------------------------- 299 // AppCacheResponseWriter ----------------------------------------------
289 300
290 AppCacheResponseWriter::AppCacheResponseWriter( 301 AppCacheResponseWriter::AppCacheResponseWriter(
291 int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) 302 int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache)
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 430
420 create_callback_.Reset(); 431 create_callback_.Reset();
421 } 432 }
422 433
423 if (info_buffer_.get()) 434 if (info_buffer_.get())
424 ContinueWriteInfo(); 435 ContinueWriteInfo();
425 else 436 else
426 ContinueWriteData(); 437 ContinueWriteData();
427 } 438 }
428 439
440 // AppCacheResponseMetadataWriter ----------------------------------------------
441
442 AppCacheResponseMetadataWriter::AppCacheResponseMetadataWriter(
443 int64 response_id,
444 int64 group_id,
445 AppCacheDiskCacheInterface* disk_cache)
446 : AppCacheResponseIO(response_id, group_id, disk_cache),
447 write_amount_(0),
448 weak_factory_(this) {
449 }
450
451 AppCacheResponseMetadataWriter::~AppCacheResponseMetadataWriter() {
452 }
453
454 void AppCacheResponseMetadataWriter::WriteMetadata(
455 net::IOBuffer* buf,
456 int buf_len,
457 const net::CompletionCallback& callback) {
458 DCHECK(!callback.is_null());
459 DCHECK(!IsIOPending());
460 DCHECK(buf);
461 DCHECK(buf_len >= 0);
462 DCHECK(!buffer_.get());
463
464 buffer_ = buf;
465 write_amount_ = buf_len;
466 callback_ = callback; // cleared on completion
467 OpenEntryIfNeeded();
468 }
469
470 void AppCacheResponseMetadataWriter::OnOpenEntryComplete() {
471 if (!entry_) {
472 ScheduleIOCompletionCallback(net::ERR_FAILED);
473 return;
474 }
475 WriteRaw(kResponseMetadataIndex, 0, buffer_.get(), write_amount_);
476 }
477
478 void AppCacheResponseMetadataWriter::OnIOComplete(int result) {
479 DCHECK(result < 0 || write_amount_ == result);
480 InvokeUserCompletionCallback(result);
481 }
482
429 } // namespace content 483 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/appcache/appcache_response.h ('k') | content/browser/appcache/appcache_response_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698