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