1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/common/appcache_interfaces.h"
#include "content/common/content_export.h"
#include "net/base/completion_callback.h"
#include "net/http/http_response_info.h"
#include "url/gurl.h"
namespace net {
class IOBuffer;
}
namespace content {
class AppCacheStorage;
class MockAppCacheStorage;
static const int kUnkownResponseDataSize = -1;
// Response info for a particular response id. Instances are tracked in
// the working set.
class CONTENT_EXPORT AppCacheResponseInfo
: public base::RefCounted<AppCacheResponseInfo> {
public:
// AppCacheResponseInfo takes ownership of the http_info.
AppCacheResponseInfo(AppCacheStorage* storage, const GURL& manifest_url,
int64 response_id, net::HttpResponseInfo* http_info,
int64 response_data_size);
const GURL& manifest_url() const { return manifest_url_; }
int64 response_id() const { return response_id_; }
const net::HttpResponseInfo* http_response_info() const {
return http_response_info_.get();
}
int64 response_data_size() const { return response_data_size_; }
private:
friend class base::RefCounted<AppCacheResponseInfo>;
virtual ~AppCacheResponseInfo();
const GURL manifest_url_;
const int64 response_id_;
const scoped_ptr<net::HttpResponseInfo> http_response_info_;
const int64 response_data_size_;
AppCacheStorage* storage_;
};
// A refcounted wrapper for HttpResponseInfo so we can apply the
// refcounting semantics used with IOBuffer with these structures too.
struct CONTENT_EXPORT HttpResponseInfoIOBuffer
: public base::RefCountedThreadSafe<HttpResponseInfoIOBuffer> {
scoped_ptr<net::HttpResponseInfo> http_info;
int response_data_size;
HttpResponseInfoIOBuffer();
explicit HttpResponseInfoIOBuffer(net::HttpResponseInfo* info);
protected:
friend class base::RefCountedThreadSafe<HttpResponseInfoIOBuffer>;
virtual ~HttpResponseInfoIOBuffer();
};
// Low level storage API used by the response reader and writer.
class CONTENT_EXPORT AppCacheDiskCacheInterface {
public:
class Entry {
public:
virtual int Read(int index, int64 offset, net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) = 0;
virtual int Write(int index, int64 offset, net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) = 0;
virtual int64 GetSize(int index) = 0;
virtual void Close() = 0;
protected:
virtual ~Entry() {}
};
virtual int CreateEntry(int64 key, Entry** entry,
const net::CompletionCallback& callback) = 0;
virtual int OpenEntry(int64 key, Entry** entry,
const net::CompletionCallback& callback) = 0;
virtual int DoomEntry(int64 key, const net::CompletionCallback& callback) = 0;
protected:
friend class base::RefCounted<AppCacheDiskCacheInterface>;
virtual ~AppCacheDiskCacheInterface() {}
};
// Common base class for response reader and writer.
class CONTENT_EXPORT AppCacheResponseIO {
public:
virtual ~AppCacheResponseIO();
int64 response_id() const { return response_id_; }
protected:
AppCacheResponseIO(int64 response_id,
int64 group_id,
AppCacheDiskCacheInterface* disk_cache);
virtual void OnIOComplete(int result) = 0;
bool IsIOPending() { return !callback_.is_null(); }
void ScheduleIOCompletionCallback(int result);
void InvokeUserCompletionCallback(int result);
void ReadRaw(int index, int offset, net::IOBuffer* buf, int buf_len);
void WriteRaw(int index, int offset, net::IOBuffer* buf, int buf_len);
const int64 response_id_;
const int64 group_id_;
AppCacheDiskCacheInterface* disk_cache_;
AppCacheDiskCacheInterface::Entry* entry_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
scoped_refptr<net::IOBuffer> buffer_;
int buffer_len_;
net::CompletionCallback callback_;
base::WeakPtrFactory<AppCacheResponseIO> weak_factory_;
private:
void OnRawIOComplete(int result);
};
// Reads existing response data from storage. If the object is deleted
// and there is a read in progress, the implementation will return
// immediately but will take care of any side effect of cancelling the
// operation. In other words, instances are safe to delete at will.
class CONTENT_EXPORT AppCacheResponseReader
: public AppCacheResponseIO {
public:
~AppCacheResponseReader() override;
// Reads http info from storage. Always returns the result of the read
// asynchronously through the 'callback'. Returns the number of bytes read
// or a net:: error code. Guaranteed to not perform partial reads of
// the info data. The reader acquires a reference to the 'info_buf' until
// completion at which time the callback is invoked with either a negative
// error code or the number of bytes read. The 'info_buf' argument should
// contain a NULL http_info when ReadInfo is called. The 'callback' is a
// required parameter.
// Should only be called where there is no Read operation in progress.
// (virtual for testing)
virtual void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
const net::CompletionCallback& callback);
// Reads data from storage. Always returns the result of the read
// asynchronously through the 'callback'. Returns the number of bytes read
// or a net:: error code. EOF is indicated with a return value of zero.
// The reader acquires a reference to the provided 'buf' until completion
// at which time the callback is invoked with either a negative error code
// or the number of bytes read. The 'callback' is a required parameter.
// Should only be called where there is no Read operation in progress.
// (virtual for testing)
virtual void ReadData(net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback);
// Returns true if there is a read operation, for data or info, pending.
bool IsReadPending() { return IsIOPending(); }
// Used to support range requests. If not called, the reader will
// read the entire response body. If called, this must be called prior
// to the first call to the ReadData method.
void SetReadRange(int offset, int length);
protected:
friend class AppCacheStorageImpl;
friend class content::MockAppCacheStorage;
// Should only be constructed by the storage class and derivatives.
AppCacheResponseReader(int64 response_id,
int64 group_id,
AppCacheDiskCacheInterface* disk_cache);
void OnIOComplete(int result) override;
void ContinueReadInfo();
void ContinueReadData();
void OpenEntryIfNeededAndContinue();
void OnOpenEntryComplete(AppCacheDiskCacheInterface::Entry** entry, int rv);
int range_offset_;
int range_length_;
int read_position_;
net::CompletionCallback open_callback_;
base::WeakPtrFactory<AppCacheResponseReader> weak_factory_;
};
// Writes new response data to storage. If the object is deleted
// and there is a write in progress, the implementation will return
// immediately but will take care of any side effect of cancelling the
// operation. In other words, instances are safe to delete at will.
class CONTENT_EXPORT AppCacheResponseWriter
: public AppCacheResponseIO {
public:
~AppCacheResponseWriter() override;
// Writes the http info to storage. Always returns the result of the write
// asynchronously through the 'callback'. Returns the number of bytes written
// or a net:: error code. The writer acquires a reference to the 'info_buf'
// until completion at which time the callback is invoked with either a
// negative error code or the number of bytes written. The 'callback' is a
// required parameter. The contents of 'info_buf' are not modified.
// Should only be called where there is no Write operation in progress.
void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
const net::CompletionCallback& callback);
// Writes data to storage. Always returns the result of the write
// asynchronously through the 'callback'. Returns the number of bytes written
// or a net:: error code. Guaranteed to not perform partial writes.
// The writer acquires a reference to the provided 'buf' until completion at
// which time the callback is invoked with either a negative error code or
// the number of bytes written. The 'callback' is a required parameter.
// The contents of 'buf' are not modified.
// Should only be called where there is no Write operation in progress.
void WriteData(net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback);
// Returns true if there is a write pending.
bool IsWritePending() { return IsIOPending(); }
// Returns the amount written, info and data.
int64 amount_written() { return info_size_ + write_position_; }
protected:
// Should only be constructed by the storage class and derivatives.
AppCacheResponseWriter(int64 response_id,
int64 group_id,
AppCacheDiskCacheInterface* disk_cache);
private:
friend class AppCacheStorageImpl;
friend class content::MockAppCacheStorage;
enum CreationPhase {
NO_ATTEMPT,
INITIAL_ATTEMPT,
DOOM_EXISTING,
SECOND_ATTEMPT
};
void OnIOComplete(int result) override;
void ContinueWriteInfo();
void ContinueWriteData();
void CreateEntryIfNeededAndContinue();
void OnCreateEntryComplete(AppCacheDiskCacheInterface::Entry** entry, int rv);
int info_size_;
int write_position_;
int write_amount_;
CreationPhase creation_phase_;
net::CompletionCallback create_callback_;
base::WeakPtrFactory<AppCacheResponseWriter> weak_factory_;
};
} // namespace content
#endif // CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
|