github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/docs/examples/example-nodejs-fileserver/node_modules/express/lib/request.js (about) 1 /*! 2 * express 3 * Copyright(c) 2009-2013 TJ Holowaychuk 4 * Copyright(c) 2013 Roman Shtylman 5 * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 * MIT Licensed 7 */ 8 9 'use strict'; 10 11 /** 12 * Module dependencies. 13 * @private 14 */ 15 16 var accepts = require('accepts'); 17 var deprecate = require('depd')('express'); 18 var isIP = require('net').isIP; 19 var typeis = require('type-is'); 20 var http = require('http'); 21 var fresh = require('fresh'); 22 var parseRange = require('range-parser'); 23 var parse = require('parseurl'); 24 var proxyaddr = require('proxy-addr'); 25 26 /** 27 * Request prototype. 28 */ 29 30 var req = exports = module.exports = { 31 __proto__: http.IncomingMessage.prototype 32 }; 33 34 /** 35 * Return request header. 36 * 37 * The `Referrer` header field is special-cased, 38 * both `Referrer` and `Referer` are interchangeable. 39 * 40 * Examples: 41 * 42 * req.get('Content-Type'); 43 * // => "text/plain" 44 * 45 * req.get('content-type'); 46 * // => "text/plain" 47 * 48 * req.get('Something'); 49 * // => undefined 50 * 51 * Aliased as `req.header()`. 52 * 53 * @param {String} name 54 * @return {String} 55 * @public 56 */ 57 58 req.get = 59 req.header = function header(name) { 60 var lc = name.toLowerCase(); 61 62 switch (lc) { 63 case 'referer': 64 case 'referrer': 65 return this.headers.referrer 66 || this.headers.referer; 67 default: 68 return this.headers[lc]; 69 } 70 }; 71 72 /** 73 * To do: update docs. 74 * 75 * Check if the given `type(s)` is acceptable, returning 76 * the best match when true, otherwise `undefined`, in which 77 * case you should respond with 406 "Not Acceptable". 78 * 79 * The `type` value may be a single MIME type string 80 * such as "application/json", an extension name 81 * such as "json", a comma-delimited list such as "json, html, text/plain", 82 * an argument list such as `"json", "html", "text/plain"`, 83 * or an array `["json", "html", "text/plain"]`. When a list 84 * or array is given, the _best_ match, if any is returned. 85 * 86 * Examples: 87 * 88 * // Accept: text/html 89 * req.accepts('html'); 90 * // => "html" 91 * 92 * // Accept: text/*, application/json 93 * req.accepts('html'); 94 * // => "html" 95 * req.accepts('text/html'); 96 * // => "text/html" 97 * req.accepts('json, text'); 98 * // => "json" 99 * req.accepts('application/json'); 100 * // => "application/json" 101 * 102 * // Accept: text/*, application/json 103 * req.accepts('image/png'); 104 * req.accepts('png'); 105 * // => undefined 106 * 107 * // Accept: text/*;q=.5, application/json 108 * req.accepts(['html', 'json']); 109 * req.accepts('html', 'json'); 110 * req.accepts('html, json'); 111 * // => "json" 112 * 113 * @param {String|Array} type(s) 114 * @return {String|Array|Boolean} 115 * @public 116 */ 117 118 req.accepts = function(){ 119 var accept = accepts(this); 120 return accept.types.apply(accept, arguments); 121 }; 122 123 /** 124 * Check if the given `encoding`s are accepted. 125 * 126 * @param {String} ...encoding 127 * @return {String|Array} 128 * @public 129 */ 130 131 req.acceptsEncodings = function(){ 132 var accept = accepts(this); 133 return accept.encodings.apply(accept, arguments); 134 }; 135 136 req.acceptsEncoding = deprecate.function(req.acceptsEncodings, 137 'req.acceptsEncoding: Use acceptsEncodings instead'); 138 139 /** 140 * Check if the given `charset`s are acceptable, 141 * otherwise you should respond with 406 "Not Acceptable". 142 * 143 * @param {String} ...charset 144 * @return {String|Array} 145 * @public 146 */ 147 148 req.acceptsCharsets = function(){ 149 var accept = accepts(this); 150 return accept.charsets.apply(accept, arguments); 151 }; 152 153 req.acceptsCharset = deprecate.function(req.acceptsCharsets, 154 'req.acceptsCharset: Use acceptsCharsets instead'); 155 156 /** 157 * Check if the given `lang`s are acceptable, 158 * otherwise you should respond with 406 "Not Acceptable". 159 * 160 * @param {String} ...lang 161 * @return {String|Array} 162 * @public 163 */ 164 165 req.acceptsLanguages = function(){ 166 var accept = accepts(this); 167 return accept.languages.apply(accept, arguments); 168 }; 169 170 req.acceptsLanguage = deprecate.function(req.acceptsLanguages, 171 'req.acceptsLanguage: Use acceptsLanguages instead'); 172 173 /** 174 * Parse Range header field, 175 * capping to the given `size`. 176 * 177 * Unspecified ranges such as "0-" require 178 * knowledge of your resource length. In 179 * the case of a byte range this is of course 180 * the total number of bytes. If the Range 181 * header field is not given `null` is returned, 182 * `-1` when unsatisfiable, `-2` when syntactically invalid. 183 * 184 * NOTE: remember that ranges are inclusive, so 185 * for example "Range: users=0-3" should respond 186 * with 4 users when available, not 3. 187 * 188 * @param {Number} size 189 * @return {Array} 190 * @public 191 */ 192 193 req.range = function(size){ 194 var range = this.get('Range'); 195 if (!range) return; 196 return parseRange(size, range); 197 }; 198 199 /** 200 * Return the value of param `name` when present or `defaultValue`. 201 * 202 * - Checks route placeholders, ex: _/user/:id_ 203 * - Checks body params, ex: id=12, {"id":12} 204 * - Checks query string params, ex: ?id=12 205 * 206 * To utilize request bodies, `req.body` 207 * should be an object. This can be done by using 208 * the `bodyParser()` middleware. 209 * 210 * @param {String} name 211 * @param {Mixed} [defaultValue] 212 * @return {String} 213 * @public 214 */ 215 216 req.param = function param(name, defaultValue) { 217 var params = this.params || {}; 218 var body = this.body || {}; 219 var query = this.query || {}; 220 221 var args = arguments.length === 1 222 ? 'name' 223 : 'name, default'; 224 deprecate('req.param(' + args + '): Use req.params, req.body, or req.query instead'); 225 226 if (null != params[name] && params.hasOwnProperty(name)) return params[name]; 227 if (null != body[name]) return body[name]; 228 if (null != query[name]) return query[name]; 229 230 return defaultValue; 231 }; 232 233 /** 234 * Check if the incoming request contains the "Content-Type" 235 * header field, and it contains the give mime `type`. 236 * 237 * Examples: 238 * 239 * // With Content-Type: text/html; charset=utf-8 240 * req.is('html'); 241 * req.is('text/html'); 242 * req.is('text/*'); 243 * // => true 244 * 245 * // When Content-Type is application/json 246 * req.is('json'); 247 * req.is('application/json'); 248 * req.is('application/*'); 249 * // => true 250 * 251 * req.is('html'); 252 * // => false 253 * 254 * @param {String|Array} types... 255 * @return {String|false|null} 256 * @public 257 */ 258 259 req.is = function is(types) { 260 var arr = types; 261 262 // support flattened arguments 263 if (!Array.isArray(types)) { 264 arr = new Array(arguments.length); 265 for (var i = 0; i < arr.length; i++) { 266 arr[i] = arguments[i]; 267 } 268 } 269 270 return typeis(this, arr); 271 }; 272 273 /** 274 * Return the protocol string "http" or "https" 275 * when requested with TLS. When the "trust proxy" 276 * setting trusts the socket address, the 277 * "X-Forwarded-Proto" header field will be trusted 278 * and used if present. 279 * 280 * If you're running behind a reverse proxy that 281 * supplies https for you this may be enabled. 282 * 283 * @return {String} 284 * @public 285 */ 286 287 defineGetter(req, 'protocol', function protocol(){ 288 var proto = this.connection.encrypted 289 ? 'https' 290 : 'http'; 291 var trust = this.app.get('trust proxy fn'); 292 293 if (!trust(this.connection.remoteAddress, 0)) { 294 return proto; 295 } 296 297 // Note: X-Forwarded-Proto is normally only ever a 298 // single value, but this is to be safe. 299 proto = this.get('X-Forwarded-Proto') || proto; 300 return proto.split(/\s*,\s*/)[0]; 301 }); 302 303 /** 304 * Short-hand for: 305 * 306 * req.protocol == 'https' 307 * 308 * @return {Boolean} 309 * @public 310 */ 311 312 defineGetter(req, 'secure', function secure(){ 313 return this.protocol === 'https'; 314 }); 315 316 /** 317 * Return the remote address from the trusted proxy. 318 * 319 * The is the remote address on the socket unless 320 * "trust proxy" is set. 321 * 322 * @return {String} 323 * @public 324 */ 325 326 defineGetter(req, 'ip', function ip(){ 327 var trust = this.app.get('trust proxy fn'); 328 return proxyaddr(this, trust); 329 }); 330 331 /** 332 * When "trust proxy" is set, trusted proxy addresses + client. 333 * 334 * For example if the value were "client, proxy1, proxy2" 335 * you would receive the array `["client", "proxy1", "proxy2"]` 336 * where "proxy2" is the furthest down-stream and "proxy1" and 337 * "proxy2" were trusted. 338 * 339 * @return {Array} 340 * @public 341 */ 342 343 defineGetter(req, 'ips', function ips() { 344 var trust = this.app.get('trust proxy fn'); 345 var addrs = proxyaddr.all(this, trust); 346 return addrs.slice(1).reverse(); 347 }); 348 349 /** 350 * Return subdomains as an array. 351 * 352 * Subdomains are the dot-separated parts of the host before the main domain of 353 * the app. By default, the domain of the app is assumed to be the last two 354 * parts of the host. This can be changed by setting "subdomain offset". 355 * 356 * For example, if the domain is "tobi.ferrets.example.com": 357 * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`. 358 * If "subdomain offset" is 3, req.subdomains is `["tobi"]`. 359 * 360 * @return {Array} 361 * @public 362 */ 363 364 defineGetter(req, 'subdomains', function subdomains() { 365 var hostname = this.hostname; 366 367 if (!hostname) return []; 368 369 var offset = this.app.get('subdomain offset'); 370 var subdomains = !isIP(hostname) 371 ? hostname.split('.').reverse() 372 : [hostname]; 373 374 return subdomains.slice(offset); 375 }); 376 377 /** 378 * Short-hand for `url.parse(req.url).pathname`. 379 * 380 * @return {String} 381 * @public 382 */ 383 384 defineGetter(req, 'path', function path() { 385 return parse(this).pathname; 386 }); 387 388 /** 389 * Parse the "Host" header field to a hostname. 390 * 391 * When the "trust proxy" setting trusts the socket 392 * address, the "X-Forwarded-Host" header field will 393 * be trusted. 394 * 395 * @return {String} 396 * @public 397 */ 398 399 defineGetter(req, 'hostname', function hostname(){ 400 var trust = this.app.get('trust proxy fn'); 401 var host = this.get('X-Forwarded-Host'); 402 403 if (!host || !trust(this.connection.remoteAddress, 0)) { 404 host = this.get('Host'); 405 } 406 407 if (!host) return; 408 409 // IPv6 literal support 410 var offset = host[0] === '[' 411 ? host.indexOf(']') + 1 412 : 0; 413 var index = host.indexOf(':', offset); 414 415 return index !== -1 416 ? host.substring(0, index) 417 : host; 418 }); 419 420 // TODO: change req.host to return host in next major 421 422 defineGetter(req, 'host', deprecate.function(function host(){ 423 return this.hostname; 424 }, 'req.host: Use req.hostname instead')); 425 426 /** 427 * Check if the request is fresh, aka 428 * Last-Modified and/or the ETag 429 * still match. 430 * 431 * @return {Boolean} 432 * @public 433 */ 434 435 defineGetter(req, 'fresh', function(){ 436 var method = this.method; 437 var s = this.res.statusCode; 438 439 // GET or HEAD for weak freshness validation only 440 if ('GET' != method && 'HEAD' != method) return false; 441 442 // 2xx or 304 as per rfc2616 14.26 443 if ((s >= 200 && s < 300) || 304 == s) { 444 return fresh(this.headers, (this.res._headers || {})); 445 } 446 447 return false; 448 }); 449 450 /** 451 * Check if the request is stale, aka 452 * "Last-Modified" and / or the "ETag" for the 453 * resource has changed. 454 * 455 * @return {Boolean} 456 * @public 457 */ 458 459 defineGetter(req, 'stale', function stale(){ 460 return !this.fresh; 461 }); 462 463 /** 464 * Check if the request was an _XMLHttpRequest_. 465 * 466 * @return {Boolean} 467 * @public 468 */ 469 470 defineGetter(req, 'xhr', function xhr(){ 471 var val = this.get('X-Requested-With') || ''; 472 return val.toLowerCase() === 'xmlhttprequest'; 473 }); 474 475 /** 476 * Helper function for creating a getter on an object. 477 * 478 * @param {Object} obj 479 * @param {String} name 480 * @param {Function} getter 481 * @private 482 */ 483 function defineGetter(obj, name, getter) { 484 Object.defineProperty(obj, name, { 485 configurable: true, 486 enumerable: true, 487 get: getter 488 }); 489 };