--- a/dom/webidl/ChannelWrapper.webidl
+++ b/dom/webidl/ChannelWrapper.webidl
@@ -164,16 +164,27 @@ interface ChannelWrapper : EventTarget {
/**
* Checks the request's current status and dispatches an error event if the
* request has failed and one has not already been dispatched.
*/
void errorCheck();
/**
+ * Dispatched when the channel begins receiving data.
+ */
+ attribute EventHandler onstart;
+
+ /**
+ * Dispatched when the channel has finished receiving data.
+ */
+ attribute EventHandler onstop;
+
+
+ /**
* Information about the proxy server which is handling this request, or
* null if the request is not proxied.
*/
[Cached, Frozen, GetterThrows, Pure]
readonly attribute MozProxyInfo? proxyInfo;
/**
* For HTTP requests, the IP address of the remote server handling the
--- a/toolkit/components/build/nsToolkitCompsModule.cpp
+++ b/toolkit/components/build/nsToolkitCompsModule.cpp
@@ -41,18 +41,16 @@
#include "mozilla/WebRequestService.h"
#if defined(XP_WIN)
#include "NativeFileWatcherWin.h"
#else
#include "NativeFileWatcherNotSupported.h"
#endif // (XP_WIN)
-#include "nsWebRequestListener.h"
-
#if !defined(MOZ_WIDGET_ANDROID)
#define MOZ_HAS_TERMINATOR
#endif
#if defined(MOZ_HAS_TERMINATOR)
#include "nsTerminator.h"
#endif
@@ -126,18 +124,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(NativeOSF
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_GENERIC_FACTORY_CONSTRUCTOR(nsWebRequestListener)
-
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);
#endif
@@ -163,17 +159,16 @@ NS_DEFINE_NAMED_CID(NS_UPDATEPROCESSOR_C
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);
-NS_DEFINE_NAMED_CID(NS_WEBREQUESTLISTENER_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)
{ &kNS_TOOLKIT_PERFORMANCESTATSSERVICE_CID, false, nullptr, nsPerformanceStatsServiceConstructor },
@@ -200,17 +195,16 @@ static const Module::CIDEntry kToolkitCI
{ &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 },
- { &kNS_WEBREQUESTLISTENER_CID, false, nullptr, nsWebRequestListenerConstructor },
{ 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 },
#endif
@@ -240,17 +234,16 @@ static const Module::ContractIDEntry kTo
{ 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 },
- { NS_WEBREQUESTLISTENER_CONTRACTID, &kNS_WEBREQUESTLISTENER_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
@@ -24,18 +24,20 @@
#include "nsIHttpChannelInternal.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadContext.h"
#include "nsILoadGroup.h"
#include "nsIProxiedChannel.h"
#include "nsIProxyInfo.h"
+#include "nsITraceableChannel.h"
#include "nsIWritablePropertyBag2.h"
#include "nsNetUtil.h"
+#include "nsProxyRelease.h"
#include "nsPrintfCString.h"
using namespace mozilla::dom;
using namespace JS;
namespace mozilla {
namespace extensions {
@@ -714,16 +716,84 @@ ChannelWrapper::ErrorCheck()
mFiredErrorEvent = true;
ChannelWrapperBinding::ClearCachedErrorStringValue(this);
FireEvent(NS_LITERAL_STRING("error"));
}
}
}
/*****************************************************************************
+ * nsIWebRequestListener
+ *****************************************************************************/
+
+NS_IMPL_ISUPPORTS(ChannelWrapper::RequestListener,
+ nsIStreamListener,
+ nsIRequestObserver,
+ nsIThreadRetargetableStreamListener)
+
+ChannelWrapper::RequestListener::~RequestListener() {
+ NS_ReleaseOnMainThreadSystemGroup("RequestListener::mChannelWrapper",
+ mChannelWrapper.forget());
+}
+
+nsresult
+ChannelWrapper::RequestListener::Init()
+{
+ if (nsCOMPtr<nsITraceableChannel> chan = mChannelWrapper->QueryChannel()) {
+ return chan->SetNewListener(this, getter_AddRefs(mOrigStreamListener));
+ }
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+ChannelWrapper::RequestListener::OnStartRequest(nsIRequest *request, nsISupports * aCtxt)
+{
+ MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
+
+ 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->ErrorCheck();
+ mChannelWrapper->FireEvent(NS_LITERAL_STRING("stop"));
+
+ return mOrigStreamListener->OnStopRequest(request, aCtxt, aStatus);
+}
+
+NS_IMETHODIMP
+ChannelWrapper::RequestListener::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt,
+ nsIInputStream * inStr,
+ uint64_t sourceOffset, uint32_t count)
+{
+ MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
+ return mOrigStreamListener->OnDataAvailable(request, aCtxt, inStr, sourceOffset, count);
+}
+
+NS_IMETHODIMP
+ChannelWrapper::RequestListener::CheckListenerChain()
+{
+ MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread!");
+ nsresult rv;
+ nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
+ do_QueryInterface(mOrigStreamListener, &rv);
+ if (retargetableListener) {
+ return retargetableListener->CheckListenerChain();
+ }
+ return rv;
+}
+
+/*****************************************************************************
* Event dispatching
*****************************************************************************/
void
ChannelWrapper::FireEvent(const nsAString& aType)
{
EventInit init;
init.mBubbles = false;
@@ -731,16 +801,41 @@ ChannelWrapper::FireEvent(const nsAStrin
RefPtr<Event> event = Event::Constructor(this, aType, init);
event->SetTrusted(true);
bool defaultPrevented;
DispatchEvent(event, &defaultPrevented);
}
+void
+ChannelWrapper::CheckEventListeners()
+{
+ if (!mAddedStreamListener && (HasListenersFor(nsGkAtoms::onerror) ||
+ HasListenersFor(nsGkAtoms::onstart) ||
+ HasListenersFor(nsGkAtoms::onstop))) {
+ auto listener = MakeRefPtr<RequestListener>(this);
+ if (!NS_WARN_IF(NS_FAILED(listener->Init()))) {
+ mAddedStreamListener = true;
+ }
+ }
+}
+
+void
+ChannelWrapper::EventListenerAdded(nsIAtom* aType)
+{
+ CheckEventListeners();
+}
+
+void
+ChannelWrapper::EventListenerRemoved(nsIAtom* aType)
+{
+ CheckEventListeners();
+}
+
/*****************************************************************************
* Glue
*****************************************************************************/
JSObject*
ChannelWrapper::WrapObject(JSContext* aCx, HandleObject aGivenProto)
{
return ChannelWrapperBinding::Wrap(aCx, this, aGivenProto);
--- a/toolkit/components/extensions/webrequest/ChannelWrapper.h
+++ b/toolkit/components/extensions/webrequest/ChannelWrapper.h
@@ -13,16 +13,18 @@
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
+#include "nsIStreamListener.h"
+#include "nsIThreadRetargetableStreamListener.h"
#include "nsWeakPtr.h"
#include "nsWrapperCache.h"
#define NS_CHANNELWRAPPER_IID \
{ 0xc06162d2, 0xb803, 0x43b4, \
{ 0xaa, 0x31, 0xcf, 0x69, 0x7f, 0x93, 0x68, 0x1c } }
class nsIDOMElement;
@@ -134,16 +136,18 @@ public:
void GetStatusLine(nsCString& aRetVal) const;
void GetErrorString(nsString& aRetVal) const;
void ErrorCheck();
IMPL_EVENT_HANDLER(error);
+ IMPL_EVENT_HANDLER(start);
+ IMPL_EVENT_HANDLER(stop);
already_AddRefed<nsIURI> GetFinalURI(ErrorResult& aRv) const;
void GetFinalURL(nsCString& aRetVal, ErrorResult& aRv) const;
already_AddRefed<nsILoadInfo> GetLoadInfo() const
@@ -187,16 +191,22 @@ public:
void GetResponseHeaders(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv) const;
void SetRequestHeader(const nsCString& header, const nsCString& value, ErrorResult& aRv);
void SetResponseHeader(const nsCString& header, const nsCString& value, ErrorResult& aRv);
+ using EventTarget::EventListenerAdded;
+ using EventTarget::EventListenerRemoved;
+ virtual void EventListenerAdded(nsIAtom* aType) override;
+ virtual void EventListenerRemoved(nsIAtom* aType) override;
+
+
nsISupports* GetParentObject() const { return mParent; }
JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override;
protected:
~ChannelWrapper() = default;
private:
@@ -221,22 +231,55 @@ private:
uint64_t WindowId(nsILoadInfo* aLoadInfo) const;
static uint64_t GetNextId()
{
static uint64_t sNextId = 1;
return ++sNextId;
}
+ void CheckEventListeners();
+
+ mutable Maybe<URLInfo> mFinalURLInfo;
+ mutable Maybe<URLInfo> mDocumentURLInfo;
+
+ UniquePtr<WebRequestChannelEntry> mChannelEntry;
+
+ // The overridden Content-Type header value.
+ nsCString mContentTypeHdr = VoidCString();
const uint64_t mId = GetNextId();
nsCOMPtr<nsISupports> mParent;
+ bool mAddedStreamListener = false;
bool mFiredErrorEvent = false;
bool mSuspended = false;
+
+
+ class RequestListener final : public nsIStreamListener
+ , public nsIThreadRetargetableStreamListener
+ {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+
+ explicit RequestListener(ChannelWrapper* aWrapper)
+ : mChannelWrapper(aWrapper) {}
+
+ nsresult Init();
+
+ protected:
+ virtual ~RequestListener();
+
+ private:
+ RefPtr<ChannelWrapper> mChannelWrapper;
+ nsCOMPtr<nsIStreamListener> mOrigStreamListener;
+ };
};
NS_DEFINE_STATIC_IID_ACCESSOR(ChannelWrapper,
NS_CHANNELWRAPPER_IID)
} // namespace extensions
} // namespace mozilla
--- a/toolkit/components/extensions/webrequest/moz.build
+++ b/toolkit/components/extensions/webrequest/moz.build
@@ -1,39 +1,33 @@
# -*- 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',
- 'nsIWebRequestListener.idl',
]
XPIDL_MODULE = 'webextensions'
UNIFIED_SOURCES += [
'ChannelWrapper.cpp',
- 'nsWebRequestListener.cpp',
'StreamFilter.cpp',
'StreamFilterChild.cpp',
'StreamFilterEvents.cpp',
'StreamFilterParent.cpp',
'WebRequestService.cpp',
]
IPDL_SOURCES += [
'PStreamFilter.ipdl',
]
-EXPORTS += [
- 'nsWebRequestListener.h',
-]
-
EXPORTS.mozilla += [
'WebRequestService.h',
]
EXPORTS.mozilla.extensions += [
'ChannelWrapper.h',
'StreamFilter.h',
'StreamFilterBase.h',
deleted file mode 100644
--- a/toolkit/components/extensions/webrequest/nsIWebRequestListener.idl
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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"
-#include "nsIStreamListener.idl"
-#include "nsITraceableChannel.idl"
-
-/* nsIWebRequestListener is a nsIThreadRetargetableStreamListener that handles
- * forwarding of nsIRequestObserver for JS consumers. nsIWebRequestListener
- * is not cycle collected, JS consumers should not keep a reference to this.
- */
-
-[scriptable, uuid(699a50bb-1f18-2844-b9ea-9f216f62cb18)]
-interface nsIWebRequestListener : nsISupports
-{
- void init(in nsIStreamListener aStreamListener,
- in nsITraceableChannel aTraceableChannel);
-};
-
-%{C++
-/* ebea9901-e135-b546-82e2-052666992dbb */
-#define NS_WEBREQUESTLISTENER_CID \
- {0xebea9901, 0xe135, 0xb546, \
- {0x82, 0xe2, 0x05, 0x26, 0x66, 0x99, 0x2d, 0xbb} }
-#define NS_WEBREQUESTLISTENER_CONTRACTID "@mozilla.org/webextensions/webRequestListener;1"
-%}
\ No newline at end of file
deleted file mode 100644
--- a/toolkit/components/extensions/webrequest/nsWebRequestListener.cpp
+++ /dev/null
@@ -1,72 +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 "mozilla/ModuleUtils.h"
-#include "nsWebRequestListener.h"
-
-#ifdef DEBUG
-#include "MainThreadUtils.h"
-#endif
-
-using namespace mozilla;
-
-NS_IMPL_ISUPPORTS(nsWebRequestListener,
- nsIWebRequestListener,
- nsIStreamListener,
- nsIRequestObserver,
- nsIThreadRetargetableStreamListener)
-
-NS_IMETHODIMP
-nsWebRequestListener::Init(nsIStreamListener *aStreamListener, nsITraceableChannel *aTraceableChannel)
-{
- MOZ_ASSERT(aStreamListener, "Should have aStreamListener");
- MOZ_ASSERT(aTraceableChannel, "Should have aTraceableChannel");
- mTargetStreamListener = aStreamListener;
- return aTraceableChannel->SetNewListener(this, getter_AddRefs(mOrigStreamListener));
-}
-
-NS_IMETHODIMP
-nsWebRequestListener::OnStartRequest(nsIRequest *request, nsISupports * aCtxt)
-{
- MOZ_ASSERT(mTargetStreamListener, "Should have mTargetStreamListener");
- MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
-
- mTargetStreamListener->OnStartRequest(request, aCtxt);
-
- return mOrigStreamListener->OnStartRequest(request, aCtxt);
-}
-
-NS_IMETHODIMP
-nsWebRequestListener::OnStopRequest(nsIRequest *request, nsISupports *aCtxt,
- nsresult aStatus)
-{
- MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
- MOZ_ASSERT(mTargetStreamListener, "Should have mTargetStreamListener");
-
- mOrigStreamListener->OnStopRequest(request, aCtxt, aStatus);
-
- return mTargetStreamListener->OnStopRequest(request, aCtxt, aStatus);
-}
-
-NS_IMETHODIMP
-nsWebRequestListener::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt,
- nsIInputStream * inStr,
- uint64_t sourceOffset, uint32_t count)
-{
- MOZ_ASSERT(mOrigStreamListener, "Should have mOrigStreamListener");
- return mOrigStreamListener->OnDataAvailable(request, aCtxt, inStr, sourceOffset, count);
-}
-
-NS_IMETHODIMP
-nsWebRequestListener::CheckListenerChain()
-{
- MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread!");
- nsresult rv;
- nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
- do_QueryInterface(mOrigStreamListener, &rv);
- if (retargetableListener) {
- return retargetableListener->CheckListenerChain();
- }
- return rv;
-}
deleted file mode 100644
--- a/toolkit/components/extensions/webrequest/nsWebRequestListener.h
+++ /dev/null
@@ -1,40 +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/. */
-
-#ifndef nsWebRequestListener_h__
-#define nsWebRequestListener_h__
-
-#include "nsCOMPtr.h"
-#include "nsIWebRequestListener.h"
-#include "nsIRequestObserver.h"
-#include "nsIStreamListener.h"
-#include "nsITraceableChannel.h"
-#include "nsIThreadRetargetableStreamListener.h"
-#include "nsProxyRelease.h"
-#include "mozilla/Attributes.h"
-
-class nsWebRequestListener final : public nsIWebRequestListener
- , public nsIStreamListener
- , public nsIThreadRetargetableStreamListener
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIWEBREQUESTLISTENER
- NS_DECL_NSIREQUESTOBSERVER
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
-
- nsWebRequestListener() {}
-
-private:
- ~nsWebRequestListener() {
- NS_ReleaseOnMainThreadSystemGroup("nsWebRequestListener::mTargetStreamListener",
- mTargetStreamListener.forget());
- }
- nsCOMPtr<nsIStreamListener> mOrigStreamListener;
- nsCOMPtr<nsIStreamListener> mTargetStreamListener;
-};
-
-#endif // nsWebRequestListener_h__
-
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -28,19 +28,16 @@ XPCOMUtils.defineLazyModuleGetter(this,
"resource://gre/modules/WebRequestUpload.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "webReqService",
"@mozilla.org/addons/webrequest-service;1",
"mozIWebRequestService");
XPCOMUtils.defineLazyGetter(this, "ExtensionError", () => ExtensionUtils.ExtensionError);
-let WebRequestListener = Components.Constructor("@mozilla.org/webextensions/webRequestListener;1",
- "nsIWebRequestListener", "init");
-
function runLater(job) {
Services.tm.dispatchToMainThread(job);
}
function parseFilter(filter) {
if (!filter) {
filter = {};
}
@@ -301,34 +298,16 @@ var ContentPolicyManager = {
this.policyData.delete(id);
this.idMap.delete(callback);
this.policies.delete(id);
},
};
ContentPolicyManager.init();
-function StartStopListener(manager, channel) {
- this.manager = manager;
- new WebRequestListener(this, channel.channel);
-}
-
-StartStopListener.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
- Ci.nsIStreamListener]),
-
- onStartRequest: function(request, context) {
- this.manager.onStartRequest(ChannelWrapper.get(request));
- },
-
- onStopRequest(request, context, statusCode) {
- this.manager.onStopRequest(ChannelWrapper.get(request));
- },
-};
-
var ChannelEventSink = {
_classDescription: "WebRequest channel event sink",
_classID: Components.ID("115062f8-92f1-11e5-8b7f-080027b0f7ec"),
_contractID: "@mozilla.org/webrequest/channel-event-sink;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannelEventSink,
Ci.nsIFactory]),
@@ -527,16 +506,22 @@ HttpObserverManager = {
getWrapper(nativeChannel) {
let wrapper = ChannelWrapper.get(nativeChannel);
if (!wrapper._addedListeners) {
/* eslint-disable mozilla/balanced-listeners */
if (this.listeners.onError.size) {
wrapper.addEventListener("error", this);
}
+ if (this.listeners.onStart.size) {
+ wrapper.addEventListener("start", this);
+ }
+ if (this.listeners.onStop.size) {
+ wrapper.addEventListener("stop", this);
+ }
/* eslint-enable mozilla/balanced-listeners */
wrapper._addedListeners = true;
}
return wrapper;
},
get activityDistributor() {
@@ -651,23 +636,16 @@ HttpObserverManager = {
observeActivity(nativeChannel, activityType, activitySubtype /* , aTimestamp, aExtraSizeData, aExtraStringData */) {
// Sometimes we get a NullHttpChannel, which implements
// nsIHttpChannel but not nsIChannel.
if (!(nativeChannel instanceof Ci.nsIChannel)) {
return;
}
let channel = this.getWrapper(nativeChannel);
- // StartStopListener has to be activated early in the request to catch
- // SSL connection issues which do not get reported via nsIHttpActivityObserver.
- if (activityType == nsIHttpActivityObserver.ACTIVITY_TYPE_HTTP_TRANSACTION &&
- activitySubtype == nsIHttpActivityObserver.ACTIVITY_SUBTYPE_REQUEST_HEADER) {
- this.attachStartStopListener(channel);
- }
-
let lastActivity = channel.lastActivity || 0;
if (activitySubtype === nsIHttpActivityObserver.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE &&
lastActivity && lastActivity !== this.GOOD_LAST_ACTIVITY) {
// Make a trip through the event loop to make sure errors have a
// chance to be processed before we fall back to a generic error
// string.
Services.tm.dispatchToMainThread(() => {
channel.errorCheck();
@@ -760,16 +738,23 @@ HttpObserverManager = {
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;
}
},
runChannelListener(channel, kind, extraData = null) {
let handlerResults = [];
let requestHeaders;
let responseHeaders;
@@ -909,35 +894,17 @@ HttpObserverManager = {
for (let opts of listener.values()) {
if (this.shouldRunListener(channel.type, channel.finalURI, opts.filter)) {
return true;
}
}
return false;
},
- attachStartStopListener(channel) {
- // Check whether we've already added a listener to this channel,
- // so we don't wind up chaining multiple listeners.
- if (!this.needTracing || channel.hasListener ||
- !(channel.channel instanceof Ci.nsITraceableChannel)) {
- return;
- }
-
- // skip redirections, https://bugzilla.mozilla.org/show_bug.cgi?id=728901#c8
- let {statusCode} = channel;
- if (statusCode < 300 || statusCode >= 400) {
- new StartStopListener(this, channel);
- channel.hasListener = true;
- }
- },
-
examine(channel, topic, data) {
- this.attachStartStopListener(channel);
-
if (this.listeners.headersReceived.size) {
this.runChannelListener(channel, "headersReceived");
}
if (!channel.hasAuthRequestor && this.shouldHookListener(this.listeners.authRequired, channel)) {
channel.channel.notificationCallbacks = new AuthRequestor(channel.channel, this);
channel.hasAuthRequestor = true;
}
@@ -947,25 +914,16 @@ HttpObserverManager = {
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;
},
-
- onStartRequest(channel) {
- this.destroyFilters(channel);
- this.runChannelListener(channel, "onStart");
- },
-
- onStopRequest(channel) {
- this.runChannelListener(channel, "onStop");
- },
};
var onBeforeRequest = {
allowedOptions: ["blocking", "requestBody"],
addListener(callback, filter = null, options = null, optionsObject = null) {
let opts = parseExtra(options, this.allowedOptions);
opts.filter = parseFilter(filter);