URLClassifierParent.cpp (8107B)
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/. */ 6 7 #include "URLClassifierParent.h" 8 9 #include "mozilla/net/UrlClassifierFeatureResult.h" 10 #include "nsComponentManagerUtils.h" 11 #include "nsIUrlClassifierFeature.h" 12 #include "nsNetCID.h" 13 14 using namespace mozilla; 15 using namespace mozilla::dom; 16 17 class nsIUrlClassifierExceptionList; 18 19 ///////////////////////////////////////////////////////////////////// 20 // URLClassifierParent. 21 22 NS_IMPL_ISUPPORTS(URLClassifierParent, nsIURIClassifierCallback) 23 24 mozilla::ipc::IPCResult URLClassifierParent::StartClassify( 25 nsIPrincipal* aPrincipal, bool* aSuccess) { 26 *aSuccess = false; 27 nsresult rv = NS_OK; 28 // Note that in safe mode, the URL classifier service isn't available, so we 29 // should handle the service not being present gracefully. 30 nsCOMPtr<nsIURIClassifier> uriClassifier = 31 do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); 32 if (NS_SUCCEEDED(rv)) { 33 rv = uriClassifier->Classify(aPrincipal, this, aSuccess); 34 } 35 if (NS_FAILED(rv) || !*aSuccess) { 36 // We treat the case where we fail to classify and the case where the 37 // classifier returns successfully but doesn't perform a lookup as the 38 // classification not yielding any results, so we just kill the child actor 39 // without ever calling out callback in both cases. 40 // This means that code using this in the child process will only get a hit 41 // on its callback if some classification actually happens. 42 *aSuccess = false; 43 ClassificationFailed(); 44 } 45 return IPC_OK(); 46 } 47 48 ///////////////////////////////////////////////////////////////////// 49 // URLClassifierLocalParent. 50 51 namespace { 52 53 // This class implements a nsIUrlClassifierFeature on the parent side, starting 54 // from an IPC data struct. 55 class IPCFeature final : public nsIUrlClassifierFeature { 56 public: 57 NS_DECL_ISUPPORTS 58 59 IPCFeature(nsIURI* aURI, const IPCURLClassifierFeature& aFeature) 60 : mURI(aURI), mIPCFeature(aFeature) {} 61 62 NS_IMETHOD 63 GetName(nsACString& aName) override { 64 aName = mIPCFeature.featureName(); 65 return NS_OK; 66 } 67 68 NS_IMETHOD 69 GetTables(nsIUrlClassifierFeature::listType, 70 nsTArray<nsCString>& aTables) override { 71 aTables.AppendElements(mIPCFeature.tables()); 72 return NS_OK; 73 } 74 75 NS_IMETHOD 76 HasTable(const nsACString& aTable, nsIUrlClassifierFeature::listType, 77 bool* aResult) override { 78 NS_ENSURE_ARG_POINTER(aResult); 79 *aResult = mIPCFeature.tables().Contains(aTable); 80 return NS_OK; 81 } 82 83 NS_IMETHOD 84 HasHostInPreferences(const nsACString& aHost, 85 nsIUrlClassifierFeature::listType, 86 nsACString& aTableName, bool* aResult) override { 87 NS_ENSURE_ARG_POINTER(aResult); 88 *aResult = false; 89 return NS_OK; 90 } 91 92 NS_IMETHOD 93 GetExceptionList(nsIUrlClassifierExceptionList** aList) override { 94 return NS_OK; 95 } 96 97 NS_IMETHOD 98 ProcessChannel(nsIChannel* aChannel, const nsTArray<nsCString>& aList, 99 const nsTArray<nsCString>& aHashes, 100 bool* aShouldContinue) override { 101 NS_ENSURE_ARG_POINTER(aShouldContinue); 102 *aShouldContinue = true; 103 104 // Nothing to do here. 105 return NS_OK; 106 } 107 108 NS_IMETHOD 109 GetURIByListType(nsIChannel* aChannel, 110 nsIUrlClassifierFeature::listType aListType, 111 nsIUrlClassifierFeature::URIType* aURIType, 112 nsIURI** aURI) override { 113 NS_ENSURE_ARG_POINTER(aURI); 114 115 // This method should not be called, but we have a URI, let's return it. 116 nsCOMPtr<nsIURI> uri = mURI; 117 uri.forget(aURI); 118 *aURIType = aListType == nsIUrlClassifierFeature::blocklist 119 ? nsIUrlClassifierFeature::URIType::blocklistURI 120 : nsIUrlClassifierFeature::URIType::entitylistURI; 121 return NS_OK; 122 } 123 124 private: 125 ~IPCFeature() = default; 126 127 nsCOMPtr<nsIURI> mURI; 128 IPCURLClassifierFeature mIPCFeature; 129 }; 130 131 NS_IMPL_ISUPPORTS(IPCFeature, nsIUrlClassifierFeature) 132 133 } // namespace 134 135 NS_IMPL_ISUPPORTS(URLClassifierLocalParent, nsIUrlClassifierFeatureCallback) 136 137 mozilla::ipc::IPCResult URLClassifierLocalParent::StartClassify( 138 nsIURI* aURI, const nsTArray<IPCURLClassifierFeature>& aFeatures) { 139 MOZ_ASSERT(aURI); 140 141 nsresult rv = NS_OK; 142 // Note that in safe mode, the URL classifier service isn't available, so we 143 // should handle the service not being present gracefully. 144 nsCOMPtr<nsIURIClassifier> uriClassifier = 145 do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); 146 if (NS_WARN_IF(NS_FAILED(rv))) { 147 OnClassifyComplete(nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>()); 148 return IPC_OK(); 149 } 150 151 nsTArray<RefPtr<nsIUrlClassifierFeature>> features; 152 for (const IPCURLClassifierFeature& feature : aFeatures) { 153 features.AppendElement(new IPCFeature(aURI, feature)); 154 } 155 156 // Doesn't matter if we pass blocklist, entitylist or any other list. 157 // IPCFeature returns always the same values. 158 rv = uriClassifier->AsyncClassifyLocalWithFeatures( 159 aURI, features, nsIUrlClassifierFeature::blocklist, this, false); 160 if (NS_WARN_IF(NS_FAILED(rv))) { 161 OnClassifyComplete(nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>()); 162 return IPC_OK(); 163 } 164 165 return IPC_OK(); 166 } 167 168 NS_IMETHODIMP 169 URLClassifierLocalParent::OnClassifyComplete( 170 const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults) { 171 if (mIPCOpen) { 172 nsTArray<URLClassifierLocalResult> ipcResults; 173 for (nsIUrlClassifierFeatureResult* result : aResults) { 174 URLClassifierLocalResult* ipcResult = ipcResults.AppendElement(); 175 176 net::UrlClassifierFeatureResult* r = 177 static_cast<net::UrlClassifierFeatureResult*>(result); 178 179 ipcResult->uri() = r->URI(); 180 r->Feature()->GetName(ipcResult->featureName()); 181 ipcResult->matchingList() = r->List(); 182 } 183 184 (void)Send__delete__(this, ipcResults); 185 } 186 return NS_OK; 187 } 188 189 NS_IMPL_ISUPPORTS(URLClassifierLocalByNameParent, 190 nsIUrlClassifierFeatureCallback) 191 192 mozilla::ipc::IPCResult URLClassifierLocalByNameParent::StartClassify( 193 nsIURI* aURI, const nsTArray<IPCURLClassifierFeature>& aFeatures, 194 nsIUrlClassifierFeature::listType aListType) { 195 MOZ_ASSERT(aURI); 196 197 nsresult rv = NS_OK; 198 // Note that in safe mode, the URL classifier service isn't available, so we 199 // should handle the service not being present gracefully. 200 nsCOMPtr<nsIURIClassifier> uriClassifier = 201 do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); 202 if (NS_WARN_IF(NS_FAILED(rv))) { 203 OnClassifyComplete(nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>()); 204 return IPC_OK(); 205 } 206 207 nsTArray<RefPtr<nsIUrlClassifierFeature>> features; 208 for (const IPCURLClassifierFeature& feature : aFeatures) { 209 features.AppendElement(new IPCFeature(aURI, feature)); 210 } 211 212 // Doesn't matter if we pass blocklist, entitylist or any other list. 213 // IPCFeature returns always the same values. 214 rv = uriClassifier->AsyncClassifyLocalWithFeatures(aURI, features, aListType, 215 this, false); 216 if (NS_WARN_IF(NS_FAILED(rv))) { 217 OnClassifyComplete(nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>()); 218 return IPC_OK(); 219 } 220 221 return IPC_OK(); 222 } 223 224 NS_IMETHODIMP 225 URLClassifierLocalByNameParent::OnClassifyComplete( 226 const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults) { 227 if (mIPCOpen) { 228 nsTArray<URLClassifierLocalResult> ipcResults; 229 for (nsIUrlClassifierFeatureResult* result : aResults) { 230 URLClassifierLocalResult* ipcResult = ipcResults.AppendElement(); 231 232 net::UrlClassifierFeatureResult* r = 233 static_cast<net::UrlClassifierFeatureResult*>(result); 234 235 ipcResult->uri() = r->URI(); 236 r->Feature()->GetName(ipcResult->featureName()); 237 ipcResult->matchingList() = r->List(); 238 } 239 240 (void)Send__delete__(this, ipcResults); 241 } 242 return NS_OK; 243 }