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