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 47 bool is_waiting() const { 48 return delivery_type_ == AWAITING_DELIVERY_ORDERS; 49 } 50 51 bool is_delivering_appcache_response() const { 52 return delivery_type_ == APPCACHED_DELIVERY; 53 } 54 55 bool is_delivering_network_response() const { 56 return delivery_type_ == NETWORK_DELIVERY; 57 } 58 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. 66 const GURL& manifest_url() const { return manifest_url_; } 67 int64 group_id() const { return group_id_; } 68 int64 cache_id() const { return cache_id_; } 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. 76 bool has_been_started() const { 77 return has_been_started_; 78 } 79 80 // Returns true if the job 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. 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. 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; 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