subprotocol.js (1498B)
1 'use strict'; 2 3 const { tokenChars } = require('./validation'); 4 5 /** 6 * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names. 7 * 8 * @param {String} header The field value of the header 9 * @return {Set} The subprotocol names 10 * @public 11 */ 12 function parse(header) { 13 const protocols = new Set(); 14 let start = -1; 15 let end = -1; 16 let i = 0; 17 18 for (i; i < header.length; i++) { 19 const code = header.charCodeAt(i); 20 21 if (end === -1 && tokenChars[code] === 1) { 22 if (start === -1) start = i; 23 } else if ( 24 i !== 0 && 25 (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */ 26 ) { 27 if (end === -1 && start !== -1) end = i; 28 } else if (code === 0x2c /* ',' */) { 29 if (start === -1) { 30 throw new SyntaxError(`Unexpected character at index ${i}`); 31 } 32 33 if (end === -1) end = i; 34 35 const protocol = header.slice(start, end); 36 37 if (protocols.has(protocol)) { 38 throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); 39 } 40 41 protocols.add(protocol); 42 start = end = -1; 43 } else { 44 throw new SyntaxError(`Unexpected character at index ${i}`); 45 } 46 } 47 48 if (start === -1 || end !== -1) { 49 throw new SyntaxError('Unexpected end of input'); 50 } 51 52 const protocol = header.slice(start, i); 53 54 if (protocols.has(protocol)) { 55 throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); 56 } 57 58 protocols.add(protocol); 59 return protocols; 60 } 61 62 module.exports = { parse };