Bug 1273138 fix WebRequest for background pages, r=kmag

MozReview-Commit-ID: DEW9anMmKi2

--HG--
extra : rebase_source : 7d82d1000473b2530d6144987a28e35815c11999
This commit is contained in:
Shane Caraveo 2016-11-02 09:30:50 -07:00
parent 5dad9554f6
commit cb4c301312
12 changed files with 261 additions and 29 deletions

View File

@ -75,14 +75,8 @@ extensions.on("page-shutdown", (type, context) => {
}
});
extensions.on("fill-browser-data", (type, browser, data, result) => {
let tabId = TabManager.getBrowserId(browser);
if (tabId == -1) {
result.cancel = true;
return;
}
data.tabId = tabId;
extensions.on("fill-browser-data", (type, browser, data) => {
data.tabId = browser ? TabManager.getBrowserId(browser) : -1;
});
/* eslint-enable mozilla/balanced-listeners */

View File

@ -109,11 +109,6 @@ function WebNavigationEventManager(context, eventName) {
return;
}
let tabId = TabManager.getBrowserId(data.browser);
if (tabId == -1) {
return;
}
let data2 = {
url: data.url,
timeStamp: Date.now(),
@ -126,9 +121,8 @@ function WebNavigationEventManager(context, eventName) {
}
// Fills in tabId typically.
let result = {};
extensions.emit("fill-browser-data", data.browser, data2, result);
if (result.cancel) {
extensions.emit("fill-browser-data", data.browser, data2);
if (data2.tabId < 0) {
return;
}

View File

@ -23,12 +23,9 @@ function WebRequestEventManager(context, eventName) {
let name = `webRequest.${eventName}`;
let register = (callback, filter, info) => {
let listener = data => {
if (!data.browser) {
return;
}
let tabId = TabManager.getBrowserId(data.browser);
if (tabId == -1) {
// Prevent listening in on requests originating from system principal to
// prevent tinkering with OCSP, app and addon updates, etc.
if (data.isSystemPrincipal) {
return;
}
@ -52,12 +49,7 @@ function WebRequestEventManager(context, eventName) {
data2.ip = data.ip;
}
// Fills in tabId typically.
let result = {};
extensions.emit("fill-browser-data", data.browser, data2, result);
if (result.cancel) {
return;
}
extensions.emit("fill-browser-data", data.browser, data2);
let optional = ["requestHeaders", "responseHeaders", "statusCode", "statusLine", "error", "redirectUrl",
"requestBody"];

View File

@ -8,6 +8,8 @@ module.exports = { // eslint-disable-line no-undef
},
"globals": {
"ChromeWorker": false,
"onmessage": true,
"sendAsyncMessage": false,
"waitForLoad": true,
@ -15,6 +17,7 @@ module.exports = { // eslint-disable-line no-undef
"ExtensionTestUtils": false,
"NetUtil": true,
"webrequest_test": false,
"XPCOMUtils": true,
},
};

View File

@ -3,6 +3,8 @@ support-files =
chrome_head.js
head.js
file_sample.html
webrequest_chromeworker.js
webrequest_test.jsm
tags = webextensions
[test_chrome_ext_background_debug_global.html]
@ -27,3 +29,5 @@ skip-if = os != "mac" && os != "linux"
[test_chrome_ext_storage_cleanup.html]
[test_chrome_ext_idle.html]
[test_chrome_ext_downloads_saveAs.html]
[test_chrome_ext_webrequest_background_events.html]
skip-if = os == 'android' # webrequest api unsupported (bug 1258975).

View File

@ -35,6 +35,7 @@ support-files =
file_ext_test_api_injection.js
file_permission_xhr.html
file_teardown_test.js
webrequest_worker.js
tags = webextensions
[test_clipboard.html]
@ -93,6 +94,8 @@ skip-if = (os == 'android') # Bug 1258975 on android.
skip-if = (os == 'android') # Bug 1258975 on android.
[test_ext_webrequest.html]
skip-if = os == 'android' # webrequest api unsupported (bug 1258975).
[test_ext_webrequest_background_events.html]
skip-if = os == 'android' # webrequest api unsupported (bug 1258975).
[test_ext_webrequest_upload.html]
skip-if = os == 'android' # webrequest api unsupported (bug 1258975).
[test_ext_webnavigation.html]

View File

@ -0,0 +1,96 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for simple WebExtension</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="chrome_head.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";
Cu.import(SimpleTest.getTestFileURL("webrequest_test.jsm"));
let {testFetch, testXHR} = webrequest_test;
// Here we test that any requests originating from a system principal are not
// accessible through WebRequest. text_ext_webrequest_background_events tests
// non-system principal requests.
let testExtension = {
manifest: {
permissions: [
"webRequest",
"<all_urls>",
],
},
background() {
let eventNames = [
"onBeforeRequest",
"onBeforeSendHeaders",
"onSendHeaders",
"onHeadersReceived",
"onResponseStarted",
"onCompleted",
];
function listener(name, details) {
// If we get anything, we failed. Removing the system principal check
// in ext-webrequest triggers this failure.
browser.test.fail(`recieved ${name}`);
}
for (let name of eventNames) {
browser.webRequest[name].addListener(
listener.bind(null, name),
{urls: ["https://example.com/*"]}
);
}
},
};
add_task(function* test_webRequest_chromeworker_events() {
let extension = ExtensionTestUtils.loadExtension(testExtension);
yield extension.startup();
yield new Promise(resolve => {
let worker = new ChromeWorker("webrequest_chromeworker.js");
worker.onmessage = event => {
ok("chrome worker fetch finished");
resolve();
};
worker.postMessage("go");
});
yield extension.unload();
});
add_task(function* test_webRequest_chromepage_events() {
let extension = ExtensionTestUtils.loadExtension(testExtension);
yield extension.startup();
yield new Promise(resolve => {
fetch("https://example.com/example.txt").then(() => {
ok("test page loaded");
resolve();
});
});
yield extension.unload();
});
add_task(function* test_webRequest_jsm_events() {
let extension = ExtensionTestUtils.loadExtension(testExtension);
yield extension.startup();
yield testFetch("https://example.com/example.txt").then(() => {
ok("fetch page loaded");
});
yield testXHR("https://example.com/example.txt").then(() => {
ok("xhr page loaded");
});
yield extension.unload();
});
</script>
</body>
</html>

View File

@ -0,0 +1,109 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for simple WebExtension</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";
add_task(function* test_webRequest_serviceworker_events() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.serviceWorkers.testing.enabled", true]],
});
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: [
"webRequest",
"<all_urls>",
],
},
background() {
let eventNames = new Set([
"onBeforeRequest",
"onBeforeSendHeaders",
"onSendHeaders",
"onHeadersReceived",
"onResponseStarted",
"onCompleted",
]);
function listener(name, details) {
browser.test.assertTrue(eventNames.has(name), `recieved ${name}`);
eventNames.delete(name);
if (eventNames.size == 0) {
browser.test.sendMessage("done");
}
}
for (let name of eventNames) {
browser.webRequest[name].addListener(
listener.bind(null, name),
{urls: ["https://example.com/*"]}
);
}
},
});
yield extension.startup();
let registration = yield navigator.serviceWorker.register("webrequest_worker.js", {scope: "."});
yield extension.awaitMessage("done");
yield registration.unregister();
yield extension.unload();
});
add_task(function* test_webRequest_background_events() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: [
"webRequest",
"<all_urls>",
],
},
background() {
let eventNames = new Set([
"onBeforeRequest",
"onBeforeSendHeaders",
"onSendHeaders",
"onHeadersReceived",
"onResponseStarted",
"onCompleted",
]);
function listener(name, details) {
browser.test.assertTrue(eventNames.has(name), `recieved ${name}`);
eventNames.delete(name);
}
for (let name of eventNames) {
browser.webRequest[name].addListener(
listener.bind(null, name),
{urls: ["https://example.com/*"]}
);
}
fetch("https://example.com/example.txt").then(() => {
browser.test.assertEq(0, eventNames.size, "messages recieved");
browser.test.sendMessage("done");
}, () => {
browser.test.fail("fetch recieved");
browser.test.sendMessage("done");
});
},
});
yield extension.startup();
yield extension.awaitMessage("done");
yield extension.unload();
});
</script>
</body>
</html>

View File

@ -0,0 +1,8 @@
"use strict";
onmessage = function(event) {
fetch("https://example.com/example.txt").then(() => {
postMessage("Done!");
});
};

View File

@ -0,0 +1,22 @@
"use strict";
this.EXPORTED_SYMBOLS = ["webrequest_test"];
Components.utils.importGlobalProperties(["fetch", "XMLHttpRequest"]);
this.webrequest_test = {
testFetch(url) {
return fetch(url);
},
testXHR(url) {
return new Promise(resolve => {
let xhr = new XMLHttpRequest();
xhr.open("HEAD", url);
xhr.onload = () => {
resolve();
};
xhr.send();
});
},
};

View File

@ -0,0 +1,3 @@
"use strict";
fetch("https://example.com/example.txt");

View File

@ -545,7 +545,7 @@ HttpObserverManager = {
if (loadInfo) {
let originPrincipal = loadInfo.triggeringPrincipal || loadInfo.loadingPrincipal;
if (originPrincipal && originPrincipal.URI) {
if (originPrincipal.URI) {
commonData.originUrl = originPrincipal.URI.spec;
}
Object.assign(commonData, {
@ -553,6 +553,10 @@ HttpObserverManager = {
loadInfo.frameOuterWindowID : loadInfo.outerWindowID,
parentWindowId: loadInfo.frameOuterWindowID ?
loadInfo.outerWindowID : loadInfo.parentOuterWindowID,
isSystemPrincipal: Services.scriptSecurityManager
.isSystemPrincipal(loadInfo.triggeringPrincipal) ||
Services.scriptSecurityManager
.isSystemPrincipal(loadInfo.loadingPrincipal),
});
} else {
Object.assign(commonData, {