diff options
Diffstat (limited to '')
-rw-r--r-- | dom/ipc/URLClassifierParent.cpp | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/dom/ipc/URLClassifierParent.cpp b/dom/ipc/URLClassifierParent.cpp new file mode 100644 index 0000000000..d0d2f8f26e --- /dev/null +++ b/dom/ipc/URLClassifierParent.cpp @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "URLClassifierParent.h" +#include "nsComponentManagerUtils.h" +#include "nsIUrlClassifierFeature.h" +#include "nsNetCID.h" +#include "mozilla/net/UrlClassifierFeatureResult.h" +#include "mozilla/Unused.h" + +using namespace mozilla; +using namespace mozilla::dom; + +///////////////////////////////////////////////////////////////////// +// URLClassifierParent. + +NS_IMPL_ISUPPORTS(URLClassifierParent, nsIURIClassifierCallback) + +mozilla::ipc::IPCResult URLClassifierParent::StartClassify( + nsIPrincipal* aPrincipal, bool* aSuccess) { + *aSuccess = false; + nsresult rv = NS_OK; + // Note that in safe mode, the URL classifier service isn't available, so we + // should handle the service not being present gracefully. + nsCOMPtr<nsIURIClassifier> uriClassifier = + do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = uriClassifier->Classify(aPrincipal, this, aSuccess); + } + if (NS_FAILED(rv) || !*aSuccess) { + // We treat the case where we fail to classify and the case where the + // classifier returns successfully but doesn't perform a lookup as the + // classification not yielding any results, so we just kill the child actor + // without ever calling out callback in both cases. + // This means that code using this in the child process will only get a hit + // on its callback if some classification actually happens. + *aSuccess = false; + ClassificationFailed(); + } + return IPC_OK(); +} + +///////////////////////////////////////////////////////////////////// +// URLClassifierLocalParent. + +namespace { + +// This class implements a nsIUrlClassifierFeature on the parent side, starting +// from an IPC data struct. +class IPCFeature final : public nsIUrlClassifierFeature { + public: + NS_DECL_ISUPPORTS + + IPCFeature(nsIURI* aURI, const IPCURLClassifierFeature& aFeature) + : mURI(aURI), mIPCFeature(aFeature) {} + + NS_IMETHOD + GetName(nsACString& aName) override { + aName = mIPCFeature.featureName(); + return NS_OK; + } + + NS_IMETHOD + GetTables(nsIUrlClassifierFeature::listType, + nsTArray<nsCString>& aTables) override { + aTables.AppendElements(mIPCFeature.tables()); + return NS_OK; + } + + NS_IMETHOD + HasTable(const nsACString& aTable, nsIUrlClassifierFeature::listType, + bool* aResult) override { + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mIPCFeature.tables().Contains(aTable); + return NS_OK; + } + + NS_IMETHOD + HasHostInPreferences(const nsACString& aHost, + nsIUrlClassifierFeature::listType, + nsACString& aTableName, bool* aResult) override { + NS_ENSURE_ARG_POINTER(aResult); + *aResult = false; + return NS_OK; + } + + NS_IMETHOD + GetExceptionHostList(nsACString& aList) override { + aList = mIPCFeature.exceptionHostList(); + return NS_OK; + } + + NS_IMETHOD + ProcessChannel(nsIChannel* aChannel, const nsTArray<nsCString>& aList, + const nsTArray<nsCString>& aHashes, + bool* aShouldContinue) override { + NS_ENSURE_ARG_POINTER(aShouldContinue); + *aShouldContinue = true; + + // Nothing to do here. + return NS_OK; + } + + NS_IMETHOD + GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIUrlClassifierFeature::URIType* aURIType, + nsIURI** aURI) override { + NS_ENSURE_ARG_POINTER(aURI); + + // This method should not be called, but we have a URI, let's return it. + nsCOMPtr<nsIURI> uri = mURI; + uri.forget(aURI); + *aURIType = aListType == nsIUrlClassifierFeature::blocklist + ? nsIUrlClassifierFeature::URIType::blocklistURI + : nsIUrlClassifierFeature::URIType::entitylistURI; + return NS_OK; + } + + private: + ~IPCFeature() = default; + + nsCOMPtr<nsIURI> mURI; + IPCURLClassifierFeature mIPCFeature; +}; + +NS_IMPL_ISUPPORTS(IPCFeature, nsIUrlClassifierFeature) + +} // namespace + +NS_IMPL_ISUPPORTS(URLClassifierLocalParent, nsIUrlClassifierFeatureCallback) + +mozilla::ipc::IPCResult URLClassifierLocalParent::StartClassify( + nsIURI* aURI, const nsTArray<IPCURLClassifierFeature>& aFeatures) { + MOZ_ASSERT(aURI); + + nsresult rv = NS_OK; + // Note that in safe mode, the URL classifier service isn't available, so we + // should handle the service not being present gracefully. + nsCOMPtr<nsIURIClassifier> uriClassifier = + do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + OnClassifyComplete(nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>()); + return IPC_OK(); + } + + nsTArray<RefPtr<nsIUrlClassifierFeature>> features; + for (const IPCURLClassifierFeature& feature : aFeatures) { + features.AppendElement(new IPCFeature(aURI, feature)); + } + + // Doesn't matter if we pass blocklist, entitylist or any other list. + // IPCFeature returns always the same values. + rv = uriClassifier->AsyncClassifyLocalWithFeatures( + aURI, features, nsIUrlClassifierFeature::blocklist, this); + if (NS_WARN_IF(NS_FAILED(rv))) { + OnClassifyComplete(nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>()); + return IPC_OK(); + } + + return IPC_OK(); +} + +NS_IMETHODIMP +URLClassifierLocalParent::OnClassifyComplete( + const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults) { + if (mIPCOpen) { + nsTArray<URLClassifierLocalResult> ipcResults; + for (nsIUrlClassifierFeatureResult* result : aResults) { + URLClassifierLocalResult* ipcResult = ipcResults.AppendElement(); + + net::UrlClassifierFeatureResult* r = + static_cast<net::UrlClassifierFeatureResult*>(result); + + ipcResult->uri() = r->URI(); + r->Feature()->GetName(ipcResult->featureName()); + ipcResult->matchingList() = r->List(); + } + + Unused << Send__delete__(this, ipcResults); + } + return NS_OK; +} |