[email protected] | f90bf0d9 | 2011-01-13 02:12:44 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "webkit/appcache/appcache_request_handler.h" |
| 6 | |
| 7 | #include "net/url_request/url_request.h" |
| 8 | #include "net/url_request/url_request_job.h" |
| 9 | #include "webkit/appcache/appcache.h" |
[email protected] | 0a60884 | 2011-09-08 10:55:19 | [diff] [blame] | 10 | #include "webkit/appcache/appcache_policy.h" |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 11 | #include "webkit/appcache/appcache_url_request_job.h" |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 12 | |
| 13 | namespace appcache { |
| 14 | |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 15 | AppCacheRequestHandler::AppCacheRequestHandler( |
| 16 | AppCacheHost* host, ResourceType::Type resource_type) |
[email protected] | 15f9cded | 2010-05-20 20:51:06 | [diff] [blame] | 17 | : host_(host), resource_type_(resource_type), |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 18 | is_waiting_for_cache_selection_(false), found_group_id_(0), |
| 19 | found_cache_id_(0), found_network_namespace_(false), |
[email protected] | 17d64785 | 2012-09-08 17:45:52 | [diff] [blame] | 20 | cache_entry_not_found_(false), maybe_load_resource_executed_(false) { |
[email protected] | 7e8e3dd | 2009-09-18 01:05:09 | [diff] [blame] | 21 | DCHECK(host_); |
| 22 | host_->AddObserver(this); |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 23 | } |
| 24 | |
[email protected] | 7e8e3dd | 2009-09-18 01:05:09 | [diff] [blame] | 25 | AppCacheRequestHandler::~AppCacheRequestHandler() { |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 26 | if (host_) { |
| 27 | storage()->CancelDelegateCallbacks(this); |
[email protected] | 7e8e3dd | 2009-09-18 01:05:09 | [diff] [blame] | 28 | host_->RemoveObserver(this); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 29 | } |
| 30 | } |
| 31 | |
[email protected] | 15f9cded | 2010-05-20 20:51:06 | [diff] [blame] | 32 | AppCacheStorage* AppCacheRequestHandler::storage() const { |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 33 | DCHECK(host_); |
| 34 | return host_->service()->storage(); |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | void AppCacheRequestHandler::GetExtraResponseInfo( |
| 38 | int64* cache_id, GURL* manifest_url) { |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 39 | if (job_ && job_->is_delivering_appcache_response()) { |
| 40 | *cache_id = job_->cache_id(); |
| 41 | *manifest_url = job_->manifest_url(); |
| 42 | } |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 43 | } |
| 44 | |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 45 | AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadResource( |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 46 | net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
[email protected] | 17d64785 | 2012-09-08 17:45:52 | [diff] [blame] | 47 | maybe_load_resource_executed_ = true; |
[email protected] | 1e1f7d5 | 2010-08-25 21:38:20 | [diff] [blame] | 48 | if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 49 | return NULL; |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 50 | |
| 51 | // This method can get called multiple times over the life |
| 52 | // of a request. The case we detect here is having scheduled |
| 53 | // delivery of a "network response" using a job setup on an |
| 54 | // earlier call thru this method. To send the request thru |
| 55 | // to the network involves restarting the request altogether, |
| 56 | // which will call thru to our interception layer again. |
| 57 | // This time thru, we return NULL so the request hits the wire. |
| 58 | if (job_) { |
[email protected] | dc03398 | 2010-08-24 19:15:32 | [diff] [blame] | 59 | DCHECK(job_->is_delivering_network_response() || |
| 60 | job_->cache_entry_not_found()); |
[email protected] | 1e1f7d5 | 2010-08-25 21:38:20 | [diff] [blame] | 61 | if (job_->cache_entry_not_found()) |
| 62 | cache_entry_not_found_ = true; |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 63 | job_ = NULL; |
[email protected] | e6de0cc | 2011-09-06 21:06:47 | [diff] [blame] | 64 | storage()->CancelDelegateCallbacks(this); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 65 | return NULL; |
| 66 | } |
| 67 | |
| 68 | // Clear out our 'found' fields since we're starting a request for a |
| 69 | // new resource, any values in those fields are no longer valid. |
| 70 | found_entry_ = AppCacheEntry(); |
| 71 | found_fallback_entry_ = AppCacheEntry(); |
| 72 | found_cache_id_ = kNoCacheId; |
[email protected] | 810a52ef | 2010-01-08 01:22:15 | [diff] [blame] | 73 | found_manifest_url_ = GURL(); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 74 | found_network_namespace_ = false; |
| 75 | |
[email protected] | 15f9cded | 2010-05-20 20:51:06 | [diff] [blame] | 76 | if (is_main_resource()) |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 77 | MaybeLoadMainResource(request, network_delegate); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 78 | else |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 79 | MaybeLoadSubResource(request, network_delegate); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 80 | |
| 81 | // If its been setup to deliver a network response, we can just delete |
| 82 | // it now and return NULL instead to achieve that since it couldn't |
| 83 | // have been started yet. |
| 84 | if (job_ && job_->is_delivering_network_response()) { |
| 85 | DCHECK(!job_->has_been_started()); |
| 86 | job_ = NULL; |
| 87 | } |
| 88 | |
| 89 | return job_; |
| 90 | } |
| 91 | |
| 92 | AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 93 | net::URLRequest* request, |
| 94 | net::NetworkDelegate* network_delegate, |
| 95 | const GURL& location) { |
[email protected] | 1e1f7d5 | 2010-08-25 21:38:20 | [diff] [blame] | 96 | if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 97 | return NULL; |
[email protected] | 15f9cded | 2010-05-20 20:51:06 | [diff] [blame] | 98 | if (is_main_resource()) |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 99 | return NULL; |
[email protected] | 17d64785 | 2012-09-08 17:45:52 | [diff] [blame] | 100 | // TODO(vabr) This is a temporary fix (see crbug/141114). We should get rid of |
| 101 | // it once a more general solution to crbug/121325 is in place. |
| 102 | if (!maybe_load_resource_executed_) |
| 103 | return NULL; |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 104 | if (request->url().GetOrigin() == location.GetOrigin()) |
| 105 | return NULL; |
| 106 | |
| 107 | DCHECK(!job_); // our jobs never generate redirects |
| 108 | |
| 109 | if (found_fallback_entry_.has_response_id()) { |
| 110 | // 6.9.6, step 4: If this results in a redirect to another origin, |
| 111 | // get the resource of the fallback entry. |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 112 | job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
[email protected] | 07b8eed | 2010-07-23 23:40:20 | [diff] [blame] | 113 | DeliverAppCachedResponse( |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 114 | found_fallback_entry_, found_cache_id_, found_group_id_, |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 115 | found_manifest_url_, true, found_namespace_entry_url_); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 116 | } else if (!found_network_namespace_) { |
| 117 | // 6.9.6, step 6: Fail the resource load. |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 118 | job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 119 | DeliverErrorResponse(); |
| 120 | } else { |
| 121 | // 6.9.6 step 3 and 5: Fetch the resource normally. |
| 122 | } |
| 123 | |
| 124 | return job_; |
| 125 | } |
| 126 | |
| 127 | AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse( |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 128 | net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
[email protected] | 1e1f7d5 | 2010-08-25 21:38:20 | [diff] [blame] | 129 | if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 130 | return NULL; |
| 131 | if (!found_fallback_entry_.has_response_id()) |
| 132 | return NULL; |
| 133 | |
[email protected] | 2756a8e | 2012-09-07 18:24:29 | [diff] [blame] | 134 | if (request->status().status() == net::URLRequestStatus::CANCELED) { |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 135 | // 6.9.6, step 4: But not if the user canceled the download. |
| 136 | return NULL; |
| 137 | } |
| 138 | |
| 139 | // We don't fallback for responses that we delivered. |
| 140 | if (job_) { |
| 141 | DCHECK(!job_->is_delivering_network_response()); |
| 142 | return NULL; |
| 143 | } |
| 144 | |
| 145 | if (request->status().is_success()) { |
| 146 | int code_major = request->GetResponseCode() / 100; |
| 147 | if (code_major !=4 && code_major != 5) |
| 148 | return NULL; |
[email protected] | cb0d6bd5 | 2011-05-10 01:27:48 | [diff] [blame] | 149 | |
| 150 | // Servers can override the fallback behavior with a response header. |
| 151 | const std::string kFallbackOverrideHeader( |
| 152 | "x-chromium-appcache-fallback-override"); |
| 153 | const std::string kFallbackOverrideValue( |
| 154 | "disallow-fallback"); |
| 155 | std::string header_value; |
| 156 | request->GetResponseHeaderByName(kFallbackOverrideHeader, &header_value); |
| 157 | if (header_value == kFallbackOverrideValue) |
| 158 | return NULL; |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | // 6.9.6, step 4: If this results in a 4xx or 5xx status code |
| 162 | // or there were network errors, get the resource of the fallback entry. |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 163 | job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
[email protected] | 07b8eed | 2010-07-23 23:40:20 | [diff] [blame] | 164 | DeliverAppCachedResponse( |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 165 | found_fallback_entry_, found_cache_id_, found_group_id_, |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 166 | found_manifest_url_, true, found_namespace_entry_url_); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 167 | return job_; |
| 168 | } |
| 169 | |
| 170 | void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) { |
| 171 | storage()->CancelDelegateCallbacks(this); |
| 172 | host_ = NULL; // no need to RemoveObserver, the host is being deleted |
| 173 | |
| 174 | // Since the host is being deleted, we don't have to complete any job |
| 175 | // that is current running. It's destined for the bit bucket anyway. |
| 176 | if (job_) { |
| 177 | job_->Kill(); |
| 178 | job_ = NULL; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | void AppCacheRequestHandler::DeliverAppCachedResponse( |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 183 | const AppCacheEntry& entry, int64 cache_id, int64 group_id, |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 184 | const GURL& manifest_url, bool is_fallback, |
| 185 | const GURL& namespace_entry_url) { |
[email protected] | 6ed2a5a5 | 2010-11-03 02:29:14 | [diff] [blame] | 186 | DCHECK(host_ && job_ && job_->is_waiting()); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 187 | DCHECK(entry.has_response_id()); |
[email protected] | 6ed2a5a5 | 2010-11-03 02:29:14 | [diff] [blame] | 188 | |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 189 | if (ResourceType::IsFrame(resource_type_) && !namespace_entry_url.is_empty()) |
| 190 | host_->NotifyMainResourceIsNamespaceEntry(namespace_entry_url); |
[email protected] | 6ed2a5a5 | 2010-11-03 02:29:14 | [diff] [blame] | 191 | |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 192 | job_->DeliverAppCachedResponse(manifest_url, group_id, cache_id, |
| 193 | entry, is_fallback); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | void AppCacheRequestHandler::DeliverErrorResponse() { |
| 197 | DCHECK(job_ && job_->is_waiting()); |
| 198 | job_->DeliverErrorResponse(); |
| 199 | } |
| 200 | |
| 201 | void AppCacheRequestHandler::DeliverNetworkResponse() { |
| 202 | DCHECK(job_ && job_->is_waiting()); |
| 203 | job_->DeliverNetworkResponse(); |
| 204 | } |
| 205 | |
| 206 | // Main-resource handling ---------------------------------------------- |
| 207 | |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 208 | void AppCacheRequestHandler::MaybeLoadMainResource( |
| 209 | net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 210 | DCHECK(!job_); |
[email protected] | ea2a7b9 | 2011-04-15 20:56:47 | [diff] [blame] | 211 | DCHECK(host_); |
| 212 | |
| 213 | const AppCacheHost* spawning_host = |
| 214 | ResourceType::IsSharedWorker(resource_type_) ? |
| 215 | host_ : host_->GetSpawningHost(); |
| 216 | GURL preferred_manifest_url = spawning_host ? |
| 217 | spawning_host->preferred_manifest_url() : GURL(); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 218 | |
| 219 | // We may have to wait for our storage query to complete, but |
| 220 | // this query can also complete syncrhonously. |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 221 | job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
[email protected] | ea2a7b9 | 2011-04-15 20:56:47 | [diff] [blame] | 222 | storage()->FindResponseForMainRequest( |
| 223 | request->url(), preferred_manifest_url, this); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | void AppCacheRequestHandler::OnMainResponseFound( |
| 227 | const GURL& url, const AppCacheEntry& entry, |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 228 | const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry, |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 229 | int64 cache_id, int64 group_id, const GURL& manifest_url) { |
[email protected] | e6de0cc | 2011-09-06 21:06:47 | [diff] [blame] | 230 | DCHECK(job_); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 231 | DCHECK(host_); |
[email protected] | 15f9cded | 2010-05-20 20:51:06 | [diff] [blame] | 232 | DCHECK(is_main_resource()); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 233 | DCHECK(!entry.IsForeign()); |
| 234 | DCHECK(!fallback_entry.IsForeign()); |
| 235 | DCHECK(!(entry.has_response_id() && fallback_entry.has_response_id())); |
| 236 | |
[email protected] | e6de0cc | 2011-09-06 21:06:47 | [diff] [blame] | 237 | if (!job_) |
| 238 | return; |
| 239 | |
[email protected] | 0a60884 | 2011-09-08 10:55:19 | [diff] [blame] | 240 | AppCachePolicy* policy = host_->service()->appcache_policy(); |
| 241 | bool was_blocked_by_policy = !manifest_url.is_empty() && policy && |
| 242 | !policy->CanLoadAppCache(manifest_url, host_->first_party_url()); |
[email protected] | 035545f | 2010-04-09 13:10:21 | [diff] [blame] | 243 | |
[email protected] | 0a60884 | 2011-09-08 10:55:19 | [diff] [blame] | 244 | if (was_blocked_by_policy) { |
| 245 | if (ResourceType::IsFrame(resource_type_)) { |
| 246 | host_->NotifyMainResourceBlocked(manifest_url); |
| 247 | } else { |
| 248 | DCHECK(ResourceType::IsSharedWorker(resource_type_)); |
[email protected] | 5c7d598 | 2010-07-12 09:12:59 | [diff] [blame] | 249 | host_->frontend()->OnContentBlocked(host_->host_id(), manifest_url); |
[email protected] | 0a60884 | 2011-09-08 10:55:19 | [diff] [blame] | 250 | } |
| 251 | DeliverNetworkResponse(); |
| 252 | return; |
| 253 | } |
| 254 | |
| 255 | if (ResourceType::IsFrame(resource_type_) && cache_id != kNoCacheId) { |
| 256 | // AppCacheHost loads and holds a reference to the main resource cache |
| 257 | // for two reasons, firstly to preload the cache into the working set |
| 258 | // in advance of subresource loads happening, secondly to prevent the |
| 259 | // AppCache from falling out of the working set on frame navigations. |
| 260 | host_->LoadMainResourceCache(cache_id); |
| 261 | host_->set_preferred_manifest_url(manifest_url); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | // 6.11.1 Navigating across documents, steps 10 and 14. |
| 265 | |
| 266 | found_entry_ = entry; |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 267 | found_namespace_entry_url_ = namespace_entry_url; |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 268 | found_fallback_entry_ = fallback_entry; |
| 269 | found_cache_id_ = cache_id; |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 270 | found_group_id_ = group_id; |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 271 | found_manifest_url_ = manifest_url; |
| 272 | found_network_namespace_ = false; // not applicable to main requests |
| 273 | |
| 274 | if (found_entry_.has_response_id()) { |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 275 | DCHECK(!found_fallback_entry_.has_response_id()); |
[email protected] | 07b8eed | 2010-07-23 23:40:20 | [diff] [blame] | 276 | DeliverAppCachedResponse( |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 277 | found_entry_, found_cache_id_, found_group_id_, found_manifest_url_, |
[email protected] | 2abcade | 2012-01-05 00:19:40 | [diff] [blame] | 278 | false, found_namespace_entry_url_); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 279 | } else { |
| 280 | DeliverNetworkResponse(); |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | // Sub-resource handling ---------------------------------------------- |
| 285 | |
| 286 | void AppCacheRequestHandler::MaybeLoadSubResource( |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 287 | net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 288 | DCHECK(!job_); |
| 289 | |
| 290 | if (host_->is_selection_pending()) { |
| 291 | // We have to wait until cache selection is complete and the |
| 292 | // selected cache is loaded. |
| 293 | is_waiting_for_cache_selection_ = true; |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 294 | job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 295 | return; |
| 296 | } |
| 297 | |
| 298 | if (!host_->associated_cache() || |
| 299 | !host_->associated_cache()->is_complete()) { |
| 300 | return; |
| 301 | } |
| 302 | |
[email protected] | 9f17046 | 2012-08-24 01:06:58 | [diff] [blame] | 303 | job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 304 | ContinueMaybeLoadSubResource(); |
| 305 | } |
| 306 | |
| 307 | void AppCacheRequestHandler::ContinueMaybeLoadSubResource() { |
| 308 | // 6.9.6 Changes to the networking model |
| 309 | // If the resource is not to be fetched using the HTTP GET mechanism or |
| 310 | // equivalent ... then fetch the resource normally. |
| 311 | DCHECK(job_); |
| 312 | DCHECK(host_->associated_cache() && |
| 313 | host_->associated_cache()->is_complete()); |
| 314 | |
| 315 | const GURL& url = job_->request()->url(); |
| 316 | AppCache* cache = host_->associated_cache(); |
| 317 | storage()->FindResponseForSubRequest( |
| 318 | host_->associated_cache(), url, |
| 319 | &found_entry_, &found_fallback_entry_, &found_network_namespace_); |
| 320 | |
| 321 | if (found_entry_.has_response_id()) { |
| 322 | // Step 2: If there's an entry, get it instead. |
| 323 | DCHECK(!found_network_namespace_ && |
| 324 | !found_fallback_entry_.has_response_id()); |
| 325 | found_cache_id_ = cache->cache_id(); |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 326 | found_group_id_ = cache->owning_group()->group_id(); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 327 | found_manifest_url_ = cache->owning_group()->manifest_url(); |
| 328 | DeliverAppCachedResponse( |
[email protected] | 4252f60 | 2011-10-21 19:18:36 | [diff] [blame] | 329 | found_entry_, found_cache_id_, found_group_id_, found_manifest_url_, |
[email protected] | 6ed2a5a5 | 2010-11-03 02:29:14 | [diff] [blame] | 330 | false, GURL()); |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 331 | return; |
| 332 | } |
| 333 | |
| 334 | if (found_fallback_entry_.has_response_id()) { |
| 335 | // Step 4: Fetch the resource normally, if this results |
| 336 | // in certain conditions, then use the fallback. |
| 337 | DCHECK(!found_network_namespace_ && |
| 338 | !found_entry_.has_response_id()); |
| 339 | found_cache_id_ = cache->cache_id(); |
| 340 | found_manifest_url_ = cache->owning_group()->manifest_url(); |
| 341 | DeliverNetworkResponse(); |
| 342 | return; |
| 343 | } |
| 344 | |
| 345 | if (found_network_namespace_) { |
| 346 | // Step 3 and 5: Fetch the resource normally. |
| 347 | DCHECK(!found_entry_.has_response_id() && |
| 348 | !found_fallback_entry_.has_response_id()); |
| 349 | DeliverNetworkResponse(); |
| 350 | return; |
| 351 | } |
| 352 | |
| 353 | // Step 6: Fail the resource load. |
| 354 | DeliverErrorResponse(); |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 355 | } |
| 356 | |
[email protected] | 7e8e3dd | 2009-09-18 01:05:09 | [diff] [blame] | 357 | void AppCacheRequestHandler::OnCacheSelectionComplete(AppCacheHost* host) { |
| 358 | DCHECK(host == host_); |
[email protected] | 15f9cded | 2010-05-20 20:51:06 | [diff] [blame] | 359 | if (is_main_resource()) |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 360 | return; |
| 361 | if (!is_waiting_for_cache_selection_) |
| 362 | return; |
[email protected] | 7e8e3dd | 2009-09-18 01:05:09 | [diff] [blame] | 363 | |
[email protected] | 3367fc1d | 2009-11-09 00:09:21 | [diff] [blame] | 364 | is_waiting_for_cache_selection_ = false; |
| 365 | |
| 366 | if (!host_->associated_cache() || |
| 367 | !host_->associated_cache()->is_complete()) { |
| 368 | DeliverNetworkResponse(); |
| 369 | return; |
| 370 | } |
| 371 | |
| 372 | ContinueMaybeLoadSubResource(); |
[email protected] | 7e8e3dd | 2009-09-18 01:05:09 | [diff] [blame] | 373 | } |
| 374 | |
[email protected] | 97e3edc | 2009-09-15 22:07:15 | [diff] [blame] | 375 | } // namespace appcache |