AK-21/Graphite-Industrial-Intelligence
0
1/*!2 * express3 * Copyright(c) 2009-2013 TJ Holowaychuk4 * Copyright(c) 2014-2015 Douglas Christopher Wilson5 * MIT Licensed6 */7 8'use strict';9 10/**11 * Module dependencies.12 * @api private13 */14 15var { METHODS } = require('node:http');16var contentType = require('content-type');17var etag = require('etag');18var mime = require('mime-types')19var proxyaddr = require('proxy-addr');20var qs = require('qs');21var querystring = require('node:querystring');22const { Buffer } = require('node:buffer');23 24 25/**26 * A list of lowercased HTTP methods that are supported by Node.js.27 * @api private28 */29exports.methods = METHODS.map((method) => method.toLowerCase());30 31/**32 * Return strong ETag for `body`.33 *34 * @param {String|Buffer} body35 * @param {String} [encoding]36 * @return {String}37 * @api private38 */39 40exports.etag = createETagGenerator({ weak: false })41 42/**43 * Return weak ETag for `body`.44 *45 * @param {String|Buffer} body46 * @param {String} [encoding]47 * @return {String}48 * @api private49 */50 51exports.wetag = createETagGenerator({ weak: true })52 53/**54 * Normalize the given `type`, for example "html" becomes "text/html".55 *56 * @param {String} type57 * @return {Object}58 * @api private59 */60 61exports.normalizeType = function(type){62 return ~type.indexOf('/')63 ? acceptParams(type)64 : { value: (mime.lookup(type) || 'application/octet-stream'), params: {} }65};66 67/**68 * Normalize `types`, for example "html" becomes "text/html".69 *70 * @param {Array} types71 * @return {Array}72 * @api private73 */74 75exports.normalizeTypes = function(types) {76 return types.map(exports.normalizeType);77};78 79 80/**81 * Parse accept params `str` returning an82 * object with `.value`, `.quality` and `.params`.83 *84 * @param {String} str85 * @return {Object}86 * @api private87 */88 89function acceptParams (str) {90 var length = str.length;91 var colonIndex = str.indexOf(';');92 var index = colonIndex === -1 ? length : colonIndex;93 var ret = { value: str.slice(0, index).trim(), quality: 1, params: {} };94 95 while (index < length) {96 var splitIndex = str.indexOf('=', index);97 if (splitIndex === -1) break;98 99 var colonIndex = str.indexOf(';', index);100 var endIndex = colonIndex === -1 ? length : colonIndex;101 102 if (splitIndex > endIndex) {103 index = str.lastIndexOf(';', splitIndex - 1) + 1;104 continue;105 }106 107 var key = str.slice(index, splitIndex).trim();108 var value = str.slice(splitIndex + 1, endIndex).trim();109 110 if (key === 'q') {111 ret.quality = parseFloat(value);112 } else {113 ret.params[key] = value;114 }115 116 index = endIndex + 1;117 }118 119 return ret;120}121 122/**123 * Compile "etag" value to function.124 *125 * @param {Boolean|String|Function} val126 * @return {Function}127 * @api private128 */129 130exports.compileETag = function(val) {131 var fn;132 133 if (typeof val === 'function') {134 return val;135 }136 137 switch (val) {138 case true:139 case 'weak':140 fn = exports.wetag;141 break;142 case false:143 break;144 case 'strong':145 fn = exports.etag;146 break;147 default:148 throw new TypeError('unknown value for etag function: ' + val);149 }150 151 return fn;152}153 154/**155 * Compile "query parser" value to function.156 *157 * @param {String|Function} val158 * @return {Function}159 * @api private160 */161 162exports.compileQueryParser = function compileQueryParser(val) {163 var fn;164 165 if (typeof val === 'function') {166 return val;167 }168 169 switch (val) {170 case true:171 case 'simple':172 fn = querystring.parse;173 break;174 case false:175 break;176 case 'extended':177 fn = parseExtendedQueryString;178 break;179 default:180 throw new TypeError('unknown value for query parser function: ' + val);181 }182 183 return fn;184}185 186/**187 * Compile "proxy trust" value to function.188 *189 * @param {Boolean|String|Number|Array|Function} val190 * @return {Function}191 * @api private192 */193 194exports.compileTrust = function(val) {195 if (typeof val === 'function') return val;196 197 if (val === true) {198 // Support plain true/false199 return function(){ return true };200 }201 202 if (typeof val === 'number') {203 // Support trusting hop count204 return function(a, i){ return i < val };205 }206 207 if (typeof val === 'string') {208 // Support comma-separated values209 val = val.split(',')210 .map(function (v) { return v.trim() })211 }212 213 return proxyaddr.compile(val || []);214}215 216/**217 * Set the charset in a given Content-Type string.218 *219 * @param {String} type220 * @param {String} charset221 * @return {String}222 * @api private223 */224 225exports.setCharset = function setCharset(type, charset) {226 if (!type || !charset) {227 return type;228 }229 230 // parse type231 var parsed = contentType.parse(type);232 233 // set charset234 parsed.parameters.charset = charset;235 236 // format type237 return contentType.format(parsed);238};239 240/**241 * Create an ETag generator function, generating ETags with242 * the given options.243 *244 * @param {object} options245 * @return {function}246 * @private247 */248 249function createETagGenerator (options) {250 return function generateETag (body, encoding) {251 var buf = !Buffer.isBuffer(body)252 ? Buffer.from(body, encoding)253 : body254 255 return etag(buf, options)256 }257}258 259/**260 * Parse an extended query string with qs.261 *262 * @param {String} str263 * @return {Object}264 * @private265 */266 267function parseExtendedQueryString(str) {268 return qs.parse(str, {269 allowPrototypes: true270 });271}272 