Files
tubestation/toolkit/components/extensions/parent/ext-webRequest.js
Shane Caraveo 32e3a1a959 Bug 1322748 add securityInfo to webRequest listeners, r=keeler,rpl
MozReview-Commit-ID: Hen1tl1RWTC
2018-05-23 14:36:19 -04:00

139 lines
4.1 KiB
JavaScript

"use strict";
// This file expects tabTracker to be defined in the global scope (e.g.
// by ext-utils.js).
/* global tabTracker */
ChromeUtils.defineModuleGetter(this, "WebRequest",
"resource://gre/modules/WebRequest.jsm");
// The guts of a WebRequest event handler. Takes care of converting
// |details| parameter when invoking listeners.
function registerEvent(extension, eventName, fire, filter, info, tabParent = null) {
let listener = async data => {
let browserData = {tabId: -1, windowId: -1};
if (data.browser) {
browserData = tabTracker.getBrowserData(data.browser);
}
if (filter.tabId != null && browserData.tabId != filter.tabId) {
return;
}
if (filter.windowId != null && browserData.windowId != filter.windowId) {
return;
}
let event = data.serialize(eventName);
event.tabId = browserData.tabId;
if (data.registerTraceableChannel) {
if (fire.wakeup) {
await fire.wakeup();
}
data.registerTraceableChannel(extension.policy, tabParent);
}
return fire.sync(event);
};
let filter2 = {};
if (filter.urls) {
let perms = new MatchPatternSet([...extension.whiteListedHosts.patterns,
...extension.optionalOrigins.patterns]);
filter2.urls = new MatchPatternSet(filter.urls);
if (!perms.overlapsAll(filter2.urls)) {
Cu.reportError("The webRequest.addListener filter doesn't overlap with host permissions.");
}
}
if (filter.types) {
filter2.types = filter.types;
}
if (filter.tabId) {
filter2.tabId = filter.tabId;
}
if (filter.windowId) {
filter2.windowId = filter.windowId;
}
let blockingAllowed = extension.hasPermission("webRequestBlocking");
let info2 = [];
if (info) {
for (let desc of info) {
if (desc == "blocking" && !blockingAllowed) {
Cu.reportError("Using webRequest.addListener with the blocking option " +
"requires the 'webRequestBlocking' permission.");
} else {
info2.push(desc);
}
}
}
let listenerDetails = {
addonId: extension.id,
extension: extension.policy,
blockingAllowed,
};
WebRequest[eventName].addListener(
listener, filter2, info2,
listenerDetails);
return {
unregister: () => { WebRequest[eventName].removeListener(listener); },
convert(_fire, context) {
fire = _fire;
tabParent = context.xulBrowser.frameLoader.tabParent;
},
};
}
function makeWebRequestEvent(context, name) {
return new EventManager({
context,
name: `webRequest.${name}`,
persistent: {
module: "webRequest",
event: name,
},
register: (fire, filter, info) => {
return registerEvent(context.extension, name, fire, filter, info,
context.xulBrowser.frameLoader.tabParent).unregister;
},
}).api();
}
this.webRequest = class extends ExtensionAPI {
primeListener(extension, event, fire, params) {
return registerEvent(extension, event, fire, ...params);
}
getAPI(context) {
return {
webRequest: {
onBeforeRequest: makeWebRequestEvent(context, "onBeforeRequest"),
onBeforeSendHeaders: makeWebRequestEvent(context, "onBeforeSendHeaders"),
onSendHeaders: makeWebRequestEvent(context, "onSendHeaders"),
onHeadersReceived: makeWebRequestEvent(context, "onHeadersReceived"),
onAuthRequired: makeWebRequestEvent(context, "onAuthRequired"),
onBeforeRedirect: makeWebRequestEvent(context, "onBeforeRedirect"),
onResponseStarted: makeWebRequestEvent(context, "onResponseStarted"),
onErrorOccurred: makeWebRequestEvent(context, "onErrorOccurred"),
onCompleted: makeWebRequestEvent(context, "onCompleted"),
getSecurityInfo: function(requestId, options = {}) {
return WebRequest.getSecurityInfo({
id: requestId,
extension: context.extension.policy,
tabParent: context.xulBrowser.frameLoader.tabParent,
options,
});
},
handlerBehaviorChanged: function() {
// TODO: Flush all caches.
},
},
};
}
};