summaryrefslogtreecommitdiffstats
path: root/content/renderer/render_view_impl.cc
diff options
context:
space:
mode:
authornasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-04 21:14:18 +0000
committernasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-04 21:14:18 +0000
commit65920f331b2945f739abdbb8a3ede4ca68f142a6 (patch)
tree08f9cbc66775fbabdcf35e97913d9d8762cf4a59 /content/renderer/render_view_impl.cc
parent3a1f1144d2385c01e62f9b474b173a8a8af47608 (diff)
downloadchromium_src-65920f331b2945f739abdbb8a3ede4ca68f142a6.zip
chromium_src-65920f331b2945f739abdbb8a3ede4ca68f142a6.tar.gz
chromium_src-65920f331b2945f739abdbb8a3ede4ca68f142a6.tar.bz2
Move OpenURL from RenderView to RenderFrame.
This CL is follow up attempt at landing this change. The original CL is https://codereview.chromium.org/165063003 and is also ps1. BUG=304341 R=creis@chromium.org Review URL: https://codereview.chromium.org/186623004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254821 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/render_view_impl.cc')
-rw-r--r--content/renderer/render_view_impl.cc293
1 files changed, 2 insertions, 291 deletions
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index bf4357f..f4db0f2 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -378,44 +378,6 @@ Referrer RenderViewImpl::GetReferrerFromRequest(
request.referrerPolicy());
}
-// Returns false unless this is a top-level navigation.
-static bool IsTopLevelNavigation(WebFrame* frame) {
- return frame->parent() == NULL;
-}
-
-// Returns false unless this is a top-level navigation that crosses origins.
-static bool IsNonLocalTopLevelNavigation(const GURL& url,
- WebFrame* frame,
- WebNavigationType type,
- bool is_form_post) {
- if (!IsTopLevelNavigation(frame))
- return false;
-
- // Navigations initiated within Webkit are not sent out to the external host
- // in the following cases.
- // 1. The url scheme is not http/https
- // 2. The origin of the url and the opener is the same in which case the
- // opener relationship is maintained.
- // 3. Reloads/form submits/back forward navigations
- if (!url.SchemeIs(kHttpScheme) && !url.SchemeIs(kHttpsScheme))
- return false;
-
- if (type != blink::WebNavigationTypeReload &&
- type != blink::WebNavigationTypeBackForward && !is_form_post) {
- // The opener relationship between the new window and the parent allows the
- // new window to script the parent and vice versa. This is not allowed if
- // the origins of the two domains are different. This can be treated as a
- // top level navigation and routed back to the host.
- blink::WebFrame* opener = frame->opener();
- if (!opener)
- return true;
-
- if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin())
- return true;
- }
- return false;
-}
-
// static
void RenderViewImpl::NotifyTimezoneChange(blink::WebFrame* frame) {
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
@@ -426,7 +388,8 @@ void RenderViewImpl::NotifyTimezoneChange(blink::WebFrame* frame) {
NotifyTimezoneChange(child);
}
-static WindowOpenDisposition NavigationPolicyToDisposition(
+// static
+WindowOpenDisposition RenderViewImpl::NavigationPolicyToDisposition(
WebNavigationPolicy policy) {
switch (policy) {
case blink::WebNavigationPolicyIgnore:
@@ -1630,47 +1593,6 @@ void RenderViewImpl::SendUpdateState(const WebHistoryItem& item) {
routing_id_, page_id_, HistoryItemToPageState(item)));
}
-void RenderViewImpl::OpenURL(WebFrame* frame,
- const GURL& url,
- const Referrer& referrer,
- WebNavigationPolicy policy) {
- ViewHostMsg_OpenURL_Params params;
- params.url = url;
- params.referrer = referrer;
- params.disposition = NavigationPolicyToDisposition(policy);
- params.frame_id = RenderFrameImpl::FromWebFrame(frame)->GetRoutingID();
- WebDataSource* ds = frame->provisionalDataSource();
- if (ds) {
- DocumentState* document_state = DocumentState::FromDataSource(ds);
- NavigationState* navigation_state = document_state->navigation_state();
- if (navigation_state->is_content_initiated()) {
- params.should_replace_current_entry = ds->replacesCurrentHistoryItem();
- } else {
- // This is necessary to preserve the should_replace_current_entry value on
- // cross-process redirects, in the event it was set by a previous process.
- //
- // TODO(davidben): Avoid this awkward duplication of state. See comment on
- // NavigationState::should_replace_current_entry().
- params.should_replace_current_entry =
- navigation_state->should_replace_current_entry();
- }
- } else {
- params.should_replace_current_entry = false;
- }
- params.user_gesture = WebUserGestureIndicator::isProcessingUserGesture();
- if (GetContentClient()->renderer()->AllowPopup())
- params.user_gesture = true;
-
- if (policy == blink::WebNavigationPolicyNewBackgroundTab ||
- policy == blink::WebNavigationPolicyNewForegroundTab ||
- policy == blink::WebNavigationPolicyNewWindow ||
- policy == blink::WebNavigationPolicyNewPopup) {
- WebUserGestureIndicator::consumeUserGesture();
- }
-
- Send(new ViewHostMsg_OpenURL(routing_id_, params));
-}
-
// WebViewDelegate ------------------------------------------------------------
void RenderViewImpl::LoadNavigationErrorPage(
@@ -2587,217 +2509,6 @@ const std::string& RenderViewImpl::GetAcceptLanguages() const {
return renderer_preferences_.accept_languages;
}
-WebNavigationPolicy RenderViewImpl::DecidePolicyForNavigation(
- RenderFrame* render_frame, WebFrame* frame,
- WebDataSource::ExtraData* extraData, const WebURLRequest& request,
- WebNavigationType type, WebNavigationPolicy default_policy,
- bool is_redirect) {
-#ifdef OS_ANDROID
- // The handlenavigation API is deprecated and will be removed once
- // crbug.com/325351 is resolved.
- if (request.url() != GURL(kSwappedOutURL) &&
- GetContentClient()->renderer()->HandleNavigation(
- render_frame,
- static_cast<DocumentState*>(extraData),
- opener_id_,
- frame,
- request,
- type,
- default_policy,
- is_redirect)) {
- return blink::WebNavigationPolicyIgnore;
- }
-#endif
-
- Referrer referrer(GetReferrerFromRequest(frame, request));
-
- if (is_swapped_out_) {
- if (request.url() != GURL(kSwappedOutURL)) {
- // Targeted links may try to navigate a swapped out frame. Allow the
- // browser process to navigate the tab instead. Note that it is also
- // possible for non-targeted navigations (from this view) to arrive
- // here just after we are swapped out. It's ok to send them to the
- // browser, as long as they're for the top level frame.
- // TODO(creis): Ensure this supports targeted form submissions when
- // fixing http://crbug.com/101395.
- if (frame->parent() == NULL) {
- OpenURL(frame, request.url(), referrer, default_policy);
- return blink::WebNavigationPolicyIgnore; // Suppress the load here.
- }
-
- // We should otherwise ignore in-process iframe navigations, if they
- // arrive just after we are swapped out.
- return blink::WebNavigationPolicyIgnore;
- }
-
- // Allow kSwappedOutURL to complete.
- return default_policy;
- }
-
- // Webkit is asking whether to navigate to a new URL.
- // This is fine normally, except if we're showing UI from one security
- // context and they're trying to navigate to a different context.
- const GURL& url = request.url();
-
- // A content initiated navigation may have originated from a link-click,
- // script, drag-n-drop operation, etc.
- bool is_content_initiated = static_cast<DocumentState*>(extraData)->
- navigation_state()->is_content_initiated();
-
- // Experimental:
- // If --enable-strict-site-isolation or --site-per-process is enabled, send
- // all top-level navigations to the browser to let it swap processes when
- // crossing site boundaries. This is currently expected to break some script
- // calls and navigations, such as form submissions.
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- bool force_swap_due_to_flag =
- command_line.HasSwitch(switches::kEnableStrictSiteIsolation) ||
- command_line.HasSwitch(switches::kSitePerProcess);
- if (force_swap_due_to_flag &&
- !frame->parent() && (is_content_initiated || is_redirect)) {
- WebString origin_str = frame->document().securityOrigin().toString();
- GURL frame_url(origin_str.utf8().data());
- // TODO(cevans): revisit whether this site check is still necessary once
- // crbug.com/101395 is fixed.
- bool same_domain_or_host =
- net::registry_controlled_domains::SameDomainOrHost(
- frame_url,
- url,
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- if (!same_domain_or_host || frame_url.scheme() != url.scheme()) {
- OpenURL(frame, url, referrer, default_policy);
- return blink::WebNavigationPolicyIgnore;
- }
- }
-
- // If the browser is interested, then give it a chance to look at the request.
- if (is_content_initiated) {
- bool is_form_post = ((type == blink::WebNavigationTypeFormSubmitted) ||
- (type == blink::WebNavigationTypeFormResubmitted)) &&
- EqualsASCII(request.httpMethod(), "POST");
- bool browser_handles_request =
- renderer_preferences_.browser_handles_non_local_top_level_requests &&
- IsNonLocalTopLevelNavigation(url, frame, type, is_form_post);
- if (!browser_handles_request) {
- browser_handles_request = IsTopLevelNavigation(frame) &&
- renderer_preferences_.browser_handles_all_top_level_requests;
- }
-
- if (browser_handles_request) {
- // Reset these counters as the RenderView could be reused for the next
- // navigation.
- page_id_ = -1;
- last_page_id_sent_to_browser_ = -1;
- OpenURL(frame, url, referrer, default_policy);
- return blink::WebNavigationPolicyIgnore; // Suppress the load here.
- }
- }
-
- // Use the frame's original request's URL rather than the document's URL for
- // subsequent checks. For a popup, the document's URL may become the opener
- // window's URL if the opener has called document.write().
- // See http://crbug.com/93517.
- GURL old_url(frame->dataSource()->request().url());
-
- // Detect when we're crossing a permission-based boundary (e.g. into or out of
- // an extension or app origin, leaving a WebUI page, etc). We only care about
- // top-level navigations (not iframes). But we sometimes navigate to
- // about:blank to clear a tab, and we want to still allow that.
- //
- // Note: this is known to break POST submissions when crossing process
- // boundaries until http://crbug.com/101395 is fixed. This is better for
- // security than loading a WebUI, extension or app page in the wrong process.
- // POST requests don't work because this mechanism does not preserve form
- // POST data. We will need to send the request's httpBody data up to the
- // browser process, and issue a special POST navigation in WebKit (via
- // FrameLoader::loadFrameRequest). See ResourceDispatcher and WebURLLoaderImpl
- // for examples of how to send the httpBody data.
- if (!frame->parent() && is_content_initiated &&
- !url.SchemeIs(chrome::kAboutScheme)) {
- bool send_referrer = false;
-
- // All navigations to or from WebUI URLs or within WebUI-enabled
- // RenderProcesses must be handled by the browser process so that the
- // correct bindings and data sources can be registered.
- // Similarly, navigations to view-source URLs or within ViewSource mode
- // must be handled by the browser process (except for reloads - those are
- // safe to leave within the renderer).
- // Lastly, access to file:// URLs from non-file:// URL pages must be
- // handled by the browser so that ordinary renderer processes don't get
- // blessed with file permissions.
- int cumulative_bindings = RenderProcess::current()->GetEnabledBindings();
- bool is_initial_navigation = page_id_ == -1;
- bool should_fork = HasWebUIScheme(url) || HasWebUIScheme(old_url) ||
- (cumulative_bindings & BINDINGS_POLICY_WEB_UI) ||
- url.SchemeIs(kViewSourceScheme) ||
- (frame->isViewSourceModeEnabled() &&
- type != blink::WebNavigationTypeReload);
-
- if (!should_fork && url.SchemeIs(kFileScheme)) {
- // Fork non-file to file opens. Check the opener URL if this is the
- // initial navigation in a newly opened window.
- GURL source_url(old_url);
- if (is_initial_navigation && source_url.is_empty() && frame->opener())
- source_url = frame->opener()->top()->document().url();
- DCHECK(!source_url.is_empty());
- should_fork = !source_url.SchemeIs(kFileScheme);
- }
-
- if (!should_fork) {
- // Give the embedder a chance.
- should_fork = GetContentClient()->renderer()->ShouldFork(
- frame, url, request.httpMethod().utf8(), is_initial_navigation,
- is_redirect, &send_referrer);
- }
-
- if (should_fork) {
- OpenURL(
- frame, url, send_referrer ? referrer : Referrer(), default_policy);
- return blink::WebNavigationPolicyIgnore; // Suppress the load here.
- }
- }
-
- // Detect when a page is "forking" a new tab that can be safely rendered in
- // its own process. This is done by sites like Gmail that try to open links
- // in new windows without script connections back to the original page. We
- // treat such cases as browser navigations (in which we will create a new
- // renderer for a cross-site navigation), rather than WebKit navigations.
- //
- // We use the following heuristic to decide whether to fork a new page in its
- // own process:
- // The parent page must open a new tab to about:blank, set the new tab's
- // window.opener to null, and then redirect the tab to a cross-site URL using
- // JavaScript.
- //
- // TODO(creis): Deprecate this logic once we can rely on rel=noreferrer
- // (see below).
- bool is_fork =
- // Must start from a tab showing about:blank, which is later redirected.
- old_url == GURL(kAboutBlankURL) &&
- // Must be the first real navigation of the tab.
- historyBackListCount() < 1 &&
- historyForwardListCount() < 1 &&
- // The parent page must have set the child's window.opener to null before
- // redirecting to the desired URL.
- frame->opener() == NULL &&
- // Must be a top-level frame.
- frame->parent() == NULL &&
- // Must not have issued the request from this page.
- is_content_initiated &&
- // Must be targeted at the current tab.
- default_policy == blink::WebNavigationPolicyCurrentTab &&
- // Must be a JavaScript navigation, which appears as "other".
- type == blink::WebNavigationTypeOther;
-
- if (is_fork) {
- // Open the URL via the browser, not via WebKit.
- OpenURL(frame, url, Referrer(), default_policy);
- return blink::WebNavigationPolicyIgnore;
- }
-
- return default_policy;
-}
-
void RenderViewImpl::willSendSubmitEvent(blink::WebFrame* frame,
const blink::WebFormElement& form) {
FOR_EACH_OBSERVER(