OLD | NEW |
---|---|
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 |
142 | 139 |
143 // AppCacheResponseReader ---------------------------------------------- | 140 // AppCacheResponseReader ---------------------------------------------- |
144 | 141 |
145 AppCacheResponseReader::AppCacheResponseReader( | 142 AppCacheResponseReader::AppCacheResponseReader( |
146 int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) | 143 int64 response_id, |
144 int64 group_id, | |
145 AppCacheDiskCacheInterface* disk_cache) | |
147 : AppCacheResponseIO(response_id, group_id, disk_cache), | 146 : AppCacheResponseIO(response_id, group_id, disk_cache), |
148 range_offset_(0), | 147 range_offset_(0), |
149 range_length_(kint32max), | 148 range_length_(kint32max), |
150 read_position_(0), | 149 read_position_(0), |
150 reading_metadata_size_(0), | |
151 weak_factory_(this) { | 151 weak_factory_(this) { |
152 } | 152 } |
153 | 153 |
154 AppCacheResponseReader::~AppCacheResponseReader() { | 154 AppCacheResponseReader::~AppCacheResponseReader() { |
155 } | 155 } |
156 | 156 |
157 void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, | 157 void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, |
158 const net::CompletionCallback& callback) { | 158 const net::CompletionCallback& callback) { |
159 DCHECK(!callback.is_null()); | 159 DCHECK(!callback.is_null()); |
160 DCHECK(!IsReadPending()); | 160 DCHECK(!IsReadPending()); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 } | 217 } |
218 | 218 |
219 void AppCacheResponseReader::SetReadRange(int offset, int length) { | 219 void AppCacheResponseReader::SetReadRange(int offset, int length) { |
220 DCHECK(!IsReadPending() && !read_position_); | 220 DCHECK(!IsReadPending() && !read_position_); |
221 range_offset_ = offset; | 221 range_offset_ = offset; |
222 range_length_ = length; | 222 range_length_ = length; |
223 } | 223 } |
224 | 224 |
225 void AppCacheResponseReader::OnIOComplete(int result) { | 225 void AppCacheResponseReader::OnIOComplete(int result) { |
226 if (result >= 0) { | 226 if (result >= 0) { |
227 if (info_buffer_.get()) { | 227 if (reading_metadata_size_) { |
228 DCHECK(reading_metadata_size_ == result); | |
229 DCHECK(info_buffer_->http_info->metadata); | |
230 reading_metadata_size_ = 0; | |
231 } else if (info_buffer_.get()) { | |
228 // Deserialize the http info structure, ensuring we got headers. | 232 // Deserialize the http info structure, ensuring we got headers. |
229 Pickle pickle(buffer_->data(), result); | 233 Pickle pickle(buffer_->data(), result); |
230 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); | 234 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); |
231 bool response_truncated = false; | 235 bool response_truncated = false; |
232 if (!info->InitFromPickle(pickle, &response_truncated) || | 236 if (!info->InitFromPickle(pickle, &response_truncated) || |
233 !info->headers.get()) { | 237 !info->headers.get()) { |
234 InvokeUserCompletionCallback(net::ERR_FAILED); | 238 InvokeUserCompletionCallback(net::ERR_FAILED); |
235 return; | 239 return; |
236 } | 240 } |
237 DCHECK(!response_truncated); | 241 DCHECK(!response_truncated); |
238 info_buffer_->http_info.reset(info.release()); | 242 info_buffer_->http_info.reset(info.release()); |
239 | 243 |
240 // Also return the size of the response body | 244 // Also return the size of the response body |
241 DCHECK(entry_); | 245 DCHECK(entry_); |
242 info_buffer_->response_data_size = | 246 info_buffer_->response_data_size = |
243 entry_->GetSize(kResponseContentIndex); | 247 entry_->GetSize(kResponseContentIndex); |
248 | |
249 int64 metadata_size = entry_->GetSize(kResponseMetadataIndex); | |
250 if (metadata_size > 0) { | |
251 reading_metadata_size_ = metadata_size; | |
252 info_buffer_->http_info->metadata = | |
253 new net::IOBufferWithSize(metadata_size); | |
254 ReadRaw(kResponseMetadataIndex, 0, | |
255 info_buffer_->http_info->metadata.get(), metadata_size); | |
256 return; | |
257 } | |
244 } else { | 258 } else { |
245 read_position_ += result; | 259 read_position_ += result; |
246 } | 260 } |
247 } | 261 } |
248 InvokeUserCompletionCallback(result); | 262 InvokeUserCompletionCallback(result); |
249 } | 263 } |
250 | 264 |
251 void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { | 265 void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { |
252 int rv; | 266 int rv; |
253 AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; | 267 AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 | 433 |
420 create_callback_.Reset(); | 434 create_callback_.Reset(); |
421 } | 435 } |
422 | 436 |
423 if (info_buffer_.get()) | 437 if (info_buffer_.get()) |
424 ContinueWriteInfo(); | 438 ContinueWriteInfo(); |
425 else | 439 else |
426 ContinueWriteData(); | 440 ContinueWriteData(); |
427 } | 441 } |
428 | 442 |
443 // AppCacheResponseMetadataWriter ---------------------------------------------- | |
444 | |
445 AppCacheResponseMetadataWriter::AppCacheResponseMetadataWriter( | |
446 int64 response_id, | |
447 int64 group_id, | |
448 AppCacheDiskCacheInterface* disk_cache) | |
449 : AppCacheResponseIO(response_id, group_id, disk_cache), | |
450 started_(false), | |
451 write_amount_(0), | |
452 weak_factory_(this) { | |
453 } | |
454 | |
455 AppCacheResponseMetadataWriter::~AppCacheResponseMetadataWriter() { | |
456 } | |
457 | |
458 void AppCacheResponseMetadataWriter::WriteMetadata( | |
459 net::IOBuffer* buf, | |
460 int buf_len, | |
461 const net::CompletionCallback& callback) { | |
462 DCHECK(!callback.is_null()); | |
463 DCHECK(!IsIOPending()); | |
464 DCHECK(buf); | |
465 DCHECK(buf_len >= 0); | |
466 DCHECK(!buffer_.get()); | |
467 DCHECK(!started_); | |
468 | |
469 started_ = true; | |
470 buffer_ = buf; | |
471 write_amount_ = buf_len; | |
472 callback_ = callback; // cleared on completion | |
473 OpenEntry(); | |
474 } | |
475 | |
476 void AppCacheResponseMetadataWriter::OpenEntry() { | |
michaeln
2015/02/18 02:18:59
It'd be nice to hoist this method and the followin
horo
2015/02/18 03:33:44
Sounds good!
done.
| |
477 int rv; | |
478 DCHECK(!entry_); | |
479 DCHECK(disk_cache_); | |
480 AppCacheDiskCacheInterface::Entry** entry_ptr = | |
481 new AppCacheDiskCacheInterface::Entry*; | |
482 open_callback_ = | |
483 base::Bind(&AppCacheResponseMetadataWriter::OnOpenEntryComplete, | |
484 weak_factory_.GetWeakPtr(), base::Owned(entry_ptr)); | |
485 rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_); | |
486 if (rv != net::ERR_IO_PENDING) | |
487 OnOpenEntryComplete(entry_ptr, rv); | |
488 } | |
489 | |
490 void AppCacheResponseMetadataWriter::OnOpenEntryComplete( | |
491 AppCacheDiskCacheInterface::Entry** entry, | |
492 int rv) { | |
493 DCHECK(buffer_.get()); | |
494 if (!open_callback_.is_null()) { | |
495 if (rv == net::OK) { | |
496 DCHECK(entry); | |
497 entry_ = *entry; | |
498 } | |
499 open_callback_.Reset(); | |
500 } | |
501 if (!entry_) { | |
502 ScheduleIOCompletionCallback(net::ERR_FAILED); | |
503 return; | |
504 } | |
505 WriteRaw(kResponseMetadataIndex, 0, buffer_.get(), write_amount_); | |
michaeln
2015/02/18 02:18:59
and have it call a virtual method here to continue
horo
2015/02/18 03:33:44
Done.
| |
506 } | |
507 | |
508 void AppCacheResponseMetadataWriter::OnIOComplete(int result) { | |
509 DCHECK(result < 0 || write_amount_ == result); | |
510 InvokeUserCompletionCallback(result); | |
511 } | |
512 | |
429 } // namespace content | 513 } // namespace content |
OLD | NEW |