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

Side by Side Diff: components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc

Issue 2691423006: Introduce the ThrottleManager (Closed)
Patch Set: update NavigationSimulator description Created 3 years, 9 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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/subresource_filter/content/browser/content_subresource_filt er_throttle_manager.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ptr_util.h"
10 #include "components/subresource_filter/content/browser/activation_state_computi ng_navigation_throttle.h"
11 #include "components/subresource_filter/content/browser/async_document_subresour ce_filter.h"
12 #include "components/subresource_filter/content/browser/subframe_navigation_filt ering_throttle.h"
13 #include "content/public/browser/navigation_handle.h"
14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "net/base/net_errors.h"
17
18 namespace subresource_filter {
19
20 bool ContentSubresourceFilterThrottleManager::Delegate::
21 ShouldSuppressActivation(content::NavigationHandle* navigation_handle) {
22 return false;
23 }
24
25 ContentSubresourceFilterThrottleManager::
26 ContentSubresourceFilterThrottleManager(
27 Delegate* delegate,
28 VerifiedRulesetDealer::Handle* dealer_handle,
29 content::WebContents* web_contents)
30 : content::WebContentsObserver(web_contents),
31 dealer_handle_(dealer_handle),
32 delegate_(delegate),
33 weak_ptr_factory_(this) {}
34
35 ContentSubresourceFilterThrottleManager::
36 ~ContentSubresourceFilterThrottleManager() {}
37
38 void ContentSubresourceFilterThrottleManager::NotifyPageActivationComputed(
39 content::NavigationHandle* navigation_handle,
40 const ActivationState& activation_state) {
41 DCHECK(navigation_handle->IsInMainFrame());
42 DCHECK(!navigation_handle->HasCommitted());
43 auto it = ongoing_activation_throttles_.find(navigation_handle);
44 if (it != ongoing_activation_throttles_.end()) {
45 it->second->NotifyPageActivationWithRuleset(EnsureRulesetHandle(),
46 activation_state);
47 }
48 }
49
50 void ContentSubresourceFilterThrottleManager::RenderFrameDeleted(
51 content::RenderFrameHost* frame_host) {
52 activated_frame_hosts_.erase(frame_host);
53 DestroyRulesetHandleIfNoLongerUsed();
54 }
55
56 // Pull the AsyncDocumentSubresourceFilter and its associated ActivationState
57 // out of the activation state computing throttle. Store it for later filtering
58 // of subframe navigations.
59 void ContentSubresourceFilterThrottleManager::ReadyToCommitNavigation(
60 content::NavigationHandle* navigation_handle) {
61 auto throttle = ongoing_activation_throttles_.find(navigation_handle);
62 if (throttle == ongoing_activation_throttles_.end())
63 return;
64
65 // Some browser-initiated navigations (like about:blank) do not go through
66 // WillProcessResponse, and won't receive valid filters or activation states.
67 AsyncDocumentSubresourceFilter* filter = throttle->second->filter();
68 if (!filter || navigation_handle->GetNetErrorCode() != net::OK ||
engedy 2017/03/20 18:58:14 nit: Can |filter| really be false for the reason a
Charlie Harrison 2017/03/20 20:02:56 I can't reproduce this now, as NavigationSimulator
69 delegate_->ShouldSuppressActivation(navigation_handle)) {
70 return;
71 }
72
73 DCHECK_NE(ActivationLevel::DISABLED,
74 filter->activation_state().activation_level);
75
76 filter->set_first_disallowed_load_callback(base::Bind(
engedy 2017/03/20 18:58:14 nit: Could we set this later once we have taken ow
Charlie Harrison 2017/03/20 20:02:56 Done.
77 &ContentSubresourceFilterThrottleManager::MaybeCallFirstDisallowedLoad,
78 weak_ptr_factory_.GetWeakPtr()));
79 throttle->second->WillSendActivationToRenderer();
80 // TODO(csharrison): Send an IPC to the renderer.
81 }
82
83 void ContentSubresourceFilterThrottleManager::DidFinishNavigation(
84 content::NavigationHandle* navigation_handle) {
85 // Do nothing if the navigation finished in the same document. Just make sure
86 // to not leak throttle pointers.
87 if (!navigation_handle->HasCommitted() ||
88 navigation_handle->IsSameDocument()) {
89 ongoing_activation_throttles_.erase(navigation_handle);
90 return;
91 }
92
93 auto throttle = ongoing_activation_throttles_.find(navigation_handle);
94 std::unique_ptr<AsyncDocumentSubresourceFilter> filter;
95 if (throttle != ongoing_activation_throttles_.end()) {
96 filter = throttle->second->ReleaseFilter();
97 ongoing_activation_throttles_.erase(throttle);
98 }
99
100 // Make sure |activated_frame_hosts_| is updated or cleaned up depending on
101 // this navigation's activation state.
102 content::RenderFrameHost* frame_host =
103 navigation_handle->GetRenderFrameHost();
104 if (filter) {
105 activated_frame_hosts_[frame_host] = std::move(filter);
106 } else {
107 activated_frame_hosts_.erase(frame_host);
108 }
109
110 if (navigation_handle->IsInMainFrame())
111 current_committed_load_has_notified_disallowed_load_ = false;
112 DestroyRulesetHandleIfNoLongerUsed();
113 }
114
115 void ContentSubresourceFilterThrottleManager::MaybeAppendNavigationThrottles(
116 content::NavigationHandle* navigation_handle,
117 std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) {
118 DCHECK(!navigation_handle->IsSameDocument());
119 if (auto filtering_throttle =
120 MaybeCreateSubframeNavigationFilteringThrottle(navigation_handle)) {
121 throttles->push_back(std::move(filtering_throttle));
122 }
123 if (auto activation_throttle =
124 MaybeCreateActivationStateComputingThrottle(navigation_handle)) {
125 ongoing_activation_throttles_[navigation_handle] =
126 activation_throttle.get();
127 throttles->push_back(std::move(activation_throttle));
128 }
129 }
130
131 std::unique_ptr<SubframeNavigationFilteringThrottle>
132 ContentSubresourceFilterThrottleManager::
133 MaybeCreateSubframeNavigationFilteringThrottle(
134 content::NavigationHandle* navigation_handle) {
135 if (navigation_handle->IsInMainFrame())
136 return nullptr;
137 AsyncDocumentSubresourceFilter* parent_filter =
138 GetParentFrameFilter(navigation_handle);
139 return parent_filter ? base::MakeUnique<SubframeNavigationFilteringThrottle>(
140 navigation_handle, parent_filter)
141 : nullptr;
142 }
143
144 std::unique_ptr<ActivationStateComputingNavigationThrottle>
145 ContentSubresourceFilterThrottleManager::
146 MaybeCreateActivationStateComputingThrottle(
147 content::NavigationHandle* navigation_handle) {
148 // Main frames: create unconditionally.
149 if (navigation_handle->IsInMainFrame()) {
150 return ActivationStateComputingNavigationThrottle::CreateForMainFrame(
151 navigation_handle);
152 }
153
154 // Subframes: create only for frames with activated parents.
155 AsyncDocumentSubresourceFilter* parent_filter =
156 GetParentFrameFilter(navigation_handle);
157 if (!parent_filter)
158 return nullptr;
159 DCHECK(ruleset_handle_);
160 return ActivationStateComputingNavigationThrottle::CreateForSubframe(
161 navigation_handle, ruleset_handle_.get(),
162 parent_filter->activation_state());
163 }
164
165 AsyncDocumentSubresourceFilter*
166 ContentSubresourceFilterThrottleManager::GetParentFrameFilter(
167 content::NavigationHandle* child_frame_navigation) {
168 DCHECK(!child_frame_navigation->IsInMainFrame());
169 content::RenderFrameHost* parent = web_contents()->FindFrameByFrameTreeNodeId(
170 child_frame_navigation->GetParentFrameTreeNodeId());
171 DCHECK(parent);
172 auto it = activated_frame_hosts_.find(parent);
173 return it == activated_frame_hosts_.end() ? nullptr : it->second.get();
174 }
175
176 void ContentSubresourceFilterThrottleManager::MaybeCallFirstDisallowedLoad() {
177 if (current_committed_load_has_notified_disallowed_load_)
178 return;
179 delegate_->OnFirstSubresourceLoadDisallowed();
180 current_committed_load_has_notified_disallowed_load_ = true;
181 }
182
183 VerifiedRuleset::Handle*
184 ContentSubresourceFilterThrottleManager::EnsureRulesetHandle() {
185 if (!ruleset_handle_)
186 ruleset_handle_ = base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_);
187 return ruleset_handle_.get();
188 }
189
190 void ContentSubresourceFilterThrottleManager::
191 DestroyRulesetHandleIfNoLongerUsed() {
192 if (activated_frame_hosts_.size() == 0)
engedy 2017/03/20 18:58:14 Can it happen that |activated_frame_hosts| is empt
Charlie Harrison 2017/03/20 20:02:56 This is pretty tricky. I think we're ok here but I
193 ruleset_handle_.reset();
194 }
195
196 } // namespace subresource_filter
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698