1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/navigation_interception/intercept_navigation_resource_throttle.h"
7 #include "components/navigation_interception/navigation_params.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/child_process_security_policy.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/resource_controller.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/common/page_transition_types.h"
15 #include "content/public/common/referrer.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_request.h"
19 using content::BrowserThread;
20 using content::ChildProcessSecurityPolicy;
21 using content::PageTransition;
22 using content::Referrer;
23 using content::RenderViewHost;
24 using content::ResourceRequestInfo;
26 namespace navigation_interception {
30 void CheckIfShouldIgnoreNavigationOnUIThread(
31 int render_process_id,
33 const NavigationParams& navigation_params,
34 InterceptNavigationResourceThrottle::CheckOnUIThreadCallback
35 should_ignore_callback,
36 base::Callback<void(bool)> callback) {
38 bool should_ignore_navigation = false;
40 RenderViewHost::FromID(render_process_id, render_view_id);
43 NavigationParams validated_params(navigation_params);
44 RenderViewHost::FilterURL(
45 rvh->GetProcess(), false, &validated_params.url());
47 should_ignore_navigation = should_ignore_callback.Run(rvh,
51 BrowserThread::PostTask(
54 base::Bind(callback, should_ignore_navigation));
59 InterceptNavigationResourceThrottle::InterceptNavigationResourceThrottle(
60 net::URLRequest* request,
61 CheckOnUIThreadCallback should_ignore_callback)
63 should_ignore_callback_(should_ignore_callback),
64 weak_ptr_factory_(this) {
67 InterceptNavigationResourceThrottle::~InterceptNavigationResourceThrottle() {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
71 void InterceptNavigationResourceThrottle::WillStartRequest(bool* defer) {
73 CheckIfShouldIgnoreNavigation(request_->url(), request_->method(), false);
76 void InterceptNavigationResourceThrottle::WillRedirectRequest(
80 CheckIfShouldIgnoreNavigation(new_url, GetMethodAfterRedirect(), true);
83 std::string InterceptNavigationResourceThrottle::GetMethodAfterRedirect() {
84 net::HttpResponseHeaders* headers = request_->response_headers();
86 return request_->method();
87 return net::URLRequest::ComputeMethodForRedirect(
88 request_->method(), headers->response_code());
91 bool InterceptNavigationResourceThrottle::CheckIfShouldIgnoreNavigation(
93 const std::string& method,
95 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
99 int render_process_id, render_view_id;
100 if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id))
103 NavigationParams navigation_params(url,
104 Referrer(GURL(request_->referrer()),
105 info->GetReferrerPolicy()),
106 info->HasUserGesture(),
108 info->GetPageTransition(),
111 BrowserThread::PostTask(
115 &CheckIfShouldIgnoreNavigationOnUIThread,
119 should_ignore_callback_,
121 &InterceptNavigationResourceThrottle::OnResultObtained,
122 weak_ptr_factory_.GetWeakPtr())));
124 // Defer request while we wait for the UI thread to check if the navigation
125 // should be ignored.
129 void InterceptNavigationResourceThrottle::OnResultObtained(
130 bool should_ignore_navigation) {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
133 if (should_ignore_navigation) {
134 controller()->CancelAndIgnore();
136 controller()->Resume();
140 } // namespace navigation_interception