diff --git a/lib/web/websocket/util.js b/lib/web/websocket/util.js index f9cbf912d09..c60f711cb09 100644 --- a/lib/web/websocket/util.js +++ b/lib/web/websocket/util.js @@ -210,8 +210,8 @@ function parseExtensions (extensions) { const [name, value = ''] = pair.split('=', 2) extensionList.set( - removeHTTPWhitespace(name, true, false), - removeHTTPWhitespace(value, false, true) + removeHTTPWhitespace(name, true, true), + removeHTTPWhitespace(value, true, true) ) position.position++ diff --git a/test/websocket/util.js b/test/websocket/util.js index b6b05c5ba62..2305e97e794 100644 --- a/test/websocket/util.js +++ b/test/websocket/util.js @@ -1,7 +1,7 @@ 'use strict' const { describe, test } = require('node:test') -const { isValidSubprotocol } = require('../../lib/web/websocket/util') +const { isValidSubprotocol, parseExtensions } = require('../../lib/web/websocket/util') describe('isValidSubprotocol', () => { test('empty string returns false', t => { @@ -28,3 +28,23 @@ describe('isValidSubprotocol', () => { } }) }) + +describe('parseExtensions', () => { + test('keeps whitespace out of parameter names and values', t => { + // Optional whitespace is allowed around the ";" and "=" delimiters of an + // extension header, so it must be stripped from both ends of every name + // and value before the map is keyed on them. + const cases = { + 'permessage-deflate; client_max_window_bits': [['permessage-deflate', ''], ['client_max_window_bits', '']], + 'permessage-deflate ; client_max_window_bits': [['permessage-deflate', ''], ['client_max_window_bits', '']], + 'permessage-deflate;\tclient_max_window_bits': [['permessage-deflate', ''], ['client_max_window_bits', '']], + 'permessage-deflate; server_max_window_bits = 10': [['permessage-deflate', ''], ['server_max_window_bits', '10']], + 'permessage-deflate; server_max_window_bits=10 ': [['permessage-deflate', ''], ['server_max_window_bits', '10']] + } + + t.plan(Object.keys(cases).length) + for (const [header, expected] of Object.entries(cases)) { + t.assert.deepStrictEqual([...parseExtensions(header).entries()], expected, header) + } + }) +})