| 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 |