| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/loader/resource_dispatcher_host_impl.h" | 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 8 | 8 |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 | 10 |
| (...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 } else { | 1193 } else { |
| 1194 handler->CompleteCrossSiteTransfer( | 1194 handler->CompleteCrossSiteTransfer( |
| 1195 child_id, request_data.service_worker_provider_id); | 1195 child_id, request_data.service_worker_provider_id); |
| 1196 } | 1196 } |
| 1197 } | 1197 } |
| 1198 } | 1198 } |
| 1199 | 1199 |
| 1200 void ResourceDispatcherHostImpl::CompleteTransfer( | 1200 void ResourceDispatcherHostImpl::CompleteTransfer( |
| 1201 int request_id, | 1201 int request_id, |
| 1202 const ResourceRequest& request_data, | 1202 const ResourceRequest& request_data, |
| 1203 int route_id) { | 1203 int route_id, |
| 1204 mojom::URLLoaderAssociatedRequest mojo_request, |
| 1205 mojom::URLLoaderClientAssociatedPtr url_loader_client) { |
| 1204 // Caller should ensure that |request_data| is associated with a transfer. | 1206 // Caller should ensure that |request_data| is associated with a transfer. |
| 1205 DCHECK(request_data.transferred_request_child_id != -1 || | 1207 DCHECK(request_data.transferred_request_child_id != -1 || |
| 1206 request_data.transferred_request_request_id != -1); | 1208 request_data.transferred_request_request_id != -1); |
| 1207 | 1209 |
| 1208 bool is_navigational_request = | 1210 bool is_navigational_request = |
| 1209 request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME || | 1211 request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME || |
| 1210 request_data.resource_type == RESOURCE_TYPE_SUB_FRAME; | 1212 request_data.resource_type == RESOURCE_TYPE_SUB_FRAME; |
| 1211 if (!is_navigational_request) { | 1213 if (!is_navigational_request) { |
| 1212 // Transfers apply only to navigational requests - the renderer seems to | 1214 // Transfers apply only to navigational requests - the renderer seems to |
| 1213 // have sent bogus IPC data. | 1215 // have sent bogus IPC data. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1238 base::debug::Alias(pending_loader); | 1240 base::debug::Alias(pending_loader); |
| 1239 bad_message::ReceivedBadMessage(filter_, | 1241 bad_message::ReceivedBadMessage(filter_, |
| 1240 bad_message::RDH_REQUEST_NOT_TRANSFERRING); | 1242 bad_message::RDH_REQUEST_NOT_TRANSFERRING); |
| 1241 return; | 1243 return; |
| 1242 } | 1244 } |
| 1243 | 1245 |
| 1244 // If the request is transferring to a new process, we can update our | 1246 // If the request is transferring to a new process, we can update our |
| 1245 // state and let it resume with its existing ResourceHandlers. | 1247 // state and let it resume with its existing ResourceHandlers. |
| 1246 UpdateRequestForTransfer(filter_->child_id(), route_id, request_id, | 1248 UpdateRequestForTransfer(filter_->child_id(), route_id, request_id, |
| 1247 request_data, it); | 1249 request_data, it); |
| 1248 pending_loader->CompleteTransfer(); | 1250 pending_loader->CompleteTransfer(std::move(mojo_request), |
| 1251 std::move(url_loader_client)); |
| 1249 } | 1252 } |
| 1250 | 1253 |
| 1251 void ResourceDispatcherHostImpl::BeginRequest( | 1254 void ResourceDispatcherHostImpl::BeginRequest( |
| 1252 int request_id, | 1255 int request_id, |
| 1253 const ResourceRequest& request_data, | 1256 const ResourceRequest& request_data, |
| 1254 const SyncLoadResultCallback& sync_result_handler, // only valid for sync | 1257 const SyncLoadResultCallback& sync_result_handler, // only valid for sync |
| 1255 int route_id, | 1258 int route_id, |
| 1256 mojom::URLLoaderAssociatedRequest mojo_request, | 1259 mojom::URLLoaderAssociatedRequest mojo_request, |
| 1257 mojom::URLLoaderClientAssociatedPtr url_loader_client) { | 1260 mojom::URLLoaderClientAssociatedPtr url_loader_client) { |
| 1258 int process_type = filter_->process_type(); | 1261 int process_type = filter_->process_type(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1287 // If we crash here, figure out what URL the renderer was requesting. | 1290 // If we crash here, figure out what URL the renderer was requesting. |
| 1288 // http://crbug.com/91398 | 1291 // http://crbug.com/91398 |
| 1289 char url_buf[128]; | 1292 char url_buf[128]; |
| 1290 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf)); | 1293 base::strlcpy(url_buf, request_data.url.spec().c_str(), arraysize(url_buf)); |
| 1291 base::debug::Alias(url_buf); | 1294 base::debug::Alias(url_buf); |
| 1292 | 1295 |
| 1293 // If the request that's coming in is being transferred from another process, | 1296 // If the request that's coming in is being transferred from another process, |
| 1294 // we want to reuse and resume the old loader rather than start a new one. | 1297 // we want to reuse and resume the old loader rather than start a new one. |
| 1295 if (request_data.transferred_request_child_id != -1 || | 1298 if (request_data.transferred_request_child_id != -1 || |
| 1296 request_data.transferred_request_request_id != -1) { | 1299 request_data.transferred_request_request_id != -1) { |
| 1297 // TODO(yhirano): Make mojo work for this case. | 1300 CompleteTransfer(request_id, request_data, route_id, |
| 1298 DCHECK(!url_loader_client); | 1301 std::move(mojo_request), std::move(url_loader_client)); |
| 1299 | |
| 1300 CompleteTransfer(request_id, request_data, route_id); | |
| 1301 return; | 1302 return; |
| 1302 } | 1303 } |
| 1303 | 1304 |
| 1304 ResourceContext* resource_context = NULL; | 1305 ResourceContext* resource_context = NULL; |
| 1305 net::URLRequestContext* request_context = NULL; | 1306 net::URLRequestContext* request_context = NULL; |
| 1306 filter_->GetContexts(request_data.resource_type, &resource_context, | 1307 filter_->GetContexts(request_data.resource_type, &resource_context, |
| 1307 &request_context); | 1308 &request_context); |
| 1308 | 1309 |
| 1309 // Parse the headers before calling ShouldServiceRequest, so that they are | 1310 // Parse the headers before calling ShouldServiceRequest, so that they are |
| 1310 // available to be validated. | 1311 // available to be validated. |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 ResourceDispatcherHostImpl::CreateResourceHandler( | 1592 ResourceDispatcherHostImpl::CreateResourceHandler( |
| 1592 net::URLRequest* request, | 1593 net::URLRequest* request, |
| 1593 const ResourceRequest& request_data, | 1594 const ResourceRequest& request_data, |
| 1594 const SyncLoadResultCallback& sync_result_handler, | 1595 const SyncLoadResultCallback& sync_result_handler, |
| 1595 int route_id, | 1596 int route_id, |
| 1596 int process_type, | 1597 int process_type, |
| 1597 int child_id, | 1598 int child_id, |
| 1598 ResourceContext* resource_context, | 1599 ResourceContext* resource_context, |
| 1599 mojom::URLLoaderAssociatedRequest mojo_request, | 1600 mojom::URLLoaderAssociatedRequest mojo_request, |
| 1600 mojom::URLLoaderClientAssociatedPtr url_loader_client) { | 1601 mojom::URLLoaderClientAssociatedPtr url_loader_client) { |
| 1602 TransferCallback transfer_callback; |
| 1601 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. | 1603 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. |
| 1602 tracked_objects::ScopedTracker tracking_profile( | 1604 tracked_objects::ScopedTracker tracking_profile( |
| 1603 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1605 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1604 "456331 ResourceDispatcherHostImpl::CreateResourceHandler")); | 1606 "456331 ResourceDispatcherHostImpl::CreateResourceHandler")); |
| 1605 // Construct the IPC resource handler. | 1607 // Construct the IPC resource handler. |
| 1606 std::unique_ptr<ResourceHandler> handler; | 1608 std::unique_ptr<ResourceHandler> handler; |
| 1607 if (sync_result_handler) { | 1609 if (sync_result_handler) { |
| 1608 // download_to_file is not supported for synchronous requests. | 1610 // download_to_file is not supported for synchronous requests. |
| 1609 if (request_data.download_to_file) { | 1611 if (request_data.download_to_file) { |
| 1610 bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD); | 1612 bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD); |
| 1611 return std::unique_ptr<ResourceHandler>(); | 1613 return std::unique_ptr<ResourceHandler>(); |
| 1612 } | 1614 } |
| 1613 | 1615 |
| 1614 DCHECK(!mojo_request.is_pending()); | 1616 DCHECK(!mojo_request.is_pending()); |
| 1615 DCHECK(!url_loader_client); | 1617 DCHECK(!url_loader_client); |
| 1616 handler.reset(new SyncResourceHandler(request, sync_result_handler, this)); | 1618 handler.reset(new SyncResourceHandler(request, sync_result_handler, this)); |
| 1617 } else { | 1619 } else { |
| 1618 if (mojo_request.is_pending()) { | 1620 if (mojo_request.is_pending()) { |
| 1619 handler.reset(new MojoAsyncResourceHandler(request, this, | 1621 auto mojo_handler = base::MakeUnique<MojoAsyncResourceHandler>( |
| 1620 std::move(mojo_request), | 1622 request, this, std::move(mojo_request), std::move(url_loader_client)); |
| 1621 std::move(url_loader_client))); | 1623 transfer_callback = mojo_handler->GetTransferCallback(); |
| 1624 handler = std::move(mojo_handler); |
| 1622 } else { | 1625 } else { |
| 1623 handler.reset(new AsyncResourceHandler(request, this)); | 1626 handler.reset(new AsyncResourceHandler(request, this)); |
| 1624 } | 1627 } |
| 1625 | 1628 |
| 1626 // The RedirectToFileResourceHandler depends on being next in the chain. | 1629 // The RedirectToFileResourceHandler depends on being next in the chain. |
| 1627 if (request_data.download_to_file) { | 1630 if (request_data.download_to_file) { |
| 1628 handler.reset( | 1631 handler.reset( |
| 1629 new RedirectToFileResourceHandler(std::move(handler), request)); | 1632 new RedirectToFileResourceHandler(std::move(handler), request)); |
| 1630 } | 1633 } |
| 1631 } | 1634 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1642 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), | 1645 base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs), |
| 1643 std::move(handler)); | 1646 std::move(handler)); |
| 1644 if (start_detached) | 1647 if (start_detached) |
| 1645 detachable_handler->Detach(); | 1648 detachable_handler->Detach(); |
| 1646 handler = std::move(detachable_handler); | 1649 handler = std::move(detachable_handler); |
| 1647 } | 1650 } |
| 1648 | 1651 |
| 1649 return AddStandardHandlers( | 1652 return AddStandardHandlers( |
| 1650 request, request_data.resource_type, resource_context, | 1653 request, request_data.resource_type, resource_context, |
| 1651 request_data.fetch_request_context_type, filter_->appcache_service(), | 1654 request_data.fetch_request_context_type, filter_->appcache_service(), |
| 1652 child_id, route_id, std::move(handler)); | 1655 child_id, route_id, std::move(handler), transfer_callback); |
| 1653 } | 1656 } |
| 1654 | 1657 |
| 1655 std::unique_ptr<ResourceHandler> | 1658 std::unique_ptr<ResourceHandler> |
| 1656 ResourceDispatcherHostImpl::AddStandardHandlers( | 1659 ResourceDispatcherHostImpl::AddStandardHandlers( |
| 1657 net::URLRequest* request, | 1660 net::URLRequest* request, |
| 1658 ResourceType resource_type, | 1661 ResourceType resource_type, |
| 1659 ResourceContext* resource_context, | 1662 ResourceContext* resource_context, |
| 1660 RequestContextType fetch_request_context_type, | 1663 RequestContextType fetch_request_context_type, |
| 1661 AppCacheService* appcache_service, | 1664 AppCacheService* appcache_service, |
| 1662 int child_id, | 1665 int child_id, |
| 1663 int route_id, | 1666 int route_id, |
| 1664 std::unique_ptr<ResourceHandler> handler) { | 1667 std::unique_ptr<ResourceHandler> handler, |
| 1668 TransferCallback transfer_callback) { |
| 1665 // PlzNavigate: do not add ResourceThrottles for main resource requests from | 1669 // PlzNavigate: do not add ResourceThrottles for main resource requests from |
| 1666 // the renderer. Decisions about the navigation should have been done in the | 1670 // the renderer. Decisions about the navigation should have been done in the |
| 1667 // initial request. | 1671 // initial request. |
| 1668 bool is_renderer = | 1672 bool is_renderer = |
| 1669 filter_ ? (filter_->process_type() == PROCESS_TYPE_RENDERER) : false; | 1673 filter_ ? (filter_->process_type() == PROCESS_TYPE_RENDERER) : false; |
| 1670 if (is_renderer && IsBrowserSideNavigationEnabled() && | 1674 if (is_renderer && IsBrowserSideNavigationEnabled() && |
| 1671 IsResourceTypeFrame(resource_type)) { | 1675 IsResourceTypeFrame(resource_type)) { |
| 1672 DCHECK(request->url().SchemeIs(url::kBlobScheme)); | 1676 DCHECK(request->url().SchemeIs(url::kBlobScheme)); |
| 1673 return handler; | 1677 return handler; |
| 1674 } | 1678 } |
| 1675 | 1679 |
| 1676 // The InterceptingResourceHandler will replace its next handler with an | 1680 // The InterceptingResourceHandler will replace its next handler with an |
| 1677 // appropriate one based on the MIME type of the response if needed. It | 1681 // appropriate one based on the MIME type of the response if needed. It |
| 1678 // should be placed at the end of the chain, just before |handler|. | 1682 // should be placed at the end of the chain, just before |handler|. |
| 1679 handler.reset(new InterceptingResourceHandler(std::move(handler), request)); | 1683 handler.reset(new InterceptingResourceHandler(std::move(handler), request)); |
| 1680 InterceptingResourceHandler* intercepting_handler = | 1684 InterceptingResourceHandler* intercepting_handler = |
| 1681 static_cast<InterceptingResourceHandler*>(handler.get()); | 1685 static_cast<InterceptingResourceHandler*>(handler.get()); |
| 1682 | 1686 |
| 1683 ScopedVector<ResourceThrottle> throttles; | 1687 ScopedVector<ResourceThrottle> throttles; |
| 1684 | 1688 |
| 1685 // Add a NavigationResourceThrottle for navigations. | 1689 // Add a NavigationResourceThrottle for navigations. |
| 1686 // PlzNavigate: the throttle is unnecessary as communication with the UI | 1690 // PlzNavigate: the throttle is unnecessary as communication with the UI |
| 1687 // thread is handled by the NavigationURLloader. | 1691 // thread is handled by the NavigationURLloader. |
| 1688 if (!IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type)) { | 1692 if (!IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type)) { |
| 1689 throttles.push_back(new NavigationResourceThrottle( | 1693 throttles.push_back(new NavigationResourceThrottle( |
| 1690 request, delegate_, fetch_request_context_type)); | 1694 request, delegate_, fetch_request_context_type, transfer_callback)); |
| 1691 } | 1695 } |
| 1692 | 1696 |
| 1693 if (delegate_) { | 1697 if (delegate_) { |
| 1694 delegate_->RequestBeginning(request, | 1698 delegate_->RequestBeginning(request, |
| 1695 resource_context, | 1699 resource_context, |
| 1696 appcache_service, | 1700 appcache_service, |
| 1697 resource_type, | 1701 resource_type, |
| 1698 &throttles); | 1702 &throttles); |
| 1699 } | 1703 } |
| 1700 | 1704 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 } | 1860 } |
| 1857 | 1861 |
| 1858 void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id, | 1862 void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id, |
| 1859 int route_id, | 1863 int route_id, |
| 1860 bool is_loading) { | 1864 bool is_loading) { |
| 1861 scheduler_->OnLoadingStateChanged(child_id, route_id, !is_loading); | 1865 scheduler_->OnLoadingStateChanged(child_id, route_id, !is_loading); |
| 1862 } | 1866 } |
| 1863 | 1867 |
| 1864 void ResourceDispatcherHostImpl::MarkAsTransferredNavigation( | 1868 void ResourceDispatcherHostImpl::MarkAsTransferredNavigation( |
| 1865 const GlobalRequestID& id, | 1869 const GlobalRequestID& id, |
| 1866 const base::Closure& on_transfer_complete_callback) { | 1870 const TransferCallback& on_transfer_complete_callback) { |
| 1867 GetLoader(id)->MarkAsTransferring(on_transfer_complete_callback); | 1871 GetLoader(id)->MarkAsTransferring(on_transfer_complete_callback); |
| 1868 } | 1872 } |
| 1869 | 1873 |
| 1870 void ResourceDispatcherHostImpl::CancelTransferringNavigation( | 1874 void ResourceDispatcherHostImpl::CancelTransferringNavigation( |
| 1871 const GlobalRequestID& id) { | 1875 const GlobalRequestID& id) { |
| 1872 // Request should still exist and be in the middle of a transfer. | 1876 // Request should still exist and be in the middle of a transfer. |
| 1873 DCHECK(IsTransferredNavigation(id)); | 1877 DCHECK(IsTransferredNavigation(id)); |
| 1874 RemovePendingRequest(id.child_id, id.request_id); | 1878 RemovePendingRequest(id.child_id, id.request_id); |
| 1875 } | 1879 } |
| 1876 | 1880 |
| 1877 void ResourceDispatcherHostImpl::ResumeDeferredNavigation( | 1881 void ResourceDispatcherHostImpl::ResumeDeferredNavigation( |
| 1878 const GlobalRequestID& id) { | 1882 const GlobalRequestID& id) { |
| 1879 ResourceLoader* loader = GetLoader(id); | 1883 ResourceLoader* loader = GetLoader(id); |
| 1880 // The response we were meant to resume could have already been canceled. | 1884 // The response we were meant to resume could have already been canceled. |
| 1881 if (loader) | 1885 if (loader) |
| 1882 loader->CompleteTransfer(); | 1886 loader->CompleteTransfer(nullptr, nullptr); |
| 1883 } | 1887 } |
| 1884 | 1888 |
| 1885 // The object died, so cancel and detach all requests associated with it except | 1889 // The object died, so cancel and detach all requests associated with it except |
| 1886 // for downloads and detachable resources, which belong to the browser process | 1890 // for downloads and detachable resources, which belong to the browser process |
| 1887 // even if initiated via a renderer. | 1891 // even if initiated via a renderer. |
| 1888 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { | 1892 void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) { |
| 1889 CancelRequestsForRoute( | 1893 CancelRequestsForRoute( |
| 1890 GlobalFrameRoutingId(child_id, MSG_ROUTING_NONE /* cancel all */)); | 1894 GlobalFrameRoutingId(child_id, MSG_ROUTING_NONE /* cancel all */)); |
| 1891 registered_temp_files_.erase(child_id); | 1895 registered_temp_files_.erase(child_id); |
| 1892 } | 1896 } |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2256 | 2260 |
| 2257 // TODO(davidben): Pass in the appropriate appcache_service. Also fix the | 2261 // TODO(davidben): Pass in the appropriate appcache_service. Also fix the |
| 2258 // dependency on child_id/route_id. Those are used by the ResourceScheduler; | 2262 // dependency on child_id/route_id. Those are used by the ResourceScheduler; |
| 2259 // currently it's a no-op. | 2263 // currently it's a no-op. |
| 2260 handler = | 2264 handler = |
| 2261 AddStandardHandlers(new_request.get(), resource_type, resource_context, | 2265 AddStandardHandlers(new_request.get(), resource_type, resource_context, |
| 2262 info.begin_params.request_context_type, | 2266 info.begin_params.request_context_type, |
| 2263 nullptr, // appcache_service | 2267 nullptr, // appcache_service |
| 2264 -1, // child_id | 2268 -1, // child_id |
| 2265 -1, // route_id | 2269 -1, // route_id |
| 2266 std::move(handler)); | 2270 std::move(handler), {}); |
| 2267 | 2271 |
| 2268 BeginRequestInternal(std::move(new_request), std::move(handler)); | 2272 BeginRequestInternal(std::move(new_request), std::move(handler)); |
| 2269 } | 2273 } |
| 2270 | 2274 |
| 2271 void ResourceDispatcherHostImpl::EnableStaleWhileRevalidateForTesting() { | 2275 void ResourceDispatcherHostImpl::EnableStaleWhileRevalidateForTesting() { |
| 2272 if (!async_revalidation_manager_) | 2276 if (!async_revalidation_manager_) |
| 2273 async_revalidation_manager_.reset(new AsyncRevalidationManager); | 2277 async_revalidation_manager_.reset(new AsyncRevalidationManager); |
| 2274 } | 2278 } |
| 2275 | 2279 |
| 2276 void ResourceDispatcherHostImpl::SetLoaderDelegate( | 2280 void ResourceDispatcherHostImpl::SetLoaderDelegate( |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2799 &throttles); | 2803 &throttles); |
| 2800 if (!throttles.empty()) { | 2804 if (!throttles.empty()) { |
| 2801 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, | 2805 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, |
| 2802 std::move(throttles))); | 2806 std::move(throttles))); |
| 2803 } | 2807 } |
| 2804 } | 2808 } |
| 2805 return handler; | 2809 return handler; |
| 2806 } | 2810 } |
| 2807 | 2811 |
| 2808 } // namespace content | 2812 } // namespace content |
| OLD | NEW |