diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/content/browser/loader | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/content/browser/loader')
52 files changed, 1262 insertions, 1120 deletions
diff --git a/chromium/content/browser/loader/DEPS b/chromium/content/browser/loader/DEPS index 191c9259b8e..28ae5824446 100644 --- a/chromium/content/browser/loader/DEPS +++ b/chromium/content/browser/loader/DEPS @@ -29,15 +29,15 @@ specific_include_rules = { # TODO: To be replaced by mojo. "+content/common/resource_messages.h", - "+content/common/resource_request_completion_status.h", "+content/common/view_messages.h", + "+content/public/common/resource_request_completion_status.h", ], "downloaded_temp_file_impl\.(cc|h)": [ "-content", "+content/browser/loader/downloaded_temp_file_impl.h", "+content/browser/loader/resource_dispatcher_host_impl.h", "+content/common/content_export.h", - "+content/common/url_loader_factory.mojom.h" + "+content/public/common/url_loader_factory.mojom.h" ], "resource_buffer.*\.(cc|h)": [ "-content", @@ -67,25 +67,20 @@ specific_include_rules = { "+content/browser/loader/resource_scheduler.h", "+content/browser/loader/upload_progress_tracker.h", "+content/common/content_export.h", - "+content/common/resource_request_completion_status.h", - "+content/common/url_loader.mojom.h", "+content/public/browser/global_request_id.h", + "+content/public/common/resource_request_completion_status.h", "+content/public/common/resource_response.h", "+content/public/common/resource_type.h", + "+content/public/common/url_loader.mojom.h", ], "mojo_async_resource_handler_unittest\.cc": [ "-content", "+content/browser/loader/mock_resource_loader.h", "+content/browser/loader/mojo_async_resource_handler.h", - "+content/browser/loader/test_url_loader_client.h", "+content/browser/loader/resource_controller.h", "+content/browser/loader/resource_dispatcher_host_impl.h", "+content/browser/loader/resource_request_info_impl.h", "+content/browser/loader/resource_scheduler.h", - "+content/common/resource_request.h", - "+content/common/resource_request_completion_status.h", - "+content/common/url_loader.mojom.h", - "+content/common/url_loader_factory.mojom.h", "+content/public/browser/appcache_service.h", "+content/public/browser/navigation_data.h", "+content/public/browser/resource_context.h", @@ -93,10 +88,15 @@ specific_include_rules = { "+content/public/browser/resource_throttle.h", "+content/public/browser/stream_info.h", "+content/public/common/previews_state.h", + "+content/public/common/resource_request.h", + "+content/public/common/resource_request_completion_status.h", "+content/public/common/resource_response.h", "+content/public/common/resource_type.h", + "+content/public/common/url_loader.mojom.h", + "+content/public/common/url_loader_factory.mojom.h", "+content/public/test/test_browser_context.h", "+content/public/test/test_browser_thread_bundle.h", + "+content/public/test/test_url_loader_client.h", ], "netlog_observer\.(cc|h)": [ "-content", @@ -127,14 +127,14 @@ specific_include_rules = { "+content/browser/loader/throttling_resource_handler.h", "+content/browser/loader/wake_lock_resource_throttle.h", "+content/common/resource_request_body.h", - "+content/common/resource_request_body_impl.h", - "+content/common/url_loader.mojom.h", "+content/public/browser/global_request_id.h", "+content/public/browser/resource_dispatcher_host.h", "+content/public/browser/resource_dispatcher_host_delegate.h", "+content/public/browser/resource_request_info.h", "+content/public/browser/resource_throttle.h", "+content/public/common/previews_state.h", + "+content/public/common/resource_request_body.h", + "+content/public/common/url_loader.mojom.h", # TODO: These all have to be removed. "+content/browser/appcache/appcache_interceptor.h", @@ -142,6 +142,7 @@ specific_include_rules = { "+content/browser/appcache/chrome_appcache_service.h", "+content/browser/bad_message.h", "+content/browser/blob_storage/chrome_blob_storage_context.h", + "+content/browser/browsing_data/clear_site_data_throttle.h", "+content/browser/child_process_security_policy_impl.h", "+content/browser/frame_host/navigation_request_info.h", "+content/browser/loader/cross_site_resource_handler.h", @@ -164,6 +165,7 @@ specific_include_rules = { "+content/browser/streams/stream_registry.h", "+content/common/content_export.h", "+content/common/net/url_request_service_worker_data.h", + "+content/common/site_isolation_policy.h", "+content/public/browser/browser_thread.h", "+content/public/browser/navigation_ui_data.h", "+content/public/browser/plugin_service.h", @@ -178,9 +180,9 @@ specific_include_rules = { # TODO: To be replaced by mojo. "+content/common/resource_messages.h", - "+content/common/resource_request.h", - "+content/common/resource_request_completion_status.h", "+content/common/view_messages.h", + "+content/public/common/resource_request.h", + "+content/public/common/resource_request_completion_status.h", ], "resource_handler\.(cc|h)": [ "-content", @@ -221,19 +223,20 @@ specific_include_rules = { ], "resource_request_info_impl\.(cc|h)": [ "-content", + "+content/browser/blob_storage/chrome_blob_storage_context.h", "+content/browser/loader/global_routing_id.h", "+content/browser/loader/resource_handler.h", "+content/browser/loader/resource_message_filter.h", "+content/browser/loader/resource_request_info_impl.h", "+content/browser/loader/resource_requester_info.h", "+content/common/content_export.h", - "+content/common/resource_request_body_impl.h", - "+content/common/url_loader.mojom.h", "+content/public/browser/global_request_id.h", "+content/public/browser/resource_request_info.h", "+content/public/common/previews_state.h", "+content/public/common/referrer.h", + "+content/public/common/resource_request_body.h", "+content/public/common/resource_type.h", + "+content/public/common/url_loader.mojom.h", # TODO: these all have to be removed. "+content/browser/frame_host/frame_tree_node.h", @@ -298,14 +301,6 @@ specific_include_rules = { # TODO: To be replaced by mojo. "+content/common/resource_messages.h", ], - "test_url_loader_client\.(cc|h)": [ - "-content", - "+content/browser/loader/test_url_loader_client.h", - "+content/common/resource_request_completion_status.h", - "+content/common/url_loader.mojom.h", - "+content/common/url_loader_factory.mojom.h", - "+content/public/common/resource_response.h", - ], "upload_progress_tracker\.(cc|h)": [ "-content", "+content/browser/loader/upload_progress_tracker.h", @@ -317,29 +312,29 @@ specific_include_rules = { "+content/browser/loader/resource_requester_info.h", "+content/browser/loader/url_loader_factory_impl.h", "+content/common/content_export.h", - "+content/common/resource_request.h", - "+content/common/url_loader.mojom.h", - "+content/common/url_loader_factory.mojom.h", + "+content/public/common/resource_request.h", + "+content/public/common/url_loader.mojom.h", + "+content/public/common/url_loader_factory.mojom.h", ], "url_loader_factory_impl_unittest\.cc": [ "-content", "+content/browser/child_process_security_policy_impl.h", "+content/browser/loader/mojo_async_resource_handler.h", - "+content/browser/loader/test_url_loader_client.h", "+content/browser/loader/resource_dispatcher_host_impl.h", "+content/browser/loader/resource_message_filter.h", "+content/browser/loader/resource_request_info_impl.h", "+content/browser/loader/url_loader_factory_impl.h", "+content/browser/loader_delegate_impl.h", - "+content/common/resource_request.h", - "+content/common/resource_request_completion_status.h", - "+content/common/url_loader.mojom.h", - "+content/common/url_loader_factory.mojom.h", "+content/public/browser/resource_context.h", "+content/public/browser/resource_dispatcher_host_delegate.h", "+content/public/common/content_paths.h", + "+content/public/common/resource_request.h", + "+content/public/common/resource_request_completion_status.h", + "+content/public/common/url_loader.mojom.h", + "+content/public/common/url_loader_factory.mojom.h", "+content/public/test/test_browser_context.h", "+content/public/test/test_browser_thread_bundle.h", + "+content/public/test/test_url_loader_client.h", #TODO: To be removed when PlzNavigate lands. "+content/browser/loader/navigation_resource_throttle.h" diff --git a/chromium/content/browser/loader/OWNERS b/chromium/content/browser/loader/OWNERS index e8096c7e3b6..466c50011c4 100644 --- a/chromium/content/browser/loader/OWNERS +++ b/chromium/content/browser/loader/OWNERS @@ -1,6 +1,7 @@ csharrison@chromium.org mmenke@chromium.org rdsmith@chromium.org +yhirano@chromium.org # TEAM: net-dev@chromium.org # COMPONENT: Internals>Network diff --git a/chromium/content/browser/loader/async_resource_handler.cc b/chromium/content/browser/loader/async_resource_handler.cc index a9b2e0e78c2..c8c8dd04203 100644 --- a/chromium/content/browser/loader/async_resource_handler.cc +++ b/chromium/content/browser/loader/async_resource_handler.cc @@ -25,8 +25,8 @@ #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/loader/upload_progress_tracker.h" #include "content/common/resource_messages.h" -#include "content/common/resource_request_completion_status.h" #include "content/common/view_messages.h" +#include "content/public/common/resource_request_completion_status.h" #include "content/public/common/resource_response.h" #include "ipc/ipc_message_macros.h" #include "net/base/io_buffer.h" diff --git a/chromium/content/browser/loader/async_resource_handler_unittest.cc b/chromium/content/browser/loader/async_resource_handler_unittest.cc index d9d65651b62..53184f2ac02 100644 --- a/chromium/content/browser/loader/async_resource_handler_unittest.cc +++ b/chromium/content/browser/loader/async_resource_handler_unittest.cc @@ -29,11 +29,11 @@ #include "content/browser/loader/resource_message_filter.h" #include "content/browser/loader/resource_request_info_impl.h" #include "content/common/resource_messages.h" -#include "content/common/resource_request.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/content_features.h" #include "content/public/common/previews_state.h" +#include "content/public/common/resource_request.h" #include "content/public/common/resource_type.h" #include "content/public/test/mock_resource_context.h" #include "content/public/test/test_browser_thread_bundle.h" diff --git a/chromium/content/browser/loader/downloaded_temp_file_impl.h b/chromium/content/browser/loader/downloaded_temp_file_impl.h index 160511b2ac5..0ef0231b2fb 100644 --- a/chromium/content/browser/loader/downloaded_temp_file_impl.h +++ b/chromium/content/browser/loader/downloaded_temp_file_impl.h @@ -7,7 +7,7 @@ #include "base/macros.h" #include "content/common/content_export.h" -#include "content/common/url_loader_factory.mojom.h" +#include "content/public/common/url_loader_factory.mojom.h" namespace content { diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc index 11adad47047..20d09f512da 100644 --- a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc +++ b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc @@ -22,6 +22,7 @@ #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/loader/stream_resource_handler.h" +#include "content/common/loader_util.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/download_item.h" #include "content/public/browser/download_save_info.h" @@ -194,7 +195,9 @@ void MimeSniffingResourceHandler::OnResponseStarted( // the response, and so must be skipped for 304 responses. if (!(response_->head.headers.get() && response_->head.headers->response_code() == 304)) { - if (ShouldSniffContent()) { + // MIME sniffing should be disabled for a request initiated by fetch(). + if (request_context_type_ != REQUEST_CONTEXT_TYPE_FETCH && + ShouldSniffContent(request(), response_.get())) { controller->Resume(); return; } @@ -425,34 +428,6 @@ void MimeSniffingResourceHandler::ReplayReadCompleted() { base::MakeUnique<Controller>(this)); } -bool MimeSniffingResourceHandler::ShouldSniffContent() { - if (request_context_type_ == REQUEST_CONTEXT_TYPE_FETCH) { - // MIME sniffing should be disabled for a request initiated by fetch(). - return false; - } - - const std::string& mime_type = response_->head.mime_type; - - std::string content_type_options; - request()->GetResponseHeaderByName("x-content-type-options", - &content_type_options); - - bool sniffing_blocked = - base::LowerCaseEqualsASCII(content_type_options, "nosniff"); - bool we_would_like_to_sniff = - net::ShouldSniffMimeType(request()->url(), mime_type); - - if (!sniffing_blocked && we_would_like_to_sniff) { - // We're going to look at the data before deciding what the content type - // is. That means we need to delay sending the ResponseStarted message - // over the IPC channel. - VLOG(1) << "To buffer: " << request()->url().spec(); - return true; - } - - return false; -} - bool MimeSniffingResourceHandler::MaybeStartInterception() { if (!CanBeIntercepted()) return true; @@ -545,10 +520,8 @@ bool MimeSniffingResourceHandler::CheckForPluginHandler( std::unique_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream( plugin_path, request(), response_.get(), &payload)); if (handler) { - if (!CheckResponseIsNotProvisional()) { - Cancel(); + if (!CheckResponseIsNotProvisional()) return false; - } *handled_by_plugin = true; intercepting_handler_->UseNewHandler(std::move(handler), payload); } @@ -577,7 +550,7 @@ bool MimeSniffingResourceHandler::CheckResponseIsNotProvisional() { // download. // TODO(abarth): We should abstract the response_code test, but this kind // of check is scattered throughout our codebase. - request()->CancelWithError(net::ERR_INVALID_RESPONSE); + CancelWithError(net::ERR_INVALID_RESPONSE); return false; } diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler.h b/chromium/content/browser/loader/mime_sniffing_resource_handler.h index 21200938cb7..c9b490bb19c 100644 --- a/chromium/content/browser/loader/mime_sniffing_resource_handler.h +++ b/chromium/content/browser/loader/mime_sniffing_resource_handler.h @@ -130,10 +130,6 @@ class CONTENT_EXPORT MimeSniffingResourceHandler // -------------------------------------------------------------------------- - // Whether the response body should be sniffed in order to determine the MIME - // type of the response. - bool ShouldSniffContent(); - // Checks whether this request should be intercepted as a stream or a // download. If this is the case, sets up the new ResourceHandler that will be // used for interception. @@ -173,7 +169,7 @@ class CONTENT_EXPORT MimeSniffingResourceHandler bool must_download_; bool must_download_is_set_; - // Used to buffer the reponse received until replay. + // Used to buffer the response received until replay. scoped_refptr<ResourceResponse> response_; scoped_refptr<net::IOBuffer> read_buffer_; int read_buffer_size_; diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.cc b/chromium/content/browser/loader/mojo_async_resource_handler.cc index 7ec6e4a6973..1a84825e28f 100644 --- a/chromium/content/browser/loader/mojo_async_resource_handler.cc +++ b/chromium/content/browser/loader/mojo_async_resource_handler.cc @@ -23,8 +23,8 @@ #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/loader/resource_scheduler.h" #include "content/browser/loader/upload_progress_tracker.h" -#include "content/common/resource_request_completion_status.h" #include "content/public/browser/global_request_id.h" +#include "content/public/common/resource_request_completion_status.h" #include "content/public/common/resource_response.h" #include "mojo/public/c/system/data_pipe.h" #include "mojo/public/cpp/bindings/message.h" diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.h b/chromium/content/browser/loader/mojo_async_resource_handler.h index bbe3370c67a..e139f123028 100644 --- a/chromium/content/browser/loader/mojo_async_resource_handler.h +++ b/chromium/content/browser/loader/mojo_async_resource_handler.h @@ -16,8 +16,8 @@ #include "content/browser/loader/resource_handler.h" #include "content/browser/loader/upload_progress_tracker.h" #include "content/common/content_export.h" -#include "content/common/url_loader.mojom.h" #include "content/public/common/resource_type.h" +#include "content/public/common/url_loader.mojom.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/simple_watcher.h" diff --git a/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc b/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc index 906c85fe5e2..d6bf4cba787 100644 --- a/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc +++ b/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc @@ -23,10 +23,6 @@ #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/loader/resource_scheduler.h" -#include "content/browser/loader/test_url_loader_client.h" -#include "content/common/resource_request_completion_status.h" -#include "content/common/url_loader.mojom.h" -#include "content/common/url_loader_factory.mojom.h" #include "content/public/browser/appcache_service.h" #include "content/public/browser/navigation_data.h" #include "content/public/browser/resource_context.h" @@ -34,10 +30,14 @@ #include "content/public/browser/resource_throttle.h" #include "content/public/browser/stream_info.h" #include "content/public/common/previews_state.h" +#include "content/public/common/resource_request_completion_status.h" #include "content/public/common/resource_response.h" #include "content/public/common/resource_type.h" +#include "content/public/common/url_loader.mojom.h" +#include "content/public/common/url_loader_factory.mojom.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_url_loader_client.h" #include "mojo/public/c/system/data_pipe.h" #include "mojo/public/c/system/types.h" #include "mojo/public/cpp/bindings/strong_binding.h" @@ -180,9 +180,9 @@ class TestResourceDispatcherHostDelegate final ADD_FAILURE() << "RequestComplete should not be called."; } - PreviewsState GetPreviewsState( - const net::URLRequest& url_request, - content::ResourceContext* resource_context) override { + PreviewsState GetPreviewsState(const net::URLRequest& url_request, + content::ResourceContext* resource_context, + PreviewsState previews_to_allow) override { ADD_FAILURE() << "GetPreviewsState should not be called."; return PREVIEWS_UNSPECIFIED; } @@ -296,7 +296,9 @@ class TestURLLoaderFactory final : public mojom::URLLoaderFactory { int32_t request_id, uint32_t options, const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client_ptr) override { + mojom::URLLoaderClientPtr client_ptr, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override { loader_request_ = std::move(request); client_ptr_ = std::move(client_ptr); } @@ -360,7 +362,8 @@ class MojoAsyncResourceHandlerTestBase { url_loader_factory_->CreateLoaderAndStart( mojo::MakeRequest(&url_loader_proxy_), kRouteId, kRequestId, mojom::kURLLoadOptionNone, request, - url_loader_client_.CreateInterfacePtr()); + url_loader_client_.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); url_loader_factory_.FlushForTesting(); DCHECK(weak_binding); diff --git a/chromium/content/browser/loader/navigation_resource_throttle.cc b/chromium/content/browser/loader/navigation_resource_throttle.cc index dcdceaea91c..0d791612af2 100644 --- a/chromium/content/browser/loader/navigation_resource_throttle.cc +++ b/chromium/content/browser/loader/navigation_resource_throttle.cc @@ -93,8 +93,7 @@ void CheckWillStartRequestOnUIThread( int render_process_id, int render_frame_host_id, const std::string& method, - const scoped_refptr<content::ResourceRequestBodyImpl>& - resource_request_body, + const scoped_refptr<content::ResourceRequestBody>& resource_request_body, const Referrer& sanitized_referrer, bool has_user_gesture, ui::PageTransition transition, @@ -135,7 +134,7 @@ void CheckWillRedirectRequestOnUIThread( ->FilterURL(false, &new_validated_url); navigation_handle->WillRedirectRequest( new_validated_url, new_method, new_referrer_url, new_is_external_protocol, - headers, connection_info, + headers, connection_info, nullptr, base::Bind(&SendCheckResultToIOThread, callback)); } diff --git a/chromium/content/browser/loader/navigation_url_loader.cc b/chromium/content/browser/loader/navigation_url_loader.cc index cca051b7d28..e12f666dd58 100644 --- a/chromium/content/browser/loader/navigation_url_loader.cc +++ b/chromium/content/browser/loader/navigation_url_loader.cc @@ -13,7 +13,7 @@ #include "content/browser/loader/navigation_url_loader_impl.h" #include "content/browser/loader/navigation_url_loader_network_service.h" #include "content/public/browser/navigation_ui_data.h" -#include "content/public/common/content_switches.h" +#include "content/public/common/content_features.h" namespace content { @@ -32,8 +32,7 @@ std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create( resource_context, storage_partition, std::move(request_info), std::move(navigation_ui_data), service_worker_handle, delegate); } - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableNetworkService)) { + if (base::FeatureList::IsEnabled(features::kNetworkService)) { return base::MakeUnique<NavigationURLLoaderNetworkService>( resource_context, storage_partition, std::move(request_info), std::move(navigation_ui_data), service_worker_handle, appcache_handle, diff --git a/chromium/content/browser/loader/navigation_url_loader_delegate.h b/chromium/content/browser/loader/navigation_url_loader_delegate.h index 8a71b22018b..34723cf4e1c 100644 --- a/chromium/content/browser/loader/navigation_url_loader_delegate.h +++ b/chromium/content/browser/loader/navigation_url_loader_delegate.h @@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "content/common/content_export.h" +#include "content/public/common/url_loader_factory.mojom.h" #include "mojo/public/cpp/system/data_pipe.h" namespace net { @@ -38,6 +39,9 @@ class CONTENT_EXPORT NavigationURLLoaderDelegate { // |body_stream|. |navigation_data| is passed to the NavigationHandle. // If --enable-network-service, then |consumer_handle| will be used, // otherwise |body_stream|. Only one of these will ever be non-null. + // |subresource_url_loader_factory_info| is used in the network service only + // for passing factories which are interested in handling subresource + // requests like AppCache. virtual void OnResponseStarted( const scoped_refptr<ResourceResponse>& response, std::unique_ptr<StreamHandle> body_stream, @@ -46,7 +50,8 @@ class CONTENT_EXPORT NavigationURLLoaderDelegate { std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, - bool is_stream) = 0; + bool is_stream, + mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_info) = 0; // Called if the request fails before receving a response. |net_error| is a // network error code for the failure. |has_stale_copy_in_cache| is true if diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.cc b/chromium/content/browser/loader/navigation_url_loader_impl.cc index b7827ed4cc3..71d0c2cba99 100644 --- a/chromium/content/browser/loader/navigation_url_loader_impl.cc +++ b/chromium/content/browser/loader/navigation_url_loader_impl.cc @@ -101,10 +101,10 @@ void NavigationURLLoaderImpl::NotifyResponseStarted( bool is_stream) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - delegate_->OnResponseStarted(response, std::move(body), - mojo::ScopedDataPipeConsumerHandle(), ssl_status, - std::move(navigation_data), request_id, - is_download, is_stream); + delegate_->OnResponseStarted( + response, std::move(body), mojo::ScopedDataPipeConsumerHandle(), + ssl_status, std::move(navigation_data), request_id, is_download, + is_stream, mojom::URLLoaderFactoryPtrInfo()); } void NavigationURLLoaderImpl::NotifyRequestFailed(bool in_cache, diff --git a/chromium/content/browser/loader/navigation_url_loader_network_service.cc b/chromium/content/browser/loader/navigation_url_loader_network_service.cc index f32156a4074..e925cdc1f39 100644 --- a/chromium/content/browser/loader/navigation_url_loader_network_service.cc +++ b/chromium/content/browser/loader/navigation_url_loader_network_service.cc @@ -9,12 +9,14 @@ #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "content/browser/appcache/appcache_navigation_handle.h" +#include "content/browser/appcache/appcache_request_handler.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/navigation_request_info.h" #include "content/browser/loader/navigation_resource_handler.h" #include "content/browser/loader/navigation_resource_throttle.h" #include "content/browser/loader/navigation_url_loader_delegate.h" +#include "content/browser/loader/url_loader_request_handler.h" #include "content/browser/resource_context_impl.h" #include "content/browser/service_worker/service_worker_navigation_handle.h" #include "content/browser/service_worker/service_worker_navigation_handle_core.h" @@ -24,8 +26,10 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/webui/url_data_manager_backend.h" #include "content/browser/webui/web_ui_url_loader_factory.h" +#include "content/common/throttling_url_loader.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/navigation_data.h" #include "content/public/browser/navigation_ui_data.h" @@ -33,8 +37,11 @@ #include "content/public/browser/stream_handle.h" #include "content/public/common/referrer.h" #include "content/public/common/url_constants.h" +#include "content/public/common/url_loader_factory.mojom.h" #include "net/base/load_flags.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request_context.h" +#include "services/service_manager/public/cpp/connector.h" namespace content { @@ -54,72 +61,252 @@ WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) { return WebContentsImpl::FromFrameTreeNode(frame_tree_node); } -void PrepareNavigationStartOnIO( - std::unique_ptr<ResourceRequest> resource_request, - ResourceContext* resource_context, - ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core, - AppCacheNavigationHandleCore* appcache_handle_core, - NavigationRequestInfo* request_info, - mojom::URLLoaderFactoryPtrInfo factory_from_ui, - scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter, - const base::Callback<WebContents*(void)>& web_contents_getter, - mojom::URLLoaderAssociatedRequest url_loader_request, - mojom::URLLoaderClientPtr url_loader_client_to_pass, - std::unique_ptr<service_manager::Connector> connector) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - const ResourceType resource_type = request_info->is_main_frame - ? RESOURCE_TYPE_MAIN_FRAME - : RESOURCE_TYPE_SUB_FRAME; - - if (resource_request->request_body) { - AttachRequestBodyBlobDataHandles(resource_request->request_body.get(), - resource_context); +net::NetworkTrafficAnnotationTag kTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("navigation_url_loader", R"( + semantics { + sender: "Navigation URL Loader" + description: + "This request is issued by a main frame navigation to fetch the " + "content of the page that is being navigated to." + trigger: + "Navigating Chrome (by clicking on a link, bookmark, history item, " + "using session restore, etc)." + data: + "Arbitrary site-controlled data can be included in the URL, HTTP " + "headers, and request body. Requests may include cookies and " + "site-specific credentials." + destination: WEBSITE + } + policy { + cookies_allowed: true + cookies_store: "user" + setting: "This feature cannot be disabled." + policy_exception_justification: + "Not implemented, without this type of request, Chrome would be " + "unable to navigate to websites." + })"); + +} // namespace + +// Kept around during the lifetime of the navigation request, and is +// responsible for dispatching a ResourceRequest to the appropriate +// URLLoader. In order to get the right URLLoader it builds a vector +// of URLLoaderRequestHandler's and successively calls MaybeCreateLoader +// on each until the request is successfully handled. The same sequence +// may be performed multiple times when redirects happen. +class NavigationURLLoaderNetworkService::URLLoaderRequestController + : public mojom::URLLoaderClient { + public: + URLLoaderRequestController( + std::unique_ptr<ResourceRequest> resource_request, + ResourceContext* resource_context, + scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter, + const base::WeakPtr<NavigationURLLoaderNetworkService>& owner) + : resource_request_(std::move(resource_request)), + resource_context_(resource_context), + default_url_loader_factory_getter_(default_url_loader_factory_getter), + owner_(owner) {} + + ~URLLoaderRequestController() override { + DCHECK_CURRENTLY_ON(BrowserThread::IO); } - mojom::URLLoaderFactoryPtr url_loader_factory_ptr; - if (service_worker_navigation_handle_core) { - RequestContextFrameType frame_type = - request_info->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL - : REQUEST_CONTEXT_FRAME_TYPE_NESTED; - - storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext( - GetChromeBlobStorageContextForResourceContext(resource_context)); - url_loader_factory_ptr = - ServiceWorkerRequestHandler::InitializeForNavigationNetworkService( - *resource_request, resource_context, - service_worker_navigation_handle_core, blob_storage_context, - request_info->begin_params.skip_service_worker, resource_type, - request_info->begin_params.request_context_type, frame_type, - request_info->are_ancestors_secure, - request_info->common_params.post_data, web_contents_getter); + void Start( + ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core, + AppCacheNavigationHandleCore* appcache_handle_core, + std::unique_ptr<NavigationRequestInfo> request_info, + mojom::URLLoaderFactoryPtrInfo factory_for_webui, + const base::Callback<WebContents*(void)>& web_contents_getter, + std::unique_ptr<service_manager::Connector> connector) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + web_contents_getter_ = web_contents_getter; + const ResourceType resource_type = request_info->is_main_frame + ? RESOURCE_TYPE_MAIN_FRAME + : RESOURCE_TYPE_SUB_FRAME; + + if (resource_request_->request_body) { + GetBodyBlobDataHandles(resource_request_->request_body.get(), + resource_context_, &blob_handles_); + } + + // Requests to WebUI scheme won't get redirected to/from other schemes + // or be intercepted, so we just let it go here. + if (factory_for_webui.is_valid()) { + webui_factory_ptr_.Bind(std::move(factory_for_webui)); + url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( + webui_factory_ptr_.get(), + GetContentClient()->browser()->CreateURLLoaderThrottles( + web_contents_getter_), + 0 /* routing_id? */, 0 /* request_id? */, mojom::kURLLoadOptionNone, + *resource_request_, this, kTrafficAnnotation); + return; + } + + DCHECK(handlers_.empty()); + if (service_worker_navigation_handle_core) { + RequestContextFrameType frame_type = + request_info->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL + : REQUEST_CONTEXT_FRAME_TYPE_NESTED; + + storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext( + GetChromeBlobStorageContextForResourceContext(resource_context_)); + std::unique_ptr<URLLoaderRequestHandler> service_worker_handler = + ServiceWorkerRequestHandler::InitializeForNavigationNetworkService( + *resource_request_, resource_context_, + service_worker_navigation_handle_core, blob_storage_context, + request_info->begin_params.skip_service_worker, resource_type, + request_info->begin_params.request_context_type, frame_type, + request_info->are_ancestors_secure, + request_info->common_params.post_data, web_contents_getter); + if (service_worker_handler) + handlers_.push_back(std::move(service_worker_handler)); + } + + if (appcache_handle_core) { + std::unique_ptr<URLLoaderRequestHandler> appcache_handler = + AppCacheRequestHandler::InitializeForNavigationNetworkService( + *resource_request_, appcache_handle_core, + default_url_loader_factory_getter_.get()); + if (appcache_handler) + handlers_.push_back(std::move(appcache_handler)); + } + + Restart(); } - // If we haven't gotten one from the above, then use the one the UI thread - // gave us, or otherwise fallback to the default. - mojom::URLLoaderFactory* factory; - if (url_loader_factory_ptr) { - factory = url_loader_factory_ptr.get(); - } else { - if (factory_from_ui.is_valid()) { - url_loader_factory_ptr.Bind(std::move(factory_from_ui)); - factory = url_loader_factory_ptr.get(); - } else { - if (appcache_handle_core) { - factory = url_loader_factory_getter->GetAppCacheFactory()->get(); - } else { - factory = url_loader_factory_getter->GetNetworkFactory()->get(); + // This could be called multiple times. + void Restart() { + handler_index_ = 0; + MaybeStartLoader(StartLoaderCallback()); + } + + void MaybeStartLoader(StartLoaderCallback start_loader_callback) { + if (start_loader_callback) { + url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( + std::move(start_loader_callback), + GetContentClient()->browser()->CreateURLLoaderThrottles( + web_contents_getter_), + *resource_request_, this, kTrafficAnnotation); + + DCHECK_GT(handler_index_, 0U); + + mojom::URLLoaderFactoryPtr subresource_loader_factory = + handlers_[handler_index_ - 1]->MaybeCreateSubresourceFactory(); + if (subresource_loader_factory.get()) { + subresource_url_loader_factory_ptr_info_ = + subresource_loader_factory.PassInterface(); } + return; + } + + if (handler_index_ < handlers_.size()) { + handlers_[handler_index_++]->MaybeCreateLoader( + *resource_request_, resource_context_, + base::BindOnce(&URLLoaderRequestController::MaybeStartLoader, + base::Unretained(this))); + return; + } + + mojom::URLLoaderFactory* factory = nullptr; + DCHECK_EQ(handlers_.size(), handler_index_); + if (resource_request_->url.SchemeIs(url::kBlobScheme)) { + factory = default_url_loader_factory_getter_->GetBlobFactory()->get(); + } else { + factory = default_url_loader_factory_getter_->GetNetworkFactory()->get(); } + url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( + factory, + GetContentClient()->browser()->CreateURLLoaderThrottles( + web_contents_getter_), + 0 /* routing_id? */, 0 /* request_id? */, + mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType, + *resource_request_, this, kTrafficAnnotation); } - factory->CreateLoaderAndStart( - std::move(url_loader_request), 0 /* routing_id? */, 0 /* request_id? */, - mojom::kURLLoadOptionSendSSLInfo, *resource_request, - std::move(url_loader_client_to_pass)); -} + void FollowRedirect() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(url_loader_); -} // namespace + url_loader_->FollowRedirect(); + } + + // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the + // caller. + mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() { + return std::move(subresource_url_loader_factory_ptr_info_); + } + + private: + // mojom::URLLoaderClient implementation: + void OnReceiveResponse( + const ResourceResponseHead& head, + const base::Optional<net::SSLInfo>& ssl_info, + mojom::DownloadedTempFilePtr downloaded_file) override { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse, + owner_, head, ssl_info, base::Passed(&downloaded_file))); + } + + void OnReceiveRedirect(const net::RedirectInfo& redirect_info, + const ResourceResponseHead& head) override { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect, + owner_, redirect_info, head)); + } + + void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {} + + void OnUploadProgress(int64_t current_position, + int64_t total_size, + OnUploadProgressCallback callback) override {} + + void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} + + void OnTransferSizeUpdated(int32_t transfer_size_diff) override {} + + void OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) override { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind( + &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody, + owner_, base::Passed(&body))); + } + + void OnComplete( + const ResourceRequestCompletionStatus& completion_status) override { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_, + completion_status)); + } + + std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_; + size_t handler_index_ = 0; + + std::unique_ptr<ResourceRequest> resource_request_; + ResourceContext* resource_context_; + base::Callback<WebContents*()> web_contents_getter_; + + scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_; + + mojom::URLLoaderFactoryPtr webui_factory_ptr_; + + std::unique_ptr<ThrottlingURLLoader> url_loader_; + + BlobHandles blob_handles_; + + // Currently used by the AppCache loader to pass its factory to the + // renderer which enables it to handle subresources. + mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_; + + // This is referenced only on the UI thread. + base::WeakPtr<NavigationURLLoaderNetworkService> owner_; + + DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); +}; NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( ResourceContext* resource_context, @@ -129,36 +316,34 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( ServiceWorkerNavigationHandle* service_worker_navigation_handle, AppCacheNavigationHandle* appcache_handle, NavigationURLLoaderDelegate* delegate) - : delegate_(delegate), - binding_(this), - request_info_(std::move(request_info)) { + : delegate_(delegate), weak_factory_(this) { DCHECK_CURRENTLY_ON(BrowserThread::UI); TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( "navigation", "Navigation timeToResponseStarted", this, - request_info_->common_params.navigation_start, "FrameTreeNode id", - request_info_->frame_tree_node_id); + request_info->common_params.navigation_start, "FrameTreeNode id", + request_info->frame_tree_node_id); // TODO(scottmg): Port over stuff from RDHI::BeginNavigationRequest() here. auto new_request = base::MakeUnique<ResourceRequest>(); - new_request->method = request_info_->common_params.method; - new_request->url = request_info_->common_params.url; - new_request->first_party_for_cookies = request_info_->first_party_for_cookies; + new_request->method = request_info->common_params.method; + new_request->url = request_info->common_params.url; + new_request->first_party_for_cookies = request_info->first_party_for_cookies; new_request->priority = net::HIGHEST; // The code below to set fields like request_initiator, referrer, etc has // been copied from ResourceDispatcherHostImpl. We did not refactor the // common code into a function, because RDHI uses accessor functions on the // URLRequest class to set these fields. whereas we use ResourceRequest here. - new_request->request_initiator = request_info_->begin_params.initiator_origin; - new_request->referrer = request_info_->common_params.referrer.url; - new_request->referrer_policy = request_info_->common_params.referrer.policy; - new_request->headers = request_info_->begin_params.headers; + new_request->request_initiator = request_info->begin_params.initiator_origin; + new_request->referrer = request_info->common_params.referrer.url; + new_request->referrer_policy = request_info->common_params.referrer.policy; + new_request->headers = request_info->begin_params.headers; - int load_flags = request_info_->begin_params.load_flags; + int load_flags = request_info->begin_params.load_flags; load_flags |= net::LOAD_VERIFY_EV_CERT; - if (request_info_->is_main_frame) + if (request_info->is_main_frame) load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED; // Sync loads should have maximum priority and should be the only @@ -167,50 +352,55 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( new_request->load_flags = load_flags; - new_request->request_body = request_info_->common_params.post_data.get(); + new_request->request_body = request_info->common_params.post_data.get(); - mojom::URLLoaderAssociatedRequest loader_associated_request = - mojo::MakeRequest(&url_loader_associated_ptr_); - mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; - binding_.Bind(mojo::MakeRequest(&url_loader_client_ptr_to_pass)); + int frame_tree_node_id = request_info->frame_tree_node_id; // Check if a web UI scheme wants to handle this request. - mojom::URLLoaderFactoryPtrInfo factory_ptr_info; - + mojom::URLLoaderFactoryPtrInfo factory_for_webui; const auto& schemes = URLDataManagerBackend::GetWebUISchemes(); if (std::find(schemes.begin(), schemes.end(), new_request->url.scheme()) != schemes.end()) { FrameTreeNode* frame_tree_node = - FrameTreeNode::GloballyFindByID(request_info_->frame_tree_node_id); - factory_ptr_info = GetWebUIURLLoader(frame_tree_node).PassInterface(); + FrameTreeNode::GloballyFindByID(frame_tree_node_id); + factory_for_webui = CreateWebUIURLLoader(frame_tree_node).PassInterface(); } g_next_request_id--; + DCHECK(!request_controller_); + request_controller_ = base::MakeUnique<URLLoaderRequestController>( + std::move(new_request), resource_context, + static_cast<StoragePartitionImpl*>(storage_partition) + ->url_loader_factory_getter(), + weak_factory_.GetWeakPtr()); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&PrepareNavigationStartOnIO, - base::Passed(std::move(new_request)), resource_context, - service_worker_navigation_handle - ? service_worker_navigation_handle->core() - : nullptr, - appcache_handle ? appcache_handle->core() : nullptr, - request_info_.get(), base::Passed(std::move(factory_ptr_info)), - static_cast<StoragePartitionImpl*>(storage_partition) - ->url_loader_factory_getter(), - base::Bind(&GetWebContentsFromFrameTreeNodeID, - request_info_->frame_tree_node_id), - base::Passed(std::move(loader_associated_request)), - base::Passed(std::move(url_loader_client_ptr_to_pass)), - base::Passed(ServiceManagerConnection::GetForProcess() - ->GetConnector() - ->Clone()))); + base::Bind( + &URLLoaderRequestController::Start, + base::Unretained(request_controller_.get()), + service_worker_navigation_handle + ? service_worker_navigation_handle->core() + : nullptr, + appcache_handle ? appcache_handle->core() : nullptr, + base::Passed(std::move(request_info)), + base::Passed(std::move(factory_for_webui)), + base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id), + base::Passed(ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->Clone()))); } -NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {} +NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() { + BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, + request_controller_.release()); +} void NavigationURLLoaderNetworkService::FollowRedirect() { - url_loader_associated_ptr_->FollowRedirect(); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&URLLoaderRequestController::FollowRedirect, + base::Unretained(request_controller_.get()))); } void NavigationURLLoaderNetworkService::ProceedWithResponse() {} @@ -220,7 +410,7 @@ void NavigationURLLoaderNetworkService::OnReceiveResponse( const base::Optional<net::SSLInfo>& ssl_info, mojom::DownloadedTempFilePtr downloaded_file) { // TODO(scottmg): This needs to do more of what - // NavigationResourceHandler::OnReponseStarted() does. Or maybe in + // NavigationResourceHandler::OnResponseStarted() does. Or maybe in // OnStartLoadingResponseBody(). if (ssl_info && ssl_info->cert) NavigationResourceHandler::GetSSLStatusForRequest(*ssl_info, &ssl_status_); @@ -232,26 +422,13 @@ void NavigationURLLoaderNetworkService::OnReceiveRedirect( const net::RedirectInfo& redirect_info, const ResourceResponseHead& head) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(kinuko): Perform the necessary check and call + // URLLoaderRequestController::Restart with the new URL?? scoped_refptr<ResourceResponse> response(new ResourceResponse()); response->head = head; delegate_->OnRequestRedirected(redirect_info, response); } -void NavigationURLLoaderNetworkService::OnDataDownloaded( - int64_t data_length, - int64_t encoded_length) {} - -void NavigationURLLoaderNetworkService::OnUploadProgress( - int64_t current_position, - int64_t total_size, - OnUploadProgressCallback callback) {} - -void NavigationURLLoaderNetworkService::OnReceiveCachedMetadata( - const std::vector<uint8_t>& data) {} - -void NavigationURLLoaderNetworkService::OnTransferSizeUpdated( - int32_t transfer_size_diff) {} - void NavigationURLLoaderNetworkService::OnStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle body) { DCHECK(response_); @@ -263,10 +440,11 @@ void NavigationURLLoaderNetworkService::OnStartLoadingResponseBody( // Temporarily, we pass both a stream (null) and the data pipe to the // delegate until PlzNavigate has shipped and we can be comfortable fully // switching to the data pipe. - delegate_->OnResponseStarted(response_, nullptr, std::move(body), ssl_status_, - std::unique_ptr<NavigationData>(), - GlobalRequestID(-1, g_next_request_id), - false /* is_download? */, false /* is_stream */); + delegate_->OnResponseStarted( + response_, nullptr, std::move(body), ssl_status_, + std::unique_ptr<NavigationData>(), GlobalRequestID(-1, g_next_request_id), + false /* is_download? */, false /* is_stream */, + request_controller_->GetSubresourceURLLoaderFactory()); } void NavigationURLLoaderNetworkService::OnComplete( diff --git a/chromium/content/browser/loader/navigation_url_loader_network_service.h b/chromium/content/browser/loader/navigation_url_loader_network_service.h index 9e7af001a1c..c15a4dade7c 100644 --- a/chromium/content/browser/loader/navigation_url_loader_network_service.h +++ b/chromium/content/browser/loader/navigation_url_loader_network_service.h @@ -6,12 +6,10 @@ #define CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_NETWORK_SERVICE_H_ #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "content/browser/loader/navigation_url_loader.h" -#include "content/common/url_loader.mojom.h" -#include "content/common/url_loader_factory.mojom.h" #include "content/public/browser/ssl_status.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/service_manager/public/cpp/connector.h" +#include "content/public/common/url_loader.mojom.h" namespace net { struct RedirectInfo; @@ -24,8 +22,7 @@ class NavigationPostDataHandler; // This is an implementation of NavigationURLLoader used when // --enable-network-service is used. -class NavigationURLLoaderNetworkService : public NavigationURLLoader, - public mojom::URLLoaderClient { +class NavigationURLLoaderNetworkService : public NavigationURLLoader { public: // The caller is responsible for ensuring that |delegate| outlives the loader. NavigationURLLoaderNetworkService( @@ -42,32 +39,27 @@ class NavigationURLLoaderNetworkService : public NavigationURLLoader, void FollowRedirect() override; void ProceedWithResponse() override; - // mojom::URLLoaderClient implementation: void OnReceiveResponse(const ResourceResponseHead& head, const base::Optional<net::SSLInfo>& ssl_info, - mojom::DownloadedTempFilePtr downloaded_file) override; + mojom::DownloadedTempFilePtr downloaded_file); void OnReceiveRedirect(const net::RedirectInfo& redirect_info, - const ResourceResponseHead& head) override; - void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override; - void OnUploadProgress(int64_t current_position, - int64_t total_size, - OnUploadProgressCallback callback) override; - void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override; - void OnTransferSizeUpdated(int32_t transfer_size_diff) override; - void OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) override; - void OnComplete( - const ResourceRequestCompletionStatus& completion_status) override; + const ResourceResponseHead& head); + void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body); + void OnComplete(const ResourceRequestCompletionStatus& completion_status); private: + class URLLoaderRequestController; + NavigationURLLoaderDelegate* delegate_; - mojo::Binding<mojom::URLLoaderClient> binding_; - std::unique_ptr<NavigationRequestInfo> request_info_; - mojom::URLLoaderAssociatedPtr url_loader_associated_ptr_; scoped_refptr<ResourceResponse> response_; SSLStatus ssl_status_; + // Lives on the IO thread. + std::unique_ptr<URLLoaderRequestController> request_controller_; + + base::WeakPtrFactory<NavigationURLLoaderNetworkService> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(NavigationURLLoaderNetworkService); }; diff --git a/chromium/content/browser/loader/netlog_observer.cc b/chromium/content/browser/loader/netlog_observer.cc index 0dc79f3a1e9..ed30d3d35af 100644 --- a/chromium/content/browser/loader/netlog_observer.cc +++ b/chromium/content/browser/loader/netlog_observer.cc @@ -167,7 +167,7 @@ void NetLogObserver::Attach(net::NetLog* net_log) { io_thread_checker_.Get().reset(new base::ThreadChecker()); if (net_log) { instance_ = new NetLogObserver(); - net_log->DeprecatedAddObserver( + net_log->AddObserver( instance_, net::NetLogCaptureMode::IncludeCookiesAndCredentials()); } } @@ -179,7 +179,7 @@ void NetLogObserver::Detach() { if (instance_) { // Safest not to do this in the destructor to maintain thread safety across // refactorings. - instance_->net_log()->DeprecatedRemoveObserver(instance_); + instance_->net_log()->RemoveObserver(instance_); delete instance_; instance_ = NULL; } diff --git a/chromium/content/browser/loader/reload_cache_control_browsertest.cc b/chromium/content/browser/loader/reload_cache_control_browsertest.cc index 148436d3f99..5951cd3d212 100644 --- a/chromium/content/browser/loader/reload_cache_control_browsertest.cc +++ b/chromium/content/browser/loader/reload_cache_control_browsertest.cc @@ -28,8 +28,6 @@ using net::test_server::HttpRequest; using net::test_server::HttpResponse; const char kReloadTestPath[] = "/loader/reload_test.html"; -const char kReloadFramePath[] = "/loader/simple_frame.html"; -const char kReloadImagePath[] = "/loader/empty16x16.png"; // The test page should request resources as the content structure is described // below. Reload and the same page navigation will affect only the top frame // resource, reload_test.html. But bypassing reload will affect all resources. @@ -47,6 +45,18 @@ struct RequestLog { std::string cache_control; }; +struct ExpectedCacheControl { + const char* top_main; + const char* others; +}; + +const ExpectedCacheControl kExpectedCacheControlForNormalLoad = { + kNoCacheControl, kNoCacheControl}; +const ExpectedCacheControl kExpectedCacheControlForReload = { + kMaxAgeCacheControl, kNoCacheControl}; +const ExpectedCacheControl kExpectedCacheControlForBypassingReload = { + kNoCacheCacheControl, kNoCacheCacheControl}; + // Tests end to end behaviors between Blink and content around reload variants. class ReloadCacheControlBrowserTest : public ContentBrowserTest { protected: @@ -70,6 +80,18 @@ class ReloadCacheControlBrowserTest : public ContentBrowserTest { } protected: + void CheckCacheControl(const ExpectedCacheControl& expectation) { + base::AutoLock lock(request_log_lock_); + EXPECT_EQ(4u, request_log_.size()); + for (const auto& log : request_log_) { + if (log.relative_url == kReloadTestPath) + EXPECT_EQ(expectation.top_main, log.cache_control); + else + EXPECT_EQ(expectation.others, log.cache_control); + } + request_log_.clear(); + } + std::vector<RequestLog> request_log_; base::Lock request_log_lock_; @@ -93,139 +115,37 @@ IN_PROC_BROWSER_TEST_F(ReloadCacheControlBrowserTest, NormalReload) { GURL url(embedded_test_server()->GetURL(kReloadTestPath)); EXPECT_TRUE(NavigateToURL(shell(), url)); - ReloadBlockUntilNavigationsComplete(shell(), 1); + CheckCacheControl(kExpectedCacheControlForNormalLoad); - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(8UL, request_log_.size()); - EXPECT_EQ(kReloadTestPath, request_log_[0].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[0].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[1].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[1].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[2].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[2].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[3].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[3].cache_control); - - // Only the top main resource should be requested with kMaxAgeCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[4].relative_url); - EXPECT_EQ(kMaxAgeCacheControl, request_log_[4].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[5].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[5].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[6].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[6].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[7].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[7].cache_control); - } + ReloadBlockUntilNavigationsComplete(shell(), 1); + CheckCacheControl(kExpectedCacheControlForReload); shell()->ShowDevTools(); ReloadBlockUntilNavigationsComplete(shell(), 1); - - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(12UL, request_log_.size()); - - // Only the top main resource should be requested with kMaxAgeCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[8].relative_url); - EXPECT_EQ(kMaxAgeCacheControl, request_log_[8].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[9].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[9].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[10].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[10].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[11].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[11].cache_control); - } + CheckCacheControl(kExpectedCacheControlForReload); shell()->CloseDevTools(); ReloadBlockUntilNavigationsComplete(shell(), 1); - - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(16UL, request_log_.size()); - - // Only the top main resource should be requested with kMaxAgeCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[12].relative_url); - EXPECT_EQ(kMaxAgeCacheControl, request_log_[12].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[13].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[13].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[14].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[14].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[15].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[15].cache_control); - } + CheckCacheControl(kExpectedCacheControlForReload); } // Test if bypassing reload issues requests with proper cache control flags. IN_PROC_BROWSER_TEST_F(ReloadCacheControlBrowserTest, BypassingReload) { - GURL url(embedded_test_server()->GetURL(kReloadTestPath)); NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1); - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(4UL, request_log_.size()); - - EXPECT_EQ(kReloadTestPath, request_log_[0].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[0].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[1].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[1].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[2].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[2].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[3].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[3].cache_control); - } + CheckCacheControl(kExpectedCacheControlForNormalLoad); ReloadBypassingCacheBlockUntilNavigationsComplete(shell(), 1); - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(8UL, request_log_.size()); - - // Only the top main resource should be requested with kNoCacheCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[4].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[4].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[5].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[5].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[6].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[6].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[7].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[7].cache_control); - } + CheckCacheControl(kExpectedCacheControlForBypassingReload); shell()->ShowDevTools(); ReloadBypassingCacheBlockUntilNavigationsComplete(shell(), 1); - - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(12UL, request_log_.size()); - - // All resources should be requested with kNoCacheCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[8].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[8].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[9].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[9].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[10].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[10].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[11].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[11].cache_control); - } + CheckCacheControl(kExpectedCacheControlForBypassingReload); shell()->CloseDevTools(); ReloadBypassingCacheBlockUntilNavigationsComplete(shell(), 1); - - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(16UL, request_log_.size()); - - // All resources should be requested with kNoCacheCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[12].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[12].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[13].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[13].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[14].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[14].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[15].relative_url); - EXPECT_EQ(kNoCacheCacheControl, request_log_[15].cache_control); - } + CheckCacheControl(kExpectedCacheControlForBypassingReload); } // Test if the same page navigation issues requests with proper cache control @@ -233,75 +153,23 @@ IN_PROC_BROWSER_TEST_F(ReloadCacheControlBrowserTest, BypassingReload) { IN_PROC_BROWSER_TEST_F(ReloadCacheControlBrowserTest, NavigateToSame) { GURL url(embedded_test_server()->GetURL(kReloadTestPath)); - EXPECT_TRUE(NavigateToURL(shell(), url)); - EXPECT_TRUE(NavigateToURL(shell(), url)); - // The first navigation is just a normal load. - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(8UL, request_log_.size()); - EXPECT_EQ(kReloadTestPath, request_log_[0].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[0].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[1].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[1].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[2].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[3].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[3].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[3].cache_control); - } + EXPECT_TRUE(NavigateToURL(shell(), url)); + CheckCacheControl(kExpectedCacheControlForNormalLoad); // The second navigation is the same page navigation. This should be handled // as a reload, revalidating the main resource, but following cache protocols // for others. - { - base::AutoLock lock(request_log_lock_); - - // Only the top main resource should be requested with kMaxAgeCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[4].relative_url); - EXPECT_EQ(kMaxAgeCacheControl, request_log_[4].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[5].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[5].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[6].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[6].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[7].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[7].cache_control); - } + EXPECT_TRUE(NavigateToURL(shell(), url)); + CheckCacheControl(kExpectedCacheControlForReload); shell()->ShowDevTools(); EXPECT_TRUE(NavigateToURL(shell(), url)); - - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(12UL, request_log_.size()); - - // Only the top main resource should be requested with kMaxAgeCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[8].relative_url); - EXPECT_EQ(kMaxAgeCacheControl, request_log_[8].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[9].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[9].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[10].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[10].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[11].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[11].cache_control); - } + CheckCacheControl(kExpectedCacheControlForReload); shell()->CloseDevTools(); EXPECT_TRUE(NavigateToURL(shell(), url)); - - { - base::AutoLock lock(request_log_lock_); - ASSERT_EQ(16UL, request_log_.size()); - - // Only the top main resource should be requested with kMaxAgeCacheControl. - EXPECT_EQ(kReloadTestPath, request_log_[12].relative_url); - EXPECT_EQ(kMaxAgeCacheControl, request_log_[12].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[13].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[13].cache_control); - EXPECT_EQ(kReloadFramePath, request_log_[14].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[14].cache_control); - EXPECT_EQ(kReloadImagePath, request_log_[15].relative_url); - EXPECT_EQ(kNoCacheControl, request_log_[15].cache_control); - } + CheckCacheControl(kExpectedCacheControlForReload); } } // namespace diff --git a/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc b/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc index 806df8c3191..cbec7a039e2 100644 --- a/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc +++ b/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc @@ -17,7 +17,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" #include "build/build_config.h" #include "content/browser/download/download_manager_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" @@ -38,6 +37,7 @@ #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_content_browser_client.h" #include "content/shell/browser/shell_network_delegate.h" +#include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -62,9 +62,7 @@ class ResourceDispatcherHostBrowserTest : public ContentBrowserTest, base::FilePath path = GetTestFilePath("", ""); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind( - &net::URLRequestMockHTTPJob::AddUrlHandlers, path, - make_scoped_refptr(content::BrowserThread::GetBlockingPool()))); + base::Bind(&net::URLRequestMockHTTPJob::AddUrlHandlers, path)); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&net::URLRequestFailedJob::AddUrlHandler)); @@ -552,8 +550,8 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CookiePolicy) { class PageTransitionResourceDispatcherHostDelegate : public ResourceDispatcherHostDelegate { public: - PageTransitionResourceDispatcherHostDelegate(GURL watch_url) - : watch_url_(watch_url) {} + explicit PageTransitionResourceDispatcherHostDelegate(GURL watch_url) + : watch_url_(watch_url) {} // ResourceDispatcherHostDelegate implementation: void RequestBeginning( @@ -650,7 +648,8 @@ class PreviewsStateResourceDispatcherHostDelegate PreviewsState GetPreviewsState( const net::URLRequest& request, - content::ResourceContext* resource_context) override { + content::ResourceContext* resource_context, + content::PreviewsState previews_to_allow) override { DCHECK_CURRENTLY_ON(BrowserThread::IO); EXPECT_FALSE(should_get_previews_state_called_); should_get_previews_state_called_ = true; @@ -815,15 +814,23 @@ struct RequestDataForDelegate { const GURL url; const GURL first_party; const base::Optional<url::Origin> initiator; + const int load_flags; + const std::string referrer; RequestDataForDelegate(const GURL& url, const GURL& first_party, - const base::Optional<url::Origin>& initiator) - : url(url), first_party(first_party), initiator(initiator) {} + const base::Optional<url::Origin>& initiator, + int load_flags, + const std::string& referrer) + : url(url), + first_party(first_party), + initiator(initiator), + load_flags(load_flags), + referrer(referrer) {} }; // Captures calls to 'RequestBeginning' and records the URL, first-party for -// cookies, and initiator. +// cookies, initiator, load flags, and referrer. class RequestDataResourceDispatcherHostDelegate : public ResourceDispatcherHostDelegate { public: @@ -841,8 +848,8 @@ class RequestDataResourceDispatcherHostDelegate ResourceType resource_type, std::vector<std::unique_ptr<ResourceThrottle>>* throttles) override { requests_.push_back(base::MakeUnique<RequestDataForDelegate>( - request->url(), request->first_party_for_cookies(), - request->initiator())); + request->url(), request->first_party_for_cookies(), request->initiator(), + request->load_flags(), request->referrer())); } void SetDelegate() { ResourceDispatcherHost::Get()->SetDelegate(this); } @@ -912,6 +919,36 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, Basic) { } IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, + LinkRelPrefetch) { + GURL top_url(embedded_test_server()->GetURL("/link_rel_prefetch.html")); + url::Origin top_origin(top_url); + + NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); + + EXPECT_EQ(2u, delegate_->data().size()); + auto* request = delegate_->data()[1].get(); + EXPECT_EQ(top_origin, request->initiator); + EXPECT_EQ(top_url, request->referrer); + EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH); +} + +IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, + LinkRelPrefetchReferrerPolicy) { + GURL top_url(embedded_test_server()->GetURL( + "/link_rel_prefetch_referrer_policy.html")); + url::Origin top_origin(top_url); + + NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); + + EXPECT_EQ(2u, delegate_->data().size()); + auto* request = delegate_->data()[1].get(); + EXPECT_EQ(top_origin, request->initiator); + // Respect the "origin" policy set by the <meta> tag. + EXPECT_EQ(top_url.GetOrigin().spec(), request->referrer); + EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH); +} + +IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, BasicCrossSite) { GURL top_url(embedded_test_server()->GetURL( "a.com", "/nested_page_with_subresources.html")); diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc index a4b99cdddfb..efbdb38552a 100644 --- a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc @@ -32,6 +32,8 @@ #include "base/profiler/scoped_tracker.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" #include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/threading/thread_task_runner_handle.h" #include "base/timer/timer.h" @@ -39,7 +41,7 @@ #include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/appcache/chrome_appcache_service.h" #include "content/browser/bad_message.h" -#include "content/browser/blob_storage/chrome_blob_storage_context.h" +#include "content/browser/browsing_data/clear_site_data_throttle.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/frame_host/navigation_request_info.h" #include "content/browser/loader/async_resource_handler.h" @@ -74,9 +76,7 @@ #include "content/browser/streams/stream_registry.h" #include "content/common/net/url_request_service_worker_data.h" #include "content/common/resource_messages.h" -#include "content/common/resource_request.h" -#include "content/common/resource_request_body_impl.h" -#include "content/common/resource_request_completion_status.h" +#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/global_request_id.h" @@ -89,7 +89,9 @@ #include "content/public/browser/stream_info.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_features.h" -#include "content/public/common/content_switches.h" +#include "content/public/common/resource_request.h" +#include "content/public/common/resource_request_body.h" +#include "content/public/common/resource_request_completion_status.h" #include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_start.h" #include "net/base/auth.h" @@ -132,7 +134,8 @@ using SyncLoadResultCallback = namespace { constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation = - net::DefineNetworkTrafficAnnotation("resource_dispather_host", R"( + net::DefineNetworkTrafficAnnotation("resource_dispather_host", + R"( semantics { sender: "Resource Dispatcher Host" description: @@ -141,7 +144,7 @@ constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation = "chrome URLs, resources for installed extensions, as well as " "downloads." trigger: - "Navigating to a URL or downloading a file. A webpage, " + "Navigating to a URL or downloading a file. A webpage, " "ServiceWorker, chrome:// page, or extension may also initiate " "requests in the background." data: "Anything the initiator wants to send." @@ -167,6 +170,9 @@ static ResourceDispatcherHostImpl* g_resource_dispatcher_host; // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates const int kUpdateLoadStatesIntervalMsec = 250; +// The interval for calls to RecordOutstandingRequestsStats. +const int kRecordOutstandingRequestsStatsIntervalSec = 60; + // Maximum byte "cost" of all the outstanding requests for a renderer. // See declaration of |max_outstanding_requests_cost_per_process_| for details. // This bound is 25MB, which allows for around 6000 outstanding requests. @@ -191,60 +197,6 @@ const double kMaxRequestsPerProcessRatio = 0.45; // same resource (see bugs 46104 and 31014). const int kDefaultDetachableCancelDelayMs = 30000; -enum SHA1HistogramTypes { - // SHA-1 is not present in the certificate chain. - SHA1_NOT_PRESENT = 0, - // SHA-1 is present in the certificate chain, and the leaf expires on or - // after January 1, 2017. - SHA1_EXPIRES_AFTER_JANUARY_2017 = 1, - // SHA-1 is present in the certificate chain, and the leaf expires on or - // after June 1, 2016. - SHA1_EXPIRES_AFTER_JUNE_2016 = 2, - // SHA-1 is present in the certificate chain, and the leaf expires on or - // after January 1, 2016. - SHA1_EXPIRES_AFTER_JANUARY_2016 = 3, - // SHA-1 is present in the certificate chain, but the leaf expires before - // January 1, 2016 - SHA1_PRESENT = 4, - // Always keep this at the end. - SHA1_HISTOGRAM_TYPES_MAX, -}; - -void RecordCertificateHistograms(const net::SSLInfo& ssl_info, - ResourceType resource_type) { - // The internal representation of the dates for UI treatment of SHA-1. - // See http://crbug.com/401365 for details - static const int64_t kJanuary2017 = INT64_C(13127702400000000); - static const int64_t kJune2016 = INT64_C(13109213000000000); - static const int64_t kJanuary2016 = INT64_C(13096080000000000); - - SHA1HistogramTypes sha1_histogram = SHA1_NOT_PRESENT; - if (ssl_info.cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT) { - DCHECK(ssl_info.cert.get()); - if (ssl_info.cert->valid_expiry() >= - base::Time::FromInternalValue(kJanuary2017)) { - sha1_histogram = SHA1_EXPIRES_AFTER_JANUARY_2017; - } else if (ssl_info.cert->valid_expiry() >= - base::Time::FromInternalValue(kJune2016)) { - sha1_histogram = SHA1_EXPIRES_AFTER_JUNE_2016; - } else if (ssl_info.cert->valid_expiry() >= - base::Time::FromInternalValue(kJanuary2016)) { - sha1_histogram = SHA1_EXPIRES_AFTER_JANUARY_2016; - } else { - sha1_histogram = SHA1_PRESENT; - } - } - if (resource_type == RESOURCE_TYPE_MAIN_FRAME) { - UMA_HISTOGRAM_ENUMERATION("Net.Certificate.SHA1.MainFrame", - sha1_histogram, - SHA1_HISTOGRAM_TYPES_MAX); - } else { - UMA_HISTOGRAM_ENUMERATION("Net.Certificate.SHA1.Subresource", - sha1_histogram, - SHA1_HISTOGRAM_TYPES_MAX); - } -} - bool IsDetachableResourceType(ResourceType type) { switch (type) { case RESOURCE_TYPE_PREFETCH: @@ -298,14 +250,26 @@ bool IsValidatedSCT( // Returns the PreviewsState after requesting it from the delegate. The // PreviewsState is a bitmask of potentially several Previews optimizations. -PreviewsState GetPreviewsState(PreviewsState previews_state, +// If previews_to_allow is set to anything other than PREVIEWS_UNSPECIFIED, +// it is either the values passed in for a sub-frame to use, or if this is +// the main frame, it is a limitation on which previews to allow. +PreviewsState GetPreviewsState(PreviewsState previews_to_allow, ResourceDispatcherHostDelegate* delegate, const net::URLRequest& request, ResourceContext* resource_context, bool is_main_frame) { - // previews_state is set to PREVIEWS_OFF when reloading with Lo-Fi disabled. - if (previews_state == PREVIEWS_UNSPECIFIED && delegate && is_main_frame) - return delegate->GetPreviewsState(request, resource_context); + // If previews have already been turned off, or we are inheriting values on a + // sub-frame, don't check any further. + if (previews_to_allow & PREVIEWS_OFF || + previews_to_allow & PREVIEWS_NO_TRANSFORM || !is_main_frame || + !delegate) { + return previews_to_allow; + } + + // Get the mask of previews we could apply to the current navigation. + PreviewsState previews_state = + delegate->GetPreviewsState(request, resource_context, previews_to_allow); + return previews_state; } @@ -325,6 +289,42 @@ void HandleSyncLoadResult(base::WeakPtr<ResourceMessageFilter> filter, filter->Send(sync_result.release()); } +// Used to log the cache flags for back-forward navigation requests. +// Because this enum is used to back a histogrma, DO NOT REMOVE OR RENAME VALUES +// in this enum. Instead, add a new one at the end. +// TODO(clamy): Remove this once we know the reason behind PlzNavigate's +// regression on PLT for back forward navigations. +enum HistogramCacheFlag { + HISTOGRAM_VALIDATE_CACHE, + HISTOGRAM_BYPASS_CACHE, + HISTOGRAM_SKIP_CACHE_VALIDATION, + HISTOGRAM_ONLY_FROM_CACHE, + HISTOGRAM_DISABLE_CACHE, + HISTOGRAM_CACHE_FLAG_MAX = HISTOGRAM_DISABLE_CACHE, +}; + +void RecordCacheFlags(HistogramCacheFlag flag) { + UMA_HISTOGRAM_ENUMERATION("Navigation.BackForward.CacheFlags", flag, + HISTOGRAM_CACHE_FLAG_MAX); +} + +void LogBackForwardNavigationFlagsHistogram(int load_flags) { + if (load_flags & net::LOAD_VALIDATE_CACHE) + RecordCacheFlags(HISTOGRAM_VALIDATE_CACHE); + + if (load_flags & net::LOAD_BYPASS_CACHE) + RecordCacheFlags(HISTOGRAM_BYPASS_CACHE); + + if (load_flags & net::LOAD_SKIP_CACHE_VALIDATION) + RecordCacheFlags(HISTOGRAM_SKIP_CACHE_VALIDATION); + + if (load_flags & net::LOAD_ONLY_FROM_CACHE) + RecordCacheFlags(HISTOGRAM_ONLY_FROM_CACHE); + + if (load_flags & net::LOAD_DISABLE_CACHE) + RecordCacheFlags(HISTOGRAM_DISABLE_CACHE); +} + } // namespace ResourceDispatcherHostImpl::LoadInfo::LoadInfo() {} @@ -374,7 +374,16 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl( FROM_HERE, base::Bind(&ResourceDispatcherHostImpl::OnInit, base::Unretained(this))); - update_load_states_timer_.reset(new base::RepeatingTimer()); + update_load_states_timer_ = base::MakeUnique<base::RepeatingTimer>(); + + // Monitor per-tab outstanding requests only if OOPIF is not enabled, because + // the routing id doesn't represent tabs in OOPIF modes. + if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites() && + !SiteIsolationPolicy::IsTopDocumentIsolationEnabled() && + !SiteIsolationPolicy::AreIsolatedOriginsEnabled()) { + record_outstanding_requests_stats_timer_ = + base::MakeUnique<base::RepeatingTimer>(); + } } // The default ctor is only used by unittests. It is reasonable to assume that @@ -385,6 +394,7 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { DCHECK(outstanding_requests_stats_map_.empty()); + DCHECK(outstanding_requests_per_tab_map_.empty()); DCHECK(g_resource_dispatcher_host); DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); g_resource_dispatcher_host = NULL; @@ -603,13 +613,20 @@ bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader, } void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { - // Make sure we have the load state monitor running. + // Make sure we have the load state monitors running. if (!update_load_states_timer_->IsRunning() && scheduler_->HasLoadingClients()) { update_load_states_timer_->Start( FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), this, &ResourceDispatcherHostImpl::UpdateLoadInfo); } + if (record_outstanding_requests_stats_timer_ && + !record_outstanding_requests_stats_timer_->IsRunning()) { + record_outstanding_requests_stats_timer_->Start( + FROM_HERE, + TimeDelta::FromSeconds(kRecordOutstandingRequestsStatsIntervalSec), + this, &ResourceDispatcherHostImpl::RecordOutstandingRequestsStats); + } } void ResourceDispatcherHostImpl::DidReceiveRedirect( @@ -775,11 +792,6 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) { -loader->request()->status().error()); } - if (loader->request()->url().SchemeIsCryptographic()) { - RecordCertificateHistograms(loader->request()->ssl_info(), - info->GetResourceType()); - } - if (delegate_) delegate_->RequestComplete(loader->request()); @@ -803,10 +815,11 @@ void ResourceDispatcherHostImpl::OnShutdown() { is_shutdown_ = true; pending_loaders_.clear(); - // Make sure we shutdown the timer now, otherwise by the time our destructor + // Make sure we shutdown the timers now, otherwise by the time our destructor // runs if the timer is still running the Task is deleted twice (once by // the MessageLoop and the second time by RepeatingTimer). update_load_states_timer_.reset(); + record_outstanding_requests_stats_timer_.reset(); // Clear blocked requests if any left. // Note that we have to do this in 2 passes as we cannot call @@ -872,9 +885,11 @@ void ResourceDispatcherHostImpl::OnRequestResource( ResourceRequesterInfo* requester_info, int routing_id, int request_id, - const ResourceRequest& request_data) { - OnRequestResourceInternal(requester_info, routing_id, request_id, - request_data, nullptr, nullptr); + const ResourceRequest& request_data, + net::MutableNetworkTrafficAnnotationTag traffic_annotation) { + OnRequestResourceInternal( + requester_info, routing_id, request_id, request_data, nullptr, nullptr, + net::NetworkTrafficAnnotationTag(traffic_annotation)); } void ResourceDispatcherHostImpl::OnRequestResourceInternal( @@ -883,7 +898,8 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal( int request_id, const ResourceRequest& request_data, mojom::URLLoaderAssociatedRequest mojo_request, - mojom::URLLoaderClientPtr url_loader_client) { + mojom::URLLoaderClientPtr url_loader_client, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(requester_info->IsRenderer() || requester_info->IsNavigationPreload()); // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. tracked_objects::ScopedTracker tracking_profile( @@ -903,7 +919,7 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal( } BeginRequest(requester_info, request_id, request_data, SyncLoadResultCallback(), routing_id, std::move(mojo_request), - std::move(url_loader_client)); + std::move(url_loader_client), traffic_annotation); } // Begins a resource request with the given params on behalf of the specified @@ -923,7 +939,7 @@ void ResourceDispatcherHostImpl::OnSyncLoad( base::Bind(&HandleSyncLoadResult, requester_info->filter()->GetWeakPtr(), base::Passed(WrapUnique(sync_result))); BeginRequest(requester_info, request_id, request_data, callback, - sync_result->routing_id(), nullptr, nullptr); + sync_result->routing_id(), nullptr, nullptr, kTrafficAnnotation); } bool ResourceDispatcherHostImpl::IsRequestIDInUse( @@ -1085,7 +1101,8 @@ void ResourceDispatcherHostImpl::BeginRequest( const SyncLoadResultCallback& sync_result_handler, // only valid for sync int route_id, mojom::URLLoaderAssociatedRequest mojo_request, - mojom::URLLoaderClientPtr url_loader_client) { + mojom::URLLoaderClientPtr url_loader_client, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(requester_info->IsRenderer() || requester_info->IsNavigationPreload()); int child_id = requester_info->child_id(); @@ -1156,7 +1173,29 @@ void ResourceDispatcherHostImpl::BeginRequest( return; } + BlobHandles blob_handles; if (!is_navigation_stream_request) { + storage::BlobStorageContext* blob_context = + GetBlobStorageContext(requester_info->blob_storage_context()); + // Resolve elements from request_body and prepare upload data. + if (request_data.request_body.get()) { + // |blob_context| could be null when the request is from the plugins + // because ResourceMessageFilters created in PluginProcessHost don't have + // the blob context. + if (blob_context) { + // Get BlobHandles to request_body to prevent blobs and any attached + // shareable files from being freed until upload completion. These data + // will be used in UploadDataStream and ServiceWorkerURLRequestJob. + if (!GetBodyBlobDataHandles(request_data.request_body.get(), + resource_context, &blob_handles)) { + AbortRequestBeforeItStarts(requester_info->filter(), + sync_result_handler, request_id, + std::move(url_loader_client)); + return; + } + } + } + // Check if we have a registered interceptor for the headers passed in. If // yes then we need to mark the current request as pending and wait for the // interceptor to invoke the callback with a status code indicating whether @@ -1178,10 +1217,11 @@ void ResourceDispatcherHostImpl::BeginRequest( it.name(), it.value(), child_id, resource_context, base::Bind( &ResourceDispatcherHostImpl::ContinuePendingBeginRequest, - base::Unretained(this), requester_info, request_id, - request_data, sync_result_handler, route_id, headers, - base::Passed(std::move(mojo_request)), - base::Passed(std::move(url_loader_client)))); + base::Unretained(this), make_scoped_refptr(requester_info), + request_id, request_data, sync_result_handler, route_id, + headers, base::Passed(std::move(mojo_request)), + base::Passed(std::move(url_loader_client)), + base::Passed(std::move(blob_handles)), traffic_annotation)); return; } } @@ -1190,6 +1230,7 @@ void ResourceDispatcherHostImpl::BeginRequest( ContinuePendingBeginRequest( requester_info, request_id, request_data, sync_result_handler, route_id, headers, std::move(mojo_request), std::move(url_loader_client), + std::move(blob_handles), traffic_annotation, HeaderInterceptorResult::CONTINUE); } @@ -1202,6 +1243,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( const net::HttpRequestHeaders& headers, mojom::URLLoaderAssociatedRequest mojo_request, mojom::URLLoaderClientPtr url_loader_client, + BlobHandles blob_handles, + const net::NetworkTrafficAnnotationTag& traffic_annotation, HeaderInterceptorResult interceptor_result) { DCHECK(requester_info->IsRenderer() || requester_info->IsNavigationPreload()); if (interceptor_result != HeaderInterceptorResult::CONTINUE) { @@ -1247,7 +1290,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( std::unique_ptr<net::URLRequest> new_request = request_context->CreateRequest( is_navigation_stream_request ? request_data.resource_body_stream_url : request_data.url, - request_data.priority, nullptr, kTrafficAnnotation); + request_data.priority, nullptr, traffic_annotation); if (is_navigation_stream_request) { // PlzNavigate: Always set the method to GET when gaining access to the @@ -1304,20 +1347,12 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( GetBlobStorageContext(requester_info->blob_storage_context()); // Resolve elements from request_body and prepare upload data. if (request_data.request_body.get()) { - // |blob_context| could be null when the request is from the plugins - // because ResourceMessageFilters created in PluginProcessHost don't have - // the blob context. - if (blob_context) { - // Attaches the BlobDataHandles to request_body not to free the blobs - // and any attached shareable files until upload completion. These data - // will be used in UploadDataStream and ServiceWorkerURLRequestJob. - AttachRequestBodyBlobDataHandles(request_data.request_body.get(), - resource_context); - } new_request->set_upload(UploadDataStreamBuilder::Build( request_data.request_body.get(), blob_context, requester_info->file_system_context(), - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get())); + base::CreateSingleThreadTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}) + .get())); } allow_download = request_data.allow_download && @@ -1373,6 +1408,14 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( new_request->SetLoadFlags(load_flags); + // Update the previews state, but only if this is not using PlzNavigate. + PreviewsState previews_state = request_data.previews_state; + if (!IsBrowserSideNavigationEnabled()) { + previews_state = GetPreviewsState( + request_data.previews_state, delegate_, *new_request, resource_context, + request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME); + } + // Make extra info and read footer (contains request ID). ResourceRequestInfoImpl* extra_info = new ResourceRequestInfoImpl( requester_info, route_id, @@ -1387,11 +1430,10 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( request_data.enable_load_timing, request_data.enable_upload_progress, do_not_prompt_for_login, request_data.referrer_policy, request_data.visibility_state, resource_context, report_raw_headers, - !is_sync_load, - GetPreviewsState(request_data.previews_state, delegate_, *new_request, - resource_context, - request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME), - request_data.request_body, request_data.initiated_in_secure_context); + !is_sync_load, previews_state, request_data.request_body, + request_data.initiated_in_secure_context); + extra_info->SetBlobHandles(std::move(blob_handles)); + // Request takes ownership. extra_info->AssociateWithRequest(new_request.get()); @@ -1423,18 +1465,18 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( blob_context, child_id, request_data.service_worker_provider_id, service_worker_mode != ServiceWorkerMode::ALL, request_data.fetch_request_mode, request_data.fetch_credentials_mode, - request_data.fetch_redirect_mode, request_data.resource_type, - request_data.fetch_request_context_type, request_data.fetch_frame_type, - request_data.request_body); + request_data.fetch_redirect_mode, request_data.fetch_integrity, + request_data.resource_type, request_data.fetch_request_context_type, + request_data.fetch_frame_type, request_data.request_body); ForeignFetchRequestHandler::InitializeHandler( new_request.get(), requester_info->service_worker_context(), blob_context, child_id, request_data.service_worker_provider_id, service_worker_mode, request_data.fetch_request_mode, request_data.fetch_credentials_mode, request_data.fetch_redirect_mode, - request_data.resource_type, request_data.fetch_request_context_type, - request_data.fetch_frame_type, request_data.request_body, - request_data.initiated_in_secure_context); + request_data.fetch_integrity, request_data.resource_type, + request_data.fetch_request_context_type, request_data.fetch_frame_type, + request_data.request_body, request_data.initiated_in_secure_context); // Have the appcache associate its extra info with the request. AppCacheInterceptor::SetExtraRequestInfo( @@ -1586,6 +1628,12 @@ ResourceDispatcherHostImpl::AddStandardHandlers( base::MakeUnique<WakeLockResourceThrottle>(request->url().host())); } + // The Clear-Site-Data throttle. + std::unique_ptr<ResourceThrottle> clear_site_data_throttle = + ClearSiteDataThrottle::MaybeCreateThrottleForRequest(request); + if (clear_site_data_throttle) + throttles.push_back(std::move(clear_site_data_throttle)); + // TODO(ricea): Stop looking this up so much. ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); throttles.push_back(scheduler_->ScheduleRequest(child_id, route_id, @@ -1918,6 +1966,18 @@ void ResourceDispatcherHostImpl::UpdateOutstandingRequestsStats( outstanding_requests_stats_map_[info.GetChildID()] = stats; } +void ResourceDispatcherHostImpl::IncrementOutstandingRequestsPerTab( + int count, + const ResourceRequestInfoImpl& info) { + auto key = std::make_pair(info.GetChildID(), info.GetRouteID()); + OutstandingRequestsPerTabMap::iterator entry = + outstanding_requests_per_tab_map_.insert(std::make_pair(key, 0)).first; + entry->second += count; + DCHECK_GE(entry->second, 0); + if (entry->second == 0) + outstanding_requests_per_tab_map_.erase(entry); +} + ResourceDispatcherHostImpl::OustandingRequestsStats ResourceDispatcherHostImpl::IncrementOutstandingRequestsMemory( int count, @@ -1953,6 +2013,8 @@ ResourceDispatcherHostImpl::IncrementOutstandingRequestsCount( DCHECK_GE(stats.num_requests, 0); UpdateOutstandingRequestsStats(*info, stats); + IncrementOutstandingRequestsPerTab(count, *info); + if (num_in_flight_requests_ > largest_outstanding_request_count_seen_) { largest_outstanding_request_count_seen_ = num_in_flight_requests_; UMA_HISTOGRAM_COUNTS_1M( @@ -1968,6 +2030,14 @@ ResourceDispatcherHostImpl::IncrementOutstandingRequestsCount( largest_outstanding_request_per_process_count_seen_); } + if (num_in_flight_requests_ > peak_outstanding_request_count_) + peak_outstanding_request_count_ = num_in_flight_requests_; + + if (HasRequestsFromMultipleActiveTabs() && + num_in_flight_requests_ > peak_outstanding_request_count_multitab_) { + peak_outstanding_request_count_multitab_ = num_in_flight_requests_; + } + return stats; } @@ -2022,9 +2092,6 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( !is_external_protocol; if (is_shutdown_ || non_web_url_in_guest || - // TODO(davidben): Check ShouldServiceRequest here. This is important; it - // needs to be checked relative to the child that /requested/ the - // navigation. It's where file upload checks, etc., come in. (delegate_ && !delegate_->ShouldBeginRequest( info.common_params.method, info.common_params.url, @@ -2072,14 +2139,25 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( GetChromeBlobStorageContextForResourceContext(resource_context)); // Resolve elements from request_body and prepare upload data. - ResourceRequestBodyImpl* body = info.common_params.post_data.get(); + ResourceRequestBody* body = info.common_params.post_data.get(); + BlobHandles blob_handles; if (body) { - AttachRequestBodyBlobDataHandles(body, resource_context); + if (!GetBodyBlobDataHandles(body, resource_context, &blob_handles)) { + new_request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); + loader->NotifyRequestFailed(false, net::ERR_ABORTED); + return; + } new_request->set_upload(UploadDataStreamBuilder::Build( body, blob_context, upload_file_system_context, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get())); + base::CreateSingleThreadTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}) + .get())); } + PreviewsState previews_state = + GetPreviewsState(info.common_params.previews_state, delegate_, + *new_request, resource_context, info.is_main_frame); + // Make extra info and read footer (contains request ID). // // TODO(davidben): Associate the request with the FrameTreeNode and/or tab so @@ -2108,14 +2186,13 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( info.common_params.referrer.policy, info.page_visibility_state, resource_context, info.report_raw_headers, true, // is_async - GetPreviewsState(info.common_params.previews_state, delegate_, - *new_request, resource_context, info.is_main_frame), - info.common_params.post_data, + previews_state, info.common_params.post_data, // TODO(mek): Currently initiated_in_secure_context is only used for // subresource requests, so it doesn't matter what value it gets here. // If in the future this changes this should be updated to somehow get a // meaningful value. false); // initiated_in_secure_context + extra_info->SetBlobHandles(std::move(blob_handles)); extra_info->set_navigation_ui_data(std::move(navigation_ui_data)); // Request takes ownership. @@ -2190,10 +2267,11 @@ void ResourceDispatcherHostImpl::OnRequestResourceWithMojo( int request_id, const ResourceRequest& request, mojom::URLLoaderAssociatedRequest mojo_request, - mojom::URLLoaderClientPtr url_loader_client) { + mojom::URLLoaderClientPtr url_loader_client, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { OnRequestResourceInternal(requester_info, routing_id, request_id, request, std::move(mojo_request), - std::move(url_loader_client)); + std::move(url_loader_client), traffic_annotation); } void ResourceDispatcherHostImpl::OnSyncLoadWithMojo( @@ -2203,7 +2281,7 @@ void ResourceDispatcherHostImpl::OnSyncLoadWithMojo( const ResourceRequest& request_data, const SyncLoadResultCallback& result_handler) { BeginRequest(requester_info, request_id, request_data, result_handler, - routing_id, nullptr, nullptr); + routing_id, nullptr, nullptr, kTrafficAnnotation); } // static @@ -2233,6 +2311,15 @@ void ResourceDispatcherHostImpl::BeginRequestInternal( ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request.get()); + // Log metrics for back-forward navigations. + // TODO(clamy): Remove this once we understand the reason behind the + // back-forward PLT regression with PlzNavigate + if ((info->GetPageTransition() & ui::PAGE_TRANSITION_FORWARD_BACK) && + IsResourceTypeFrame(info->GetResourceType()) && + request->url().SchemeIsHTTPOrHTTPS()) { + LogBackForwardNavigationFlagsHistogram(request->load_flags()); + } + if ((TimeTicks::Now() - last_user_gesture_time_) < TimeDelta::FromMilliseconds(kUserGestureWindowMs)) { request->SetLoadFlags(request->load_flags() | net::LOAD_MAYBE_USER_GESTURE); @@ -2486,6 +2573,23 @@ void ResourceDispatcherHostImpl::UpdateLoadInfo() { base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos))); } +void ResourceDispatcherHostImpl::RecordOutstandingRequestsStats() { + if (peak_outstanding_request_count_ != 0) { + UMA_HISTOGRAM_COUNTS_1M( + "Net.ResourceDispatcherHost.PeakOutstandingRequests", + peak_outstanding_request_count_); + peak_outstanding_request_count_ = num_in_flight_requests_; + } + + if (peak_outstanding_request_count_multitab_ != 0) { + UMA_HISTOGRAM_COUNTS_1M( + "Net.ResourceDispatcherHost.PeakOutstandingRequests.MultiTabLoading", + peak_outstanding_request_count_multitab_); + peak_outstanding_request_count_multitab_ = + HasRequestsFromMultipleActiveTabs() ? num_in_flight_requests_ : 0; + } +} + void ResourceDispatcherHostImpl::BlockRequestsForRoute( const GlobalFrameRoutingId& global_routing_id) { DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); @@ -2663,30 +2767,13 @@ bool ResourceDispatcherHostImpl::ShouldServiceRequest( } // Check if the renderer is permitted to upload the requested files. - if (request_data.request_body.get()) { - const std::vector<ResourceRequestBodyImpl::Element>* uploads = - request_data.request_body->elements(); - std::vector<ResourceRequestBodyImpl::Element>::const_iterator iter; - for (iter = uploads->begin(); iter != uploads->end(); ++iter) { - if (iter->type() == ResourceRequestBodyImpl::Element::TYPE_FILE && - !policy->CanReadFile(child_id, iter->path())) { - NOTREACHED() << "Denied unauthorized upload of " - << iter->path().value(); - return false; - } - if (iter->type() == - ResourceRequestBodyImpl::Element::TYPE_FILE_FILESYSTEM) { - storage::FileSystemURL url = - requester_info->file_system_context()->CrackURL( - iter->filesystem_url()); - if (!policy->CanReadFileSystemFile(child_id, url)) { - NOTREACHED() << "Denied unauthorized upload of " - << iter->filesystem_url().spec(); - return false; - } - } - } + if (!policy->CanReadRequestBody(child_id, + requester_info->file_system_context(), + request_data.request_body)) { + NOTREACHED() << "Denied unauthorized upload"; + return false; } + return true; } @@ -2712,4 +2799,20 @@ ResourceDispatcherHostImpl::HandleDownloadStarted( return handler; } +bool ResourceDispatcherHostImpl::HasRequestsFromMultipleActiveTabs() { + if (outstanding_requests_per_tab_map_.size() < 2) + return false; + + int active_tabs = 0; + for (auto iter = outstanding_requests_per_tab_map_.begin(); + iter != outstanding_requests_per_tab_map_.end(); ++iter) { + if (iter->second > 2) { + active_tabs++; + if (active_tabs >= 2) + return true; + } + } + return false; +} + } // namespace content diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.h b/chromium/content/browser/loader/resource_dispatcher_host_impl.h index 9ac1b256959..49645a1d284 100644 --- a/chromium/content/browser/loader/resource_dispatcher_host_impl.h +++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.h @@ -26,10 +26,10 @@ #include "base/observer_list.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/global_routing_id.h" #include "content/browser/loader/resource_loader_delegate.h" #include "content/common/content_export.h" -#include "content/common/url_loader.mojom.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_request_info.h" @@ -37,9 +37,11 @@ #include "content/public/common/previews_state.h" #include "content/public/common/request_context_type.h" #include "content/public/common/resource_type.h" +#include "content/public/common/url_loader.mojom.h" #include "ipc/ipc_message.h" #include "net/base/load_states.h" #include "net/base/request_priority.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "third_party/WebKit/public/platform/WebMixedContentContextType.h" #include "url/gurl.h" @@ -278,12 +280,14 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl void OnRenderFrameDeleted(const GlobalFrameRoutingId& global_routing_id); // Called when loading a request with mojo. - void OnRequestResourceWithMojo(ResourceRequesterInfo* requester_info, - int routing_id, - int request_id, - const ResourceRequest& request, - mojom::URLLoaderAssociatedRequest mojo_request, - mojom::URLLoaderClientPtr url_loader_client); + void OnRequestResourceWithMojo( + ResourceRequesterInfo* requester_info, + int routing_id, + int request_id, + const ResourceRequest& request, + mojom::URLLoaderAssociatedRequest mojo_request, + mojom::URLLoaderClientPtr url_loader_client, + const net::NetworkTrafficAnnotationTag& traffic_annotation); void OnSyncLoadWithMojo(ResourceRequesterInfo* requester_info, int routing_id, @@ -457,6 +461,13 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl int count, ResourceRequestInfoImpl* info); + // Called from IncrementOutstandingRequestsCount to update the per-tab + // request stats in |outstanding_requests_per_tab_map_|. + // TODO(ksakamoto): This is just for temporary metrics collection for the + // Loading Dispatcher v0 (crbug.com/723233), and will be removed soon. + void IncrementOutstandingRequestsPerTab(int count, + const ResourceRequestInfoImpl& info); + // Estimate how much heap space |request| will consume to run. static int CalculateApproximateMemoryCost(net::URLRequest* request); @@ -513,22 +524,30 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl // Checks all pending requests and updates the load info if necessary. void UpdateLoadInfo(); + // Records statistics about outstanding requests since the last call, and + // reset the stats. + void RecordOutstandingRequestsStats(); + // Resumes or cancels (if |cancel_requests| is true) any blocked requests. void ProcessBlockedRequestsForRoute( const GlobalFrameRoutingId& global_routing_id, bool cancel_requests); - void OnRequestResource(ResourceRequesterInfo* requester_info, - int routing_id, - int request_id, - const ResourceRequest& request_data); + void OnRequestResource( + ResourceRequesterInfo* requester_info, + int routing_id, + int request_id, + const ResourceRequest& request_data, + net::MutableNetworkTrafficAnnotationTag traffic_annotation); - void OnRequestResourceInternal(ResourceRequesterInfo* requester_info, - int routing_id, - int request_id, - const ResourceRequest& request_data, - mojom::URLLoaderAssociatedRequest mojo_request, - mojom::URLLoaderClientPtr url_loader_client); + void OnRequestResourceInternal( + ResourceRequesterInfo* requester_info, + int routing_id, + int request_id, + const ResourceRequest& request_data, + mojom::URLLoaderAssociatedRequest mojo_request, + mojom::URLLoaderClientPtr url_loader_client, + const net::NetworkTrafficAnnotationTag& traffic_annotation); void OnSyncLoad(ResourceRequesterInfo* requester_info, int request_id, @@ -563,7 +582,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl const SyncLoadResultCallback& sync_result_handler, // only valid for sync int route_id, mojom::URLLoaderAssociatedRequest mojo_request, - mojom::URLLoaderClientPtr url_loader_client); + mojom::URLLoaderClientPtr url_loader_client, + const net::NetworkTrafficAnnotationTag& traffic_annotation); // There are requests which need decisions to be made like the following: // Whether the presence of certain HTTP headers like the Origin header are @@ -582,6 +602,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl const net::HttpRequestHeaders& headers, mojom::URLLoaderAssociatedRequest mojo_request, mojom::URLLoaderClientPtr url_loader_client, + BlobHandles blob_handles, + const net::NetworkTrafficAnnotationTag& traffic_annotation, HeaderInterceptorResult interceptor_result); // Creates a ResourceHandler to be used by BeginRequest() for normal resource @@ -695,6 +717,10 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl bool must_download, bool is_new_request); + // Returns true if there are two or more tabs that are not network 2-quiet + // (i.e. have at least three outstanding requests). + bool HasRequestsFromMultipleActiveTabs(); + LoaderMap pending_loaders_; // Collection of temp files downloaded for child processes via @@ -710,6 +736,10 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl // not empty and at least one RenderViewHost is loading. std::unique_ptr<base::RepeatingTimer> update_load_states_timer_; + // A timer that periodically calls RecordOutstandingRequestsStats. + std::unique_ptr<base::RepeatingTimer> + record_outstanding_requests_stats_timer_; + // Request ID for browser initiated requests. request_ids generated by // child processes are counted up from 0, while browser created requests // start at -2 and go down from there. (We need to start at -2 because -1 is @@ -732,6 +762,14 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl typedef std::map<int, OustandingRequestsStats> OutstandingRequestsStatsMap; OutstandingRequestsStatsMap outstanding_requests_stats_map_; + // Maps (child_id, route_id) to the number of outstanding requests. + // Used only when OOPIF is not enabled, since in OOPIF modes routing_id + // doesn't represent tabs. + // TODO(ksakamoto): This is just for temporary metrics collection for the + // Loading Dispatcher v0 (crbug.com/723233), and will be removed soon. + typedef std::map<std::pair<int, int>, int> OutstandingRequestsPerTabMap; + OutstandingRequestsPerTabMap outstanding_requests_per_tab_map_; + // |num_in_flight_requests_| is the total number of requests currently issued // summed across all renderers. int num_in_flight_requests_; @@ -763,6 +801,15 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl // Largest number of outstanding requests seen so far in any single process. int largest_outstanding_request_per_process_count_seen_; + // Largest number of outstanding requests seen since the last call to + // RecordOutstandingRequestsStats. + int peak_outstanding_request_count_ = 0; + + // Largest number of outstanding requests seen while there are outstanding + // requests from two or more tabs, since the last call to + // RecordOutstandingRequestsStats. + int peak_outstanding_request_count_multitab_ = 0; + // Time of the last user gesture. Stored so that we can add a load // flag to requests occurring soon after a gesture to indicate they // may be because of explicit user action. diff --git a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc index ec9bfc80ead..433243aba2a 100644 --- a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc +++ b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc @@ -21,6 +21,8 @@ #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/child_process_security_policy_impl.h" @@ -40,7 +42,6 @@ #include "content/common/child_process_host_impl.h" #include "content/common/navigation_params.h" #include "content/common/resource_messages.h" -#include "content/common/resource_request.h" #include "content/common/view_messages.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/render_process_host.h" @@ -54,6 +55,7 @@ #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/child_process_host.h" #include "content/public/common/process_type.h" +#include "content/public/common/resource_request.h" #include "content/public/common/resource_response.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -1155,7 +1157,9 @@ void ResourceDispatcherHostTest::MakeTestRequestWithRenderFrame( ResourceType type) { ResourceRequest request = CreateResourceRequest("GET", type, url); request.render_frame_id = render_frame_id; - ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); + ResourceHostMsg_RequestResource msg( + render_view_id, request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg, filter_.get()); KickOffRequest(); } @@ -1167,7 +1171,9 @@ void ResourceDispatcherHostTest::MakeTestRequestWithResourceType( const GURL& url, ResourceType type) { ResourceRequest request = CreateResourceRequest("GET", type, url); - ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); + ResourceHostMsg_RequestResource msg( + render_view_id, request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg, filter); KickOffRequest(); } @@ -1187,7 +1193,8 @@ void ResourceDispatcherHostTest:: request.origin_pid = web_contents_->GetRenderProcessHost()->GetID(); request.render_frame_id = web_contents_->GetMainFrame()->GetRoutingID(); ResourceHostMsg_RequestResource msg( - web_contents_->GetRenderViewHost()->GetRoutingID(), request_id, request); + web_contents_->GetRenderViewHost()->GetRoutingID(), request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg, web_contents_filter_.get()); KickOffRequest(); } @@ -1209,7 +1216,9 @@ void ResourceDispatcherHostTest::MakeTestRequestWithPriorityAndRenderFrame( "GET", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/priority")); request.render_frame_id = render_frame_id; request.priority = priority; - ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); + ResourceHostMsg_RequestResource msg( + render_view_id, request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg, filter_.get()); } @@ -1435,7 +1444,9 @@ TEST_F(ResourceDispatcherHostTest, DownloadToNetworkCache) { ResourceRequest request_to_cache = CreateResourceRequest( "GET", RESOURCE_TYPE_IMAGE, net::URLRequestTestJob::test_url_3()); request_to_cache.download_to_network_cache_only = true; - ResourceHostMsg_RequestResource msg_to_cache(0, 2, request_to_cache); + ResourceHostMsg_RequestResource msg_to_cache( + 0, 2, request_to_cache, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg_to_cache, filter_.get()); KickOffRequest(); @@ -1578,9 +1589,13 @@ TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) { ResourceRequest request_ping = CreateResourceRequest( "GET", RESOURCE_TYPE_PING, net::URLRequestTestJob::test_url_3()); - ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch); + ResourceHostMsg_RequestResource msg_prefetch( + 0, 1, request_prefetch, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg_prefetch, filter_.get()); - ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping); + ResourceHostMsg_RequestResource msg_ping( + 0, 2, request_ping, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg_ping, filter_.get()); // Remove the filter before processing the requests by simulating channel @@ -1626,7 +1641,9 @@ TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) { "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_redirect_to_url_2()); - ResourceHostMsg_RequestResource msg(0, 1, request); + ResourceHostMsg_RequestResource msg( + 0, 1, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(msg, filter_.get()); // Remove the filter before processing the request by simulating channel @@ -2736,7 +2753,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { request.transferred_request_request_id = request_id; ResourceHostMsg_RequestResource transfer_request_msg( - new_render_view_id, new_request_id, request); + new_render_view_id, new_request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(transfer_request_msg, second_filter.get()); content::RunAllBlockingPoolTasksUntilIdle(); @@ -2805,7 +2823,8 @@ TEST_F(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) { request.transferred_request_request_id = request_id; ResourceHostMsg_RequestResource transfer_request_msg( - new_render_view_id, new_request_id, request); + new_render_view_id, new_request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(transfer_request_msg, second_filter.get()); content::RunAllBlockingPoolTasksUntilIdle(); @@ -2817,7 +2836,8 @@ TEST_F(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) { request.transferred_request_request_id = second_request_id; ResourceHostMsg_RequestResource second_transfer_request_msg( - new_render_view_id, new_second_request_id, second_request); + new_render_view_id, new_second_request_id, second_request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(second_transfer_request_msg, second_filter.get()); content::RunAllBlockingPoolTasksUntilIdle(); @@ -2887,7 +2907,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { request.transferred_request_request_id = request_id; ResourceHostMsg_RequestResource transfer_request_msg( - new_render_view_id, new_request_id, request); + new_render_view_id, new_request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(transfer_request_msg, second_filter.get()); content::RunAllBlockingPoolTasksUntilIdle(); @@ -2933,7 +2954,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://example.com/blah")); ResourceHostMsg_RequestResource first_request_msg( - render_view_id, request_id, first_request); + render_view_id, request_id, first_request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(first_request_msg, first_filter.get()); content::RunAllBlockingPoolTasksUntilIdle(); @@ -2971,7 +2993,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { // For cleanup. child_ids_.insert(second_filter->child_id()); ResourceHostMsg_RequestResource transfer_request_msg( - new_render_view_id, new_request_id, request); + new_render_view_id, new_request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(transfer_request_msg, second_filter.get()); content::RunAllBlockingPoolTasksUntilIdle(); @@ -3048,7 +3071,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { // For cleanup. child_ids_.insert(second_filter->child_id()); ResourceHostMsg_RequestResource transfer_request_msg( - new_render_view_id, new_request_id, request); + new_render_view_id, new_request_id, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(transfer_request_msg, second_filter.get()); // Verify that we update the ResourceRequestInfo. @@ -3279,7 +3303,8 @@ TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) { scoped_refptr<ShareableFileReference> deletable_file = ShareableFileReference::GetOrCreate( file_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()); + base::CreateSingleThreadTaskRunnerWithTraits({base::MayBlock()}) + .get()); // Not readable. EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( @@ -3325,7 +3350,8 @@ TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFileWithMojo) { scoped_refptr<ShareableFileReference> deletable_file = ShareableFileReference::GetOrCreate( file_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()); + base::CreateSingleThreadTaskRunnerWithTraits({base::MayBlock()}) + .get()); // Not readable. EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( @@ -3374,7 +3400,8 @@ TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) { scoped_refptr<ShareableFileReference> deletable_file = ShareableFileReference::GetOrCreate( file_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()); + base::CreateSingleThreadTaskRunnerWithTraits({base::MayBlock()}) + .get()); // Register it for a resource request. host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path); @@ -3399,7 +3426,9 @@ TEST_F(ResourceDispatcherHostTest, DownloadToFile) { ResourceRequest request = CreateResourceRequest( "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); request.download_to_file = true; - ResourceHostMsg_RequestResource request_msg(0, 1, request); + ResourceHostMsg_RequestResource request_msg( + 0, 1, request, + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); OnMessageReceived(request_msg, filter_.get()); // Running the message loop until idle does not work because diff --git a/chromium/content/browser/loader/resource_handler.cc b/chromium/content/browser/loader/resource_handler.cc index 961934d05e9..0f875512f69 100644 --- a/chromium/content/browser/loader/resource_handler.cc +++ b/chromium/content/browser/loader/resource_handler.cc @@ -16,7 +16,9 @@ void ResourceHandler::SetDelegate(Delegate* delegate) { delegate_ = delegate; } -ResourceHandler::~ResourceHandler() {} +ResourceHandler::~ResourceHandler() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} ResourceHandler::ResourceHandler(net::URLRequest* request) : request_(request) {} diff --git a/chromium/content/browser/loader/resource_handler.h b/chromium/content/browser/loader/resource_handler.h index c292cab2312..2b67e0c4c32 100644 --- a/chromium/content/browser/loader/resource_handler.h +++ b/chromium/content/browser/loader/resource_handler.h @@ -18,7 +18,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/threading/non_thread_safe.h" +#include "base/sequence_checker.h" #include "content/browser/loader/resource_controller.h" #include "content/common/content_export.h" @@ -43,8 +43,7 @@ struct ResourceResponse; // No ResourceHandler method other than OnWillRead will ever be called // synchronously when it calls into the ResourceController passed in to it, // either to resume or cancel the request. -class CONTENT_EXPORT ResourceHandler - : public NON_EXPORTED_BASE(base::NonThreadSafe) { +class CONTENT_EXPORT ResourceHandler { public: virtual ~ResourceHandler(); @@ -176,6 +175,8 @@ class CONTENT_EXPORT ResourceHandler Delegate* delegate_; std::unique_ptr<ResourceController> controller_; + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(ResourceHandler); }; diff --git a/chromium/content/browser/loader/resource_hints_impl.cc b/chromium/content/browser/loader/resource_hints_impl.cc index 5d091710177..05eb063cbb8 100644 --- a/chromium/content/browser/loader/resource_hints_impl.cc +++ b/chromium/content/browser/loader/resource_hints_impl.cc @@ -7,7 +7,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" -#include "content/public/browser/resource_context.h" #include "content/public/browser/resource_hints.h" #include "net/base/address_list.h" #include "net/base/load_flags.h" @@ -19,6 +18,7 @@ #include "net/log/net_log_with_source.h" #include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" namespace content { @@ -45,7 +45,7 @@ void OnResolveComplete(std::unique_ptr<RequestHolder> request_holder, } // namespace -void PreconnectUrl(content::ResourceContext* resource_context, +void PreconnectUrl(net::URLRequestContextGetter* getter, const GURL& url, const GURL& first_party_for_cookies, int count, @@ -54,15 +54,19 @@ void PreconnectUrl(content::ResourceContext* resource_context, DCHECK(ResourceDispatcherHostImpl::Get() ->io_thread_task_runner() ->BelongsToCurrentThread()); - DCHECK(resource_context); + DCHECK(getter); - net::URLRequestContext* context = resource_context->GetRequestContext(); - net::HttpTransactionFactory* factory = context->http_transaction_factory(); + net::URLRequestContext* request_context = getter->GetURLRequestContext(); + if (!request_context) + return; + + net::HttpTransactionFactory* factory = + request_context->http_transaction_factory(); net::HttpNetworkSession* session = factory->GetSession(); std::string user_agent; - if (context->http_user_agent_settings()) - user_agent = context->http_user_agent_settings()->GetUserAgent(); + if (request_context->http_user_agent_settings()) + user_agent = request_context->http_user_agent_settings()->GetUserAgent(); net::HttpRequestInfo request_info; request_info.url = url; request_info.method = "GET"; @@ -70,7 +74,7 @@ void PreconnectUrl(content::ResourceContext* resource_context, user_agent); request_info.motivation = motivation; - net::NetworkDelegate* delegate = context->network_delegate(); + net::NetworkDelegate* delegate = request_context->network_delegate(); if (delegate->CanEnablePrivacyMode(url, first_party_for_cookies)) request_info.privacy_mode = net::PRIVACY_MODE_ENABLED; @@ -88,13 +92,17 @@ void PreconnectUrl(content::ResourceContext* resource_context, http_stream_factory->PreconnectStreams(count, request_info); } -int PreresolveUrl(content::ResourceContext* resource_context, +int PreresolveUrl(net::URLRequestContextGetter* getter, const GURL& url, const net::CompletionCallback& callback) { DCHECK(ResourceDispatcherHostImpl::Get() ->io_thread_task_runner() ->BelongsToCurrentThread()); - DCHECK(resource_context); + DCHECK(getter); + + net::URLRequestContext* request_context = getter->GetURLRequestContext(); + if (!request_context) + return net::ERR_CONTEXT_SHUT_DOWN; auto request_holder = base::MakeUnique<RequestHolder>(); auto addresses = base::MakeUnique<net::AddressList>(); @@ -104,7 +112,7 @@ int PreresolveUrl(content::ResourceContext* resource_context, std::unique_ptr<net::HostResolver::Request>* out_request = request_holder->GetRequest(); - net::HostResolver* resolver = resource_context->GetHostResolver(); + net::HostResolver* resolver = request_context->host_resolver(); net::HostResolver::RequestInfo resolve_info(net::HostPortPair::FromURL(url)); resolve_info.set_is_speculative(true); return resolver->Resolve( diff --git a/chromium/content/browser/loader/resource_loader.cc b/chromium/content/browser/loader/resource_loader.cc index d2a1bb1945d..3a185938f43 100644 --- a/chromium/content/browser/loader/resource_loader.cc +++ b/chromium/content/browser/loader/resource_loader.cc @@ -37,8 +37,6 @@ #include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator.h" #include "net/ssl/client_cert_store.h" -#include "net/ssl/ssl_platform_key.h" -#include "net/ssl/ssl_private_key.h" #include "net/url_request/redirect_info.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_status.h" @@ -469,16 +467,12 @@ void ResourceLoader::ContinueSSLRequest() { request_->ContinueDespiteLastError(); } -void ResourceLoader::ContinueWithCertificate(net::X509Certificate* cert) { +void ResourceLoader::ContinueWithCertificate( + scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> private_key) { DCHECK(ssl_client_auth_handler_); ssl_client_auth_handler_.reset(); - if (!cert) { - request_->ContinueWithCertificate(nullptr, nullptr); - return; - } - scoped_refptr<net::SSLPrivateKey> private_key = - net::FetchClientCertPrivateKey(cert); - request_->ContinueWithCertificate(cert, private_key.get()); + request_->ContinueWithCertificate(std::move(cert), std::move(private_key)); } void ResourceLoader::CancelCertificateSelection() { @@ -646,6 +640,16 @@ void ResourceLoader::CompleteResponseStarted() { delegate_->DidReceiveResponse(this, response.get()); + // For back-forward navigations, record metrics. + // TODO(clamy): Remove once we understand the root cause behind the regression + // of PLT for b/f navigations in PlzNavigate. + if ((info->GetPageTransition() & ui::PAGE_TRANSITION_FORWARD_BACK) && + IsResourceTypeFrame(info->GetResourceType()) && + request_->url().SchemeIsHTTPOrHTTPS()) { + UMA_HISTOGRAM_BOOLEAN("Navigation.BackForward.WasCached", + request_->was_cached()); + } + read_deferral_start_time_ = base::TimeTicks::Now(); // Using a ScopedDeferral here would result in calling ReadMore(true) on sync // success. Calling PrepareToReadMore(false) here instead allows small diff --git a/chromium/content/browser/loader/resource_loader.h b/chromium/content/browser/loader/resource_loader.h index 9558c19d766..49ce93a45fd 100644 --- a/chromium/content/browser/loader/resource_loader.h +++ b/chromium/content/browser/loader/resource_loader.h @@ -81,7 +81,9 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate, void ContinueSSLRequest() override; // SSLClientAuthHandler::Delegate implementation. - void ContinueWithCertificate(net::X509Certificate* cert) override; + void ContinueWithCertificate( + scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> private_key) override; void CancelCertificateSelection() override; // These correspond to Controller's methods. diff --git a/chromium/content/browser/loader/resource_loader_unittest.cc b/chromium/content/browser/loader/resource_loader_unittest.cc index ff068e7a740..dab9d6a9aa6 100644 --- a/chromium/content/browser/loader/resource_loader_unittest.cc +++ b/chromium/content/browser/loader/resource_loader_unittest.cc @@ -42,6 +42,7 @@ #include "net/cert/x509_certificate.h" #include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator_test_util.h" +#include "net/ssl/client_cert_identity_test_util.h" #include "net/ssl/client_cert_store.h" #include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_private_key.h" @@ -79,7 +80,7 @@ class ClientCertStoreStub : public net::ClientCertStore { ClientCertStoreStub(const net::CertificateList& response, int* request_count, std::vector<std::string>* requested_authorities) - : response_(response), + : response_(std::move(response)), requested_authorities_(requested_authorities), request_count_(request_count) { requested_authorities_->clear(); @@ -94,7 +95,7 @@ class ClientCertStoreStub : public net::ClientCertStore { *requested_authorities_ = cert_request_info.cert_authorities; ++(*request_count_); - callback.Run(response_); + callback.Run(net::FakeClientCertIdentityListFromCertificateList(response_)); } private: @@ -134,7 +135,7 @@ class LoaderDestroyingCertStore : public net::ClientCertStore { const ClientCertListCallback& cert_selected_callback, const base::Closure& on_loader_deleted_callback) { loader->reset(); - cert_selected_callback.Run(net::CertificateList()); + cert_selected_callback.Run(net::ClientCertIdentityList()); on_loader_deleted_callback.Run(); } @@ -168,8 +169,9 @@ class MockClientCertURLRequestJob : public net::URLRequestTestJob { base::RetainedRef(cert_request_info))); } - void ContinueWithCertificate(net::X509Certificate* cert, - net::SSLPrivateKey* private_key) override { + void ContinueWithCertificate( + scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> private_key) override { net::URLRequestTestJob::Start(); } @@ -194,11 +196,6 @@ class MockClientCertJobProtocolHandler // Set up dummy values to use in test HTTPS requests. -scoped_refptr<net::X509Certificate> GetTestCert() { - return net::ImportCertFromFile(net::GetTestCertsDirectory(), - "test_mail_google_com.pem"); -} - const net::CertStatus kTestCertError = net::CERT_STATUS_DATE_INVALID; const int kTestSecurityBits = 256; // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA @@ -222,7 +219,8 @@ class MockHTTPSURLRequestJob : public net::URLRequestTestJob { void GetResponseInfo(net::HttpResponseInfo* info) override { // Get the original response info, but override the SSL info. net::URLRequestJob::GetResponseInfo(info); - info->ssl_info.cert = GetTestCert(); + info->ssl_info.cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); info->ssl_info.cert_status = kTestCertError; info->ssl_info.security_bits = kTestSecurityBits; info->ssl_info.connection_status = kTestConnectionStatus; @@ -277,28 +275,31 @@ class SelectCertificateBrowserClient : public TestContentBrowserClient { void SelectClientCertificate( WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, - net::CertificateList client_certs, + net::ClientCertIdentityList client_certs, std::unique_ptr<ClientCertificateDelegate> delegate) override { EXPECT_FALSE(delegate_.get()); ++call_count_; - passed_certs_ = std::move(client_certs); + passed_identities_ = std::move(client_certs); delegate_ = std::move(delegate); select_certificate_run_loop_.Quit(); } int call_count() { return call_count_; } - net::CertificateList passed_certs() { return passed_certs_; } + const net::ClientCertIdentityList& passed_identities() { + return passed_identities_; + } - void ContinueWithCertificate(net::X509Certificate* cert) { - delegate_->ContinueWithCertificate(cert); + void ContinueWithCertificate(scoped_refptr<net::X509Certificate> cert, + scoped_refptr<net::SSLPrivateKey> private_key) { + delegate_->ContinueWithCertificate(std::move(cert), std::move(private_key)); delegate_.reset(); } void CancelCertificateSelection() { delegate_.reset(); } private: - net::CertificateList passed_certs_; + net::ClientCertIdentityList passed_identities_; int call_count_; std::unique_ptr<ClientCertificateDelegate> delegate_; @@ -599,7 +600,10 @@ TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { // Set up the test client cert store. int store_request_count; std::vector<std::string> store_requested_authorities; - net::CertificateList dummy_certs(1, GetTestCert()); + scoped_refptr<net::X509Certificate> test_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); + ASSERT_TRUE(test_cert); + net::CertificateList dummy_certs(1, test_cert); std::unique_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( dummy_certs, &store_request_count, &store_requested_authorities)); SetClientCertStore(std::move(test_store)); @@ -622,10 +626,11 @@ TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { // Check if the retrieved certificates were passed to the content browser // client. EXPECT_EQ(1, test_client.call_count()); - EXPECT_EQ(dummy_certs, test_client.passed_certs()); + EXPECT_EQ(1U, test_client.passed_identities().size()); + EXPECT_EQ(test_cert.get(), test_client.passed_identities()[0]->certificate()); // Continue the request. - test_client.ContinueWithCertificate(nullptr); + test_client.ContinueWithCertificate(nullptr, nullptr); raw_ptr_resource_handler_->WaitUntilResponseComplete(); EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); @@ -647,10 +652,10 @@ TEST_F(ClientCertResourceLoaderTest, WithNullStore) { // Check if the SelectClientCertificate was called on the content browser // client. EXPECT_EQ(1, test_client.call_count()); - EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); + EXPECT_EQ(net::ClientCertIdentityList(), test_client.passed_identities()); // Continue the request. - test_client.ContinueWithCertificate(nullptr); + test_client.ContinueWithCertificate(nullptr, nullptr); raw_ptr_resource_handler_->WaitUntilResponseComplete(); EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); @@ -671,7 +676,7 @@ TEST_F(ClientCertResourceLoaderTest, CancelSelection) { // Check if the SelectClientCertificate was called on the content browser // client. EXPECT_EQ(1, test_client.call_count()); - EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); + EXPECT_EQ(net::ClientCertIdentityList(), test_client.passed_identities()); // Cancel the request. test_client.CancelCertificateSelection(); diff --git a/chromium/content/browser/loader/resource_message_filter.cc b/chromium/content/browser/loader/resource_message_filter.cc index 57d7409ec26..b584b3cd2fd 100644 --- a/chromium/content/browser/loader/resource_message_filter.cc +++ b/chromium/content/browser/loader/resource_message_filter.cc @@ -90,11 +90,13 @@ void ResourceMessageFilter::CreateLoaderAndStart( int32_t request_id, uint32_t options, const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client) { + mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { DCHECK_EQ(options, mojom::kURLLoadOptionNone); URLLoaderFactoryImpl::CreateLoaderAndStart( requester_info_.get(), std::move(request), routing_id, request_id, - url_request, std::move(client)); + url_request, std::move(client), + net::NetworkTrafficAnnotationTag(traffic_annotation)); } void ResourceMessageFilter::SyncLoad(int32_t routing_id, diff --git a/chromium/content/browser/loader/resource_message_filter.h b/chromium/content/browser/loader/resource_message_filter.h index 4e4d580b276..b318a5526b6 100644 --- a/chromium/content/browser/loader/resource_message_filter.h +++ b/chromium/content/browser/loader/resource_message_filter.h @@ -14,10 +14,11 @@ #include "base/sequenced_task_runner_helpers.h" #include "base/single_thread_task_runner.h" #include "content/common/content_export.h" -#include "content/common/url_loader_factory.mojom.h" #include "content/public/browser/browser_associated_interface.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/common/resource_type.h" +#include "content/public/common/url_loader_factory.mojom.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace storage { class FileSystemContext; @@ -75,7 +76,10 @@ class CONTENT_EXPORT ResourceMessageFilter int32_t request_id, uint32_t options, const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client) override; + mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override; + void SyncLoad(int32_t routing_id, int32_t request_id, const ResourceRequest& request, diff --git a/chromium/content/browser/loader/resource_request_info_impl.cc b/chromium/content/browser/loader/resource_request_info_impl.cc index 2d9e6e9071c..f81f45fef4b 100644 --- a/chromium/content/browser/loader/resource_request_info_impl.cc +++ b/chromium/content/browser/loader/resource_request_info_impl.cc @@ -150,7 +150,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl( bool report_raw_headers, bool is_async, PreviewsState previews_state, - const scoped_refptr<ResourceRequestBodyImpl> body, + const scoped_refptr<ResourceRequestBody> body, bool initiated_in_secure_context) : detachable_handler_(NULL), requester_info_(std::move(requester_info)), @@ -365,4 +365,8 @@ void ResourceRequestInfoImpl::ResetBody() { body_ = nullptr; } +void ResourceRequestInfoImpl::SetBlobHandles(BlobHandles blob_handles) { + blob_handles_ = std::move(blob_handles); +} + } // namespace content diff --git a/chromium/content/browser/loader/resource_request_info_impl.h b/chromium/content/browser/loader/resource_request_info_impl.h index d9dac75d256..a306acb03c8 100644 --- a/chromium/content/browser/loader/resource_request_info_impl.h +++ b/chromium/content/browser/loader/resource_request_info_impl.h @@ -14,14 +14,15 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/supports_user_data.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/resource_requester_info.h" -#include "content/common/resource_request_body_impl.h" -#include "content/common/url_loader.mojom.h" #include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/previews_state.h" #include "content/public/common/referrer.h" +#include "content/public/common/resource_request_body.h" #include "content/public/common/resource_type.h" +#include "content/public/common/url_loader.mojom.h" #include "net/base/load_states.h" namespace content { @@ -72,7 +73,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo, bool report_raw_headers, bool is_async, PreviewsState previews_state, - const scoped_refptr<ResourceRequestBodyImpl> body, + const scoped_refptr<ResourceRequestBody> body, bool initiated_in_secure_context); ~ResourceRequestInfoImpl() override; @@ -114,7 +115,9 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo, // request). int frame_tree_node_id() const { return frame_tree_node_id_; } - ResourceRequesterInfo* requester_info() { return requester_info_.get(); } + ResourceRequesterInfo* requester_info() const { + return requester_info_.get(); + } // Updates the data associated with this request after it is is transferred // to a new renderer process. Not all data will change during a transfer. @@ -181,7 +184,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo, do_not_prompt_for_login_ = do_not_prompt; } - const scoped_refptr<ResourceRequestBodyImpl>& body() const { return body_; } + const scoped_refptr<ResourceRequestBody>& body() const { return body_; } void ResetBody(); bool initiated_in_secure_context() const { @@ -200,6 +203,8 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo, on_transfer_ = on_transfer; } + void SetBlobHandles(BlobHandles blob_handles); + private: FRIEND_TEST_ALL_PREFIXES(ResourceDispatcherHostTest, DeletedFilterDetached); @@ -235,10 +240,13 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo, bool report_raw_headers_; bool is_async_; PreviewsState previews_state_; - scoped_refptr<ResourceRequestBodyImpl> body_; + scoped_refptr<ResourceRequestBody> body_; bool initiated_in_secure_context_; std::unique_ptr<NavigationUIData> navigation_ui_data_; + // Keeps upload body blobs alive for the duration of the request. + BlobHandles blob_handles_; + // This callback is set by MojoAsyncResourceHandler to update its mojo binding // and remote endpoint. This callback will be removed once PlzNavigate is // shipped. diff --git a/chromium/content/browser/loader/resource_scheduler.cc b/chromium/content/browser/loader/resource_scheduler.cc index 774f698c066..f2b329fc159 100644 --- a/chromium/content/browser/loader/resource_scheduler.cc +++ b/chromium/content/browser/loader/resource_scheduler.cc @@ -227,6 +227,7 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle { scheduler_(scheduler), priority_(priority), fifo_ordering_(0), + peak_delayable_requests_in_flight_(0u), host_port_pair_(net::HostPortPair::FromURL(request->url())), weak_ptr_factory_(this) { DCHECK(!request_->GetUserData(kUserDataKey)); @@ -234,6 +235,16 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle { } ~ScheduledResourceRequest() override { + if ((attributes_ & kAttributeLayoutBlocking) == kAttributeLayoutBlocking) { + UMA_HISTOGRAM_COUNTS_100( + "ResourceScheduler.PeakDelayableRequestsInFlight.LayoutBlocking", + peak_delayable_requests_in_flight_); + } + if (!((attributes_ & kAttributeDelayable) == kAttributeDelayable)) { + UMA_HISTOGRAM_COUNTS_100( + "ResourceScheduler.PeakDelayableRequestsInFlight.NonDelayable", + peak_delayable_requests_in_flight_); + } request_->RemoveUserData(kUserDataKey); scheduler_->RemoveRequest(this); } @@ -274,6 +285,11 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle { ready_ = true; } + void UpdateDelayableRequestsInFlight(size_t delayable_requests_in_flight) { + peak_delayable_requests_in_flight_ = std::max( + peak_delayable_requests_in_flight_, delayable_requests_in_flight); + } + void set_request_priority_params(const RequestPriorityParams& priority) { priority_ = priority; } @@ -328,6 +344,9 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle { ResourceScheduler* scheduler_; RequestPriorityParams priority_; uint32_t fifo_ordering_; + + // Maximum number of delayable requests in-flight when |this| was in-flight. + size_t peak_delayable_requests_in_flight_; // Cached to excessive recomputation in ShouldKeepSearching. const net::HostPortPair host_port_pair_; @@ -494,9 +513,40 @@ class ResourceScheduler::Client { YIELD_SCHEDULER }; + // Records the metrics related to number of requests in flight. + void RecordRequestCountMetrics() const { + UMA_HISTOGRAM_COUNTS_100("ResourceScheduler.RequestsCount.All", + in_flight_requests_.size()); + UMA_HISTOGRAM_COUNTS_100("ResourceScheduler.RequestsCount.Delayable", + in_flight_delayable_count_); + UMA_HISTOGRAM_COUNTS_100( + "ResourceScheduler.RequestsCount.NonDelayable", + in_flight_requests_.size() - in_flight_delayable_count_); + UMA_HISTOGRAM_COUNTS_100( + "ResourceScheduler.RequestsCount.TotalLayoutBlocking", + total_layout_blocking_count_); + } + void InsertInFlightRequest(ScheduledResourceRequest* request) { in_flight_requests_.insert(request); SetRequestAttributes(request, DetermineRequestAttributes(request)); + RecordRequestCountMetrics(); + + if (RequestAttributesAreSet(request->attributes(), kAttributeDelayable)) { + // Notify all in-flight with the new count of in-flight delayable + // requests. + for (RequestSet::const_iterator it = in_flight_requests_.begin(); + it != in_flight_requests_.end(); ++it) { + (*it)->UpdateDelayableRequestsInFlight(in_flight_delayable_count_); + } + } + + if (RequestAttributesAreSet(request->attributes(), + kAttributeLayoutBlocking) || + !RequestAttributesAreSet(request->attributes(), kAttributeDelayable)) { + // |request| is either a layout blocking or a non-delayable request. + request->UpdateDelayableRequestsInFlight(in_flight_delayable_count_); + } } void EraseInFlightRequest(ScheduledResourceRequest* request) { @@ -894,6 +944,7 @@ ResourceScheduler::ResourceScheduler() kMaxRequestsBeforeYieldingDefault)) {} ResourceScheduler::~ResourceScheduler() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(unowned_requests_.empty()); DCHECK(client_map_.empty()); } @@ -903,7 +954,7 @@ std::unique_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest( int route_id, bool is_async, net::URLRequest* url_request) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClientId client_id = MakeClientId(child_id, route_id); std::unique_ptr<ScheduledResourceRequest> request( new ScheduledResourceRequest( @@ -927,7 +978,7 @@ std::unique_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest( } void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (base::ContainsKey(unowned_requests_, request)) { unowned_requests_.erase(request); return; @@ -944,7 +995,7 @@ void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) { void ResourceScheduler::OnClientCreated(int child_id, int route_id) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClientId client_id = MakeClientId(child_id, route_id); DCHECK(!base::ContainsKey(client_map_, client_id)); @@ -955,7 +1006,7 @@ void ResourceScheduler::OnClientCreated(int child_id, } void ResourceScheduler::OnClientDeleted(int child_id, int route_id) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClientId client_id = MakeClientId(child_id, route_id); ClientMap::iterator it = client_map_.find(client_id); DCHECK(it != client_map_.end()); @@ -983,7 +1034,7 @@ void ResourceScheduler::OnLoadingStateChanged(int child_id, } void ResourceScheduler::OnNavigate(int child_id, int route_id) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClientId client_id = MakeClientId(child_id, route_id); ClientMap::iterator it = client_map_.find(client_id); @@ -997,7 +1048,7 @@ void ResourceScheduler::OnNavigate(int child_id, int route_id) { } void ResourceScheduler::OnWillInsertBody(int child_id, int route_id) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClientId client_id = MakeClientId(child_id, route_id); ClientMap::iterator it = client_map_.find(client_id); @@ -1013,7 +1064,7 @@ void ResourceScheduler::OnWillInsertBody(int child_id, int route_id) { void ResourceScheduler::OnReceivedSpdyProxiedHttpResponse( int child_id, int route_id) { - DCHECK(CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ClientId client_id = MakeClientId(child_id, route_id); ClientMap::iterator client_it = client_map_.find(client_id); diff --git a/chromium/content/browser/loader/resource_scheduler.h b/chromium/content/browser/loader/resource_scheduler.h index 71014ce122f..9e112298297 100644 --- a/chromium/content/browser/loader/resource_scheduler.h +++ b/chromium/content/browser/loader/resource_scheduler.h @@ -14,7 +14,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/threading/non_thread_safe.h" +#include "base/sequence_checker.h" #include "content/common/content_export.h" #include "net/base/priority_queue.h" #include "net/base/request_priority.h" @@ -52,7 +52,7 @@ class ResourceThrottle; // The scheduler may defer issuing the request via the ResourceThrottle // interface or it may alter the request's priority by calling set_priority() on // the URLRequest. -class CONTENT_EXPORT ResourceScheduler : public base::NonThreadSafe { +class CONTENT_EXPORT ResourceScheduler { public: ResourceScheduler(); ~ResourceScheduler(); @@ -109,12 +109,6 @@ class CONTENT_EXPORT ResourceScheduler : public base::NonThreadSafe { net::RequestPriority new_priority); private: - // Returns the maximum number of delayable requests to all be in-flight at - // any point in time (across all hosts). - size_t max_num_delayable_requests() const { - return max_num_delayable_requests_; - } - class RequestQueue; class ScheduledResourceRequest; struct RequestPriorityParams; @@ -138,7 +132,6 @@ class CONTENT_EXPORT ResourceScheduler : public base::NonThreadSafe { Client* GetClient(int child_id, int route_id); ClientMap client_map_; - size_t max_num_delayable_requests_; RequestSet unowned_requests_; // True if requests to servers that support priorities (e.g., H2/QUIC) can @@ -150,6 +143,8 @@ class CONTENT_EXPORT ResourceScheduler : public base::NonThreadSafe { bool yielding_scheduler_enabled_; int max_requests_before_yielding_; + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(ResourceScheduler); }; diff --git a/chromium/content/browser/loader/resource_scheduler_unittest.cc b/chromium/content/browser/loader/resource_scheduler_unittest.cc index 482b08c4337..15b1dcc019d 100644 --- a/chromium/content/browser/loader/resource_scheduler_unittest.cc +++ b/chromium/content/browser/loader/resource_scheduler_unittest.cc @@ -13,6 +13,7 @@ #include "base/metrics/field_trial_param_associator.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/test/histogram_tester.h" #include "base/test/mock_entropy_provider.h" #include "base/test/scoped_feature_list.h" #include "base/timer/mock_timer.h" @@ -30,6 +31,7 @@ #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/latency/latency_info.h" #include "url/scheme_host_port.h" @@ -505,15 +507,38 @@ TEST_F(ResourceSchedulerTest, SpdyLowBlocksOtherLowUntilBodyInserted) { } TEST_F(ResourceSchedulerTest, NavigationResetsState) { + base::HistogramTester histogram_tester; scheduler()->OnWillInsertBody(kChildId, kRouteId); scheduler()->OnNavigate(kChildId, kRouteId); - std::unique_ptr<TestRequest> high( - NewRequest("http://host/high", net::HIGHEST)); - std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST)); - std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST)); - EXPECT_TRUE(high->started()); - EXPECT_TRUE(low->started()); - EXPECT_FALSE(low2->started()); + + { + std::unique_ptr<TestRequest> high( + NewRequest("http://host/high", net::HIGHEST)); + std::unique_ptr<TestRequest> low( + NewRequest("http://host/low", net::LOWEST)); + std::unique_ptr<TestRequest> low2( + NewRequest("http://host/low", net::LOWEST)); + EXPECT_TRUE(high->started()); + EXPECT_TRUE(low->started()); + EXPECT_FALSE(low2->started()); + } + + histogram_tester.ExpectTotalCount("ResourceScheduler.RequestsCount.All", 2); + EXPECT_THAT( + histogram_tester.GetAllSamples("ResourceScheduler.RequestsCount.All"), + testing::ElementsAre(base::Bucket(1, 1), base::Bucket(2, 1))); + + histogram_tester.ExpectTotalCount("ResourceScheduler.RequestsCount.Delayable", + 2); + histogram_tester.ExpectTotalCount( + "ResourceScheduler.RequestsCount.NonDelayable", 2); + histogram_tester.ExpectTotalCount( + "ResourceScheduler.RequestsCount.TotalLayoutBlocking", 2); + + histogram_tester.ExpectUniqueSample( + "ResourceScheduler.PeakDelayableRequestsInFlight.LayoutBlocking", 1, 1); + histogram_tester.ExpectUniqueSample( + "ResourceScheduler.PeakDelayableRequestsInFlight.NonDelayable", 1, 1); } TEST_F(ResourceSchedulerTest, BackgroundRequestStartsImmediately) { diff --git a/chromium/content/browser/loader/temporary_file_stream.cc b/chromium/content/browser/loader/temporary_file_stream.cc index 74ca4920b4a..f1493e705bb 100644 --- a/chromium/content/browser/loader/temporary_file_stream.cc +++ b/chromium/content/browser/loader/temporary_file_stream.cc @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/files/file_proxy.h" #include "base/memory/ref_counted.h" +#include "base/task_scheduler/post_task.h" #include "content/public/browser/browser_thread.h" #include "net/base/file_stream.h" #include "storage/browser/blob/shareable_file_reference.h" @@ -20,10 +21,12 @@ namespace content { namespace { -void DidCreateTemporaryFile(const CreateTemporaryFileStreamCallback& callback, - std::unique_ptr<base::FileProxy> file_proxy, - base::File::Error error_code, - const base::FilePath& file_path) { +void DidCreateTemporaryFile( + const CreateTemporaryFileStreamCallback& callback, + std::unique_ptr<base::FileProxy> file_proxy, + scoped_refptr<base::SequencedTaskRunner> task_runner, + base::File::Error error_code, + const base::FilePath& file_path) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!file_proxy->IsValid()) { @@ -31,9 +34,6 @@ void DidCreateTemporaryFile(const CreateTemporaryFileStreamCallback& callback, return; } - scoped_refptr<base::TaskRunner> task_runner = - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE); - // Cancelled or not, create the deletable_file so the temporary is cleaned up. scoped_refptr<ShareableFileReference> deletable_file = ShareableFileReference::GetOrCreate( @@ -53,12 +53,18 @@ void CreateTemporaryFileStream( const CreateTemporaryFileStreamCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - std::unique_ptr<base::FileProxy> file_proxy(new base::FileProxy( - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get())); + scoped_refptr<base::SequencedTaskRunner> task_runner = + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); + + std::unique_ptr<base::FileProxy> file_proxy( + new base::FileProxy(task_runner.get())); base::FileProxy* proxy = file_proxy.get(); proxy->CreateTemporary( base::File::FLAG_ASYNC, - base::Bind(&DidCreateTemporaryFile, callback, Passed(&file_proxy))); + base::Bind(&DidCreateTemporaryFile, callback, Passed(&file_proxy), + std::move(task_runner))); } } // namespace content diff --git a/chromium/content/browser/loader/temporary_file_stream_unittest.cc b/chromium/content/browser/loader/temporary_file_stream_unittest.cc index 4db92d3111c..939d0aae3e0 100644 --- a/chromium/content/browser/loader/temporary_file_stream_unittest.cc +++ b/chromium/content/browser/loader/temporary_file_stream_unittest.cc @@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "net/base/file_stream.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -111,7 +112,7 @@ TEST(TemporaryFileStreamTest, Basic) { // Release everything. The file should be gone now. file_stream_waiter.Release(); - base::RunLoop().RunUntilIdle(); + content::RunAllBlockingPoolTasksUntilIdle(); // The temporary should be gone now. EXPECT_FALSE(base::PathExists(file_path)); diff --git a/chromium/content/browser/loader/test_url_loader_client.cc b/chromium/content/browser/loader/test_url_loader_client.cc deleted file mode 100644 index 7bee53631b7..00000000000 --- a/chromium/content/browser/loader/test_url_loader_client.cc +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/loader/test_url_loader_client.h" - -#include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -TestURLLoaderClient::TestURLLoaderClient() : binding_(this) {} -TestURLLoaderClient::~TestURLLoaderClient() {} - -void TestURLLoaderClient::OnReceiveResponse( - const ResourceResponseHead& response_head, - const base::Optional<net::SSLInfo>& ssl_info, - mojom::DownloadedTempFilePtr downloaded_file) { - EXPECT_FALSE(has_received_response_); - EXPECT_FALSE(has_received_cached_metadata_); - EXPECT_FALSE(has_received_completion_); - has_received_response_ = true; - response_head_ = response_head; - ssl_info_ = ssl_info; - if (quit_closure_for_on_receive_response_) - quit_closure_for_on_receive_response_.Run(); -} - -void TestURLLoaderClient::OnReceiveRedirect( - const net::RedirectInfo& redirect_info, - const ResourceResponseHead& response_head) { - EXPECT_FALSE(has_received_cached_metadata_); - EXPECT_FALSE(response_body_.is_valid()); - EXPECT_FALSE(has_received_response_); - // Use ClearHasReceivedRedirect to accept more redirects. - EXPECT_FALSE(has_received_redirect_); - EXPECT_FALSE(has_received_completion_); - has_received_redirect_ = true; - redirect_info_ = redirect_info; - response_head_ = response_head; - if (quit_closure_for_on_receive_redirect_) - quit_closure_for_on_receive_redirect_.Run(); -} - -void TestURLLoaderClient::OnDataDownloaded(int64_t data_length, - int64_t encoded_data_length) { - EXPECT_TRUE(has_received_response_); - EXPECT_FALSE(has_received_completion_); - has_data_downloaded_ = true; - download_data_length_ += data_length; - encoded_download_data_length_ += encoded_data_length; - if (quit_closure_for_on_data_downloaded_) - quit_closure_for_on_data_downloaded_.Run(); -} - -void TestURLLoaderClient::OnReceiveCachedMetadata( - const std::vector<uint8_t>& data) { - EXPECT_FALSE(has_received_cached_metadata_); - EXPECT_TRUE(has_received_response_); - EXPECT_FALSE(has_received_completion_); - has_received_cached_metadata_ = true; - cached_metadata_ = - std::string(reinterpret_cast<const char*>(data.data()), data.size()); - if (quit_closure_for_on_receive_cached_metadata_) - quit_closure_for_on_receive_cached_metadata_.Run(); -} - -void TestURLLoaderClient::OnTransferSizeUpdated(int32_t transfer_size_diff) { - EXPECT_TRUE(has_received_response_); - EXPECT_FALSE(has_received_completion_); - EXPECT_GT(transfer_size_diff, 0); - body_transfer_size_ += transfer_size_diff; -} - -void TestURLLoaderClient::OnUploadProgress( - int64_t current_position, - int64_t total_size, - OnUploadProgressCallback ack_callback) { - EXPECT_TRUE(ack_callback); - EXPECT_FALSE(has_received_response_); - EXPECT_FALSE(has_received_completion_); - EXPECT_LT(0, current_position); - EXPECT_LE(current_position, total_size); - - has_received_upload_progress_ = true; - current_upload_position_ = current_position; - total_upload_size_ = total_size; - std::move(ack_callback).Run(); -} - -void TestURLLoaderClient::OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) { - EXPECT_TRUE(has_received_response_); - EXPECT_FALSE(has_received_completion_); - response_body_ = std::move(body); - if (quit_closure_for_on_start_loading_response_body_) - quit_closure_for_on_start_loading_response_body_.Run(); -} - -void TestURLLoaderClient::OnComplete( - const ResourceRequestCompletionStatus& status) { - EXPECT_FALSE(has_received_completion_); - has_received_completion_ = true; - completion_status_ = status; - if (quit_closure_for_on_complete_) - quit_closure_for_on_complete_.Run(); -} - -void TestURLLoaderClient::ClearHasReceivedRedirect() { - has_received_redirect_ = false; -} - -mojom::URLLoaderClientPtr TestURLLoaderClient::CreateInterfacePtr() { - mojom::URLLoaderClientPtr client_ptr; - binding_.Bind(mojo::MakeRequest(&client_ptr)); - return client_ptr; -} - -void TestURLLoaderClient::Unbind() { - binding_.Unbind(); - response_body_.reset(); -} - -void TestURLLoaderClient::RunUntilResponseReceived() { - if (has_received_response_) - return; - base::RunLoop run_loop; - quit_closure_for_on_receive_response_ = run_loop.QuitClosure(); - run_loop.Run(); - quit_closure_for_on_receive_response_.Reset(); -} - -void TestURLLoaderClient::RunUntilRedirectReceived() { - if (has_received_redirect_) - return; - base::RunLoop run_loop; - quit_closure_for_on_receive_redirect_ = run_loop.QuitClosure(); - run_loop.Run(); - quit_closure_for_on_receive_redirect_.Reset(); -} - -void TestURLLoaderClient::RunUntilDataDownloaded() { - if (has_data_downloaded_) - return; - base::RunLoop run_loop; - quit_closure_for_on_data_downloaded_ = run_loop.QuitClosure(); - run_loop.Run(); - quit_closure_for_on_data_downloaded_.Reset(); -} - -void TestURLLoaderClient::RunUntilCachedMetadataReceived() { - if (has_received_cached_metadata_) - return; - base::RunLoop run_loop; - quit_closure_for_on_receive_cached_metadata_ = run_loop.QuitClosure(); - run_loop.Run(); - quit_closure_for_on_receive_cached_metadata_.Reset(); -} - -void TestURLLoaderClient::RunUntilResponseBodyArrived() { - if (response_body_.is_valid()) - return; - base::RunLoop run_loop; - quit_closure_for_on_start_loading_response_body_ = run_loop.QuitClosure(); - run_loop.Run(); - quit_closure_for_on_start_loading_response_body_.Reset(); -} - -void TestURLLoaderClient::RunUntilComplete() { - if (has_received_completion_) - return; - base::RunLoop run_loop; - quit_closure_for_on_complete_ = run_loop.QuitClosure(); - run_loop.Run(); - quit_closure_for_on_complete_.Reset(); -} - -} // namespace content diff --git a/chromium/content/browser/loader/test_url_loader_client.h b/chromium/content/browser/loader/test_url_loader_client.h deleted file mode 100644 index ba50bc794e6..00000000000 --- a/chromium/content/browser/loader/test_url_loader_client.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_LOADER_TEST_URL_LOADER_CLIENT_H_ -#define CONTENT_BROWSER_LOADER_TEST_URL_LOADER_CLIENT_H_ - -#include <stdint.h> -#include <vector> - -#include "base/callback.h" -#include "base/macros.h" -#include "content/common/resource_request_completion_status.h" -#include "content/common/url_loader.mojom.h" -#include "content/common/url_loader_factory.mojom.h" -#include "content/public/common/resource_response.h" -#include "mojo/public/c/system/data_pipe.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "net/url_request/redirect_info.h" - -namespace content { - -// A TestURLLoaderClient records URLLoaderClient function calls. It also calls -// the closure set via set_quit_closure if set, in order to make it possible to -// create a base::RunLoop, set its quit closure to this client and then run the -// RunLoop. -class TestURLLoaderClient final : public mojom::URLLoaderClient { - public: - TestURLLoaderClient(); - ~TestURLLoaderClient() override; - - void OnReceiveResponse(const ResourceResponseHead& response_head, - const base::Optional<net::SSLInfo>& ssl_info, - mojom::DownloadedTempFilePtr downloaded_file) override; - void OnReceiveRedirect(const net::RedirectInfo& redirect_info, - const ResourceResponseHead& response_head) override; - void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override; - void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override; - void OnTransferSizeUpdated(int32_t transfer_size_diff) override; - void OnUploadProgress(int64_t current_position, - int64_t total_size, - OnUploadProgressCallback ack_callback) override; - void OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) override; - void OnComplete(const ResourceRequestCompletionStatus& status) override; - - bool has_received_response() const { return has_received_response_; } - bool has_received_redirect() const { return has_received_redirect_; } - bool has_data_downloaded() const { return has_data_downloaded_; } - bool has_received_upload_progress() const { - return has_received_upload_progress_; - } - bool has_received_cached_metadata() const { - return has_received_cached_metadata_; - } - bool has_received_completion() const { return has_received_completion_; } - const ResourceResponseHead& response_head() const { return response_head_; } - const base::Optional<net::SSLInfo>& ssl_info() const { return ssl_info_; } - const net::RedirectInfo& redirect_info() const { return redirect_info_; } - const std::string& cached_metadata() const { - return cached_metadata_; - } - mojo::DataPipeConsumerHandle response_body() { return response_body_.get(); } - const ResourceRequestCompletionStatus& completion_status() const { - return completion_status_; - } - int64_t download_data_length() const { return download_data_length_; } - int64_t encoded_download_data_length() const { - return encoded_download_data_length_; - } - int64_t body_transfer_size() const { return body_transfer_size_; } - int64_t current_upload_position() const { return current_upload_position_; } - int64_t total_upload_size() const { return total_upload_size_; } - - void reset_has_received_upload_progress() { - has_received_upload_progress_ = false; - } - - void ClearHasReceivedRedirect(); - // Creates an InterfacePtr, binds it to |*this| and returns it. - mojom::URLLoaderClientPtr CreateInterfacePtr(); - - void Unbind(); - - void RunUntilResponseReceived(); - void RunUntilRedirectReceived(); - void RunUntilDataDownloaded(); - void RunUntilCachedMetadataReceived(); - void RunUntilResponseBodyArrived(); - void RunUntilComplete(); - - private: - mojo::Binding<mojom::URLLoaderClient> binding_; - ResourceResponseHead response_head_; - base::Optional<net::SSLInfo> ssl_info_; - net::RedirectInfo redirect_info_; - std::string cached_metadata_; - mojo::ScopedDataPipeConsumerHandle response_body_; - ResourceRequestCompletionStatus completion_status_; - bool has_received_response_ = false; - bool has_received_redirect_ = false; - bool has_data_downloaded_ = false; - bool has_received_upload_progress_ = false; - bool has_received_cached_metadata_ = false; - bool has_received_completion_ = false; - base::Closure quit_closure_for_on_receive_response_; - base::Closure quit_closure_for_on_receive_redirect_; - base::Closure quit_closure_for_on_data_downloaded_; - base::Closure quit_closure_for_on_receive_cached_metadata_; - base::Closure quit_closure_for_on_start_loading_response_body_; - base::Closure quit_closure_for_on_complete_; - mojom::URLLoaderFactoryPtr url_loader_factory_; - int64_t download_data_length_ = 0; - int64_t encoded_download_data_length_ = 0; - int64_t body_transfer_size_ = 0; - int64_t current_upload_position_ = 0; - int64_t total_upload_size_ = 0; - - DISALLOW_COPY_AND_ASSIGN(TestURLLoaderClient); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_LOADER_TEST_URL_LOADER_CLIENT_H_ diff --git a/chromium/content/browser/loader/upload_data_stream_builder.cc b/chromium/content/browser/loader/upload_data_stream_builder.cc index 389a8e9b394..ba96cb2de5a 100644 --- a/chromium/content/browser/loader/upload_data_stream_builder.cc +++ b/chromium/content/browser/loader/upload_data_stream_builder.cc @@ -16,7 +16,7 @@ #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "content/browser/fileapi/upload_file_system_file_element_reader.h" -#include "content/common/resource_request_body_impl.h" +#include "content/public/common/resource_request_body.h" #include "net/base/elements_upload_data_stream.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_file_element_reader.h" @@ -37,46 +37,46 @@ namespace content { namespace { // A subclass of net::UploadBytesElementReader which owns -// ResourceRequestBodyImpl. +// ResourceRequestBody. class BytesElementReader : public net::UploadBytesElementReader { public: - BytesElementReader(ResourceRequestBodyImpl* resource_request_body, - const ResourceRequestBodyImpl::Element& element) + BytesElementReader(ResourceRequestBody* resource_request_body, + const ResourceRequestBody::Element& element) : net::UploadBytesElementReader(element.bytes(), element.length()), resource_request_body_(resource_request_body) { - DCHECK_EQ(ResourceRequestBodyImpl::Element::TYPE_BYTES, element.type()); + DCHECK_EQ(ResourceRequestBody::Element::TYPE_BYTES, element.type()); } ~BytesElementReader() override {} private: - scoped_refptr<ResourceRequestBodyImpl> resource_request_body_; + scoped_refptr<ResourceRequestBody> resource_request_body_; DISALLOW_COPY_AND_ASSIGN(BytesElementReader); }; // A subclass of net::UploadFileElementReader which owns -// ResourceRequestBodyImpl. +// ResourceRequestBody. // This class is necessary to ensure the BlobData and any attached shareable // files survive until upload completion. class FileElementReader : public net::UploadFileElementReader { public: - FileElementReader(ResourceRequestBodyImpl* resource_request_body, + FileElementReader(ResourceRequestBody* resource_request_body, base::TaskRunner* task_runner, - const ResourceRequestBodyImpl::Element& element) + const ResourceRequestBody::Element& element) : net::UploadFileElementReader(task_runner, element.path(), element.offset(), element.length(), element.expected_modification_time()), resource_request_body_(resource_request_body) { - DCHECK_EQ(ResourceRequestBodyImpl::Element::TYPE_FILE, element.type()); + DCHECK_EQ(ResourceRequestBody::Element::TYPE_FILE, element.type()); } ~FileElementReader() override {} private: - scoped_refptr<ResourceRequestBodyImpl> resource_request_body_; + scoped_refptr<ResourceRequestBody> resource_request_body_; DISALLOW_COPY_AND_ASSIGN(FileElementReader); }; @@ -84,22 +84,22 @@ class FileElementReader : public net::UploadFileElementReader { } // namespace std::unique_ptr<net::UploadDataStream> UploadDataStreamBuilder::Build( - ResourceRequestBodyImpl* body, + ResourceRequestBody* body, storage::BlobStorageContext* blob_context, storage::FileSystemContext* file_system_context, base::SingleThreadTaskRunner* file_task_runner) { std::vector<std::unique_ptr<net::UploadElementReader>> element_readers; for (const auto& element : *body->elements()) { switch (element.type()) { - case ResourceRequestBodyImpl::Element::TYPE_BYTES: + case ResourceRequestBody::Element::TYPE_BYTES: element_readers.push_back( base::MakeUnique<BytesElementReader>(body, element)); break; - case ResourceRequestBodyImpl::Element::TYPE_FILE: + case ResourceRequestBody::Element::TYPE_FILE: element_readers.push_back(base::MakeUnique<FileElementReader>( body, file_task_runner, element)); break; - case ResourceRequestBodyImpl::Element::TYPE_FILE_FILESYSTEM: + case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM: // If |body| contains any filesystem URLs, the caller should have // supplied a FileSystemContext. DCHECK(file_system_context); @@ -108,19 +108,19 @@ std::unique_ptr<net::UploadDataStream> UploadDataStreamBuilder::Build( file_system_context, element.filesystem_url(), element.offset(), element.length(), element.expected_modification_time())); break; - case ResourceRequestBodyImpl::Element::TYPE_BLOB: { + case ResourceRequestBody::Element::TYPE_BLOB: { DCHECK_EQ(std::numeric_limits<uint64_t>::max(), element.length()); DCHECK_EQ(0ul, element.offset()); std::unique_ptr<storage::BlobDataHandle> handle = blob_context->GetBlobDataFromUUID(element.blob_uuid()); element_readers.push_back( base::MakeUnique<storage::UploadBlobElementReader>( - std::move(handle), file_system_context, file_task_runner)); + std::move(handle), file_system_context)); break; } - case ResourceRequestBodyImpl::Element::TYPE_DISK_CACHE_ENTRY: - case ResourceRequestBodyImpl::Element::TYPE_BYTES_DESCRIPTION: - case ResourceRequestBodyImpl::Element::TYPE_UNKNOWN: + case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY: + case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION: + case ResourceRequestBody::Element::TYPE_UNKNOWN: NOTREACHED(); break; } diff --git a/chromium/content/browser/loader/upload_data_stream_builder.h b/chromium/content/browser/loader/upload_data_stream_builder.h index 9b2bfcbf275..fae5f3a70ca 100644 --- a/chromium/content/browser/loader/upload_data_stream_builder.h +++ b/chromium/content/browser/loader/upload_data_stream_builder.h @@ -27,7 +27,7 @@ class BlobStorageContext; namespace content { -class ResourceRequestBodyImpl; +class ResourceRequestBody; class CONTENT_EXPORT UploadDataStreamBuilder { public: @@ -35,14 +35,14 @@ class CONTENT_EXPORT UploadDataStreamBuilder { // // If |body| contains any blob references, the caller is responsible for // making sure them outlive the returned value of UploadDataStream. We do this - // by binding the BlobDataHandles of them to ResourceRequestBodyImpl in + // by binding the BlobDataHandles of them to ResourceRequestBody in // ResourceDispatcherHostImpl::BeginRequest(). // // |file_system_context| is used to create a FileStreamReader for files with // filesystem URLs. |file_task_runner| is used to perform file operations // when the data gets uploaded. static std::unique_ptr<net::UploadDataStream> Build( - ResourceRequestBodyImpl* body, + ResourceRequestBody* body, storage::BlobStorageContext* blob_context, storage::FileSystemContext* file_system_context, base::SingleThreadTaskRunner* file_task_runner); diff --git a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc index 26058d75b02..a6aab0887ba 100644 --- a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc +++ b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc @@ -12,11 +12,11 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "content/common/resource_request_body_impl.h" +#include "content/public/common/resource_request_body.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" @@ -38,10 +38,9 @@ using storage::BlobStorageContext; namespace content { TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) { - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment scoped_task_environment_; { - scoped_refptr<ResourceRequestBodyImpl> request_body = - new ResourceRequestBodyImpl; + scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; const std::string kBlob = "blobuuid"; const std::string kBlobData = "blobdata"; @@ -98,7 +97,8 @@ TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) { TEST(UploadDataStreamBuilderTest, WriteUploadDataStreamWithEmptyFileBackedBlob) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO); { base::FilePath test_blob_path; ASSERT_TRUE(base::CreateTemporaryFile(&test_blob_path)); @@ -119,14 +119,13 @@ TEST(UploadDataStreamBuilderTest, std::unique_ptr<BlobDataHandle> handle = blob_storage_context.AddFinishedBlob(blob_data_builder.get()); - scoped_refptr<ResourceRequestBodyImpl> request_body( - new ResourceRequestBodyImpl()); + scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); std::unique_ptr<net::UploadDataStream> upload( UploadDataStreamBuilder::Build( request_body.get(), &blob_storage_context, NULL, base::ThreadTaskRunnerHandle::Get().get())); - request_body = new ResourceRequestBodyImpl(); + request_body = new ResourceRequestBody(); request_body->AppendBlob(blob_id); request_body->AppendBlob(blob_id); request_body->AppendBlob(blob_id); @@ -163,10 +162,10 @@ TEST(UploadDataStreamBuilderTest, } TEST(UploadDataStreamBuilderTest, ResetUploadStreamWithBlob) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO); { - scoped_refptr<ResourceRequestBodyImpl> request_body = - new ResourceRequestBodyImpl; + scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; const std::string kBlob = "blobuuid"; const std::string kBlobData = "blobdata"; diff --git a/chromium/content/browser/loader/upload_progress_tracker.cc b/chromium/content/browser/loader/upload_progress_tracker.cc index 6633e61b7ec..f9fe05ba04a 100644 --- a/chromium/content/browser/loader/upload_progress_tracker.cc +++ b/chromium/content/browser/loader/upload_progress_tracker.cc @@ -19,7 +19,7 @@ UploadProgressTracker::UploadProgressTracker( const tracked_objects::Location& location, UploadProgressReportCallback report_progress, net::URLRequest* request, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) + scoped_refptr<base::SequencedTaskRunner> task_runner) : request_(request), report_progress_(std::move(report_progress)) { DCHECK(report_progress_); @@ -40,6 +40,11 @@ void UploadProgressTracker::OnUploadCompleted() { progress_timer_.Stop(); } +// static +base::TimeDelta UploadProgressTracker::GetUploadProgressIntervalForTesting() { + return kUploadProgressInterval; +} + base::TimeTicks UploadProgressTracker::GetCurrentTime() const { return base::TimeTicks::Now(); } diff --git a/chromium/content/browser/loader/upload_progress_tracker.h b/chromium/content/browser/loader/upload_progress_tracker.h index 6840f5a60bc..236ced27a5f 100644 --- a/chromium/content/browser/loader/upload_progress_tracker.h +++ b/chromium/content/browser/loader/upload_progress_tracker.h @@ -10,17 +10,13 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/sequenced_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "content/common/content_export.h" #include "net/base/upload_progress.h" -namespace base { -class SingleThreadTaskRunner; -} - namespace tracked_objects { class Location; } @@ -41,13 +37,15 @@ class CONTENT_EXPORT UploadProgressTracker { UploadProgressTracker(const tracked_objects::Location& location, UploadProgressReportCallback report_progress, net::URLRequest* request, - scoped_refptr<base::SingleThreadTaskRunner> - task_runner = base::ThreadTaskRunnerHandle::Get()); + scoped_refptr<base::SequencedTaskRunner> task_runner = + base::SequencedTaskRunnerHandle::Get()); ~UploadProgressTracker(); void OnAckReceived(); void OnUploadCompleted(); + static base::TimeDelta GetUploadProgressIntervalForTesting(); + private: // Overridden by tests to use a fake time and progress. virtual base::TimeTicks GetCurrentTime() const; diff --git a/chromium/content/browser/loader/upload_progress_tracker_unittest.cc b/chromium/content/browser/loader/upload_progress_tracker_unittest.cc index cf556db2c94..363ae990eb1 100644 --- a/chromium/content/browser/loader/upload_progress_tracker_unittest.cc +++ b/chromium/content/browser/loader/upload_progress_tracker_unittest.cc @@ -9,7 +9,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" -#include "base/test/test_simple_task_runner.h" +#include "base/test/test_mock_time_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "net/base/upload_progress.h" #include "testing/gtest/include/gtest/gtest.h" @@ -54,13 +55,13 @@ class TestingUploadProgressTracker : public UploadProgressTracker { class UploadProgressTrackerTest : public ::testing::Test { public: UploadProgressTrackerTest() - : task_runner_(new base::TestSimpleTaskRunner), + : task_runner_handle_(mock_task_runner_), upload_progress_tracker_( FROM_HERE, base::BindRepeating( &UploadProgressTrackerTest::OnUploadProgressReported, base::Unretained(this)), - task_runner_) {} + mock_task_runner_) {} private: void OnUploadProgressReported(const net::UploadProgress& progress) { @@ -74,7 +75,12 @@ class UploadProgressTrackerTest : public ::testing::Test { int64_t reported_position_ = 0; int64_t reported_total_size_ = 0; - scoped_refptr<base::TestSimpleTaskRunner> task_runner_; + // Mocks the current thread's task runner which will also be used as the + // UploadProgressTracker's task runner. + scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_ = + new base::TestMockTimeTaskRunner; + base::ThreadTaskRunnerHandle task_runner_handle_; + TestingUploadProgressTracker upload_progress_tracker_; DISALLOW_COPY_AND_ASSIGN(UploadProgressTrackerTest); @@ -85,7 +91,8 @@ TEST_F(UploadProgressTrackerTest, NoACK) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(500, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -94,7 +101,8 @@ TEST_F(UploadProgressTrackerTest, NoACK) { // The second timer task does nothing, since the first report didn't send the // ACK. - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); } @@ -103,7 +111,8 @@ TEST_F(UploadProgressTrackerTest, NoUpload) { // UploadProgressTracker does nothing on the empty upload content. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(0, report_count_); } @@ -112,7 +121,8 @@ TEST_F(UploadProgressTrackerTest, NoProgress) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(500, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -122,7 +132,8 @@ TEST_F(UploadProgressTrackerTest, NoProgress) { // The second time doesn't call ReportUploadProgress since there's no // progress. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); } @@ -131,7 +142,8 @@ TEST_F(UploadProgressTrackerTest, Finished) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(999, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -142,7 +154,8 @@ TEST_F(UploadProgressTrackerTest, Finished) { // The second timer task calls ReportUploadProgress for reporting the // completion. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(2, report_count_); EXPECT_EQ(1000, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -153,7 +166,8 @@ TEST_F(UploadProgressTrackerTest, Progress) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(500, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -164,7 +178,8 @@ TEST_F(UploadProgressTrackerTest, Progress) { // The second timer task calls ReportUploadProgress since the progress is // big enough to report. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(2, report_count_); EXPECT_EQ(750, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -175,7 +190,8 @@ TEST_F(UploadProgressTrackerTest, TimePassed) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(500, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -186,7 +202,8 @@ TEST_F(UploadProgressTrackerTest, TimePassed) { // The second timer task doesn't call ReportUploadProgress since the progress // is too small to report it. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); upload_progress_tracker_.set_current_time(base::TimeTicks::Now() + @@ -195,7 +212,8 @@ TEST_F(UploadProgressTrackerTest, TimePassed) { // The third timer task calls ReportUploadProgress since it's been long time // from the last report. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(2, report_count_); EXPECT_EQ(501, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -206,7 +224,8 @@ TEST_F(UploadProgressTrackerTest, Rewound) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(500, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -217,7 +236,8 @@ TEST_F(UploadProgressTrackerTest, Rewound) { // The second timer task doesn't call ReportUploadProgress since the progress // was rewound. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); upload_progress_tracker_.set_current_time(base::TimeTicks::Now() + @@ -226,7 +246,8 @@ TEST_F(UploadProgressTrackerTest, Rewound) { // Even after a good amount of time passed, the rewound progress should not be // reported. EXPECT_EQ(1, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); } @@ -235,7 +256,8 @@ TEST_F(UploadProgressTrackerTest, Completed) { // The first timer task calls ReportUploadProgress. EXPECT_EQ(0, report_count_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(1, report_count_); EXPECT_EQ(500, reported_position_); EXPECT_EQ(1000, reported_total_size_); @@ -248,9 +270,10 @@ TEST_F(UploadProgressTrackerTest, Completed) { EXPECT_EQ(1000, reported_position_); EXPECT_EQ(1000, reported_total_size_); - task_runner_->RunPendingTasks(); + mock_task_runner_->FastForwardBy( + UploadProgressTracker::GetUploadProgressIntervalForTesting()); EXPECT_EQ(2, report_count_); - EXPECT_FALSE(task_runner_->HasPendingTask()); + EXPECT_FALSE(mock_task_runner_->HasPendingTask()); } } // namespace context diff --git a/chromium/content/browser/loader/url_loader_factory_impl.cc b/chromium/content/browser/loader/url_loader_factory_impl.cc index 048e212e7dc..1c761e55bf2 100644 --- a/chromium/content/browser/loader/url_loader_factory_impl.cc +++ b/chromium/content/browser/loader/url_loader_factory_impl.cc @@ -7,9 +7,10 @@ #include "base/memory/ptr_util.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_requester_info.h" -#include "content/common/resource_request.h" -#include "content/common/url_loader.mojom.h" +#include "content/public/common/resource_request.h" +#include "content/public/common/url_loader.mojom.h" #include "mojo/public/cpp/bindings/strong_binding.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace content { @@ -52,10 +53,13 @@ void URLLoaderFactoryImpl::CreateLoaderAndStart( int32_t request_id, uint32_t options, const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client) { + mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { DCHECK_EQ(options, mojom::kURLLoadOptionNone); - CreateLoaderAndStart(requester_info_.get(), std::move(request), routing_id, - request_id, url_request, std::move(client)); + CreateLoaderAndStart( + requester_info_.get(), std::move(request), routing_id, request_id, + url_request, std::move(client), + static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation)); } void URLLoaderFactoryImpl::SyncLoad(int32_t routing_id, @@ -73,7 +77,8 @@ void URLLoaderFactoryImpl::CreateLoaderAndStart( int32_t routing_id, int32_t request_id, const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client) { + mojom::URLLoaderClientPtr client, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(ResourceDispatcherHostImpl::Get() ->io_thread_task_runner() ->BelongsToCurrentThread()); @@ -81,7 +86,7 @@ void URLLoaderFactoryImpl::CreateLoaderAndStart( ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); rdh->OnRequestResourceWithMojo(requester_info, routing_id, request_id, url_request, std::move(request), - std::move(client)); + std::move(client), traffic_annotation); } // static diff --git a/chromium/content/browser/loader/url_loader_factory_impl.h b/chromium/content/browser/loader/url_loader_factory_impl.h index 585b21443f2..6177975c7ad 100644 --- a/chromium/content/browser/loader/url_loader_factory_impl.h +++ b/chromium/content/browser/loader/url_loader_factory_impl.h @@ -9,7 +9,8 @@ #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "content/common/content_export.h" -#include "content/common/url_loader_factory.mojom.h" +#include "content/public/common/url_loader_factory.mojom.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace content { @@ -27,18 +28,23 @@ class URLLoaderFactoryImpl final : public mojom::URLLoaderFactory { int32_t request_id, uint32_t options, const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client) override; + mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override; void SyncLoad(int32_t routing_id, int32_t request_id, const ResourceRequest& request, SyncLoadCallback callback) override; - static void CreateLoaderAndStart(ResourceRequesterInfo* requester_info, - mojom::URLLoaderAssociatedRequest request, - int32_t routing_id, - int32_t request_id, - const ResourceRequest& url_request, - mojom::URLLoaderClientPtr client); + static void CreateLoaderAndStart( + ResourceRequesterInfo* requester_info, + mojom::URLLoaderAssociatedRequest request, + int32_t routing_id, + int32_t request_id, + const ResourceRequest& url_request, + mojom::URLLoaderClientPtr client, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + static void SyncLoad(ResourceRequesterInfo* requester_info, int32_t routing_id, int32_t request_id, diff --git a/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc b/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc index 2254eb4f38e..c477cf63370 100644 --- a/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc +++ b/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc @@ -20,24 +20,23 @@ #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/threading/sequenced_worker_pool.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/loader/mojo_async_resource_handler.h" #include "content/browser/loader/navigation_resource_throttle.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_message_filter.h" #include "content/browser/loader/resource_request_info_impl.h" -#include "content/browser/loader/test_url_loader_client.h" #include "content/browser/loader_delegate_impl.h" -#include "content/common/resource_request.h" -#include "content/common/resource_request_completion_status.h" -#include "content/common/url_loader.mojom.h" -#include "content/common/url_loader_factory.mojom.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" #include "content/public/common/content_paths.h" +#include "content/public/common/resource_request.h" +#include "content/public/common/resource_request_completion_status.h" +#include "content/public/common/url_loader.mojom.h" +#include "content/public/common/url_loader_factory.mojom.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_url_loader_client.h" #include "mojo/public/c/system/data_pipe.h" #include "mojo/public/c/system/types.h" #include "mojo/public/cpp/bindings/binding.h" @@ -51,6 +50,7 @@ #include "net/test/url_request/url_request_failed_job.h" #include "net/test/url_request/url_request_mock_http_job.h" #include "net/test/url_request/url_request_slow_download_job.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_filter.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -152,8 +152,7 @@ TEST_P(URLLoaderFactoryImplTest, GetResponse) { mojom::URLLoaderAssociatedPtr loader; base::FilePath root; PathService::Get(DIR_TEST_DATA, &root); - net::URLRequestMockHTTPJob::AddUrlHandlers(root, - BrowserThread::GetBlockingPool()); + net::URLRequestMockHTTPJob::AddUrlHandlers(root); ResourceRequest request; TestURLLoaderClient client; // Assume the file contents is small enough to be stored in the data pipe. @@ -165,9 +164,10 @@ TEST_P(URLLoaderFactoryImplTest, GetResponse) { request.resource_type = RESOURCE_TYPE_XHR; // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), kRoutingId, - kRequestId, mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), kRoutingId, kRequestId, + mojom::kURLLoadOptionNone, request, client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); ASSERT_FALSE(client.has_received_response()); ASSERT_FALSE(client.response_body().is_valid()); @@ -241,9 +241,10 @@ TEST_P(URLLoaderFactoryImplTest, GetFailedResponse) { request.resource_type = RESOURCE_TYPE_XHR; // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), 2, 1, - mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), 2, 1, mojom::kURLLoadOptionNone, request, + client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); client.RunUntilComplete(); ASSERT_FALSE(client.has_received_response()); @@ -270,9 +271,10 @@ TEST_P(URLLoaderFactoryImplTest, GetFailedResponse2) { request.resource_type = RESOURCE_TYPE_XHR; // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), 2, 1, - mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), 2, 1, mojom::kURLLoadOptionNone, request, + client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); client.RunUntilComplete(); ASSERT_FALSE(client.has_received_response()); @@ -297,9 +299,10 @@ TEST_P(URLLoaderFactoryImplTest, InvalidURL) { // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); ASSERT_FALSE(request.url.is_valid()); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), 2, 1, - mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), 2, 1, mojom::kURLLoadOptionNone, request, + client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); client.RunUntilComplete(); ASSERT_FALSE(client.has_received_response()); @@ -323,9 +326,10 @@ TEST_P(URLLoaderFactoryImplTest, ShouldNotRequestURL) { request.resource_type = RESOURCE_TYPE_XHR; // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), 2, 1, - mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), 2, 1, mojom::kURLLoadOptionNone, request, + client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); client.RunUntilComplete(); rdh_.SetDelegate(nullptr); @@ -343,8 +347,7 @@ TEST_P(URLLoaderFactoryImplTest, DownloadToFile) { mojom::URLLoaderAssociatedPtr loader; base::FilePath root; PathService::Get(DIR_TEST_DATA, &root); - net::URLRequestMockHTTPJob::AddUrlHandlers(root, - BrowserThread::GetBlockingPool()); + net::URLRequestMockHTTPJob::AddUrlHandlers(root); ResourceRequest request; TestURLLoaderClient client; @@ -353,9 +356,10 @@ TEST_P(URLLoaderFactoryImplTest, DownloadToFile) { request.resource_type = RESOURCE_TYPE_XHR; request.download_to_file = true; request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), kRoutingId, - kRequestId, 0, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), kRoutingId, kRequestId, 0, request, + client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); ASSERT_FALSE(client.has_received_response()); ASSERT_FALSE(client.has_data_downloaded()); ASSERT_FALSE(client.has_received_completion()); @@ -420,9 +424,10 @@ TEST_P(URLLoaderFactoryImplTest, DownloadToFileFailure) { request.resource_type = RESOURCE_TYPE_XHR; request.download_to_file = true; request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), kRoutingId, - kRequestId, 0, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), kRoutingId, kRequestId, 0, request, + client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); ASSERT_FALSE(client.has_received_response()); ASSERT_FALSE(client.has_data_downloaded()); ASSERT_FALSE(client.has_received_completion()); @@ -469,8 +474,7 @@ TEST_P(URLLoaderFactoryImplTest, OnTransferSizeUpdated) { mojom::URLLoaderAssociatedPtr loader; base::FilePath root; PathService::Get(DIR_TEST_DATA, &root); - net::URLRequestMockHTTPJob::AddUrlHandlers(root, - BrowserThread::GetBlockingPool()); + net::URLRequestMockHTTPJob::AddUrlHandlers(root); ResourceRequest request; TestURLLoaderClient client; // Assume the file contents is small enough to be stored in the data pipe. @@ -483,9 +487,10 @@ TEST_P(URLLoaderFactoryImplTest, OnTransferSizeUpdated) { // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); request.report_raw_headers = true; - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), kRoutingId, - kRequestId, mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), kRoutingId, kRequestId, + mojom::kURLLoadOptionNone, request, client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); client.RunUntilComplete(); @@ -543,9 +548,10 @@ TEST_P(URLLoaderFactoryImplTest, CancelFromRenderer) { request.resource_type = RESOURCE_TYPE_XHR; // Need to set |request_initiator| for non main frame type request. request.request_initiator = url::Origin(); - factory_->CreateLoaderAndStart(mojo::MakeRequest(&loader), kRoutingId, - kRequestId, mojom::kURLLoadOptionNone, request, - client.CreateInterfacePtr()); + factory_->CreateLoaderAndStart( + mojo::MakeRequest(&loader), kRoutingId, kRequestId, + mojom::kURLLoadOptionNone, request, client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); base::RunLoop().RunUntilIdle(); ASSERT_TRUE(rdh_.GetURLRequest(GlobalRequestID(kChildId, kRequestId))); diff --git a/chromium/content/browser/loader/url_loader_request_handler.cc b/chromium/content/browser/loader/url_loader_request_handler.cc new file mode 100644 index 00000000000..0925e224cfb --- /dev/null +++ b/chromium/content/browser/loader/url_loader_request_handler.cc @@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/loader/url_loader_request_handler.h" + +namespace content { + +mojom::URLLoaderFactoryPtr +URLLoaderRequestHandler::MaybeCreateSubresourceFactory() { + return nullptr; +} + +} // namespace content
\ No newline at end of file diff --git a/chromium/content/browser/loader/url_loader_request_handler.h b/chromium/content/browser/loader/url_loader_request_handler.h new file mode 100644 index 00000000000..fb0a1f4b2f3 --- /dev/null +++ b/chromium/content/browser/loader/url_loader_request_handler.h @@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_LOADER_URL_LOADER_REQUEST_HANDLER_H_ +#define CONTENT_BROWSER_LOADER_URL_LOADER_REQUEST_HANDLER_H_ + +#include <memory> +#include "base/callback_forward.h" +#include "base/macros.h" +#include "content/public/common/url_loader.mojom.h" +#include "content/public/common/url_loader_factory.mojom.h" + +namespace content { + +class ResourceContext; +struct ResourceRequest; + +using StartLoaderCallback = + base::OnceCallback<void(mojom::URLLoaderRequest request, + mojom::URLLoaderClientPtr client)>; + +using LoaderCallback = base::OnceCallback<void(StartLoaderCallback)>; + +// An instance of this class is a per-request object and kept around during +// the lifetime of a request (including multiple redirect legs) on IO thread. +class CONTENT_EXPORT URLLoaderRequestHandler { + public: + URLLoaderRequestHandler() = default; + virtual ~URLLoaderRequestHandler() = default; + + // Calls |callback| with a non-null StartLoaderCallback if this handler + // can handle the request, calls it with null callback otherwise. + virtual void MaybeCreateLoader(const ResourceRequest& resource_request, + ResourceContext* resource_context, + LoaderCallback callback) = 0; + + // Returns the URLLoaderFactory if any to be used for subsequent URL requests + // going forward. Subclasses who want to handle subresource requests etc may + // want to override this to return a custom factory. + virtual mojom::URLLoaderFactoryPtr MaybeCreateSubresourceFactory(); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_LOADER_URL_LOADER_REQUEST_HANDLER_H_ diff --git a/chromium/content/browser/loader/wake_lock_resource_throttle.cc b/chromium/content/browser/loader/wake_lock_resource_throttle.cc index 6d9594fcb59..568be0b89e1 100644 --- a/chromium/content/browser/loader/wake_lock_resource_throttle.cc +++ b/chromium/content/browser/loader/wake_lock_resource_throttle.cc @@ -6,9 +6,9 @@ #include "content/browser/service_manager/service_manager_context.h" #include "content/public/browser/browser_thread.h" -#include "device/wake_lock/public/interfaces/wake_lock_provider.mojom.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "services/device/public/interfaces/constants.mojom.h" +#include "services/device/public/interfaces/wake_lock_provider.mojom.h" #include "services/service_manager/public/cpp/connector.h" namespace content { diff --git a/chromium/content/browser/loader/wake_lock_resource_throttle.h b/chromium/content/browser/loader/wake_lock_resource_throttle.h index 1bef48cfe39..138adc548f9 100644 --- a/chromium/content/browser/loader/wake_lock_resource_throttle.h +++ b/chromium/content/browser/loader/wake_lock_resource_throttle.h @@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/timer/timer.h" #include "content/public/browser/resource_throttle.h" -#include "device/wake_lock/public/interfaces/wake_lock_service.mojom.h" +#include "services/device/public/interfaces/wake_lock.mojom.h" namespace content { @@ -34,9 +34,9 @@ class WakeLockResourceThrottle : public ResourceThrottle { base::OneShotTimer timer_; // Destruction of wake_lock_ will trigger - // WakeLockServicImpl::OnConnectionError on the service side, so there is no + // WakeLock::OnConnectionError on the service side, so there is no // need to call CancelWakeLock() in the destructor. - device::mojom::WakeLockServicePtr wake_lock_; + device::mojom::WakeLockPtr wake_lock_; DISALLOW_COPY_AND_ASSIGN(WakeLockResourceThrottle); }; |