Skip to content

Commit

Permalink
perf: improve performance of isValidSubprotocol (nodejs#2861)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak authored Feb 27, 2024
1 parent 1978601 commit 7146587
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 22 deletions.
17 changes: 17 additions & 0 deletions benchmarks/websocketIsValidSubprotocol.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { bench, group, run } from 'mitata'
import { isValidSubprotocol } from '../lib/web/websocket/util.js'

const valid = 'valid'
const invalid = 'invalid '

group('isValidSubprotocol', () => {
bench(`valid: ${valid}`, () => {
return isValidSubprotocol(valid)
})

bench(`invalid: ${invalid}`, () => {
return isValidSubprotocol(invalid)
})
})

await run()
42 changes: 20 additions & 22 deletions lib/web/websocket/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,31 +119,29 @@ function isValidSubprotocol (protocol) {
return false
}

for (const char of protocol) {
const code = char.charCodeAt(0)
for (let i = 0; i < protocol.length; ++i) {
const code = protocol.charCodeAt(i)

if (
code < 0x21 ||
code < 0x21 || // CTL, contains SP (0x20) and HT (0x09)
code > 0x7E ||
char === '(' ||
char === ')' ||
char === '<' ||
char === '>' ||
char === '@' ||
char === ',' ||
char === ';' ||
char === ':' ||
char === '\\' ||
char === '"' ||
char === '/' ||
char === '[' ||
char === ']' ||
char === '?' ||
char === '=' ||
char === '{' ||
char === '}' ||
code === 32 || // SP
code === 9 // HT
code === 0x22 || // "
code === 0x28 || // (
code === 0x29 || // )
code === 0x2C || // ,
code === 0x2F || // /
code === 0x3A || // :
code === 0x3B || // ;
code === 0x3C || // <
code === 0x3D || // =
code === 0x3E || // >
code === 0x3F || // ?
code === 0x40 || // @
code === 0x5B || // [
code === 0x5C || // \
code === 0x5D || // ]
code === 0x7B || // {
code === 0x7D // }
) {
return false
}
Expand Down
31 changes: 31 additions & 0 deletions test/websocket/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

const { tspl } = require('@matteo.collina/tspl')
const { describe, test } = require('node:test')
const { isValidSubprotocol } = require('../../lib/web/websocket/util')

describe('isValidSubprotocol', () => {
test('empty string returns false', t => {
t = tspl(t, { plan: 1 })
t.strictEqual(isValidSubprotocol(''), false)
})

test('simple valid value returns false', t => {
t = tspl(t, { plan: 1 })
t.strictEqual(isValidSubprotocol('chat'), true)
})

test('empty string returns false', t => {
t = tspl(t, { plan: 1 })
t.strictEqual(isValidSubprotocol(''), false)
})

test('value with "(),/:;<=>?@[\\]{} returns false', t => {
const chars = '"(),/:;<=>?@[\\]{}'
t = tspl(t, { plan: 17 })

for (let i = 0; i < chars.length; ++i) {
t.strictEqual(isValidSubprotocol('valid' + chars[i]), false)
}
})
})

0 comments on commit 7146587

Please sign in to comment.