--- a/dom/webidl/ChannelWrapper.webidl
+++ b/dom/webidl/ChannelWrapper.webidl
@@ -1,14 +1,15 @@
/* 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/. */
interface LoadInfo;
interface MozChannel;
+interface TabParent;
interface URI;
interface nsISupports;
/**
* Load types that correspond to the external types in nsIContentPolicy.idl.
* Please also update that IDL when updating this list.
*/
enum MozContentPolicyType {
@@ -128,16 +129,22 @@ interface ChannelWrapper : EventTarget {
* Returns true if the request matches the given request filter, and the
* given extension has permission to access it.
*/
boolean matches(optional MozRequestFilter filter,
optional WebExtensionPolicy? extension = null);
/**
+ * Register's this channel as traceable by the given add-on when accessed
+ * via the process of the given TabParent.
+ */
+ void registerTraceableChannel(WebExtensionPolicy extension, TabParent? tabParent);
+
+ /**
* The current HTTP status code of the request. This will be 0 if a response
* has not yet been received, or if the request is not an HTTP request.
*/
[Cached, Pure]
readonly attribute unsigned long statusCode;
/**
* The HTTP status line for the request (e.g., "HTTP/1.0 200 Success"). This
--- a/toolkit/components/build/nsToolkitCompsCID.h
+++ b/toolkit/components/build/nsToolkitCompsCID.h
@@ -87,19 +87,16 @@
#endif
#define NS_ADDONCONTENTPOLICY_CONTRACTID \
"@mozilla.org/addons/content-policy;1"
#define NS_ADDONPATHSERVICE_CONTRACTID \
"@mozilla.org/addon-path-service;1"
-#define NS_WEBREQUESTSERVICE_CONTRACTID \
- "@mozilla.org/addons/webrequest-service;1"
-
/////////////////////////////////////////////////////////////////////////////
#define ALERT_NOTIFICATION_CID \
{ 0x9a7b7a41, 0x0b47, 0x47f7, { 0xb6, 0x1b, 0x15, 0xa2, 0x10, 0xd6, 0xf0, 0x20 } }
// {A0CCAAF8-09DA-44D8-B250-9AC3E93C8117}
#define NS_ALERTSSERVICE_CID \
{ 0xa0ccaaf8, 0x9da, 0x44d8, { 0xb2, 0x50, 0x9a, 0xc3, 0xe9, 0x3c, 0x81, 0x17 } }
@@ -190,12 +187,8 @@
#define NS_ADDON_PATH_SERVICE_CID \
{ 0xa39f39d0, 0xdfb6, 0x11e3, { 0x8b, 0x68, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
#define NS_ADDON_POLICY_SERVICE_CID \
{ 0x562de129, 0x8338, 0x482c, { 0xbb, 0x96, 0xa1, 0xff, 0x09, 0xee, 0x53, 0xcc } }
#define NS_ADDON_POLICY_SERVICE_CONTRACTID \
"@mozilla.org/addons/policy-service;1"
-
-// {5dd0c968-d74d-42c3-b930-36145f885c3b}
-#define NS_WEBREQUEST_SERVICE_CID \
-{ 0x5dd0c968, 0xd74d, 0x42c3, { 0xb9, 0x30, 0x36, 0x14, 0x5f, 0x88, 0x5c, 0x3b } }
--- a/toolkit/components/build/nsToolkitCompsModule.cpp
+++ b/toolkit/components/build/nsToolkitCompsModule.cpp
@@ -33,17 +33,16 @@
#include "nsBrowserStatusFilter.h"
#include "mozilla/FinalizationWitnessService.h"
#include "mozilla/NativeOSFileInternals.h"
#include "mozilla/AddonContentPolicy.h"
#include "mozilla/AddonManagerStartup.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/ExtensionPolicyService.h"
-#include "mozilla/WebRequestService.h"
#if defined(XP_WIN)
#include "NativeFileWatcherWin.h"
#else
#include "NativeFileWatcherNotSupported.h"
#endif // (XP_WIN)
#if !defined(MOZ_WIDGET_ANDROID)
@@ -122,17 +121,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsUpdateP
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(FinalizationWitnessService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(NativeOSFileInternalsService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NativeFileWatcherService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(AddonContentPolicy)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AddonPathService, AddonPathService::GetInstance)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AddonManagerStartup, AddonManagerStartup::GetInstance)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ExtensionPolicyService, ExtensionPolicyService::GetInstance)
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WebRequestService, WebRequestService::GetInstance)
NS_DEFINE_NAMED_CID(NS_TOOLKIT_APPSTARTUP_CID);
#if defined(MOZ_HAS_PERFSTATS)
NS_DEFINE_NAMED_CID(NS_TOOLKIT_PERFORMANCESTATSSERVICE_CID);
#endif // defined (MOZ_HAS_PERFSTATS)
#if defined(MOZ_HAS_TERMINATOR)
NS_DEFINE_NAMED_CID(NS_TOOLKIT_TERMINATOR_CID);
@@ -157,17 +155,16 @@ NS_DEFINE_NAMED_CID(NS_BROWSERSTATUSFILT
NS_DEFINE_NAMED_CID(NS_UPDATEPROCESSOR_CID);
#endif
NS_DEFINE_NAMED_CID(FINALIZATIONWITNESSSERVICE_CID);
NS_DEFINE_NAMED_CID(NATIVE_OSFILE_INTERNALS_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_ADDONCONTENTPOLICY_CID);
NS_DEFINE_NAMED_CID(NS_ADDON_PATH_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_ADDON_MANAGER_STARTUP_CID);
NS_DEFINE_NAMED_CID(NS_ADDON_POLICY_SERVICE_CID);
-NS_DEFINE_NAMED_CID(NS_WEBREQUEST_SERVICE_CID);
NS_DEFINE_NAMED_CID(NATIVE_FILEWATCHER_SERVICE_CID);
static const Module::CIDEntry kToolkitCIDs[] = {
{ &kNS_TOOLKIT_APPSTARTUP_CID, false, nullptr, nsAppStartupConstructor },
#if defined(MOZ_HAS_TERMINATOR)
{ &kNS_TOOLKIT_TERMINATOR_CID, false, nullptr, nsTerminatorConstructor },
#endif
#if defined(MOZ_HAS_PERFSTATS)
@@ -193,17 +190,16 @@ static const Module::CIDEntry kToolkitCI
{ &kNS_UPDATEPROCESSOR_CID, false, nullptr, nsUpdateProcessorConstructor },
#endif
{ &kFINALIZATIONWITNESSSERVICE_CID, false, nullptr, FinalizationWitnessServiceConstructor },
{ &kNATIVE_OSFILE_INTERNALS_SERVICE_CID, false, nullptr, NativeOSFileInternalsServiceConstructor },
{ &kNS_ADDONCONTENTPOLICY_CID, false, nullptr, AddonContentPolicyConstructor },
{ &kNS_ADDON_PATH_SERVICE_CID, false, nullptr, AddonPathServiceConstructor },
{ &kNS_ADDON_MANAGER_STARTUP_CID, false, nullptr, AddonManagerStartupConstructor },
{ &kNS_ADDON_POLICY_SERVICE_CID, false, nullptr, ExtensionPolicyServiceConstructor },
- { &kNS_WEBREQUEST_SERVICE_CID, false, nullptr, WebRequestServiceConstructor },
{ &kNATIVE_FILEWATCHER_SERVICE_CID, false, nullptr, NativeFileWatcherServiceConstructor },
{ nullptr }
};
static const Module::ContractIDEntry kToolkitContracts[] = {
{ NS_APPSTARTUP_CONTRACTID, &kNS_TOOLKIT_APPSTARTUP_CID },
#if defined(MOZ_HAS_TERMINATOR)
{ NS_TOOLKIT_TERMINATOR_CONTRACTID, &kNS_TOOLKIT_TERMINATOR_CID },
@@ -232,17 +228,16 @@ static const Module::ContractIDEntry kTo
{ NS_UPDATEPROCESSOR_CONTRACTID, &kNS_UPDATEPROCESSOR_CID },
#endif
{ FINALIZATIONWITNESSSERVICE_CONTRACTID, &kFINALIZATIONWITNESSSERVICE_CID },
{ NATIVE_OSFILE_INTERNALS_SERVICE_CONTRACTID, &kNATIVE_OSFILE_INTERNALS_SERVICE_CID },
{ NS_ADDONCONTENTPOLICY_CONTRACTID, &kNS_ADDONCONTENTPOLICY_CID },
{ NS_ADDONPATHSERVICE_CONTRACTID, &kNS_ADDON_PATH_SERVICE_CID },
{ NS_ADDONMANAGERSTARTUP_CONTRACTID, &kNS_ADDON_MANAGER_STARTUP_CID },
{ NS_ADDON_POLICY_SERVICE_CONTRACTID, &kNS_ADDON_POLICY_SERVICE_CID },
- { NS_WEBREQUESTSERVICE_CONTRACTID, &kNS_WEBREQUEST_SERVICE_CID },
{ NATIVE_FILEWATCHER_SERVICE_CONTRACTID, &kNATIVE_FILEWATCHER_SERVICE_CID },
{ nullptr }
};
static const mozilla::Module::CategoryEntry kToolkitCategories[] = {
{ "content-policy", NS_ADDONCONTENTPOLICY_CONTRACTID, NS_ADDONCONTENTPOLICY_CONTRACTID },
{ nullptr }
};
--- a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp
+++ b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp
@@ -15,16 +15,17 @@
#include "NSSErrorsService.h"
#include "nsITransportSecurityInfo.h"
#include "mozilla/AddonManagerWebAPI.h"
#include "mozilla/ErrorNames.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/Event.h"
+#include "mozilla/dom/TabParent.h"
#include "nsIContentPolicy.h"
#include "nsIHttpChannelInternal.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadContext.h"
#include "nsILoadGroup.h"
#include "nsIProxiedChannel.h"
@@ -559,16 +560,48 @@ ChannelWrapper::ParentWindowId() const
parentID = loadInfo->GetParentOuterWindowID();
}
return NormalizeWindowID(loadInfo, parentID);
}
return -1;
}
/*****************************************************************************
+ * Response filtering
+ *****************************************************************************/
+
+void
+ChannelWrapper::RegisterTraceableChannel(const WebExtensionPolicy& aAddon, nsITabParent* aTabParent)
+{
+ mAddonEntries.Put(aAddon.Id(), aTabParent);
+ if (!mChannelEntry) {
+ mChannelEntry = WebRequestService::GetSingleton().RegisterChannel(this);
+ CheckEventListeners();
+ }
+}
+
+already_AddRefed<nsIChannel>
+ChannelWrapper::GetTraceableChannel(nsIAtom* aAddonId, dom::nsIContentParent* aContentParent) const
+{
+ nsCOMPtr<nsITabParent> tabParent;
+ if (mAddonEntries.Get(aAddonId, getter_AddRefs(tabParent))) {
+ nsIContentParent* contentParent = nullptr;
+ if (tabParent) {
+ contentParent = static_cast<nsIContentParent*>(
+ static_cast<TabParent*>(tabParent.get())->Manager());
+ }
+
+ if (contentParent == aContentParent) {
+ return MaybeChannel();
+ }
+ }
+ return nullptr;
+}
+
+/*****************************************************************************
* ...
*****************************************************************************/
MozContentPolicyType
GetContentPolicyType(uint32_t aType)
{
// Note: Please keep this function in sync with the external types in
// nsIContentPolicy.idl
@@ -777,16 +810,17 @@ ChannelWrapper::GetErrorString(nsString&
void
ChannelWrapper::ErrorCheck()
{
if (!mFiredErrorEvent) {
nsAutoString error;
GetErrorString(error);
if (error.Length()) {
+ mChannelEntry = nullptr;
mFiredErrorEvent = true;
ChannelWrapperBinding::ClearCachedErrorStringValue(this);
FireEvent(NS_LITERAL_STRING("error"));
}
}
}
/*****************************************************************************
@@ -812,28 +846,30 @@ ChannelWrapper::RequestListener::Init()
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
ChannelWrapper::RequestListener::OnStartRequest(nsIRequest *request, nsISupports * aCtxt)
{
MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
+ mChannelWrapper->mChannelEntry = nullptr;
mChannelWrapper->ErrorCheck();
mChannelWrapper->FireEvent(NS_LITERAL_STRING("start"));
return mOrigStreamListener->OnStartRequest(request, aCtxt);
}
NS_IMETHODIMP
ChannelWrapper::RequestListener::OnStopRequest(nsIRequest *request, nsISupports *aCtxt,
nsresult aStatus)
{
MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
+ mChannelWrapper->mChannelEntry = nullptr;
mChannelWrapper->ErrorCheck();
mChannelWrapper->FireEvent(NS_LITERAL_STRING("stop"));
return mOrigStreamListener->OnStopRequest(request, aCtxt, aStatus);
}
NS_IMETHODIMP
ChannelWrapper::RequestListener::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt,
@@ -875,17 +911,18 @@ ChannelWrapper::FireEvent(const nsAStrin
DispatchEvent(event, &defaultPrevented);
}
void
ChannelWrapper::CheckEventListeners()
{
if (!mAddedStreamListener && (HasListenersFor(nsGkAtoms::onerror) ||
HasListenersFor(nsGkAtoms::onstart) ||
- HasListenersFor(nsGkAtoms::onstop))) {
+ HasListenersFor(nsGkAtoms::onstop) ||
+ mChannelEntry)) {
auto listener = MakeRefPtr<RequestListener>(this);
if (!NS_WARN_IF(NS_FAILED(listener->Init()))) {
mAddedStreamListener = true;
}
}
}
void
--- a/toolkit/components/extensions/webrequest/ChannelWrapper.h
+++ b/toolkit/components/extensions/webrequest/ChannelWrapper.h
@@ -5,40 +5,49 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_extensions_ChannelWrapper_h
#define mozilla_extensions_ChannelWrapper_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ChannelWrapperBinding.h"
+#include "mozilla/WebRequestService.h"
#include "mozilla/extensions/MatchPattern.h"
#include "mozilla/extensions/WebExtensionPolicy.h"
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/WeakPtr.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
#include "nsIStreamListener.h"
+#include "nsITabParent.h"
#include "nsIThreadRetargetableStreamListener.h"
+#include "nsPointerHashKeys.h"
+#include "nsInterfaceHashtable.h"
#include "nsWeakPtr.h"
#include "nsWrapperCache.h"
#define NS_CHANNELWRAPPER_IID \
{ 0xc06162d2, 0xb803, 0x43b4, \
{ 0xaa, 0x31, 0xcf, 0x69, 0x7f, 0x93, 0x68, 0x1c } }
class nsIDOMElement;
class nsILoadContext;
namespace mozilla {
+namespace dom {
+ class nsIContentParent;
+}
namespace extensions {
namespace detail {
// We need to store our wrapped channel as a weak reference, since channels
// are not cycle collected, and we're going to be hanging this wrapper
// instance off the channel in order to ensure the same channel always has
// the same wrapper.
@@ -92,17 +101,20 @@ namespace detail {
private:
nsWeakPtr mChannel;
mutable nsIChannel* MOZ_NON_OWNING_REF mWeakChannel;
mutable Maybe<nsIHttpChannel*> MOZ_NON_OWNING_REF mWeakHttpChannel;
};
}
+class WebRequestChannelEntry;
+
class ChannelWrapper final : public DOMEventTargetHelper
+ , public SupportsWeakPtr<ChannelWrapper>
, private detail::ChannelHolder
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ChannelWrapper, DOMEventTargetHelper)
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CHANNELWRAPPER_IID)
@@ -125,16 +137,21 @@ public:
void SetSuspended(bool aSuspended, ErrorResult& aRv);
void GetContentType(nsCString& aContentType) const;
void SetContentType(const nsACString& aContentType);
+ void RegisterTraceableChannel(const WebExtensionPolicy& aAddon, nsITabParent* aTabParent);
+
+ already_AddRefed<nsIChannel> GetTraceableChannel(nsIAtom* aAddonId, dom::nsIContentParent* aContentParent) const;
+
+
void GetMethod(nsCString& aRetVal) const;
dom::MozContentPolicyType Type() const;
uint32_t StatusCode() const;
void GetStatusLine(nsCString& aRetVal) const;
@@ -256,24 +273,29 @@ private:
UniquePtr<WebRequestChannelEntry> mChannelEntry;
// The overridden Content-Type header value.
nsCString mContentTypeHdr = VoidCString();
mutable Maybe<URLInfo> mFinalURLInfo;
mutable Maybe<URLInfo> mDocumentURLInfo;
+ UniquePtr<WebRequestChannelEntry> mChannelEntry;
+
const uint64_t mId = GetNextId();
nsCOMPtr<nsISupports> mParent;
bool mAddedStreamListener = false;
bool mFiredErrorEvent = false;
bool mSuspended = false;
+ nsInterfaceHashtable<nsPtrHashKey<const nsIAtom>, nsITabParent> mAddonEntries;
+
+
class RequestListener final : public nsIStreamListener
, public nsIThreadRetargetableStreamListener
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
--- a/toolkit/components/extensions/webrequest/WebRequestService.cpp
+++ b/toolkit/components/extensions/webrequest/WebRequestService.cpp
@@ -3,54 +3,29 @@
/* 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 "WebRequestService.h"
#include "mozilla/Assertions.h"
#include "mozilla/ClearOnShutdown.h"
-#include "nsCOMPtr.h"
#include "nsIChannel.h"
-#include "nsIDOMWindowUtils.h"
-#include "nsISupports.h"
-#include "nsITabParent.h"
-#include "nsITraceableChannel.h"
-#include "nsTArray.h"
-
-#include "mozilla/dom/TabParent.h"
using namespace mozilla;
using namespace mozilla::dom;
+using namespace mozilla::extensions;
static WebRequestService* sWeakWebRequestService;
-WebRequestService::WebRequestService()
- : mDataLock("WebRequest service data lock")
-{
-}
-
WebRequestService::~WebRequestService()
{
- // Store existing entries in an array, since Detach can't safely remove them
- // while we're iterating the hashtable.
- AutoTArray<ChannelEntry*, 32> entries;
- for (auto iter = mChannelEntries.Iter(); !iter.Done(); iter.Next()) {
- entries.AppendElement(iter.Data());
- }
-
- for (auto channel : entries) {
- channel->DetachAll();
- }
-
sWeakWebRequestService = nullptr;
}
-NS_IMPL_ISUPPORTS(WebRequestService, mozIWebRequestService)
-
/* static */ WebRequestService&
WebRequestService::GetSingleton()
{
static RefPtr<WebRequestService> instance;
if (!sWeakWebRequestService) {
instance = new WebRequestService();
ClearOnShutdown(&instance);
@@ -58,131 +33,46 @@ WebRequestService::GetSingleton()
// original service is alive, even after our strong reference is cleared to
// allow the service to be destroyed.
sWeakWebRequestService = instance;
}
return *sWeakWebRequestService;
}
-NS_IMETHODIMP
-WebRequestService::RegisterTraceableChannel(uint64_t aChannelId,
- nsIChannel* aChannel,
- const nsAString& aAddonId,
- nsITabParent* aTabParent,
- nsIJSRAIIHelper** aHelper)
+UniquePtr<WebRequestChannelEntry>
+WebRequestService::RegisterChannel(ChannelWrapper* aChannel)
{
- nsCOMPtr<nsITraceableChannel> traceableChannel = do_QueryInterface(aChannel);
- NS_ENSURE_TRUE(traceableChannel, NS_ERROR_INVALID_ARG);
+ UniquePtr<ChannelEntry> entry(new ChannelEntry(aChannel));
- nsCOMPtr<nsIAtom> addonId = NS_Atomize(aAddonId);
- ChannelParent* entry = new ChannelParent(aChannelId, aChannel,
- addonId, aTabParent);
+ auto key = mChannelEntries.LookupForAdd(entry->mChannelId);
+ MOZ_DIAGNOSTIC_ASSERT(!key);
+ key.OrInsert([&entry]() { return entry.get(); });
- RefPtr<Destructor> destructor = new Destructor(entry);
- destructor.forget(aHelper);
+ return Move(entry);
- return NS_OK;
}
already_AddRefed<nsIChannel>
WebRequestService::GetTraceableChannel(uint64_t aChannelId,
nsIAtom* aAddonId,
nsIContentParent* aContentParent)
{
- MutexAutoLock al(mDataLock);
-
- auto entry = mChannelEntries.Get(aChannelId);
- if (!entry) {
- return nullptr;
- }
+ if (auto entry = mChannelEntries.Get(aChannelId)) {
+ if (entry->mChannel) {
+ return entry->mChannel->GetTraceableChannel(aAddonId, aContentParent);
- for (auto channelEntry : entry->mTabParents) {
- nsIContentParent* contentParent = nullptr;
- if (channelEntry->mTabParent) {
- contentParent = static_cast<nsIContentParent*>(
- channelEntry->mTabParent->Manager());
- }
-
- if (channelEntry->mAddonId == aAddonId && contentParent == aContentParent) {
- nsCOMPtr<nsIChannel> channel = do_QueryReferent(entry->mChannel);
- return channel.forget();
}
}
-
return nullptr;
}
-
-WebRequestService::ChannelParent::ChannelParent(uint64_t aChannelId, nsIChannel* aChannel,
- nsIAtom* aAddonId, nsITabParent* aTabParent)
- : mTabParent(static_cast<TabParent*>(aTabParent))
- , mAddonId(aAddonId)
- , mChannelId(aChannelId)
-{
- auto service = &GetSingleton();
- MutexAutoLock al(service->mDataLock);
-
- auto entry = service->mChannelEntries.LookupOrAdd(mChannelId);
+WebRequestChannelEntry::WebRequestChannelEntry(ChannelWrapper* aChannel)
+ : mChannelId(aChannel->Id())
+ , mChannel(aChannel)
+{}
- entry->mChannel = do_GetWeakReference(aChannel);
- entry->mTabParents.insertBack(this);
-}
-
-WebRequestService::ChannelParent::~ChannelParent()
-{
- MOZ_ASSERT(mDetached);
-}
-
-void
-WebRequestService::ChannelParent::Detach()
+WebRequestChannelEntry::~WebRequestChannelEntry()
{
- if (mDetached) {
- return;
- }
- auto service = &GetSingleton();
- MutexAutoLock al(service->mDataLock);
-
- auto& map = service->mChannelEntries;
- auto entry = map.Get(mChannelId);
- MOZ_ASSERT(entry);
-
- removeFrom(entry->mTabParents);
- if (entry->mTabParents.isEmpty()) {
- map.Remove(mChannelId);
- }
- mDetached = true;
-}
-
-void
-WebRequestService::ChannelEntry::DetachAll()
-{
- // Store the next link gecore calling Detach(), since the last Detach() call
- // will destroy this instance and poison our mTabParents member.
- for (ChannelParent *parent, *next = mTabParents.getFirst();
- (parent = next);) {
- next = parent->getNext();
- parent->Detach();
+ if (sWeakWebRequestService) {
+ sWeakWebRequestService->mChannelEntries.Remove(mChannelId);
}
}
-
-WebRequestService::Destructor::~Destructor()
-{
- if (NS_WARN_IF(!mDestructCalled)) {
- Destruct();
- }
-}
-
-NS_IMETHODIMP
-WebRequestService::Destructor::Destruct()
-{
- if (NS_WARN_IF(mDestructCalled)) {
- return NS_ERROR_FAILURE;
- }
- mDestructCalled = true;
-
- mChannelParent->Detach();
- delete mChannelParent;
-
- return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS(WebRequestService::Destructor, nsIJSRAIIHelper)
--- a/toolkit/components/extensions/webrequest/WebRequestService.h
+++ b/toolkit/components/extensions/webrequest/WebRequestService.h
@@ -2,103 +2,78 @@
/* 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/. */
#ifndef mozilla_WebRequestService_h
#define mozilla_WebRequestService_h
-#include "mozIWebRequestService.h"
+#include "mozilla/LinkedList.h"
+#include "mozilla/UniquePtr.h"
-#include "mozilla/LinkedList.h"
-#include "mozilla/Mutex.h"
-#include "nsCOMPtr.h"
+#include "mozilla/extensions/ChannelWrapper.h"
+#include "mozilla/extensions/WebExtensionPolicy.h"
+
#include "nsHashKeys.h"
-#include "nsClassHashtable.h"
-#include "nsIAtom.h"
-#include "nsIDOMWindowUtils.h"
-#include "nsWeakPtr.h"
+#include "nsDataHashtable.h"
-using namespace mozilla;
+class nsIAtom;
+class nsITabParent;
namespace mozilla {
namespace dom {
class TabParent;
class nsIContentParent;
}
-}
-class WebRequestService : public mozIWebRequestService
+namespace extensions {
+
+class WebRequestChannelEntry final
{
public:
- NS_DECL_ISUPPORTS
- NS_DECL_MOZIWEBREQUESTSERVICE
+ ~WebRequestChannelEntry();
+
+private:
+ friend class WebRequestService;
+
+ WebRequestChannelEntry(ChannelWrapper* aChannel);
- explicit WebRequestService();
+ uint64_t mChannelId;
+ WeakPtr<ChannelWrapper> mChannel;
+};
+
+class WebRequestService final
+{
+public:
+ NS_INLINE_DECL_REFCOUNTING(WebRequestService)
+
+ WebRequestService() = default;
static already_AddRefed<WebRequestService> GetInstance()
{
return do_AddRef(&GetSingleton());
}
static WebRequestService& GetSingleton();
+ using ChannelEntry = WebRequestChannelEntry;
+
+ UniquePtr<ChannelEntry> RegisterChannel(ChannelWrapper* aChannel);
+
+ void UnregisterTraceableChannel(uint64_t aChannelId);
+
already_AddRefed<nsIChannel>
GetTraceableChannel(uint64_t aChannelId, nsIAtom* aAddonId,
dom::nsIContentParent* aContentParent);
-protected:
- virtual ~WebRequestService();
-
private:
- class ChannelParent : public LinkedListElement<ChannelParent>
- {
- public:
- explicit ChannelParent(uint64_t aChannelId, nsIChannel* aChannel, nsIAtom* aAddonId, nsITabParent* aTabParent);
- ~ChannelParent();
-
- void Detach();
-
- const RefPtr<dom::TabParent> mTabParent;
- const nsCOMPtr<nsIAtom> mAddonId;
-
- private:
- const uint64_t mChannelId;
- bool mDetached = false;
- };
-
- class Destructor : public nsIJSRAIIHelper
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIJSRAIIHELPER
+ ~WebRequestService();
- explicit Destructor(ChannelParent* aChannelParent)
- : mChannelParent(aChannelParent)
- , mDestructCalled(false)
- {}
-
- protected:
- virtual ~Destructor();
-
- private:
- ChannelParent* mChannelParent;
- bool mDestructCalled;
- };
+ friend ChannelEntry;
- class ChannelEntry
- {
- public:
- void DetachAll();
-
- // Note: We can't keep a strong pointer to the channel here, since channels
- // are not cycle collected, and a reference to this object will be stored on
- // the channel in order to keep the entry alive.
- nsWeakPtr mChannel;
- LinkedList<ChannelParent> mTabParents;
- };
-
- nsClassHashtable<nsUint64HashKey, ChannelEntry> mChannelEntries;
- Mutex mDataLock;
+ nsDataHashtable<nsUint64HashKey, ChannelEntry*> mChannelEntries;
};
+}
+}
+
#endif // mozilla_WebRequestService_h
--- a/toolkit/components/extensions/webrequest/moz.build
+++ b/toolkit/components/extensions/webrequest/moz.build
@@ -1,20 +1,14 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
-XPIDL_SOURCES += [
- 'mozIWebRequestService.idl',
-]
-
-XPIDL_MODULE = 'webextensions'
-
UNIFIED_SOURCES += [
'ChannelWrapper.cpp',
'StreamFilter.cpp',
'StreamFilterChild.cpp',
'StreamFilterEvents.cpp',
'StreamFilterParent.cpp',
'WebRequestService.cpp',
]
deleted file mode 100644
--- a/toolkit/components/extensions/webrequest/mozIWebRequestService.idl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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 "nsISupports.idl"
-
-interface nsIChannel;
-interface nsIJSRAIIHelper;
-interface nsITabParent;
-
-[scriptable, builtinclass, uuid(1b1118ed-f208-4cfc-b841-5b31a78c2b7a)]
-interface mozIWebRequestService : nsISupports
-{
- nsIJSRAIIHelper registerTraceableChannel(in uint64_t channelId,
- in nsIChannel channel,
- in AString addonId,
- [optional] in nsITabParent tabParent);
-};
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -22,20 +22,16 @@ Cu.import("resource://gre/modules/XPCOMU
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionUtils",
"resource://gre/modules/ExtensionUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebRequestCommon",
"resource://gre/modules/WebRequestCommon.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebRequestUpload",
"resource://gre/modules/WebRequestUpload.jsm");
-XPCOMUtils.defineLazyServiceGetter(this, "webReqService",
- "@mozilla.org/addons/webrequest-service;1",
- "mozIWebRequestService");
-
XPCOMUtils.defineLazyGetter(this, "ExtensionError", () => ExtensionUtils.ExtensionError);
function runLater(job) {
Services.tm.dispatchToMainThread(job);
}
function parseFilter(filter) {
if (!filter) {
@@ -696,53 +692,24 @@ HttpObserverManager = {
proxyInfo: channel.proxyInfo,
serialize: serializeRequestData,
};
return Object.assign(data, extraData);
},
- registerChannel(channel, opts) {
- if (!opts.blockingAllowed || !opts.addonId) {
- return;
- }
-
- if (!channel.registeredFilters) {
- channel.registeredFilters = new Map();
- } else if (channel.registeredFilters.has(opts.addonId)) {
- return;
- }
-
- let filter = webReqService.registerTraceableChannel(
- channel.id,
- channel.channel,
- opts.addonId,
- opts.tabParent);
-
- channel.registeredFilters.set(opts.addonId, filter);
- },
-
- destroyFilters(channel) {
- let filters = channel.registeredFilters || new Map();
- for (let [key, filter] of filters.entries()) {
- filter.destruct();
- filters.delete(key);
- }
- },
-
handleEvent(event) {
let channel = event.currentTarget;
switch (event.type) {
case "error":
this.runChannelListener(
channel, "onError", {error: channel.errorString});
break;
case "start":
- this.destroyFilters(channel);
this.runChannelListener(channel, "onStart");
break;
case "stop":
this.runChannelListener(channel, "onStop");
break;
}
},
@@ -770,18 +737,18 @@ HttpObserverManager = {
commonData = this.getRequestData(channel, extraData);
if (includeStatus) {
commonData.statusCode = channel.statusCode;
commonData.statusLine = channel.statusLine;
}
}
let data = Object.assign({}, commonData);
- if (registerFilter && opts.blocking) {
- this.registerChannel(channel, opts);
+ if (registerFilter && opts.blocking && opts.extension) {
+ channel.registerTraceableChannel(opts.extension, opts.tabParent);
}
if (opts.requestHeaders) {
requestHeaders = requestHeaders || new RequestHeaderChanger(channel);
data.requestHeaders = requestHeaders.toArray();
}
if (opts.responseHeaders) {
@@ -902,17 +869,16 @@ HttpObserverManager = {
}
},
onChannelReplaced(oldChannel, newChannel) {
let channel = this.getWrapper(oldChannel);
// We want originalURI, this will provide a moz-ext rather than jar or file
// uri on redirects.
- this.destroyFilters(channel);
this.runChannelListener(channel, "onRedirect", {redirectUrl: newChannel.originalURI.spec});
channel.channel = newChannel;
},
};
var onBeforeRequest = {
allowedOptions: ["blocking", "requestBody"],