Commit 2695d04d authored by arthursonzogni's avatar arthursonzogni Committed by Commit Bot

PlzNavigate: Use the NavigationUrlLoaderNetworkService.

Use the NavigationURLLoaderNetworkService when NavigationMojoResponse is
enabled, even if the network service isn’t.

The feature NavigationMojoResponse is currently disabled by default, so
this patch shouldn't introduce any new regression.

See the others CLs in this series:
[1/3] https://chromium-review.googlesource.com/c/739502
[2/3] this CL.
[3/3] https://chromium-review.googlesource.com/c/753738

This is part 2 of the implementation plan.
Design doc: https://goo.gl/Rrrc7n

Bug: 705744
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo;master.tryserver.chromium.linux:linux_site_isolation
Change-Id: Ia95527dce4be7b43747fec09ffe61bc51b2195a6
Reviewed-on: https://chromium-review.googlesource.com/741237
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523373}
parent 70340ce0
...@@ -582,4 +582,205 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest, ...@@ -582,4 +582,205 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
} }
// TODO(arthursonzogni): Remove these tests once NavigationMojoResponse has
// launched.
class NavigationMojoResponseBrowserTest : public ContentBrowserTest {
public:
NavigationMojoResponseBrowserTest() {}
protected:
void SetUp() override {
base::test::ScopedFeatureList().InitAndEnableFeature(
features::kNavigationMojoResponse);
ContentBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(embedded_test_server()->Start());
}
};
// Ensure that browser initiated basic navigations work with browser side
// navigation.
// TODO(arthursonzogni): Remove this test once NavigationMojoResponse has
// launched.
IN_PROC_BROWSER_TEST_F(NavigationMojoResponseBrowserTest,
BrowserInitiatedNavigations) {
// Perform a navigation with no live renderer.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/title1.html"));
NavigateToURL(shell(), url);
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
RenderFrameHost* initial_rfh =
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
// Perform a same site navigation.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/title2.html"));
NavigateToURL(shell(), url);
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
// The RenderFrameHost should not have changed.
EXPECT_EQ(initial_rfh, static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host());
// Perform a cross-site navigation.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url = embedded_test_server()->GetURL("foo.com", "/title3.html");
NavigateToURL(shell(), url);
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
// The RenderFrameHost should have changed.
EXPECT_NE(initial_rfh, static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host());
}
// Ensure that renderer initiated same-site navigations work with browser side
// navigation.
// TODO(arthursonzogni): Remove this test once NavigationMojoResponse has
// launched.
IN_PROC_BROWSER_TEST_F(NavigationMojoResponseBrowserTest,
RendererInitiatedSameSiteNavigation) {
// Perform a navigation with no live renderer.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/simple_links.html"));
NavigateToURL(shell(), url);
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
RenderFrameHost* initial_rfh =
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
// Simulate clicking on a same-site link.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/title2.html"));
bool success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
shell(), "window.domAutomationController.send(clickSameSiteLink());",
&success));
EXPECT_TRUE(success);
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
// The RenderFrameHost should not have changed.
EXPECT_EQ(initial_rfh, static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host());
}
// Ensure that renderer initiated cross-site navigations work with browser side
// navigation.
// TODO(arthursonzogni): Remove this test once NavigationMojoResponse has
// launched.
IN_PROC_BROWSER_TEST_F(NavigationMojoResponseBrowserTest,
RendererInitiatedCrossSiteNavigation) {
// Perform a navigation with no live renderer.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/simple_links.html"));
NavigateToURL(shell(), url);
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
RenderFrameHost* initial_rfh =
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
// Simulate clicking on a cross-site link.
{
TestNavigationObserver observer(shell()->web_contents());
const char kReplacePortNumber[] =
"window.domAutomationController.send(setPortNumber(%d));";
uint16_t port_number = embedded_test_server()->port();
GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
bool success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
shell(), base::StringPrintf(kReplacePortNumber, port_number),
&success));
success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
shell(), "window.domAutomationController.send(clickCrossSiteLink());",
&success));
EXPECT_TRUE(success);
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
// The RenderFrameHost should not have changed unless site-per-process is
// enabled.
if (AreAllSitesIsolatedForTesting()) {
EXPECT_NE(initial_rfh,
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host());
} else {
EXPECT_EQ(initial_rfh,
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host());
}
}
// Ensure that browser side navigation handles navigation failures.
// TODO(arthursonzogni): Remove this test once NavigationMojoResponse has
// launched.
IN_PROC_BROWSER_TEST_F(NavigationMojoResponseBrowserTest, FailedNavigation) {
// Perform a navigation with no live renderer.
{
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/title1.html"));
NavigateToURL(shell(), url);
EXPECT_EQ(url, observer.last_navigation_url());
EXPECT_TRUE(observer.last_navigation_succeeded());
}
// Now navigate to an unreachable url.
{
TestNavigationObserver observer(shell()->web_contents());
GURL error_url(
net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_RESET));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
NavigateToURL(shell(), error_url);
EXPECT_EQ(error_url, observer.last_navigation_url());
NavigationEntry* entry =
shell()->web_contents()->GetController().GetLastCommittedEntry();
EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
}
}
} // namespace content } // namespace content
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "content/browser/loader/navigation_url_loader_network_service.h" #include "content/browser/loader/navigation_url_loader_network_service.h"
#include "content/browser/loader/url_loader_request_handler.h" #include "content/browser/loader/url_loader_request_handler.h"
#include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/navigation_ui_data.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
namespace content { namespace content {
...@@ -33,7 +34,8 @@ std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create( ...@@ -33,7 +34,8 @@ std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create(
resource_context, storage_partition, std::move(request_info), resource_context, storage_partition, std::move(request_info),
std::move(navigation_ui_data), service_worker_handle, delegate); std::move(navigation_ui_data), service_worker_handle, delegate);
} }
if (base::FeatureList::IsEnabled(features::kNetworkService)) { if (base::FeatureList::IsEnabled(features::kNetworkService) ||
IsNavigationMojoResponseEnabled()) {
return std::make_unique<NavigationURLLoaderNetworkService>( return std::make_unique<NavigationURLLoaderNetworkService>(
resource_context, storage_partition, std::move(request_info), resource_context, storage_partition, std::move(request_info),
std::move(navigation_ui_data), service_worker_handle, appcache_handle, std::move(navigation_ui_data), service_worker_handle, appcache_handle,
......
...@@ -54,7 +54,8 @@ void NavigationURLLoaderImplCore::Start( ...@@ -54,7 +54,8 @@ void NavigationURLLoaderImplCore::Start(
ResourceDispatcherHostImpl::Get()->BeginNavigationRequest( ResourceDispatcherHostImpl::Get()->BeginNavigationRequest(
resource_context, url_request_context_getter->GetURLRequestContext(), resource_context, url_request_context_getter->GetURLRequestContext(),
upload_file_system_context, *request_info, upload_file_system_context, *request_info,
std::move(navigation_ui_data), this, service_worker_handle_core, std::move(navigation_ui_data), this, mojom::URLLoaderClientPtr(),
mojom::URLLoaderRequest(), service_worker_handle_core,
appcache_handle_core); appcache_handle_core);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/browser/loader/navigation_url_loader.h" #include "content/browser/loader/navigation_url_loader.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
#include "content/public/browser/ssl_status.h" #include "content/public/browser/ssl_status.h"
...@@ -57,6 +58,7 @@ class CONTENT_EXPORT NavigationURLLoaderNetworkService ...@@ -57,6 +58,7 @@ class CONTENT_EXPORT NavigationURLLoaderNetworkService
private: private:
class URLLoaderRequestController; class URLLoaderRequestController;
void OnRequestStarted(base::TimeTicks timestamp);
void BindNonNetworkURLLoaderFactoryRequest( void BindNonNetworkURLLoaderFactoryRequest(
const GURL& url, const GURL& url,
......
...@@ -1558,7 +1558,8 @@ ResourceDispatcherHostImpl::AddStandardHandlers( ...@@ -1558,7 +1558,8 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
handler.reset(new ThrottlingResourceHandler( handler.reset(new ThrottlingResourceHandler(
std::move(handler), request, std::move(post_mime_sniffing_throttles))); std::move(handler), request, std::move(post_mime_sniffing_throttles)));
if (IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type)) { if (IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type) &&
!IsNavigationMojoResponseEnabled()) {
DCHECK(navigation_loader_core); DCHECK(navigation_loader_core);
DCHECK(stream_handle); DCHECK(stream_handle);
// PlzNavigate // PlzNavigate
...@@ -1999,12 +2000,18 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( ...@@ -1999,12 +2000,18 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
const NavigationRequestInfo& info, const NavigationRequestInfo& info,
std::unique_ptr<NavigationUIData> navigation_ui_data, std::unique_ptr<NavigationUIData> navigation_ui_data,
NavigationURLLoaderImplCore* loader, NavigationURLLoaderImplCore* loader,
mojom::URLLoaderClientPtr url_loader_client,
mojom::URLLoaderRequest url_loader_request,
ServiceWorkerNavigationHandleCore* service_worker_handle_core, ServiceWorkerNavigationHandleCore* service_worker_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core) { AppCacheNavigationHandleCore* appcache_handle_core) {
// PlzNavigate: BeginNavigationRequest currently should only be used for the // PlzNavigate: BeginNavigationRequest currently should only be used for the
// browser-side navigations project. // browser-side navigations project.
CHECK(IsBrowserSideNavigationEnabled()); CHECK(IsBrowserSideNavigationEnabled());
DCHECK_EQ(IsNavigationMojoResponseEnabled(), !loader);
DCHECK_EQ(IsNavigationMojoResponseEnabled(), url_loader_client.is_bound());
DCHECK_EQ(IsNavigationMojoResponseEnabled(), url_loader_request.is_pending());
ResourceType resource_type = info.is_main_frame ? ResourceType resource_type = info.is_main_frame ?
RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME; RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME;
...@@ -2029,7 +2036,12 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( ...@@ -2029,7 +2036,12 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
info.common_params.url, info.common_params.url,
resource_type, resource_type,
resource_context))) { resource_context))) {
loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt); if (IsNavigationMojoResponseEnabled()) {
url_loader_client->OnComplete(
network::URLLoaderCompletionStatus(net::ERR_ABORTED));
} else {
loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt);
}
return; return;
} }
...@@ -2075,7 +2087,12 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( ...@@ -2075,7 +2087,12 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
if (body) { if (body) {
if (!GetBodyBlobDataHandles(body, resource_context, &blob_handles)) { if (!GetBodyBlobDataHandles(body, resource_context, &blob_handles)) {
new_request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); new_request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt); if (IsNavigationMojoResponseEnabled()) {
url_loader_client->OnComplete(
network::URLLoaderCompletionStatus(net::ERR_ABORTED));
} else {
loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt);
}
return; return;
} }
new_request->set_upload(UploadDataStreamBuilder::Build( new_request->set_upload(UploadDataStreamBuilder::Build(
...@@ -2153,19 +2170,26 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( ...@@ -2153,19 +2170,26 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
new_request.get(), appcache_handle_core->host(), resource_type, false); new_request.get(), appcache_handle_core->host(), resource_type, false);
} }
StreamContext* stream_context = std::unique_ptr<ResourceHandler> handler;
GetStreamContextForResourceContext(resource_context); std::unique_ptr<StreamHandle> stream_handle;
// Note: the stream should be created with immediate mode set to true to if (IsNavigationMojoResponseEnabled()) {
// ensure that data read will be flushed to the reader as soon as it's handler = std::make_unique<MojoAsyncResourceHandler>(
// available. Otherwise, we risk delaying transmitting the body of the new_request.get(), this, std::move(url_loader_request),
// resource to the renderer, which will delay parsing accordingly. std::move(url_loader_client), resource_type);
std::unique_ptr<ResourceHandler> handler( } else {
new StreamResourceHandler(new_request.get(), stream_context->registry(), StreamContext* stream_context =
new_request->url().GetOrigin(), true)); GetStreamContextForResourceContext(resource_context);
std::unique_ptr<StreamHandle> stream_handle = // Note: the stream should be created with immediate mode set to true to
static_cast<StreamResourceHandler*>(handler.get()) // ensure that data read will be flushed to the reader as soon as it's
->stream() // available. Otherwise, we risk delaying transmitting the body of the
->CreateHandle(); // resource to the renderer, which will delay parsing accordingly.
handler = std::make_unique<StreamResourceHandler>(
new_request.get(), stream_context->registry(),
new_request->url().GetOrigin(), true);
stream_handle = static_cast<StreamResourceHandler*>(handler.get())
->stream()
->CreateHandle();
}
// Safe to consider navigations as kNoCORS. // Safe to consider navigations as kNoCORS.
// TODO(davidben): Fix the dependency on child_id/route_id. Those are used // TODO(davidben): Fix the dependency on child_id/route_id. Those are used
......
...@@ -270,6 +270,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl ...@@ -270,6 +270,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const NavigationRequestInfo& info, const NavigationRequestInfo& info,
std::unique_ptr<NavigationUIData> navigation_ui_data, std::unique_ptr<NavigationUIData> navigation_ui_data,
NavigationURLLoaderImplCore* loader, NavigationURLLoaderImplCore* loader,
mojom::URLLoaderClientPtr url_loader_client,
mojom::URLLoaderRequest url_loader_request,
ServiceWorkerNavigationHandleCore* service_worker_handle_core, ServiceWorkerNavigationHandleCore* service_worker_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core); AppCacheNavigationHandleCore* appcache_handle_core);
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
-NavigationControllerBrowserTest.ErrorPageReplacement -NavigationControllerBrowserTest.ErrorPageReplacement
-NavigationHandleImplBrowserTest.ErrorCodeOnRedirect -NavigationHandleImplBrowserTest.ErrorCodeOnRedirect
-NavigationHandleImplBrowserTest.RedirectToRendererDebugUrl -NavigationHandleImplBrowserTest.RedirectToRendererDebugUrl
-NavigationMojoResponseBrowserTest.FailedNavigation
-PlzNavigateNavigationHandleImplBrowserTest.ErrorPageNetworkError -PlzNavigateNavigationHandleImplBrowserTest.ErrorPageNetworkError
-PowerMonitorTest.TestGpuProcess -PowerMonitorTest.TestGpuProcess
-PowerMonitorTest.TestRendererProcess -PowerMonitorTest.TestRendererProcess
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment