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