| 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 // 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 "content/browser/renderer_host/resource_dispatcher_host.h" | 7 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/shared_memory.h" | 18 #include "base/shared_memory.h" |
| 19 #include "base/stl_util-inl.h" | 19 #include "base/stl_util-inl.h" |
| 20 #include "base/time.h" | 20 #include "base/time.h" |
| 21 #include "chrome/browser/download/download_file_manager.h" | 21 #include "chrome/browser/download/download_file_manager.h" |
| 22 #include "chrome/browser/download/download_manager.h" | 22 #include "chrome/browser/download/download_manager.h" |
| 23 #include "chrome/browser/download/download_request_limiter.h" | 23 #include "chrome/browser/download/download_request_limiter.h" |
| 24 #include "chrome/browser/download/download_util.h" | 24 #include "chrome/browser/download/download_util.h" |
| 25 #include "chrome/browser/download/save_file_manager.h" | 25 #include "chrome/browser/download/save_file_manager.h" |
| 26 #include "chrome/browser/external_protocol_handler.h" | 26 #include "chrome/browser/external_protocol_handler.h" |
| 27 #include "chrome/browser/net/url_request_tracking.h" | 27 #include "chrome/browser/net/url_request_tracking.h" |
| 28 #include "chrome/browser/prerender/prerender_manager.h" | |
| 29 #include "chrome/browser/prerender/prerender_tracker.h" | |
| 30 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 31 #include "chrome/browser/renderer_host/download_resource_handler.h" | 29 #include "chrome/browser/renderer_host/download_resource_handler.h" |
| 32 #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" | 30 #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" |
| 33 #include "chrome/browser/renderer_host/save_file_resource_handler.h" | 31 #include "chrome/browser/renderer_host/save_file_resource_handler.h" |
| 34 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 32 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| 35 #include "chrome/browser/ssl/ssl_client_auth_handler.h" | 33 #include "chrome/browser/ssl/ssl_client_auth_handler.h" |
| 36 #include "chrome/browser/ssl/ssl_manager.h" | 34 #include "chrome/browser/ssl/ssl_manager.h" |
| 37 #include "chrome/browser/ui/login/login_prompt.h" | 35 #include "chrome/browser/ui/login/login_prompt.h" |
| 38 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
| 39 #include "content/browser/appcache/chrome_appcache_service.h" | 37 #include "content/browser/appcache/chrome_appcache_service.h" |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 download_request_limiter_(new DownloadRequestLimiter()), | 272 download_request_limiter_(new DownloadRequestLimiter()), |
| 275 ALLOW_THIS_IN_INITIALIZER_LIST( | 273 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 276 save_file_manager_(new SaveFileManager(this))), | 274 save_file_manager_(new SaveFileManager(this))), |
| 277 safe_browsing_(SafeBrowsingService::CreateSafeBrowsingService()), | 275 safe_browsing_(SafeBrowsingService::CreateSafeBrowsingService()), |
| 278 webkit_thread_(new WebKitThread), | 276 webkit_thread_(new WebKitThread), |
| 279 request_id_(-1), | 277 request_id_(-1), |
| 280 ALLOW_THIS_IN_INITIALIZER_LIST(method_runner_(this)), | 278 ALLOW_THIS_IN_INITIALIZER_LIST(method_runner_(this)), |
| 281 is_shutdown_(false), | 279 is_shutdown_(false), |
| 282 max_outstanding_requests_cost_per_process_( | 280 max_outstanding_requests_cost_per_process_( |
| 283 kMaxOutstandingRequestsCostPerProcess), | 281 kMaxOutstandingRequestsCostPerProcess), |
| 284 filter_(NULL) { | 282 filter_(NULL), |
| 283 observer_(NULL) { |
| 285 resource_queue_.Initialize(resource_queue_delegates); | 284 resource_queue_.Initialize(resource_queue_delegates); |
| 286 } | 285 } |
| 287 | 286 |
| 288 ResourceDispatcherHost::~ResourceDispatcherHost() { | 287 ResourceDispatcherHost::~ResourceDispatcherHost() { |
| 289 AsyncResourceHandler::GlobalCleanup(); | 288 AsyncResourceHandler::GlobalCleanup(); |
| 290 STLDeleteValues(&pending_requests_); | 289 STLDeleteValues(&pending_requests_); |
| 291 } | 290 } |
| 292 | 291 |
| 293 void ResourceDispatcherHost::Initialize() { | 292 void ResourceDispatcherHost::Initialize() { |
| 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); | 425 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); |
| 427 } | 426 } |
| 428 | 427 |
| 429 if (is_shutdown_ || | 428 if (is_shutdown_ || |
| 430 !ShouldServiceRequest(process_type, child_id, request_data)) { | 429 !ShouldServiceRequest(process_type, child_id, request_data)) { |
| 431 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); | 430 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); |
| 432 return; | 431 return; |
| 433 } | 432 } |
| 434 | 433 |
| 435 const GURL referrer = MaybeStripReferrer(request_data.referrer); | 434 const GURL referrer = MaybeStripReferrer(request_data.referrer); |
| 436 const bool is_prerendering = | |
| 437 prerender::PrerenderTracker::GetInstance()->IsPrerenderingOnIOThread( | |
| 438 child_id, route_id); | |
| 439 | 435 |
| 440 // Handle a PREFETCH resource type. If prefetch is disabled, squelch the | 436 // Allow the observer to block/handle the request. |
| 441 // request. If prerendering is enabled, trigger a prerender for the URL | 437 if (observer_ && !observer_->ShouldBeginRequest(child_id, route_id, |
| 442 // and abort the request, to prevent double-gets. Otherwise, do a normal | 438 request_data, |
| 443 // prefetch. | 439 resource_context, |
| 444 if (request_data.resource_type == ResourceType::PREFETCH) { | 440 referrer)) { |
| 445 // All PREFETCH requests should be GETs, but be defensive about it. | 441 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); |
| 446 if (request_data.method != "GET") { | 442 return; |
| 447 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); | |
| 448 return; | |
| 449 } | |
| 450 if (!ResourceDispatcherHost::is_prefetch_enabled()) { | |
| 451 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); | |
| 452 return; | |
| 453 } | |
| 454 if (prerender::PrerenderManager::IsPrerenderingPossible()) { | |
| 455 BrowserThread::PostTask( | |
| 456 BrowserThread::UI, FROM_HERE, | |
| 457 NewRunnableFunction(prerender::HandlePrefetchTag, | |
| 458 resource_context.prerender_manager(), | |
| 459 child_id, | |
| 460 route_id, | |
| 461 request_data.url, | |
| 462 referrer, | |
| 463 is_prerendering)); | |
| 464 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); | |
| 465 return; | |
| 466 } | |
| 467 // Otherwise, treat like a normal request, and fall-through. | |
| 468 } | |
| 469 | |
| 470 // Abort any prerenders that spawn requests that use invalid HTTP methods. | |
| 471 if (is_prerendering && | |
| 472 !prerender::PrerenderManager::IsValidHttpMethod(request_data.method)) { | |
| 473 if (prerender::PrerenderTracker::GetInstance()->TryCancelOnIOThread( | |
| 474 child_id, route_id, prerender::FINAL_STATUS_INVALID_HTTP_METHOD)) { | |
| 475 AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); | |
| 476 return; | |
| 477 } | |
| 478 } | 443 } |
| 479 | 444 |
| 480 // Construct the event handler. | 445 // Construct the event handler. |
| 481 scoped_refptr<ResourceHandler> handler; | 446 scoped_refptr<ResourceHandler> handler; |
| 482 if (sync_result) { | 447 if (sync_result) { |
| 483 handler = new SyncResourceHandler( | 448 handler = new SyncResourceHandler( |
| 484 filter_, request_data.url, sync_result, this); | 449 filter_, request_data.url, sync_result, this); |
| 485 } else { | 450 } else { |
| 486 handler = new AsyncResourceHandler( | 451 handler = new AsyncResourceHandler( |
| 487 filter_, route_id, request_data.url, resource_context.host_zoom_map(), | 452 filter_, route_id, request_data.url, resource_context.host_zoom_map(), |
| (...skipping 29 matching lines...) Expand all Loading... |
| 517 if (request_data.resource_type == ResourceType::MAIN_FRAME) { | 482 if (request_data.resource_type == ResourceType::MAIN_FRAME) { |
| 518 load_flags |= net::LOAD_MAIN_FRAME; | 483 load_flags |= net::LOAD_MAIN_FRAME; |
| 519 } else if (request_data.resource_type == ResourceType::SUB_FRAME) { | 484 } else if (request_data.resource_type == ResourceType::SUB_FRAME) { |
| 520 load_flags |= net::LOAD_SUB_FRAME; | 485 load_flags |= net::LOAD_SUB_FRAME; |
| 521 } else if (request_data.resource_type == ResourceType::PREFETCH) { | 486 } else if (request_data.resource_type == ResourceType::PREFETCH) { |
| 522 load_flags |= (net::LOAD_PREFETCH | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); | 487 load_flags |= (net::LOAD_PREFETCH | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); |
| 523 } else if (request_data.resource_type == ResourceType::FAVICON) { | 488 } else if (request_data.resource_type == ResourceType::FAVICON) { |
| 524 load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; | 489 load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; |
| 525 } | 490 } |
| 526 | 491 |
| 527 if (is_prerendering) | |
| 528 load_flags |= net::LOAD_PRERENDER; | |
| 529 | |
| 530 if (sync_result) | 492 if (sync_result) |
| 531 load_flags |= net::LOAD_IGNORE_LIMITS; | 493 load_flags |= net::LOAD_IGNORE_LIMITS; |
| 532 | 494 |
| 495 // Allow the observer to change the load flags. |
| 496 if (observer_) |
| 497 observer_->MutateLoadFlags(child_id, route_id, &load_flags); |
| 498 |
| 533 // Raw headers are sensitive, as they inclide Cookie/Set-Cookie, so only | 499 // Raw headers are sensitive, as they inclide Cookie/Set-Cookie, so only |
| 534 // allow requesting them if requestor has ReadRawCookies permission. | 500 // allow requesting them if requestor has ReadRawCookies permission. |
| 535 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) | 501 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) |
| 536 && !ChildProcessSecurityPolicy::GetInstance()-> | 502 && !ChildProcessSecurityPolicy::GetInstance()-> |
| 537 CanReadRawCookies(child_id)) { | 503 CanReadRawCookies(child_id)) { |
| 538 VLOG(1) << "Denied unathorized request for raw headers"; | 504 VLOG(1) << "Denied unathorized request for raw headers"; |
| 539 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; | 505 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; |
| 540 } | 506 } |
| 541 | 507 |
| 542 request->set_load_flags(load_flags); | 508 request->set_load_flags(load_flags); |
| (...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2027 case ResourceType::PREFETCH: | 1993 case ResourceType::PREFETCH: |
| 2028 return net::IDLE; | 1994 return net::IDLE; |
| 2029 | 1995 |
| 2030 default: | 1996 default: |
| 2031 // When new resource types are added, their priority must be considered. | 1997 // When new resource types are added, their priority must be considered. |
| 2032 NOTREACHED(); | 1998 NOTREACHED(); |
| 2033 return net::LOW; | 1999 return net::LOW; |
| 2034 } | 2000 } |
| 2035 } | 2001 } |
| 2036 | 2002 |
| 2037 | |
| 2038 // static | 2003 // static |
| 2039 bool ResourceDispatcherHost::is_prefetch_enabled() { | 2004 bool ResourceDispatcherHost::is_prefetch_enabled() { |
| 2040 return is_prefetch_enabled_; | 2005 return is_prefetch_enabled_; |
| 2041 } | 2006 } |
| 2042 | 2007 |
| 2043 // static | 2008 // static |
| 2044 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { | 2009 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { |
| 2045 is_prefetch_enabled_ = value; | 2010 is_prefetch_enabled_ = value; |
| 2046 } | 2011 } |
| 2047 | 2012 |
| 2048 // static | 2013 // static |
| 2049 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; | 2014 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; |
| OLD | NEW |