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