118 lines
4.4 KiB
C++
118 lines
4.4 KiB
C++
// Copyright 2020 The Chromium Embedded Framework 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 "libcef/browser/net/throttle_handler.h"
|
|
|
|
#include "libcef/browser/browser_host_base.h"
|
|
#include "libcef/browser/browser_info_manager.h"
|
|
#include "libcef/browser/frame_host_impl.h"
|
|
#include "libcef/common/request_impl.h"
|
|
|
|
#include "components/navigation_interception/intercept_navigation_throttle.h"
|
|
#include "components/navigation_interception/navigation_params.h"
|
|
#include "content/public/browser/navigation_handle.h"
|
|
#include "content/public/browser/navigation_throttle.h"
|
|
#include "content/public/browser/page_navigator.h"
|
|
|
|
namespace throttle {
|
|
|
|
namespace {
|
|
|
|
// TODO(cef): We can't currently trust NavigationParams::is_main_frame() because
|
|
// it's always set to true in
|
|
// InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation. Remove the
|
|
// |is_main_frame| argument once this problem is fixed.
|
|
bool NavigationOnUIThread(
|
|
bool is_main_frame,
|
|
int64_t frame_id,
|
|
int64_t parent_frame_id,
|
|
int frame_tree_node_id,
|
|
content::WebContents* source,
|
|
const navigation_interception::NavigationParams& params) {
|
|
CEF_REQUIRE_UIT();
|
|
|
|
content::OpenURLParams open_params(
|
|
params.url(), params.referrer(), WindowOpenDisposition::CURRENT_TAB,
|
|
params.transition_type(), params.is_renderer_initiated());
|
|
open_params.user_gesture = params.has_user_gesture();
|
|
open_params.initiator_origin = params.initiator_origin();
|
|
|
|
CefRefPtr<CefBrowserHostBase> browser;
|
|
if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation(
|
|
source->GetMainFrame(), open_params, browser)) {
|
|
// Cancel the navigation.
|
|
return true;
|
|
}
|
|
|
|
bool ignore_navigation = false;
|
|
|
|
if (browser) {
|
|
if (auto client = browser->GetClient()) {
|
|
if (auto handler = client->GetRequestHandler()) {
|
|
CefRefPtr<CefFrame> frame;
|
|
if (is_main_frame) {
|
|
frame = browser->GetMainFrame();
|
|
} else if (frame_id >= 0) {
|
|
frame = browser->GetFrame(frame_id);
|
|
}
|
|
if (!frame && frame_tree_node_id >= 0) {
|
|
frame = browser->GetFrameForFrameTreeNode(frame_tree_node_id);
|
|
}
|
|
if (!frame) {
|
|
// Create a temporary frame object for navigation of sub-frames that
|
|
// don't yet exist.
|
|
frame = browser->browser_info()->CreateTempSubFrame(parent_frame_id);
|
|
}
|
|
|
|
CefRefPtr<CefRequestImpl> request = new CefRequestImpl();
|
|
request->Set(params, is_main_frame);
|
|
request->SetReadOnly(true);
|
|
|
|
// Initiating a new navigation in OnBeforeBrowse will delete the
|
|
// InterceptNavigationThrottle that currently owns this callback,
|
|
// resulting in a crash. Use the lock to prevent that.
|
|
auto navigation_lock = browser->browser_info()->CreateNavigationLock();
|
|
ignore_navigation = handler->OnBeforeBrowse(
|
|
browser.get(), frame, request.get(), params.has_user_gesture(),
|
|
params.is_redirect());
|
|
}
|
|
}
|
|
}
|
|
|
|
return ignore_navigation;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
|
|
NavigationThrottleList& throttles) {
|
|
CEF_REQUIRE_UIT();
|
|
|
|
const bool is_main_frame = navigation_handle->IsInMainFrame();
|
|
|
|
// Identify the RenderFrameHost that originated the navigation.
|
|
const int64_t parent_frame_id =
|
|
!is_main_frame
|
|
? CefFrameHostImpl::MakeFrameId(navigation_handle->GetParentFrame())
|
|
: CefFrameHostImpl::kInvalidFrameId;
|
|
|
|
const int64_t frame_id = !is_main_frame && navigation_handle->HasCommitted()
|
|
? CefFrameHostImpl::MakeFrameId(
|
|
navigation_handle->GetRenderFrameHost())
|
|
: CefFrameHostImpl::kInvalidFrameId;
|
|
|
|
// Must use SynchronyMode::kSync to ensure that OnBeforeBrowse is always
|
|
// called before OnBeforeResourceLoad.
|
|
std::unique_ptr<content::NavigationThrottle> throttle =
|
|
std::make_unique<navigation_interception::InterceptNavigationThrottle>(
|
|
navigation_handle,
|
|
base::BindRepeating(&NavigationOnUIThread, is_main_frame, frame_id,
|
|
parent_frame_id,
|
|
navigation_handle->GetFrameTreeNodeId()),
|
|
navigation_interception::SynchronyMode::kSync);
|
|
throttles.push_back(std::move(throttle));
|
|
}
|
|
|
|
} // namespace throttle
|