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 21 matching lines...) Expand all Loading... | |
32 #include "base/stl_util.h" | 32 #include "base/stl_util.h" |
33 #include "base/strings/string_util.h" | 33 #include "base/strings/string_util.h" |
34 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 34 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
35 #include "base/time/time.h" | 35 #include "base/time/time.h" |
36 #include "content/browser/appcache/appcache_interceptor.h" | 36 #include "content/browser/appcache/appcache_interceptor.h" |
37 #include "content/browser/appcache/chrome_appcache_service.h" | 37 #include "content/browser/appcache/chrome_appcache_service.h" |
38 #include "content/browser/bad_message.h" | 38 #include "content/browser/bad_message.h" |
39 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 39 #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
40 #include "content/browser/cert_store_impl.h" | 40 #include "content/browser/cert_store_impl.h" |
41 #include "content/browser/child_process_security_policy_impl.h" | 41 #include "content/browser/child_process_security_policy_impl.h" |
42 #include "content/browser/download/download_resource_handler.h" | |
43 #include "content/browser/download/save_file_resource_handler.h" | |
44 #include "content/browser/frame_host/frame_tree.h" | 42 #include "content/browser/frame_host/frame_tree.h" |
45 #include "content/browser/frame_host/navigation_request_info.h" | 43 #include "content/browser/frame_host/navigation_request_info.h" |
46 #include "content/browser/frame_host/navigator.h" | 44 #include "content/browser/frame_host/navigator.h" |
47 #include "content/browser/loader/async_resource_handler.h" | 45 #include "content/browser/loader/async_resource_handler.h" |
48 #include "content/browser/loader/async_revalidation_manager.h" | 46 #include "content/browser/loader/async_revalidation_manager.h" |
49 #include "content/browser/loader/cross_site_resource_handler.h" | 47 #include "content/browser/loader/cross_site_resource_handler.h" |
50 #include "content/browser/loader/detachable_resource_handler.h" | 48 #include "content/browser/loader/detachable_resource_handler.h" |
51 #include "content/browser/loader/loader_delegate.h" | 49 #include "content/browser/loader/loader_delegate.h" |
52 #include "content/browser/loader/mime_type_resource_handler.h" | 50 #include "content/browser/loader/mime_type_resource_handler.h" |
53 #include "content/browser/loader/mojo_async_resource_handler.h" | 51 #include "content/browser/loader/mojo_async_resource_handler.h" |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
603 loaders_to_cancel.clear(); | 601 loaders_to_cancel.clear(); |
604 | 602 |
605 if (async_revalidation_manager_) { | 603 if (async_revalidation_manager_) { |
606 // Cancelling async revalidations should not result in the creation of new | 604 // Cancelling async revalidations should not result in the creation of new |
607 // requests. Do it before the CHECKs to ensure this does not happen. | 605 // requests. Do it before the CHECKs to ensure this does not happen. |
608 async_revalidation_manager_->CancelAsyncRevalidationsForResourceContext( | 606 async_revalidation_manager_->CancelAsyncRevalidationsForResourceContext( |
609 context); | 607 context); |
610 } | 608 } |
611 } | 609 } |
612 | 610 |
613 DownloadInterruptReason ResourceDispatcherHostImpl::BeginDownload( | |
614 std::unique_ptr<net::URLRequest> request, | |
615 const Referrer& referrer, | |
616 bool is_content_initiated, | |
617 ResourceContext* context, | |
618 int render_process_id, | |
619 int render_view_route_id, | |
620 int render_frame_route_id, | |
621 bool do_not_prompt_for_login) { | |
622 if (is_shutdown_) | |
623 return DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN; | |
624 | |
625 const GURL& url = request->original_url(); | |
626 SetReferrerForRequest(request.get(), referrer); | |
627 | |
628 // We treat a download as a main frame load, and thus update the policy URL on | |
629 // redirects. | |
630 // | |
631 // TODO(davidben): Is this correct? If this came from a | |
632 // ViewHostMsg_DownloadUrl in a frame, should it have first-party URL set | |
633 // appropriately? | |
634 request->set_first_party_url_policy( | |
635 net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); | |
636 | |
637 // Check if the renderer is permitted to request the requested URL. | |
638 if (!ChildProcessSecurityPolicyImpl::GetInstance()-> | |
639 CanRequestURL(render_process_id, url)) { | |
640 DVLOG(1) << "Denied unauthorized download request for " | |
641 << url.possibly_invalid_spec(); | |
642 return DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST; | |
643 } | |
644 | |
645 request_id_--; | |
646 | |
647 const net::URLRequestContext* request_context = request->context(); | |
648 if (!request_context->job_factory()->IsHandledURL(url)) { | |
649 DVLOG(1) << "Download request for unsupported protocol: " | |
650 << url.possibly_invalid_spec(); | |
651 return DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST; | |
652 } | |
653 | |
654 ResourceRequestInfoImpl* extra_info = | |
655 CreateRequestInfo(render_process_id, render_view_route_id, | |
656 render_frame_route_id, true, context); | |
657 extra_info->set_do_not_prompt_for_login(do_not_prompt_for_login); | |
658 extra_info->AssociateWithRequest(request.get()); // Request takes ownership. | |
659 | |
660 if (request->url().SchemeIs(url::kBlobScheme) && | |
661 !storage::BlobProtocolHandler::GetRequestBlobDataHandle(request.get())) { | |
662 ChromeBlobStorageContext* blob_context = | |
663 GetChromeBlobStorageContextForResourceContext(context); | |
664 storage::BlobProtocolHandler::SetRequestedBlobDataHandle( | |
665 request.get(), | |
666 blob_context->context()->GetBlobDataFromPublicURL(request->url())); | |
667 } | |
668 | |
669 // From this point forward, the |DownloadResourceHandler| is responsible for | |
670 // |started_callback|. | |
671 std::unique_ptr<ResourceHandler> handler(CreateResourceHandlerForDownload( | |
672 request.get(), is_content_initiated, true)); | |
673 | |
674 BeginRequestInternal(std::move(request), std::move(handler)); | |
675 | |
676 return DOWNLOAD_INTERRUPT_REASON_NONE; | |
677 } | |
678 | |
679 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( | 611 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( |
680 net::URLRequest* request) { | 612 net::URLRequest* request) { |
681 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); | 613 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); |
682 if (info) { | 614 if (info) { |
683 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); | 615 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); |
684 if (loader) | 616 if (loader) |
685 loader->ClearLoginDelegate(); | 617 loader->ClearLoginDelegate(); |
686 } | 618 } |
687 } | 619 } |
688 | 620 |
(...skipping 20 matching lines...) Expand all Loading... | |
709 FROM_HERE, | 641 FROM_HERE, |
710 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, | 642 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, |
711 base::Unretained(this))); | 643 base::Unretained(this))); |
712 } | 644 } |
713 | 645 |
714 std::unique_ptr<ResourceHandler> | 646 std::unique_ptr<ResourceHandler> |
715 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( | 647 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( |
716 net::URLRequest* request, | 648 net::URLRequest* request, |
717 bool is_content_initiated, | 649 bool is_content_initiated, |
718 bool must_download) { | 650 bool must_download) { |
719 std::unique_ptr<ResourceHandler> handler( | 651 DCHECK(!create_download_handler_intercept_.is_null()); |
720 new DownloadResourceHandler(request)); | 652 // TODO(ananta) |
721 if (delegate_) { | 653 // Find a better way to create the download handler and notifying the |
722 const ResourceRequestInfoImpl* request_info( | 654 // delegate of the download start. |
723 ResourceRequestInfoImpl::ForRequest(request)); | 655 std::unique_ptr<ResourceHandler> handler = |
724 | 656 create_download_handler_intercept_.Run(request); |
725 ScopedVector<ResourceThrottle> throttles; | 657 handler = HandleDownloadStarted(request, std::move(handler), |
726 delegate_->DownloadStarting( | 658 is_content_initiated, must_download); |
727 request, request_info->GetContext(), request_info->GetChildID(), | |
728 request_info->GetRouteID(), is_content_initiated, must_download, | |
729 &throttles); | |
730 if (!throttles.empty()) { | |
731 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, | |
732 std::move(throttles))); | |
733 } | |
734 } | |
735 return handler; | 659 return handler; |
736 } | 660 } |
737 | 661 |
738 std::unique_ptr<ResourceHandler> | 662 std::unique_ptr<ResourceHandler> |
739 ResourceDispatcherHostImpl::MaybeInterceptAsStream( | 663 ResourceDispatcherHostImpl::MaybeInterceptAsStream( |
740 const base::FilePath& plugin_path, | 664 const base::FilePath& plugin_path, |
741 net::URLRequest* request, | 665 net::URLRequest* request, |
742 ResourceResponse* response, | 666 ResourceResponse* response, |
743 std::string* payload) { | 667 std::string* payload) { |
744 payload->clear(); | 668 payload->clear(); |
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1854 context, | 1778 context, |
1855 base::WeakPtr<ResourceMessageFilter>(), // filter | 1779 base::WeakPtr<ResourceMessageFilter>(), // filter |
1856 false, // report_raw_headers | 1780 false, // report_raw_headers |
1857 true, // is_async | 1781 true, // is_async |
1858 false, // is_using_lofi | 1782 false, // is_using_lofi |
1859 std::string(), // original_headers | 1783 std::string(), // original_headers |
1860 nullptr, // body | 1784 nullptr, // body |
1861 false); // initiated_in_secure_context | 1785 false); // initiated_in_secure_context |
1862 } | 1786 } |
1863 | 1787 |
1788 void ResourceDispatcherHostImpl::RegisterCreateDownloadHandlerInterceptor( | |
1789 CreateDownloadHandlerIntercept intercept) { | |
1790 create_download_handler_intercept_ = intercept; | |
1791 } | |
1792 | |
1864 void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id, | 1793 void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id, |
1865 int route_id) { | 1794 int route_id) { |
1866 scheduler_->OnClientCreated(child_id, route_id); | 1795 scheduler_->OnClientCreated(child_id, route_id); |
1867 } | 1796 } |
1868 | 1797 |
1869 void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(int child_id, | 1798 void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(int child_id, |
1870 int route_id) { | 1799 int route_id) { |
1871 scheduler_->OnClientDeleted(child_id, route_id); | 1800 scheduler_->OnClientDeleted(child_id, route_id); |
1872 } | 1801 } |
1873 | 1802 |
1874 void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id, | 1803 void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id, |
1875 int route_id, | 1804 int route_id, |
1876 bool is_loading) { | 1805 bool is_loading) { |
1877 scheduler_->OnLoadingStateChanged(child_id, route_id, !is_loading); | 1806 scheduler_->OnLoadingStateChanged(child_id, route_id, !is_loading); |
1878 } | 1807 } |
1879 | 1808 |
1880 // This function is only used for saving feature. | |
1881 void ResourceDispatcherHostImpl::BeginSaveFile(const GURL& url, | |
1882 const Referrer& referrer, | |
1883 SaveItemId save_item_id, | |
1884 SavePackageId save_package_id, | |
1885 int child_id, | |
1886 int render_view_route_id, | |
1887 int render_frame_route_id, | |
1888 ResourceContext* context) { | |
1889 if (is_shutdown_) | |
1890 return; | |
1891 | |
1892 request_id_--; | |
1893 | |
1894 const net::URLRequestContext* request_context = context->GetRequestContext(); | |
1895 bool known_proto = | |
1896 request_context->job_factory()->IsHandledURL(url); | |
1897 if (!known_proto) { | |
1898 // Since any URLs which have non-standard scheme have been filtered | |
1899 // by save manager(see GURL::SchemeIsStandard). This situation | |
1900 // should not happen. | |
1901 NOTREACHED(); | |
1902 return; | |
1903 } | |
1904 | |
1905 std::unique_ptr<net::URLRequest> request( | |
1906 request_context->CreateRequest(url, net::DEFAULT_PRIORITY, NULL)); | |
1907 request->set_method("GET"); | |
1908 SetReferrerForRequest(request.get(), referrer); | |
1909 | |
1910 // So far, for saving page, we need fetch content from cache, in the | |
1911 // future, maybe we can use a configuration to configure this behavior. | |
1912 request->SetLoadFlags(net::LOAD_PREFERRING_CACHE); | |
1913 | |
1914 // Since we're just saving some resources we need, disallow downloading. | |
1915 ResourceRequestInfoImpl* extra_info = | |
1916 CreateRequestInfo(child_id, render_view_route_id, | |
1917 render_frame_route_id, false, context); | |
1918 extra_info->AssociateWithRequest(request.get()); // Request takes ownership. | |
1919 | |
1920 // Check if the renderer is permitted to request the requested URL. | |
1921 using AuthorizationState = SaveFileResourceHandler::AuthorizationState; | |
1922 AuthorizationState authorization_state = AuthorizationState::AUTHORIZED; | |
1923 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(child_id, | |
1924 url)) { | |
1925 DVLOG(1) << "Denying unauthorized save of " << url.possibly_invalid_spec(); | |
1926 authorization_state = AuthorizationState::NOT_AUTHORIZED; | |
1927 // No need to return here (i.e. okay to begin processing the request below), | |
1928 // because NOT_AUTHORIZED will cause the request to be cancelled. See also | |
1929 // doc comments for AuthorizationState enum. | |
1930 } | |
1931 | |
1932 std::unique_ptr<SaveFileResourceHandler> handler(new SaveFileResourceHandler( | |
1933 request.get(), save_item_id, save_package_id, child_id, | |
1934 render_frame_route_id, url, authorization_state)); | |
1935 | |
1936 BeginRequestInternal(std::move(request), std::move(handler)); | |
1937 } | |
1938 | |
1939 void ResourceDispatcherHostImpl::MarkAsTransferredNavigation( | 1809 void ResourceDispatcherHostImpl::MarkAsTransferredNavigation( |
1940 const GlobalRequestID& id, | 1810 const GlobalRequestID& id, |
1941 const scoped_refptr<ResourceResponse>& response) { | 1811 const scoped_refptr<ResourceResponse>& response) { |
1942 GetLoader(id)->MarkAsTransferring(response); | 1812 GetLoader(id)->MarkAsTransferring(response); |
1943 } | 1813 } |
1944 | 1814 |
1945 void ResourceDispatcherHostImpl::CancelTransferringNavigation( | 1815 void ResourceDispatcherHostImpl::CancelTransferringNavigation( |
1946 const GlobalRequestID& id) { | 1816 const GlobalRequestID& id) { |
1947 // Request should still exist and be in the middle of a transfer. | 1817 // Request should still exist and be in the middle of a transfer. |
1948 DCHECK(IsTransferredNavigation(id)); | 1818 DCHECK(IsTransferredNavigation(id)); |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2360 | 2230 |
2361 void ResourceDispatcherHostImpl::BeginRequestInternal( | 2231 void ResourceDispatcherHostImpl::BeginRequestInternal( |
2362 std::unique_ptr<net::URLRequest> request, | 2232 std::unique_ptr<net::URLRequest> request, |
2363 std::unique_ptr<ResourceHandler> handler) { | 2233 std::unique_ptr<ResourceHandler> handler) { |
2364 DCHECK(!request->is_pending()); | 2234 DCHECK(!request->is_pending()); |
2365 ResourceRequestInfoImpl* info = | 2235 ResourceRequestInfoImpl* info = |
2366 ResourceRequestInfoImpl::ForRequest(request.get()); | 2236 ResourceRequestInfoImpl::ForRequest(request.get()); |
2367 | 2237 |
2368 if ((TimeTicks::Now() - last_user_gesture_time_) < | 2238 if ((TimeTicks::Now() - last_user_gesture_time_) < |
2369 TimeDelta::FromMilliseconds(kUserGestureWindowMs)) { | 2239 TimeDelta::FromMilliseconds(kUserGestureWindowMs)) { |
2370 request->SetLoadFlags( | 2240 request->SetLoadFlags(request->load_flags() | net::LOAD_MAYBE_USER_GESTURE); |
2371 request->load_flags() | net::LOAD_MAYBE_USER_GESTURE); | |
2372 } | 2241 } |
2373 | 2242 |
2374 // Add the memory estimate that starting this request will consume. | 2243 // Add the memory estimate that starting this request will consume. |
2375 info->set_memory_cost(CalculateApproximateMemoryCost(request.get())); | 2244 info->set_memory_cost(CalculateApproximateMemoryCost(request.get())); |
2376 | 2245 |
2377 // If enqueing/starting this request will exceed our per-process memory | 2246 // If enqueing/starting this request will exceed our per-process memory |
2378 // bound, abort it right away. | 2247 // bound, abort it right away. |
2379 OustandingRequestsStats stats = IncrementOutstandingRequestsMemory(1, *info); | 2248 OustandingRequestsStats stats = IncrementOutstandingRequestsMemory(1, *info); |
2380 if (stats.memory_cost > max_outstanding_requests_cost_per_process_) { | 2249 if (stats.memory_cost > max_outstanding_requests_cost_per_process_) { |
2381 // We call "CancelWithError()" as a way of setting the net::URLRequest's | 2250 // We call "CancelWithError()" as a way of setting the net::URLRequest's |
(...skipping 21 matching lines...) Expand all Loading... | |
2403 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id); | 2272 BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id); |
2404 if (iter != blocked_loaders_map_.end()) { | 2273 if (iter != blocked_loaders_map_.end()) { |
2405 // The request should be blocked. | 2274 // The request should be blocked. |
2406 iter->second->push_back(std::move(loader)); | 2275 iter->second->push_back(std::move(loader)); |
2407 return; | 2276 return; |
2408 } | 2277 } |
2409 | 2278 |
2410 StartLoading(info, std::move(loader)); | 2279 StartLoading(info, std::move(loader)); |
2411 } | 2280 } |
2412 | 2281 |
2282 ResourceDispatcherHostImpl::URLRequestStatus | |
2283 ResourceDispatcherHostImpl::BeginURLRequest( | |
2284 std::unique_ptr<net::URLRequest> request, | |
2285 std::unique_ptr<ResourceHandler> handler, | |
2286 const Referrer& referrer, | |
2287 bool is_download, | |
2288 bool is_content_initiated, | |
2289 bool do_not_prompt_for_login, | |
2290 int render_process_host_id, | |
2291 int render_view_routing_id, | |
2292 int render_frame_routing_id, | |
2293 ResourceContext* context) { | |
2294 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
2295 DCHECK(!request->is_pending()); | |
2296 | |
2297 if (is_shutdown()) | |
svaldez
2016/08/19 17:05:14
Why does this not just use is_shutdown_?
ananta
2016/08/19 19:02:14
Done.
| |
2298 return URL_REQUEST_FAILED_SHUTDOWN; | |
2299 | |
2300 request_id_--; | |
2301 | |
2302 ResourceRequestInfoImpl* info = | |
2303 ResourceDispatcherHostImpl::Get()->CreateRequestInfo( | |
2304 render_process_host_id, render_view_routing_id, | |
2305 render_frame_routing_id, is_download, context); | |
2306 | |
2307 info->set_do_not_prompt_for_login(do_not_prompt_for_login); | |
2308 // Request takes ownership. | |
2309 info->AssociateWithRequest(request.get()); | |
2310 SetReferrerForRequest(request.get(), referrer); | |
2311 // TODO(ananta) | |
2312 // Find a better place for notifying the delegate about the download start. | |
2313 if (is_download && delegate()) { | |
2314 handler = HandleDownloadStarted(request.get(), std::move(handler), | |
2315 is_content_initiated, true); | |
2316 } | |
2317 BeginRequestInternal(std::move(request), std::move(handler)); | |
2318 return URL_REQUEST_ISSUED; | |
2319 } | |
2320 | |
2413 void ResourceDispatcherHostImpl::StartLoading( | 2321 void ResourceDispatcherHostImpl::StartLoading( |
2414 ResourceRequestInfoImpl* info, | 2322 ResourceRequestInfoImpl* info, |
2415 std::unique_ptr<ResourceLoader> loader) { | 2323 std::unique_ptr<ResourceLoader> loader) { |
2416 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. | 2324 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. |
2417 tracked_objects::ScopedTracker tracking_profile( | 2325 tracked_objects::ScopedTracker tracking_profile( |
2418 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2326 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2419 "456331 ResourceDispatcherHostImpl::StartLoading")); | 2327 "456331 ResourceDispatcherHostImpl::StartLoading")); |
2420 | 2328 |
2421 ResourceLoader* loader_ptr = loader.get(); | 2329 ResourceLoader* loader_ptr = loader.get(); |
2422 pending_loaders_[info->GetGlobalRequestID()] = std::move(loader); | 2330 pending_loaders_[info->GetGlobalRequestID()] = std::move(loader); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2718 NOTREACHED() << "Denied unauthorized upload of " | 2626 NOTREACHED() << "Denied unauthorized upload of " |
2719 << iter->filesystem_url().spec(); | 2627 << iter->filesystem_url().spec(); |
2720 return false; | 2628 return false; |
2721 } | 2629 } |
2722 } | 2630 } |
2723 } | 2631 } |
2724 } | 2632 } |
2725 return true; | 2633 return true; |
2726 } | 2634 } |
2727 | 2635 |
2636 std::unique_ptr<ResourceHandler> | |
2637 ResourceDispatcherHostImpl::HandleDownloadStarted( | |
2638 net::URLRequest* request, | |
2639 std::unique_ptr<ResourceHandler> handler, | |
2640 bool is_content_initiated, | |
2641 bool must_download) { | |
2642 if (delegate()) { | |
2643 const ResourceRequestInfoImpl* request_info( | |
2644 ResourceRequestInfoImpl::ForRequest(request)); | |
2645 ScopedVector<ResourceThrottle> throttles; | |
2646 delegate()->DownloadStarting( | |
2647 request, request_info->GetContext(), request_info->GetChildID(), | |
2648 request_info->GetRouteID(), is_content_initiated, true, &throttles); | |
2649 if (!throttles.empty()) { | |
2650 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, | |
2651 std::move(throttles))); | |
2652 } | |
2653 } | |
2654 return handler; | |
2655 } | |
2656 | |
2728 } // namespace content | 2657 } // namespace content |
OLD | NEW |