Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / components / navigation_interception / intercept_navigation_resource_throttle.cc
blob8729d2ceeb9d86aef105ba26779071276d2fa358
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_frame_host.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/resource_controller.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/page_transition_types.h"
16 #include "content/public/common/referrer.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request.h"
20 using content::BrowserThread;
21 using content::ChildProcessSecurityPolicy;
22 using content::PageTransition;
23 using content::Referrer;
24 using content::RenderProcessHost;
25 using content::ResourceRequestInfo;
27 namespace navigation_interception {
29 namespace {
31 void CheckIfShouldIgnoreNavigationOnUIThread(
32 int render_process_id,
33 int render_frame_id,
34 const NavigationParams& navigation_params,
35 InterceptNavigationResourceThrottle::CheckOnUIThreadCallback
36 should_ignore_callback,
37 base::Callback<void(bool)> callback) {
38 bool should_ignore_navigation = false;
39 RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
40 if (rph) {
41 NavigationParams validated_params(navigation_params);
42 rph->FilterURL(false, &validated_params.url());
44 content::RenderFrameHost* render_frame_host =
45 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
46 content::WebContents* web_contents =
47 content::WebContents::FromRenderFrameHost(render_frame_host);
49 if (web_contents) {
50 should_ignore_navigation = should_ignore_callback.Run(web_contents,
51 validated_params);
55 BrowserThread::PostTask(
56 BrowserThread::IO,
57 FROM_HERE,
58 base::Bind(callback, should_ignore_navigation));
61 } // namespace
63 InterceptNavigationResourceThrottle::InterceptNavigationResourceThrottle(
64 net::URLRequest* request,
65 CheckOnUIThreadCallback should_ignore_callback)
66 : request_(request),
67 should_ignore_callback_(should_ignore_callback),
68 weak_ptr_factory_(this) {
71 InterceptNavigationResourceThrottle::~InterceptNavigationResourceThrottle() {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
75 void InterceptNavigationResourceThrottle::WillStartRequest(bool* defer) {
76 *defer =
77 CheckIfShouldIgnoreNavigation(request_->url(), request_->method(), false);
80 void InterceptNavigationResourceThrottle::WillRedirectRequest(
81 const GURL& new_url,
82 bool* defer) {
83 *defer =
84 CheckIfShouldIgnoreNavigation(new_url, GetMethodAfterRedirect(), true);
87 const char* InterceptNavigationResourceThrottle::GetNameForLogging() const {
88 return "InterceptNavigationResourceThrottle";
91 std::string InterceptNavigationResourceThrottle::GetMethodAfterRedirect() {
92 net::HttpResponseHeaders* headers = request_->response_headers();
93 if (!headers)
94 return request_->method();
95 // TODO(davidben): Plumb net::RedirectInfo through content::ResourceThrottle
96 // and unexpose net::URLRequest::ComputeMethodForRedirect.
97 return net::URLRequest::ComputeMethodForRedirect(
98 request_->method(), headers->response_code());
101 bool InterceptNavigationResourceThrottle::CheckIfShouldIgnoreNavigation(
102 const GURL& url,
103 const std::string& method,
104 bool is_redirect) {
105 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
106 if (!info)
107 return false;
109 int render_process_id, render_frame_id;
110 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
111 return false;
113 NavigationParams navigation_params(url,
114 Referrer(GURL(request_->referrer()),
115 info->GetReferrerPolicy()),
116 info->HasUserGesture(),
117 method == "POST",
118 info->GetPageTransition(),
119 is_redirect);
121 BrowserThread::PostTask(
122 BrowserThread::UI,
123 FROM_HERE,
124 base::Bind(
125 &CheckIfShouldIgnoreNavigationOnUIThread,
126 render_process_id,
127 render_frame_id,
128 navigation_params,
129 should_ignore_callback_,
130 base::Bind(
131 &InterceptNavigationResourceThrottle::OnResultObtained,
132 weak_ptr_factory_.GetWeakPtr())));
134 // Defer request while we wait for the UI thread to check if the navigation
135 // should be ignored.
136 return true;
139 void InterceptNavigationResourceThrottle::OnResultObtained(
140 bool should_ignore_navigation) {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143 if (should_ignore_navigation) {
144 controller()->CancelAndIgnore();
145 } else {
146 controller()->Resume();
150 } // namespace navigation_interception