Commit 75d2c9f9 authored by Lucas Garron's avatar Lucas Garron Committed by Commit Bot

Committed Interstitial error page HTML (1/2): attach net_error and...

Committed Interstitial error page HTML (1/2): attach net_error and error_page_content to ThrottleCheckResult.

Changes NavigationThrottle::ThrottleCheckResult into a struct that holds a net
error and an optional error page content (i.e. HTML + inline JS/CSS). The old
ThrottleCheckResult enum is changed to ThrottleAction and included in the
struct.

TBRing jochen@ for mechanical changes.

TBR=jochen@chromium.org

Bug: 751949
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_site_isolation
Change-Id: I2b4836d1be24251704f25b05f0fd0c38bb74c341
Reviewed-on: https://chromium-review.googlesource.com/647656
Commit-Queue: Lucas Garron <lgarron@chromium.org>
Reviewed-by: default avatarLucas Garron <lgarron@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#501244}
parent 7acc981d
......@@ -70,7 +70,7 @@ class ExtensionNavigationThrottleUnitTest
void CheckTestCase(
content::RenderFrameHost* host,
const GURL& extension_url,
NavigationThrottle::ThrottleCheckResult expected_will_start_result) {
NavigationThrottle::ThrottleAction expected_will_start_result) {
// First subtest: direct navigation to |extension_url|.
std::unique_ptr<content::NavigationHandle> handle =
content::NavigationHandle::CreateNavigationHandleForTesting(
......@@ -91,7 +91,7 @@ class ExtensionNavigationThrottleUnitTest
// TODO(nick): https://crbug.com/695421 Once PlzNavigate is enabled 100%, it
// should be possible to support return values other than PROCEED and CANCEL
// from ExtensionNavigationThrottle::WillRedirectRequest.
NavigationThrottle::ThrottleCheckResult expected_will_redirect_result =
NavigationThrottle::ThrottleAction expected_will_redirect_result =
(expected_will_start_result == NavigationThrottle::PROCEED)
? NavigationThrottle::PROCEED
: NavigationThrottle::CANCEL;
......
......@@ -123,7 +123,7 @@ SubresourceFilterTestHarness::SimulateNavigateAndCommit(
auto simulator =
content::NavigationSimulator::CreateRendererInitiated(url, rfh);
simulator->Commit();
return simulator->GetLastThrottleCheckResult() ==
return simulator->GetLastThrottleCheckResult().action() ==
content::NavigationThrottle::PROCEED
? simulator->GetFinalRenderFrameHost()
: nullptr;
......
......@@ -74,7 +74,7 @@ SupervisedUserGoogleAuthNavigationThrottle::WillStartOrRedirectRequest() {
content::NavigationThrottle::ThrottleCheckResult result =
ShouldProceed(child_account_service_->IsGoogleAuthenticated());
if (result == content::NavigationThrottle::DEFER) {
if (result.action() == content::NavigationThrottle::DEFER) {
google_auth_state_subscription_ =
child_account_service_->ObserveGoogleAuthState(
base::Bind(&SupervisedUserGoogleAuthNavigationThrottle::
......@@ -90,7 +90,7 @@ void SupervisedUserGoogleAuthNavigationThrottle::OnGoogleAuthStateChanged(
content::NavigationThrottle::ThrottleCheckResult result =
ShouldProceed(authenticated);
switch (result) {
switch (result.action()) {
case content::NavigationThrottle::PROCEED: {
google_auth_state_subscription_.reset();
Resume();
......
......@@ -159,8 +159,8 @@ SupervisedUserNavigationThrottle::CheckURL() {
if (got_result)
behavior_ = SupervisedUserURLFilter::INVALID;
if (deferred_)
return ThrottleCheckResult::DEFER;
return ThrottleCheckResult::PROCEED;
return NavigationThrottle::DEFER;
return NavigationThrottle::PROCEED;
}
void SupervisedUserNavigationThrottle::ShowInterstitial(
......
......@@ -79,7 +79,7 @@ ActivationStateComputingNavigationThrottle::WillProcessResponse() {
parent_activation_state_->activation_level == ActivationLevel::DISABLED) {
DCHECK(navigation_handle()->IsInMainFrame());
DCHECK(!ruleset_handle_);
return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
return content::NavigationThrottle::PROCEED;
}
DCHECK(ruleset_handle_);
......@@ -99,7 +99,7 @@ ActivationStateComputingNavigationThrottle::WillProcessResponse() {
weak_ptr_factory_.GetWeakPtr()));
defer_timestamp_ = base::TimeTicks::Now();
return content::NavigationThrottle::ThrottleCheckResult::DEFER;
return content::NavigationThrottle::DEFER;
}
const char* ActivationStateComputingNavigationThrottle::GetNameForLogging() {
......
......@@ -194,36 +194,36 @@ class ContentSubresourceFilterThrottleManagerTest
}
void SimulateStartAndExpectResult(
content::NavigationThrottle::ThrottleCheckResult expect_result) {
content::NavigationThrottle::ThrottleAction expect_result) {
navigation_simulator_->Start();
content::NavigationThrottle::ThrottleCheckResult result =
navigation_simulator_->GetLastThrottleCheckResult();
EXPECT_EQ(expect_result, result);
if (result != content::NavigationThrottle::PROCEED)
if (result.action() != content::NavigationThrottle::PROCEED)
navigation_simulator_.reset();
}
void SimulateRedirectAndExpectResult(
const GURL& new_url,
content::NavigationThrottle::ThrottleCheckResult expect_result) {
content::NavigationThrottle::ThrottleAction expect_result) {
navigation_simulator_->Redirect(new_url);
content::NavigationThrottle::ThrottleCheckResult result =
navigation_simulator_->GetLastThrottleCheckResult();
EXPECT_EQ(expect_result, result);
if (result != content::NavigationThrottle::PROCEED)
if (result.action() != content::NavigationThrottle::PROCEED)
navigation_simulator_.reset();
}
// Returns the RenderFrameHost that the navigation commit in.
content::RenderFrameHost* SimulateCommitAndExpectResult(
content::NavigationThrottle::ThrottleCheckResult expect_result) {
content::NavigationThrottle::ThrottleAction expect_result) {
navigation_simulator_->Commit();
content::NavigationThrottle::ThrottleCheckResult result =
navigation_simulator_->GetLastThrottleCheckResult();
EXPECT_EQ(expect_result, result);
auto scoped_simulator = std::move(navigation_simulator_);
if (result == content::NavigationThrottle::PROCEED)
if (result.action() == content::NavigationThrottle::PROCEED)
return scoped_simulator->GetFinalRenderFrameHost();
return nullptr;
}
......@@ -370,12 +370,12 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/before-redirect.html"), main_rfh());
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
content::NavigationThrottle::ThrottleCheckResult expected_result =
content::NavigationThrottle::ThrottleAction expected_action =
content::IsBrowserSideNavigationEnabled()
? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
: content::NavigationThrottle::CANCEL;
SimulateRedirectAndExpectResult(
GURL("https://www.example.com/disallowed.html"), expected_result);
GURL("https://www.example.com/disallowed.html"), expected_action);
EXPECT_EQ(1, disallowed_notification_count());
}
......
......@@ -63,7 +63,7 @@ content::NavigationThrottle::ThrottleCheckResult
SubframeNavigationFilteringThrottle::WillProcessResponse() {
DCHECK_NE(load_policy_, LoadPolicy::DISALLOW);
NotifyLoadPolicy();
return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
return PROCEED;
}
const char* SubframeNavigationFilteringThrottle::GetNameForLogging() {
......@@ -75,13 +75,13 @@ SubframeNavigationFilteringThrottle::DeferToCalculateLoadPolicy(
ThrottlingStage stage) {
DCHECK_NE(load_policy_, LoadPolicy::DISALLOW);
if (load_policy_ == LoadPolicy::WOULD_DISALLOW)
return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
return PROCEED;
parent_frame_filter_->GetLoadPolicyForSubdocument(
navigation_handle()->GetURL(),
base::Bind(&SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy,
weak_ptr_factory_.GetWeakPtr(), stage));
last_defer_timestamp_ = base::TimeTicks::Now();
return content::NavigationThrottle::ThrottleCheckResult::DEFER;
return DEFER;
}
void SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy(
......@@ -111,9 +111,7 @@ void SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy(
content::IsBrowserSideNavigationEnabled() ||
stage == ThrottlingStage::WillStartRequest;
CancelDeferredNavigation(
block_and_collapse_is_supported
? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
: content::NavigationThrottle::CANCEL);
block_and_collapse_is_supported ? BLOCK_REQUEST_AND_COLLAPSE : CANCEL);
} else {
Resume();
}
......
......@@ -104,7 +104,7 @@ class SubframeNavigationFilteringThrottleTest
}
void SimulateStartAndExpectResult(
content::NavigationThrottle::ThrottleCheckResult expect_result) {
content::NavigationThrottle::ThrottleAction expect_result) {
navigation_simulator_->Start();
EXPECT_EQ(expect_result,
navigation_simulator_->GetLastThrottleCheckResult());
......@@ -112,14 +112,14 @@ class SubframeNavigationFilteringThrottleTest
void SimulateRedirectAndExpectResult(
const GURL& new_url,
content::NavigationThrottle::ThrottleCheckResult expect_result) {
content::NavigationThrottle::ThrottleAction expect_result) {
navigation_simulator_->Redirect(new_url);
EXPECT_EQ(expect_result,
navigation_simulator_->GetLastThrottleCheckResult());
}
void SimulateCommitAndExpectResult(
content::NavigationThrottle::ThrottleCheckResult expect_result) {
content::NavigationThrottle::ThrottleAction expect_result) {
navigation_simulator_->Commit();
EXPECT_EQ(expect_result,
navigation_simulator_->GetLastThrottleCheckResult());
......@@ -158,7 +158,7 @@ TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnRedirect) {
main_rfh());
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
content::NavigationThrottle::ThrottleCheckResult expected_result =
content::NavigationThrottle::ThrottleAction expected_result =
content::IsBrowserSideNavigationEnabled()
? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
: content::NavigationThrottle::CANCEL;
......@@ -174,7 +174,7 @@ TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnSecondRedirect) {
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
SimulateRedirectAndExpectResult(GURL("https://example.test/allowed2.html"),
content::NavigationThrottle::PROCEED);
content::NavigationThrottle::ThrottleCheckResult expected_result =
content::NavigationThrottle::ThrottleAction expected_result =
content::IsBrowserSideNavigationEnabled()
? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
: content::NavigationThrottle::CANCEL;
......@@ -219,7 +219,7 @@ TEST_F(SubframeNavigationFilteringThrottleTest, DelayMetrics) {
if (content::IsBrowserSideNavigationEnabled())
navigation_simulator()->SetTransition(ui::PAGE_TRANSITION_MANUAL_SUBFRAME);
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
content::NavigationThrottle::ThrottleCheckResult expected_result =
content::NavigationThrottle::ThrottleAction expected_result =
content::IsBrowserSideNavigationEnabled()
? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
: content::NavigationThrottle::CANCEL;
......
......@@ -119,7 +119,7 @@ content::NavigationThrottle::ThrottleCheckResult
SubresourceFilterSafeBrowsingActivationThrottle::WillRedirectRequest() {
CheckCurrentUrl();
DCHECK(!database_client_ || !check_results_.empty());
return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
return PROCEED;
}
content::NavigationThrottle::ThrottleCheckResult
......@@ -128,12 +128,12 @@ SubresourceFilterSafeBrowsingActivationThrottle::WillProcessResponse() {
// No need to defer the navigation if the check already happened.
if (!database_client_ || check_results_.back().finished) {
NotifyResult();
return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
return PROCEED;
}
CHECK(!deferring_);
deferring_ = true;
defer_time_ = base::TimeTicks::Now();
return content::NavigationThrottle::ThrottleCheckResult::DEFER;
return DEFER;
}
const char*
......
......@@ -255,7 +255,7 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
auto simulator = content::NavigationSimulator::CreateRendererInitiated(
GURL("https://example.test/disallowed.html"), subframe);
simulator->Commit();
return simulator->GetLastThrottleCheckResult() ==
return simulator->GetLastThrottleCheckResult().action() ==
content::NavigationThrottle::PROCEED
? simulator->GetFinalRenderFrameHost()
: nullptr;
......@@ -280,7 +280,7 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
content::NavigationSimulator::CreateRendererInitiated(first_url, rfh);
navigation_simulator_->Start();
auto result = navigation_simulator_->GetLastThrottleCheckResult();
if (result == content::NavigationThrottle::CANCEL)
if (result.action() == content::NavigationThrottle::CANCEL)
navigation_simulator_.reset();
return result;
}
......@@ -289,7 +289,7 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
const GURL& new_url) {
navigation_simulator_->Redirect(new_url);
auto result = navigation_simulator_->GetLastThrottleCheckResult();
if (result == content::NavigationThrottle::CANCEL)
if (result.action() == content::NavigationThrottle::CANCEL)
navigation_simulator_.reset();
return result;
}
......
......@@ -566,9 +566,9 @@ class NetworkNavigationThrottle : public content::NavigationThrottle {
NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
if (network_handler_ && network_handler_->ShouldCancelNavigation(
navigation_handle()->GetGlobalRequestID())) {
return ThrottleCheckResult::CANCEL_AND_IGNORE;
return CANCEL_AND_IGNORE;
}
return ThrottleCheckResult::PROCEED;
return PROCEED;
}
const char* GetNameForLogging() override {
......
......@@ -33,8 +33,8 @@ IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
const struct {
GURL main_page_url;
GURL form_page_url;
NavigationThrottle::ThrottleCheckResult start_expectation;
NavigationThrottle::ThrottleCheckResult redirect_expectation;
NavigationThrottle::ThrottleAction start_expectation;
NavigationThrottle::ThrottleAction redirect_expectation;
} kTestCases[] = {
// Form submissions is allowed by default when there is no CSP.
{
......
......@@ -127,26 +127,27 @@ MixedContentNavigationThrottle::MixedContentNavigationThrottle(
MixedContentNavigationThrottle::~MixedContentNavigationThrottle() {}
ThrottleCheckResult MixedContentNavigationThrottle::WillStartRequest() {
NavigationThrottle::ThrottleCheckResult
MixedContentNavigationThrottle::WillStartRequest() {
bool should_block = ShouldBlockNavigation(false);
return should_block ? ThrottleCheckResult::CANCEL
: ThrottleCheckResult::PROCEED;
return should_block ? CANCEL : PROCEED;
}
ThrottleCheckResult MixedContentNavigationThrottle::WillRedirectRequest() {
NavigationThrottle::ThrottleCheckResult
MixedContentNavigationThrottle::WillRedirectRequest() {
// Upon redirects the same checks are to be executed as for requests.
bool should_block = ShouldBlockNavigation(true);
return should_block ? ThrottleCheckResult::CANCEL
: ThrottleCheckResult::PROCEED;
return should_block ? CANCEL : PROCEED;
}
ThrottleCheckResult MixedContentNavigationThrottle::WillProcessResponse() {
NavigationThrottle::ThrottleCheckResult
MixedContentNavigationThrottle::WillProcessResponse() {
// TODO(carlosk): At this point we are about to process the request response.
// So if we ever need to, here/now it is a good moment to check for the final
// attained security level of the connection. For instance, does it use an
// outdated protocol? The implementation should be based off
// MixedContentChecker::handleCertificateError. See https://crbug.com/576270.
return ThrottleCheckResult::PROCEED;
return PROCEED;
}
const char* MixedContentNavigationThrottle::GetNameForLogging() {
......
......@@ -20,8 +20,6 @@ namespace content {
class FrameTreeNode;
struct WebPreferences;
using ThrottleCheckResult = NavigationThrottle::ThrottleCheckResult;
// Responsible for browser-process-side mixed content security checks. It is
// only enabled if PlzNavigate is and checks only for frame-level resource loads
// (aka navigation loads). Sub-resources fetches are checked in the renderer
......
......@@ -588,7 +588,7 @@ void NavigationHandleImpl::WillStartRequest(
// Notify each throttle of the request.
base::Closure on_defer_callback_copy = on_defer_callback_for_testing_;
NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest();
if (result == NavigationThrottle::DEFER) {
if (result.action() == NavigationThrottle::DEFER) {
if (!on_defer_callback_copy.is_null())
on_defer_callback_copy.Run();
// DO NOT ADD CODE: the NavigationHandle might have been destroyed during
......@@ -597,7 +597,7 @@ void NavigationHandleImpl::WillStartRequest(
}
TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationHandle", this,
"StartRequest", "result", result);
"StartRequest", "result", result.action());
RunCompleteCallback(result);
}
......@@ -653,7 +653,7 @@ void NavigationHandleImpl::WillRedirectRequest(
// Notify each throttle of the request.
base::Closure on_defer_callback_copy = on_defer_callback_for_testing_;
NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest();
if (result == NavigationThrottle::DEFER) {
if (result.action() == NavigationThrottle::DEFER) {
if (!on_defer_callback_copy.is_null())
on_defer_callback_copy.Run();
// DO NOT ADD CODE: the NavigationHandle might have been destroyed during
......@@ -662,7 +662,7 @@ void NavigationHandleImpl::WillRedirectRequest(
}
TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationHandle", this,
"RedirectRequest", "result", result);
"RedirectRequest", "result", result.action());
RunCompleteCallback(result);
}
......@@ -696,7 +696,7 @@ void NavigationHandleImpl::WillProcessResponse(
// Notify each throttle of the response.
base::Closure on_defer_callback_copy = on_defer_callback_for_testing_;
NavigationThrottle::ThrottleCheckResult result = CheckWillProcessResponse();
if (result == NavigationThrottle::DEFER) {
if (result.action() == NavigationThrottle::DEFER) {
if (!on_defer_callback_copy.is_null())
on_defer_callback_copy.Run();
// DO NOT ADD CODE: the NavigationHandle might have been destroyed during
......@@ -709,11 +709,12 @@ void NavigationHandleImpl::WillProcessResponse(
// on its site (after any redirects).
// Note: if MaybeTransferAndProceed returns false, this means that this
// NavigationHandle was deleted, so return immediately.
if (result == NavigationThrottle::PROCEED && !MaybeTransferAndProceed())
if (result.action() == NavigationThrottle::PROCEED &&
!MaybeTransferAndProceed())
return;
TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationHandle", this,
"ProcessResponse", "result", result);
"ProcessResponse", "result", result.action());
RunCompleteCallback(result);
}
......@@ -867,8 +868,9 @@ NavigationHandleImpl::CheckWillStartRequest() {
TRACE_EVENT_ASYNC_STEP_INTO0(
"navigation", "NavigationHandle", this,
base::StringPrintf("CheckWillStartRequest: %s: %d",
throttles_[i]->GetNameForLogging(), result));
switch (result) {
throttles_[i]->GetNameForLogging(),
result.action()));
switch (result.action()) {
case NavigationThrottle::PROCEED:
continue;
......@@ -913,8 +915,9 @@ NavigationHandleImpl::CheckWillRedirectRequest() {
TRACE_EVENT_ASYNC_STEP_INTO0(
"navigation", "NavigationHandle", this,
base::StringPrintf("CheckWillRedirectRequest: %s: %d",
throttles_[i]->GetNameForLogging(), result));
switch (result) {
throttles_[i]->GetNameForLogging(),
result.action()));
switch (result.action()) {
case NavigationThrottle::PROCEED:
continue;
......@@ -966,8 +969,9 @@ NavigationHandleImpl::CheckWillProcessResponse() {
TRACE_EVENT_ASYNC_STEP_INTO0(
"navigation", "NavigationHandle", this,
base::StringPrintf("CheckWillProcessResponse: %s: %d",
throttles_[i]->GetNameForLogging(), result));
switch (result) {
throttles_[i]->GetNameForLogging(),
result.action()));
switch (result.action()) {
case NavigationThrottle::PROCEED:
continue;
......@@ -1004,7 +1008,7 @@ void NavigationHandleImpl::ResumeInternal() {
base::Closure on_defer_callback_copy = on_defer_callback_for_testing_;
if (state_ == DEFERRING_START) {
result = CheckWillStartRequest();
if (result == NavigationThrottle::DEFER) {
if (result.action() == NavigationThrottle::DEFER) {
if (!on_defer_callback_copy.is_null())
on_defer_callback_copy.Run();
// DO NOT ADD CODE: the NavigationHandle might have been destroyed during
......@@ -1013,7 +1017,7 @@ void NavigationHandleImpl::ResumeInternal() {
}
} else if (state_ == DEFERRING_REDIRECT) {
result = CheckWillRedirectRequest();
if (result == NavigationThrottle::DEFER) {
if (result.action() == NavigationThrottle::DEFER) {
if (!on_defer_callback_copy.is_null())
on_defer_callback_copy.Run();
// DO NOT ADD CODE: the NavigationHandle might have been destroyed during
......@@ -1022,7 +1026,7 @@ void NavigationHandleImpl::ResumeInternal() {
}
} else {
result = CheckWillProcessResponse();
if (result == NavigationThrottle::DEFER) {
if (result.action() == NavigationThrottle::DEFER) {
if (!on_defer_callback_copy.is_null())
on_defer_callback_copy.Run();
// DO NOT ADD CODE: the NavigationHandle might have been destroyed during
......@@ -1036,10 +1040,11 @@ void NavigationHandleImpl::ResumeInternal() {
// redirects).
// Note: if MaybeTransferAndProceed returns false, this means that this
// NavigationHandle was deleted, so return immediately.
if (result == NavigationThrottle::PROCEED && !MaybeTransferAndProceed())
if (result.action() == NavigationThrottle::PROCEED &&
!MaybeTransferAndProceed())
return;
}
DCHECK_NE(NavigationThrottle::DEFER, result);
DCHECK_NE(NavigationThrottle::DEFER, result.action());
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationHandle", this,
"Resuming");
......@@ -1050,14 +1055,14 @@ void NavigationHandleImpl::CancelDeferredNavigationInternal(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT ||
state_ == DEFERRING_RESPONSE);
DCHECK(result == NavigationThrottle::CANCEL_AND_IGNORE ||
result == NavigationThrottle::CANCEL ||
result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
DCHECK(result != NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE ||
DCHECK(result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL ||
result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
DCHECK(result.action() != NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE ||
state_ == DEFERRING_START ||
(state_ == DEFERRING_REDIRECT && IsBrowserSideNavigationEnabled()));
if (result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE)
if (result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE)
frame_tree_node_->SetCollapsed(true);
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationHandle", this,
......@@ -1155,7 +1160,7 @@ bool NavigationHandleImpl::MaybeTransferAndProceedInternal() {
void NavigationHandleImpl::RunCompleteCallback(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result != NavigationThrottle::DEFER);
DCHECK(result.action() != NavigationThrottle::DEFER);
ThrottleChecksFinishedCallback callback = complete_callback_;
complete_callback_.Reset();
......
......@@ -39,9 +39,9 @@ class TestNavigationThrottle : public NavigationThrottle {
public:
TestNavigationThrottle(
NavigationHandle* handle,
NavigationThrottle::ThrottleCheckResult will_start_result,
NavigationThrottle::ThrottleCheckResult will_redirect_result,
NavigationThrottle::ThrottleCheckResult will_process_result,
NavigationThrottle::ThrottleAction will_start_result,
NavigationThrottle::ThrottleAction will_redirect_result,
NavigationThrottle::ThrottleAction will_process_result,
base::Closure did_call_will_start,
base::Closure did_call_will_redirect,
base::Closure did_call_will_process)
......@@ -100,9 +100,9 @@ class TestNavigationThrottle : public NavigationThrottle {
return will_process_result_;
}
NavigationThrottle::ThrottleCheckResult will_start_result_;
NavigationThrottle::ThrottleCheckResult will_redirect_result_;
NavigationThrottle::ThrottleCheckResult will_process_result_;
NavigationThrottle::ThrottleAction will_start_result_;
NavigationThrottle::ThrottleAction will_redirect_result_;
NavigationThrottle::ThrottleAction will_process_result_;
base::Closure did_call_will_start_;
base::Closure did_call_will_redirect_;
base::Closure did_call_will_process_;
......@@ -117,9 +117,9 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
public:
TestNavigationThrottleInstaller(
WebContents* web_contents,
NavigationThrottle::ThrottleCheckResult will_start_result,
NavigationThrottle::ThrottleCheckResult will_redirect_result,
NavigationThrottle::ThrottleCheckResult will_process_result,
NavigationThrottle::ThrottleAction will_start_result,
NavigationThrottle::ThrottleAction will_redirect_result,
NavigationThrottle::ThrottleAction will_process_result,
const GURL& expected_start_url = GURL())
: WebContentsObserver(web_contents),
will_start_result_(will_start_result),
......@@ -156,8 +156,8 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
}
void Continue(NavigationThrottle::ThrottleCheckResult result) {
ASSERT_NE(NavigationThrottle::DEFER, result);
if (result == NavigationThrottle::PROCEED)
ASSERT_NE(NavigationThrottle::DEFER, result.action());
if (result.action() == NavigationThrottle::PROCEED)
navigation_throttle()->ResumeNavigation();
else
navigation_throttle()->CancelNavigation(result);
......@@ -215,9 +215,9 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
navigation_throttle_ = nullptr;
}
NavigationThrottle::ThrottleCheckResult will_start_result_;
NavigationThrottle::ThrottleCheckResult will_redirect_result_;
NavigationThrottle::ThrottleCheckResult will_process_result_;
NavigationThrottle::ThrottleAction will_start_result_;
NavigationThrottle::ThrottleAction will_redirect_result_;
NavigationThrottle::ThrottleAction will_process_result_;
int will_start_called_ = 0;
int will_redirect_called_ = 0;
int will_process_called_ = 0;
......@@ -241,9 +241,9 @@ class TestDeferringNavigationThrottleInstaller
public:
TestDeferringNavigationThrottleInstaller(
WebContents* web_contents,
NavigationThrottle::ThrottleCheckResult will_start_result,
NavigationThrottle::ThrottleCheckResult will_redirect_result,
NavigationThrottle::ThrottleCheckResult will_process_result,
NavigationThrottle::ThrottleAction will_start_result,
NavigationThrottle::ThrottleAction will_redirect_result,
NavigationThrottle::ThrottleAction will_process_result,
GURL expected_start_url = GURL())
: TestNavigationThrottleInstaller(web_contents,
NavigationThrottle::DEFER,
......@@ -271,9 +271,9 @@ class TestDeferringNavigationThrottleInstaller
}
private:
NavigationThrottle::ThrottleCheckResult will_start_deferred_result_;
NavigationThrottle::ThrottleCheckResult will_redirect_deferred_result_;
NavigationThrottle::ThrottleCheckResult will_process_deferred_result_;
NavigationThrottle::ThrottleAction will_start_deferred_result_;
NavigationThrottle::ThrottleAction will_redirect_deferred_result_;
NavigationThrottle::ThrottleAction will_process_deferred_result_;
};
// Records all navigation start URLs from the WebContents.
......@@ -749,8 +749,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// Exercise both synchronous and deferred throttle check results, and both on
// WillStartRequest and on WillRedirectRequest.
const struct {
NavigationThrottle::ThrottleCheckResult will_start_result;
NavigationThrottle::ThrottleCheckResult will_redirect_result;
NavigationThrottle::ThrottleAction will_start_result;
NavigationThrottle::ThrottleAction will_redirect_result;
bool deferred_block;
} kTestCases[] = {
{NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
......
......@@ -9,6 +9,7 @@
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/request_context_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_side_navigation_test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_web_contents.h"
......@@ -304,7 +305,7 @@ class NavigationHandleImplThrottleInsertionTest
std::vector<std::unique_ptr<NavigationThrottle>> GetThrottles(
NavigationHandle* handle) {
auto throttle = base::MakeUnique<TestNavigationThrottle>(
handle, NavigationThrottle::ThrottleCheckResult::PROCEED);
handle, NavigationThrottle::PROCEED);
std::vector<std::unique_ptr<NavigationThrottle>> vec;
throttles_inserted_++;
vec.push_back(std::move(throttle));
......@@ -864,6 +865,172 @@ TEST_F(NavigationHandleImplTest, BlockResponseThenProceedWillProcessResponse) {
EXPECT_EQ(0, proceed_throttle->will_process_response_calls());
}
TEST_F(NavigationHandleImplTest, BlockRequestCustomNetError) {
TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_BLOCKED_BY_ADMINISTRATOR});
EXPECT_EQ(0, blocked_throttle->will_start_calls());
EXPECT_EQ(0, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillStartRequest();
EXPECT_FALSE(IsDeferringStart());
EXPECT_FALSE(IsDeferringRedirect());
EXPECT_FALSE(IsDeferringResponse());
EXPECT_TRUE(was_callback_called());
EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result().action());
EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR,
callback_result().net_error_code());
EXPECT_FALSE(callback_result().error_page_content().has_value());
EXPECT_EQ(1, blocked_throttle->will_start_calls());
EXPECT_EQ(0, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
}
TEST_F(NavigationHandleImplTest, BlockRequestCustomNetErrorAndErrorHTML) {
std::string expected_error_page_content("<html><body>test</body></html>");
TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_BLOCKED_BY_ADMINISTRATOR,
expected_error_page_content});
EXPECT_EQ(0, blocked_throttle->will_start_calls());
EXPECT_EQ(0, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillStartRequest();
EXPECT_FALSE(IsDeferringStart());
EXPECT_FALSE(IsDeferringRedirect());
EXPECT_FALSE(IsDeferringResponse());
EXPECT_TRUE(was_callback_called());
EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR,
callback_result().net_error_code());
EXPECT_TRUE(callback_result().error_page_content().has_value());
EXPECT_EQ(expected_error_page_content,
callback_result().error_page_content().value());
EXPECT_EQ(1, blocked_throttle->will_start_calls());
EXPECT_EQ(0, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
}
TEST_F(NavigationHandleImplTest, BlockRequestCustomNetErrorInRedirect) {
// BLOCK_REQUEST on redirect requires PlzNavigate.
EnableBrowserSideNavigation();
TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_FILE_NOT_FOUND});
EXPECT_EQ(0, blocked_throttle->will_start_calls());
EXPECT_EQ(0, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillRedirectRequest();
EXPECT_FALSE(IsDeferringStart());
EXPECT_FALSE(IsDeferringRedirect());
EXPECT_FALSE(IsDeferringResponse());
EXPECT_TRUE(was_callback_called());
EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result().action());
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, callback_result().net_error_code());
EXPECT_FALSE(callback_result().error_page_content().has_value());
EXPECT_EQ(0, blocked_throttle->will_start_calls());
EXPECT_EQ(1, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
}
TEST_F(NavigationHandleImplTest,
BlockRequestCustomNetErrorAndErrorHTMLInRedirect) {
// BLOCK_REQUEST on redirect requires PlzNavigate.
EnableBrowserSideNavigation();
std::string expected_error_page_content("<html><body>test</body></html>");
TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_FILE_NOT_FOUND,
expected_error_page_content});
EXPECT_EQ(0, blocked_throttle->will_start_calls());
EXPECT_EQ(0, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillRedirectRequest();
EXPECT_FALSE(IsDeferringStart());
EXPECT_FALSE(IsDeferringRedirect());
EXPECT_FALSE(IsDeferringResponse());
EXPECT_TRUE(was_callback_called());
EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result().action());
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, callback_result().net_error_code());
EXPECT_TRUE(callback_result().error_page_content().has_value());
EXPECT_EQ(expected_error_page_content,
callback_result().error_page_content().value());
EXPECT_EQ(0, blocked_throttle->will_start_calls());
EXPECT_EQ(1, blocked_throttle->will_redirect_calls());
EXPECT_EQ(0, blocked_throttle->will_process_response_calls());
}
TEST_F(NavigationHandleImplTest, BlockResponseCustomNetError) {
TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_RESPONSE, net::ERR_FILE_VIRUS_INFECTED});
EXPECT_EQ(0, block_throttle->will_start_calls());
EXPECT_EQ(0, block_throttle->will_redirect_calls());
EXPECT_EQ(0, block_throttle->will_process_response_calls());
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillProcessResponse();
EXPECT_FALSE(IsDeferringStart());
EXPECT_FALSE(IsDeferringRedirect());
EXPECT_FALSE(IsDeferringResponse());
EXPECT_TRUE(was_callback_called());
EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result().action());
EXPECT_EQ(net::ERR_FILE_VIRUS_INFECTED, callback_result().net_error_code());
EXPECT_FALSE(callback_result().error_page_content().has_value());
EXPECT_EQ(0, block_throttle->will_start_calls());
EXPECT_EQ(0, block_throttle->will_redirect_calls());
EXPECT_EQ(1, block_throttle->will_process_response_calls());
}
TEST_F(NavigationHandleImplTest, BlockResponseCustomNetErrorAndErrorHTML) {
std::string expected_error_page_content("<html><body>test</body></html>");
TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_RESPONSE, net::ERR_FILE_VIRUS_INFECTED,
expected_error_page_content});
EXPECT_EQ(0, block_throttle->will_start_calls());
EXPECT_EQ(0, block_throttle->will_redirect_calls());
EXPECT_EQ(0, block_throttle->will_process_response_calls());
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillProcessResponse();
EXPECT_FALSE(IsDeferringStart());
EXPECT_FALSE(IsDeferringRedirect());
EXPECT_FALSE(IsDeferringResponse());
EXPECT_TRUE(was_callback_called());
EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result().action());
EXPECT_EQ(net::ERR_FILE_VIRUS_INFECTED, callback_result().net_error_code());
EXPECT_TRUE(callback_result().error_page_content().has_value());
EXPECT_EQ(expected_error_page_content,
callback_result().error_page_content().value());
EXPECT_EQ(0, block_throttle->will_start_calls());
EXPECT_EQ(0, block_throttle->will_redirect_calls());
EXPECT_EQ(1, block_throttle->will_process_response_calls());
}
// Checks that a NavigationHandle can be safely deleted by teh execution of one
// of its NavigationThrottle.
TEST_F(NavigationHandleImplTest, DeletionByNavigationThrottle) {
......
......@@ -825,31 +825,32 @@ void NavigationRequest::OnRequestStarted(base::TimeTicks timestamp) {
void NavigationRequest::OnStartChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result != NavigationThrottle::DEFER);
DCHECK(result != NavigationThrottle::BLOCK_RESPONSE);
DCHECK(result.action() != NavigationThrottle::DEFER);
DCHECK(result.action() != NavigationThrottle::BLOCK_RESPONSE);
if (on_start_checks_complete_closure_)
on_start_checks_complete_closure_.Run();
// Abort the request if needed. This will destroy the NavigationRequest.
if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
result == NavigationThrottle::CANCEL ||
result == NavigationThrottle::BLOCK_REQUEST ||
result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL ||
result.action() == NavigationThrottle::BLOCK_REQUEST ||
result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
int error_code = net::ERR_ABORTED;
if (result == NavigationThrottle::BLOCK_REQUEST ||
result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
error_code = net::ERR_BLOCKED_BY_CLIENT;
}
DCHECK_EQ((result.action() == NavigationThrottle::CANCEL ||
result.action() == NavigationThrottle::CANCEL_AND_IGNORE)
? net::ERR_ABORTED
: net::ERR_BLOCKED_BY_CLIENT,
result.net_error_code());
// If the start checks completed synchronously, which could happen if there
// is no onbeforeunload handler or if a NavigationThrottle cancelled it,
// then this could cause reentrancy into NavigationController. So use a
// PostTask to avoid that.
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(&NavigationRequest::OnRequestFailed,
weak_factory_.GetWeakPtr(), false,
error_code, base::nullopt, false));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&NavigationRequest::OnRequestFailed,
weak_factory_.GetWeakPtr(), false,
result.net_error_code(), base::nullopt, false));
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
......@@ -937,23 +938,25 @@ void NavigationRequest::OnStartChecksComplete(
void NavigationRequest::OnRedirectChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result != NavigationThrottle::DEFER);
DCHECK(result != NavigationThrottle::BLOCK_RESPONSE);
DCHECK(result.action() != NavigationThrottle::DEFER);
DCHECK(result.action() != NavigationThrottle::BLOCK_RESPONSE);
// Abort the request if needed. This will destroy the NavigationRequest.
if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
result == NavigationThrottle::CANCEL) {
if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL) {
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE if needed.
OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false);
DCHECK_EQ(net::ERR_ABORTED, result.net_error_code());
OnRequestFailed(false, result.net_error_code(), base::nullopt, false);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
}
if (result == NavigationThrottle::BLOCK_REQUEST ||
result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt, false);
if (result.action() == NavigationThrottle::BLOCK_REQUEST ||
result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
DCHECK_EQ(net::ERR_BLOCKED_BY_CLIENT, result.net_error_code());
OnRequestFailed(false, result.net_error_code(), base::nullopt, false);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
......@@ -964,28 +967,34 @@ void NavigationRequest::OnRedirectChecksComplete(
void NavigationRequest::OnWillProcessResponseChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result != NavigationThrottle::DEFER);
DCHECK(result.action() != NavigationThrottle::DEFER);
// If the NavigationThrottles allowed the navigation to continue, have the
// processing of the response resume in the network stack.
if (result == NavigationThrottle::PROCEED)
if (result.action() == NavigationThrottle::PROCEED)
loader_->ProceedWithResponse();
// Abort the request if needed. This includes requests that were blocked by
// NavigationThrottles and requests that should not commit (e.g. downloads,
// 204/205s). This will destroy the NavigationRequest.
if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
result == NavigationThrottle::CANCEL || !response_should_be_rendered_) {
if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL ||
!response_should_be_rendered_) {
int net_error = result.net_error_code();
if (!response_should_be_rendered_)
net_error = net::ERR_ABORTED;
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false);
DCHECK_EQ(net::ERR_ABORTED, net_error);
OnRequestFailed(false, net_error, base::nullopt, false);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
}
if (result == NavigationThrottle::BLOCK_RESPONSE) {
OnRequestFailed(false, net::ERR_BLOCKED_BY_RESPONSE, base::nullopt, false);
if (result.action() == NavigationThrottle::BLOCK_RESPONSE) {
DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, result.net_error_code());
OnRequestFailed(false, result.net_error_code(), base::nullopt, false);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
......
......@@ -48,7 +48,7 @@ typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)>
void SendCheckResultToIOThread(UIChecksPerformedCallback callback,
NavigationThrottle::ThrottleCheckResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(result, NavigationThrottle::DEFER);
DCHECK_NE(result.action(), NavigationThrottle::DEFER);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::BindOnce(callback, result));
}
......@@ -344,19 +344,20 @@ void NavigationResourceThrottle::set_force_transfer_for_testing(
void NavigationResourceThrottle::OnUIChecksPerformed(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_NE(NavigationThrottle::DEFER, result);
DCHECK_NE(NavigationThrottle::DEFER, result.action());
if (in_cross_site_transition_) {
on_transfer_done_result_ = result;
return;
}
if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
result == NavigationThrottle::CANCEL) {
if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL) {
Cancel();
} else if (result == NavigationThrottle::BLOCK_REQUEST ||
result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
} else if (result.action() == NavigationThrottle::BLOCK_REQUEST ||
result.action() ==
NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
CancelWithError(net::ERR_BLOCKED_BY_CLIENT);
} else if (result == NavigationThrottle::BLOCK_RESPONSE) {
} else if (result.action() == NavigationThrottle::BLOCK_RESPONSE) {
// TODO(mkwst): If we cancel the main frame request with anything other than
// 'net::ERR_ABORTED', we'll trigger some special behavior that might not be
// desirable here (non-POSTs will reload the page, while POST has some logic
......@@ -389,7 +390,7 @@ void NavigationResourceThrottle::OnTransferComplete() {
// If the results of the checks on the UI thread are known, unblock the
// navigation. Otherwise, wait until the callback has executed.
if (on_transfer_done_result_ != NavigationThrottle::DEFER) {
if (on_transfer_done_result_.action() != NavigationThrottle::DEFER) {
OnUIChecksPerformed(on_transfer_done_result_);
on_transfer_done_result_ = NavigationThrottle::DEFER;
}
......
......@@ -8,6 +8,55 @@
namespace content {
namespace {
net::Error DefaultNetErrorCode(NavigationThrottle::ThrottleAction action) {
switch (action) {
case NavigationThrottle::PROCEED:
case NavigationThrottle::DEFER:
return net::OK;
case NavigationThrottle::CANCEL:
case NavigationThrottle::CANCEL_AND_IGNORE:
return net::ERR_ABORTED;
case NavigationThrottle::BLOCK_REQUEST:
case NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE:
return net::ERR_BLOCKED_BY_CLIENT;
case NavigationThrottle::BLOCK_RESPONSE:
return net::ERR_BLOCKED_BY_RESPONSE;
default:
NOTREACHED();
return net::ERR_UNEXPECTED;
}
}
} // namespace
NavigationThrottle::ThrottleCheckResult::ThrottleCheckResult(
NavigationThrottle::ThrottleAction action)
: NavigationThrottle::ThrottleCheckResult(action,
DefaultNetErrorCode(action),
base::nullopt) {}
NavigationThrottle::ThrottleCheckResult::ThrottleCheckResult(
NavigationThrottle::ThrottleAction action,
net::Error net_error_code)
: NavigationThrottle::ThrottleCheckResult(action,
net_error_code,
base::nullopt) {}
NavigationThrottle::ThrottleCheckResult::ThrottleCheckResult(
NavigationThrottle::ThrottleAction action,
net::Error net_error_code,
base::Optional<std::string> error_page_content)
: action_(action),
net_error_code_(net_error_code),
error_page_content_(error_page_content) {}
NavigationThrottle::ThrottleCheckResult::ThrottleCheckResult(
const ThrottleCheckResult& other) = default;
NavigationThrottle::ThrottleCheckResult::~ThrottleCheckResult() {}
NavigationThrottle::NavigationThrottle(NavigationHandle* navigation_handle)
: navigation_handle_(navigation_handle) {}
......
......@@ -5,7 +5,9 @@
#ifndef CONTENT_PUBLIC_BROWSER_NAVIGATION_THROTTLE_H_
#define CONTENT_PUBLIC_BROWSER_NAVIGATION_THROTTLE_H_
#include "base/optional.h"
#include "content/common/content_export.h"
#include "net/base/net_errors.h"
namespace content {
class NavigationHandle;
......@@ -14,30 +16,30 @@ class NavigationHandle;
// UI thread.
class CONTENT_EXPORT NavigationThrottle {
public:
// This is returned to the NavigationHandle to allow the navigation to
// proceed, or to cancel it.
enum ThrottleCheckResult {
// Represents what a NavigationThrottle can decide to do to a navigation. Note
// that this enum is implicitly convertable to ThrottleCheckResult.
enum ThrottleAction {
// The navigation proceeds uninterrupted.
PROCEED,
// Defers the navigation until the NavigationThrottle calls
// NavigationHandle::Resume or NavigationHandle::CancelDeferredRequest.
// If the NavigationHandle is destroyed while the navigation is deferred,
// the navigation will be canceled in the network stack.
// NavigationHandle::Resume or NavigationHandle::CancelDeferredRequest. If
// the NavigationHandle is destroyed while the navigation is deferred, the
// navigation will be canceled in the network stack.
DEFER,
// Cancels the navigation.
CANCEL,
// Cancels the navigation and makes the requester of the navigation acts
// Cancels the navigation and makes the requester of the navigation act
// like the request was never made.
CANCEL_AND_IGNORE,
// Blocks a navigation due to rules asserted before the request is made.
// This can only be returned from WillStartRequest and also from
// WillRedirectRequest when PlzNavigate is enabled. This will result in an
// error page for net::ERR_BLOCKED_BY_CLIENT being loaded in the frame that
// is navigated.
// default net_error code of net::ERR_BLOCKED_BY_CLIENT being loaded in
// the frame that is navigated.
BLOCK_REQUEST,
// Blocks a navigation taking place in a subframe, and collapses the frame
......@@ -52,6 +54,70 @@ class CONTENT_EXPORT NavigationThrottle {
BLOCK_RESPONSE,
};
// ThrottleCheckResult, the return value for NavigationThrottle decision
// methods, is a ThrottleAction value with an attached net::Error and an
// optional attached error page HTML string.
//
// ThrottleCheckResult is implicitly convertible from ThrottleAction, allowing
// the following examples to work:
//
// ThrottleCheckResult WillStartRequest() override {
// // Uses default error for PROCEED (net::OK).
// return PROCEED;
// }
//
// ThrottleCheckResult WillStartRequest() override {
// // Uses default error for BLOCK_REQUEST (net::ERR_BLOCKED_BY_CLIENT).
// return BLOCK_REQUEST;
// }
//
// ThrottleCheckResult WillStartRequest() override {
// // Identical to previous example (net::ERR_BLOCKED_BY_CLIENT)
// return {BLOCK_REQUEST};
// }
//
// ThrottleCheckResult WillStartRequest() override {
// // Uses a custom error code of ERR_FILE_NOT_FOUND.
// return {BLOCK_REQUEST, net::ERR_FILE_NOT_FOUND};
// }
//
// ThrottleCheckResult WillStartRequest() override {
// // Uses a custom error code of ERR_FILE_NOT_FOUND and an error page
// string.
// return {BLOCK_REQUEST,
// net::ERR_FILE_NOT_FOUND,
// std::string("<html><body>Could not find.</body></html>")};
// }
class CONTENT_EXPORT ThrottleCheckResult {
public:
// Construct with just a ThrottleAction, using the default net::Error for
// that action.
ThrottleCheckResult(ThrottleAction action);
// Construct with an action and error.
ThrottleCheckResult(ThrottleAction action, net::Error net_error_code);
// Construct with an action, error, and error page HTML.
ThrottleCheckResult(ThrottleAction action,
net::Error net_error_code,
base::Optional<std::string> error_page_content);
ThrottleCheckResult(const ThrottleCheckResult& other);
~ThrottleCheckResult();
ThrottleAction action() const { return action_; }
net::Error net_error_code() const { return net_error_code_; }
base::Optional<std::string> error_page_content() {
return error_page_content_;
}
private:
ThrottleAction action_;
net::Error net_error_code_;
base::Optional<std::string> error_page_content_;
};
NavigationThrottle(NavigationHandle* navigation_handle);
virtual ~NavigationThrottle();
......@@ -111,6 +177,21 @@ class CONTENT_EXPORT NavigationThrottle {
NavigationHandle* navigation_handle_;
};
#if defined(UNIT_TEST)
// Test-only operator== to enable assertions like:
// EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillProcessResponse())
inline bool operator==(NavigationThrottle::ThrottleAction lhs,
const NavigationThrottle::ThrottleCheckResult& rhs) {
return lhs == rhs.action();
}
// Test-only operator!= to enable assertions like:
// EXPECT_NE(NavigationThrottle::PROCEED, throttle->WillProcessResponse())
inline bool operator!=(NavigationThrottle::ThrottleAction lhs,
const NavigationThrottle::ThrottleCheckResult& rhs) {
return lhs != rhs.action();
}
#endif
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_NAVIGATION_THROTTLE_H_
......@@ -203,7 +203,7 @@ void NavigationSimulator::Start() {
WaitForThrottleChecksComplete();
CHECK_EQ(1, num_did_start_navigation_called_);
if (GetLastThrottleCheckResult() == NavigationThrottle::PROCEED) {
if (GetLastThrottleCheckResult().action() == NavigationThrottle::PROCEED) {
CHECK_EQ(1, num_will_start_request_called_);
} else {
FailFromThrottleCheck(GetLastThrottleCheckResult());
......@@ -259,7 +259,7 @@ void NavigationSimulator::Redirect(const GURL& new_url) {
WaitForThrottleChecksComplete();
if (GetLastThrottleCheckResult() == NavigationThrottle::PROCEED) {
if (GetLastThrottleCheckResult().action() == NavigationThrottle::PROCEED) {
CHECK_EQ(previous_num_will_redirect_request_called + 1,
num_will_redirect_request_called_);
CHECK_EQ(previous_did_redirect_navigation_called + 1,
......@@ -330,7 +330,7 @@ void NavigationSimulator::ReadyToCommit() {
IsURLHandledByNetworkStack(navigation_url_))) {
WaitForThrottleChecksComplete();
if (GetLastThrottleCheckResult() != NavigationThrottle::PROCEED) {
if (GetLastThrottleCheckResult().action() != NavigationThrottle::PROCEED) {
FailFromThrottleCheck(GetLastThrottleCheckResult());
return;
}
......@@ -849,38 +849,24 @@ RenderFrameHost* NavigationSimulator::GetFinalRenderFrameHost() {
void NavigationSimulator::FailFromThrottleCheck(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK_NE(result, NavigationThrottle::PROCEED);
DCHECK_NE(NavigationThrottle::PROCEED, result.action());
state_ = FAILED;
// Special failure logic only needed for non-PlzNavigate case.
if (IsBrowserSideNavigationEnabled())
return;
int error_code = net::OK;
switch (result) {
case NavigationThrottle::PROCEED:
case NavigationThrottle::DEFER:
NOTREACHED();
break;
case NavigationThrottle::CANCEL:
case NavigationThrottle::CANCEL_AND_IGNORE:
error_code = net::ERR_ABORTED;
break;
case NavigationThrottle::BLOCK_REQUEST:
case NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE:
error_code = net::ERR_BLOCKED_BY_CLIENT;
break;
case NavigationThrottle::BLOCK_RESPONSE:
error_code = net::ERR_BLOCKED_BY_RESPONSE;
break;
};
DCHECK_NE(NavigationThrottle::DEFER, result.action());
DCHECK_NE(NavigationThrottle::PROCEED, result.action());
DCHECK_NE(net::OK, result.net_error_code());
FrameHostMsg_DidFailProvisionalLoadWithError_Params error_params;
error_params.error_code = error_code;
error_params.error_code = result.net_error_code();
error_params.url = navigation_url_;
render_frame_host_->OnMessageReceived(
FrameHostMsg_DidFailProvisionalLoadWithError(
render_frame_host_->GetRoutingID(), error_params));
bool should_result_in_error_page = error_code != net::ERR_ABORTED;
bool should_result_in_error_page =
result.net_error_code() != net::ERR_ABORTED;
if (!should_result_in_error_page) {
render_frame_host_->OnMessageReceived(
FrameHostMsg_DidStopLoading(render_frame_host_->GetRoutingID()));
......
......@@ -191,7 +191,7 @@ ExtensionNavigationThrottle::WillStartRequest() {
content::NavigationThrottle::ThrottleCheckResult
ExtensionNavigationThrottle::WillRedirectRequest() {
ThrottleCheckResult result = WillStartOrRedirectRequest();
if (result == BLOCK_REQUEST) {
if (result.action() == BLOCK_REQUEST) {
// TODO(nick): https://crbug.com/695421 means that BLOCK_REQUEST does not
// work here. Once PlzNavigate is enabled 100%, just return |result|.
return CANCEL;
......
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