summaryrefslogtreecommitdiffstats
path: root/content/browser/loader
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/loader')
-rw-r--r--content/browser/loader/navigation_resource_throttle.cc154
-rw-r--r--content/browser/loader/navigation_resource_throttle.h44
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.cc11
3 files changed, 209 insertions, 0 deletions
diff --git a/content/browser/loader/navigation_resource_throttle.cc b/content/browser/loader/navigation_resource_throttle.cc
new file mode 100644
index 0000000..8dd143c
--- /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();
+ 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(
+ 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
diff --git a/content/browser/loader/navigation_resource_throttle.h b/content/browser/loader/navigation_resource_throttle.h
new file mode 100644
index 0000000..e46b59d
--- /dev/null
+++ b/content/browser/loader/navigation_resource_throttle.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_
+#define CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/navigation_throttle.h"
+#include "content/public/browser/resource_throttle.h"
+
+namespace net {
+class URLRequest;
+}
+
+namespace content {
+
+// This ResourceThrottle is used to convey throttling information to the UI
+// thread during navigations. The UI thread can then use its NavigationThrottle
+// mechanism to interact with the navigation.
+class NavigationResourceThrottle : public ResourceThrottle {
+ public:
+ NavigationResourceThrottle(net::URLRequest* request);
+ ~NavigationResourceThrottle() override;
+
+ // ResourceThrottle overrides:
+ void WillStartRequest(bool* defer) override;
+ void WillRedirectRequest(const net::RedirectInfo& redirect_info,
+ bool* defer) override;
+ const char* GetNameForLogging() const override;
+
+ private:
+ void OnUIChecksPerformed(NavigationThrottle::ThrottleCheckResult result);
+
+ net::URLRequest* request_;
+ base::WeakPtrFactory<NavigationResourceThrottle> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationResourceThrottle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index c5c6796..81cbf8a 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -41,6 +41,7 @@
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/mime_type_resource_handler.h"
#include "content/browser/loader/navigation_resource_handler.h"
+#include "content/browser/loader/navigation_resource_throttle.h"
#include "content/browser/loader/navigation_url_loader_impl_core.h"
#include "content/browser/loader/power_save_block_resource_throttle.h"
#include "content/browser/loader/redirect_to_file_resource_handler.h"
@@ -1481,6 +1482,16 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
plugin_service, request));
ScopedVector<ResourceThrottle> throttles;
+
+ // Add a NavigationResourceThrottle for navigations.
+ // PlzNavigate: the throttle is unnecessary as communication with the UI
+ // thread is handled by the NavigationURLloader.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation) &&
+ IsResourceTypeFrame(resource_type)) {
+ throttles.push_back(new NavigationResourceThrottle(request));
+ }
+
if (delegate_) {
delegate_->RequestBeginning(request,
resource_context,