| 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" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 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, net::NetworkDelegate* network_delegate) { |
| 47 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) | 47 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
| 48 return NULL; | 48 return NULL; |
| 49 | 49 |
| 50 // This method can get called multiple times over the life | 50 // This method can get called multiple times over the life |
| 51 // of a request. The case we detect here is having scheduled | 51 // of a request. The case we detect here is having scheduled |
| 52 // delivery of a "network response" using a job setup on an | 52 // delivery of a "network response" using a job setup on an |
| 53 // earlier call thru this method. To send the request thru | 53 // earlier call thru this method. To send the request thru |
| 54 // to the network involves restarting the request altogether, | 54 // to the network involves restarting the request altogether, |
| 55 // which will call thru to our interception layer again. | 55 // which will call thru to our interception layer again. |
| 56 // This time thru, we return NULL so the request hits the wire. | 56 // This time thru, we return NULL so the request hits the wire. |
| 57 if (job_) { | 57 if (job_) { |
| 58 DCHECK(job_->is_delivering_network_response() || | 58 DCHECK(job_->is_delivering_network_response() || |
| 59 job_->cache_entry_not_found()); | 59 job_->cache_entry_not_found()); |
| 60 if (job_->cache_entry_not_found()) | 60 if (job_->cache_entry_not_found()) |
| 61 cache_entry_not_found_ = true; | 61 cache_entry_not_found_ = true; |
| 62 job_ = NULL; | 62 job_ = NULL; |
| 63 storage()->CancelDelegateCallbacks(this); | 63 storage()->CancelDelegateCallbacks(this); |
| 64 return NULL; | 64 return NULL; |
| 65 } | 65 } |
| 66 | 66 |
| 67 // Clear out our 'found' fields since we're starting a request for a | 67 // Clear out our 'found' fields since we're starting a request for a |
| 68 // new resource, any values in those fields are no longer valid. | 68 // new resource, any values in those fields are no longer valid. |
| 69 found_entry_ = AppCacheEntry(); | 69 found_entry_ = AppCacheEntry(); |
| 70 found_fallback_entry_ = AppCacheEntry(); | 70 found_fallback_entry_ = AppCacheEntry(); |
| 71 found_cache_id_ = kNoCacheId; | 71 found_cache_id_ = kNoCacheId; |
| 72 found_manifest_url_ = GURL(); | 72 found_manifest_url_ = GURL(); |
| 73 found_network_namespace_ = false; | 73 found_network_namespace_ = false; |
| 74 | 74 |
| 75 if (is_main_resource()) | 75 if (is_main_resource()) |
| 76 MaybeLoadMainResource(request); | 76 MaybeLoadMainResource(request, network_delegate); |
| 77 else | 77 else |
| 78 MaybeLoadSubResource(request); | 78 MaybeLoadSubResource(request, network_delegate); |
| 79 | 79 |
| 80 // If its been setup to deliver a network response, we can just delete | 80 // If its been setup to deliver a network response, we can just delete |
| 81 // it now and return NULL instead to achieve that since it couldn't | 81 // it now and return NULL instead to achieve that since it couldn't |
| 82 // have been started yet. | 82 // have been started yet. |
| 83 if (job_ && job_->is_delivering_network_response()) { | 83 if (job_ && job_->is_delivering_network_response()) { |
| 84 DCHECK(!job_->has_been_started()); | 84 DCHECK(!job_->has_been_started()); |
| 85 job_ = NULL; | 85 job_ = NULL; |
| 86 } | 86 } |
| 87 | 87 |
| 88 return job_; | 88 return job_; |
| 89 } | 89 } |
| 90 | 90 |
| 91 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( | 91 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect( |
| 92 net::URLRequest* request, const GURL& location) { | 92 net::URLRequest* request, |
| 93 net::NetworkDelegate* network_delegate, |
| 94 const GURL& location) { |
| 93 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) | 95 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
| 94 return NULL; | 96 return NULL; |
| 95 if (is_main_resource()) | 97 if (is_main_resource()) |
| 96 return NULL; | 98 return NULL; |
| 97 if (request->url().GetOrigin() == location.GetOrigin()) | 99 if (request->url().GetOrigin() == location.GetOrigin()) |
| 98 return NULL; | 100 return NULL; |
| 99 | 101 |
| 100 DCHECK(!job_); // our jobs never generate redirects | 102 DCHECK(!job_); // our jobs never generate redirects |
| 101 | 103 |
| 102 if (found_fallback_entry_.has_response_id()) { | 104 if (found_fallback_entry_.has_response_id()) { |
| 103 // 6.9.6, step 4: If this results in a redirect to another origin, | 105 // 6.9.6, step 4: If this results in a redirect to another origin, |
| 104 // get the resource of the fallback entry. | 106 // get the resource of the fallback entry. |
| 105 job_ = new AppCacheURLRequestJob(request, storage()); | 107 job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
| 106 DeliverAppCachedResponse( | 108 DeliverAppCachedResponse( |
| 107 found_fallback_entry_, found_cache_id_, found_group_id_, | 109 found_fallback_entry_, found_cache_id_, found_group_id_, |
| 108 found_manifest_url_, true, found_namespace_entry_url_); | 110 found_manifest_url_, true, found_namespace_entry_url_); |
| 109 } else if (!found_network_namespace_) { | 111 } else if (!found_network_namespace_) { |
| 110 // 6.9.6, step 6: Fail the resource load. | 112 // 6.9.6, step 6: Fail the resource load. |
| 111 job_ = new AppCacheURLRequestJob(request, storage()); | 113 job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
| 112 DeliverErrorResponse(); | 114 DeliverErrorResponse(); |
| 113 } else { | 115 } else { |
| 114 // 6.9.6 step 3 and 5: Fetch the resource normally. | 116 // 6.9.6 step 3 and 5: Fetch the resource normally. |
| 115 } | 117 } |
| 116 | 118 |
| 117 return job_; | 119 return job_; |
| 118 } | 120 } |
| 119 | 121 |
| 120 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse( | 122 AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse( |
| 121 net::URLRequest* request) { | 123 net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
| 122 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) | 124 if (!host_ || !IsSchemeAndMethodSupported(request) || cache_entry_not_found_) |
| 123 return NULL; | 125 return NULL; |
| 124 if (!found_fallback_entry_.has_response_id()) | 126 if (!found_fallback_entry_.has_response_id()) |
| 125 return NULL; | 127 return NULL; |
| 126 | 128 |
| 127 if (request->status().status() == net::URLRequestStatus::CANCELED || | 129 if (request->status().status() == net::URLRequestStatus::CANCELED || |
| 128 request->status().status() == net::URLRequestStatus::HANDLED_EXTERNALLY) { | 130 request->status().status() == net::URLRequestStatus::HANDLED_EXTERNALLY) { |
| 129 // 6.9.6, step 4: But not if the user canceled the download. | 131 // 6.9.6, step 4: But not if the user canceled the download. |
| 130 return NULL; | 132 return NULL; |
| 131 } | 133 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 147 const std::string kFallbackOverrideValue( | 149 const std::string kFallbackOverrideValue( |
| 148 "disallow-fallback"); | 150 "disallow-fallback"); |
| 149 std::string header_value; | 151 std::string header_value; |
| 150 request->GetResponseHeaderByName(kFallbackOverrideHeader, &header_value); | 152 request->GetResponseHeaderByName(kFallbackOverrideHeader, &header_value); |
| 151 if (header_value == kFallbackOverrideValue) | 153 if (header_value == kFallbackOverrideValue) |
| 152 return NULL; | 154 return NULL; |
| 153 } | 155 } |
| 154 | 156 |
| 155 // 6.9.6, step 4: If this results in a 4xx or 5xx status code | 157 // 6.9.6, step 4: If this results in a 4xx or 5xx status code |
| 156 // or there were network errors, get the resource of the fallback entry. | 158 // or there were network errors, get the resource of the fallback entry. |
| 157 job_ = new AppCacheURLRequestJob(request, storage()); | 159 job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
| 158 DeliverAppCachedResponse( | 160 DeliverAppCachedResponse( |
| 159 found_fallback_entry_, found_cache_id_, found_group_id_, | 161 found_fallback_entry_, found_cache_id_, found_group_id_, |
| 160 found_manifest_url_, true, found_namespace_entry_url_); | 162 found_manifest_url_, true, found_namespace_entry_url_); |
| 161 return job_; | 163 return job_; |
| 162 } | 164 } |
| 163 | 165 |
| 164 void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) { | 166 void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) { |
| 165 storage()->CancelDelegateCallbacks(this); | 167 storage()->CancelDelegateCallbacks(this); |
| 166 host_ = NULL; // no need to RemoveObserver, the host is being deleted | 168 host_ = NULL; // no need to RemoveObserver, the host is being deleted |
| 167 | 169 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 192 job_->DeliverErrorResponse(); | 194 job_->DeliverErrorResponse(); |
| 193 } | 195 } |
| 194 | 196 |
| 195 void AppCacheRequestHandler::DeliverNetworkResponse() { | 197 void AppCacheRequestHandler::DeliverNetworkResponse() { |
| 196 DCHECK(job_ && job_->is_waiting()); | 198 DCHECK(job_ && job_->is_waiting()); |
| 197 job_->DeliverNetworkResponse(); | 199 job_->DeliverNetworkResponse(); |
| 198 } | 200 } |
| 199 | 201 |
| 200 // Main-resource handling ---------------------------------------------- | 202 // Main-resource handling ---------------------------------------------- |
| 201 | 203 |
| 202 void AppCacheRequestHandler::MaybeLoadMainResource(net::URLRequest* request) { | 204 void AppCacheRequestHandler::MaybeLoadMainResource( |
| 205 net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
| 203 DCHECK(!job_); | 206 DCHECK(!job_); |
| 204 DCHECK(host_); | 207 DCHECK(host_); |
| 205 | 208 |
| 206 const AppCacheHost* spawning_host = | 209 const AppCacheHost* spawning_host = |
| 207 ResourceType::IsSharedWorker(resource_type_) ? | 210 ResourceType::IsSharedWorker(resource_type_) ? |
| 208 host_ : host_->GetSpawningHost(); | 211 host_ : host_->GetSpawningHost(); |
| 209 GURL preferred_manifest_url = spawning_host ? | 212 GURL preferred_manifest_url = spawning_host ? |
| 210 spawning_host->preferred_manifest_url() : GURL(); | 213 spawning_host->preferred_manifest_url() : GURL(); |
| 211 | 214 |
| 212 // We may have to wait for our storage query to complete, but | 215 // We may have to wait for our storage query to complete, but |
| 213 // this query can also complete syncrhonously. | 216 // this query can also complete syncrhonously. |
| 214 job_ = new AppCacheURLRequestJob(request, storage()); | 217 job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
| 215 storage()->FindResponseForMainRequest( | 218 storage()->FindResponseForMainRequest( |
| 216 request->url(), preferred_manifest_url, this); | 219 request->url(), preferred_manifest_url, this); |
| 217 } | 220 } |
| 218 | 221 |
| 219 void AppCacheRequestHandler::OnMainResponseFound( | 222 void AppCacheRequestHandler::OnMainResponseFound( |
| 220 const GURL& url, const AppCacheEntry& entry, | 223 const GURL& url, const AppCacheEntry& entry, |
| 221 const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry, | 224 const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry, |
| 222 int64 cache_id, int64 group_id, const GURL& manifest_url) { | 225 int64 cache_id, int64 group_id, const GURL& manifest_url) { |
| 223 DCHECK(job_); | 226 DCHECK(job_); |
| 224 DCHECK(host_); | 227 DCHECK(host_); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 found_entry_, found_cache_id_, found_group_id_, found_manifest_url_, | 273 found_entry_, found_cache_id_, found_group_id_, found_manifest_url_, |
| 271 false, found_namespace_entry_url_); | 274 false, found_namespace_entry_url_); |
| 272 } else { | 275 } else { |
| 273 DeliverNetworkResponse(); | 276 DeliverNetworkResponse(); |
| 274 } | 277 } |
| 275 } | 278 } |
| 276 | 279 |
| 277 // Sub-resource handling ---------------------------------------------- | 280 // Sub-resource handling ---------------------------------------------- |
| 278 | 281 |
| 279 void AppCacheRequestHandler::MaybeLoadSubResource( | 282 void AppCacheRequestHandler::MaybeLoadSubResource( |
| 280 net::URLRequest* request) { | 283 net::URLRequest* request, net::NetworkDelegate* network_delegate) { |
| 281 DCHECK(!job_); | 284 DCHECK(!job_); |
| 282 | 285 |
| 283 if (host_->is_selection_pending()) { | 286 if (host_->is_selection_pending()) { |
| 284 // We have to wait until cache selection is complete and the | 287 // We have to wait until cache selection is complete and the |
| 285 // selected cache is loaded. | 288 // selected cache is loaded. |
| 286 is_waiting_for_cache_selection_ = true; | 289 is_waiting_for_cache_selection_ = true; |
| 287 job_ = new AppCacheURLRequestJob(request, storage()); | 290 job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
| 288 return; | 291 return; |
| 289 } | 292 } |
| 290 | 293 |
| 291 if (!host_->associated_cache() || | 294 if (!host_->associated_cache() || |
| 292 !host_->associated_cache()->is_complete()) { | 295 !host_->associated_cache()->is_complete()) { |
| 293 return; | 296 return; |
| 294 } | 297 } |
| 295 | 298 |
| 296 job_ = new AppCacheURLRequestJob(request, storage()); | 299 job_ = new AppCacheURLRequestJob(request, network_delegate, storage()); |
| 297 ContinueMaybeLoadSubResource(); | 300 ContinueMaybeLoadSubResource(); |
| 298 } | 301 } |
| 299 | 302 |
| 300 void AppCacheRequestHandler::ContinueMaybeLoadSubResource() { | 303 void AppCacheRequestHandler::ContinueMaybeLoadSubResource() { |
| 301 // 6.9.6 Changes to the networking model | 304 // 6.9.6 Changes to the networking model |
| 302 // If the resource is not to be fetched using the HTTP GET mechanism or | 305 // If the resource is not to be fetched using the HTTP GET mechanism or |
| 303 // equivalent ... then fetch the resource normally. | 306 // equivalent ... then fetch the resource normally. |
| 304 DCHECK(job_); | 307 DCHECK(job_); |
| 305 DCHECK(host_->associated_cache() && | 308 DCHECK(host_->associated_cache() && |
| 306 host_->associated_cache()->is_complete()); | 309 host_->associated_cache()->is_complete()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 if (!host_->associated_cache() || | 362 if (!host_->associated_cache() || |
| 360 !host_->associated_cache()->is_complete()) { | 363 !host_->associated_cache()->is_complete()) { |
| 361 DeliverNetworkResponse(); | 364 DeliverNetworkResponse(); |
| 362 return; | 365 return; |
| 363 } | 366 } |
| 364 | 367 |
| 365 ContinueMaybeLoadSubResource(); | 368 ContinueMaybeLoadSubResource(); |
| 366 } | 369 } |
| 367 | 370 |
| 368 } // namespace appcache | 371 } // namespace appcache |
| OLD | NEW |