Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/appcache/appcache_request_handler.h" | 5 #include "webkit/appcache/appcache_request_handler.h" |
| 6 | 6 |
| 7 #include "net/url_request/url_request.h" | 7 #include "net/url_request/url_request.h" |
| 8 #include "net/url_request/url_request_job.h" | 8 #include "net/url_request/url_request_job.h" |
| 9 #include "webkit/appcache/appcache.h" | 9 #include "webkit/appcache/appcache.h" |
| 10 #include "webkit/appcache/appcache_policy.h" | 10 #include "webkit/appcache/appcache_policy.h" |
| 11 #include "webkit/appcache/appcache_url_request_job.h" | 11 #include "webkit/appcache/appcache_url_request_job.h" |
| 12 | 12 |
| 13 namespace appcache { | 13 namespace appcache { |
| 14 | 14 |
| 15 AppCacheRequestHandler::AppCacheRequestHandler( | 15 AppCacheRequestHandler::AppCacheRequestHandler( |
| 16 AppCacheHost* host, ResourceType::Type resource_type) | 16 AppCacheHost* host, ResourceType::Type resource_type) |
| 17 : host_(host), resource_type_(resource_type), | 17 : host_(host), resource_type_(resource_type), |
| 18 is_waiting_for_cache_selection_(false), found_group_id_(0), | 18 is_waiting_for_cache_selection_(false), found_group_id_(0), |
| 19 found_cache_id_(0), found_network_namespace_(false), | 19 found_cache_id_(0), found_network_namespace_(false), |
| 20 cache_entry_not_found_(false) { | 20 cache_entry_not_found_(false), maybe_load_resource_executed_(false) { |
| 21 DCHECK(host_); | 21 DCHECK(host_); |
| 22 host_->AddObserver(this); | 22 host_->AddObserver(this); |
| 23 } | 23 } |
| 24 | 24 |
| 25 AppCacheRequestHandler::~AppCacheRequestHandler() { | 25 AppCacheRequestHandler::~AppCacheRequestHandler() { |
| 26 if (host_) { | 26 if (host_) { |
| 27 storage()->CancelDelegateCallbacks(this); | 27 storage()->CancelDelegateCallbacks(this); |
| 28 host_->RemoveObserver(this); | 28 host_->RemoveObserver(this); |
| 29 } | 29 } |
| 30 } | 30 } |
| 31 | 31 |
| 32 AppCacheStorage* AppCacheRequestHandler::storage() const { | 32 AppCacheStorage* AppCacheRequestHandler::storage() const { |
| 33 DCHECK(host_); | 33 DCHECK(host_); |
| 34 return host_->service()->storage(); | 34 return host_->service()->storage(); |
| 35 } | 35 } |
| 36 | 36 |
| 37 void AppCacheRequestHandler::GetExtraResponseInfo( | 37 void AppCacheRequestHandler::GetExtraResponseInfo( |
| 38 int64* cache_id, GURL* manifest_url) { | 38 int64* cache_id, GURL* manifest_url) { |
| 39 if (job_ && job_->is_delivering_appcache_response()) { | 39 if (job_ && job_->is_delivering_appcache_response()) { |
| 40 *cache_id = job_->cache_id(); | 40 *cache_id = job_->cache_id(); |
| 41 *manifest_url = job_->manifest_url(); | 41 *manifest_url = job_->manifest_url(); |
| 42 } | 42 } |
| 43 } | 43 } |
| 44 | 44 |
| 45 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadResource( | 45 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadResource( |
| 46 net::URLRequest* request) { | 46 net::URLRequest* request) { |
| 47 maybe_load_resource_executed_ = true; | |
| 47 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) | 48 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
| 48 return NULL; | 49 return NULL; |
| 49 | 50 |
| 50 // This method can get called multiple times over the life | 51 // This method can get called multiple times over the life |
| 51 // of a request. The case we detect here is having scheduled | 52 // of a request. The case we detect here is having scheduled |
| 52 // delivery of a "network response" using a job setup on an | 53 // delivery of a "network response" using a job setup on an |
| 53 // earlier call thru this method. To send the request thru | 54 // earlier call thru this method. To send the request thru |
| 54 // to the network involves restarting the request altogether, | 55 // to the network involves restarting the request altogether, |
| 55 // which will call thru to our interception layer again. | 56 // which will call thru to our interception layer again. |
| 56 // This time thru, we return NULL so the request hits the wire. | 57 // This time thru, we return NULL so the request hits the wire. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 86 } | 87 } |
| 87 | 88 |
| 88 return job_; | 89 return job_; |
| 89 } | 90 } |
| 90 | 91 |
| 91 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( | 92 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( |
| 92 net::URLRequest* request, const GURL& location) { | 93 net::URLRequest* request, const GURL& location) { |
| 93 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) | 94 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
| 94 return NULL; | 95 return NULL; |
| 95 if (is_main_resource()) | 96 if (is_main_resource()) |
| 96 return NULL; | 97 return NULL; |
|
michaeln
2012/08/25 01:33:41
a very small change that might workaround the imme
vabr (Chromium)
2012/08/30 13:01:06
I like very much this suggestion.
However, it wil
michaeln
2012/09/05 19:24:21
No worse than the current state of things where bo
vabr (Chromium)
2012/09/06 17:34:21
I agree that this is not making things worse.
When
| |
| 97 if (request->url().GetOrigin() == location.GetOrigin()) | 98 if (request->url().GetOrigin() == location.GetOrigin()) |
| 98 return NULL; | 99 return NULL; |
| 99 | 100 |
| 100 DCHECK(!job_); // our jobs never generate redirects | 101 DCHECK(!job_); // our jobs never generate redirects |
| 101 | 102 |
| 103 if (!maybe_load_resource_executed_) { | |
| 104 // If MaybeLoadResource was not executed, we did not see this request | |
| 105 // before redirect. We need to call MaybeLoadResource to fill our 'found' | |
| 106 // data members and handle things we should have chance to handle before | |
| 107 // the redirect. | |
| 108 return MaybeLoadResource(request); | |
|
michaeln
2012/08/25 01:33:41
How is the 'fallback' behavior triggered if we go
| |
| 109 } | |
| 110 | |
| 102 if (found_fallback_entry_.has_response_id()) { | 111 if (found_fallback_entry_.has_response_id()) { |
| 103 // 6.9.6, step 4: If this results in a redirect to another origin, | 112 // 6.9.6, step 4: If this results in a redirect to another origin, |
| 104 // get the resource of the fallback entry. | 113 // get the resource of the fallback entry. |
| 105 job_ = new AppCacheURLRequestJob(request, storage()); | 114 job_ = new AppCacheURLRequestJob(request, storage()); |
| 106 DeliverAppCachedResponse( | 115 DeliverAppCachedResponse( |
| 107 found_fallback_entry_, found_cache_id_, found_group_id_, | 116 found_fallback_entry_, found_cache_id_, found_group_id_, |
| 108 found_manifest_url_, true, found_namespace_entry_url_); | 117 found_manifest_url_, true, found_namespace_entry_url_); |
| 109 } else if (!found_network_namespace_) { | 118 } else if (!found_network_namespace_) { |
| 110 // 6.9.6, step 6: Fail the resource load. | 119 // 6.9.6, step 6: Fail the resource load. |
| 111 job_ = new AppCacheURLRequestJob(request, storage()); | 120 job_ = new AppCacheURLRequestJob(request, storage()); |
| 112 DeliverErrorResponse(); | 121 DeliverErrorResponse(); |
| 113 } else { | 122 } else { |
| 114 // 6.9.6 step 3 and 5: Fetch the resource normally. | 123 // 6.9.6 step 3 and 5: Fetch the resource normally. |
| 115 } | 124 } |
| 116 | 125 |
| 117 return job_; | 126 return job_; |
| 118 } | 127 } |
| 119 | 128 |
| 120 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse( | 129 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse( |
| 121 net::URLRequest* request) { | 130 net::URLRequest* request) { |
| 122 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) | 131 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
| 123 return NULL; | 132 return NULL; |
|
michaeln
2012/08/25 01:33:42
ditto if (!maybe_load_resource_executed_) return N
| |
| 124 if (!found_fallback_entry_.has_response_id()) | 133 if (!found_fallback_entry_.has_response_id()) |
| 125 return NULL; | 134 return NULL; |
| 126 | 135 |
| 127 if (request->status().status() == net::URLRequestStatus::CANCELED || | 136 if (request->status().status() == net::URLRequestStatus::CANCELED || |
| 128 request->status().status() == net::URLRequestStatus::HANDLED_EXTERNALLY) { | 137 request->status().status() == net::URLRequestStatus::HANDLED_EXTERNALLY) { |
| 129 // 6.9.6, step 4: But not if the user canceled the download. | 138 // 6.9.6, step 4: But not if the user canceled the download. |
| 130 return NULL; | 139 return NULL; |
| 131 } | 140 } |
| 132 | 141 |
| 133 // We don't fallback for responses that we delivered. | 142 // We don't fallback for responses that we delivered. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 } | 307 } |
| 299 | 308 |
| 300 void AppCacheRequestHandler::ContinueMaybeLoadSubResource() { | 309 void AppCacheRequestHandler::ContinueMaybeLoadSubResource() { |
| 301 // 6.9.6 Changes to the networking model | 310 // 6.9.6 Changes to the networking model |
| 302 // If the resource is not to be fetched using the HTTP GET mechanism or | 311 // If the resource is not to be fetched using the HTTP GET mechanism or |
| 303 // equivalent ... then fetch the resource normally. | 312 // equivalent ... then fetch the resource normally. |
| 304 DCHECK(job_); | 313 DCHECK(job_); |
| 305 DCHECK(host_->associated_cache() && | 314 DCHECK(host_->associated_cache() && |
| 306 host_->associated_cache()->is_complete()); | 315 host_->associated_cache()->is_complete()); |
| 307 | 316 |
| 308 const GURL& url = job_->request()->url(); | 317 const GURL& url = job_->request()->original_url(); |
|
michaeln
2012/08/25 01:33:42
It doesn't look like will work when following a ch
| |
| 309 AppCache* cache = host_->associated_cache(); | 318 AppCache* cache = host_->associated_cache(); |
| 310 storage()->FindResponseForSubRequest( | 319 storage()->FindResponseForSubRequest( |
| 311 host_->associated_cache(), url, | 320 host_->associated_cache(), url, |
| 312 &found_entry_, &found_fallback_entry_, &found_network_namespace_); | 321 &found_entry_, &found_fallback_entry_, &found_network_namespace_); |
| 313 | 322 |
| 314 if (found_entry_.has_response_id()) { | 323 if (found_entry_.has_response_id()) { |
| 315 // Step 2: If there's an entry, get it instead. | 324 // Step 2: If there's an entry, get it instead. |
| 316 DCHECK(!found_network_namespace_ && | 325 DCHECK(!found_network_namespace_ && |
| 317 !found_fallback_entry_.has_response_id()); | 326 !found_fallback_entry_.has_response_id()); |
| 318 found_cache_id_ = cache->cache_id(); | 327 found_cache_id_ = cache->cache_id(); |
| 319 found_group_id_ = cache->owning_group()->group_id(); | 328 found_group_id_ = cache->owning_group()->group_id(); |
| 320 found_manifest_url_ = cache->owning_group()->manifest_url(); | 329 found_manifest_url_ = cache->owning_group()->manifest_url(); |
| 321 DeliverAppCachedResponse( | 330 DeliverAppCachedResponse( |
| 322 found_entry_, found_cache_id_, found_group_id_, found_manifest_url_, | 331 found_entry_, found_cache_id_, found_group_id_, found_manifest_url_, |
| 323 false, GURL()); | 332 false, GURL()); |
| 324 return; | 333 return; |
| 325 } | 334 } |
| 326 | 335 |
| 327 if (found_fallback_entry_.has_response_id()) { | 336 if (found_fallback_entry_.has_response_id()) { |
| 337 // First check whether this is in fact a redirected request. If it is then | |
| 338 // we were got here through MaybeLoadFallbackForRedirect. | |
| 339 if (job_->request()->url_chain().size() > 1) { | |
| 340 // 6.9.6, step 4: If this results in a redirect to another origin, | |
| 341 // get the resource of the fallback entry. | |
| 342 DeliverAppCachedResponse( | |
| 343 found_fallback_entry_, found_cache_id_, found_group_id_, | |
| 344 found_manifest_url_, true, found_namespace_entry_url_); | |
| 345 return; | |
| 346 } | |
| 328 // Step 4: Fetch the resource normally, if this results | 347 // Step 4: Fetch the resource normally, if this results |
| 329 // in certain conditions, then use the fallback. | 348 // in certain conditions, then use the fallback. |
| 330 DCHECK(!found_network_namespace_ && | 349 DCHECK(!found_network_namespace_ && |
| 331 !found_entry_.has_response_id()); | 350 !found_entry_.has_response_id()); |
| 332 found_cache_id_ = cache->cache_id(); | 351 found_cache_id_ = cache->cache_id(); |
| 333 found_manifest_url_ = cache->owning_group()->manifest_url(); | 352 found_manifest_url_ = cache->owning_group()->manifest_url(); |
| 334 DeliverNetworkResponse(); | 353 DeliverNetworkResponse(); |
| 335 return; | 354 return; |
| 336 } | 355 } |
| 337 | 356 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 359 if (!host_->associated_cache() || | 378 if (!host_->associated_cache() || |
| 360 !host_->associated_cache()->is_complete()) { | 379 !host_->associated_cache()->is_complete()) { |
| 361 DeliverNetworkResponse(); | 380 DeliverNetworkResponse(); |
| 362 return; | 381 return; |
| 363 } | 382 } |
| 364 | 383 |
| 365 ContinueMaybeLoadSubResource(); | 384 ContinueMaybeLoadSubResource(); |
| 366 } | 385 } |
| 367 | 386 |
| 368 } // namespace appcache | 387 } // namespace appcache |
| OLD | NEW |