mirror of
https://github.com/seejohnrun/haste-server
synced 2025-07-16 10:03:45 -07:00
Added node modules
This commit is contained in:
parent
ca9d4c18f7
commit
d1e0644a4e
575 changed files with 77900 additions and 6 deletions
451
node_modules/connect/lib/utils.js
generated
vendored
Normal file
451
node_modules/connect/lib/utils.js
generated
vendored
Normal file
|
@ -0,0 +1,451 @@
|
|||
|
||||
/*!
|
||||
* Connect - utils
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var crypto = require('crypto')
|
||||
, Path = require('path')
|
||||
, fs = require('fs');
|
||||
|
||||
/**
|
||||
* Flatten the given `arr`.
|
||||
*
|
||||
* @param {Array} arr
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.flatten = function(arr, ret){
|
||||
var ret = ret || []
|
||||
, len = arr.length;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (Array.isArray(arr[i])) {
|
||||
exports.flatten(arr[i], ret);
|
||||
} else {
|
||||
ret.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return md5 hash of the given string and optional encoding,
|
||||
* defaulting to hex.
|
||||
*
|
||||
* utils.md5('wahoo');
|
||||
* // => "e493298061761236c96b02ea6aa8a2ad"
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {String} encoding
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.md5 = function(str, encoding){
|
||||
return crypto
|
||||
.createHash('md5')
|
||||
.update(str)
|
||||
.digest(encoding || 'hex');
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge object b with object a.
|
||||
*
|
||||
* var a = { foo: 'bar' }
|
||||
* , b = { bar: 'baz' };
|
||||
*
|
||||
* utils.merge(a, b);
|
||||
* // => { foo: 'bar', bar: 'baz' }
|
||||
*
|
||||
* @param {Object} a
|
||||
* @param {Object} b
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.merge = function(a, b){
|
||||
if (a && b) {
|
||||
for (var key in b) {
|
||||
a[key] = b[key];
|
||||
}
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape the given string of `html`.
|
||||
*
|
||||
* @param {String} html
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.escape = function(html){
|
||||
return String(html)
|
||||
.replace(/&(?!\w+;)/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return a unique identifier with the given `len`.
|
||||
*
|
||||
* utils.uid(10);
|
||||
* // => "FDaS435D2z"
|
||||
*
|
||||
* @param {Number} len
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.uid = function(len) {
|
||||
var buf = []
|
||||
, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
, charlen = chars.length;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
buf.push(chars[getRandomInt(0, charlen - 1)]);
|
||||
}
|
||||
|
||||
return buf.join('');
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given cookie string into an object.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.parseCookie = function(str){
|
||||
var obj = {}
|
||||
, pairs = str.split(/[;,] */);
|
||||
for (var i = 0, len = pairs.length; i < len; ++i) {
|
||||
var pair = pairs[i]
|
||||
, eqlIndex = pair.indexOf('=')
|
||||
, key = pair.substr(0, eqlIndex).trim().toLowerCase()
|
||||
, val = pair.substr(++eqlIndex, pair.length).trim();
|
||||
|
||||
// quoted values
|
||||
if ('"' == val[0]) val = val.slice(1, -1);
|
||||
|
||||
// only assign once
|
||||
if (undefined == obj[key]) {
|
||||
val = val.replace(/\+/g, ' ');
|
||||
try {
|
||||
obj[key] = decodeURIComponent(val);
|
||||
} catch (err) {
|
||||
if (err instanceof URIError) {
|
||||
obj[key] = val;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the given object into a cookie string.
|
||||
*
|
||||
* utils.serializeCookie('name', 'tj', { httpOnly: true })
|
||||
* // => "name=tj; httpOnly"
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String} val
|
||||
* @param {Object} obj
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.serializeCookie = function(name, val, obj){
|
||||
var pairs = [name + '=' + encodeURIComponent(val)]
|
||||
, obj = obj || {};
|
||||
|
||||
if (obj.domain) pairs.push('domain=' + obj.domain);
|
||||
if (obj.path) pairs.push('path=' + obj.path);
|
||||
if (obj.expires) pairs.push('expires=' + obj.expires.toUTCString());
|
||||
if (obj.httpOnly) pairs.push('httpOnly');
|
||||
if (obj.secure) pairs.push('secure');
|
||||
|
||||
return pairs.join('; ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Pause `data` and `end` events on the given `obj`.
|
||||
* Middleware performing async tasks _should_ utilize
|
||||
* this utility (or similar), to re-emit data once
|
||||
* the async operation has completed, otherwise these
|
||||
* events may be lost.
|
||||
*
|
||||
* var pause = utils.pause(req);
|
||||
* fs.readFile(path, function(){
|
||||
* next();
|
||||
* pause.resume();
|
||||
* });
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.pause = function(obj){
|
||||
var onData
|
||||
, onEnd
|
||||
, events = [];
|
||||
|
||||
// buffer data
|
||||
obj.on('data', onData = function(data, encoding){
|
||||
events.push(['data', data, encoding]);
|
||||
});
|
||||
|
||||
// buffer end
|
||||
obj.on('end', onEnd = function(data, encoding){
|
||||
events.push(['end', data, encoding]);
|
||||
});
|
||||
|
||||
return {
|
||||
end: function(){
|
||||
obj.removeListener('data', onData);
|
||||
obj.removeListener('end', onEnd);
|
||||
},
|
||||
resume: function(){
|
||||
this.end();
|
||||
for (var i = 0, len = events.length; i < len; ++i) {
|
||||
obj.emit.apply(obj, events[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Check `req` and `res` to see if it has been modified.
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @param {ServerResponse} res
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.modified = function(req, res, headers) {
|
||||
var headers = headers || res._headers || {}
|
||||
, modifiedSince = req.headers['if-modified-since']
|
||||
, lastModified = headers['last-modified']
|
||||
, noneMatch = req.headers['if-none-match']
|
||||
, etag = headers['etag'];
|
||||
|
||||
if (noneMatch) noneMatch = noneMatch.split(/ *, */);
|
||||
|
||||
// check If-None-Match
|
||||
if (noneMatch && etag && ~noneMatch.indexOf(etag)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check If-Modified-Since
|
||||
if (modifiedSince && lastModified) {
|
||||
modifiedSince = new Date(modifiedSince);
|
||||
lastModified = new Date(lastModified);
|
||||
// Ignore invalid dates
|
||||
if (!isNaN(modifiedSince.getTime())) {
|
||||
if (lastModified <= modifiedSince) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Strip `Content-*` headers from `res`.
|
||||
*
|
||||
* @param {ServerResponse} res
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.removeContentHeaders = function(res){
|
||||
Object.keys(res._headers).forEach(function(field){
|
||||
if (0 == field.indexOf('content')) {
|
||||
res.removeHeader(field);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `req` is a conditional GET request.
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.conditionalGET = function(req) {
|
||||
return req.headers['if-modified-since']
|
||||
|| req.headers['if-none-match'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with 403 "Forbidden".
|
||||
*
|
||||
* @param {ServerResponse} res
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.forbidden = function(res) {
|
||||
var body = 'Forbidden';
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.setHeader('Content-Length', body.length);
|
||||
res.statusCode = 403;
|
||||
res.end(body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with 401 "Unauthorized".
|
||||
*
|
||||
* @param {ServerResponse} res
|
||||
* @param {String} realm
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.unauthorized = function(res, realm) {
|
||||
res.statusCode = 401;
|
||||
res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');
|
||||
res.end('Unauthorized');
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with 400 "Bad Request".
|
||||
*
|
||||
* @param {ServerResponse} res
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.badRequest = function(res) {
|
||||
res.statusCode = 400;
|
||||
res.end('Bad Request');
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with 304 "Not Modified".
|
||||
*
|
||||
* @param {ServerResponse} res
|
||||
* @param {Object} headers
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.notModified = function(res) {
|
||||
exports.removeContentHeaders(res);
|
||||
res.statusCode = 304;
|
||||
res.end();
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an ETag in the form of `"<size>-<mtime>"`
|
||||
* from the given `stat`.
|
||||
*
|
||||
* @param {Object} stat
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.etag = function(stat) {
|
||||
return '"' + stat.size + '-' + Number(stat.mtime) + '"';
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse "Range" header `str` relative to the given file `size`.
|
||||
*
|
||||
* @param {Number} size
|
||||
* @param {String} str
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.parseRange = function(size, str){
|
||||
var valid = true;
|
||||
var arr = str.substr(6).split(',').map(function(range){
|
||||
var range = range.split('-')
|
||||
, start = parseInt(range[0], 10)
|
||||
, end = parseInt(range[1], 10);
|
||||
|
||||
// -500
|
||||
if (isNaN(start)) {
|
||||
start = size - end;
|
||||
end = size - 1;
|
||||
// 500-
|
||||
} else if (isNaN(end)) {
|
||||
end = size - 1;
|
||||
}
|
||||
|
||||
// Invalid
|
||||
if (isNaN(start) || isNaN(end) || start > end) valid = false;
|
||||
|
||||
return { start: start, end: end };
|
||||
});
|
||||
return valid ? arr : undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given Cache-Control `str`.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.parseCacheControl = function(str){
|
||||
var directives = str.split(',')
|
||||
, obj = {};
|
||||
|
||||
for(var i = 0, len = directives.length; i < len; i++) {
|
||||
var parts = directives[i].split('=')
|
||||
, key = parts.shift().trim()
|
||||
, val = parseInt(parts.shift(), 10);
|
||||
|
||||
obj[key] = isNaN(val) ? true : val;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert array-like object to an `Array`.
|
||||
*
|
||||
* node-bench measured "16.5 times faster than Array.prototype.slice.call()"
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var toArray = exports.toArray = function(obj){
|
||||
var len = obj.length
|
||||
, arr = new Array(len);
|
||||
for (var i = 0; i < len; ++i) {
|
||||
arr[i] = obj[i];
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrun a random int, used by `utils.uid()`
|
||||
*
|
||||
* @param {Number} min
|
||||
* @param {Number} max
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue