Home | History | Annotate | Download | only in appcache
      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