1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* import-globals-from head_cache.js */
8 /* import-globals-from head_cookies.js */
9 /* import-globals-from head_channels.js */
10 /* import-globals-from head_servers.js */
11 /* import-globals-from head_websocket.js */
13 var CC
= Components
.Constructor
;
14 const ServerSocket
= CC(
15 "@mozilla.org/network/server-socket;1",
20 let certdb
= Cc
["@mozilla.org/security/x509certdb;1"].getService(
25 Services
.prefs
.setBoolPref("network.http.http2.websockets", true);
28 registerCleanupFunction(() => {
29 Services
.prefs
.clearUserPref("network.http.http2.websockets");
32 // TLS handshake to the end server fails - no proxy
33 async
function test_tls_fail_on_direct_ws_server_handshake() {
34 // no cert and no proxy
35 let wss
= new NodeWebSocketServer();
37 registerCleanupFunction(async () => {
41 Assert
.notEqual(wss
.port(), null);
43 let chan
= makeWebSocketChan();
44 let url
= `wss://localhost:${wss.port()}`;
45 const msg
= "test tls handshake with direct ws server fails";
46 let [status
] = await
openWebSocketChannelPromise(chan
, url
, msg
);
48 // can be two errors, seems to be a race between:
49 // * overwriting the WebSocketChannel status with NS_ERROR_NET_RESET and
50 // * getting the original 805A1FF3 // SEC_ERROR_UNKNOWN_ISSUER
51 if (status
== 2152398930) {
52 Assert
.equal(status
, 0x804b0052); // NS_ERROR_NET_INADEQUATE_SECURITY
54 // occasionally this happens
55 Assert
.equal(status
, 0x804b0057); // NS_ERROR_WEBSOCKET_CONNECTION_REFUSED
59 // TLS handshake to proxy fails
60 async
function test_tls_fail_on_proxy_handshake() {
61 // we have ws cert, but no proxy cert
62 addCertFromFile(certdb
, "http2-ca.pem", "CTu,u,u");
64 let proxy
= new NodeHTTPSProxyServer();
67 let wss
= new NodeWebSocketServer();
70 registerCleanupFunction(async () => {
75 Assert
.notEqual(wss
.port(), null);
77 let chan
= makeWebSocketChan();
78 let url
= `wss://localhost:${wss.port()}`;
79 const msg
= "test tls failure on proxy handshake";
80 let [status
] = await
openWebSocketChannelPromise(chan
, url
, msg
);
82 // see above test for details on why 2 cases here
83 if (status
== 2152398930) {
84 Assert
.equal(status
, 0x804b0052); // NS_ERROR_NET_INADEQUATE_SECURITY
86 Assert
.equal(status
, 0x804b0057); // NS_ERROR_WEBSOCKET_CONNECTION_REFUSED
92 // the ws server does not respond (closed port)
93 async
function test_non_responsive_ws_server_closed_port() {
94 // ws server cert already added in previous test
96 // no ws server listening (closed port)
97 let randomPort
= 666; // "random" port
98 let chan
= makeWebSocketChan();
99 let url
= `wss://localhost:${randomPort}`;
100 const msg
= "test non-responsive ws server closed port";
101 let [status
] = await
openWebSocketChannelPromise(chan
, url
, msg
);
102 Assert
.equal(status
, 0x804b0057); // NS_ERROR_WEBSOCKET_CONNECTION_REFUSED
105 // no ws response from server (ie. no ws server, use tcp server to open port)
106 async
function test_non_responsive_ws_server_open_port() {
107 // we are expecting the timeout in this test, so lets shorten to 1s
108 Services
.prefs
.setIntPref("network.websocket.timeout.open", 1);
110 // ws server cert already added in previous test
112 // use a tcp server to test open port, not a ws server
113 var server
= ServerSocket(-1, true, -1); // port, loopback, default-backlog
114 var port
= server
.port
;
115 info("server: listening on " + server
.port
);
116 server
.asyncListen({});
118 // queue cleanup after all tests
119 registerCleanupFunction(() => {
121 Services
.prefs
.clearUserPref("network.websocket.timeout.open");
125 let chan
= makeWebSocketChan();
126 let url
= `wss://localhost:${port}`;
127 const msg
= "test non-responsive ws server open port";
128 let [status
] = await
openWebSocketChannelPromise(chan
, url
, msg
);
129 Assert
.equal(status
, Cr
.NS_ERROR_NET_TIMEOUT_EXTERNAL
); // we will timeout
130 Services
.prefs
.clearUserPref("network.websocket.timeout.open");
133 // proxy does not respond
134 async
function test_proxy_doesnt_respond() {
135 Services
.prefs
.setIntPref("network.websocket.timeout.open", 1);
136 Services
.prefs
.setBoolPref("network.http.http2.websockets", false);
137 // ws cert added in previous test, add proxy cert
138 addCertFromFile(certdb
, "http2-ca.pem", "CTu,u,u");
139 addCertFromFile(certdb
, "proxy-ca.pem", "CTu,u,u");
141 info("spinning up proxy");
142 let proxy
= new NodeHTTPSProxyServer();
145 // route traffic through non-existant proxy
146 const pps
= Cc
["@mozilla.org/network/protocol-proxy-service;1"].getService();
147 let randomPort
= proxy
.port() + 1;
148 var filter
= new NodeProxyFilter(
154 pps
.registerFilter(filter
, 10);
156 registerCleanupFunction(async () => {
158 Services
.prefs
.clearUserPref("network.websocket.timeout.open");
161 // setup the websocket server
162 info("spinning up websocket server");
163 let wss
= new NodeWebSocketServer();
165 registerCleanupFunction(() => {
168 Assert
.notEqual(wss
.port(), null);
169 await wss
.registerMessageHandler((data
, ws
) => {
173 info("creating and connecting websocket");
174 let url
= `wss://localhost:${wss.port()}`;
175 let conn
= new WebSocketConnection();
176 conn
.open(url
); // do not await, we don't expect a fully opened channel
179 info("checking proxy info");
180 let proxyInfoPromise
= conn
.getProxyInfo();
181 let proxyInfo
= await proxyInfoPromise
;
182 Assert
.equal(proxyInfo
.type
, "https"); // let's be sure that failure is not "direct"
184 // we fail to connect via proxy, as expected
185 let { status
} = await conn
.finished();
186 info("stats: " + status
);
187 Assert
.equal(status
, 0x804b0057); // NS_ERROR_WEBSOCKET_CONNECTION_REFUSED
190 add_task(test_tls_fail_on_direct_ws_server_handshake
);
191 add_task(test_tls_fail_on_proxy_handshake
);
192 add_task(test_non_responsive_ws_server_closed_port
);
193 add_task(test_non_responsive_ws_server_open_port
);
194 add_task(test_proxy_doesnt_respond
);