Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / netwerk / url-classifier / ChannelClassifierService.cpp
blob4b1145ba00f1c19a694da0b0e47447246ed46a8a
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ChannelClassifierService.h"
9 #include "mozilla/ClearOnShutdown.h"
10 #include "mozilla/dom/BrowserParent.h"
11 #include "mozilla/dom/BrowsingContext.h"
12 #include "mozilla/dom/CanonicalBrowsingContext.h"
13 #include "mozilla/dom/WindowGlobalParent.h"
14 #include "mozilla/net/UrlClassifierCommon.h"
16 #include "UrlClassifierFeatureCryptominingProtection.h"
17 #include "UrlClassifierFeatureFingerprintingProtection.h"
18 #include "UrlClassifierFeatureSocialTrackingProtection.h"
19 #include "UrlClassifierFeatureTrackingProtection.h"
21 #include "mozilla/StaticPtr.h"
22 #include "nsIChannel.h"
24 namespace mozilla {
25 namespace net {
27 static StaticRefPtr<ChannelClassifierService> gChannelClassifierService;
29 NS_IMPL_ISUPPORTS(UrlClassifierBlockedChannel, nsIUrlClassifierBlockedChannel)
31 UrlClassifierBlockedChannel::UrlClassifierBlockedChannel(nsIChannel* aChannel)
32 : mChannel(aChannel),
33 mDecision(ChannelBlockDecision::Blocked),
34 mReason(TRACKING_PROTECTION) {
35 MOZ_ASSERT(aChannel);
38 NS_IMETHODIMP
39 UrlClassifierBlockedChannel::GetReason(uint8_t* aReason) {
40 NS_ENSURE_ARG_POINTER(aReason);
42 *aReason = mReason;
43 return NS_OK;
46 NS_IMETHODIMP
47 UrlClassifierBlockedChannel::GetUrl(nsAString& aUrl) {
48 nsCOMPtr<nsIURI> uri;
49 mChannel->GetURI(getter_AddRefs(uri));
50 if (uri) {
51 CopyUTF8toUTF16(uri->GetSpecOrDefault(), aUrl);
53 return NS_OK;
56 NS_IMETHODIMP
57 UrlClassifierBlockedChannel::GetTabId(uint64_t* aTabId) {
58 NS_ENSURE_ARG_POINTER(aTabId);
60 *aTabId = 0;
62 nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
63 MOZ_ASSERT(loadInfo);
65 RefPtr<dom::BrowsingContext> browsingContext;
66 nsresult rv =
67 loadInfo->GetTargetBrowsingContext(getter_AddRefs(browsingContext));
68 if (NS_WARN_IF(NS_FAILED(rv)) || !browsingContext) {
69 return NS_ERROR_FAILURE;
72 // Get top-level browsing context to ensure window global parent is ready
73 // to use, tabId is the same anyway.
74 dom::CanonicalBrowsingContext* top = browsingContext->Canonical()->Top();
75 dom::WindowGlobalParent* wgp = top->GetCurrentWindowGlobal();
76 if (!wgp) {
77 return NS_ERROR_FAILURE;
80 RefPtr<dom::BrowserParent> browserParent = wgp->GetBrowserParent();
81 if (!browserParent) {
82 return NS_ERROR_FAILURE;
85 *aTabId = browserParent->GetTabId();
86 return NS_OK;
89 NS_IMETHODIMP
90 UrlClassifierBlockedChannel::GetChannelId(uint64_t* aChannelId) {
91 NS_ENSURE_ARG_POINTER(aChannelId);
93 nsCOMPtr<nsIIdentChannel> channel(do_QueryInterface(mChannel));
94 *aChannelId = channel ? channel->ChannelId() : 0;
96 return NS_OK;
99 NS_IMETHODIMP
100 UrlClassifierBlockedChannel::GetTopLevelUrl(nsAString& aTopLevelUrl) {
101 nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
102 MOZ_ASSERT(loadInfo);
104 RefPtr<dom::BrowsingContext> browsingContext;
105 nsresult rv =
106 loadInfo->GetTargetBrowsingContext(getter_AddRefs(browsingContext));
107 if (NS_WARN_IF(NS_FAILED(rv)) || !browsingContext) {
108 return NS_ERROR_FAILURE;
111 // Get top-level browsing context to ensure window global parent is ready
112 // to use, tabId is the same anyway.
113 dom::CanonicalBrowsingContext* top = browsingContext->Canonical()->Top();
114 dom::WindowGlobalParent* wgp = top->GetCurrentWindowGlobal();
115 if (!wgp) {
116 return NS_ERROR_FAILURE;
119 RefPtr<nsIURI> uri = wgp->GetDocumentURI();
120 if (!uri) {
121 return NS_ERROR_FAILURE;
124 CopyUTF8toUTF16(uri->GetSpecOrDefault(), aTopLevelUrl);
125 return NS_OK;
128 NS_IMETHODIMP
129 UrlClassifierBlockedChannel::GetTables(nsACString& aTables) {
130 aTables.Assign(mTables);
131 return NS_OK;
134 NS_IMETHODIMP
135 UrlClassifierBlockedChannel::GetIsPrivateBrowsing(bool* aIsPrivateBrowsing) {
136 NS_ENSURE_ARG_POINTER(aIsPrivateBrowsing);
138 *aIsPrivateBrowsing = NS_UsePrivateBrowsing(mChannel);
139 return NS_OK;
142 NS_IMETHODIMP
143 UrlClassifierBlockedChannel::Allow() {
144 UC_LOG(("ChannelClassifierService: allow loading the channel %p",
145 mChannel.get()));
147 mDecision = ChannelBlockDecision::Allowed;
148 return NS_OK;
151 NS_IMETHODIMP
152 UrlClassifierBlockedChannel::Replace() {
153 UC_LOG(("ChannelClassifierService: replace channel %p", mChannel.get()));
155 mDecision = ChannelBlockDecision::Replaced;
156 return NS_OK;
159 void UrlClassifierBlockedChannel::SetReason(const nsACString& aFeatureName,
160 const nsACString& aTableName) {
161 mTables = aTableName;
163 nsCOMPtr<nsIUrlClassifierFeature> feature;
164 feature =
165 UrlClassifierFeatureTrackingProtection::GetIfNameMatches(aFeatureName);
166 if (feature) {
167 mReason = TRACKING_PROTECTION;
168 return;
171 feature = UrlClassifierFeatureSocialTrackingProtection::GetIfNameMatches(
172 aFeatureName);
173 if (feature) {
174 mReason = SOCIAL_TRACKING_PROTECTION;
175 return;
178 feature = UrlClassifierFeatureFingerprintingProtection::GetIfNameMatches(
179 aFeatureName);
180 if (feature) {
181 mReason = FINGERPRINTING_PROTECTION;
182 return;
185 feature = UrlClassifierFeatureCryptominingProtection::GetIfNameMatches(
186 aFeatureName);
187 if (feature) {
188 mReason = CRYPTOMINING_PROTECTION;
189 return;
193 NS_IMPL_ISUPPORTS(ChannelClassifierService, nsIChannelClassifierService)
195 // static
196 already_AddRefed<nsIChannelClassifierService>
197 ChannelClassifierService::GetSingleton() {
198 if (gChannelClassifierService) {
199 return do_AddRef(gChannelClassifierService);
202 gChannelClassifierService = new ChannelClassifierService();
203 ClearOnShutdown(&gChannelClassifierService);
204 return do_AddRef(gChannelClassifierService);
207 ChannelClassifierService::ChannelClassifierService() { mListeners.Clear(); }
209 NS_IMETHODIMP
210 ChannelClassifierService::AddListener(nsIObserver* aObserver) {
211 MOZ_ASSERT(aObserver);
212 MOZ_ASSERT(!mListeners.Contains(aObserver));
214 mListeners.AppendElement(aObserver);
215 return NS_OK;
218 NS_IMETHODIMP
219 ChannelClassifierService::RemoveListener(nsIObserver* aObserver) {
220 MOZ_ASSERT(aObserver);
221 MOZ_ASSERT(mListeners.Contains(aObserver));
223 mListeners.RemoveElement(aObserver);
224 return NS_OK;
227 /* static */
228 ChannelBlockDecision ChannelClassifierService::OnBeforeBlockChannel(
229 nsIChannel* aChannel, const nsACString& aFeatureName,
230 const nsACString& aTableName) {
231 MOZ_ASSERT(aChannel);
233 // Don't bother continuing if no one has ever registered listener
234 if (!gChannelClassifierService || !gChannelClassifierService->HasListener()) {
235 return ChannelBlockDecision::Blocked;
238 ChannelBlockDecision decision;
239 nsresult rv = gChannelClassifierService->OnBeforeBlockChannel(
240 aChannel, aFeatureName, aTableName, decision);
241 if (NS_WARN_IF(NS_FAILED(rv))) {
242 return ChannelBlockDecision::Blocked;
245 return decision;
248 nsresult ChannelClassifierService::OnBeforeBlockChannel(
249 nsIChannel* aChannel, const nsACString& aFeatureName,
250 const nsACString& aTableName, ChannelBlockDecision& aDecision) {
251 MOZ_ASSERT(aChannel);
253 aDecision = ChannelBlockDecision::Blocked;
255 RefPtr<UrlClassifierBlockedChannel> channel =
256 new UrlClassifierBlockedChannel(aChannel);
257 channel->SetReason(aFeatureName, aTableName);
259 for (const auto& listener : mListeners) {
260 listener->Observe(
261 NS_ISUPPORTS_CAST(nsIUrlClassifierBlockedChannel*, channel),
262 "urlclassifier-before-block-channel", nullptr);
264 aDecision = channel->GetDecision();
267 return NS_OK;
270 } // namespace net
271 } // namespace mozilla