Bug 1367478 support websocket ws/wss protocol in matchpattern, r?kmag
MozReview-Commit-ID: 6cnRyWRnRzT
--- a/toolkit/components/extensions/MatchPattern.cpp
+++ b/toolkit/components/extensions/MatchPattern.cpp
@@ -243,19 +243,19 @@ CookieInfo::RawHost() const
return mRawHost;
}
/*****************************************************************************
* MatchPattern
*****************************************************************************/
-const char* PERMITTED_SCHEMES[] = {"http", "https", "file", "ftp", "data", nullptr};
+const char* PERMITTED_SCHEMES[] = {"http", "https", "ws", "wss", "file", "ftp", "data", nullptr};
-const char* WILDCARD_SCHEMES[] = {"http", "https", nullptr};
+const char* WILDCARD_SCHEMES[] = {"http", "https", "ws", "wss", nullptr};
/* static */ already_AddRefed<MatchPattern>
MatchPattern::Constructor(dom::GlobalObject& aGlobal,
const nsAString& aPattern,
const MatchPatternOptions& aOptions,
ErrorResult& aRv)
{
RefPtr<MatchPattern> pattern = new MatchPattern(aGlobal.GetAsSupports());
--- a/toolkit/components/extensions/schemas/manifest.json
+++ b/toolkit/components/extensions/schemas/manifest.json
@@ -304,17 +304,17 @@
"id": "MatchPattern",
"choices": [
{
"type": "string",
"enum": ["<all_urls>"]
},
{
"type": "string",
- "pattern": "^(https?|file|ftp|\\*)://(\\*|\\*\\.[^*/]+|[^*/]+)/.*$"
+ "pattern": "^(https?|wss?|file|ftp|\\*)://(\\*|\\*\\.[^*/]+|[^*/]+)/.*$"
},
{
"type": "string",
"pattern": "^file:///.*$"
}
]
},
{
--- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini
@@ -109,13 +109,14 @@ skip-if = os == 'android'
[test_ext_webrequest_background_events.html]
[test_ext_webrequest_basic.html]
[test_ext_webrequest_filter.html]
[test_ext_webrequest_frameId.html]
[test_ext_webrequest_suspend.html]
[test_ext_webrequest_upload.html]
skip-if = os == 'android' # Currently fails in emulator tests
[test_ext_webrequest_permission.html]
+[test_ext_webrequest_websocket.html]
[test_ext_webnavigation.html]
[test_ext_webnavigation_filters.html]
[test_ext_window_postMessage.html]
[test_ext_subframes_privileges.html]
[test_ext_xhr_capabilities.html]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_websocket.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+ <title>Basic websocket test</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" />
+
+<script class="testbody" type="text/javascript">
+"use strict";
+
+add_task(async function test_webSocket() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "permissions": [
+ "webRequest",
+ "webRequestBlocking",
+ "<all_urls>",
+ ],
+ },
+ background() {
+ browser.webRequest.onBeforeRequest.addListener(details => {
+ browser.test.assertEq("ws:", new URL(details.url).protocol, "ws protocol worked");
+ browser.test.notifyPass("websocket");
+ }, {urls: ["*://mochi.test/*"]}, ["blocking"]);
+
+ browser.test.onMessage.addListener(msg => {
+ let ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket_hello");
+ ws.onopen = (e) => {
+ ws.send("data");
+ };
+ ws.onclose = (e) => {};
+ ws.onerror = (e) => {};
+ ws.onmessage = (e) => {
+ ws.close();
+ };
+ });
+ browser.test.sendMessage("ready");
+ },
+ });
+ await extension.startup();
+ await extension.awaitMessage("ready");
+ extension.sendMessage("go");
+ await extension.awaitFinish();
+ await extension.unload();
+});
+
+</script>
+</head>
+<body>
+</body>
+</html>
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -675,16 +675,20 @@ HttpObserverManager = {
}
} else if (lastActivity !== this.GOOD_LAST_ACTIVITY &&
lastActivity !== nsIHttpActivityObserver.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE) {
channelData.lastActivity = activitySubtype;
}
},
shouldRunListener(policyType, uri, filter) {
+ // force the protocol to be ws again.
+ if (policyType == "websocket" && uri.startsWith("http")) {
+ uri = `ws${uri.substring(4)}`;
+ }
return WebRequestCommon.typeMatches(policyType, filter.types) &&
WebRequestCommon.urlMatches(uri, filter.urls);
},
get resultsMap() {
delete this.resultsMap;
this.resultsMap = new Map(Object.keys(Cr).map(name => [Cr[name], name]));
return this.resultsMap;
@@ -756,16 +760,21 @@ HttpObserverManager = {
browser: loadContext && loadContext.topFrameElement,
type: WebRequestCommon.typeForPolicyType(policyType),
fromCache: getData(channel).fromCache,
// Defaults for a top level request
windowId: 0,
parentWindowId: -1,
};
+ // force the protocol to be ws again.
+ if (data.type == "websocket" && data.url.startsWith("http")) {
+ data.url = `ws${data.url.substring(4)}`;
+ }
+
if (loadInfo) {
let originPrincipal = loadInfo.triggeringPrincipal;
if (originPrincipal.URI) {
data.originUrl = originPrincipal.URI.spec;
}
let docPrincipal = loadInfo.loadingPrincipal;
if (docPrincipal && docPrincipal.URI) {
data.documentUrl = docPrincipal.URI.spec;