OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "components/navigation_interception/intercept_navigation_resource_throt
tle.h" | |
6 | |
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_context.h" | |
13 #include "content/public/browser/resource_controller.h" | |
14 #include "content/public/browser/resource_request_info.h" | |
15 #include "content/public/browser/web_contents.h" | |
16 #include "content/public/common/referrer.h" | |
17 #include "net/http/http_response_headers.h" | |
18 #include "net/url_request/redirect_info.h" | |
19 #include "net/url_request/url_request_context.h" | |
20 #include "net/url_request/url_request_job_factory.h" | |
21 #include "net/url_request/url_request.h" | |
22 #include "ui/base/page_transition_types.h" | |
23 | |
24 using content::BrowserThread; | |
25 using content::ChildProcessSecurityPolicy; | |
26 using ui::PageTransition; | |
27 using content::Referrer; | |
28 using content::RenderProcessHost; | |
29 using content::ResourceRequestInfo; | |
30 | |
31 namespace navigation_interception { | |
32 | |
33 namespace { | |
34 | |
35 void CheckIfShouldIgnoreNavigationOnUIThread( | |
36 int render_process_id, | |
37 int render_frame_id, | |
38 const NavigationParams& navigation_params, | |
39 InterceptNavigationResourceThrottle::CheckOnUIThreadCallback | |
40 should_ignore_callback, | |
41 base::Callback<void(bool)> callback) { | |
42 bool should_ignore_navigation = false; | |
43 RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id); | |
44 if (rph) { | |
45 NavigationParams validated_params(navigation_params); | |
46 rph->FilterURL(false, &validated_params.url()); | |
47 | |
48 content::RenderFrameHost* render_frame_host = | |
49 content::RenderFrameHost::FromID(render_process_id, render_frame_id); | |
50 content::WebContents* web_contents = | |
51 content::WebContents::FromRenderFrameHost(render_frame_host); | |
52 | |
53 if (web_contents) { | |
54 should_ignore_navigation = should_ignore_callback.Run(web_contents, | |
55 validated_params); | |
56 } | |
57 } | |
58 | |
59 BrowserThread::PostTask( | |
60 BrowserThread::IO, | |
61 FROM_HERE, | |
62 base::Bind(callback, should_ignore_navigation)); | |
63 } | |
64 | |
65 } // namespace | |
66 | |
67 InterceptNavigationResourceThrottle::InterceptNavigationResourceThrottle( | |
68 net::URLRequest* request, | |
69 CheckOnUIThreadCallback should_ignore_callback) | |
70 : request_(request), | |
71 should_ignore_callback_(should_ignore_callback), | |
72 weak_ptr_factory_(this) { | |
73 } | |
74 | |
75 InterceptNavigationResourceThrottle::~InterceptNavigationResourceThrottle() { | |
76 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
77 } | |
78 | |
79 void InterceptNavigationResourceThrottle::WillStartRequest(bool* defer) { | |
80 *defer = | |
81 CheckIfShouldIgnoreNavigation(request_->url(), request_->method(), false); | |
82 } | |
83 | |
84 void InterceptNavigationResourceThrottle::WillRedirectRequest( | |
85 const net::RedirectInfo& redirect_info, | |
86 bool* defer) { | |
87 *defer = CheckIfShouldIgnoreNavigation(redirect_info.new_url, | |
88 redirect_info.new_method, true); | |
89 } | |
90 | |
91 const char* InterceptNavigationResourceThrottle::GetNameForLogging() const { | |
92 return "InterceptNavigationResourceThrottle"; | |
93 } | |
94 | |
95 bool InterceptNavigationResourceThrottle::CheckIfShouldIgnoreNavigation( | |
96 const GURL& url, | |
97 const std::string& method, | |
98 bool is_redirect) { | |
99 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); | |
100 if (!info) | |
101 return false; | |
102 | |
103 int render_process_id, render_frame_id; | |
104 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) | |
105 return false; | |
106 | |
107 bool is_external_protocol = | |
108 !info->GetContext()->GetRequestContext()->job_factory()->IsHandledURL( | |
109 url); | |
110 NavigationParams navigation_params( | |
111 url, | |
112 Referrer::SanitizeForRequest( | |
113 url, Referrer(GURL(request_->referrer()), info->GetReferrerPolicy())), | |
114 info->HasUserGesture(), method == "POST", info->GetPageTransition(), | |
115 is_redirect, is_external_protocol, true); | |
116 | |
117 BrowserThread::PostTask( | |
118 BrowserThread::UI, | |
119 FROM_HERE, | |
120 base::Bind( | |
121 &CheckIfShouldIgnoreNavigationOnUIThread, | |
122 render_process_id, | |
123 render_frame_id, | |
124 navigation_params, | |
125 should_ignore_callback_, | |
126 base::Bind( | |
127 &InterceptNavigationResourceThrottle::OnResultObtained, | |
128 weak_ptr_factory_.GetWeakPtr()))); | |
129 | |
130 // Defer request while we wait for the UI thread to check if the navigation | |
131 // should be ignored. | |
132 return true; | |
133 } | |
134 | |
135 void InterceptNavigationResourceThrottle::OnResultObtained( | |
136 bool should_ignore_navigation) { | |
137 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
138 | |
139 if (should_ignore_navigation) { | |
140 controller()->CancelAndIgnore(); | |
141 } else { | |
142 controller()->Resume(); | |
143 } | |
144 } | |
145 | |
146 } // namespace navigation_interception | |
OLD | NEW |