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