OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "chrome/browser/external_protocol_handler.h" | 23 #include "chrome/browser/external_protocol_handler.h" |
24 #include "chrome/browser/in_process_webkit/webkit_thread.h" | 24 #include "chrome/browser/in_process_webkit/webkit_thread.h" |
25 #include "chrome/browser/plugin_service.h" | 25 #include "chrome/browser/plugin_service.h" |
26 #include "chrome/browser/privacy_blacklist/blacklist.h" | 26 #include "chrome/browser/privacy_blacklist/blacklist.h" |
27 #include "chrome/browser/profile.h" | 27 #include "chrome/browser/profile.h" |
28 #include "chrome/browser/renderer_host/async_resource_handler.h" | 28 #include "chrome/browser/renderer_host/async_resource_handler.h" |
29 #include "chrome/browser/renderer_host/buffered_resource_handler.h" | 29 #include "chrome/browser/renderer_host/buffered_resource_handler.h" |
30 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" | 30 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" |
31 #include "chrome/browser/renderer_host/download_resource_handler.h" | 31 #include "chrome/browser/renderer_host/download_resource_handler.h" |
32 #include "chrome/browser/renderer_host/render_view_host.h" | 32 #include "chrome/browser/renderer_host/render_view_host.h" |
| 33 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
33 #include "chrome/browser/renderer_host/resource_request_details.h" | 34 #include "chrome/browser/renderer_host/resource_request_details.h" |
34 #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" | 35 #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" |
35 #include "chrome/browser/renderer_host/save_file_resource_handler.h" | 36 #include "chrome/browser/renderer_host/save_file_resource_handler.h" |
36 #include "chrome/browser/renderer_host/sync_resource_handler.h" | 37 #include "chrome/browser/renderer_host/sync_resource_handler.h" |
37 #include "chrome/browser/ssl/ssl_client_auth_handler.h" | 38 #include "chrome/browser/ssl/ssl_client_auth_handler.h" |
| 39 #include "chrome/browser/ssl/ssl_manager.h" |
38 #include "chrome/browser/tab_contents/tab_util.h" | 40 #include "chrome/browser/tab_contents/tab_util.h" |
39 #include "chrome/browser/tab_contents/tab_contents.h" | |
40 #include "chrome/common/chrome_switches.h" | 41 #include "chrome/common/chrome_switches.h" |
41 #include "chrome/common/notification_service.h" | 42 #include "chrome/common/notification_service.h" |
42 #include "chrome/common/render_messages.h" | 43 #include "chrome/common/render_messages.h" |
43 #include "net/base/auth.h" | 44 #include "net/base/auth.h" |
44 #include "net/base/cert_status_flags.h" | 45 #include "net/base/cert_status_flags.h" |
45 #include "net/base/load_flags.h" | 46 #include "net/base/load_flags.h" |
46 #include "net/base/mime_util.h" | 47 #include "net/base/mime_util.h" |
47 #include "net/base/net_errors.h" | 48 #include "net/base/net_errors.h" |
48 #include "net/base/ssl_cert_request_info.h" | 49 #include "net/base/ssl_cert_request_info.h" |
49 #include "net/url_request/url_request.h" | 50 #include "net/url_request/url_request.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 102 |
102 // Maximum number of pending data messages sent to the renderer at any | 103 // Maximum number of pending data messages sent to the renderer at any |
103 // given time for a given request. | 104 // given time for a given request. |
104 const int kMaxPendingDataMessages = 20; | 105 const int kMaxPendingDataMessages = 20; |
105 | 106 |
106 // Maximum byte "cost" of all the outstanding requests for a renderer. | 107 // Maximum byte "cost" of all the outstanding requests for a renderer. |
107 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. | 108 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. |
108 // This bound is 25MB, which allows for around 6000 outstanding requests. | 109 // This bound is 25MB, which allows for around 6000 outstanding requests. |
109 const int kMaxOutstandingRequestsCostPerProcess = 26214400; | 110 const int kMaxOutstandingRequestsCostPerProcess = 26214400; |
110 | 111 |
| 112 // A NotificationTask proxies a resource dispatcher notification from the IO |
| 113 // thread to the RenderViewHostDelegate on the UI thread. It should be |
| 114 // constructed on the IO thread and run in the UI thread. |
| 115 class NotificationTask : public Task { |
| 116 public: |
| 117 // Supply the originating URLRequest, a function on RenderViewHostDelegate |
| 118 // to call, and the details to use as the parameter to the given function. |
| 119 // |
| 120 // This object will take ownership of the details pointer, which must be |
| 121 // allocated on the heap. |
| 122 NotificationTask( |
| 123 URLRequest* request, |
| 124 void (RenderViewHostDelegate::* function)(ResourceRequestDetails*), |
| 125 ResourceRequestDetails* details) |
| 126 : function_(function), |
| 127 details_(details) { |
| 128 if (!ResourceDispatcherHost::RenderViewForRequest(request, |
| 129 &render_process_host_id_, |
| 130 &render_view_host_id_)) |
| 131 NOTREACHED(); |
| 132 } |
| 133 |
| 134 virtual void Run() { |
| 135 RenderViewHost* rvh = RenderViewHost::FromID(render_process_host_id_, |
| 136 render_view_host_id_); |
| 137 if (rvh) |
| 138 (rvh->delegate()->*function_)(details_.get()); |
| 139 } |
| 140 |
| 141 private: |
| 142 int render_process_host_id_; |
| 143 int render_view_host_id_; |
| 144 |
| 145 // The function to call on RenderViewHostDelegate on the UI thread. |
| 146 void (RenderViewHostDelegate::* function_)(ResourceRequestDetails*); |
| 147 |
| 148 // The details for the notification. |
| 149 scoped_ptr<ResourceRequestDetails> details_; |
| 150 |
| 151 DISALLOW_COPY_AND_ASSIGN(NotificationTask); |
| 152 }; |
| 153 |
111 // Consults the RendererSecurity policy to determine whether the | 154 // Consults the RendererSecurity policy to determine whether the |
112 // ResourceDispatcherHost should service this request. A request might be | 155 // ResourceDispatcherHost should service this request. A request might be |
113 // disallowed if the renderer is not authorized to restrive the request URL or | 156 // disallowed if the renderer is not authorized to restrive the request URL or |
114 // if the renderer is attempting to upload an unauthorized file. | 157 // if the renderer is attempting to upload an unauthorized file. |
115 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, | 158 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, |
116 int process_id, | 159 int process_id, |
117 const ViewHostMsg_Resource_Request& request_data) { | 160 const ViewHostMsg_Resource_Request& request_data) { |
118 if (process_type == ChildProcessInfo::PLUGIN_PROCESS) | 161 if (process_type == ChildProcessInfo::PLUGIN_PROCESS) |
119 return true; | 162 return true; |
120 | 163 |
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 // unit_tests. | 1361 // unit_tests. |
1319 DCHECK(MessageLoop::current() == io_loop_ && io_loop_); | 1362 DCHECK(MessageLoop::current() == io_loop_ && io_loop_); |
1320 | 1363 |
1321 PendingRequestList::const_iterator i = pending_requests_.find(request_id); | 1364 PendingRequestList::const_iterator i = pending_requests_.find(request_id); |
1322 if (i == pending_requests_.end()) | 1365 if (i == pending_requests_.end()) |
1323 return NULL; | 1366 return NULL; |
1324 | 1367 |
1325 return i->second; | 1368 return i->second; |
1326 } | 1369 } |
1327 | 1370 |
1328 // A NotificationTask proxies a resource dispatcher notification from the IO | |
1329 // thread to the UI thread. It should be constructed on the IO thread and run | |
1330 // in the UI thread. Takes ownership of |details|. | |
1331 class NotificationTask : public Task { | |
1332 public: | |
1333 NotificationTask(NotificationType type, | |
1334 URLRequest* request, | |
1335 ResourceRequestDetails* details) | |
1336 : type_(type), | |
1337 details_(details) { | |
1338 if (!ResourceDispatcherHost::RenderViewForRequest(request, | |
1339 &process_id_, | |
1340 &tab_contents_id_)) | |
1341 NOTREACHED(); | |
1342 } | |
1343 | |
1344 void Run() { | |
1345 // Find the tab associated with this request. | |
1346 TabContents* tab_contents = | |
1347 tab_util::GetTabContentsByID(process_id_, tab_contents_id_); | |
1348 | |
1349 if (tab_contents) { | |
1350 // Issue the notification. | |
1351 NotificationService::current()->Notify( | |
1352 type_, | |
1353 Source<NavigationController>(&tab_contents->controller()), | |
1354 Details<ResourceRequestDetails>(details_.get())); | |
1355 } | |
1356 } | |
1357 | |
1358 private: | |
1359 // These IDs let us find the correct tab on the UI thread. | |
1360 int process_id_; | |
1361 int tab_contents_id_; | |
1362 | |
1363 // The type and details of the notification. | |
1364 NotificationType type_; | |
1365 scoped_ptr<ResourceRequestDetails> details_; | |
1366 }; | |
1367 | |
1368 static int GetCertID(URLRequest* request, int process_id) { | 1371 static int GetCertID(URLRequest* request, int process_id) { |
1369 if (request->ssl_info().cert) { | 1372 if (request->ssl_info().cert) { |
1370 return CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, | 1373 return CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, |
1371 process_id); | 1374 process_id); |
1372 } | 1375 } |
1373 // If there is no SSL info attached to this request, we must either be a non | 1376 // If there is no SSL info attached to this request, we must either be a non |
1374 // secure request, or the request has been canceled or failed (before the SSL | 1377 // secure request, or the request has been canceled or failed (before the SSL |
1375 // info was populated), or the response is an error (we have seen 403, 404, | 1378 // info was populated), or the response is an error (we have seen 403, 404, |
1376 // and 501) made up by the proxy. | 1379 // and 501) made up by the proxy. |
1377 DCHECK(!request->url().SchemeIsSecure() || | 1380 DCHECK(!request->url().SchemeIsSecure() || |
1378 (request->status().status() == URLRequestStatus::CANCELED) || | 1381 (request->status().status() == URLRequestStatus::CANCELED) || |
1379 (request->status().status() == URLRequestStatus::FAILED) || | 1382 (request->status().status() == URLRequestStatus::FAILED) || |
1380 ((request->response_headers()->response_code() >= 400) && | 1383 ((request->response_headers()->response_code() >= 400) && |
1381 (request->response_headers()->response_code() <= 599))); | 1384 (request->response_headers()->response_code() <= 599))); |
1382 return 0; | 1385 return 0; |
1383 } | 1386 } |
1384 | 1387 |
1385 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request, | 1388 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request, |
1386 int process_id) { | 1389 int process_id) { |
1387 // Notify the observers on the IO thread. | 1390 // Notify the observers on the IO thread. |
1388 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request)); | 1391 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request)); |
1389 | 1392 |
1390 // Notify the observers on the UI thread. | 1393 // Notify the observers on the UI thread. |
1391 ui_loop_->PostTask(FROM_HERE, | 1394 ui_loop_->PostTask(FROM_HERE, new NotificationTask(request, |
1392 new NotificationTask(NotificationType::RESOURCE_RESPONSE_STARTED, request, | 1395 &RenderViewHostDelegate::DidStartReceivingResourceResponse, |
1393 new ResourceRequestDetails(request, | 1396 new ResourceRequestDetails(request, |
1394 GetCertID(request, process_id)))); | 1397 GetCertID(request, process_id)))); |
1395 } | 1398 } |
1396 | 1399 |
1397 void ResourceDispatcherHost::NotifyResponseCompleted( | 1400 void ResourceDispatcherHost::NotifyResponseCompleted( |
1398 URLRequest* request, | 1401 URLRequest* request, |
1399 int process_id) { | 1402 int process_id) { |
1400 // Notify the observers on the IO thread. | 1403 // Notify the observers on the IO thread. |
1401 FOR_EACH_OBSERVER(Observer, observer_list_, | 1404 FOR_EACH_OBSERVER(Observer, observer_list_, |
1402 OnResponseCompleted(this, request)); | 1405 OnResponseCompleted(this, request)); |
1403 | |
1404 // Notify the observers on the UI thread. | |
1405 ui_loop_->PostTask(FROM_HERE, | |
1406 new NotificationTask(NotificationType::RESOURCE_RESPONSE_COMPLETED, | |
1407 request, | |
1408 new ResourceRequestDetails(request, | |
1409 GetCertID(request, process_id)))); | |
1410 } | 1406 } |
1411 | 1407 |
1412 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request, | 1408 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request, |
1413 int process_id, | 1409 int process_id, |
1414 const GURL& new_url) { | 1410 const GURL& new_url) { |
1415 // Notify the observers on the IO thread. | 1411 // Notify the observers on the IO thread. |
1416 FOR_EACH_OBSERVER(Observer, observer_list_, | 1412 FOR_EACH_OBSERVER(Observer, observer_list_, |
1417 OnReceivedRedirect(this, request, new_url)); | 1413 OnReceivedRedirect(this, request, new_url)); |
1418 | 1414 |
1419 int cert_id = GetCertID(request, process_id); | 1415 int cert_id = GetCertID(request, process_id); |
1420 | 1416 |
1421 // Notify the observers on the UI thread. | 1417 // Notify the observers on the UI thread. |
1422 ui_loop_->PostTask(FROM_HERE, | 1418 ui_loop_->PostTask(FROM_HERE, |
1423 new NotificationTask(NotificationType::RESOURCE_RECEIVED_REDIRECT, | 1419 new NotificationTask(request, |
1424 request, | 1420 &RenderViewHostDelegate::DidRedirectResource, |
1425 new ResourceRedirectDetails(request, | 1421 new ResourceRedirectDetails(request, |
1426 cert_id, | 1422 cert_id, |
1427 new_url))); | 1423 new_url))); |
1428 } | 1424 } |
1429 | 1425 |
1430 namespace { | 1426 namespace { |
1431 | 1427 |
1432 // This function attempts to return the "more interesting" load state of |a| | 1428 // This function attempts to return the "more interesting" load state of |a| |
1433 // and |b|. We don't have temporal information about these load states | 1429 // and |b|. We don't have temporal information about these load states |
1434 // (meaning we don't know when we transitioned into these states), so we just | 1430 // (meaning we don't know when we transitioned into these states), so we just |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1614 case ViewHostMsg_UploadProgress_ACK::ID: | 1610 case ViewHostMsg_UploadProgress_ACK::ID: |
1615 case ViewHostMsg_SyncLoad::ID: | 1611 case ViewHostMsg_SyncLoad::ID: |
1616 return true; | 1612 return true; |
1617 | 1613 |
1618 default: | 1614 default: |
1619 break; | 1615 break; |
1620 } | 1616 } |
1621 | 1617 |
1622 return false; | 1618 return false; |
1623 } | 1619 } |
OLD | NEW |