--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -325,16 +325,17 @@
@RESPATH@/components/txmgr.xpt
@RESPATH@/components/uconv.xpt
@RESPATH@/components/unicharutil.xpt
@RESPATH@/components/update.xpt
@RESPATH@/components/uriloader.xpt
@RESPATH@/components/urlformatter.xpt
@RESPATH@/components/webBrowser_core.xpt
@RESPATH@/components/webbrowserpersist.xpt
+@RESPATH@/components/webextensions.xpt
@RESPATH@/components/widget.xpt
#ifdef XP_MACOSX
@RESPATH@/components/widget_cocoa.xpt
#endif
@RESPATH@/components/windowcreator.xpt
@RESPATH@/components/windowds.xpt
@RESPATH@/components/windowwatcher.xpt
@RESPATH@/components/xpcom_base.xpt
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -236,16 +236,17 @@
@BINPATH@/components/txmgr.xpt
@BINPATH@/components/uconv.xpt
@BINPATH@/components/unicharutil.xpt
@BINPATH@/components/update.xpt
@BINPATH@/components/uriloader.xpt
@BINPATH@/components/urlformatter.xpt
@BINPATH@/components/webBrowser_core.xpt
@BINPATH@/components/webbrowserpersist.xpt
+@BINPATH@/components/webextensions.xpt
@BINPATH@/components/widget.xpt
@BINPATH@/components/widget_android.xpt
@BINPATH@/components/windowcreator.xpt
@BINPATH@/components/windowds.xpt
@BINPATH@/components/windowwatcher.xpt
@BINPATH@/components/xpcom_base.xpt
@BINPATH@/components/xpcom_system.xpt
@BINPATH@/components/xpcom_components.xpt
--- a/toolkit/components/build/nsToolkitCompsModule.cpp
+++ b/toolkit/components/build/nsToolkitCompsModule.cpp
@@ -39,16 +39,18 @@
#include "mozilla/AddonPathService.h"
#if defined(XP_WIN)
#include "NativeFileWatcherWin.h"
#else
#include "NativeFileWatcherNotSupported.h"
#endif // (XP_WIN)
+#include "nsWebRequestListener.h"
+
#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID)
#define MOZ_HAS_TERMINATOR
#endif
#if defined(MOZ_HAS_TERMINATOR)
#include "nsTerminator.h"
#endif
@@ -120,16 +122,18 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsUpdateP
#endif
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_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
@@ -153,16 +157,17 @@ NS_DEFINE_NAMED_CID(NS_BROWSERSTATUSFILT
#if defined(MOZ_UPDATER) && !defined(MOZ_WIDGET_ANDROID)
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(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 },
@@ -187,16 +192,17 @@ static const Module::CIDEntry kToolkitCI
#if defined(MOZ_UPDATER) && !defined(MOZ_WIDGET_ANDROID)
{ &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 },
{ &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
@@ -223,16 +229,17 @@ static const Module::ContractIDEntry kTo
#if defined(MOZ_UPDATER) && !defined(MOZ_WIDGET_ANDROID)
{ 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 },
{ 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/moz.build
+++ b/toolkit/components/extensions/moz.build
@@ -34,17 +34,20 @@ EXTRA_COMPONENTS += [
'extensions-toolkit.manifest',
]
TESTING_JS_MODULES += [
'ExtensionTestCommon.jsm',
'ExtensionXPCShellUtils.jsm',
]
-DIRS += ['schemas']
+DIRS += [
+ 'schemas',
+ 'webrequest',
+]
JAR_MANIFESTS += ['jar.mn']
BROWSER_CHROME_MANIFESTS += [
'test/browser/browser.ini',
]
MOCHITEST_MANIFESTS += [
--- a/toolkit/components/extensions/test/mochitest/file_WebRequest_page3.html
+++ b/toolkit/components/extensions/test/mochitest/file_WebRequest_page3.html
@@ -1,11 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script>
"use strict";
-window.close();
+window.onload = () => {
+ window.close();
+};
</script>
</head>
</html>
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_basic.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_basic.html
@@ -234,17 +234,17 @@ add_task(function* test_webRequest_heade
add_task(function* test_webRequest_tabId() {
let expect = {
"file_WebRequest_page3.html": {
type: "main_frame",
},
};
extension.sendMessage("set-expected", {expect, origin: location.href});
yield extension.awaitMessage("continue");
- let a = addLink("file_WebRequest_page3.html?trigger=a");
+ let a = addLink(`file_WebRequest_page3.html?trigger=a&nocache=${Math.random()}`);
a.click();
yield extension.awaitMessage("done");
});
add_task(function* test_webRequest_tabId_browser() {
async function background(url) {
let tabId;
browser.test.onMessage.addListener(async (msg, expected) => {
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/webrequest/moz.build
@@ -0,0 +1,21 @@
+# -*- 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 += [
+ 'nsIWebRequestListener.idl',
+]
+
+XPIDL_MODULE = 'webextensions'
+
+EXPORTS += [
+ 'nsWebRequestListener.h',
+]
+
+UNIFIED_SOURCES += [
+ 'nsWebRequestListener.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/webrequest/nsIWebRequestListener.idl
@@ -0,0 +1,28 @@
+/* -*- 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
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/webrequest/nsWebRequestListener.cpp
@@ -0,0 +1,74 @@
+/* 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");
+
+ nsresult rv = mTargetStreamListener->OnStartRequest(request, aCtxt);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ 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");
+
+ nsresult rv = mOrigStreamListener->OnStopRequest(request, aCtxt, aStatus);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ 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;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/webrequest/nsWebRequestListener.h
@@ -0,0 +1,36 @@
+/* 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 "mozilla/Attributes.h"
+
+class nsWebRequestListener final : public nsIWebRequestListener
+ , public nsIStreamListener
+ , public nsIThreadRetargetableStreamListener
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBREQUESTLISTENER
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+
+ nsWebRequestListener() {}
+
+private:
+ ~nsWebRequestListener() {}
+ nsCOMPtr<nsIStreamListener> mOrigStreamListener;
+ nsCOMPtr<nsIStreamListener> mTargetStreamListener;
+};
+
+#endif // nsWebRequestListener_h__
+
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -25,16 +25,19 @@ XPCOMUtils.defineLazyModuleGetter(this,
"resource://gre/modules/ExtensionUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebRequestCommon",
"resource://gre/modules/WebRequestCommon.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebRequestUpload",
"resource://gre/modules/WebRequestUpload.jsm");
XPCOMUtils.defineLazyGetter(this, "ExtensionError", () => ExtensionUtils.ExtensionError);
+let WebRequestListener = Components.Constructor("@mozilla.org/webextensions/webRequestListener;1",
+ "nsIWebRequestListener", "init");
+
function attachToChannel(channel, key, data) {
if (channel instanceof Ci.nsIWritablePropertyBag2) {
let wrapper = {wrappedJSObject: data};
channel.setPropertyAsInterface(key, wrapper);
}
return data;
}
@@ -321,43 +324,33 @@ var ContentPolicyManager = {
this.policyData.delete(id);
this.idMap.delete(callback);
this.policies.delete(id);
},
};
ContentPolicyManager.init();
-function StartStopListener(manager, loadContext) {
+function StartStopListener(manager, channel, loadContext) {
this.manager = manager;
this.loadContext = loadContext;
- this.orig = null;
+ new WebRequestListener(this, channel);
}
StartStopListener.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
Ci.nsIStreamListener]),
onStartRequest: function(request, context) {
this.manager.onStartRequest(request, this.loadContext);
- this.orig.onStartRequest(request, context);
},
onStopRequest(request, context, statusCode) {
- try {
- this.orig.onStopRequest(request, context, statusCode);
- } catch (e) {
- Cu.reportError(e);
- }
this.manager.onStopRequest(request, this.loadContext);
},
-
- onDataAvailable(...args) {
- return this.orig.onDataAvailable(...args);
- },
};
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,
@@ -995,19 +988,17 @@ HttpObserverManager = {
let channelData = getData(channel);
if (this.needTracing) {
// Check whether we've already added a listener to this channel,
// so we don't wind up chaining multiple listeners.
if (!channelData.hasListener && channel instanceof Ci.nsITraceableChannel) {
let responseStatus = channel.responseStatus;
// skip redirections, https://bugzilla.mozilla.org/show_bug.cgi?id=728901#c8
if (responseStatus < 300 || responseStatus >= 400) {
- let listener = new StartStopListener(this, loadContext);
- let orig = channel.setNewListener(listener);
- listener.orig = orig;
+ new StartStopListener(this, channel, loadContext);
channelData.hasListener = true;
}
}
}
if (this.listeners.headersReceived.size) {
this.runChannelListener(channel, loadContext, "headersReceived");
}