diff options
author | nasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-04 21:14:18 +0000 |
---|---|---|
committer | nasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-04 21:14:18 +0000 |
commit | 65920f331b2945f739abdbb8a3ede4ca68f142a6 (patch) | |
tree | 08f9cbc66775fbabdcf35e97913d9d8762cf4a59 /content/renderer/render_view_impl.cc | |
parent | 3a1f1144d2385c01e62f9b474b173a8a8af47608 (diff) | |
download | chromium_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.cc | 293 |
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( |