OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading |
6 | 6 |
7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/file_util.h" |
| 14 #include "base/format_macros.h" |
13 #include "base/histogram.h" | 15 #include "base/histogram.h" |
14 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
15 #include "base/scoped_ptr.h" | 17 #include "base/scoped_ptr.h" |
16 #include "base/shared_memory.h" | 18 #include "base/shared_memory.h" |
17 #include "base/stl_util-inl.h" | 19 #include "base/stl_util-inl.h" |
18 #include "base/time.h" | 20 #include "base/time.h" |
19 #include "chrome/browser/cert_store.h" | 21 #include "chrome/browser/cert_store.h" |
20 #include "chrome/browser/child_process_security_policy.h" | 22 #include "chrome/browser/child_process_security_policy.h" |
21 #include "chrome/browser/chrome_blob_storage_context.h" | 23 #include "chrome/browser/chrome_blob_storage_context.h" |
22 #include "chrome/browser/cross_site_request_manager.h" | 24 #include "chrome/browser/cross_site_request_manager.h" |
23 #include "chrome/browser/download/download_file_manager.h" | 25 #include "chrome/browser/download/download_file_manager.h" |
24 #include "chrome/browser/download/download_manager.h" | 26 #include "chrome/browser/download/download_manager.h" |
25 #include "chrome/browser/download/download_request_limiter.h" | 27 #include "chrome/browser/download/download_request_limiter.h" |
| 28 #include "chrome/browser/download/download_util.h" |
26 #include "chrome/browser/download/save_file_manager.h" | 29 #include "chrome/browser/download/save_file_manager.h" |
27 #include "chrome/browser/extensions/user_script_listener.h" | 30 #include "chrome/browser/extensions/user_script_listener.h" |
28 #include "chrome/browser/external_protocol_handler.h" | 31 #include "chrome/browser/external_protocol_handler.h" |
| 32 #include "chrome/browser/history/download_create_info.h" |
29 #include "chrome/browser/in_process_webkit/webkit_thread.h" | 33 #include "chrome/browser/in_process_webkit/webkit_thread.h" |
30 #include "chrome/browser/login_prompt.h" | 34 #include "chrome/browser/login_prompt.h" |
31 #include "chrome/browser/net/chrome_url_request_context.h" | 35 #include "chrome/browser/net/chrome_url_request_context.h" |
32 #include "chrome/browser/net/url_request_tracking.h" | 36 #include "chrome/browser/net/url_request_tracking.h" |
33 #include "chrome/browser/plugin_service.h" | 37 #include "chrome/browser/plugin_service.h" |
34 #include "chrome/browser/profile.h" | 38 #include "chrome/browser/profile.h" |
35 #include "chrome/browser/renderer_host/async_resource_handler.h" | 39 #include "chrome/browser/renderer_host/async_resource_handler.h" |
36 #include "chrome/browser/renderer_host/buffered_resource_handler.h" | 40 #include "chrome/browser/renderer_host/buffered_resource_handler.h" |
37 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" | 41 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" |
38 #include "chrome/browser/renderer_host/download_resource_handler.h" | 42 #include "chrome/browser/renderer_host/download_resource_handler.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // Maximum byte "cost" of all the outstanding requests for a renderer. | 124 // Maximum byte "cost" of all the outstanding requests for a renderer. |
121 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. | 125 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. |
122 // This bound is 25MB, which allows for around 6000 outstanding requests. | 126 // This bound is 25MB, which allows for around 6000 outstanding requests. |
123 const int kMaxOutstandingRequestsCostPerProcess = 26214400; | 127 const int kMaxOutstandingRequestsCostPerProcess = 26214400; |
124 | 128 |
125 // Consults the RendererSecurity policy to determine whether the | 129 // Consults the RendererSecurity policy to determine whether the |
126 // ResourceDispatcherHost should service this request. A request might be | 130 // ResourceDispatcherHost should service this request. A request might be |
127 // disallowed if the renderer is not authorized to retrieve the request URL or | 131 // disallowed if the renderer is not authorized to retrieve the request URL or |
128 // if the renderer is attempting to upload an unauthorized file. | 132 // if the renderer is attempting to upload an unauthorized file. |
129 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, | 133 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, |
130 int child_id, | 134 int process_unique_id, |
131 const ViewHostMsg_Resource_Request& request_data) { | 135 const ViewHostMsg_Resource_Request& request_data) { |
132 if (process_type == ChildProcessInfo::PLUGIN_PROCESS) | 136 if (process_type == ChildProcessInfo::PLUGIN_PROCESS) |
133 return true; | 137 return true; |
134 | 138 |
135 if (request_data.resource_type == ResourceType::PREFETCH && | 139 if (request_data.resource_type == ResourceType::PREFETCH && |
136 !ResourceDispatcherHost::is_prefetch_enabled()) | 140 !ResourceDispatcherHost::is_prefetch_enabled()) |
137 return false; | 141 return false; |
138 | 142 |
139 ChildProcessSecurityPolicy* policy = | 143 ChildProcessSecurityPolicy* policy = |
140 ChildProcessSecurityPolicy::GetInstance(); | 144 ChildProcessSecurityPolicy::GetInstance(); |
141 | 145 |
142 // Check if the renderer is permitted to request the requested URL. | 146 // Check if the renderer is permitted to request the requested URL. |
143 if (!policy->CanRequestURL(child_id, request_data.url)) { | 147 if (!policy->CanRequestURL(process_unique_id, request_data.url)) { |
144 LOG(INFO) << "Denied unauthorized request for " << | 148 LOG(INFO) << "Denied unauthorized request for " << |
145 request_data.url.possibly_invalid_spec(); | 149 request_data.url.possibly_invalid_spec(); |
146 return false; | 150 return false; |
147 } | 151 } |
148 | 152 |
149 // Check if the renderer is permitted to upload the requested files. | 153 // Check if the renderer is permitted to upload the requested files. |
150 if (request_data.upload_data) { | 154 if (request_data.upload_data) { |
151 const std::vector<net::UploadData::Element>* uploads = | 155 const std::vector<net::UploadData::Element>* uploads = |
152 request_data.upload_data->elements(); | 156 request_data.upload_data->elements(); |
153 std::vector<net::UploadData::Element>::const_iterator iter; | 157 std::vector<net::UploadData::Element>::const_iterator iter; |
154 for (iter = uploads->begin(); iter != uploads->end(); ++iter) { | 158 for (iter = uploads->begin(); iter != uploads->end(); ++iter) { |
155 if (iter->type() == net::UploadData::TYPE_FILE && | 159 if (iter->type() == net::UploadData::TYPE_FILE && |
156 !policy->CanUploadFile(child_id, iter->file_path())) { | 160 !policy->CanUploadFile(process_unique_id, iter->file_path())) { |
157 NOTREACHED() << "Denied unauthorized upload of " | 161 NOTREACHED() << "Denied unauthorized upload of " |
158 << iter->file_path().value(); | 162 << iter->file_path().value(); |
159 return false; | 163 return false; |
160 } | 164 } |
161 } | 165 } |
162 } | 166 } |
163 | 167 |
164 return true; | 168 return true; |
165 } | 169 } |
166 | 170 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 kMaxOutstandingRequestsCostPerProcess), | 231 kMaxOutstandingRequestsCostPerProcess), |
228 receiver_(NULL) { | 232 receiver_(NULL) { |
229 ResourceQueue::DelegateSet resource_queue_delegates; | 233 ResourceQueue::DelegateSet resource_queue_delegates; |
230 resource_queue_delegates.insert(user_script_listener_.get()); | 234 resource_queue_delegates.insert(user_script_listener_.get()); |
231 resource_queue_.Initialize(resource_queue_delegates); | 235 resource_queue_.Initialize(resource_queue_delegates); |
232 } | 236 } |
233 | 237 |
234 ResourceDispatcherHost::~ResourceDispatcherHost() { | 238 ResourceDispatcherHost::~ResourceDispatcherHost() { |
235 AsyncResourceHandler::GlobalCleanup(); | 239 AsyncResourceHandler::GlobalCleanup(); |
236 STLDeleteValues(&pending_requests_); | 240 STLDeleteValues(&pending_requests_); |
| 241 STLDeleteValues(&interrupted_requests_); |
237 | 242 |
238 user_script_listener_->ShutdownMainThread(); | 243 user_script_listener_->ShutdownMainThread(); |
239 } | 244 } |
240 | 245 |
241 void ResourceDispatcherHost::Initialize() { | 246 void ResourceDispatcherHost::Initialize() { |
242 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 247 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
243 webkit_thread_->Initialize(); | 248 webkit_thread_->Initialize(); |
244 safe_browsing_->Initialize(); | 249 safe_browsing_->Initialize(); |
245 ChromeThread::PostTask( | 250 ChromeThread::PostTask( |
246 ChromeThread::IO, FROM_HERE, | 251 ChromeThread::IO, |
| 252 FROM_HERE, |
247 NewRunnableFunction(&appcache::AppCacheInterceptor::EnsureRegistered)); | 253 NewRunnableFunction(&appcache::AppCacheInterceptor::EnsureRegistered)); |
248 } | 254 } |
249 | 255 |
250 void ResourceDispatcherHost::Shutdown() { | 256 void ResourceDispatcherHost::Shutdown() { |
251 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 257 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
252 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, new ShutdownTask(this)); | 258 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, new ShutdownTask(this)); |
253 } | 259 } |
254 | 260 |
255 void ResourceDispatcherHost::SetRequestInfo( | 261 void ResourceDispatcherHost::SetRequestInfo( |
256 URLRequest* request, | 262 URLRequest* request, |
257 ResourceDispatcherHostRequestInfo* info) { | 263 ResourceDispatcherHostRequestInfo* info) { |
258 request->SetUserData(NULL, info); | 264 request->SetUserData(NULL, info); |
259 } | 265 } |
260 | 266 |
261 void ResourceDispatcherHost::OnShutdown() { | 267 void ResourceDispatcherHost::OnShutdown() { |
262 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | 268 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
263 is_shutdown_ = true; | 269 is_shutdown_ = true; |
264 resource_queue_.Shutdown(); | 270 resource_queue_.Shutdown(); |
265 STLDeleteValues(&pending_requests_); | 271 STLDeleteValues(&pending_requests_); |
| 272 STLDeleteValues(&interrupted_requests_); |
266 // Make sure we shutdown the timer now, otherwise by the time our destructor | 273 // Make sure we shutdown the timer now, otherwise by the time our destructor |
267 // runs if the timer is still running the Task is deleted twice (once by | 274 // runs if the timer is still running the Task is deleted twice (once by |
268 // the MessageLoop and the second time by RepeatingTimer). | 275 // the MessageLoop and the second time by RepeatingTimer). |
269 update_load_states_timer_.Stop(); | 276 update_load_states_timer_.Stop(); |
270 | 277 |
271 // Clear blocked requests if any left. | 278 // Clear blocked requests if any left. |
272 // Note that we have to do this in 2 passes as we cannot call | 279 // Note that we have to do this in 2 passes as we cannot call |
273 // CancelBlockedRequestsForRoute while iterating over | 280 // CancelBlockedRequestsForRoute while iterating over |
274 // blocked_requests_map_, as it modifies it. | 281 // blocked_requests_map_, as it modifies it. |
275 std::set<ProcessRouteIDs> ids; | 282 std::set<ProcessRouteIDs> ids; |
276 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); | 283 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); |
277 iter != blocked_requests_map_.end(); ++iter) { | 284 iter != blocked_requests_map_.end(); ++iter) { |
278 std::pair<std::set<ProcessRouteIDs>::iterator, bool> result = | 285 std::pair<std::set<ProcessRouteIDs>::iterator, bool> result = |
279 ids.insert(iter->first); | 286 ids.insert(iter->first); |
280 // We should not have duplicates. | 287 // We should not have duplicates. |
281 DCHECK(result.second); | 288 DCHECK(result.second); |
282 } | 289 } |
283 for (std::set<ProcessRouteIDs>::const_iterator iter = ids.begin(); | 290 for (std::set<ProcessRouteIDs>::const_iterator iter = ids.begin(); |
284 iter != ids.end(); ++iter) { | 291 iter != ids.end(); ++iter) { |
285 CancelBlockedRequestsForRoute(iter->first, iter->second); | 292 CancelBlockedRequestsForRoute(iter->first, iter->second); |
286 } | 293 } |
287 } | 294 } |
288 | 295 |
289 bool ResourceDispatcherHost::HandleExternalProtocol(int request_id, | 296 bool ResourceDispatcherHost::HandleExternalProtocol(int request_id, |
290 int child_id, | 297 int process_unique_id, |
291 int route_id, | 298 int route_id, |
292 const GURL& url, | 299 const GURL& url, |
293 ResourceType::Type type, | 300 ResourceType::Type type, |
294 ResourceHandler* handler) { | 301 ResourceHandler* handler) { |
295 if (!ResourceType::IsFrame(type) || URLRequest::IsHandledURL(url)) | 302 if (!ResourceType::IsFrame(type) || URLRequest::IsHandledURL(url)) |
296 return false; | 303 return false; |
297 | 304 |
298 ChromeThread::PostTask( | 305 ChromeThread::PostTask( |
299 ChromeThread::UI, FROM_HERE, | 306 ChromeThread::UI, |
| 307 FROM_HERE, |
300 NewRunnableFunction( | 308 NewRunnableFunction( |
301 &ExternalProtocolHandler::LaunchUrl, url, child_id, route_id)); | 309 &ExternalProtocolHandler::LaunchUrl, |
| 310 url, |
| 311 process_unique_id, |
| 312 route_id)); |
302 | 313 |
303 handler->OnResponseCompleted(request_id, URLRequestStatus( | 314 handler->OnResponseCompleted(request_id, URLRequestStatus( |
304 URLRequestStatus::FAILED, | 315 URLRequestStatus::FAILED, |
305 net::ERR_ABORTED), | 316 net::ERR_ABORTED), |
306 std::string()); // No security info necessary. | 317 std::string()); // No security info necessary. |
307 return true; | 318 return true; |
308 } | 319 } |
309 | 320 |
310 bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, | 321 bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, |
311 Receiver* receiver, | 322 Receiver* receiver, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 BeginRequest(request_id, request_data, sync_result, | 366 BeginRequest(request_id, request_data, sync_result, |
356 sync_result->routing_id()); | 367 sync_result->routing_id()); |
357 } | 368 } |
358 | 369 |
359 void ResourceDispatcherHost::BeginRequest( | 370 void ResourceDispatcherHost::BeginRequest( |
360 int request_id, | 371 int request_id, |
361 const ViewHostMsg_Resource_Request& request_data, | 372 const ViewHostMsg_Resource_Request& request_data, |
362 IPC::Message* sync_result, // only valid for sync | 373 IPC::Message* sync_result, // only valid for sync |
363 int route_id) { | 374 int route_id) { |
364 ChildProcessInfo::ProcessType process_type = receiver_->type(); | 375 ChildProcessInfo::ProcessType process_type = receiver_->type(); |
365 int child_id = receiver_->id(); | 376 int child_process_unique_id = receiver_->id(); |
366 ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>( | 377 ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>( |
367 receiver_->GetRequestContext(request_id, request_data)); | 378 receiver_->GetRequestContext(request_id, request_data)); |
368 if (!context) { | 379 if (!context) { |
369 URLRequestContextGetter* context_getter = | 380 URLRequestContextGetter* context_getter = |
370 Profile::GetDefaultRequestContext(); | 381 Profile::GetDefaultRequestContext(); |
371 if (context_getter) { | 382 if (context_getter) { |
372 context = static_cast<ChromeURLRequestContext*>( | 383 context = static_cast<ChromeURLRequestContext*>( |
373 context_getter->GetURLRequestContext()); | 384 context_getter->GetURLRequestContext()); |
374 } | 385 } |
375 } | 386 } |
376 | 387 |
377 // Might need to resolve the blob references in the upload data. | 388 // Might need to resolve the blob references in the upload data. |
378 if (request_data.upload_data) { | 389 if (request_data.upload_data) { |
379 context->blob_storage_context()->controller()-> | 390 context->blob_storage_context()->controller()-> |
380 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); | 391 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); |
381 } | 392 } |
382 | 393 |
383 if (is_shutdown_ || | 394 if (is_shutdown_ || !ShouldServiceRequest(process_type, |
384 !ShouldServiceRequest(process_type, child_id, request_data)) { | 395 child_process_unique_id, |
| 396 request_data)) { |
385 URLRequestStatus status(URLRequestStatus::FAILED, net::ERR_ABORTED); | 397 URLRequestStatus status(URLRequestStatus::FAILED, net::ERR_ABORTED); |
386 if (sync_result) { | 398 if (sync_result) { |
387 SyncLoadResult result; | 399 SyncLoadResult result; |
388 result.status = status; | 400 result.status = status; |
389 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result); | 401 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result); |
390 receiver_->Send(sync_result); | 402 receiver_->Send(sync_result); |
391 } else { | 403 } else { |
392 // Tell the renderer that this request was disallowed. | 404 // Tell the renderer that this request was disallowed. |
393 receiver_->Send(new ViewMsg_Resource_RequestComplete( | 405 receiver_->Send(new ViewMsg_Resource_RequestComplete( |
394 route_id, | 406 route_id, |
395 request_id, | 407 request_id, |
396 status, | 408 status, |
397 std::string(), // No security info needed, connection was not | 409 std::string(), // No security info needed, connection was not |
398 base::Time())); // established. | 410 base::Time())); // established. |
399 } | 411 } |
400 return; | 412 return; |
401 } | 413 } |
402 | 414 |
403 // Ensure the Chrome plugins are loaded, as they may intercept network | 415 // Ensure the Chrome plugins are loaded, as they may intercept network |
404 // requests. Does nothing if they are already loaded. | 416 // requests. Does nothing if they are already loaded. |
405 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by | 417 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by |
406 // starting the load earlier in a BG thread. | 418 // starting the load earlier in a BG thread. |
407 PluginService::GetInstance()->LoadChromePlugins(this); | 419 PluginService::GetInstance()->LoadChromePlugins(this); |
408 | 420 |
409 // Construct the event handler. | 421 // Construct the event handler. |
410 scoped_refptr<ResourceHandler> handler; | 422 scoped_refptr<ResourceHandler> handler; |
411 if (sync_result) { | 423 if (sync_result) { |
412 handler = new SyncResourceHandler(receiver_, | 424 handler = new SyncResourceHandler(receiver_, |
413 child_id, | 425 child_process_unique_id, |
414 request_data.url, | 426 request_data.url, |
415 sync_result, | 427 sync_result, |
416 this); | 428 this); |
417 } else { | 429 } else { |
418 handler = new AsyncResourceHandler(receiver_, | 430 handler = new AsyncResourceHandler(receiver_, |
419 child_id, | 431 child_process_unique_id, |
420 route_id, | 432 route_id, |
421 receiver_->handle(), | 433 receiver_->handle(), |
422 request_data.url, | 434 request_data.url, |
423 this); | 435 this); |
424 } | 436 } |
425 | 437 |
426 if (request_data.download_to_file) | 438 if (request_data.download_to_file) |
427 handler = new RedirectToFileResourceHandler(handler, child_id, this); | 439 handler = new RedirectToFileResourceHandler(handler, |
| 440 child_process_unique_id, |
| 441 this); |
428 | 442 |
429 if (HandleExternalProtocol(request_id, child_id, route_id, | 443 if (HandleExternalProtocol(request_id, child_process_unique_id, route_id, |
430 request_data.url, request_data.resource_type, | 444 request_data.url, request_data.resource_type, |
431 handler)) { | 445 handler)) { |
432 return; | 446 return; |
433 } | 447 } |
434 | 448 |
435 // Construct the request. | 449 // Construct the request. |
436 URLRequest* request = new URLRequest(request_data.url, this); | 450 URLRequest* request = new URLRequest(request_data.url, this); |
437 request->set_method(request_data.method); | 451 request->set_method(request_data.method); |
438 request->set_first_party_for_cookies(request_data.first_party_for_cookies); | 452 request->set_first_party_for_cookies(request_data.first_party_for_cookies); |
439 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( | 453 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( |
(...skipping 22 matching lines...) Expand all Loading... |
462 upload_size = request_data.upload_data->GetContentLength(); | 476 upload_size = request_data.upload_data->GetContentLength(); |
463 } | 477 } |
464 | 478 |
465 // Install a CrossSiteResourceHandler if this request is coming from a | 479 // Install a CrossSiteResourceHandler if this request is coming from a |
466 // RenderViewHost with a pending cross-site request. We only check this for | 480 // RenderViewHost with a pending cross-site request. We only check this for |
467 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do | 481 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do |
468 // not count as cross-site, otherwise it gets blocked indefinitely. | 482 // not count as cross-site, otherwise it gets blocked indefinitely. |
469 if (request_data.resource_type == ResourceType::MAIN_FRAME && | 483 if (request_data.resource_type == ResourceType::MAIN_FRAME && |
470 process_type == ChildProcessInfo::RENDER_PROCESS && | 484 process_type == ChildProcessInfo::RENDER_PROCESS && |
471 Singleton<CrossSiteRequestManager>::get()-> | 485 Singleton<CrossSiteRequestManager>::get()-> |
472 HasPendingCrossSiteRequest(child_id, route_id)) { | 486 HasPendingCrossSiteRequest(child_process_unique_id, route_id)) { |
473 // Wrap the event handler to be sure the current page's onunload handler | 487 // Wrap the event handler to be sure the current page's onunload handler |
474 // has a chance to run before we render the new page. | 488 // has a chance to run before we render the new page. |
475 handler = new CrossSiteResourceHandler(handler, | 489 handler = new CrossSiteResourceHandler(handler, |
476 child_id, | 490 child_process_unique_id, |
477 route_id, | 491 route_id, |
478 this); | 492 this); |
479 } | 493 } |
480 | 494 |
481 // Insert a buffered event handler before the actual one. | 495 // Insert a buffered event handler before the actual one. |
482 handler = new BufferedResourceHandler(handler, this, request); | 496 handler = new BufferedResourceHandler(handler, this, request); |
483 | 497 |
484 // Insert safe browsing at the front of the chain, so it gets to decide | 498 // Insert safe browsing at the front of the chain, so it gets to decide |
485 // on policies first. | 499 // on policies first. |
486 if (safe_browsing_->enabled()) { | 500 if (safe_browsing_->enabled()) { |
487 handler = CreateSafeBrowsingResourceHandler(handler, child_id, route_id, | 501 handler = CreateSafeBrowsingResourceHandler(handler, |
| 502 child_process_unique_id, |
| 503 route_id, |
488 request_data.resource_type); | 504 request_data.resource_type); |
489 } | 505 } |
490 | 506 |
491 #if defined(OS_CHROMEOS) | 507 #if defined(OS_CHROMEOS) |
492 // We check offline first, then check safe browsing so that we still can block | 508 // We check offline first, then check safe browsing so that we still can block |
493 // unsafe site after we remove offline page. | 509 // unsafe site after we remove offline page. |
494 handler = | 510 handler = new OfflineResourceHandler(handler, |
495 new OfflineResourceHandler(handler, child_id, route_id, this, request); | 511 child_process_unique_id, |
| 512 route_id, |
| 513 this, |
| 514 request); |
496 #endif | 515 #endif |
497 | 516 |
498 // Make extra info and read footer (contains request ID). | 517 // Make extra info and read footer (contains request ID). |
499 ResourceDispatcherHostRequestInfo* extra_info = | 518 ResourceDispatcherHostRequestInfo* extra_info = |
500 new ResourceDispatcherHostRequestInfo( | 519 new ResourceDispatcherHostRequestInfo( |
501 handler, | 520 handler, |
502 process_type, | 521 process_type, |
503 child_id, | 522 child_process_unique_id, |
504 route_id, | 523 route_id, |
505 request_id, | 524 request_id, |
506 request_data.frame_origin, | 525 request_data.frame_origin, |
507 request_data.main_frame_origin, | 526 request_data.main_frame_origin, |
508 request_data.resource_type, | 527 request_data.resource_type, |
509 upload_size, | 528 upload_size, |
510 false, // is download | 529 false, // is download |
511 ResourceType::IsFrame(request_data.resource_type), // allow_download | 530 ResourceType::IsFrame(request_data.resource_type), // allow_download |
512 request_data.host_renderer_id, | 531 request_data.host_renderer_id, |
513 request_data.host_render_view_id); | 532 request_data.host_render_view_id); |
514 ApplyExtensionLocalizationFilter(request_data.url, request_data.resource_type, | 533 ApplyExtensionLocalizationFilter(request_data.url, request_data.resource_type, |
515 extra_info); | 534 extra_info); |
516 SetRequestInfo(request, extra_info); // Request takes ownership. | 535 SetRequestInfo(request, extra_info); // Request takes ownership. |
517 chrome_browser_net::SetOriginProcessUniqueIDForRequest( | 536 chrome_browser_net::SetOriginProcessUniqueIDForRequest( |
518 request_data.origin_child_id, request); | 537 request_data.origin_child_id, request); |
519 | 538 |
520 // Have the appcache associate its extra info with the request. | 539 // Have the appcache associate its extra info with the request. |
521 appcache::AppCacheInterceptor::SetExtraRequestInfo( | 540 appcache::AppCacheInterceptor::SetExtraRequestInfo( |
522 request, context ? context->appcache_service() : NULL, child_id, | 541 request, |
523 request_data.appcache_host_id, request_data.resource_type); | 542 context ? context->appcache_service() : NULL, |
| 543 child_process_unique_id, |
| 544 request_data.appcache_host_id, |
| 545 request_data.resource_type); |
524 | 546 |
525 BeginRequestInternal(request); | 547 BeginRequestInternal(request); |
526 } | 548 } |
527 | 549 |
528 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { | 550 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { |
529 DataReceivedACK(receiver_->id(), request_id); | 551 DataReceivedACK(receiver_->id(), request_id); |
530 } | 552 } |
531 | 553 |
532 void ResourceDispatcherHost::DataReceivedACK(int child_id, | 554 void ResourceDispatcherHost::DataReceivedACK(int process_unique_id, |
533 int request_id) { | 555 int request_id) { |
534 PendingRequestList::iterator i = pending_requests_.find( | 556 PendingRequestList::iterator i = pending_requests_.find( |
535 GlobalRequestID(child_id, request_id)); | 557 GlobalRequestID(process_unique_id, request_id)); |
536 if (i == pending_requests_.end()) | 558 if (i == pending_requests_.end()) |
537 return; | 559 return; |
538 | 560 |
539 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); | 561 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); |
540 | 562 |
541 // Decrement the number of pending data messages. | 563 // Decrement the number of pending data messages. |
542 info->DecrementPendingDataCount(); | 564 info->DecrementPendingDataCount(); |
543 | 565 |
544 // If the pending data count was higher than the max, resume the request. | 566 // If the pending data count was higher than the max, resume the request. |
545 if (info->pending_data_count() == kMaxPendingDataMessages) { | 567 if (info->pending_data_count() == kMaxPendingDataMessages) { |
546 // Decrement the pending data count one more time because we also | 568 // Decrement the pending data count one more time because we also |
547 // incremented it before pausing the request. | 569 // incremented it before pausing the request. |
548 info->DecrementPendingDataCount(); | 570 info->DecrementPendingDataCount(); |
549 | 571 |
550 // Resume the request. | 572 // Resume the request. |
551 PauseRequest(child_id, request_id, false); | 573 PauseRequest(process_unique_id, request_id, false); |
552 } | 574 } |
553 } | 575 } |
554 | 576 |
555 bool ResourceDispatcherHost::Send(IPC::Message* message) { | 577 bool ResourceDispatcherHost::Send(IPC::Message* message) { |
556 delete message; | 578 delete message; |
557 return false; | 579 return false; |
558 } | 580 } |
559 | 581 |
560 void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { | 582 void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { |
561 int child_id = receiver_->id(); | 583 int child_process_unique_id = receiver_->id(); |
562 PendingRequestList::iterator i = pending_requests_.find( | 584 PendingRequestList::iterator i = pending_requests_.find( |
563 GlobalRequestID(child_id, request_id)); | 585 GlobalRequestID(child_process_unique_id, request_id)); |
564 if (i == pending_requests_.end()) | 586 if (i == pending_requests_.end()) |
565 return; | 587 return; |
566 | 588 |
567 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); | 589 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); |
568 info->set_waiting_for_upload_progress_ack(false); | 590 info->set_waiting_for_upload_progress_ack(false); |
569 } | 591 } |
570 | 592 |
571 void ResourceDispatcherHost::OnCancelRequest(int request_id) { | 593 void ResourceDispatcherHost::OnCancelRequest(int request_id) { |
572 CancelRequest(receiver_->id(), request_id, true); | 594 CancelRequest(receiver_->id(), request_id, true); |
573 } | 595 } |
574 | 596 |
575 void ResourceDispatcherHost::OnFollowRedirect( | 597 void ResourceDispatcherHost::OnFollowRedirect( |
576 int request_id, | 598 int request_id, |
577 bool has_new_first_party_for_cookies, | 599 bool has_new_first_party_for_cookies, |
578 const GURL& new_first_party_for_cookies) { | 600 const GURL& new_first_party_for_cookies) { |
579 FollowDeferredRedirect(receiver_->id(), request_id, | 601 FollowDeferredRedirect(receiver_->id(), request_id, |
580 has_new_first_party_for_cookies, | 602 has_new_first_party_for_cookies, |
581 new_first_party_for_cookies); | 603 new_first_party_for_cookies); |
582 } | 604 } |
583 | 605 |
584 ResourceHandler* ResourceDispatcherHost::CreateSafeBrowsingResourceHandler( | 606 ResourceHandler* ResourceDispatcherHost::CreateSafeBrowsingResourceHandler( |
585 ResourceHandler* handler, int child_id, int route_id, | 607 ResourceHandler* handler, int process_unique_id, int route_id, |
586 ResourceType::Type resource_type) { | 608 ResourceType::Type resource_type) { |
587 return new SafeBrowsingResourceHandler(handler, | 609 return new SafeBrowsingResourceHandler(handler, |
588 child_id, | 610 process_unique_id, |
589 route_id, | 611 route_id, |
590 resource_type, | 612 resource_type, |
591 safe_browsing_, | 613 safe_browsing_, |
592 this, | 614 this, |
593 receiver_); | 615 receiver_); |
594 } | 616 } |
595 | 617 |
596 ResourceDispatcherHostRequestInfo* | 618 ResourceDispatcherHostRequestInfo* |
597 ResourceDispatcherHost::CreateRequestInfoForBrowserRequest( | 619 ResourceDispatcherHost::CreateRequestInfoForBrowserRequest( |
598 ResourceHandler* handler, int child_id, int route_id, bool download) { | 620 ResourceHandler* handler, |
| 621 int process_unique_id, |
| 622 int route_id, |
| 623 bool download) { |
599 return new ResourceDispatcherHostRequestInfo(handler, | 624 return new ResourceDispatcherHostRequestInfo(handler, |
600 ChildProcessInfo::RENDER_PROCESS, | 625 ChildProcessInfo::RENDER_PROCESS, |
601 child_id, | 626 process_unique_id, |
602 route_id, | 627 route_id, |
603 request_id_, | 628 request_id_, |
604 "null", // frame_origin | 629 "null", // frame_origin |
605 "null", // main_frame_origin | 630 "null", // main_frame_origin |
606 ResourceType::SUB_RESOURCE, | 631 ResourceType::SUB_RESOURCE, |
607 0, // upload_size | 632 0, // upload_size |
608 download, // is_download | 633 download, // is_download |
609 download, // allow_download | 634 download, // allow_download |
610 -1, // Host renderer id | 635 -1, // Host renderer id |
611 -1); // Host render view id | 636 -1); // Host render view id |
(...skipping 22 matching lines...) Expand all Loading... |
634 &RenderViewHost::ClosePageIgnoringUnloadEvents); | 659 &RenderViewHost::ClosePageIgnoringUnloadEvents); |
635 } | 660 } |
636 } | 661 } |
637 | 662 |
638 // We are explicitly forcing the download of 'url'. | 663 // We are explicitly forcing the download of 'url'. |
639 void ResourceDispatcherHost::BeginDownload( | 664 void ResourceDispatcherHost::BeginDownload( |
640 const GURL& url, | 665 const GURL& url, |
641 const GURL& referrer, | 666 const GURL& referrer, |
642 const DownloadSaveInfo& save_info, | 667 const DownloadSaveInfo& save_info, |
643 bool prompt_for_save_location, | 668 bool prompt_for_save_location, |
644 int child_id, | 669 int process_unique_id, |
645 int route_id, | 670 int route_id, |
646 URLRequestContext* request_context) { | 671 URLRequestContext* request_context, |
| 672 uint64 start_offset) { |
647 if (is_shutdown_) | 673 if (is_shutdown_) |
648 return; | 674 return; |
649 | 675 |
650 // Check if the renderer is permitted to request the requested URL. | 676 // Check if the renderer is permitted to request the requested URL. |
651 if (!ChildProcessSecurityPolicy::GetInstance()-> | 677 if (!ChildProcessSecurityPolicy::GetInstance()-> |
652 CanRequestURL(child_id, url)) { | 678 CanRequestURL(process_unique_id, url)) { |
653 LOG(INFO) << "Denied unauthorized download request for " << | 679 LOG(INFO) << "Denied unauthorized download request for " << |
654 url.possibly_invalid_spec(); | 680 url.possibly_invalid_spec(); |
655 return; | 681 return; |
656 } | 682 } |
657 | 683 |
658 // Ensure the Chrome plugins are loaded, as they may intercept network | 684 // Ensure the Chrome plugins are loaded, as they may intercept network |
659 // requests. Does nothing if they are already loaded. | 685 // requests. Does nothing if they are already loaded. |
660 PluginService::GetInstance()->LoadChromePlugins(this); | 686 PluginService::GetInstance()->LoadChromePlugins(this); |
661 URLRequest* request = new URLRequest(url, this); | 687 URLRequest* request = new URLRequest(url, this); |
662 | 688 |
663 request_id_--; | 689 request_id_--; |
664 | 690 |
665 scoped_refptr<ResourceHandler> handler = | 691 scoped_refptr<ResourceHandler> handler = |
666 new DownloadResourceHandler(this, | 692 new DownloadResourceHandler(this, |
667 child_id, | 693 process_unique_id, |
668 route_id, | 694 route_id, |
669 request_id_, | 695 request_id_, |
670 url, | 696 url, |
671 download_file_manager_.get(), | 697 download_file_manager_.get(), |
672 request, | 698 request, |
673 prompt_for_save_location, | 699 prompt_for_save_location, |
674 save_info); | 700 save_info); |
675 | 701 |
676 if (safe_browsing_->enabled()) { | 702 if (safe_browsing_->enabled()) { |
677 handler = CreateSafeBrowsingResourceHandler(handler, child_id, route_id, | 703 handler = CreateSafeBrowsingResourceHandler(handler, |
| 704 process_unique_id, |
| 705 route_id, |
678 ResourceType::MAIN_FRAME); | 706 ResourceType::MAIN_FRAME); |
679 } | 707 } |
680 | 708 |
681 if (!URLRequest::IsHandledURL(url)) { | 709 if (!URLRequest::IsHandledURL(url)) { |
682 LOG(INFO) << "Download request for unsupported protocol: " << | 710 LOG(INFO) << "Download request for unsupported protocol: " << |
683 url.possibly_invalid_spec(); | 711 url.possibly_invalid_spec(); |
684 return; | 712 return; |
685 } | 713 } |
686 | 714 |
687 request->set_method("GET"); | 715 request->set_method("GET"); |
688 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( | 716 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( |
689 switches::kNoReferrers) ? std::string() : referrer.spec()); | 717 switches::kNoReferrers) ? std::string() : referrer.spec()); |
690 request->set_context(request_context); | 718 request->set_context(request_context); |
691 request->set_load_flags(request->load_flags() | | 719 request->set_load_flags(request->load_flags() | |
692 net::LOAD_IS_DOWNLOAD); | 720 net::LOAD_IS_DOWNLOAD); |
693 | 721 |
694 ResourceDispatcherHostRequestInfo* extra_info = | 722 ResourceDispatcherHostRequestInfo* extra_info = |
695 CreateRequestInfoForBrowserRequest(handler, child_id, route_id, true); | 723 CreateRequestInfoForBrowserRequest(handler, |
| 724 process_unique_id, |
| 725 route_id, |
| 726 true); |
| 727 |
| 728 // If we're not at the beginning of the file, retrieve only the remaining |
| 729 // portion. |
| 730 if (start_offset > 0) { |
| 731 request->SetExtraRequestHeaderByName( |
| 732 "Range", |
| 733 StringPrintf("bytes=%" PRId64 "-", start_offset), |
| 734 false); |
| 735 extra_info->set_was_interrupted(true); |
| 736 extra_info->set_interrupted_bytes(start_offset); |
| 737 } |
| 738 |
696 SetRequestInfo(request, extra_info); // Request takes ownership. | 739 SetRequestInfo(request, extra_info); // Request takes ownership. |
697 chrome_browser_net::SetOriginProcessUniqueIDForRequest(child_id, request); | 740 chrome_browser_net::SetOriginProcessUniqueIDForRequest(process_unique_id, |
| 741 request); |
698 | 742 |
699 BeginRequestInternal(request); | 743 BeginRequestInternal(request); |
700 } | 744 } |
701 | 745 |
702 // This function is only used for saving feature. | 746 // This function is only used for saving feature. |
703 void ResourceDispatcherHost::BeginSaveFile(const GURL& url, | 747 void ResourceDispatcherHost::BeginSaveFile(const GURL& url, |
704 const GURL& referrer, | 748 const GURL& referrer, |
705 int child_id, | 749 int process_unique_id, |
706 int route_id, | 750 int route_id, |
707 URLRequestContext* request_context) { | 751 URLRequestContext* request_context) { |
708 if (is_shutdown_) | 752 if (is_shutdown_) |
709 return; | 753 return; |
710 | 754 |
711 // Ensure the Chrome plugins are loaded, as they may intercept network | 755 // Ensure the Chrome plugins are loaded, as they may intercept network |
712 // requests. Does nothing if they are already loaded. | 756 // requests. Does nothing if they are already loaded. |
713 PluginService::GetInstance()->LoadChromePlugins(this); | 757 PluginService::GetInstance()->LoadChromePlugins(this); |
714 | 758 |
715 scoped_refptr<ResourceHandler> handler = | 759 scoped_refptr<ResourceHandler> handler = |
716 new SaveFileResourceHandler(child_id, | 760 new SaveFileResourceHandler(process_unique_id, |
717 route_id, | 761 route_id, |
718 url, | 762 url, |
719 save_file_manager_.get()); | 763 save_file_manager_.get()); |
720 request_id_--; | 764 request_id_--; |
721 | 765 |
722 bool known_proto = URLRequest::IsHandledURL(url); | 766 bool known_proto = URLRequest::IsHandledURL(url); |
723 if (!known_proto) { | 767 if (!known_proto) { |
724 // Since any URLs which have non-standard scheme have been filtered | 768 // Since any URLs which have non-standard scheme have been filtered |
725 // by save manager(see GURL::SchemeIsStandard). This situation | 769 // by save manager(see GURL::SchemeIsStandard). This situation |
726 // should not happen. | 770 // should not happen. |
727 NOTREACHED(); | 771 NOTREACHED(); |
728 return; | 772 return; |
729 } | 773 } |
730 | 774 |
731 URLRequest* request = new URLRequest(url, this); | 775 URLRequest* request = new URLRequest(url, this); |
732 request->set_method("GET"); | 776 request->set_method("GET"); |
733 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( | 777 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( |
734 switches::kNoReferrers) ? std::string() : referrer.spec()); | 778 switches::kNoReferrers) ? std::string() : referrer.spec()); |
735 // So far, for saving page, we need fetch content from cache, in the | 779 // So far, for saving page, we need fetch content from cache, in the |
736 // future, maybe we can use a configuration to configure this behavior. | 780 // future, maybe we can use a configuration to configure this behavior. |
737 request->set_load_flags(net::LOAD_PREFERRING_CACHE); | 781 request->set_load_flags(net::LOAD_PREFERRING_CACHE); |
738 request->set_context(request_context); | 782 request->set_context(request_context); |
739 | 783 |
740 // Since we're just saving some resources we need, disallow downloading. | 784 // Since we're just saving some resources we need, disallow downloading. |
741 ResourceDispatcherHostRequestInfo* extra_info = | 785 ResourceDispatcherHostRequestInfo* extra_info = |
742 CreateRequestInfoForBrowserRequest(handler, child_id, route_id, false); | 786 CreateRequestInfoForBrowserRequest(handler, |
| 787 process_unique_id, |
| 788 route_id, |
| 789 false); |
743 SetRequestInfo(request, extra_info); // Request takes ownership. | 790 SetRequestInfo(request, extra_info); // Request takes ownership. |
744 chrome_browser_net::SetOriginProcessUniqueIDForRequest(child_id, request); | 791 chrome_browser_net::SetOriginProcessUniqueIDForRequest(process_unique_id, |
| 792 request); |
745 | 793 |
746 BeginRequestInternal(request); | 794 BeginRequestInternal(request); |
747 } | 795 } |
748 | 796 |
749 void ResourceDispatcherHost::FollowDeferredRedirect( | 797 void ResourceDispatcherHost::FollowDeferredRedirect( |
750 int child_id, | 798 int process_unique_id, |
751 int request_id, | 799 int request_id, |
752 bool has_new_first_party_for_cookies, | 800 bool has_new_first_party_for_cookies, |
753 const GURL& new_first_party_for_cookies) { | 801 const GURL& new_first_party_for_cookies) { |
754 PendingRequestList::iterator i = pending_requests_.find( | 802 PendingRequestList::iterator i = pending_requests_.find( |
755 GlobalRequestID(child_id, request_id)); | 803 GlobalRequestID(process_unique_id, request_id)); |
756 if (i == pending_requests_.end() || !i->second->status().is_success()) { | 804 if (i == pending_requests_.end() || !i->second->status().is_success()) { |
757 DLOG(WARNING) << "FollowDeferredRedirect for invalid request"; | 805 DLOG(WARNING) << "FollowDeferredRedirect for invalid request"; |
758 return; | 806 return; |
759 } | 807 } |
760 | 808 |
761 if (has_new_first_party_for_cookies) | 809 if (has_new_first_party_for_cookies) |
762 i->second->set_first_party_for_cookies(new_first_party_for_cookies); | 810 i->second->set_first_party_for_cookies(new_first_party_for_cookies); |
763 i->second->FollowDeferredRedirect(); | 811 i->second->FollowDeferredRedirect(); |
764 } | 812 } |
765 | 813 |
766 void ResourceDispatcherHost::StartDeferredRequest(int process_unique_id, | 814 void ResourceDispatcherHost::StartDeferredRequest(int process_unique_id, |
767 int request_id) { | 815 int request_id) { |
768 GlobalRequestID global_id(process_unique_id, request_id); | 816 GlobalRequestID global_id(process_unique_id, request_id); |
769 PendingRequestList::iterator i = pending_requests_.find(global_id); | 817 PendingRequestList::iterator i = pending_requests_.find(global_id); |
770 if (i == pending_requests_.end()) { | 818 if (i == pending_requests_.end()) { |
771 // The request may have been destroyed | 819 // The request may have been destroyed |
772 LOG(WARNING) << "Trying to resume a non-existent request (" | 820 LOG(WARNING) << "Trying to resume a non-existent request (" |
773 << process_unique_id << ", " << request_id << ")"; | 821 << process_unique_id << ", " << request_id << ")"; |
774 return; | 822 return; |
775 } | 823 } |
776 | 824 |
777 // TODO(eroman): are there other considerations for paused or blocked | 825 // TODO(eroman): are there other considerations for paused or blocked |
778 // requests? | 826 // requests? |
779 | 827 |
780 URLRequest* request = i->second; | 828 URLRequest* request = i->second; |
781 InsertIntoResourceQueue(request, *InfoForRequest(request)); | 829 InsertIntoResourceQueue(request, *InfoForRequest(request)); |
782 } | 830 } |
783 | 831 |
784 bool ResourceDispatcherHost::WillSendData(int child_id, | 832 bool ResourceDispatcherHost::WillSendData(int process_unique_id, |
785 int request_id) { | 833 int request_id) { |
786 PendingRequestList::iterator i = pending_requests_.find( | 834 PendingRequestList::iterator i = pending_requests_.find( |
787 GlobalRequestID(child_id, request_id)); | 835 GlobalRequestID(process_unique_id, request_id)); |
788 if (i == pending_requests_.end()) { | 836 if (i == pending_requests_.end()) { |
789 NOTREACHED() << "WillSendData for invalid request"; | 837 NOTREACHED() << "WillSendData for invalid request"; |
790 return false; | 838 return false; |
791 } | 839 } |
792 | 840 |
793 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); | 841 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); |
794 | 842 |
795 info->IncrementPendingDataCount(); | 843 info->IncrementPendingDataCount(); |
796 if (info->pending_data_count() > kMaxPendingDataMessages) { | 844 if (info->pending_data_count() > kMaxPendingDataMessages) { |
797 // We reached the max number of data messages that can be sent to | 845 // We reached the max number of data messages that can be sent to |
798 // the renderer for a given request. Pause the request and wait for | 846 // the renderer for a given request. Pause the request and wait for |
799 // the renderer to start processing them before resuming it. | 847 // the renderer to start processing them before resuming it. |
800 PauseRequest(child_id, request_id, true); | 848 PauseRequest(process_unique_id, request_id, true); |
801 return false; | 849 return false; |
802 } | 850 } |
803 | 851 |
804 return true; | 852 return true; |
805 } | 853 } |
806 | 854 |
807 void ResourceDispatcherHost::PauseRequest(int child_id, | 855 void ResourceDispatcherHost::PauseRequest(int process_unique_id, |
808 int request_id, | 856 int request_id, |
809 bool pause) { | 857 bool pause) { |
810 GlobalRequestID global_id(child_id, request_id); | 858 GlobalRequestID global_id(process_unique_id, request_id); |
811 PendingRequestList::iterator i = pending_requests_.find(global_id); | 859 PendingRequestList::iterator i = pending_requests_.find(global_id); |
812 if (i == pending_requests_.end()) { | 860 if (i == pending_requests_.end()) { |
813 DLOG(WARNING) << "Pausing a request that wasn't found"; | 861 DLOG(WARNING) << "Pausing a request that wasn't found"; |
814 return; | 862 return; |
815 } | 863 } |
816 | 864 |
817 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); | 865 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); |
818 int pause_count = info->pause_count() + (pause ? 1 : -1); | 866 int pause_count = info->pause_count() + (pause ? 1 : -1); |
819 if (pause_count < 0) { | 867 if (pause_count < 0) { |
820 NOTREACHED(); // Unbalanced call to pause. | 868 NOTREACHED(); // Unbalanced call to pause. |
821 return; | 869 return; |
822 } | 870 } |
823 info->set_pause_count(pause_count); | 871 info->set_pause_count(pause_count); |
824 | 872 |
825 RESOURCE_LOG("To pause (" << pause << "): " << i->second->url().spec()); | 873 RESOURCE_LOG("To pause (" << pause << "): " << i->second->url().spec()); |
826 | 874 |
827 // If we're resuming, kick the request to start reading again. Run the read | 875 // If we're resuming, kick the request to start reading again. Run the read |
828 // asynchronously to avoid recursion problems. | 876 // asynchronously to avoid recursion problems. |
829 if (info->pause_count() == 0) { | 877 if (info->pause_count() == 0) { |
830 MessageLoop::current()->PostTask(FROM_HERE, | 878 MessageLoop::current()->PostTask( |
| 879 FROM_HERE, |
831 method_runner_.NewRunnableMethod( | 880 method_runner_.NewRunnableMethod( |
832 &ResourceDispatcherHost::ResumeRequest, global_id)); | 881 &ResourceDispatcherHost::ResumeRequest, global_id)); |
833 } | 882 } |
834 } | 883 } |
835 | 884 |
| 885 void ResourceDispatcherHost::RestartRequest(int process_unique_id, |
| 886 int request_id, |
| 887 DownloadCreateInfo* create_info) { |
| 888 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 889 GlobalRequestID global_id(process_unique_id, request_id); |
| 890 RESOURCE_LOG("Restart : " << url.spec()); |
| 891 |
| 892 // Copy the IDs from the existing interrupted request. |
| 893 PendingRequestList::iterator i = interrupted_requests_.find(global_id); |
| 894 if (i != interrupted_requests_.end()) { |
| 895 URLRequest* request = i->second; |
| 896 if (request) { |
| 897 ResourceDispatcherHostRequestInfo* req_info = InfoForRequest(request); |
| 898 create_info->render_view_id = req_info->route_id(); |
| 899 create_info->child_id = req_info->child_id(); |
| 900 } |
| 901 |
| 902 MoveInterruptedRequestToPending(process_unique_id, request_id); |
| 903 } |
| 904 |
| 905 // Restart the request to continue reading. Run the read asynchronously to |
| 906 // avoid recursion problems. |
| 907 ChromeThread::PostTask( |
| 908 ChromeThread::FILE, |
| 909 FROM_HERE, |
| 910 NewRunnableFunction(&ResourceDispatcherHost::RestartDownload, |
| 911 this, |
| 912 global_id, |
| 913 create_info)); |
| 914 } |
| 915 |
836 int ResourceDispatcherHost::GetOutstandingRequestsMemoryCost( | 916 int ResourceDispatcherHost::GetOutstandingRequestsMemoryCost( |
837 int child_id) const { | 917 int process_unique_id) const { |
838 OutstandingRequestsMemoryCostMap::const_iterator entry = | 918 OutstandingRequestsMemoryCostMap::const_iterator entry = |
839 outstanding_requests_memory_cost_map_.find(child_id); | 919 outstanding_requests_memory_cost_map_.find(process_unique_id); |
840 return (entry == outstanding_requests_memory_cost_map_.end()) ? | 920 return (entry == outstanding_requests_memory_cost_map_.end()) ? |
841 0 : entry->second; | 921 0 : entry->second; |
842 } | 922 } |
843 | 923 |
844 // The object died, so cancel and detach all requests associated with it except | 924 // The object died, so cancel and detach all requests associated with it except |
845 // for downloads, which belong to the browser process even if initiated via a | 925 // for downloads, which belong to the browser process even if initiated via a |
846 // renderer. | 926 // renderer. |
847 void ResourceDispatcherHost::CancelRequestsForProcess(int child_id) { | 927 void ResourceDispatcherHost::CancelRequestsForProcess(int process_unique_id) { |
848 socket_stream_dispatcher_host_->CancelRequestsForProcess(child_id); | 928 socket_stream_dispatcher_host_->CancelRequestsForProcess(process_unique_id); |
849 CancelRequestsForRoute(child_id, -1 /* cancel all */); | 929 CancelRequestsForRoute(process_unique_id, -1 /* cancel all */); |
850 } | 930 } |
851 | 931 |
852 void ResourceDispatcherHost::CancelRequestsForRoute(int child_id, | 932 std::vector<GlobalRequestID> ResourceDispatcherHost::GetMatchingRequests( |
| 933 int process_unique_id, |
| 934 int route_id, |
| 935 const PendingRequestList& requests) { |
| 936 std::vector<GlobalRequestID> matching_requests; |
| 937 for (PendingRequestList::const_iterator i = requests.begin(); |
| 938 i != requests.end(); ++i) { |
| 939 if (i->first.child_id == process_unique_id) { |
| 940 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); |
| 941 if (!info->is_download() && |
| 942 (route_id == -1 || route_id == info->route_id())) { |
| 943 matching_requests.push_back( |
| 944 GlobalRequestID(process_unique_id, i->first.request_id)); |
| 945 } |
| 946 } |
| 947 } |
| 948 return matching_requests; |
| 949 } |
| 950 |
| 951 void ResourceDispatcherHost::CancelRequestsForRoute(int process_unique_id, |
853 int route_id) { | 952 int route_id) { |
854 // Since pending_requests_ is a map, we first build up a list of all of the | 953 // Since pending_requests_ is a map, we first build up a list of all of the |
855 // matching requests to be cancelled, and then we cancel them. Since there | 954 // matching requests to be cancelled, and then we cancel them. Since there |
856 // may be more than one request to cancel, we cannot simply hold onto the map | 955 // may be more than one request to cancel, we cannot simply hold onto the map |
857 // iterators found in the first loop. | 956 // iterators found in the first loop. |
858 | 957 |
859 // Find the global ID of all matching elements. | 958 // Find the global ID of all matching elements. |
860 std::vector<GlobalRequestID> matching_requests; | 959 std::vector<GlobalRequestID> matching_requests = |
861 for (PendingRequestList::const_iterator i = pending_requests_.begin(); | 960 GetMatchingRequests(process_unique_id, route_id, pending_requests_); |
862 i != pending_requests_.end(); ++i) { | 961 std::vector<GlobalRequestID> matching_requests2 = |
863 if (i->first.child_id == child_id) { | 962 GetMatchingRequests(process_unique_id, route_id, interrupted_requests_); |
864 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); | 963 matching_requests.insert(matching_requests.begin(), |
865 if (!info->is_download() && | 964 matching_requests2.begin(), |
866 (route_id == -1 || route_id == info->route_id())) { | 965 matching_requests2.end()); |
867 matching_requests.push_back( | |
868 GlobalRequestID(child_id, i->first.request_id)); | |
869 } | |
870 } | |
871 } | |
872 | 966 |
873 // Remove matches. | 967 // Remove matches. |
874 for (size_t i = 0; i < matching_requests.size(); ++i) { | 968 for (size_t i = 0; i < matching_requests.size(); ++i) { |
875 PendingRequestList::iterator iter = | 969 PendingRequestList::iterator iter = |
876 pending_requests_.find(matching_requests[i]); | 970 pending_requests_.find(matching_requests[i]); |
877 // Although every matching request was in pending_requests_ when we built | 971 // Although every matching request was in pending_requests_ when we built |
878 // matching_requests, it is normal for a matching request to be not found | 972 // matching_requests, it is normal for a matching request to be not found |
879 // in pending_requests_ after we have removed some matching requests from | 973 // in pending_requests_ after we have removed some matching requests from |
880 // pending_requests_. For example, deleting a URLRequest that has | 974 // pending_requests_. For example, deleting a URLRequest that has |
881 // exclusive (write) access to an HTTP cache entry may unblock another | 975 // exclusive (write) access to an HTTP cache entry may unblock another |
882 // URLRequest that needs exclusive access to the same cache entry, and | 976 // URLRequest that needs exclusive access to the same cache entry, and |
883 // that URLRequest may complete and remove itself from pending_requests_. | 977 // that URLRequest may complete and remove itself from pending_requests_. |
884 // So we need to check that iter is not equal to pending_requests_.end(). | 978 // So we need to check that iter is not equal to pending_requests_.end(). |
885 if (iter != pending_requests_.end()) | 979 if (iter != pending_requests_.end()) |
886 RemovePendingRequest(iter); | 980 RemoveRequestFromMap(iter); |
| 981 // Same for interrupted requests. |
| 982 iter = interrupted_requests_.find(matching_requests[i]); |
| 983 if (iter != interrupted_requests_.end()) |
| 984 RemoveRequestFromMap(iter); |
887 } | 985 } |
888 | 986 |
889 // Now deal with blocked requests if any. | 987 // Now deal with blocked requests if any. |
890 if (route_id != -1) { | 988 if (route_id != -1) { |
891 if (blocked_requests_map_.find(std::pair<int, int>(child_id, route_id)) != | 989 if (blocked_requests_map_.find(std::pair<int, int>(process_unique_id, |
| 990 route_id)) != |
892 blocked_requests_map_.end()) { | 991 blocked_requests_map_.end()) { |
893 CancelBlockedRequestsForRoute(child_id, route_id); | 992 CancelBlockedRequestsForRoute(process_unique_id, route_id); |
894 } | 993 } |
895 } else { | 994 } else { |
896 // We have to do all render views for the process |child_id|. | 995 // We have to do all render views for the process |process_unique_id|. |
897 // Note that we have to do this in 2 passes as we cannot call | 996 // Note that we have to do this in 2 passes as we cannot call |
898 // CancelBlockedRequestsForRoute while iterating over | 997 // CancelBlockedRequestsForRoute while iterating over |
899 // blocked_requests_map_, as it modifies it. | 998 // blocked_requests_map_, as it modifies it. |
900 std::set<int> route_ids; | 999 std::set<int> route_ids; |
901 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); | 1000 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); |
902 iter != blocked_requests_map_.end(); ++iter) { | 1001 iter != blocked_requests_map_.end(); ++iter) { |
903 if (iter->first.first == child_id) | 1002 if (iter->first.first == process_unique_id) |
904 route_ids.insert(iter->first.second); | 1003 route_ids.insert(iter->first.second); |
905 } | 1004 } |
906 for (std::set<int>::const_iterator iter = route_ids.begin(); | 1005 for (std::set<int>::const_iterator iter = route_ids.begin(); |
907 iter != route_ids.end(); ++iter) { | 1006 iter != route_ids.end(); ++iter) { |
908 CancelBlockedRequestsForRoute(child_id, *iter); | 1007 CancelBlockedRequestsForRoute(process_unique_id, *iter); |
909 } | 1008 } |
910 } | 1009 } |
911 } | 1010 } |
912 | 1011 |
913 // Cancels the request and removes it from the list. | 1012 // Cancels the request and removes it from the list. |
914 void ResourceDispatcherHost::RemovePendingRequest(int child_id, | 1013 void ResourceDispatcherHost::RemovePendingRequest(int process_unique_id, |
915 int request_id) { | 1014 int request_id) { |
916 PendingRequestList::iterator i = pending_requests_.find( | 1015 GlobalRequestID id(process_unique_id, request_id); |
917 GlobalRequestID(child_id, request_id)); | 1016 PendingRequestList::iterator i = pending_requests_.find(id); |
918 if (i == pending_requests_.end()) { | 1017 if (i == pending_requests_.end()) { |
| 1018 i = interrupted_requests_.find(id); |
| 1019 if (i != interrupted_requests_.end()) |
| 1020 return; |
919 NOTREACHED() << "Trying to remove a request that's not here"; | 1021 NOTREACHED() << "Trying to remove a request that's not here"; |
920 return; | 1022 return; |
921 } | 1023 } |
922 RemovePendingRequest(i); | 1024 RemoveRequestFromMap(i); |
923 } | 1025 } |
924 | 1026 |
925 void ResourceDispatcherHost::RemovePendingRequest( | 1027 // Cancels the request and removes it from the list. |
| 1028 void ResourceDispatcherHost::RemoveInterruptedRequest(int process_unique_id, |
| 1029 int request_id) { |
| 1030 GlobalRequestID id(process_unique_id, request_id); |
| 1031 PendingRequestList::iterator i = interrupted_requests_.find(id); |
| 1032 if (i == interrupted_requests_.end()) { |
| 1033 NOTREACHED() << "Trying to remove a request that's not here"; |
| 1034 return; |
| 1035 } |
| 1036 RemoveRequestFromMap(i); |
| 1037 } |
| 1038 |
| 1039 void ResourceDispatcherHost::MovePendingRequestToInterrupted( |
| 1040 int process_unique_id, int request_id) { |
| 1041 GlobalRequestID id(process_unique_id, request_id); |
| 1042 PendingRequestList::iterator iter = pending_requests_.find(id); |
| 1043 if (iter == pending_requests_.end()) |
| 1044 return; |
| 1045 |
| 1046 URLRequest* url_req = iter->second; |
| 1047 |
| 1048 ResourceDispatcherHostRequestInfo* info = InfoForRequest(url_req); |
| 1049 |
| 1050 info->set_was_interrupted(true); |
| 1051 |
| 1052 interrupted_requests_[id] = pending_requests_[id]; |
| 1053 pending_requests_.erase(iter); |
| 1054 |
| 1055 // If we have no more pending requests, then stop the load state monitor |
| 1056 if (pending_requests_.empty()) |
| 1057 update_load_states_timer_.Stop(); |
| 1058 } |
| 1059 |
| 1060 void ResourceDispatcherHost::MoveInterruptedRequestToPending( |
| 1061 int process_unique_id, int request_id) { |
| 1062 GlobalRequestID id(process_unique_id, request_id); |
| 1063 PendingRequestList::iterator iter = interrupted_requests_.find(id); |
| 1064 if (iter == interrupted_requests_.end()) |
| 1065 return; |
| 1066 |
| 1067 // Don't need to call info->set_was_interrupted(false), as we will have |
| 1068 // a new URLRequest when we resume downloading. If we clear it here, |
| 1069 // then the information won't be available to |
| 1070 // DownloadResourceHandler::OnResponseStarted(). |
| 1071 |
| 1072 pending_requests_[id] = interrupted_requests_[id]; |
| 1073 interrupted_requests_.erase(iter); |
| 1074 } |
| 1075 |
| 1076 void ResourceDispatcherHost::RemoveRequestFromMap( |
926 const PendingRequestList::iterator& iter) { | 1077 const PendingRequestList::iterator& iter) { |
927 ResourceDispatcherHostRequestInfo* info = InfoForRequest(iter->second); | 1078 ResourceDispatcherHostRequestInfo* info = InfoForRequest(iter->second); |
928 | 1079 |
929 // Remove the memory credit that we added when pushing the request onto | 1080 // Remove the memory credit that we added when pushing the request onto |
930 // the pending list. | 1081 // the pending list. |
931 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), | 1082 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), |
932 info->child_id()); | 1083 info->child_id()); |
933 | 1084 |
934 // Notify interested parties that the request object is going away. | 1085 // Notify interested parties that the request object is going away. |
935 if (info->login_handler()) | 1086 if (info->login_handler()) |
936 info->login_handler()->OnRequestCancelled(); | 1087 info->login_handler()->OnRequestCancelled(); |
937 if (info->ssl_client_auth_handler()) | 1088 if (info->ssl_client_auth_handler()) |
938 info->ssl_client_auth_handler()->OnRequestCancelled(); | 1089 info->ssl_client_auth_handler()->OnRequestCancelled(); |
939 resource_queue_.RemoveRequest(iter->first); | 1090 |
| 1091 GlobalRequestID id = iter->first; |
| 1092 resource_queue_.RemoveRequest(id); |
940 | 1093 |
941 delete iter->second; | 1094 delete iter->second; |
942 pending_requests_.erase(iter); | 1095 if (pending_requests_.find(id) != pending_requests_.end()) { |
| 1096 pending_requests_.erase(iter); |
943 | 1097 |
944 // If we have no more pending requests, then stop the load state monitor | 1098 // If we have no more pending requests, then stop the load state monitor |
945 if (pending_requests_.empty()) | 1099 if (pending_requests_.empty()) |
946 update_load_states_timer_.Stop(); | 1100 update_load_states_timer_.Stop(); |
| 1101 } |
| 1102 if (interrupted_requests_.find(id) != interrupted_requests_.end()) |
| 1103 interrupted_requests_.erase(iter); |
947 } | 1104 } |
948 | 1105 |
949 // URLRequest::Delegate ------------------------------------------------------- | 1106 // URLRequest::Delegate ------------------------------------------------------- |
950 | 1107 |
951 void ResourceDispatcherHost::OnReceivedRedirect(URLRequest* request, | 1108 void ResourceDispatcherHost::OnReceivedRedirect(URLRequest* request, |
952 const GURL& new_url, | 1109 const GURL& new_url, |
953 bool* defer_redirect) { | 1110 bool* defer_redirect) { |
954 RESOURCE_LOG("OnReceivedRedirect: " << request->url().spec()); | 1111 RESOURCE_LOG("OnReceivedRedirect: " << request->url().spec()); |
955 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); | 1112 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
956 | 1113 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 request->ssl_info().security_bits == 0) && | 1254 request->ssl_info().security_bits == 0) && |
1098 !request->ssl_info().connection_status); | 1255 !request->ssl_info().connection_status); |
1099 } | 1256 } |
1100 | 1257 |
1101 NotifyResponseStarted(request, info->child_id()); | 1258 NotifyResponseStarted(request, info->child_id()); |
1102 info->set_called_on_response_started(true); | 1259 info->set_called_on_response_started(true); |
1103 return info->resource_handler()->OnResponseStarted(info->request_id(), | 1260 return info->resource_handler()->OnResponseStarted(info->request_id(), |
1104 response.get()); | 1261 response.get()); |
1105 } | 1262 } |
1106 | 1263 |
1107 void ResourceDispatcherHost::CancelRequest(int child_id, | 1264 void ResourceDispatcherHost::CancelRequest(int process_unique_id, |
1108 int request_id, | 1265 int request_id, |
1109 bool from_renderer) { | 1266 bool from_renderer) { |
1110 PendingRequestList::iterator i = pending_requests_.find( | 1267 GlobalRequestID id(process_unique_id, request_id); |
1111 GlobalRequestID(child_id, request_id)); | 1268 PendingRequestList::iterator i = pending_requests_.find(id); |
1112 if (i == pending_requests_.end()) { | 1269 if (i == pending_requests_.end()) { |
1113 // We probably want to remove this warning eventually, but I wanted to be | 1270 i = interrupted_requests_.find(id); |
1114 // able to notice when this happens during initial development since it | 1271 if (i == interrupted_requests_.end()) { |
1115 // should be rare and may indicate a bug. | 1272 // We probably want to remove this warning eventually, but I wanted to be |
1116 DLOG(WARNING) << "Canceling a request that wasn't found"; | 1273 // able to notice when this happens during initial development since it |
1117 return; | 1274 // should be rare and may indicate a bug. |
| 1275 DLOG(WARNING) << "Canceling a request that wasn't found"; |
| 1276 return; |
| 1277 } |
1118 } | 1278 } |
1119 CancelRequestInternal(i->second, from_renderer); | 1279 CancelRequestInternal(i->second, from_renderer); |
1120 } | 1280 } |
1121 | 1281 |
1122 void ResourceDispatcherHost::CancelRequestInternal(URLRequest* request, | 1282 void ResourceDispatcherHost::CancelRequestInternal(URLRequest* request, |
1123 bool from_renderer) { | 1283 bool from_renderer) { |
1124 RESOURCE_LOG("CancelRequest: " << request->url().spec()); | 1284 RESOURCE_LOG("CancelRequest: " << request->url().spec()); |
1125 | 1285 |
1126 // WebKit will send us a cancel for downloads since it no longer handles them. | 1286 // WebKit will send us a cancel for downloads since it no longer handles them. |
1127 // In this case, ignore the cancel since we handle downloads in the browser. | 1287 // In this case, ignore the cancel since we handle downloads in the browser. |
(...skipping 12 matching lines...) Expand all Loading... |
1140 DCHECK(IsValidRequest(request)); | 1300 DCHECK(IsValidRequest(request)); |
1141 } | 1301 } |
1142 | 1302 |
1143 // Do not remove from the pending requests, as the request will still | 1303 // Do not remove from the pending requests, as the request will still |
1144 // call AllDataReceived, and may even have more data before it does | 1304 // call AllDataReceived, and may even have more data before it does |
1145 // that. | 1305 // that. |
1146 } | 1306 } |
1147 | 1307 |
1148 int ResourceDispatcherHost::IncrementOutstandingRequestsMemoryCost( | 1308 int ResourceDispatcherHost::IncrementOutstandingRequestsMemoryCost( |
1149 int cost, | 1309 int cost, |
1150 int child_id) { | 1310 int process_unique_id) { |
1151 // Retrieve the previous value (defaulting to 0 if not found). | 1311 // Retrieve the previous value (defaulting to 0 if not found). |
1152 OutstandingRequestsMemoryCostMap::iterator prev_entry = | 1312 OutstandingRequestsMemoryCostMap::iterator prev_entry = |
1153 outstanding_requests_memory_cost_map_.find(child_id); | 1313 outstanding_requests_memory_cost_map_.find(process_unique_id); |
1154 int new_cost = 0; | 1314 int new_cost = 0; |
1155 if (prev_entry != outstanding_requests_memory_cost_map_.end()) | 1315 if (prev_entry != outstanding_requests_memory_cost_map_.end()) |
1156 new_cost = prev_entry->second; | 1316 new_cost = prev_entry->second; |
1157 | 1317 |
1158 // Insert/update the total; delete entries when their value reaches 0. | 1318 // Insert/update the total; delete entries when their value reaches 0. |
1159 new_cost += cost; | 1319 new_cost += cost; |
1160 CHECK(new_cost >= 0); | 1320 CHECK(new_cost >= 0); |
1161 if (new_cost == 0) | 1321 if (new_cost == 0) |
1162 outstanding_requests_memory_cost_map_.erase(prev_entry); | 1322 outstanding_requests_memory_cost_map_.erase(prev_entry); |
1163 else | 1323 else |
1164 outstanding_requests_memory_cost_map_[child_id] = new_cost; | 1324 outstanding_requests_memory_cost_map_[process_unique_id] = new_cost; |
1165 | 1325 |
1166 return new_cost; | 1326 return new_cost; |
1167 } | 1327 } |
1168 | 1328 |
1169 // static | 1329 // static |
1170 int ResourceDispatcherHost::CalculateApproximateMemoryCost( | 1330 int ResourceDispatcherHost::CalculateApproximateMemoryCost( |
1171 URLRequest* request) { | 1331 URLRequest* request) { |
1172 // The following fields should be a minor size contribution (experimentally | 1332 // The following fields should be a minor size contribution (experimentally |
1173 // on the order of 100). However since they are variable length, it could | 1333 // on the order of 100). However since they are variable length, it could |
1174 // in theory be a sizeable contribution. | 1334 // in theory be a sizeable contribution. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 void ResourceDispatcherHost::ResumeRequest(const GlobalRequestID& request_id) { | 1445 void ResourceDispatcherHost::ResumeRequest(const GlobalRequestID& request_id) { |
1286 PendingRequestList::iterator i = pending_requests_.find(request_id); | 1446 PendingRequestList::iterator i = pending_requests_.find(request_id); |
1287 if (i == pending_requests_.end()) // The request may have been destroyed | 1447 if (i == pending_requests_.end()) // The request may have been destroyed |
1288 return; | 1448 return; |
1289 | 1449 |
1290 URLRequest* request = i->second; | 1450 URLRequest* request = i->second; |
1291 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); | 1451 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
1292 if (!info->is_paused()) | 1452 if (!info->is_paused()) |
1293 return; | 1453 return; |
1294 | 1454 |
1295 RESOURCE_LOG("Resuming: " << i->second->url().spec()); | 1455 RESOURCE_LOG("Resuming: " << request->url().spec()); |
1296 | 1456 |
1297 info->set_is_paused(false); | 1457 info->set_is_paused(false); |
1298 | 1458 |
1299 if (info->called_on_response_started()) { | 1459 if (info->called_on_response_started()) { |
1300 if (info->has_started_reading()) { | 1460 if (info->has_started_reading()) { |
1301 OnReadCompleted(i->second, info->paused_read_bytes()); | 1461 OnReadCompleted(request, info->paused_read_bytes()); |
1302 } else { | 1462 } else { |
1303 StartReading(request); | 1463 StartReading(request); |
1304 } | 1464 } |
1305 } else { | 1465 } else { |
1306 OnResponseStarted(i->second); | 1466 OnResponseStarted(request); |
1307 } | 1467 } |
1308 } | 1468 } |
1309 | 1469 |
| 1470 // static |
| 1471 void ResourceDispatcherHost::RestartDownload( |
| 1472 ResourceDispatcherHost* rdh, |
| 1473 const GlobalRequestID& request_id, |
| 1474 DownloadCreateInfo* info) { |
| 1475 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 1476 RESOURCE_LOG("Restarting: " << info->url.spec()); |
| 1477 |
| 1478 // Restart the request. |
| 1479 download_util::RestartDownloadUrl(rdh, |
| 1480 info->url, |
| 1481 info->referrer_url, |
| 1482 info->path, |
| 1483 info->received_bytes, |
| 1484 request_id.child_id, |
| 1485 info->render_view_id); |
| 1486 |
| 1487 // Clean up. |
| 1488 delete info; |
| 1489 } |
| 1490 |
1310 void ResourceDispatcherHost::StartReading(URLRequest* request) { | 1491 void ResourceDispatcherHost::StartReading(URLRequest* request) { |
1311 // Start reading. | 1492 // Start reading. |
1312 int bytes_read = 0; | 1493 int bytes_read = 0; |
1313 if (Read(request, &bytes_read)) { | 1494 if (Read(request, &bytes_read)) { |
1314 OnReadCompleted(request, bytes_read); | 1495 OnReadCompleted(request, bytes_read); |
1315 } else if (!request->status().is_io_pending()) { | 1496 } else if (!request->status().is_io_pending()) { |
1316 DCHECK(!InfoForRequest(request)->is_paused()); | 1497 DCHECK(!InfoForRequest(request)->is_paused()); |
1317 // If the error is not an IO pending, then we're done reading. | 1498 // If the error is not an IO pending, then we're done reading. |
1318 OnResponseCompleted(request); | 1499 OnResponseCompleted(request); |
1319 } | 1500 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1426 int cert_id = CertStore::GetSharedInstance()->StoreCert(ssl_info.cert, | 1607 int cert_id = CertStore::GetSharedInstance()->StoreCert(ssl_info.cert, |
1427 info->child_id()); | 1608 info->child_id()); |
1428 security_info = SSLManager::SerializeSecurityInfo( | 1609 security_info = SSLManager::SerializeSecurityInfo( |
1429 cert_id, ssl_info.cert_status, ssl_info.security_bits, | 1610 cert_id, ssl_info.cert_status, ssl_info.security_bits, |
1430 ssl_info.connection_status); | 1611 ssl_info.connection_status); |
1431 } | 1612 } |
1432 | 1613 |
1433 if (info->resource_handler()->OnResponseCompleted(info->request_id(), | 1614 if (info->resource_handler()->OnResponseCompleted(info->request_id(), |
1434 request->status(), | 1615 request->status(), |
1435 security_info)) { | 1616 security_info)) { |
| 1617 if ((request->status().status() == URLRequestStatus::FAILED) && |
| 1618 (request->status().os_error() < 0)) { |
| 1619 MovePendingRequestToInterrupted(info->child_id(), info->request_id()); |
| 1620 } |
| 1621 |
1436 NotifyResponseCompleted(request, info->child_id()); | 1622 NotifyResponseCompleted(request, info->child_id()); |
1437 | 1623 |
1438 // The request is complete so we can remove it. | 1624 // The request is complete so we can remove it. |
1439 RemovePendingRequest(info->child_id(), info->request_id()); | 1625 RemovePendingRequest(info->child_id(), info->request_id()); |
1440 } | 1626 } |
1441 // If the handler's OnResponseCompleted returns false, we are deferring the | 1627 // If the handler's OnResponseCompleted returns false, we are deferring the |
1442 // call until later. We will notify the world and clean up when we resume. | 1628 // call until later. We will notify the world and clean up when we resume. |
1443 } | 1629 } |
1444 | 1630 |
1445 // static | 1631 // static |
1446 ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest( | 1632 ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest( |
1447 URLRequest* request) { | 1633 URLRequest* request) { |
1448 // Avoid writing this function twice by casting the cosnt version. | 1634 // Avoid writing this function twice by casting the const version. |
1449 const URLRequest* const_request = request; | 1635 const URLRequest* const_request = request; |
1450 return const_cast<ResourceDispatcherHostRequestInfo*>( | 1636 return const_cast<ResourceDispatcherHostRequestInfo*>( |
1451 InfoForRequest(const_request)); | 1637 InfoForRequest(const_request)); |
1452 } | 1638 } |
1453 | 1639 |
1454 // static | 1640 // static |
1455 const ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest( | 1641 const ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest( |
1456 const URLRequest* request) { | 1642 const URLRequest* request) { |
1457 const ResourceDispatcherHostRequestInfo* info = | 1643 const ResourceDispatcherHostRequestInfo* info = |
1458 static_cast<const ResourceDispatcherHostRequestInfo*>( | 1644 static_cast<const ResourceDispatcherHostRequestInfo*>( |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 void ResourceDispatcherHost::RemoveObserver(Observer* obs) { | 1688 void ResourceDispatcherHost::RemoveObserver(Observer* obs) { |
1503 observer_list_.RemoveObserver(obs); | 1689 observer_list_.RemoveObserver(obs); |
1504 } | 1690 } |
1505 | 1691 |
1506 URLRequest* ResourceDispatcherHost::GetURLRequest( | 1692 URLRequest* ResourceDispatcherHost::GetURLRequest( |
1507 const GlobalRequestID& request_id) const { | 1693 const GlobalRequestID& request_id) const { |
1508 // This should be running in the IO loop. | 1694 // This should be running in the IO loop. |
1509 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | 1695 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
1510 | 1696 |
1511 PendingRequestList::const_iterator i = pending_requests_.find(request_id); | 1697 PendingRequestList::const_iterator i = pending_requests_.find(request_id); |
1512 if (i == pending_requests_.end()) | 1698 if (i == pending_requests_.end()) { |
1513 return NULL; | 1699 i = interrupted_requests_.find(request_id); |
| 1700 if (i == interrupted_requests_.end()) |
| 1701 return NULL; |
| 1702 } |
1514 | 1703 |
1515 return i->second; | 1704 return i->second; |
1516 } | 1705 } |
1517 | 1706 |
1518 static int GetCertID(URLRequest* request, int child_id) { | 1707 static int GetCertID(URLRequest* request, int process_unique_id) { |
1519 if (request->ssl_info().cert) { | 1708 if (request->ssl_info().cert) { |
1520 return CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, | 1709 return CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, |
1521 child_id); | 1710 process_unique_id); |
1522 } | 1711 } |
1523 // If there is no SSL info attached to this request, we must either be a non | 1712 // If there is no SSL info attached to this request, we must either be a non |
1524 // secure request, or the request has been canceled or failed (before the SSL | 1713 // secure request, or the request has been canceled or failed (before the SSL |
1525 // info was populated), or the response is an error (we have seen 403, 404, | 1714 // info was populated), or the response is an error (we have seen 403, 404, |
1526 // and 501) made up by the proxy. | 1715 // and 501) made up by the proxy. |
1527 DCHECK(!request->url().SchemeIsSecure() || | 1716 DCHECK(!request->url().SchemeIsSecure() || |
1528 (request->status().status() == URLRequestStatus::CANCELED) || | 1717 (request->status().status() == URLRequestStatus::CANCELED) || |
1529 (request->status().status() == URLRequestStatus::FAILED) || | 1718 (request->status().status() == URLRequestStatus::FAILED) || |
1530 ((request->response_headers()->response_code() >= 400) && | 1719 ((request->response_headers()->response_code() >= 400) && |
1531 (request->response_headers()->response_code() <= 599))); | 1720 (request->response_headers()->response_code() <= 599))); |
1532 return 0; | 1721 return 0; |
1533 } | 1722 } |
1534 | 1723 |
1535 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request, | 1724 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request, |
1536 int child_id) { | 1725 int process_unique_id) { |
1537 // Notify the observers on the IO thread. | 1726 // Notify the observers on the IO thread. |
1538 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request)); | 1727 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request)); |
1539 | 1728 |
1540 int render_process_id, render_view_id; | 1729 int render_process_id, render_view_id; |
1541 if (!RenderViewForRequest(request, &render_process_id, &render_view_id)) | 1730 if (!RenderViewForRequest(request, &render_process_id, &render_view_id)) |
1542 return; | 1731 return; |
1543 | 1732 |
1544 // Notify the observers on the UI thread. | 1733 // Notify the observers on the UI thread. |
1545 CallRenderViewHostResourceDelegate( | 1734 CallRenderViewHostResourceDelegate( |
1546 render_process_id, render_view_id, | 1735 render_process_id, render_view_id, |
1547 &RenderViewHostDelegate::Resource::DidStartReceivingResourceResponse, | 1736 &RenderViewHostDelegate::Resource::DidStartReceivingResourceResponse, |
1548 ResourceRequestDetails(request, GetCertID(request, child_id))); | 1737 ResourceRequestDetails(request, GetCertID(request, process_unique_id))); |
1549 } | 1738 } |
1550 | 1739 |
1551 void ResourceDispatcherHost::NotifyResponseCompleted(URLRequest* request, | 1740 void ResourceDispatcherHost::NotifyResponseCompleted(URLRequest* request, |
1552 int child_id) { | 1741 int process_unique_id) { |
1553 // Notify the observers on the IO thread. | 1742 // Notify the observers on the IO thread. |
1554 FOR_EACH_OBSERVER(Observer, observer_list_, | 1743 FOR_EACH_OBSERVER(Observer, observer_list_, |
1555 OnResponseCompleted(this, request)); | 1744 OnResponseCompleted(this, request)); |
1556 } | 1745 } |
1557 | 1746 |
1558 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request, | 1747 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request, |
1559 int child_id, | 1748 int process_unique_id, |
1560 const GURL& new_url) { | 1749 const GURL& new_url) { |
1561 // Notify the observers on the IO thread. | 1750 // Notify the observers on the IO thread. |
1562 FOR_EACH_OBSERVER(Observer, observer_list_, | 1751 FOR_EACH_OBSERVER(Observer, observer_list_, |
1563 OnReceivedRedirect(this, request, new_url)); | 1752 OnReceivedRedirect(this, request, new_url)); |
1564 | 1753 |
1565 int render_process_id, render_view_id; | 1754 int render_process_id, render_view_id; |
1566 if (!RenderViewForRequest(request, &render_process_id, &render_view_id)) | 1755 if (!RenderViewForRequest(request, &render_process_id, &render_view_id)) |
1567 return; | 1756 return; |
1568 | 1757 |
1569 // Notify the observers on the UI thread. | 1758 // Notify the observers on the UI thread. |
1570 CallRenderViewHostResourceDelegate( | 1759 CallRenderViewHostResourceDelegate( |
1571 render_process_id, render_view_id, | 1760 render_process_id, render_view_id, |
1572 &RenderViewHostDelegate::Resource::DidRedirectResource, | 1761 &RenderViewHostDelegate::Resource::DidRedirectResource, |
1573 ResourceRedirectDetails(request, GetCertID(request, child_id), new_url)); | 1762 ResourceRedirectDetails(request, |
| 1763 GetCertID(request, process_unique_id), |
| 1764 new_url)); |
1574 } | 1765 } |
1575 | 1766 |
1576 namespace { | 1767 namespace { |
1577 | 1768 |
1578 // This function attempts to return the "more interesting" load state of |a| | 1769 // This function attempts to return the "more interesting" load state of |a| |
1579 // and |b|. We don't have temporal information about these load states | 1770 // and |b|. We don't have temporal information about these load states |
1580 // (meaning we don't know when we transitioned into these states), so we just | 1771 // (meaning we don't know when we transitioned into these states), so we just |
1581 // rank them according to how "interesting" the states are. | 1772 // rank them according to how "interesting" the states are. |
1582 // | 1773 // |
1583 // We take advantage of the fact that the load states are an enumeration listed | 1774 // We take advantage of the fact that the load states are an enumeration listed |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 position, size); | 1914 position, size); |
1724 info->set_waiting_for_upload_progress_ack(true); | 1915 info->set_waiting_for_upload_progress_ack(true); |
1725 } | 1916 } |
1726 info->set_last_upload_ticks(TimeTicks::Now()); | 1917 info->set_last_upload_ticks(TimeTicks::Now()); |
1727 info->set_last_upload_position(position); | 1918 info->set_last_upload_position(position); |
1728 return true; | 1919 return true; |
1729 } | 1920 } |
1730 return false; | 1921 return false; |
1731 } | 1922 } |
1732 | 1923 |
1733 void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) { | 1924 void ResourceDispatcherHost::BlockRequestsForRoute(int process_unique_id, |
1734 std::pair<int, int> key(child_id, route_id); | 1925 int route_id) { |
| 1926 std::pair<int, int> key(process_unique_id, route_id); |
1735 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << | 1927 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << |
1736 "BlockRequestsForRoute called multiple time for the same RVH"; | 1928 "BlockRequestsForRoute called multiple time for the same RVH"; |
1737 blocked_requests_map_[key] = new BlockedRequestsList(); | 1929 blocked_requests_map_[key] = new BlockedRequestsList(); |
1738 } | 1930 } |
1739 | 1931 |
1740 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(int child_id, | 1932 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute( |
1741 int route_id) { | 1933 int process_unique_id, |
1742 ProcessBlockedRequestsForRoute(child_id, route_id, false); | 1934 int route_id) { |
| 1935 ProcessBlockedRequestsForRoute(process_unique_id, route_id, false); |
1743 } | 1936 } |
1744 | 1937 |
1745 void ResourceDispatcherHost::CancelBlockedRequestsForRoute(int child_id, | 1938 void ResourceDispatcherHost::CancelBlockedRequestsForRoute( |
1746 int route_id) { | 1939 int process_unique_id, |
1747 ProcessBlockedRequestsForRoute(child_id, route_id, true); | 1940 int route_id) { |
| 1941 ProcessBlockedRequestsForRoute(process_unique_id, route_id, true); |
1748 } | 1942 } |
1749 | 1943 |
1750 void ResourceDispatcherHost::ProcessBlockedRequestsForRoute( | 1944 void ResourceDispatcherHost::ProcessBlockedRequestsForRoute( |
1751 int child_id, | 1945 int process_unique_id, |
1752 int route_id, | 1946 int route_id, |
1753 bool cancel_requests) { | 1947 bool cancel_requests) { |
1754 BlockedRequestMap::iterator iter = blocked_requests_map_.find( | 1948 BlockedRequestMap::iterator iter = blocked_requests_map_.find( |
1755 std::pair<int, int>(child_id, route_id)); | 1949 std::pair<int, int>(process_unique_id, route_id)); |
1756 if (iter == blocked_requests_map_.end()) { | 1950 if (iter == blocked_requests_map_.end()) { |
1757 // It's possible to reach here if the renderer crashed while an interstitial | 1951 // It's possible to reach here if the renderer crashed while an interstitial |
1758 // page was showing. | 1952 // page was showing. |
1759 return; | 1953 return; |
1760 } | 1954 } |
1761 | 1955 |
1762 BlockedRequestsList* requests = iter->second; | 1956 BlockedRequestsList* requests = iter->second; |
1763 | 1957 |
1764 // Removing the vector from the map unblocks any subsequent requests. | 1958 // Removing the vector from the map unblocks any subsequent requests. |
1765 blocked_requests_map_.erase(iter); | 1959 blocked_requests_map_.erase(iter); |
(...skipping 12 matching lines...) Expand all Loading... |
1778 BeginRequestInternal(request); | 1972 BeginRequestInternal(request); |
1779 } | 1973 } |
1780 | 1974 |
1781 delete requests; | 1975 delete requests; |
1782 } | 1976 } |
1783 | 1977 |
1784 bool ResourceDispatcherHost::IsValidRequest(URLRequest* request) { | 1978 bool ResourceDispatcherHost::IsValidRequest(URLRequest* request) { |
1785 if (!request) | 1979 if (!request) |
1786 return false; | 1980 return false; |
1787 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); | 1981 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
1788 return pending_requests_.find( | 1982 GlobalRequestID id(info->child_id(), info->request_id()); |
1789 GlobalRequestID(info->child_id(), info->request_id())) != | 1983 return (pending_requests_.find(id) != pending_requests_.end()) || |
1790 pending_requests_.end(); | 1984 (interrupted_requests_.find(id) != interrupted_requests_.end()); |
| 1985 } |
| 1986 |
| 1987 bool ResourceDispatcherHost::IsInterruptedRequest(URLRequest* request) { |
| 1988 if (!request) |
| 1989 return false; |
| 1990 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
| 1991 GlobalRequestID id(info->child_id(), info->request_id()); |
| 1992 return interrupted_requests_.find(id) != interrupted_requests_.end(); |
1791 } | 1993 } |
1792 | 1994 |
1793 // static | 1995 // static |
1794 bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( | 1996 bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( |
1795 const IPC::Message& message) { | 1997 const IPC::Message& message) { |
1796 switch (message.type()) { | 1998 switch (message.type()) { |
1797 case ViewHostMsg_RequestResource::ID: | 1999 case ViewHostMsg_RequestResource::ID: |
1798 case ViewHostMsg_CancelRequest::ID: | 2000 case ViewHostMsg_CancelRequest::ID: |
1799 case ViewHostMsg_FollowRedirect::ID: | 2001 case ViewHostMsg_FollowRedirect::ID: |
1800 case ViewHostMsg_ClosePage_ACK::ID: | 2002 case ViewHostMsg_ClosePage_ACK::ID: |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 return is_prefetch_enabled_; | 2083 return is_prefetch_enabled_; |
1882 } | 2084 } |
1883 | 2085 |
1884 // static | 2086 // static |
1885 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { | 2087 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { |
1886 is_prefetch_enabled_ = value; | 2088 is_prefetch_enabled_ = value; |
1887 } | 2089 } |
1888 | 2090 |
1889 // static | 2091 // static |
1890 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; | 2092 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; |
OLD | NEW |