• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Embedded Framework Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be found
3 // in the LICENSE file.
4 
5 #include "libcef/browser/net/throttle_handler.h"
6 
7 #include "libcef/browser/browser_host_base.h"
8 #include "libcef/browser/browser_info_manager.h"
9 #include "libcef/browser/frame_host_impl.h"
10 #include "libcef/common/frame_util.h"
11 #include "libcef/common/request_impl.h"
12 
13 #include "components/navigation_interception/intercept_navigation_throttle.h"
14 #include "components/navigation_interception/navigation_params.h"
15 #include "content/public/browser/navigation_handle.h"
16 #include "content/public/browser/navigation_throttle.h"
17 #include "content/public/browser/page_navigator.h"
18 
19 namespace throttle {
20 
21 namespace {
22 
23 // TODO(cef): We can't currently trust NavigationParams::is_main_frame() because
24 // it's always set to true in
25 // InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation. Remove the
26 // |is_main_frame| argument once this problem is fixed.
NavigationOnUIThread(bool is_main_frame,bool is_pdf,const content::GlobalRenderFrameHostId & global_id,const content::GlobalRenderFrameHostId & parent_global_id,content::WebContents * source,const navigation_interception::NavigationParams & params)27 bool NavigationOnUIThread(
28     bool is_main_frame,
29     bool is_pdf,
30     const content::GlobalRenderFrameHostId& global_id,
31     const content::GlobalRenderFrameHostId& parent_global_id,
32     content::WebContents* source,
33     const navigation_interception::NavigationParams& params) {
34   CEF_REQUIRE_UIT();
35 
36   content::OpenURLParams open_params(
37       params.url(), params.referrer(), WindowOpenDisposition::CURRENT_TAB,
38       params.transition_type(), params.is_renderer_initiated());
39   open_params.user_gesture = params.has_user_gesture();
40   open_params.initiator_origin = params.initiator_origin();
41   open_params.is_pdf = is_pdf;
42 
43   CefRefPtr<CefBrowserHostBase> browser;
44   if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation(
45           source->GetMainFrame(), open_params, browser)) {
46     // Cancel the navigation.
47     return true;
48   }
49 
50   bool ignore_navigation = false;
51 
52   if (browser) {
53     if (auto client = browser->GetClient()) {
54       if (auto handler = client->GetRequestHandler()) {
55         CefRefPtr<CefFrame> frame;
56         if (is_main_frame) {
57           frame = browser->GetMainFrame();
58         } else {
59           frame = browser->GetFrameForGlobalId(global_id);
60         }
61         if (!frame) {
62           // Create a temporary frame object for navigation of sub-frames that
63           // don't yet exist.
64           frame = browser->browser_info()->CreateTempSubFrame(parent_global_id);
65         }
66 
67         CefRefPtr<CefRequestImpl> request = new CefRequestImpl();
68         request->Set(params, is_main_frame);
69         request->SetReadOnly(true);
70 
71         // Initiating a new navigation in OnBeforeBrowse will delete the
72         // InterceptNavigationThrottle that currently owns this callback,
73         // resulting in a crash. Use the lock to prevent that.
74         auto navigation_lock = browser->browser_info()->CreateNavigationLock();
75         ignore_navigation = handler->OnBeforeBrowse(
76             browser.get(), frame, request.get(), params.has_user_gesture(),
77             params.is_redirect());
78       }
79     }
80   }
81 
82   return ignore_navigation;
83 }
84 
85 }  // namespace
86 
CreateThrottlesForNavigation(content::NavigationHandle * navigation_handle,NavigationThrottleList & throttles)87 void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
88                                   NavigationThrottleList& throttles) {
89   CEF_REQUIRE_UIT();
90 
91   const bool is_main_frame = navigation_handle->IsInMainFrame();
92   const bool is_pdf = navigation_handle->IsPdf();
93   const auto global_id = frame_util::GetGlobalId(navigation_handle);
94 
95   // Identify the RenderFrameHost that originated the navigation.
96   const auto parent_global_id =
97       !is_main_frame ? navigation_handle->GetParentFrame()->GetGlobalId()
98                      : frame_util::InvalidGlobalId();
99 
100   // Must use SynchronyMode::kSync to ensure that OnBeforeBrowse is always
101   // called before OnBeforeResourceLoad.
102   std::unique_ptr<content::NavigationThrottle> throttle =
103       std::make_unique<navigation_interception::InterceptNavigationThrottle>(
104           navigation_handle,
105           base::BindRepeating(&NavigationOnUIThread, is_main_frame, is_pdf,
106                               global_id, parent_global_id),
107           navigation_interception::SynchronyMode::kSync);
108   throttles.push_back(std::move(throttle));
109 }
110 
111 }  // namespace throttle
112