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