Skip to content

Commit 73dec34

Browse files
committed
[fix] Do not throw if the redirect URL is invalid
If the redirect URL is invalid, then emit the error instead of throwing it, otherwise there is no way to handle it.
1 parent 2d968a6 commit 73dec34

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-5
lines changed

lib/websocket.js

+30-5
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,14 @@ function initAsClient(websocket, address, protocols, options) {
618618
const isUnixSocket = parsedUrl.protocol === 'ws+unix:';
619619

620620
if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) {
621-
throw new Error(`Invalid URL: ${websocket.url}`);
621+
const err = new Error(`Invalid URL: ${websocket.url}`);
622+
623+
if (websocket._redirects === 0) {
624+
throw err;
625+
} else {
626+
emitErrorAndClose(websocket, err);
627+
return;
628+
}
622629
}
623630

624631
const isSecure =
@@ -687,9 +694,7 @@ function initAsClient(websocket, address, protocols, options) {
687694
if (req === null || req.aborted) return;
688695

689696
req = websocket._req = null;
690-
websocket._readyState = WebSocket.CLOSING;
691-
websocket.emit('error', err);
692-
websocket.emitClose();
697+
emitErrorAndClose(websocket, err);
693698
});
694699

695700
req.on('response', (res) => {
@@ -709,7 +714,14 @@ function initAsClient(websocket, address, protocols, options) {
709714

710715
req.abort();
711716

712-
const addr = new URL(location, address);
717+
let addr;
718+
719+
try {
720+
addr = new URL(location, address);
721+
} catch (err) {
722+
emitErrorAndClose(websocket, err);
723+
return;
724+
}
713725

714726
initAsClient(websocket, addr, protocols, options);
715727
} else if (!websocket.emit('unexpected-response', req, res)) {
@@ -811,6 +823,19 @@ function initAsClient(websocket, address, protocols, options) {
811823
});
812824
}
813825

826+
/**
827+
* Emit the `'error'` and `'close'` event.
828+
*
829+
* @param {WebSocket} websocket The WebSocket instance
830+
* @param {Error} The error to emit
831+
* @private
832+
*/
833+
function emitErrorAndClose(websocket, err) {
834+
websocket._readyState = WebSocket.CLOSING;
835+
websocket.emit('error', err);
836+
websocket.emitClose();
837+
}
838+
814839
/**
815840
* Create a `net.Socket` and initiate a connection.
816841
*

test/websocket.test.js

+45
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,51 @@ describe('WebSocket', () => {
941941
ws.on('close', () => done());
942942
});
943943
});
944+
945+
it('emits an error if the redirect URL is invalid (1/2)', (done) => {
946+
const onUpgrade = (req, socket) => {
947+
socket.end('HTTP/1.1 302 Found\r\nLocation: ws://\r\n\r\n');
948+
};
949+
950+
server.on('upgrade', onUpgrade);
951+
952+
const ws = new WebSocket(`ws://localhost:${server.address().port}`, {
953+
followRedirects: true
954+
});
955+
956+
ws.on('open', () => done(new Error("Unexpected 'open' event")));
957+
ws.on('error', (err) => {
958+
assert.ok(err instanceof Error);
959+
assert.ok(/Invalid URL/.test(err.message));
960+
assert.strictEqual(err.input, 'ws://');
961+
assert.strictEqual(ws._redirects, 1);
962+
963+
server.removeListener('upgrade', onUpgrade);
964+
ws.on('close', () => done());
965+
});
966+
});
967+
968+
it('emits an error if the redirect URL is invalid (2/2)', (done) => {
969+
const onUpgrade = (req, socket) => {
970+
socket.end('HTTP/1.1 302 Found\r\nLocation: ws+unix:\r\n\r\n');
971+
};
972+
973+
server.on('upgrade', onUpgrade);
974+
975+
const ws = new WebSocket(`ws://localhost:${server.address().port}`, {
976+
followRedirects: true
977+
});
978+
979+
ws.on('open', () => done(new Error("Unexpected 'open' event")));
980+
ws.on('error', (err) => {
981+
assert.ok(err instanceof Error);
982+
assert.strictEqual(err.message, 'Invalid URL: ws+unix:');
983+
assert.strictEqual(ws._redirects, 1);
984+
985+
server.removeListener('upgrade', onUpgrade);
986+
ws.on('close', () => done());
987+
});
988+
});
944989
});
945990

946991
describe('Connection with query string', () => {

0 commit comments

Comments
 (0)