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