• 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 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 
is_waiting()49   bool is_waiting() const {
50     return delivery_type_ == AWAITING_DELIVERY_ORDERS;
51   }
52 
is_delivering_appcache_response()53   bool is_delivering_appcache_response() const {
54     return delivery_type_ == APPCACHED_DELIVERY;
55   }
56 
is_delivering_network_response()57   bool is_delivering_network_response() const {
58     return delivery_type_ == NETWORK_DELIVERY;
59   }
60 
is_delivering_error_response()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.
manifest_url()68   const GURL& manifest_url() const { return manifest_url_; }
group_id()69   int64 group_id() const { return group_id_; }
cache_id()70   int64 cache_id() const { return cache_id_; }
entry()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.
has_been_started()78   bool has_been_started() const {
79     return has_been_started_;
80   }
81 
82   // Returns true if the job has been killed.
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.
cache_entry_not_found()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.
has_delivery_orders()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;
is_range_request()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