Skip to content

Commit 53a8888

Browse files
authored
[feature] Allow the createConnection option (#2219)
Allow passing in a custom `createConnection` function.
1 parent b119b41 commit 53a8888

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

Diff for: doc/ws.md

+4
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ This class represents a WebSocket. It extends the `EventEmitter`.
304304
`'ping'`, and `'pong'` events can be emitted multiple times in the same
305305
tick. To improve compatibility with the WHATWG standard, the default value
306306
is `false`. Setting it to `true` improves performance slightly.
307+
- `createConnection` {Function} An alternative function to use in place of
308+
`tls.createConnection` or `net.createConnection`. This can be used to
309+
manually control exactly how the connection to the server is made, or to
310+
make a connection over an existing Duplex stream obtained elsewhere.
307311
- `finishRequest` {Function} A function which can be used to customize the
308312
headers of each HTTP request before it is sent. See description below.
309313
- `followRedirects` {Boolean} Whether or not to follow redirects. Defaults to

Diff for: lib/websocket.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,8 @@ module.exports = WebSocket;
628628
* times in the same tick
629629
* @param {Boolean} [options.autoPong=true] Specifies whether or not to
630630
* automatically send a pong in response to a ping
631+
* @param {Function} [options.createConnection] An alternative function to use
632+
* in place of `tls.createConnection` or `net.createConnection`.
631633
* @param {Function} [options.finishRequest] A function which can be used to
632634
* customize the headers of each http request before it is sent
633635
* @param {Boolean} [options.followRedirects=false] Whether or not to follow
@@ -660,8 +662,8 @@ function initAsClient(websocket, address, protocols, options) {
660662
perMessageDeflate: true,
661663
followRedirects: false,
662664
maxRedirects: 10,
663-
...options,
664665
createConnection: undefined,
666+
...options,
665667
socketPath: undefined,
666668
hostname: undefined,
667669
protocol: undefined,
@@ -732,7 +734,8 @@ function initAsClient(websocket, address, protocols, options) {
732734
const protocolSet = new Set();
733735
let perMessageDeflate;
734736

735-
opts.createConnection = isSecure ? tlsConnect : netConnect;
737+
opts.createConnection =
738+
opts.createConnection || (isSecure ? tlsConnect : netConnect);
736739
opts.defaultPort = opts.defaultPort || defaultPort;
737740
opts.port = parsedUrl.port || defaultPort;
738741
opts.host = parsedUrl.hostname.startsWith('[')

Diff for: test/websocket.test.js

+28
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,34 @@ describe('WebSocket', () => {
12241224
});
12251225
});
12261226

1227+
it('honors the `createConnection` option', (done) => {
1228+
const wss = new WebSocket.Server({ noServer: true, path: '/foo' });
1229+
1230+
server.once('upgrade', (req, socket, head) => {
1231+
assert.strictEqual(req.headers.host, 'google.com:22');
1232+
wss.handleUpgrade(req, socket, head, NOOP);
1233+
});
1234+
1235+
const ws = new WebSocket('ws://google.com:22/foo', {
1236+
createConnection: (options) => {
1237+
assert.strictEqual(options.host, 'google.com');
1238+
assert.strictEqual(options.port, '22');
1239+
1240+
// Ignore the invalid host address, and connect to the server manually:
1241+
return net.createConnection({
1242+
host: 'localhost',
1243+
port: server.address().port
1244+
});
1245+
}
1246+
});
1247+
1248+
ws.on('open', () => {
1249+
assert.strictEqual(ws.url, 'ws://google.com:22/foo');
1250+
ws.on('close', () => done());
1251+
ws.close();
1252+
});
1253+
});
1254+
12271255
it('emits an error if the redirect URL is invalid (1/2)', (done) => {
12281256
server.once('upgrade', (req, socket) => {
12291257
socket.end('HTTP/1.1 302 Found\r\nLocation: ws://\r\n\r\n');

0 commit comments

Comments
 (0)