15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_response.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_storage.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/base/net_errors.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disk cache entry data indices.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kResponseInfoIndex,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kResponseContentIndex
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An IOBuffer that wraps a pickle's data. Ownership of the
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pickle is transfered to the WrappedPickleIOBuffer object.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WrappedPickleIOBuffer : public net::WrappedIOBuffer {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit WrappedPickleIOBuffer(const Pickle* pickle) :
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::WrappedIOBuffer(reinterpret_cast<const char*>(pickle->data())),
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pickle_(pickle) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(pickle->data());
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WrappedPickleIOBuffer() {}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<const Pickle> pickle_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // anon namespace
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseInfo ----------------------------------------------
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseInfo::AppCacheResponseInfo(
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    AppCacheStorage* storage, const GURL& manifest_url,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 response_id,  net::HttpResponseInfo* http_info,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 response_data_size)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : manifest_url_(manifest_url), response_id_(response_id),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_response_info_(http_info), response_data_size_(response_data_size),
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      storage_(storage) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(http_info);
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(response_id != kAppCacheNoResponseId);
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage_->working_set()->AddResponseInfo(this);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseInfo::~AppCacheResponseInfo() {
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage_->working_set()->RemoveResponseInfo(this);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HttpResponseInfoIOBuffer ------------------------------------------
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer()
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : response_data_size(kUnkownResponseDataSize) {}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer(net::HttpResponseInfo* info)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : http_info(info), response_data_size(kUnkownResponseDataSize) {}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() {}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseIO ----------------------------------------------
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseIO::AppCacheResponseIO(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : response_id_(response_id),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_id_(group_id),
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disk_cache_(disk_cache),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry_(NULL),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_len_(0),
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseIO::~AppCacheResponseIO() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry_)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_->Close();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::ScheduleIOCompletionCallback(int result) {
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&AppCacheResponseIO::OnIOComplete,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            weak_factory_.GetWeakPtr(), result));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::InvokeUserCompletionCallback(int result) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the user callback and buffers prior to invoking the callback
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the caller can schedule additional operations in the callback.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = NULL;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_buffer_ = NULL;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback cb = callback_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Reset();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.Run(result);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::ReadRaw(int index, int offset,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 net::IOBuffer* buf, int buf_len) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entry_);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = entry_->Read(
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index, offset, buf, buf_len,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AppCacheResponseIO::OnRawIOComplete,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != net::ERR_IO_PENDING)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(rv);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::WriteRaw(int index, int offset,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 net::IOBuffer* buf, int buf_len) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entry_);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = entry_->Write(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index, offset, buf, buf_len,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AppCacheResponseIO::OnRawIOComplete,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != net::ERR_IO_PENDING)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(rv);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::OnRawIOComplete(int result) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(net::ERR_IO_PENDING, result);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnIOComplete(result);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseReader ----------------------------------------------
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseReader::AppCacheResponseReader(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : AppCacheResponseIO(response_id, group_id, disk_cache),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      range_offset_(0),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      range_length_(kint32max),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_position_(0),
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseReader::~AppCacheResponseReader() {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const net::CompletionCallback& callback) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsReadPending());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info_buf);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!info_buf->http_info.get());
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!buffer_.get());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!info_buffer_.get());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_buffer_ = info_buf;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;  // cleared on completion
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenEntryIfNeededAndContinue();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ContinueReadInfo() {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry_)  {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = entry_->GetSize(kResponseInfoIndex);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size <= 0) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = new net::IOBuffer(size);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const net::CompletionCallback& callback) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsReadPending());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(buf);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(buf_len >= 0);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!buffer_.get());
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!info_buffer_.get());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = buf;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_len_ = buf_len;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;  // cleared on completion
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenEntryIfNeededAndContinue();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ContinueReadData() {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry_)  {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(net::ERR_CACHE_MISS);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_position_ + buffer_len_ > range_length_) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(michaeln): What about integer overflows?
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(range_length_ >= read_position_);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer_len_ = range_length_ - read_position_;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ReadRaw(kResponseContentIndex,
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          range_offset_ + read_position_,
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          buffer_.get(),
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          buffer_len_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::SetReadRange(int offset, int length) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsReadPending() && !read_position_);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  range_offset_ = offset;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  range_length_ = length;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::OnIOComplete(int result) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result >= 0) {
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (info_buffer_.get()) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Deserialize the http info structure, ensuring we got headers.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Pickle pickle(buffer_->data(), result);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool response_truncated = false;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!info->InitFromPickle(pickle, &response_truncated) ||
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          !info->headers.get()) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InvokeUserCompletionCallback(net::ERR_FAILED);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(!response_truncated);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info_buffer_->http_info.reset(info.release());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Also return the size of the response body
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(entry_);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info_buffer_->response_data_size =
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          entry_->GetSize(kResponseContentIndex);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_position_ += result;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InvokeUserCompletionCallback(result);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::OpenEntryIfNeededAndContinue() {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheDiskCacheInterface::Entry** entry_ptr = NULL;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry_) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = net::OK;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!disk_cache_) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = net::ERR_FAILED;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_ptr = new AppCacheDiskCacheInterface::Entry*;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    open_callback_ =
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheResponseReader::OnOpenEntryComplete,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr(), base::Owned(entry_ptr));
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != net::ERR_IO_PENDING)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnOpenEntryComplete(entry_ptr, rv);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::OnOpenEntryComplete(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDiskCacheInterface::Entry** entry, int rv) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info_buffer_.get() || buffer_.get());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!open_callback_.is_null()) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == net::OK) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(entry);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry_ = *entry;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    open_callback_.Reset();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (info_buffer_.get())
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContinueReadInfo();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContinueReadData();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseWriter ----------------------------------------------
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseWriter::AppCacheResponseWriter(
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : AppCacheResponseIO(response_id, group_id, disk_cache),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info_size_(0),
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_position_(0),
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_amount_(0),
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      creation_phase_(INITIAL_ATTEMPT),
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseWriter::~AppCacheResponseWriter() {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::WriteInfo(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpResponseInfoIOBuffer* info_buf,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::CompletionCallback& callback) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsWritePending());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info_buf);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info_buf->http_info.get());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!buffer_.get());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!info_buffer_.get());
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(info_buf->http_info->headers.get());
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_buffer_ = info_buf;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;  // cleared on completion
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateEntryIfNeededAndContinue();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::ContinueWriteInfo() {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry_) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(net::ERR_FAILED);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool kSkipTransientHeaders = true;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool kTruncated = false;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pickle* pickle = new Pickle;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_buffer_->http_info->Persist(pickle, kSkipTransientHeaders, kTruncated);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_amount_ = static_cast<int>(pickle->size());
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = new WrappedPickleIOBuffer(pickle);  // takes ownership of pickle
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WriteRaw(kResponseInfoIndex, 0, buffer_.get(), write_amount_);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::WriteData(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::IOBuffer* buf, int buf_len, const net::CompletionCallback& callback) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsWritePending());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(buf);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(buf_len >= 0);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!buffer_.get());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!info_buffer_.get());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = buf;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_amount_ = buf_len;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;  // cleared on completion
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateEntryIfNeededAndContinue();
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::ContinueWriteData() {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry_) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleIOCompletionCallback(net::ERR_FAILED);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WriteRaw(
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kResponseContentIndex, write_position_, buffer_.get(), write_amount_);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::OnIOComplete(int result) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result >= 0) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(write_amount_ == result);
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!info_buffer_.get())
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_position_ += result;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info_size_ = result;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InvokeUserCompletionCallback(result);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::CreateEntryIfNeededAndContinue() {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheDiskCacheInterface::Entry** entry_ptr = NULL;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry_) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    creation_phase_ = NO_ATTEMPT;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = net::OK;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!disk_cache_) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    creation_phase_ = NO_ATTEMPT;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = net::ERR_FAILED;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    creation_phase_ = INITIAL_ATTEMPT;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_ptr = new AppCacheDiskCacheInterface::Entry*;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_callback_ =
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheResponseWriter::OnCreateEntryComplete,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr(), base::Owned(entry_ptr));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = disk_cache_->CreateEntry(response_id_, entry_ptr, create_callback_);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != net::ERR_IO_PENDING)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnCreateEntryComplete(entry_ptr, rv);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::OnCreateEntryComplete(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDiskCacheInterface::Entry** entry, int rv) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info_buffer_.get() || buffer_.get());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (creation_phase_ == INITIAL_ATTEMPT) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != net::OK) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We may try to overwrite existing entries.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      creation_phase_ = DOOM_EXISTING;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rv = disk_cache_->DoomEntry(response_id_, create_callback_);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv != net::ERR_IO_PENDING)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        OnCreateEntryComplete(NULL, rv);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (creation_phase_ == DOOM_EXISTING) {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    creation_phase_ = SECOND_ATTEMPT;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDiskCacheInterface::Entry** entry_ptr =
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new AppCacheDiskCacheInterface::Entry*;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_callback_ =
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheResponseWriter::OnCreateEntryComplete,
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr(), base::Owned(entry_ptr));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = disk_cache_->CreateEntry(response_id_, entry_ptr, create_callback_);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != net::ERR_IO_PENDING)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OnCreateEntryComplete(entry_ptr, rv);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!create_callback_.is_null()) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == net::OK)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry_ = *entry;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_callback_.Reset();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (info_buffer_.get())
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContinueWriteInfo();
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContinueWriteData();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
424