arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
socketioMEANseed/server/node_modules/express/lib/utils.js
server/node_modules/express/lib/utils.jsRaw
  1/**
  2 * Module dependencies.
  3 */
  4
  5var contentDisposition = require('content-disposition');
  6var deprecate = require('depd')('express');
  7var mime = require('send').mime;
  8var basename = require('path').basename;
  9var etag = require('etag');
 10var proxyaddr = require('proxy-addr');
 11var qs = require('qs');
 12var querystring = require('querystring');
 13var typer = require('media-typer');
 14
 15/**
 16 * Return strong ETag for `body`.
 17 *
 18 * @param {String|Buffer} body
 19 * @param {String} [encoding]
 20 * @return {String}
 21 * @api private
 22 */
 23
 24exports.etag = function (body, encoding) {
 25  var buf = !Buffer.isBuffer(body)
 26    ? new Buffer(body, encoding)
 27    : body;
 28
 29  return etag(buf, {weak: false});
 30};
 31
 32/**
 33 * Return weak ETag for `body`.
 34 *
 35 * @param {String|Buffer} body
 36 * @param {String} [encoding]
 37 * @return {String}
 38 * @api private
 39 */
 40
 41exports.wetag = function wetag(body, encoding){
 42  var buf = !Buffer.isBuffer(body)
 43    ? new Buffer(body, encoding)
 44    : body;
 45
 46  return etag(buf, {weak: true});
 47};
 48
 49/**
 50 * Check if `path` looks absolute.
 51 *
 52 * @param {String} path
 53 * @return {Boolean}
 54 * @api private
 55 */
 56
 57exports.isAbsolute = function(path){
 58  if ('/' == path[0]) return true;
 59  if (':' == path[1] && '\\' == path[2]) return true;
 60  if ('\\\\' == path.substring(0, 2)) return true; // Microsoft Azure absolute path
 61};
 62
 63/**
 64 * Flatten the given `arr`.
 65 *
 66 * @param {Array} arr
 67 * @return {Array}
 68 * @api private
 69 */
 70
 71exports.flatten = function(arr, ret){
 72  ret = ret || [];
 73  var len = arr.length;
 74  for (var i = 0; i < len; ++i) {
 75    if (Array.isArray(arr[i])) {
 76      exports.flatten(arr[i], ret);
 77    } else {
 78      ret.push(arr[i]);
 79    }
 80  }
 81  return ret;
 82};
 83
 84/**
 85 * Normalize the given `type`, for example "html" becomes "text/html".
 86 *
 87 * @param {String} type
 88 * @return {Object}
 89 * @api private
 90 */
 91
 92exports.normalizeType = function(type){
 93  return ~type.indexOf('/')
 94    ? acceptParams(type)
 95    : { value: mime.lookup(type), params: {} };
 96};
 97
 98/**
 99 * Normalize `types`, for example "html" becomes "text/html".
100 *
101 * @param {Array} types
102 * @return {Array}
103 * @api private
104 */
105
106exports.normalizeTypes = function(types){
107  var ret = [];
108
109  for (var i = 0; i < types.length; ++i) {
110    ret.push(exports.normalizeType(types[i]));
111  }
112
113  return ret;
114};
115
116/**
117 * Generate Content-Disposition header appropriate for the filename.
118 * non-ascii filenames are urlencoded and a filename* parameter is added
119 *
120 * @param {String} filename
121 * @return {String}
122 * @api private
123 */
124
125exports.contentDisposition = deprecate.function(contentDisposition,
126  'utils.contentDisposition: use content-disposition npm module instead');
127
128/**
129 * Parse accept params `str` returning an
130 * object with `.value`, `.quality` and `.params`.
131 * also includes `.originalIndex` for stable sorting
132 *
133 * @param {String} str
134 * @return {Object}
135 * @api private
136 */
137
138function acceptParams(str, index) {
139  var parts = str.split(/ *; */);
140  var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index };
141
142  for (var i = 1; i < parts.length; ++i) {
143    var pms = parts[i].split(/ *= */);
144    if ('q' == pms[0]) {
145      ret.quality = parseFloat(pms[1]);
146    } else {
147      ret.params[pms[0]] = pms[1];
148    }
149  }
150
151  return ret;
152}
153
154/**
155 * Compile "etag" value to function.
156 *
157 * @param  {Boolean|String|Function} val
158 * @return {Function}
159 * @api private
160 */
161
162exports.compileETag = function(val) {
163  var fn;
164
165  if (typeof val === 'function') {
166    return val;
167  }
168
169  switch (val) {
170    case true:
171      fn = exports.wetag;
172      break;
173    case false:
174      break;
175    case 'strong':
176      fn = exports.etag;
177      break;
178    case 'weak':
179      fn = exports.wetag;
180      break;
181    default:
182      throw new TypeError('unknown value for etag function: ' + val);
183  }
184
185  return fn;
186}
187
188/**
189 * Compile "query parser" value to function.
190 *
191 * @param  {String|Function} val
192 * @return {Function}
193 * @api private
194 */
195
196exports.compileQueryParser = function compileQueryParser(val) {
197  var fn;
198
199  if (typeof val === 'function') {
200    return val;
201  }
202
203  switch (val) {
204    case true:
205      fn = querystring.parse;
206      break;
207    case false:
208      fn = newObject;
209      break;
210    case 'extended':
211      fn = qs.parse;
212      break;
213    case 'simple':
214      fn = querystring.parse;
215      break;
216    default:
217      throw new TypeError('unknown value for query parser function: ' + val);
218  }
219
220  return fn;
221}
222
223/**
224 * Compile "proxy trust" value to function.
225 *
226 * @param  {Boolean|String|Number|Array|Function} val
227 * @return {Function}
228 * @api private
229 */
230
231exports.compileTrust = function(val) {
232  if (typeof val === 'function') return val;
233
234  if (val === true) {
235    // Support plain true/false
236    return function(){ return true };
237  }
238
239  if (typeof val === 'number') {
240    // Support trusting hop count
241    return function(a, i){ return i < val };
242  }
243
244  if (typeof val === 'string') {
245    // Support comma-separated values
246    val = val.split(/ *, */);
247  }
248
249  return proxyaddr.compile(val || []);
250}
251
252/**
253 * Set the charset in a given Content-Type string.
254 *
255 * @param {String} type
256 * @param {String} charset
257 * @return {String}
258 * @api private
259 */
260
261exports.setCharset = function(type, charset){
262  if (!type || !charset) return type;
263
264  // parse type
265  var parsed = typer.parse(type);
266
267  // set charset
268  parsed.parameters.charset = charset;
269
270  // format type
271  return typer.format(parsed);
272};
273
274/**
275 * Return new empty objet.
276 *
277 * @return {Object}
278 * @api private
279 */
280
281function newObject() {
282  return {};
283}