CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
request.js515 linesDownload Raw Back to lib
1/*!2 * express3 * Copyright(c) 2009-2013 TJ Holowaychuk4 * Copyright(c) 2013 Roman Shtylman5 * Copyright(c) 2014-2015 Douglas Christopher Wilson6 * MIT Licensed7 */8 9'use strict';10 11/**12 * Module dependencies.13 * @private14 */15 16var accepts = require('accepts');17var isIP = require('node:net').isIP;18var typeis = require('type-is');19var http = require('node:http');20var fresh = require('fresh');21var parseRange = require('range-parser');22var parse = require('parseurl');23var proxyaddr = require('proxy-addr');24 25/**26 * Request prototype.27 * @public28 */29 30var req = Object.create(http.IncomingMessage.prototype)31 32/**33 * Module exports.34 * @public35 */36 37module.exports = req38 39/**40 * Return request header.41 *42 * The `Referrer` header field is special-cased,43 * both `Referrer` and `Referer` are interchangeable.44 *45 * Examples:46 *47 *     req.get('Content-Type');48 *     // => "text/plain"49 *50 *     req.get('content-type');51 *     // => "text/plain"52 *53 *     req.get('Something');54 *     // => undefined55 *56 * Aliased as `req.header()`.57 *58 * @param {String} name59 * @return {String}60 * @public61 */62 63req.get =64req.header = function header(name) {65  if (!name) {66    throw new TypeError('name argument is required to req.get');67  }68 69  if (typeof name !== 'string') {70    throw new TypeError('name must be a string to req.get');71  }72 73  var lc = name.toLowerCase();74 75  switch (lc) {76    case 'referer':77    case 'referrer':78      return this.headers.referrer79        || this.headers.referer;80    default:81      return this.headers[lc];82  }83};84 85/**86 * To do: update docs.87 *88 * Check if the given `type(s)` is acceptable, returning89 * the best match when true, otherwise `undefined`, in which90 * case you should respond with 406 "Not Acceptable".91 *92 * The `type` value may be a single MIME type string93 * such as "application/json", an extension name94 * such as "json", a comma-delimited list such as "json, html, text/plain",95 * an argument list such as `"json", "html", "text/plain"`,96 * or an array `["json", "html", "text/plain"]`. When a list97 * or array is given, the _best_ match, if any is returned.98 *99 * Examples:100 *101 *     // Accept: text/html102 *     req.accepts('html');103 *     // => "html"104 *105 *     // Accept: text/*, application/json106 *     req.accepts('html');107 *     // => "html"108 *     req.accepts('text/html');109 *     // => "text/html"110 *     req.accepts('json, text');111 *     // => "json"112 *     req.accepts('application/json');113 *     // => "application/json"114 *115 *     // Accept: text/*, application/json116 *     req.accepts('image/png');117 *     req.accepts('png');118 *     // => undefined119 *120 *     // Accept: text/*;q=.5, application/json121 *     req.accepts(['html', 'json']);122 *     req.accepts('html', 'json');123 *     req.accepts('html, json');124 *     // => "json"125 *126 * @param {String|Array} type(s)127 * @return {String|Array|Boolean}128 * @public129 */130 131req.accepts = function(){132  var accept = accepts(this);133  return accept.types.apply(accept, arguments);134};135 136/**137 * Check if the given `encoding`s are accepted.138 *139 * @param {String} ...encoding140 * @return {String|Array}141 * @public142 */143 144req.acceptsEncodings = function(){145  var accept = accepts(this);146  return accept.encodings.apply(accept, arguments);147};148 149/**150 * Check if the given `charset`s are acceptable,151 * otherwise you should respond with 406 "Not Acceptable".152 *153 * @param {String} ...charset154 * @return {String|Array}155 * @public156 */157 158req.acceptsCharsets = function(){159  var accept = accepts(this);160  return accept.charsets.apply(accept, arguments);161};162 163/**164 * Check if the given `lang`s are acceptable,165 * otherwise you should respond with 406 "Not Acceptable".166 *167 * @param {String} ...lang168 * @return {String|Array}169 * @public170 */171 172req.acceptsLanguages = function(...languages) {173  return accepts(this).languages(...languages);174};175 176/**177 * Parse Range header field, capping to the given `size`.178 *179 * Unspecified ranges such as "0-" require knowledge of your resource length. In180 * the case of a byte range this is of course the total number of bytes. If the181 * Range header field is not given `undefined` is returned, `-1` when unsatisfiable,182 * and `-2` when syntactically invalid.183 *184 * When ranges are returned, the array has a "type" property which is the type of185 * range that is required (most commonly, "bytes"). Each array element is an object186 * with a "start" and "end" property for the portion of the range.187 *188 * The "combine" option can be set to `true` and overlapping & adjacent ranges189 * will be combined into a single range.190 *191 * NOTE: remember that ranges are inclusive, so for example "Range: users=0-3"192 * should respond with 4 users when available, not 3.193 *194 * @param {number} size195 * @param {object} [options]196 * @param {boolean} [options.combine=false]197 * @return {number|array}198 * @public199 */200 201req.range = function range(size, options) {202  var range = this.get('Range');203  if (!range) return;204  return parseRange(size, range, options);205};206 207/**208 * Parse the query string of `req.url`.209 *210 * This uses the "query parser" setting to parse the raw211 * string into an object.212 *213 * @return {String}214 * @api public215 */216 217defineGetter(req, 'query', function query(){218  var queryparse = this.app.get('query parser fn');219 220  if (!queryparse) {221    // parsing is disabled222    return Object.create(null);223  }224 225  var querystring = parse(this).query;226 227  return queryparse(querystring);228});229 230/**231 * Check if the incoming request contains the "Content-Type"232 * header field, and it contains the given mime `type`.233 *234 * Examples:235 *236 *      // With Content-Type: text/html; charset=utf-8237 *      req.is('html');238 *      req.is('text/html');239 *      req.is('text/*');240 *      // => true241 *242 *      // When Content-Type is application/json243 *      req.is('json');244 *      req.is('application/json');245 *      req.is('application/*');246 *      // => true247 *248 *      req.is('html');249 *      // => false250 *251 * @param {String|Array} types...252 * @return {String|false|null}253 * @public254 */255 256req.is = function is(types) {257  var arr = types;258 259  // support flattened arguments260  if (!Array.isArray(types)) {261    arr = new Array(arguments.length);262    for (var i = 0; i < arr.length; i++) {263      arr[i] = arguments[i];264    }265  }266 267  return typeis(this, arr);268};269 270/**271 * Return the protocol string "http" or "https"272 * when requested with TLS. When the "trust proxy"273 * setting trusts the socket address, the274 * "X-Forwarded-Proto" header field will be trusted275 * and used if present.276 *277 * If you're running behind a reverse proxy that278 * supplies https for you this may be enabled.279 *280 * @return {String}281 * @public282 */283 284defineGetter(req, 'protocol', function protocol(){285  var proto = this.socket.encrypted286    ? 'https'287    : 'http';288  var trust = this.app.get('trust proxy fn');289 290  if (!trust(this.socket.remoteAddress, 0)) {291    return proto;292  }293 294  // Note: X-Forwarded-Proto is normally only ever a295  //       single value, but this is to be safe.296  var header = this.get('X-Forwarded-Proto') || proto297  var index = header.indexOf(',')298 299  return index !== -1300    ? header.substring(0, index).trim()301    : header.trim()302});303 304/**305 * Short-hand for:306 *307 *    req.protocol === 'https'308 *309 * @return {Boolean}310 * @public311 */312 313defineGetter(req, 'secure', function secure(){314  return this.protocol === 'https';315});316 317/**318 * Return the remote address from the trusted proxy.319 *320 * The is the remote address on the socket unless321 * "trust proxy" is set.322 *323 * @return {String}324 * @public325 */326 327defineGetter(req, 'ip', function ip(){328  var trust = this.app.get('trust proxy fn');329  return proxyaddr(this, trust);330});331 332/**333 * When "trust proxy" is set, trusted proxy addresses + client.334 *335 * For example if the value were "client, proxy1, proxy2"336 * you would receive the array `["client", "proxy1", "proxy2"]`337 * where "proxy2" is the furthest down-stream and "proxy1" and338 * "proxy2" were trusted.339 *340 * @return {Array}341 * @public342 */343 344defineGetter(req, 'ips', function ips() {345  var trust = this.app.get('trust proxy fn');346  var addrs = proxyaddr.all(this, trust);347 348  // reverse the order (to farthest -> closest)349  // and remove socket address350  addrs.reverse().pop()351 352  return addrs353});354 355/**356 * Return subdomains as an array.357 *358 * Subdomains are the dot-separated parts of the host before the main domain of359 * the app. By default, the domain of the app is assumed to be the last two360 * parts of the host. This can be changed by setting "subdomain offset".361 *362 * For example, if the domain is "tobi.ferrets.example.com":363 * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.364 * If "subdomain offset" is 3, req.subdomains is `["tobi"]`.365 *366 * @return {Array}367 * @public368 */369 370defineGetter(req, 'subdomains', function subdomains() {371  var hostname = this.hostname;372 373  if (!hostname) return [];374 375  var offset = this.app.get('subdomain offset');376  var subdomains = !isIP(hostname)377    ? hostname.split('.').reverse()378    : [hostname];379 380  return subdomains.slice(offset);381});382 383/**384 * Short-hand for `url.parse(req.url).pathname`.385 *386 * @return {String}387 * @public388 */389 390defineGetter(req, 'path', function path() {391  return parse(this).pathname;392});393 394/**395 * Parse the "Host" header field to a host.396 *397 * When the "trust proxy" setting trusts the socket398 * address, the "X-Forwarded-Host" header field will399 * be trusted.400 *401 * @return {String}402 * @public403 */404 405defineGetter(req, 'host', function host(){406  var trust = this.app.get('trust proxy fn');407  var val = this.get('X-Forwarded-Host');408 409  if (!val || !trust(this.socket.remoteAddress, 0)) {410    val = this.get('Host');411  } else if (val.indexOf(',') !== -1) {412    // Note: X-Forwarded-Host is normally only ever a413    //       single value, but this is to be safe.414    val = val.substring(0, val.indexOf(',')).trimRight()415  }416 417  return val || undefined;418});419 420/**421 * Parse the "Host" header field to a hostname.422 *423 * When the "trust proxy" setting trusts the socket424 * address, the "X-Forwarded-Host" header field will425 * be trusted.426 *427 * @return {String}428 * @api public429 */430 431defineGetter(req, 'hostname', function hostname(){432  var host = this.host;433 434  if (!host) return;435 436  // IPv6 literal support437  var offset = host[0] === '['438    ? host.indexOf(']') + 1439    : 0;440  var index = host.indexOf(':', offset);441 442  return index !== -1443    ? host.substring(0, index)444    : host;445});446 447/**448 * Check if the request is fresh, aka449 * Last-Modified or the ETag450 * still match.451 *452 * @return {Boolean}453 * @public454 */455 456defineGetter(req, 'fresh', function(){457  var method = this.method;458  var res = this.res459  var status = res.statusCode460 461  // GET or HEAD for weak freshness validation only462  if ('GET' !== method && 'HEAD' !== method) return false;463 464  // 2xx or 304 as per rfc2616 14.26465  if ((status >= 200 && status < 300) || 304 === status) {466    return fresh(this.headers, {467      'etag': res.get('ETag'),468      'last-modified': res.get('Last-Modified')469    })470  }471 472  return false;473});474 475/**476 * Check if the request is stale, aka477 * "Last-Modified" and / or the "ETag" for the478 * resource has changed.479 *480 * @return {Boolean}481 * @public482 */483 484defineGetter(req, 'stale', function stale(){485  return !this.fresh;486});487 488/**489 * Check if the request was an _XMLHttpRequest_.490 *491 * @return {Boolean}492 * @public493 */494 495defineGetter(req, 'xhr', function xhr(){496  var val = this.get('X-Requested-With') || '';497  return val.toLowerCase() === 'xmlhttprequest';498});499 500/**501 * Helper function for creating a getter on an object.502 *503 * @param {Object} obj504 * @param {String} name505 * @param {Function} getter506 * @private507 */508function defineGetter(obj, name, getter) {509  Object.defineProperty(obj, name, {510    configurable: true,511    enumerable: true,512    get: getter513  });514}515