/* -*- 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 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& 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& aList, const nsTArray& 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 uri = mURI; uri.forget(aURI); *aURIType = aListType == nsIUrlClassifierFeature::blocklist ? nsIUrlClassifierFeature::URIType::blocklistURI : nsIUrlClassifierFeature::URIType::entitylistURI; return NS_OK; } private: ~IPCFeature() = default; nsCOMPtr mURI; IPCURLClassifierFeature mIPCFeature; }; NS_IMPL_ISUPPORTS(IPCFeature, nsIUrlClassifierFeature) } // namespace NS_IMPL_ISUPPORTS(URLClassifierLocalParent, nsIUrlClassifierFeatureCallback) mozilla::ipc::IPCResult URLClassifierLocalParent::StartClassify( nsIURI* aURI, const nsTArray& 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 uriClassifier = do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { OnClassifyComplete(nsTArray>()); return IPC_OK(); } nsTArray> 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>()); return IPC_OK(); } return IPC_OK(); } NS_IMETHODIMP URLClassifierLocalParent::OnClassifyComplete( const nsTArray>& aResults) { if (mIPCOpen) { nsTArray ipcResults; for (nsIUrlClassifierFeatureResult* result : aResults) { URLClassifierLocalResult* ipcResult = ipcResults.AppendElement(); net::UrlClassifierFeatureResult* r = static_cast(result); ipcResult->uri() = r->URI(); r->Feature()->GetName(ipcResult->featureName()); ipcResult->matchingList() = r->List(); } Unused << Send__delete__(this, ipcResults); } return NS_OK; }