1'use strict' 2/** 3 * A set of utilities borrowed from Node.js' _http_common.js 4 */ 5 6/** 7 * Verifies that the given val is a valid HTTP token 8 * per the rules defined in RFC 7230 9 * See https://tools.ietf.org/html/rfc7230#section-3.2.6 10 * 11 * Allowed characters in an HTTP token: 12 * ^_`a-z 94-122 13 * A-Z 65-90 14 * - 45 15 * 0-9 48-57 16 * ! 33 17 * #$%&' 35-39 18 * *+ 42-43 19 * . 46 20 * | 124 21 * ~ 126 22 * 23 * This implementation of checkIsHttpToken() loops over the string instead of 24 * using a regular expression since the former is up to 180% faster with v8 4.9 25 * depending on the string length (the shorter the string, the larger the 26 * performance difference) 27 * 28 * Additionally, checkIsHttpToken() is currently designed to be inlinable by v8, 29 * so take care when making changes to the implementation so that the source 30 * code size does not exceed v8's default max_inlined_source_size setting. 31 **/ 32/* istanbul ignore next */ 33function isValidTokenChar (ch) { 34 if (ch >= 94 && ch <= 122) { return true } 35 if (ch >= 65 && ch <= 90) { return true } 36 if (ch === 45) { return true } 37 if (ch >= 48 && ch <= 57) { return true } 38 if (ch === 34 || ch === 40 || ch === 41 || ch === 44) { return false } 39 if (ch >= 33 && ch <= 46) { return true } 40 if (ch === 124 || ch === 126) { return true } 41 return false 42} 43/* istanbul ignore next */ 44function checkIsHttpToken (val) { 45 if (typeof val !== 'string' || val.length === 0) { return false } 46 if (!isValidTokenChar(val.charCodeAt(0))) { return false } 47 const len = val.length 48 if (len > 1) { 49 if (!isValidTokenChar(val.charCodeAt(1))) { return false } 50 if (len > 2) { 51 if (!isValidTokenChar(val.charCodeAt(2))) { return false } 52 if (len > 3) { 53 if (!isValidTokenChar(val.charCodeAt(3))) { return false } 54 for (var i = 4; i < len; i++) { 55 if (!isValidTokenChar(val.charCodeAt(i))) { return false } 56 } 57 } 58 } 59 } 60 return true 61} 62exports.checkIsHttpToken = checkIsHttpToken 63 64/** 65 * True if val contains an invalid field-vchar 66 * field-value = *( field-content / obs-fold ) 67 * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] 68 * field-vchar = VCHAR / obs-text 69 * 70 * checkInvalidHeaderChar() is currently designed to be inlinable by v8, 71 * so take care when making changes to the implementation so that the source 72 * code size does not exceed v8's default max_inlined_source_size setting. 73 **/ 74/* istanbul ignore next */ 75function checkInvalidHeaderChar (val) { 76 val += '' 77 if (val.length < 1) { return false } 78 var c = val.charCodeAt(0) 79 if ((c <= 31 && c !== 9) || c > 255 || c === 127) { return true } 80 if (val.length < 2) { return false } 81 c = val.charCodeAt(1) 82 if ((c <= 31 && c !== 9) || c > 255 || c === 127) { return true } 83 if (val.length < 3) { return false } 84 c = val.charCodeAt(2) 85 if ((c <= 31 && c !== 9) || c > 255 || c === 127) { return true } 86 for (var i = 3; i < val.length; ++i) { 87 c = val.charCodeAt(i) 88 if ((c <= 31 && c !== 9) || c > 255 || c === 127) { return true } 89 } 90 return false 91} 92exports.checkInvalidHeaderChar = checkInvalidHeaderChar 93