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 CONTENT_BROWSER_APPCACHE_APPCACHE_URL_REQUEST_JOB_H_
      6 #define CONTENT_BROWSER_APPCACHE_APPCACHE_URL_REQUEST_JOB_H_
      7 
      8 #include <string>
      9 
     10 #include "base/memory/weak_ptr.h"
     11 #include "content/browser/appcache/appcache_entry.h"
     12 #include "content/browser/appcache/appcache_executable_handler.h"
     13 #include "content/browser/appcache/appcache_response.h"
     14 #include "content/browser/appcache/appcache_storage.h"
     15 #include "content/common/content_export.h"
     16 #include "net/http/http_byte_range.h"
     17 #include "net/url_request/url_request_job.h"
     18 
     19 namespace net {
     20 class GrowableIOBuffer;
     21 };
     22 
     23 namespace content {
     24 class AppCacheHost;
     25 class AppCacheRequestHandlerTest;
     26 class AppCacheURLRequestJobTest;
     27 
     28 // A net::URLRequestJob derivative that knows how to return a response stored
     29 // in the appcache.
     30 class CONTENT_EXPORT AppCacheURLRequestJob
     31     : public net::URLRequestJob,
     32       public AppCacheStorage::Delegate {
     33  public:
     34   AppCacheURLRequestJob(net::URLRequest* request,
     35                         net::NetworkDelegate* network_delegate,
     36                         AppCacheStorage* storage,
     37                         AppCacheHost* host,
     38                         bool is_main_resource);
     39 
     40   // Informs the job of what response it should deliver. Only one of these
     41   // methods should be called, and only once per job. A job will sit idle and
     42   // wait indefinitely until one of the deliver methods is called.
     43   void DeliverAppCachedResponse(const GURL& manifest_url, int64 group_id,
     44                                 int64 cache_id, const AppCacheEntry& entry,
     45                                 bool is_fallback);
     46   void DeliverNetworkResponse();
     47   void DeliverErrorResponse();
     48 
     49   bool is_waiting() const {
     50     return delivery_type_ == AWAITING_DELIVERY_ORDERS;
     51   }
     52 
     53   bool is_delivering_appcache_response() const {
     54     return delivery_type_ == APPCACHED_DELIVERY;
     55   }
     56 
     57   bool is_delivering_network_response() const {
     58     return delivery_type_ == NETWORK_DELIVERY;
     59   }
     60 
     61   bool is_delivering_error_response() const {
     62     return delivery_type_ == ERROR_DELIVERY;
     63   }
     64 
     65   // Accessors for the info about the appcached response, if any,
     66   // that this job has been instructed to deliver. These are only
     67   // valid to call if is_delivering_appcache_response.
     68   const GURL& manifest_url() const { return manifest_url_; }
     69   int64 group_id() const { return group_id_; }
     70   int64 cache_id() const { return cache_id_; }
     71   const AppCacheEntry& entry() const { return entry_; }
     72 
     73   // net::URLRequestJob's Kill method is made public so the users of this
     74   // class in the appcache namespace can call it.
     75   virtual void Kill() OVERRIDE;
     76 
     77   // Returns true if the job has been started by the net library.
     78   bool has_been_started() const {
     79     return has_been_started_;
     80   }
     81 
     82   // Returns true if the job has been killed.
     83   bool has_been_killed() const {
     84     return has_been_killed_;
     85   }
     86 
     87   // Returns true if the cache entry was not found in the disk cache.
     88   bool cache_entry_not_found() const {
     89     return cache_entry_not_found_;
     90   }
     91 
     92  protected:
     93   virtual ~AppCacheURLRequestJob();
     94 
     95  private:
     96   friend class content::AppCacheRequestHandlerTest;
     97   friend class content::AppCacheURLRequestJobTest;
     98 
     99   enum DeliveryType {
    100     AWAITING_DELIVERY_ORDERS,
    101     APPCACHED_DELIVERY,
    102     NETWORK_DELIVERY,
    103     ERROR_DELIVERY
    104   };
    105 
    106   // Returns true if one of the Deliver methods has been called.
    107   bool has_delivery_orders() const {
    108     return !is_waiting();
    109   }
    110 
    111   void MaybeBeginDelivery();
    112   void BeginDelivery();
    113 
    114   // For executable response handling.
    115   void BeginExecutableHandlerDelivery();
    116   void OnExecutableSourceLoaded(int result);
    117   void InvokeExecutableHandler(AppCacheExecutableHandler* handler);
    118   void OnExecutableResponseCallback(
    119       const AppCacheExecutableHandler::Response& response);
    120   void BeginErrorDelivery(const char* message);
    121 
    122   // AppCacheStorage::Delegate methods
    123   virtual void OnResponseInfoLoaded(
    124       AppCacheResponseInfo* response_info, int64 response_id) OVERRIDE;
    125   virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE;
    126 
    127   const net::HttpResponseInfo* http_info() const;
    128   bool is_range_request() const { return range_requested_.IsValid(); }
    129   void SetupRangeResponse();
    130 
    131   // AppCacheResponseReader completion callback
    132   void OnReadComplete(int result);
    133 
    134   // net::URLRequestJob methods, see url_request_job.h for doc comments
    135   virtual void Start() OVERRIDE;
    136   virtual net::LoadState GetLoadState() const OVERRIDE;
    137   virtual bool GetCharset(std::string* charset) OVERRIDE;
    138   virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
    139   virtual bool ReadRawData(net::IOBuffer* buf,
    140                            int buf_size,
    141                            int *bytes_read) OVERRIDE;
    142 
    143   // Sets extra request headers for Job types that support request headers.
    144   // This is how we get informed of range-requests.
    145   virtual void SetExtraRequestHeaders(
    146       const net::HttpRequestHeaders& headers) OVERRIDE;
    147 
    148   // FilterContext methods
    149   virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
    150   virtual int GetResponseCode() const OVERRIDE;
    151 
    152   AppCacheHost* host_;
    153   AppCacheStorage* storage_;
    154   base::TimeTicks start_time_tick_;
    155   bool has_been_started_;
    156   bool has_been_killed_;
    157   DeliveryType delivery_type_;
    158   GURL manifest_url_;
    159   int64 group_id_;
    160   int64 cache_id_;
    161   AppCacheEntry entry_;
    162   bool is_fallback_;
    163   bool is_main_resource_;  // Used for histogram logging.
    164   bool cache_entry_not_found_;
    165   scoped_refptr<AppCacheResponseInfo> info_;
    166   scoped_refptr<net::GrowableIOBuffer> handler_source_buffer_;
    167   scoped_ptr<AppCacheResponseReader> handler_source_reader_;
    168   net::HttpByteRange range_requested_;
    169   scoped_ptr<net::HttpResponseInfo> range_response_info_;
    170   scoped_ptr<AppCacheResponseReader> reader_;
    171   scoped_refptr<AppCache> cache_;
    172   scoped_refptr<AppCacheGroup> group_;
    173   base::WeakPtrFactory<AppCacheURLRequestJob> weak_factory_;
    174 };
    175 
    176 }  // namespace content
    177 
    178 #endif  // CONTENT_BROWSER_APPCACHE_APPCACHE_REQUEST_HANDLER_H_
    179