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