Index: content/browser/appcache/appcache_response.cc |
diff --git a/content/browser/appcache/appcache_response.cc b/content/browser/appcache/appcache_response.cc |
index c38d3afa29305830e595b4c4adeb95207bf50f02..d53f94174bad0fa5f1935f3a2b3050355371834f 100644 |
--- a/content/browser/appcache/appcache_response.cc |
+++ b/content/browser/appcache/appcache_response.cc |
@@ -22,10 +22,7 @@ namespace content { |
namespace { |
// Disk cache entry data indices. |
-enum { |
- kResponseInfoIndex, |
- kResponseContentIndex |
-}; |
+enum { kResponseInfoIndex, kResponseContentIndex, kResponseMetadataIndex }; |
// An IOBuffer that wraps a pickle's data. Ownership of the |
// pickle is transfered to the WrappedPickleIOBuffer object. |
@@ -139,15 +136,51 @@ void AppCacheResponseIO::OnRawIOComplete(int result) { |
OnIOComplete(result); |
} |
+void AppCacheResponseIO::OpenEntryIfNeeded() { |
+ int rv; |
+ AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; |
+ if (entry_) { |
+ rv = net::OK; |
+ } else if (!disk_cache_) { |
+ rv = net::ERR_FAILED; |
+ } else { |
+ entry_ptr = new AppCacheDiskCacheInterface::Entry*; |
+ open_callback_ = |
+ base::Bind(&AppCacheResponseIO::OpenEntryCallback, |
+ weak_factory_.GetWeakPtr(), base::Owned(entry_ptr)); |
+ rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_); |
+ } |
+ |
+ if (rv != net::ERR_IO_PENDING) |
+ OpenEntryCallback(entry_ptr, rv); |
+} |
+ |
+void AppCacheResponseIO::OpenEntryCallback( |
+ AppCacheDiskCacheInterface::Entry** entry, int rv) { |
+ DCHECK(info_buffer_.get() || buffer_.get()); |
+ |
+ if (!open_callback_.is_null()) { |
+ if (rv == net::OK) { |
+ DCHECK(entry); |
+ entry_ = *entry; |
+ } |
+ open_callback_.Reset(); |
+ } |
+ OnOpenEntryComplete(); |
+} |
+ |
// AppCacheResponseReader ---------------------------------------------- |
AppCacheResponseReader::AppCacheResponseReader( |
- int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) |
+ int64 response_id, |
+ int64 group_id, |
+ AppCacheDiskCacheInterface* disk_cache) |
: AppCacheResponseIO(response_id, group_id, disk_cache), |
range_offset_(0), |
range_length_(kint32max), |
read_position_(0), |
+ reading_metadata_size_(0), |
weak_factory_(this) { |
} |
@@ -165,15 +198,10 @@ void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, |
info_buffer_ = info_buf; |
callback_ = callback; // cleared on completion |
- OpenEntryIfNeededAndContinue(); |
+ OpenEntryIfNeeded(); |
} |
void AppCacheResponseReader::ContinueReadInfo() { |
- if (!entry_) { |
- ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); |
- return; |
- } |
- |
int size = entry_->GetSize(kResponseInfoIndex); |
if (size <= 0) { |
ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); |
@@ -196,15 +224,10 @@ void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len, |
buffer_ = buf; |
buffer_len_ = buf_len; |
callback_ = callback; // cleared on completion |
- OpenEntryIfNeededAndContinue(); |
+ OpenEntryIfNeeded(); |
} |
void AppCacheResponseReader::ContinueReadData() { |
- if (!entry_) { |
- ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); |
- return; |
- } |
- |
if (read_position_ + buffer_len_ > range_length_) { |
// TODO(michaeln): What about integer overflows? |
DCHECK(range_length_ >= read_position_); |
@@ -224,7 +247,11 @@ void AppCacheResponseReader::SetReadRange(int offset, int length) { |
void AppCacheResponseReader::OnIOComplete(int result) { |
if (result >= 0) { |
- if (info_buffer_.get()) { |
+ if (reading_metadata_size_) { |
+ DCHECK(reading_metadata_size_ == result); |
+ DCHECK(info_buffer_->http_info->metadata); |
+ reading_metadata_size_ = 0; |
+ } else if (info_buffer_.get()) { |
// Deserialize the http info structure, ensuring we got headers. |
Pickle pickle(buffer_->data(), result); |
scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); |
@@ -241,6 +268,16 @@ void AppCacheResponseReader::OnIOComplete(int result) { |
DCHECK(entry_); |
info_buffer_->response_data_size = |
entry_->GetSize(kResponseContentIndex); |
+ |
+ int64 metadata_size = entry_->GetSize(kResponseMetadataIndex); |
+ if (metadata_size > 0) { |
+ reading_metadata_size_ = metadata_size; |
+ info_buffer_->http_info->metadata = |
+ new net::IOBufferWithSize(metadata_size); |
+ ReadRaw(kResponseMetadataIndex, 0, |
+ info_buffer_->http_info->metadata.get(), metadata_size); |
+ return; |
+ } |
} else { |
read_position_ += result; |
} |
@@ -248,37 +285,11 @@ void AppCacheResponseReader::OnIOComplete(int result) { |
InvokeUserCompletionCallback(result); |
} |
-void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { |
- int rv; |
- AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; |
- if (entry_) { |
- rv = net::OK; |
- } else if (!disk_cache_) { |
- rv = net::ERR_FAILED; |
- } else { |
- entry_ptr = new AppCacheDiskCacheInterface::Entry*; |
- open_callback_ = |
- base::Bind(&AppCacheResponseReader::OnOpenEntryComplete, |
- weak_factory_.GetWeakPtr(), base::Owned(entry_ptr)); |
- rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_); |
- } |
- |
- if (rv != net::ERR_IO_PENDING) |
- OnOpenEntryComplete(entry_ptr, rv); |
-} |
- |
-void AppCacheResponseReader::OnOpenEntryComplete( |
- AppCacheDiskCacheInterface::Entry** entry, int rv) { |
- DCHECK(info_buffer_.get() || buffer_.get()); |
- |
- if (!open_callback_.is_null()) { |
- if (rv == net::OK) { |
- DCHECK(entry); |
- entry_ = *entry; |
- } |
- open_callback_.Reset(); |
+void AppCacheResponseReader::OnOpenEntryComplete() { |
+ if (!entry_) { |
+ ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); |
+ return; |
} |
- |
if (info_buffer_.get()) |
ContinueReadInfo(); |
else |
@@ -426,4 +437,47 @@ void AppCacheResponseWriter::OnCreateEntryComplete( |
ContinueWriteData(); |
} |
+// AppCacheResponseMetadataWriter ---------------------------------------------- |
+ |
+AppCacheResponseMetadataWriter::AppCacheResponseMetadataWriter( |
+ int64 response_id, |
+ int64 group_id, |
+ AppCacheDiskCacheInterface* disk_cache) |
+ : AppCacheResponseIO(response_id, group_id, disk_cache), |
+ write_amount_(0), |
+ weak_factory_(this) { |
+} |
+ |
+AppCacheResponseMetadataWriter::~AppCacheResponseMetadataWriter() { |
+} |
+ |
+void AppCacheResponseMetadataWriter::WriteMetadata( |
+ net::IOBuffer* buf, |
+ int buf_len, |
+ const net::CompletionCallback& callback) { |
+ DCHECK(!callback.is_null()); |
+ DCHECK(!IsIOPending()); |
+ DCHECK(buf); |
+ DCHECK(buf_len >= 0); |
+ DCHECK(!buffer_.get()); |
+ |
+ buffer_ = buf; |
+ write_amount_ = buf_len; |
+ callback_ = callback; // cleared on completion |
+ OpenEntryIfNeeded(); |
+} |
+ |
+void AppCacheResponseMetadataWriter::OnOpenEntryComplete() { |
+ if (!entry_) { |
+ ScheduleIOCompletionCallback(net::ERR_FAILED); |
+ return; |
+ } |
+ WriteRaw(kResponseMetadataIndex, 0, buffer_.get(), write_amount_); |
+} |
+ |
+void AppCacheResponseMetadataWriter::OnIOComplete(int result) { |
+ DCHECK(result < 0 || write_amount_ == result); |
+ InvokeUserCompletionCallback(result); |
+} |
+ |
} // namespace content |