PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/sample/node_modules/express/lib/request.js

https://gitlab.com/stefan.pataky/squid.js
JavaScript | 289 lines | 78 code | 20 blank | 191 comment | 38 complexity | 4f9c589e3d093b7889ce5f6100cc4dc9 MD5 | raw file
  1. /*!
  2. * Express - request
  3. * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
  4. * MIT Licensed
  5. */
  6. /**
  7. * Module dependencies.
  8. */
  9. var http = require('http')
  10. , req = http.IncomingMessage.prototype
  11. , utils = require('./utils')
  12. , mime = require('mime');
  13. /**
  14. * Default flash formatters.
  15. *
  16. * @type Object
  17. */
  18. var flashFormatters = exports.flashFormatters = {
  19. s: function(val){
  20. return String(val);
  21. }
  22. };
  23. /**
  24. * Return request header or optional default.
  25. *
  26. * The `Referrer` header field is special-cased,
  27. * both `Referrer` and `Referer` will yield are
  28. * interchangeable.
  29. *
  30. * Examples:
  31. *
  32. * req.header('Content-Type');
  33. * // => "text/plain"
  34. *
  35. * req.header('content-type');
  36. * // => "text/plain"
  37. *
  38. * req.header('Accept');
  39. * // => undefined
  40. *
  41. * req.header('Accept', 'text/html');
  42. * // => "text/html"
  43. *
  44. * @param {String} name
  45. * @param {String} defaultValue
  46. * @return {String}
  47. * @api public
  48. */
  49. req.header = function(name, defaultValue){
  50. switch (name = name.toLowerCase()) {
  51. case 'referer':
  52. case 'referrer':
  53. return this.headers.referrer
  54. || this.headers.referer
  55. || defaultValue;
  56. default:
  57. return this.headers[name] || defaultValue;
  58. }
  59. };
  60. /**
  61. * Check if the _Accept_ header is present, and includes the given `type`.
  62. *
  63. * When the _Accept_ header is not present `true` is returned. Otherwise
  64. * the given `type` is matched by an exact match, and then subtypes. You
  65. * may pass the subtype such as "html" which is then converted internally
  66. * to "text/html" using the mime lookup table.
  67. *
  68. * Examples:
  69. *
  70. * // Accept: text/html
  71. * req.accepts('html');
  72. * // => true
  73. *
  74. * // Accept: text/*; application/json
  75. * req.accepts('html');
  76. * req.accepts('text/html');
  77. * req.accepts('text/plain');
  78. * req.accepts('application/json');
  79. * // => true
  80. *
  81. * req.accepts('image/png');
  82. * req.accepts('png');
  83. * // => false
  84. *
  85. * @param {String} type
  86. * @return {Boolean}
  87. * @api public
  88. */
  89. req.accepts = function(type){
  90. var accept = this.header('Accept');
  91. // normalize extensions ".json" -> "json"
  92. if (type && '.' == type[0]) type = type.substr(1);
  93. // when Accept does not exist, or is '*/*' return true
  94. if (!accept || '*/*' == accept) {
  95. return true;
  96. } else if (type) {
  97. // allow "html" vs "text/html" etc
  98. if (type.indexOf('/') < 0) {
  99. type = mime.lookup(type);
  100. }
  101. // check if we have a direct match
  102. if (~accept.indexOf(type)) return true;
  103. // check if we have type/*
  104. type = type.split('/')[0] + '/*';
  105. return accept.indexOf(type) >= 0;
  106. } else {
  107. return false;
  108. }
  109. };
  110. /**
  111. * Return the value of param `name` when present or `defaultValue`.
  112. *
  113. * - Checks route placeholders, ex: _/user/:id_
  114. * - Checks query string params, ex: ?id=12
  115. * - Checks urlencoded body params, ex: id=12
  116. *
  117. * To utilize urlencoded request bodies, `req.body`
  118. * should be an object. This can be done by using
  119. * the `connect.bodyParser` middleware.
  120. *
  121. * @param {String} name
  122. * @param {Mixed} defaultValue
  123. * @return {String}
  124. * @api public
  125. */
  126. req.param = function(name, defaultValue){
  127. // route params like /user/:id
  128. if (this.params && this.params.hasOwnProperty(name) && undefined !== this.params[name]) {
  129. return this.params[name];
  130. }
  131. // query string params
  132. if (undefined !== this.query[name]) {
  133. return this.query[name];
  134. }
  135. // request body params via connect.bodyParser
  136. if (this.body && undefined !== this.body[name]) {
  137. return this.body[name];
  138. }
  139. return defaultValue;
  140. };
  141. /**
  142. * Queue flash `msg` of the given `type`.
  143. *
  144. * Examples:
  145. *
  146. * req.flash('info', 'email sent');
  147. * req.flash('error', 'email delivery failed');
  148. * req.flash('info', 'email re-sent');
  149. * // => 2
  150. *
  151. * req.flash('info');
  152. * // => ['email sent', 'email re-sent']
  153. *
  154. * req.flash('info');
  155. * // => []
  156. *
  157. * req.flash();
  158. * // => { error: ['email delivery failed'], info: [] }
  159. *
  160. * Formatting:
  161. *
  162. * Flash notifications also support arbitrary formatting support.
  163. * For example you may pass variable arguments to `req.flash()`
  164. * and use the %s specifier to be replaced by the associated argument:
  165. *
  166. * req.flash('info', 'email has been sent to %s.', userName);
  167. *
  168. * To add custom formatters use the `exports.flashFormatters` object.
  169. *
  170. * @param {String} type
  171. * @param {String} msg
  172. * @return {Array|Object|Number}
  173. * @api public
  174. */
  175. req.flash = function(type, msg){
  176. if (this.session === undefined) throw Error('req.flash() requires sessions');
  177. var msgs = this.session.flash = this.session.flash || {};
  178. if (type && msg) {
  179. var i = 2
  180. , args = arguments
  181. , formatters = this.app.flashFormatters || {};
  182. formatters.__proto__ = flashFormatters;
  183. msg = utils.miniMarkdown(utils.escape(msg));
  184. msg = msg.replace(/%([a-zA-Z])/g, function(_, format){
  185. var formatter = formatters[format];
  186. if (formatter) return formatter(args[i++]);
  187. });
  188. return (msgs[type] = msgs[type] || []).push(msg);
  189. } else if (type) {
  190. var arr = msgs[type];
  191. delete msgs[type];
  192. return arr || [];
  193. } else {
  194. this.session.flash = {};
  195. return msgs;
  196. }
  197. };
  198. /**
  199. * Check if the incoming request contains the "Content-Type"
  200. * header field, and it contains the give mime `type`.
  201. *
  202. * Examples:
  203. *
  204. * // With Content-Type: text/html; charset=utf-8
  205. * req.is('html');
  206. * req.is('text/html');
  207. * // => true
  208. *
  209. * // When Content-Type is application/json
  210. * req.is('json');
  211. * req.is('application/json');
  212. * // => true
  213. *
  214. * req.is('html');
  215. * // => false
  216. *
  217. * Ad-hoc callbacks can also be registered with Express, to perform
  218. * assertions again the request, for example if we need an expressive
  219. * way to check if our incoming request is an image, we can register "an image"
  220. * callback:
  221. *
  222. * app.is('an image', function(req){
  223. * return 0 == req.headers['content-type'].indexOf('image');
  224. * });
  225. *
  226. * Now within our route callbacks, we can use to to assert content types
  227. * such as "image/jpeg", "image/png", etc.
  228. *
  229. * app.post('/image/upload', function(req, res, next){
  230. * if (req.is('an image')) {
  231. * // do something
  232. * } else {
  233. * next();
  234. * }
  235. * });
  236. *
  237. * @param {String} type
  238. * @return {Boolean}
  239. * @api public
  240. */
  241. req.is = function(type){
  242. var fn = this.app.is(type);
  243. if (fn) return fn(this);
  244. var contentType = this.headers['content-type'];
  245. if (!contentType) return;
  246. if (!~type.indexOf('/')) type = mime.lookup(type);
  247. if (~type.indexOf('*')) {
  248. type = type.split('/')
  249. contentType = contentType.split('/');
  250. if ('*' == type[0] && type[1] == contentType[1]) return true;
  251. if ('*' == type[1] && type[0] == contentType[0]) return true;
  252. }
  253. return !! ~contentType.indexOf(type);
  254. };
  255. // Callback for isXMLHttpRequest / xhr
  256. function isxhr() {
  257. return this.header('X-Requested-With', '').toLowerCase() === 'xmlhttprequest';
  258. }
  259. /**
  260. * Check if the request was an _XMLHttpRequest_.
  261. *
  262. * @return {Boolean}
  263. * @api public
  264. */
  265. req.__defineGetter__('isXMLHttpRequest', isxhr);
  266. req.__defineGetter__('xhr', isxhr);