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