* @see https://datatracker.ietf.org/doc/html/rfc6455 * @see https://datatracker.ietf.org/doc/html/rfc2616 * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 * @param {string} protocol * @returns {boolean}
(protocol)
| 99 | * @returns {boolean} |
| 100 | */ |
| 101 | function isValidSubprotocol (protocol) { |
| 102 | // If present, this value indicates one |
| 103 | // or more comma-separated subprotocol the client wishes to speak, |
| 104 | // ordered by preference. The elements that comprise this value |
| 105 | // MUST be non-empty strings with characters in the range U+0021 to |
| 106 | // U+007E not including separator characters as defined in |
| 107 | // [RFC2616] and MUST all be unique strings. |
| 108 | if (protocol.length === 0) { |
| 109 | return false |
| 110 | } |
| 111 | |
| 112 | for (let i = 0; i < protocol.length; ++i) { |
| 113 | const code = protocol.charCodeAt(i) |
| 114 | |
| 115 | if ( |
| 116 | code < 0x21 || // CTL, contains SP (0x20) and HT (0x09) |
| 117 | code > 0x7E || |
| 118 | code === 0x22 || // " |
| 119 | code === 0x28 || // ( |
| 120 | code === 0x29 || // ) |
| 121 | code === 0x2C || // , |
| 122 | code === 0x2F || // / |
| 123 | code === 0x3A || // : |
| 124 | code === 0x3B || // ; |
| 125 | code === 0x3C || // < |
| 126 | code === 0x3D || // = |
| 127 | code === 0x3E || // > |
| 128 | code === 0x3F || // ? |
| 129 | code === 0x40 || // @ |
| 130 | code === 0x5B || // [ |
| 131 | code === 0x5C || // \ |
| 132 | code === 0x5D || // ] |
| 133 | code === 0x7B || // { |
| 134 | code === 0x7D // } |
| 135 | ) { |
| 136 | return false |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | return true |
| 141 | } |
| 142 | |
| 143 | /** |
| 144 | * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 |
no outgoing calls
no test coverage detected