Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(584)

Unified Diff: content/browser/loader/navigation_resource_throttle.cc

Issue 1269813002: Add a NavigationThrottle to the public content/ interface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@navigation-api
Patch Set: Removed TestNavigationHandle + pointer to WebContents Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/loader/navigation_resource_throttle.cc
diff --git a/content/browser/loader/navigation_resource_throttle.cc b/content/browser/loader/navigation_resource_throttle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8dd143cc079f84d1f8751465da776240fc5abbb4
--- /dev/null
+++ b/content/browser/loader/navigation_resource_throttle.cc
@@ -0,0 +1,154 @@
+// Copyright 2015 The Chromium 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 "content/browser/loader/navigation_resource_throttle.h"
+
+#include "base/callback.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/public/browser/resource_context.h"
+#include "content/public/browser/resource_controller.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/common/referrer.h"
+#include "net/url_request/redirect_info.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_job_factory.h"
+#include "ui/base/page_transition_types.h"
+
+namespace content {
+
+namespace {
+typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)>
+ UIChecksPerformedCallback;
+
+void CheckWillStartRequestOnUIThread(UIChecksPerformedCallback callback,
+ int render_process_id,
+ int render_frame_host_id,
+ bool is_post,
+ const Referrer& sanitized_referrer,
+ bool has_user_gesture,
+ ui::PageTransition transition,
+ bool is_external_protocol) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::PROCEED;
+ RenderFrameHostImpl* render_frame_host =
+ RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
+ if (render_frame_host) {
+ NavigationHandleImpl* navigation_handle =
+ render_frame_host->navigation_handle();
+ if (navigation_handle) {
+ result = navigation_handle->WillStartRequest(is_post, sanitized_referrer,
+ has_user_gesture, transition,
+ is_external_protocol);
+ }
+ }
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, result));
+}
+
+void CheckWillRedirectRequestOnUIThread(UIChecksPerformedCallback callback,
+ int render_process_id,
+ int render_frame_host_id,
+ const GURL& new_url,
+ bool new_method_is_post,
+ const GURL& new_referrer_url,
+ bool new_is_external_protocol) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::PROCEED;
+ RenderFrameHostImpl* render_frame_host =
+ RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
+ if (render_frame_host) {
+ NavigationHandleImpl* navigation_handle =
+ render_frame_host->navigation_handle();
Charlie Reis 2015/09/18 05:40:02 Are there races possible here? Suppose the UI thr
clamy 2015/09/18 17:35:39 Due to all IPCs being processed on the IO thread i
Charlie Reis 2015/09/18 17:58:39 Acknowledged.
+ if (navigation_handle) {
+ RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
+ GURL new_validated_url = new_url;
+ rph->FilterURL(false, &new_validated_url);
+ result = navigation_handle->WillRedirectRequest(
+ new_validated_url, new_method_is_post, new_referrer_url,
+ new_is_external_protocol);
+ }
+ }
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, result));
+}
+} // namespace
+
+NavigationResourceThrottle::NavigationResourceThrottle(net::URLRequest* request)
+ : request_(request), weak_ptr_factory_(this) {}
+
+NavigationResourceThrottle::~NavigationResourceThrottle() {}
+
+void NavigationResourceThrottle::WillStartRequest(bool* defer) {
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
+ if (!info)
+ return;
+
+ int render_process_id, render_frame_id;
+ if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
+ return;
+
+ bool is_external_protocol =
+ !info->GetContext()->GetRequestContext()->job_factory()->IsHandledURL(
+ request_->url());
+ UIChecksPerformedCallback callback =
+ base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed,
+ weak_ptr_factory_.GetWeakPtr());
+ DCHECK(request_->method() == "POST" || request_->method() == "GET");
+ BrowserThread::PostTask(
Charlie Reis 2015/09/18 05:40:02 Sanity check: This is doing a hop to the UI thread
clamy 2015/09/18 17:35:39 On Android we are replacing a ResourceThrottle tha
nasko 2015/09/18 17:58:19 I don't think we can ensure only one thread hop pe
Charlie Reis 2015/09/18 17:58:39 Acknowledged.
clamy 2015/09/18 18:21:23 Yes that's what I meant (but my wording was not go
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&CheckWillStartRequestOnUIThread, callback, render_process_id,
+ render_frame_id, request_->method() == "POST",
+ Referrer::SanitizeForRequest(
+ request_->url(), Referrer(GURL(request_->referrer()),
+ info->GetReferrerPolicy())),
+ info->HasUserGesture(), info->GetPageTransition(),
+ is_external_protocol));
+ *defer = true;
+}
+
+void NavigationResourceThrottle::WillRedirectRequest(
+ const net::RedirectInfo& redirect_info,
+ bool* defer) {
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
+ if (!info)
+ return;
+
+ int render_process_id, render_frame_id;
+ if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
+ return;
+
+ bool new_is_external_protocol =
+ !info->GetContext()->GetRequestContext()->job_factory()->IsHandledURL(
+ request_->url());
+ DCHECK(redirect_info.new_method == "POST" ||
+ redirect_info.new_method == "GET");
+ UIChecksPerformedCallback callback =
+ base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed,
+ weak_ptr_factory_.GetWeakPtr());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&CheckWillRedirectRequestOnUIThread, callback,
+ render_process_id, render_frame_id, redirect_info.new_url,
+ redirect_info.new_method == "POST",
+ GURL(redirect_info.new_referrer), new_is_external_protocol));
+ *defer = true;
+}
+
+const char* NavigationResourceThrottle::GetNameForLogging() const {
+ return "NavigationResourceThrottle";
+}
+
+void NavigationResourceThrottle::OnUIChecksPerformed(
+ NavigationThrottle::ThrottleCheckResult result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (result == NavigationThrottle::CANCEL_AND_IGNORE) {
+ controller()->CancelAndIgnore();
+ } else {
+ controller()->Resume();
+ }
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698