63 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			63 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const { tokenChars } = require('./validation');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param {String} header The field value of the header
							 | 
						||
| 
								 | 
							
								 * @return {Set} The subprotocol names
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function parse(header) {
							 | 
						||
| 
								 | 
							
								  const protocols = new Set();
							 | 
						||
| 
								 | 
							
								  let start = -1;
							 | 
						||
| 
								 | 
							
								  let end = -1;
							 | 
						||
| 
								 | 
							
								  let i = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i; i < header.length; i++) {
							 | 
						||
| 
								 | 
							
								    const code = header.charCodeAt(i);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (end === -1 && tokenChars[code] === 1) {
							 | 
						||
| 
								 | 
							
								      if (start === -1) start = i;
							 | 
						||
| 
								 | 
							
								    } else if (
							 | 
						||
| 
								 | 
							
								      i !== 0 &&
							 | 
						||
| 
								 | 
							
								      (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */
							 | 
						||
| 
								 | 
							
								    ) {
							 | 
						||
| 
								 | 
							
								      if (end === -1 && start !== -1) end = i;
							 | 
						||
| 
								 | 
							
								    } else if (code === 0x2c /* ',' */) {
							 | 
						||
| 
								 | 
							
								      if (start === -1) {
							 | 
						||
| 
								 | 
							
								        throw new SyntaxError(`Unexpected character at index ${i}`);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (end === -1) end = i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const protocol = header.slice(start, end);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (protocols.has(protocol)) {
							 | 
						||
| 
								 | 
							
								        throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      protocols.add(protocol);
							 | 
						||
| 
								 | 
							
								      start = end = -1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      throw new SyntaxError(`Unexpected character at index ${i}`);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (start === -1 || end !== -1) {
							 | 
						||
| 
								 | 
							
								    throw new SyntaxError('Unexpected end of input');
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const protocol = header.slice(start, i);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (protocols.has(protocol)) {
							 | 
						||
| 
								 | 
							
								    throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  protocols.add(protocol);
							 | 
						||
| 
								 | 
							
								  return protocols;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = { parse };
							 |