Skip to content

Commit 347aab6

Browse files
authored
[feature] Allow http and https schemes (#2162)
Allow HTTP(S) URLs to be used in the WebSocket constructor. They are immediately converted to the ws and wss schemes. Refs: whatwg/websockets#45
1 parent 79dab96 commit 347aab6

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

lib/websocket.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,24 +667,30 @@ function initAsClient(websocket, address, protocols, options) {
667667

668668
if (address instanceof URL) {
669669
parsedUrl = address;
670-
websocket._url = address.href;
671670
} else {
672671
try {
673672
parsedUrl = new URL(address);
674673
} catch (e) {
675674
throw new SyntaxError(`Invalid URL: ${address}`);
676675
}
676+
}
677677

678-
websocket._url = address;
678+
if (parsedUrl.protocol === 'http:') {
679+
parsedUrl.protocol = 'ws:';
680+
} else if (parsedUrl.protocol === 'https:') {
681+
parsedUrl.protocol = 'wss:';
679682
}
680683

684+
websocket._url = parsedUrl.href;
685+
681686
const isSecure = parsedUrl.protocol === 'wss:';
682687
const isIpcUrl = parsedUrl.protocol === 'ws+unix:';
683688
let invalidUrlMessage;
684689

685690
if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {
686691
invalidUrlMessage =
687-
'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"';
692+
'The URL\'s protocol must be one of "ws:", "wss:", ' +
693+
'"http:", "https", or "ws+unix:"';
688694
} else if (isIpcUrl && !parsedUrl.pathname) {
689695
invalidUrlMessage = "The URL's pathname is empty";
690696
} else if (parsedUrl.hash) {

test/websocket.test.js

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,16 @@ describe('WebSocket', () => {
3636
);
3737

3838
assert.throws(
39-
() => new WebSocket('https://websocket-echo.com'),
40-
/^SyntaxError: The URL's protocol must be one of "ws:", "wss:", or "ws\+unix:"$/
39+
() => new WebSocket('bad-scheme://websocket-echo.com'),
40+
(err) => {
41+
assert.strictEqual(
42+
err.message,
43+
'The URL\'s protocol must be one of "ws:", "wss:", ' +
44+
'"http:", "https", or "ws+unix:"'
45+
);
46+
47+
return true;
48+
}
4149
);
4250

4351
assert.throws(
@@ -72,6 +80,30 @@ describe('WebSocket', () => {
7280
const ws = new WebSocket(new URL('ws://[::1]'), { agent });
7381
});
7482

83+
it('allows the http scheme', (done) => {
84+
const agent = new CustomAgent();
85+
86+
agent.addRequest = (req, opts) => {
87+
assert.strictEqual(opts.host, 'localhost');
88+
assert.strictEqual(opts.port, 80);
89+
done();
90+
};
91+
92+
const ws = new WebSocket('http://localhost', { agent });
93+
});
94+
95+
it('allows the https scheme', (done) => {
96+
const agent = new https.Agent();
97+
98+
agent.addRequest = (req, opts) => {
99+
assert.strictEqual(opts.host, 'localhost');
100+
assert.strictEqual(opts.port, 443);
101+
done();
102+
};
103+
104+
const ws = new WebSocket('https://localhost', { agent });
105+
});
106+
75107
describe('options', () => {
76108
it('accepts the `options` object as 3rd argument', () => {
77109
const agent = new http.Agent();
@@ -539,10 +571,18 @@ describe('WebSocket', () => {
539571
});
540572

541573
it('exposes the server url', () => {
542-
const url = 'ws://localhost';
543-
const ws = new WebSocket(url, { agent: new CustomAgent() });
574+
const schemes = new Map([
575+
['ws', 'ws'],
576+
['wss', 'wss'],
577+
['http', 'ws'],
578+
['https', 'wss']
579+
]);
580+
581+
for (const [key, value] of schemes) {
582+
const ws = new WebSocket(`${key}://localhost/`, { lookup() {} });
544583

545-
assert.strictEqual(ws.url, url);
584+
assert.strictEqual(ws.url, `${value}://localhost/`);
585+
}
546586
});
547587
});
548588
});
@@ -1174,7 +1214,9 @@ describe('WebSocket', () => {
11741214

11751215
it('emits an error if the redirect URL is invalid (2/2)', (done) => {
11761216
server.once('upgrade', (req, socket) => {
1177-
socket.end('HTTP/1.1 302 Found\r\nLocation: http://localhost\r\n\r\n');
1217+
socket.end(
1218+
'HTTP/1.1 302 Found\r\nLocation: bad-scheme://localhost\r\n\r\n'
1219+
);
11781220
});
11791221

11801222
const ws = new WebSocket(`ws://localhost:${server.address().port}`, {
@@ -1186,7 +1228,8 @@ describe('WebSocket', () => {
11861228
assert.ok(err instanceof SyntaxError);
11871229
assert.strictEqual(
11881230
err.message,
1189-
'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"'
1231+
'The URL\'s protocol must be one of "ws:", "wss:", ' +
1232+
'"http:", "https", or "ws+unix:"'
11901233
);
11911234
assert.strictEqual(ws._redirects, 1);
11921235

0 commit comments

Comments
 (0)