mirror of
https://github.com/bodyrep/DemoApp.git
synced 2025-12-06 06:01:48 +00:00
little css
This commit is contained in:
5
app.js
5
app.js
@@ -12,11 +12,13 @@ var dbURL = 'mongodb://localhost/database';
|
||||
var db = require('mongoose').connect(dbURL);
|
||||
var qs = require('qs');
|
||||
var MongoStore = require('connect-mongo')(express);
|
||||
var gzippo = require('gzippo');
|
||||
|
||||
// Configuration
|
||||
app.configure(function(){
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'jade');
|
||||
app.use(express.compress());
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(express.cookieParser('my secret string'));
|
||||
@@ -34,7 +36,8 @@ app.configure(function(){
|
||||
next();
|
||||
});
|
||||
app.set('port', 3000);
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
//app.use(express.static(__dirname + '/public'));
|
||||
app.use(gzippo.staticGzip(__dirname + '/public', {contentTypeMatch: /text|javascript|json|svg/}));
|
||||
app.use(app.router);
|
||||
});
|
||||
|
||||
|
||||
13
node_modules/gzippo/.npmignore
generated
vendored
Normal file
13
node_modules/gzippo/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
node_modules/*
|
||||
.DS_STORE
|
||||
*.swp
|
||||
*.monitor
|
||||
nodemon-ignore
|
||||
.*.sw[a-z]
|
||||
*.un~i
|
||||
.DS_Store
|
||||
Icon?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
bench/*
|
||||
4
node_modules/gzippo/.travis.yml
generated
vendored
Normal file
4
node_modules/gzippo/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
5
node_modules/gzippo/CHANGELOG
generated
vendored
Normal file
5
node_modules/gzippo/CHANGELOG
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Changes from version 0.1 to 0.2:
|
||||
|
||||
`clientMaxAge` now defaults to 0.
|
||||
Zlib Deflate support
|
||||
Gzippo should now support external stores, gridfs, redis etc...
|
||||
70
node_modules/gzippo/README.md
generated
vendored
Normal file
70
node_modules/gzippo/README.md
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# gzippo [](https://secure.travis-ci.org/tomgco/gzippo)
|
||||
|
||||
gzippo pronounced `g-zippo` is a gzip middleware for Connect / expressjs using node-compress for better performace, in node 0.6 and up will be using the new zlib api.
|
||||
|
||||
gzippo currently only supports only gzipping static content files however a release is in progress to introduce streaming support.
|
||||
|
||||
## Notice
|
||||
|
||||
Please note that gzippo@0.0.X branch will only be tested for nodejs 0.4, where the soon to be released gzippo@0.1.X will work for node 0.6
|
||||
|
||||
## Installation
|
||||
|
||||
$ npm install gzippo
|
||||
|
||||
### Usage
|
||||
#### Static Gzip
|
||||
|
||||
In your express/connect server setup, use as follows:
|
||||
|
||||
var gzippo = require('gzippo');
|
||||
|
||||
//Replace the static provider with gzippo's
|
||||
//app.use(express.static(__dirname + '/public'));
|
||||
app.use(gzippo.staticGzip(__dirname + '/public'));
|
||||
|
||||
Options:
|
||||
|
||||
- `contentTypeMatch` - A regular expression tested against the Content-Type header to determine whether the response should be gzipped or not. The default value is `/text|javascript|json/`.
|
||||
- `maxAge` - cache-control max-age directive, defaulting to 1 day
|
||||
- `clientMaxAge` - browser cache-control max-age directive, defaulting to 1 week
|
||||
- `prefix` - A url prefix. If you want all your static content in a root path such as /resource/. Any url paths not matching will be ignored
|
||||
|
||||
Currently the gzipped version is created and stored in memory. This is not final and was done to get a working version
|
||||
up and about.
|
||||
|
||||
Gzippo now uses the native Zlib support found in node >= 0.6
|
||||
|
||||
#### Streaming Gzip
|
||||
|
||||
Starting in Connect 2.X Expressjs has the ability to use a streaming gzip module provided natively by connect. As this 2.X branch is not currently stable I have back ported the compress.js component into gzippo.
|
||||
|
||||
app.use(gzippo.staticGzip(__dirname + '/public'));
|
||||
app.use(gzippo.compress());
|
||||
|
||||
This has no caching and is currently unsupported as it will be included in a future connect 1.X release, up until then compress.js will be included in gzippo.
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2011 Tom Gallacher <<http://www.tomg.co>>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
3
node_modules/gzippo/index.js
generated
vendored
Normal file
3
node_modules/gzippo/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
exports.staticGzip = require('./lib/staticGzip.js');
|
||||
exports.compress = require('./lib/compress.js');
|
||||
exports.Store = require('./lib/store.js');
|
||||
139
node_modules/gzippo/lib/compress.js
generated
vendored
Normal file
139
node_modules/gzippo/lib/compress.js
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
|
||||
/*!
|
||||
* Connect - compress
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var zlib = require('zlib');
|
||||
|
||||
/**
|
||||
* Supported content-encoding methods.
|
||||
*/
|
||||
|
||||
exports.methods = {
|
||||
gzip: zlib.createGzip,
|
||||
deflate: zlib.createDeflate
|
||||
};
|
||||
|
||||
/**
|
||||
* Default filter function.
|
||||
*/
|
||||
|
||||
exports.filter = function(req, res){
|
||||
var type = res.getHeader('Content-Type') || '';
|
||||
return type.match(/json|text|javascript/);
|
||||
};
|
||||
|
||||
/**
|
||||
* Compress response data with gzip/deflate.
|
||||
*
|
||||
* Filter:
|
||||
*
|
||||
* A `filter` callback function may be passed to
|
||||
* replace the default logic of:
|
||||
*
|
||||
* exports.filter = function(req, res){
|
||||
* var type = res.getHeader('Content-Type') || '';
|
||||
* return type.match(/json|text|javascript/);
|
||||
* };
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* All remaining options are passed to the gzip/deflate
|
||||
* creation functions. Consult node's docs for additional details.
|
||||
*
|
||||
* - `chunkSize` (default: 16*1024)
|
||||
* - `windowBits`
|
||||
* - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
|
||||
* - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
|
||||
* - `strategy`: compression strategy
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function compress(options) {
|
||||
var options = options || {}
|
||||
, names = Object.keys(exports.methods)
|
||||
, filter = options.filter || exports.filter;
|
||||
|
||||
return function(req, res, next){
|
||||
var accept = req.headers['accept-encoding']
|
||||
, write = res.write
|
||||
, end = res.end
|
||||
, stream
|
||||
, method;
|
||||
|
||||
// vary
|
||||
res.setHeader('Vary', 'Accept-Encoding');
|
||||
|
||||
// proxy
|
||||
|
||||
res.write = function(chunk, encoding){
|
||||
if (!this.headerSent) this._implicitHeader();
|
||||
return stream
|
||||
? stream.write(chunk, encoding)
|
||||
: write.call(res, chunk, encoding);
|
||||
};
|
||||
|
||||
res.end = function(chunk, encoding){
|
||||
if (chunk) this.write(chunk, encoding);
|
||||
return stream
|
||||
? stream.end()
|
||||
: end.call(res);
|
||||
};
|
||||
|
||||
res.on('header', function(){
|
||||
// default request filter
|
||||
if (!filter(req, res)) return;
|
||||
|
||||
// SHOULD use identity
|
||||
if (!accept) return;
|
||||
|
||||
// head
|
||||
if ('HEAD' == req.method) return;
|
||||
|
||||
// default to gzip
|
||||
if ('*' == accept.trim()) method = 'gzip';
|
||||
|
||||
// compression method
|
||||
if (!method) {
|
||||
for (var i = 0, len = names.length; i < len; ++i) {
|
||||
if (~accept.indexOf(names[i])) {
|
||||
method = names[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compression method
|
||||
if (!method) return;
|
||||
|
||||
// compression stream
|
||||
stream = exports.methods[method](options);
|
||||
|
||||
// header fields
|
||||
res.setHeader('Content-Encoding', method);
|
||||
res.removeHeader('Content-Length');
|
||||
|
||||
// compression
|
||||
|
||||
stream.on('data', function(chunk){
|
||||
write.call(res, chunk);
|
||||
});
|
||||
|
||||
stream.on('end', function(){
|
||||
end.call(res);
|
||||
});
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
61
node_modules/gzippo/lib/fileAsset.js
generated
vendored
Normal file
61
node_modules/gzippo/lib/fileAsset.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
var FileAsset = module.exports = function FileAsset(name, options) {
|
||||
options = options || {};
|
||||
this._maxAge = options.maxAge || 86400000;
|
||||
this._mtime = options.mtime || new Date();
|
||||
|
||||
this._fileName = name;
|
||||
this._ctime = +Date.now();
|
||||
this.fileContents = [];
|
||||
this.fileContentsLength = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prototype.
|
||||
*/
|
||||
|
||||
FileAsset.prototype = {
|
||||
set maxAge(maxAge) {
|
||||
this._maxAge = maxAge;
|
||||
},
|
||||
|
||||
get maxAge() {
|
||||
return this._maxAge;
|
||||
},
|
||||
|
||||
get mtime() {
|
||||
return this._mtime;
|
||||
},
|
||||
|
||||
get isExpired() {
|
||||
return (this._ctime + this._maxAge) < +Date.now();
|
||||
},
|
||||
|
||||
get name() {
|
||||
return this._fileName;
|
||||
},
|
||||
|
||||
get content() {
|
||||
// var file = Buffer(this.fileContentsLength);
|
||||
// var pos = 0;
|
||||
// for (var i = 0; i < this.fileContents.length; i++) {
|
||||
// // this.fileContents[i] = this.fileContents[i].toString();
|
||||
// // buffer.copy(file, pos);
|
||||
// // pos += buffer.length;
|
||||
// }
|
||||
|
||||
return this.fileContents;
|
||||
},
|
||||
|
||||
get length() {
|
||||
return this.fileContentsLength;
|
||||
},
|
||||
|
||||
get data() {
|
||||
return {
|
||||
expires: this._expires,
|
||||
mtime: this._mtime,
|
||||
content: this.content,
|
||||
length: this.fileContentsLength
|
||||
};
|
||||
}
|
||||
};
|
||||
103
node_modules/gzippo/lib/memory.js
generated
vendored
Normal file
103
node_modules/gzippo/lib/memory.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
/*!
|
||||
* gzippo - MemoryStore
|
||||
*
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
var Store = require('./store'),
|
||||
util = require('util');
|
||||
|
||||
/**
|
||||
* new `MemoryStore`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var MemoryStore = module.exports = function MemoryStore() {
|
||||
Store.call(this);
|
||||
this.assets = {};
|
||||
};
|
||||
|
||||
util.inherits(MemoryStore, Store);
|
||||
|
||||
/**
|
||||
* Attempt to fetch an asset by its filename - `file`.
|
||||
*
|
||||
* @param {String} fileName
|
||||
* @param {Function} cb
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.get = function(fileName, cb) {
|
||||
var that = this;
|
||||
process.nextTick(function(){
|
||||
var expires,
|
||||
asset = that.assets[fileName];
|
||||
if (asset) {
|
||||
// expires = (typeof asset.expires === 'string') ?
|
||||
// +Date.parse(asset.expires) :
|
||||
// asset.expires;
|
||||
// if (!expires || +Date.now() < expires) {
|
||||
cb(null, asset);
|
||||
// } else {
|
||||
// that.purgeFile(file, cb);
|
||||
// }
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FileAsset} asset
|
||||
* @param {Function} cb
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.set = function(asset, cb) {
|
||||
var that = this;
|
||||
process.nextTick(function() {
|
||||
that.assets[asset.name] = asset.data;
|
||||
if(cb instanceof Function) cb();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* purge the cache
|
||||
*
|
||||
* @param {Function} cb
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.purge = function(cb){
|
||||
this.assets = {};
|
||||
if(cb instanceof Function) cb();
|
||||
};
|
||||
|
||||
/**
|
||||
* purge the an item from thecache
|
||||
*
|
||||
* @param {FileAsset} asset
|
||||
* @param {Function} cb
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.purgeFile = function(asset, cb){
|
||||
process.nextTick(function() {
|
||||
delete this.assets[asset.name];
|
||||
if(cb instanceof Function) cb();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch number of cached files.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.length = function(cb){
|
||||
cb(null, Object.keys(this.assets).length);
|
||||
};
|
||||
289
node_modules/gzippo/lib/staticGzip.js
generated
vendored
Normal file
289
node_modules/gzippo/lib/staticGzip.js
generated
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
/*!
|
||||
* Tom Gallacher
|
||||
*
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
// Commented out as I think that connect is avalible from within express...
|
||||
// try {
|
||||
// var staticMiddleware = require('connect').static;
|
||||
|
||||
// } catch (e) {
|
||||
// staticMiddleware = require('express').static;
|
||||
// }
|
||||
|
||||
var fs = require('fs'),
|
||||
parse = require('url').parse,
|
||||
path = require('path'),
|
||||
zlib = require('zlib'),
|
||||
MemoryStore = require('./memory'),
|
||||
StoreStream = require('./storeStream'),
|
||||
FileAsset = require('./fileAsset'),
|
||||
send = require('send'),
|
||||
mime = send.mime
|
||||
;
|
||||
|
||||
/**
|
||||
* Strip `Content-*` headers from `res`.
|
||||
*
|
||||
* @param {ServerResponse} res
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var removeContentHeaders = function(res){
|
||||
Object.keys(res._headers).forEach(function(field){
|
||||
if (0 === field.indexOf('content')) {
|
||||
res.removeHeader(field);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported content-encoding methods.
|
||||
*/
|
||||
|
||||
var methods = {
|
||||
gzip: zlib.createGzip,
|
||||
deflate: zlib.createDeflate
|
||||
};
|
||||
|
||||
/**
|
||||
* Default filter function.
|
||||
*/
|
||||
|
||||
exports.filter = function(req, res){
|
||||
var type = res.getHeader('Content-Type') || '';
|
||||
return type.match(/json|text|javascript/);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the `req` url with memoization.
|
||||
*
|
||||
* @param {ServerRequest} req
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var parseUrl = function(req){
|
||||
var parsed = req._parsedUrl;
|
||||
if (parsed && parsed.href == req.url) {
|
||||
return parsed;
|
||||
} else {
|
||||
return req._parsedUrl = parse(req.url);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* By default gzip's static's that match the given regular expression /text|javascript|json/
|
||||
* and then serves them with Connects static provider, denoted by the given `dirPath`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxAge` how long gzippo should cache gziped assets, defaulting to 1 day
|
||||
* - `clientMaxAge` client cache-control max-age directive, defaulting to 0; 604800000 is one week.
|
||||
* - `contentTypeMatch` - A regular expression tested against the Content-Type header to determine whether the response
|
||||
* should be gzipped or not. The default value is `/text|javascript|json/`.
|
||||
* - `prefix` - A url prefix. If you want all your static content in a root path such as /resource/. Any url paths not matching will be ignored
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect.createServer(
|
||||
* connect.staticGzip(__dirname + '/public/');
|
||||
* );
|
||||
*
|
||||
* connect.createServer(
|
||||
* connect.staticGzip(__dirname + '/public/', {maxAge: 86400000});
|
||||
* );
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function staticGzip(dirPath, options){
|
||||
options = options || {};
|
||||
|
||||
var maxAge = options.maxAge || 86400000,
|
||||
contentTypeMatch = options.contentTypeMatch || /text|javascript|json/,
|
||||
clientMaxAge = options.clientMaxAge || 604800000,
|
||||
prefix = options.prefix || '',
|
||||
names = Object.keys(methods),
|
||||
compressionOptions = options.compression || {},
|
||||
store = options.store || new MemoryStore();
|
||||
|
||||
if (!dirPath) throw new Error('You need to provide the directory to your static content.');
|
||||
if (!contentTypeMatch.test) throw new Error('contentTypeMatch: must be a regular expression.');
|
||||
|
||||
dirPath = path.normalize(dirPath);
|
||||
|
||||
return function(req, res, next) {
|
||||
var acceptEncoding = req.headers['accept-encoding'] || '',
|
||||
url,
|
||||
filename,
|
||||
contentType,
|
||||
charset,
|
||||
method;
|
||||
|
||||
function pass(name) {
|
||||
send(req, url.substring(prefix.length))
|
||||
.maxage(clientMaxAge || 0)
|
||||
.root(dirPath)
|
||||
.pipe(res)
|
||||
;
|
||||
}
|
||||
|
||||
function setHeaders(stat, asset) {
|
||||
res.setHeader('Content-Type', contentType);
|
||||
res.setHeader('Content-Encoding', method);
|
||||
res.setHeader('Vary', 'Accept-Encoding');
|
||||
// if cache version is avalible then add this.
|
||||
if (asset) {
|
||||
// res.setHeader('Content-Length', asset.length);
|
||||
res.setHeader('ETag', '"' + asset.length + '-' + Number(asset.mtime) + '"');
|
||||
res.setHeader('Last-Modified', asset.mtime.toUTCString());
|
||||
}
|
||||
res.setHeader('Date', new Date().toUTCString());
|
||||
res.setHeader('Expires', new Date(Date.now() + clientMaxAge).toUTCString());
|
||||
res.setHeader('Cache-Control', 'public, max-age=' + (clientMaxAge / 1000));
|
||||
}
|
||||
|
||||
// function gzipAndSend(filename, gzipName, mtime) {
|
||||
// gzippo(filename, charset, function(gzippedData) {
|
||||
// gzippoCache[gzipName] = {
|
||||
// 'ctime': Date.now(),
|
||||
// 'mtime': mtime,
|
||||
// 'content': gzippedData
|
||||
// };
|
||||
// sendGzipped(gzippoCache[gzipName]);
|
||||
// });
|
||||
// }
|
||||
|
||||
function forbidden(res) {
|
||||
var body = 'Forbidden';
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.setHeader('Content-Length', body.length);
|
||||
res.statusCode = 403;
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||
return next();
|
||||
}
|
||||
|
||||
url = decodeURI(parseUrl(req).pathname);
|
||||
|
||||
// Allow a url path prefix
|
||||
if (url.substring(0, prefix.length) !== prefix) {
|
||||
return next();
|
||||
}
|
||||
|
||||
filename = path.normalize(path.join(dirPath, url.substring(prefix.length)));
|
||||
// malicious path
|
||||
if (0 != filename.indexOf(dirPath)){
|
||||
return forbidden(res);
|
||||
}
|
||||
|
||||
// directory index file support
|
||||
if (filename.substr(-1) === '/') filename += 'index.html';
|
||||
|
||||
|
||||
contentType = mime.lookup(filename);
|
||||
charset = mime.charsets.lookup(contentType, 'UTF-8');
|
||||
contentType = contentType + (charset ? '; charset=' + charset : '');
|
||||
|
||||
// default to gzip
|
||||
if ('*' == acceptEncoding.trim()) method = 'gzip';
|
||||
|
||||
// compression method
|
||||
if (!method) {
|
||||
for (var i = 0, len = names.length; i < len; ++i) {
|
||||
if (~acceptEncoding.indexOf(names[i])) {
|
||||
method = names[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!method) return pass(filename);
|
||||
|
||||
fs.stat(filename, function(err, stat) {
|
||||
|
||||
if (err) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!contentTypeMatch.test(contentType)) {
|
||||
return pass(filename);
|
||||
}
|
||||
|
||||
// superceeded by if (!method) return;
|
||||
// if (!~acceptEncoding.indexOf('gzip')) {
|
||||
// return pass(filename);
|
||||
// }
|
||||
|
||||
var base = path.basename(filename),
|
||||
dir = path.dirname(filename),
|
||||
gzipName = path.join(dir, base + '.gz');
|
||||
|
||||
var sendGzipped = function(filename) {
|
||||
var stream = fs.createReadStream(filename);
|
||||
|
||||
req.on('close', stream.destroy.bind(stream));
|
||||
|
||||
var storeStream = new StoreStream(store, filename, {
|
||||
mtime: stat.mtime,
|
||||
maxAge: options.maxAge
|
||||
});
|
||||
|
||||
var compressionStream = methods[method](options.compression);
|
||||
|
||||
stream.pipe(compressionStream).pipe(storeStream).pipe(res);
|
||||
|
||||
stream.on('error', function(err){
|
||||
if (res.headerSent) {
|
||||
console.error(err.stack);
|
||||
req.destroy();
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
store.get(decodeURI(filename), function(err, asset) {
|
||||
setHeaders(stat, asset);
|
||||
if (err) {
|
||||
// handle error
|
||||
|
||||
} else if (!asset) {
|
||||
sendGzipped(decodeURI(filename));
|
||||
} else if ((asset.mtime < stat.mtime) || asset.isExpired) {
|
||||
sendGzipped(decodeURI(filename));
|
||||
}
|
||||
else if (req.headers['if-modified-since'] && asset &&
|
||||
// Optimisation: new Date().getTime is 90% faster that Date.parse()
|
||||
+stat.mtime <= new Date(req.headers['if-modified-since']).getTime()) {
|
||||
removeContentHeaders(res);
|
||||
res.statusCode = 304;
|
||||
return res.end();
|
||||
}
|
||||
else {
|
||||
// StoreReadStream to pipe to res.
|
||||
// console.log("hit: " + filename + " length: " + asset.length);
|
||||
for (var i = 0; i < asset.content.length; i++) {
|
||||
res.write(asset.content[i], 'binary');
|
||||
}
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
11
node_modules/gzippo/lib/store.js
generated
vendored
Normal file
11
node_modules/gzippo/lib/store.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
var util = require('util');
|
||||
|
||||
/*
|
||||
* gzippo - store
|
||||
* Copyright(c) 2012 Tom Gallacher
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
var Store = module.exports = function Store(options) {
|
||||
if (!(this instanceof Store)) return new Store(options);
|
||||
};
|
||||
119
node_modules/gzippo/lib/storeStream.js
generated
vendored
Normal file
119
node_modules/gzippo/lib/storeStream.js
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
var util = require('util'),
|
||||
stream = require('stream'),
|
||||
FileAsset = require('./fileAsset');
|
||||
|
||||
/*
|
||||
* gzippo - StoreStream
|
||||
* Copyright(c) 2012 Tom Gallacher
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
var StoreStream = module.exports = function StoreStream(store, fileName, options) {
|
||||
if (!(this instanceof StoreStream)) return new StoreStream(store, options);
|
||||
options = options || {};
|
||||
|
||||
this._queue = [];
|
||||
this._processing = false;
|
||||
this._ended = false;
|
||||
this.readable = true;
|
||||
this.writable = true;
|
||||
|
||||
this._asset = new FileAsset(fileName, options);
|
||||
this._store = store;
|
||||
};
|
||||
|
||||
util.inherits(StoreStream, stream.Stream);
|
||||
|
||||
StoreStream.prototype.write = function write(chunk, cb) {
|
||||
if (this._ended) {
|
||||
return this.emit('error', new Error('Cannot write after end'));
|
||||
}
|
||||
|
||||
if (arguments.length === 1 && typeof chunk === 'function') {
|
||||
cb = chunk;
|
||||
chunk = null;
|
||||
}
|
||||
|
||||
if (!chunk) {
|
||||
chunk = null;
|
||||
} else if (typeof chunk === 'string') {
|
||||
chunk = new Buffer(chunk);
|
||||
} else if (!Buffer.isBuffer(chunk)) {
|
||||
return this.emit('error', new Error('Invalid argument'));
|
||||
}
|
||||
|
||||
|
||||
var empty = this._queue.length === 0;
|
||||
|
||||
this._queue.push([chunk, cb]);
|
||||
this._process();
|
||||
if (!empty) {
|
||||
this._needDrain = true;
|
||||
}
|
||||
return empty;
|
||||
};
|
||||
|
||||
StoreStream.prototype.flush = function flush(cb) {
|
||||
return this.write(cb);
|
||||
};
|
||||
|
||||
StoreStream.prototype.end = function end(chunk, cb) {
|
||||
var self = this;
|
||||
this._ending = true;
|
||||
var ret = this.write(chunk, function() {
|
||||
self.emit('end');
|
||||
process.nextTick(function() {
|
||||
self._store.set(self._asset);
|
||||
});
|
||||
if (cb) cb();
|
||||
});
|
||||
this._ended = true;
|
||||
return ret;
|
||||
};
|
||||
|
||||
StoreStream.prototype._process = function() {
|
||||
var self = this;
|
||||
if (this._processing || this._paused) return;
|
||||
|
||||
if (this._queue.length === 0) {
|
||||
if (this._needDrain) {
|
||||
this._needDrain = false;
|
||||
this.emit('drain');
|
||||
}
|
||||
// nothing to do, waiting for more data at this point.
|
||||
return;
|
||||
}
|
||||
|
||||
var req = this._queue.shift();
|
||||
var cb = req.pop();
|
||||
var chunk = req.pop();
|
||||
|
||||
if (this._ending && this._queue.length === 0) {
|
||||
this._flush = true;
|
||||
}
|
||||
|
||||
if (chunk !== null) {
|
||||
self.emit('data', chunk);
|
||||
this._asset.fileContents.push(chunk);
|
||||
}
|
||||
|
||||
// finished with the chunk.
|
||||
self._processing = false;
|
||||
if (cb) cb();
|
||||
self._process();
|
||||
};
|
||||
|
||||
StoreStream.prototype.destory = function() {
|
||||
this._paused = true;
|
||||
StoreStream.prototype.end.call(this);
|
||||
};
|
||||
|
||||
StoreStream.prototype.pause = function() {
|
||||
this._paused = true;
|
||||
this.emit('pause');
|
||||
};
|
||||
|
||||
StoreStream.prototype.resume = function() {
|
||||
this._paused = false;
|
||||
this._process();
|
||||
};
|
||||
4
node_modules/gzippo/node_modules/send/.npmignore
generated
vendored
Normal file
4
node_modules/gzippo/node_modules/send/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
support
|
||||
test
|
||||
examples
|
||||
*.sock
|
||||
25
node_modules/gzippo/node_modules/send/History.md
generated
vendored
Normal file
25
node_modules/gzippo/node_modules/send/History.md
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
0.1.0 / 2012-08-25
|
||||
==================
|
||||
|
||||
* add options parameter to send() that is passed to fs.createReadStream() [kanongil]
|
||||
|
||||
0.0.4 / 2012-08-16
|
||||
==================
|
||||
|
||||
* allow custom "Accept-Ranges" definition
|
||||
|
||||
0.0.3 / 2012-07-16
|
||||
==================
|
||||
|
||||
* fix normalization of the root directory. Closes #3
|
||||
|
||||
0.0.2 / 2012-07-09
|
||||
==================
|
||||
|
||||
* add passing of req explicitly for now (YUCK)
|
||||
|
||||
0.0.1 / 2010-01-03
|
||||
==================
|
||||
|
||||
* Initial release
|
||||
8
node_modules/gzippo/node_modules/send/Makefile
generated
vendored
Normal file
8
node_modules/gzippo/node_modules/send/Makefile
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
test:
|
||||
@./node_modules/.bin/mocha \
|
||||
--require should \
|
||||
--reporter spec \
|
||||
--bail
|
||||
|
||||
.PHONY: test
|
||||
123
node_modules/gzippo/node_modules/send/Readme.md
generated
vendored
Normal file
123
node_modules/gzippo/node_modules/send/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
# send
|
||||
|
||||
Send is Connect's `static()` extracted for generalized use, a streaming static file
|
||||
server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.
|
||||
|
||||
## Installation
|
||||
|
||||
$ npm install send
|
||||
|
||||
## Examples
|
||||
|
||||
Small:
|
||||
|
||||
```js
|
||||
var http = require('http');
|
||||
var send = require('send');
|
||||
|
||||
var app = http.createServer(function(req, res){
|
||||
send(req, req.url).pipe(res);
|
||||
});
|
||||
```
|
||||
|
||||
Serving from a root directory with custom error-handling:
|
||||
|
||||
```js
|
||||
var http = require('http');
|
||||
var send = require('send');
|
||||
|
||||
var app = http.createServer(function(req, res){
|
||||
// your custom error-handling logic:
|
||||
function error(err) {
|
||||
res.statusCode = err.status || 500;
|
||||
res.end(err.message);
|
||||
}
|
||||
|
||||
// your custom directory handling logic:
|
||||
function redirect() {
|
||||
res.statusCode = 301;
|
||||
res.setHeader('Location', req.url + '/');
|
||||
res.end('Redirecting to ' + req.url + '/');
|
||||
}
|
||||
|
||||
// transfer arbitrary files from within
|
||||
// /www/example.com/public/*
|
||||
send(req, url.parse(req.url).pathname)
|
||||
.root('/www/example.com/public')
|
||||
.on('error', error)
|
||||
.on('directory', redirect)
|
||||
.pipe(res);
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Events
|
||||
|
||||
- `error` an error occurred `(err)`
|
||||
- `directory` a directory was requested
|
||||
- `stream` file streaming has started `(stream)`
|
||||
- `end` streaming has completed
|
||||
|
||||
### .root(dir)
|
||||
|
||||
Serve files relative to `path`. Aliased as `.from(dir)`.
|
||||
|
||||
### .index(path)
|
||||
|
||||
By default send supports "index.html" files, to disable this
|
||||
invoke `.index(false)` or to supply a new index pass a string.
|
||||
|
||||
### .maxage(ms)
|
||||
|
||||
Provide a max-age in milliseconds for http caching, defaults to 0.
|
||||
|
||||
## Error-handling
|
||||
|
||||
By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.
|
||||
|
||||
## Caching
|
||||
|
||||
It does _not_ perform internal caching, you should use a reverse proxy cache such
|
||||
as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).
|
||||
|
||||
## Debugging
|
||||
|
||||
To enable `debug()` instrumentation output export __DEBUG__:
|
||||
|
||||
```
|
||||
$ DEBUG=send node app
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
```
|
||||
$ npm install
|
||||
$ make test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
2
node_modules/gzippo/node_modules/send/index.js
generated
vendored
Normal file
2
node_modules/gzippo/node_modules/send/index.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
module.exports = require('./lib/send');
|
||||
473
node_modules/gzippo/node_modules/send/lib/send.js
generated
vendored
Normal file
473
node_modules/gzippo/node_modules/send/lib/send.js
generated
vendored
Normal file
@@ -0,0 +1,473 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var debug = require('debug')('send')
|
||||
, parseRange = require('range-parser')
|
||||
, Stream = require('stream')
|
||||
, mime = require('mime')
|
||||
, fresh = require('fresh')
|
||||
, path = require('path')
|
||||
, http = require('http')
|
||||
, fs = require('fs')
|
||||
, basename = path.basename
|
||||
, normalize = path.normalize
|
||||
, join = path.join
|
||||
, utils = require('./utils');
|
||||
|
||||
/**
|
||||
* Expose `send`.
|
||||
*/
|
||||
|
||||
exports = module.exports = send;
|
||||
|
||||
/**
|
||||
* Expose mime module.
|
||||
*/
|
||||
|
||||
exports.mime = mime;
|
||||
|
||||
/**
|
||||
* Return a `SendStream` for `req` and `path`.
|
||||
*
|
||||
* @param {Request} req
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @return {SendStream}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function send(req, path, options) {
|
||||
return new SendStream(req, path, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a `SendStream` with the given `path`.
|
||||
*
|
||||
* Events:
|
||||
*
|
||||
* - `error` an error occurred
|
||||
* - `stream` file streaming has started
|
||||
* - `end` streaming has completed
|
||||
* - `directory` a directory was requested
|
||||
*
|
||||
* @param {Request} req
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SendStream(req, path, options) {
|
||||
var self = this;
|
||||
this.req = req;
|
||||
this.path = path;
|
||||
this.options = options || {};
|
||||
this.maxage(0);
|
||||
this.hidden(false);
|
||||
this.index('index.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from `Stream.prototype`.
|
||||
*/
|
||||
|
||||
SendStream.prototype.__proto__ = Stream.prototype;
|
||||
|
||||
/**
|
||||
* Enable or disable "hidden" (dot) files.
|
||||
*
|
||||
* @param {Boolean} path
|
||||
* @return {SendStream}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SendStream.prototype.hidden = function(val){
|
||||
debug('hidden %s', val);
|
||||
this._hidden = val;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set index `path`, set to a falsy
|
||||
* value to disable index support.
|
||||
*
|
||||
* @param {String|Boolean} path
|
||||
* @return {SendStream}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SendStream.prototype.index = function(path){
|
||||
debug('index %s', path);
|
||||
this._index = path;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set root `path`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {SendStream}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SendStream.prototype.root =
|
||||
SendStream.prototype.from = function(path){
|
||||
this._root = normalize(path);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set max-age to `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {SendStream}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SendStream.prototype.maxage = function(ms){
|
||||
if (Infinity == ms) ms = 60 * 60 * 24 * 365 * 1000;
|
||||
debug('max-age %d', ms);
|
||||
this._maxage = ms;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit error with `status`.
|
||||
*
|
||||
* @param {Number} status
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.error = function(status, err){
|
||||
var res = this.res;
|
||||
var msg = http.STATUS_CODES[status];
|
||||
err = err || new Error(msg);
|
||||
err.status = status;
|
||||
if (this.listeners('error').length) return this.emit('error', err);
|
||||
res.statusCode = err.status;
|
||||
res.end(msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the pathname is potentially malicious.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.isMalicious = function(){
|
||||
return !this._root && ~this.path.indexOf('..');
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the pathname ends with "/".
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.hasTrailingSlash = function(){
|
||||
return '/' == this.path[this.path.length - 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the basename leads with ".".
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.hasLeadingDot = function(){
|
||||
return '.' == basename(this.path)[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this is a conditional GET request.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.isConditionalGET = function(){
|
||||
return this.req.headers['if-none-match']
|
||||
|| this.req.headers['if-modified-since'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Strip content-* header fields.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.removeContentHeaderFields = function(){
|
||||
var res = this.res;
|
||||
Object.keys(res._headers).forEach(function(field){
|
||||
if (0 == field.indexOf('content')) {
|
||||
res.removeHeader(field);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with 304 not modified.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.notModified = function(){
|
||||
var res = this.res;
|
||||
debug('not modified');
|
||||
this.removeContentHeaderFields();
|
||||
res.statusCode = 304;
|
||||
res.end();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the request is cacheable, aka
|
||||
* responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}).
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.isCachable = function(){
|
||||
var res = this.res;
|
||||
return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle stat() error.
|
||||
*
|
||||
* @param {Error} err
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.onStatError = function(err){
|
||||
var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR'];
|
||||
if (~notfound.indexOf(err.code)) return this.error(404, err);
|
||||
this.error(500, err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the cache is fresh.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.isFresh = function(){
|
||||
return fresh(this.req.headers, this.res._headers);
|
||||
};
|
||||
|
||||
/**
|
||||
* Redirect to `path`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.redirect = function(path){
|
||||
if (this.listeners('directory').length) return this.emit('directory');
|
||||
var res = this.res;
|
||||
path += '/';
|
||||
res.statusCode = 301;
|
||||
res.setHeader('Location', path);
|
||||
res.end('Redirecting to ' + utils.escape(path));
|
||||
};
|
||||
|
||||
/**
|
||||
* Pipe to `res.
|
||||
*
|
||||
* @param {Stream} res
|
||||
* @return {Stream} res
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SendStream.prototype.pipe = function(res){
|
||||
var self = this
|
||||
, args = arguments
|
||||
, path = this.path
|
||||
, root = this._root;
|
||||
|
||||
// references
|
||||
this.res = res;
|
||||
|
||||
// invalid request uri
|
||||
path = utils.decode(path);
|
||||
if (-1 == path) return this.error(400);
|
||||
|
||||
// null byte(s)
|
||||
if (~path.indexOf('\0')) return this.error(400);
|
||||
|
||||
// join / normalize from optional root dir
|
||||
if (root) path = normalize(join(this._root, path));
|
||||
|
||||
// ".." is malicious without "root"
|
||||
if (this.isMalicious()) return this.error(403);
|
||||
|
||||
// malicious path
|
||||
if (root && 0 != path.indexOf(root)) return this.error(403);
|
||||
|
||||
// hidden file support
|
||||
if (!this._hidden && this.hasLeadingDot()) return this.error(404);
|
||||
|
||||
// index file support
|
||||
if (this._index && this.hasTrailingSlash()) path += this._index;
|
||||
|
||||
debug('stat "%s"', path);
|
||||
fs.stat(path, function(err, stat){
|
||||
if (err) return self.onStatError(err);
|
||||
if (stat.isDirectory()) return self.redirect(self.path);
|
||||
self.send(path, stat);
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfer `path`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SendStream.prototype.send = function(path, stat){
|
||||
var options = this.options;
|
||||
var len = stat.size;
|
||||
var res = this.res;
|
||||
var req = this.req;
|
||||
var ranges = req.headers.range;
|
||||
var offset = options.start || 0;
|
||||
|
||||
// set header fields
|
||||
this.setHeader(stat);
|
||||
|
||||
// set content-type
|
||||
this.type(path);
|
||||
|
||||
// conditional GET support
|
||||
if (this.isConditionalGET()
|
||||
&& this.isCachable()
|
||||
&& this.isFresh()) {
|
||||
return this.notModified();
|
||||
}
|
||||
|
||||
// adjust len to start/end options
|
||||
len = Math.max(0, len - offset);
|
||||
if (options.end !== undefined) {
|
||||
var bytes = options.end - offset + 1;
|
||||
if (len > bytes) len = bytes;
|
||||
}
|
||||
|
||||
// Range support
|
||||
if (ranges) {
|
||||
ranges = parseRange(len, ranges);
|
||||
|
||||
// unsatisfiable
|
||||
if (-1 == ranges) {
|
||||
res.setHeader('Content-Range', 'bytes */' + stat.size);
|
||||
return this.error(416);
|
||||
}
|
||||
|
||||
// valid (syntactically invalid ranges are treated as a regular response)
|
||||
if (-2 != ranges) {
|
||||
options.start = offset + ranges[0].start;
|
||||
options.end = offset + ranges[0].end;
|
||||
|
||||
// Content-Range
|
||||
res.statusCode = 206;
|
||||
res.setHeader('Content-Range', 'bytes '
|
||||
+ ranges[0].start
|
||||
+ '-'
|
||||
+ ranges[0].end
|
||||
+ '/'
|
||||
+ len);
|
||||
len = options.end - options.start + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// content-length
|
||||
res.setHeader('Content-Length', len);
|
||||
|
||||
// HEAD support
|
||||
if ('HEAD' == req.method) return res.end();
|
||||
|
||||
this.stream(path, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Stream `path` to the response.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.stream = function(path, options){
|
||||
// TODO: this is all lame, refactor meeee
|
||||
var self = this;
|
||||
var res = this.res;
|
||||
var req = this.req;
|
||||
|
||||
// pipe
|
||||
var stream = fs.createReadStream(path, options);
|
||||
this.emit('stream', stream);
|
||||
stream.pipe(res);
|
||||
|
||||
// socket closed, done with the fd
|
||||
req.on('close', stream.destroy.bind(stream));
|
||||
|
||||
// error handling code-smell
|
||||
stream.on('error', function(err){
|
||||
// no hope in responding
|
||||
if (res._header) {
|
||||
console.error(err.stack);
|
||||
req.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// 500
|
||||
err.status = 500;
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
// end
|
||||
stream.on('end', function(){
|
||||
self.emit('end');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set content-type based on `path`
|
||||
* if it hasn't been explicitly set.
|
||||
*
|
||||
* @param {String} path
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.type = function(path){
|
||||
var res = this.res;
|
||||
if (res.getHeader('Content-Type')) return;
|
||||
var type = mime.lookup(path);
|
||||
var charset = mime.charsets.lookup(type);
|
||||
debug('content-type %s', type);
|
||||
res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
|
||||
};
|
||||
|
||||
/**
|
||||
* Set reaponse header fields, most
|
||||
* fields may be pre-defined.
|
||||
*
|
||||
* @param {Object} stat
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SendStream.prototype.setHeader = function(stat){
|
||||
var res = this.res;
|
||||
if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes');
|
||||
if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat));
|
||||
if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString());
|
||||
if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (this._maxage / 1000));
|
||||
if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString());
|
||||
};
|
||||
47
node_modules/gzippo/node_modules/send/lib/utils.js
generated
vendored
Normal file
47
node_modules/gzippo/node_modules/send/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
/**
|
||||
* Return an ETag in the form of `"<size>-<mtime>"`
|
||||
* from the given `stat`.
|
||||
*
|
||||
* @param {Object} stat
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.etag = function(stat) {
|
||||
return '"' + stat.size + '-' + Number(stat.mtime) + '"';
|
||||
};
|
||||
|
||||
/**
|
||||
* decodeURIComponent.
|
||||
*
|
||||
* Allows V8 to only deoptimize this fn instead of all
|
||||
* of send().
|
||||
*
|
||||
* @param {String} path
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.decode = function(path){
|
||||
try {
|
||||
return decodeURIComponent(path);
|
||||
} catch (err) {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape the given string of `html`.
|
||||
*
|
||||
* @param {String} html
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.escape = function(html){
|
||||
return String(html)
|
||||
.replace(/&(?!\w+;)/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
};
|
||||
4
node_modules/gzippo/node_modules/send/node_modules/debug/.npmignore
generated
vendored
Normal file
4
node_modules/gzippo/node_modules/send/node_modules/debug/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
support
|
||||
test
|
||||
examples
|
||||
*.sock
|
||||
62
node_modules/gzippo/node_modules/send/node_modules/debug/History.md
generated
vendored
Normal file
62
node_modules/gzippo/node_modules/send/node_modules/debug/History.md
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
0.7.2 / 2013-02-06
|
||||
==================
|
||||
|
||||
* fix package.json
|
||||
* fix: Mobile Safari (private mode) is broken with debug
|
||||
* fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
|
||||
|
||||
0.7.1 / 2013-02-05
|
||||
==================
|
||||
|
||||
* add repository URL to package.json
|
||||
* add DEBUG_COLORED to force colored output
|
||||
* add browserify support
|
||||
* fix component. Closes #24
|
||||
|
||||
0.7.0 / 2012-05-04
|
||||
==================
|
||||
|
||||
* Added .component to package.json
|
||||
* Added debug.component.js build
|
||||
|
||||
0.6.0 / 2012-03-16
|
||||
==================
|
||||
|
||||
* Added support for "-" prefix in DEBUG [Vinay Pulim]
|
||||
* Added `.enabled` flag to the node version [TooTallNate]
|
||||
|
||||
0.5.0 / 2012-02-02
|
||||
==================
|
||||
|
||||
* Added: humanize diffs. Closes #8
|
||||
* Added `debug.disable()` to the CS variant
|
||||
* Removed padding. Closes #10
|
||||
* Fixed: persist client-side variant again. Closes #9
|
||||
|
||||
0.4.0 / 2012-02-01
|
||||
==================
|
||||
|
||||
* Added browser variant support for older browsers [TooTallNate]
|
||||
* Added `debug.enable('project:*')` to browser variant [TooTallNate]
|
||||
* Added padding to diff (moved it to the right)
|
||||
|
||||
0.3.0 / 2012-01-26
|
||||
==================
|
||||
|
||||
* Added millisecond diff when isatty, otherwise UTC string
|
||||
|
||||
0.2.0 / 2012-01-22
|
||||
==================
|
||||
|
||||
* Added wildcard support
|
||||
|
||||
0.1.0 / 2011-12-02
|
||||
==================
|
||||
|
||||
* Added: remove colors unless stderr isatty [TooTallNate]
|
||||
|
||||
0.0.1 / 2010-01-03
|
||||
==================
|
||||
|
||||
* Initial release
|
||||
115
node_modules/gzippo/node_modules/send/node_modules/debug/Readme.md
generated
vendored
Normal file
115
node_modules/gzippo/node_modules/send/node_modules/debug/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
# debug
|
||||
|
||||
tiny node.js debugging utility modelled after node core's debugging technique.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install debug
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
|
||||
|
||||
Example _app.js_:
|
||||
|
||||
```js
|
||||
var debug = require('debug')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %s', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
```
|
||||
|
||||
Example _worker.js_:
|
||||
|
||||
```js
|
||||
var debug = require('debug')('worker');
|
||||
|
||||
setInterval(function(){
|
||||
debug('doing some work');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Millisecond diff
|
||||
|
||||
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
|
||||
|
||||

|
||||
|
||||
When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
|
||||
|
||||

|
||||
|
||||
## Conventions
|
||||
|
||||
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
|
||||
|
||||
## Wildcards
|
||||
|
||||
The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
|
||||
|
||||
You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:".
|
||||
|
||||
## Browser support
|
||||
|
||||
Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.
|
||||
|
||||
```js
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1200);
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
9
node_modules/gzippo/node_modules/send/node_modules/debug/component.json
generated
vendored
Normal file
9
node_modules/gzippo/node_modules/send/node_modules/debug/component.json
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"repo": "visionmedia/debug",
|
||||
"description": "small debugging utility",
|
||||
"version": "0.7.2",
|
||||
"keywords": ["debug", "log", "debugger"],
|
||||
"scripts": ["index.js", "debug.js"],
|
||||
"dependencies": {}
|
||||
}
|
||||
124
node_modules/gzippo/node_modules/send/node_modules/debug/debug.js
generated
vendored
Normal file
124
node_modules/gzippo/node_modules/send/node_modules/debug/debug.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
|
||||
/**
|
||||
* Expose `debug()` as the module.
|
||||
*/
|
||||
|
||||
module.exports = debug;
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Type}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function debug(name) {
|
||||
if (!debug.enabled(name)) return function(){};
|
||||
|
||||
return function(fmt){
|
||||
var curr = new Date;
|
||||
var ms = curr - (debug[name] || curr);
|
||||
debug[name] = curr;
|
||||
|
||||
fmt = name
|
||||
+ ' '
|
||||
+ fmt
|
||||
+ ' +' + debug.humanize(ms);
|
||||
|
||||
// This hackery is required for IE8
|
||||
// where `console.log` doesn't have 'apply'
|
||||
window.console
|
||||
&& console.log
|
||||
&& Function.prototype.apply.call(console.log, console, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The currently active debug mode names.
|
||||
*/
|
||||
|
||||
debug.names = [];
|
||||
debug.skips = [];
|
||||
|
||||
/**
|
||||
* Enables a debug mode by name. This can include modes
|
||||
* separated by a colon and wildcards.
|
||||
*
|
||||
* @param {String} name
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.enable = function(name) {
|
||||
try {
|
||||
localStorage.debug = name;
|
||||
} catch(e){}
|
||||
|
||||
var split = (name || '').split(/[\s,]+/)
|
||||
, len = split.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
name = split[i].replace('*', '.*?');
|
||||
if (name[0] === '-') {
|
||||
debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
|
||||
}
|
||||
else {
|
||||
debug.names.push(new RegExp('^' + name + '$'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.disable = function(){
|
||||
debug.enable('');
|
||||
};
|
||||
|
||||
/**
|
||||
* Humanize the given `ms`.
|
||||
*
|
||||
* @param {Number} m
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
debug.humanize = function(ms) {
|
||||
var sec = 1000
|
||||
, min = 60 * 1000
|
||||
, hour = 60 * min;
|
||||
|
||||
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
|
||||
if (ms >= min) return (ms / min).toFixed(1) + 'm';
|
||||
if (ms >= sec) return (ms / sec | 0) + 's';
|
||||
return ms + 'ms';
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given mode name is enabled, false otherwise.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.enabled = function(name) {
|
||||
for (var i = 0, len = debug.skips.length; i < len; i++) {
|
||||
if (debug.skips[i].test(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var i = 0, len = debug.names.length; i < len; i++) {
|
||||
if (debug.names[i].test(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// persist
|
||||
|
||||
if (window.localStorage) debug.enable(localStorage.debug);
|
||||
19
node_modules/gzippo/node_modules/send/node_modules/debug/example/app.js
generated
vendored
Normal file
19
node_modules/gzippo/node_modules/send/node_modules/debug/example/app.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
var debug = require('../')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %s', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
24
node_modules/gzippo/node_modules/send/node_modules/debug/example/browser.html
generated
vendored
Normal file
24
node_modules/gzippo/node_modules/send/node_modules/debug/example/browser.html
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>debug()</title>
|
||||
<script src="../debug.js"></script>
|
||||
<script>
|
||||
// type debug.enable('*') in
|
||||
// the console and refresh :)
|
||||
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1200);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
10
node_modules/gzippo/node_modules/send/node_modules/debug/example/wildcards.js
generated
vendored
Normal file
10
node_modules/gzippo/node_modules/send/node_modules/debug/example/wildcards.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
var debug = {
|
||||
foo: require('../')('test:foo'),
|
||||
bar: require('../')('test:bar'),
|
||||
baz: require('../')('test:baz')
|
||||
};
|
||||
|
||||
debug.foo('foo')
|
||||
debug.bar('bar')
|
||||
debug.baz('baz')
|
||||
22
node_modules/gzippo/node_modules/send/node_modules/debug/example/worker.js
generated
vendored
Normal file
22
node_modules/gzippo/node_modules/send/node_modules/debug/example/worker.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
// DEBUG=* node example/worker
|
||||
// DEBUG=worker:* node example/worker
|
||||
// DEBUG=worker:a node example/worker
|
||||
// DEBUG=worker:b node example/worker
|
||||
|
||||
var a = require('../')('worker:a')
|
||||
, b = require('../')('worker:b');
|
||||
|
||||
function work() {
|
||||
a('doing lots of uninteresting work');
|
||||
setTimeout(work, Math.random() * 1000);
|
||||
}
|
||||
|
||||
work();
|
||||
|
||||
function workb() {
|
||||
b('doing some work');
|
||||
setTimeout(workb, Math.random() * 2000);
|
||||
}
|
||||
|
||||
workb();
|
||||
5
node_modules/gzippo/node_modules/send/node_modules/debug/index.js
generated
vendored
Normal file
5
node_modules/gzippo/node_modules/send/node_modules/debug/index.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
if ('undefined' == typeof window) {
|
||||
module.exports = require('./lib/debug');
|
||||
} else {
|
||||
module.exports = require('./debug');
|
||||
}
|
||||
134
node_modules/gzippo/node_modules/send/node_modules/debug/lib/debug.js
generated
vendored
Normal file
134
node_modules/gzippo/node_modules/send/node_modules/debug/lib/debug.js
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var tty = require('tty');
|
||||
|
||||
/**
|
||||
* Expose `debug()` as the module.
|
||||
*/
|
||||
|
||||
module.exports = debug;
|
||||
|
||||
/**
|
||||
* Enabled debuggers.
|
||||
*/
|
||||
|
||||
var names = []
|
||||
, skips = [];
|
||||
|
||||
(process.env.DEBUG || '')
|
||||
.split(/[\s,]+/)
|
||||
.forEach(function(name){
|
||||
name = name.replace('*', '.*?');
|
||||
if (name[0] === '-') {
|
||||
skips.push(new RegExp('^' + name.substr(1) + '$'));
|
||||
} else {
|
||||
names.push(new RegExp('^' + name + '$'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
var colors = [6, 2, 3, 4, 5, 1];
|
||||
|
||||
/**
|
||||
* Previous debug() call.
|
||||
*/
|
||||
|
||||
var prev = {};
|
||||
|
||||
/**
|
||||
* Previously assigned color.
|
||||
*/
|
||||
|
||||
var prevColor = 0;
|
||||
|
||||
/**
|
||||
* Is stdout a TTY? Colored output is disabled when `true`.
|
||||
*/
|
||||
|
||||
var isatty = tty.isatty(2);
|
||||
|
||||
/**
|
||||
* Select a color.
|
||||
*
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function color() {
|
||||
return colors[prevColor++ % colors.length];
|
||||
}
|
||||
|
||||
/**
|
||||
* Humanize the given `ms`.
|
||||
*
|
||||
* @param {Number} m
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function humanize(ms) {
|
||||
var sec = 1000
|
||||
, min = 60 * 1000
|
||||
, hour = 60 * min;
|
||||
|
||||
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
|
||||
if (ms >= min) return (ms / min).toFixed(1) + 'm';
|
||||
if (ms >= sec) return (ms / sec | 0) + 's';
|
||||
return ms + 'ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Type}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function debug(name) {
|
||||
function disabled(){}
|
||||
disabled.enabled = false;
|
||||
|
||||
var match = skips.some(function(re){
|
||||
return re.test(name);
|
||||
});
|
||||
|
||||
if (match) return disabled;
|
||||
|
||||
match = names.some(function(re){
|
||||
return re.test(name);
|
||||
});
|
||||
|
||||
if (!match) return disabled;
|
||||
var c = color();
|
||||
|
||||
function colored(fmt) {
|
||||
var curr = new Date;
|
||||
var ms = curr - (prev[name] || curr);
|
||||
prev[name] = curr;
|
||||
|
||||
fmt = ' \u001b[9' + c + 'm' + name + ' '
|
||||
+ '\u001b[3' + c + 'm\u001b[90m'
|
||||
+ fmt + '\u001b[3' + c + 'm'
|
||||
+ ' +' + humanize(ms) + '\u001b[0m';
|
||||
|
||||
console.error.apply(this, arguments);
|
||||
}
|
||||
|
||||
function plain(fmt) {
|
||||
fmt = new Date().toUTCString()
|
||||
+ ' ' + name + ' ' + fmt;
|
||||
console.error.apply(this, arguments);
|
||||
}
|
||||
|
||||
colored.enabled = plain.enabled = true;
|
||||
|
||||
return isatty || process.env.DEBUG_COLORS
|
||||
? colored
|
||||
: plain;
|
||||
}
|
||||
43
node_modules/gzippo/node_modules/send/node_modules/debug/package.json
generated
vendored
Normal file
43
node_modules/gzippo/node_modules/send/node_modules/debug/package.json
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "0.7.2",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/visionmedia/debug.git"
|
||||
},
|
||||
"description": "small debugging utility",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"log",
|
||||
"debugger"
|
||||
],
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"main": "lib/debug.js",
|
||||
"browserify": "debug.js",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"component": {
|
||||
"scripts": {
|
||||
"debug/index.js": "index.js",
|
||||
"debug/debug.js": "debug.js"
|
||||
}
|
||||
},
|
||||
"_id": "debug@0.7.2",
|
||||
"optionalDependencies": {},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.21",
|
||||
"_nodeVersion": "v0.6.18",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "22ebd8ee1bf8378ea8da9c8b27d4e0de4bfc2845"
|
||||
},
|
||||
"_from": "debug@*"
|
||||
}
|
||||
1
node_modules/gzippo/node_modules/send/node_modules/fresh/.npmignore
generated
vendored
Normal file
1
node_modules/gzippo/node_modules/send/node_modules/fresh/.npmignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
test
|
||||
7
node_modules/gzippo/node_modules/send/node_modules/fresh/Makefile
generated
vendored
Normal file
7
node_modules/gzippo/node_modules/send/node_modules/fresh/Makefile
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
test:
|
||||
@./node_modules/.bin/mocha \
|
||||
--reporter spec \
|
||||
--require should
|
||||
|
||||
.PHONY: test
|
||||
32
node_modules/gzippo/node_modules/send/node_modules/fresh/Readme.md
generated
vendored
Normal file
32
node_modules/gzippo/node_modules/send/node_modules/fresh/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
# node-fresh
|
||||
|
||||
HTTP response freshness testing
|
||||
|
||||
## fresh(req, res)
|
||||
|
||||
Check freshness of `req` and `res` headers.
|
||||
|
||||
When the cache is "fresh" __true__ is returned,
|
||||
otherwise __false__ is returned to indicate that
|
||||
the cache is now stale.
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
var req = { 'if-none-match': 'tobi' };
|
||||
var res = { 'etag': 'luna' };
|
||||
fresh(req, res);
|
||||
// => false
|
||||
|
||||
var req = { 'if-none-match': 'tobi' };
|
||||
var res = { 'etag': 'tobi' };
|
||||
fresh(req, res);
|
||||
// => true
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install fresh
|
||||
```
|
||||
49
node_modules/gzippo/node_modules/send/node_modules/fresh/index.js
generated
vendored
Normal file
49
node_modules/gzippo/node_modules/send/node_modules/fresh/index.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
/**
|
||||
* Expose `fresh()`.
|
||||
*/
|
||||
|
||||
module.exports = fresh;
|
||||
|
||||
/**
|
||||
* Check freshness of `req` and `res` headers.
|
||||
*
|
||||
* When the cache is "fresh" __true__ is returned,
|
||||
* otherwise __false__ is returned to indicate that
|
||||
* the cache is now stale.
|
||||
*
|
||||
* @param {Object} req
|
||||
* @param {Object} res
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function fresh(req, res) {
|
||||
// defaults
|
||||
var etagMatches = true;
|
||||
var notModified = true;
|
||||
|
||||
// fields
|
||||
var modifiedSince = req['if-modified-since'];
|
||||
var noneMatch = req['if-none-match'];
|
||||
var lastModified = res['last-modified'];
|
||||
var etag = res['etag'];
|
||||
|
||||
// unconditional request
|
||||
if (!modifiedSince && !noneMatch) return false;
|
||||
|
||||
// parse if-none-match
|
||||
if (noneMatch) noneMatch = noneMatch.split(/ *, */);
|
||||
|
||||
// if-none-match
|
||||
if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0];
|
||||
|
||||
// if-modified-since
|
||||
if (modifiedSince) {
|
||||
modifiedSince = new Date(modifiedSince);
|
||||
lastModified = new Date(lastModified);
|
||||
notModified = lastModified <= modifiedSince;
|
||||
}
|
||||
|
||||
return !! (etagMatches && notModified);
|
||||
}
|
||||
29
node_modules/gzippo/node_modules/send/node_modules/fresh/package.json
generated
vendored
Normal file
29
node_modules/gzippo/node_modules/send/node_modules/fresh/package.json
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "fresh",
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca",
|
||||
"url": "http://tjholowaychuk.com"
|
||||
},
|
||||
"description": "HTTP response freshness testing",
|
||||
"version": "0.1.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"_id": "fresh@0.1.0",
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.21",
|
||||
"_nodeVersion": "v0.6.18",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "7dbe9f8603e489758d42d5a694cae0602fba8ed4"
|
||||
},
|
||||
"_from": "fresh@0.1.0"
|
||||
}
|
||||
19
node_modules/gzippo/node_modules/send/node_modules/mime/LICENSE
generated
vendored
Normal file
19
node_modules/gzippo/node_modules/send/node_modules/mime/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
63
node_modules/gzippo/node_modules/send/node_modules/mime/README.md
generated
vendored
Normal file
63
node_modules/gzippo/node_modules/send/node_modules/mime/README.md
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# mime
|
||||
|
||||
Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](http://github.com/isaacs/npm):
|
||||
|
||||
npm install mime
|
||||
|
||||
## API - Queries
|
||||
|
||||
### mime.lookup(path)
|
||||
Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.
|
||||
|
||||
var mime = require('mime');
|
||||
|
||||
mime.lookup('/path/to/file.txt'); // => 'text/plain'
|
||||
mime.lookup('file.txt'); // => 'text/plain'
|
||||
mime.lookup('.TXT'); // => 'text/plain'
|
||||
mime.lookup('htm'); // => 'text/html'
|
||||
|
||||
### mime.extension(type)
|
||||
Get the default extension for `type`
|
||||
|
||||
mime.extension('text/html'); // => 'html'
|
||||
mime.extension('application/octet-stream'); // => 'bin'
|
||||
|
||||
### mime.charsets.lookup()
|
||||
|
||||
Map mime-type to charset
|
||||
|
||||
mime.charsets.lookup('text/plain'); // => 'UTF-8'
|
||||
|
||||
(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)
|
||||
|
||||
## API - Defining Custom Types
|
||||
|
||||
The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types).
|
||||
|
||||
### mime.define()
|
||||
|
||||
Add custom mime/extension mappings
|
||||
|
||||
mime.define({
|
||||
'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
|
||||
'application/x-my-type': ['x-mt', 'x-mtt'],
|
||||
// etc ...
|
||||
});
|
||||
|
||||
mime.lookup('x-sft'); // => 'text/x-some-format'
|
||||
|
||||
The first entry in the extensions array is returned by `mime.extension()`. E.g.
|
||||
|
||||
mime.extension('text/x-some-format'); // => 'x-sf'
|
||||
|
||||
### mime.load(filepath)
|
||||
|
||||
Load mappings from an Apache ".types" format file
|
||||
|
||||
mime.load('./my_project.types');
|
||||
|
||||
The .types file format is simple - See the `types` dir for examples.
|
||||
104
node_modules/gzippo/node_modules/send/node_modules/mime/mime.js
generated
vendored
Normal file
104
node_modules/gzippo/node_modules/send/node_modules/mime/mime.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
function Mime() {
|
||||
// Map of extension -> mime type
|
||||
this.types = Object.create(null);
|
||||
|
||||
// Map of mime type -> extension
|
||||
this.extensions = Object.create(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define mimetype -> extension mappings. Each key is a mime-type that maps
|
||||
* to an array of extensions associated with the type. The first extension is
|
||||
* used as the default extension for the type.
|
||||
*
|
||||
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
|
||||
*
|
||||
* @param map (Object) type definitions
|
||||
*/
|
||||
Mime.prototype.define = function (map) {
|
||||
for (var type in map) {
|
||||
var exts = map[type];
|
||||
|
||||
for (var i = 0; i < exts.length; i++) {
|
||||
this.types[exts[i]] = type;
|
||||
}
|
||||
|
||||
// Default extension is the first one we encounter
|
||||
if (!this.extensions[type]) {
|
||||
this.extensions[type] = exts[0];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load an Apache2-style ".types" file
|
||||
*
|
||||
* This may be called multiple times (it's expected). Where files declare
|
||||
* overlapping types/extensions, the last file wins.
|
||||
*
|
||||
* @param file (String) path of file to load.
|
||||
*/
|
||||
Mime.prototype.load = function(file) {
|
||||
// Read file and split into lines
|
||||
var map = {},
|
||||
content = fs.readFileSync(file, 'ascii'),
|
||||
lines = content.split(/[\r\n]+/);
|
||||
|
||||
lines.forEach(function(line) {
|
||||
// Clean up whitespace/comments, and split into fields
|
||||
var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
|
||||
map[fields.shift()] = fields;
|
||||
});
|
||||
|
||||
this.define(map);
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup a mime type based on extension
|
||||
*/
|
||||
Mime.prototype.lookup = function(path, fallback) {
|
||||
var ext = path.replace(/.*[\.\/]/, '').toLowerCase();
|
||||
|
||||
return this.types[ext] || fallback || this.default_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return file extension associated with a mime type
|
||||
*/
|
||||
Mime.prototype.extension = function(mimeType) {
|
||||
return this.extensions[mimeType];
|
||||
};
|
||||
|
||||
// Default instance
|
||||
var mime = new Mime();
|
||||
|
||||
// Load local copy of
|
||||
// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
|
||||
mime.load(path.join(__dirname, 'types/mime.types'));
|
||||
|
||||
// Load additional types from node.js community
|
||||
mime.load(path.join(__dirname, 'types/node.types'));
|
||||
|
||||
// Default type
|
||||
mime.default_type = mime.lookup('bin');
|
||||
|
||||
//
|
||||
// Additional API specific to the default instance
|
||||
//
|
||||
|
||||
mime.Mime = Mime;
|
||||
|
||||
/**
|
||||
* Lookup a charset based on mime type.
|
||||
*/
|
||||
mime.charsets = {
|
||||
lookup: function(mimeType, fallback) {
|
||||
// Assume text types are utf8
|
||||
return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = mime;
|
||||
41
node_modules/gzippo/node_modules/send/node_modules/mime/package.json
generated
vendored
Normal file
41
node_modules/gzippo/node_modules/send/node_modules/mime/package.json
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "Robert Kieffer",
|
||||
"email": "robert@broofa.com",
|
||||
"url": "http://github.com/broofa"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Benjamin Thomas",
|
||||
"email": "benjamin@benjaminthomas.org",
|
||||
"url": "http://github.com/bentomas"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"description": "A comprehensive library for mime-type mapping",
|
||||
"devDependencies": {},
|
||||
"keywords": [
|
||||
"util",
|
||||
"mime"
|
||||
],
|
||||
"main": "mime.js",
|
||||
"name": "mime",
|
||||
"repository": {
|
||||
"url": "git://github.com/broofa/node-mime.git",
|
||||
"type": "git"
|
||||
},
|
||||
"version": "1.2.6",
|
||||
"_id": "mime@1.2.6",
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.21",
|
||||
"_nodeVersion": "v0.6.18",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "e66b214a4c2f94dc15ce22f0bda388b216bf0370"
|
||||
},
|
||||
"_from": "mime@1.2.6"
|
||||
}
|
||||
55
node_modules/gzippo/node_modules/send/node_modules/mime/test.js
generated
vendored
Normal file
55
node_modules/gzippo/node_modules/send/node_modules/mime/test.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Usage: node test.js
|
||||
*/
|
||||
|
||||
var mime = require('./mime');
|
||||
var assert = require('assert');
|
||||
|
||||
function eq(a, b) {
|
||||
console.log('Test: ' + a + ' === ' + b);
|
||||
assert.strictEqual.apply(null, arguments);
|
||||
}
|
||||
|
||||
console.log(Object.keys(mime.extensions).length + ' types');
|
||||
console.log(Object.keys(mime.types).length + ' extensions\n');
|
||||
|
||||
//
|
||||
// Test mime lookups
|
||||
//
|
||||
|
||||
eq('text/plain', mime.lookup('text.txt'));
|
||||
eq('text/plain', mime.lookup('.text.txt'));
|
||||
eq('text/plain', mime.lookup('.txt'));
|
||||
eq('text/plain', mime.lookup('txt'));
|
||||
eq('application/octet-stream', mime.lookup('text.nope'));
|
||||
eq('fallback', mime.lookup('text.fallback', 'fallback'));
|
||||
eq('application/octet-stream', mime.lookup('constructor'));
|
||||
eq('text/plain', mime.lookup('TEXT.TXT'));
|
||||
eq('text/event-stream', mime.lookup('text/event-stream'));
|
||||
eq('application/x-web-app-manifest+json', mime.lookup('text.webapp'));
|
||||
|
||||
//
|
||||
// Test extensions
|
||||
//
|
||||
|
||||
eq('txt', mime.extension(mime.types.text));
|
||||
eq('html', mime.extension(mime.types.htm));
|
||||
eq('bin', mime.extension('application/octet-stream'));
|
||||
eq(undefined, mime.extension('constructor'));
|
||||
|
||||
//
|
||||
// Test node types
|
||||
//
|
||||
|
||||
eq('application/octet-stream', mime.lookup('file.buffer'));
|
||||
eq('audio/mp4', mime.lookup('file.m4a'));
|
||||
|
||||
//
|
||||
// Test charsets
|
||||
//
|
||||
|
||||
eq('UTF-8', mime.charsets.lookup('text/plain'));
|
||||
eq(undefined, mime.charsets.lookup(mime.types.js));
|
||||
eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
|
||||
|
||||
console.log('\nOK');
|
||||
1510
node_modules/gzippo/node_modules/send/node_modules/mime/types/mime.types
generated
vendored
Normal file
1510
node_modules/gzippo/node_modules/send/node_modules/mime/types/mime.types
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
65
node_modules/gzippo/node_modules/send/node_modules/mime/types/node.types
generated
vendored
Normal file
65
node_modules/gzippo/node_modules/send/node_modules/mime/types/node.types
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# What: Google Chrome Extension
|
||||
# Why: To allow apps to (work) be served with the right content type header.
|
||||
# http://codereview.chromium.org/2830017
|
||||
# Added by: niftylettuce
|
||||
application/x-chrome-extension crx
|
||||
|
||||
# What: OTF Message Silencer
|
||||
# Why: To silence the "Resource interpreted as font but transferred with MIME
|
||||
# type font/otf" message that occurs in Google Chrome
|
||||
# Added by: niftylettuce
|
||||
font/opentype otf
|
||||
|
||||
# What: HTC support
|
||||
# Why: To properly render .htc files such as CSS3PIE
|
||||
# Added by: niftylettuce
|
||||
text/x-component htc
|
||||
|
||||
# What: HTML5 application cache manifest
|
||||
# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps
|
||||
# per https://developer.mozilla.org/en/offline_resources_in_firefox
|
||||
# Added by: louisremi
|
||||
text/cache-manifest appcache manifest
|
||||
|
||||
# What: node binary buffer format
|
||||
# Why: semi-standard extension w/in the node community
|
||||
# Added by: tootallnate
|
||||
application/octet-stream buffer
|
||||
|
||||
# What: The "protected" MP-4 formats used by iTunes.
|
||||
# Why: Required for streaming music to browsers (?)
|
||||
# Added by: broofa
|
||||
application/mp4 m4p
|
||||
audio/mp4 m4a
|
||||
|
||||
# What: Music playlist format (http://en.wikipedia.org/wiki/M3U)
|
||||
# Why: See https://github.com/bentomas/node-mime/pull/6
|
||||
# Added by: mjrusso
|
||||
application/x-mpegURL m3u8
|
||||
|
||||
# What: Video format, Part of RFC1890
|
||||
# Why: See https://github.com/bentomas/node-mime/pull/6
|
||||
# Added by: mjrusso
|
||||
video/MP2T ts
|
||||
|
||||
# What: The FLAC lossless codec format
|
||||
# Why: Streaming and serving FLAC audio
|
||||
# Added by: jacobrask
|
||||
audio/flac flac
|
||||
|
||||
# What: EventSource mime type
|
||||
# Why: mime type of Server-Sent Events stream
|
||||
# http://www.w3.org/TR/eventsource/#text-event-stream
|
||||
# Added by: francois2metz
|
||||
text/event-stream event-stream
|
||||
|
||||
# What: Mozilla App manifest mime type
|
||||
# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests
|
||||
# Added by: ednapiranha
|
||||
application/x-web-app-manifest+json webapp
|
||||
|
||||
# What: Matroska Mime Types
|
||||
# Why: http://en.wikipedia.org/wiki/Matroska
|
||||
# Added by: aduncan88
|
||||
video/x-matroska mkv
|
||||
audio/x-matroska mka
|
||||
1
node_modules/gzippo/node_modules/send/node_modules/range-parser/.npmignore
generated
vendored
Normal file
1
node_modules/gzippo/node_modules/send/node_modules/range-parser/.npmignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
test
|
||||
15
node_modules/gzippo/node_modules/send/node_modules/range-parser/History.md
generated
vendored
Normal file
15
node_modules/gzippo/node_modules/send/node_modules/range-parser/History.md
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
0.0.4 / 2012-06-17
|
||||
==================
|
||||
|
||||
* changed: ret -1 for unsatisfiable and -2 when invalid
|
||||
|
||||
0.0.3 / 2012-06-17
|
||||
==================
|
||||
|
||||
* fix last-byte-pos default to len - 1
|
||||
|
||||
0.0.2 / 2012-06-14
|
||||
==================
|
||||
|
||||
* add `.type`
|
||||
7
node_modules/gzippo/node_modules/send/node_modules/range-parser/Makefile
generated
vendored
Normal file
7
node_modules/gzippo/node_modules/send/node_modules/range-parser/Makefile
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
test:
|
||||
@./node_modules/.bin/mocha \
|
||||
--reporter spec \
|
||||
--require should
|
||||
|
||||
.PHONY: test
|
||||
28
node_modules/gzippo/node_modules/send/node_modules/range-parser/Readme.md
generated
vendored
Normal file
28
node_modules/gzippo/node_modules/send/node_modules/range-parser/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
# node-range-parser
|
||||
|
||||
Range header field parser.
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
assert(-1 == parse(200, 'bytes=500-20'));
|
||||
assert(-2 == parse(200, 'bytes=malformed'));
|
||||
parse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }]));
|
||||
parse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }]));
|
||||
parse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }]));
|
||||
parse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }]));
|
||||
parse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }]));
|
||||
parse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }]));
|
||||
parse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }]));
|
||||
parse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }]));
|
||||
parse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }]));
|
||||
parse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }]));
|
||||
parse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }]));
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install range-parser
|
||||
```
|
||||
49
node_modules/gzippo/node_modules/send/node_modules/range-parser/index.js
generated
vendored
Normal file
49
node_modules/gzippo/node_modules/send/node_modules/range-parser/index.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
/**
|
||||
* Parse "Range" header `str` relative to the given file `size`.
|
||||
*
|
||||
* @param {Number} size
|
||||
* @param {String} str
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function(size, str){
|
||||
var valid = true;
|
||||
var i = str.indexOf('=');
|
||||
|
||||
if (-1 == i) return -2;
|
||||
|
||||
var arr = str.slice(i + 1).split(',').map(function(range){
|
||||
var range = range.split('-')
|
||||
, start = parseInt(range[0], 10)
|
||||
, end = parseInt(range[1], 10);
|
||||
|
||||
// -nnn
|
||||
if (isNaN(start)) {
|
||||
start = size - end;
|
||||
end = size - 1;
|
||||
// nnn-
|
||||
} else if (isNaN(end)) {
|
||||
end = size - 1;
|
||||
}
|
||||
|
||||
// limit last-byte-pos to current length
|
||||
if (end > size - 1) end = size - 1;
|
||||
|
||||
// invalid
|
||||
if (isNaN(start)
|
||||
|| isNaN(end)
|
||||
|| start > end
|
||||
|| start < 0) valid = false;
|
||||
|
||||
return {
|
||||
start: start,
|
||||
end: end
|
||||
};
|
||||
});
|
||||
|
||||
arr.type = str.slice(0, i);
|
||||
|
||||
return valid ? arr : -1;
|
||||
};
|
||||
29
node_modules/gzippo/node_modules/send/node_modules/range-parser/package.json
generated
vendored
Normal file
29
node_modules/gzippo/node_modules/send/node_modules/range-parser/package.json
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "range-parser",
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca",
|
||||
"url": "http://tjholowaychuk.com"
|
||||
},
|
||||
"description": "Range header field string parser",
|
||||
"version": "0.0.4",
|
||||
"main": "index.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"_id": "range-parser@0.0.4",
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.21",
|
||||
"_nodeVersion": "v0.6.18",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "aefe40cc8e78149013af07fe2c75ddfcd0ef2a4b"
|
||||
},
|
||||
"_from": "range-parser@0.0.4"
|
||||
}
|
||||
40
node_modules/gzippo/node_modules/send/package.json
generated
vendored
Normal file
40
node_modules/gzippo/node_modules/send/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "send",
|
||||
"version": "0.1.0",
|
||||
"description": "Better streaming static file server with Range and conditional-GET support",
|
||||
"keywords": [
|
||||
"static",
|
||||
"file",
|
||||
"server"
|
||||
],
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "*",
|
||||
"mime": "1.2.6",
|
||||
"fresh": "0.1.0",
|
||||
"range-parser": "0.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*",
|
||||
"supertest": "0.0.1",
|
||||
"connect": "2.x"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"main": "index",
|
||||
"_id": "send@0.1.0",
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.21",
|
||||
"_nodeVersion": "v0.6.18",
|
||||
"_defaultsLoaded": true,
|
||||
"_from": "send@*"
|
||||
}
|
||||
44
node_modules/gzippo/package.json
generated
vendored
Normal file
44
node_modules/gzippo/package.json
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "gzippo",
|
||||
"version": "0.2.0",
|
||||
"author": {
|
||||
"name": "Tom Gallacher"
|
||||
},
|
||||
"description": "Gzip middleware for Connect using the native zlib library in node >= 0.6",
|
||||
"homepage": "http://www.tomg.co/gzippo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/tomgco/gzippo.git"
|
||||
},
|
||||
"keywords": [
|
||||
"compression",
|
||||
"gzip",
|
||||
"compress"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.5 < 0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"main": "./index.js",
|
||||
"dependencies": {
|
||||
"send": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"should": "*",
|
||||
"connect": "~2",
|
||||
"express": "~3",
|
||||
"mocha": "*"
|
||||
},
|
||||
"_id": "gzippo@0.2.0",
|
||||
"optionalDependencies": {},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.21",
|
||||
"_nodeVersion": "v0.6.18",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "da568f98101358ca6c3a8297f79102a20c2a309e"
|
||||
},
|
||||
"_from": "gzippo"
|
||||
}
|
||||
14
node_modules/gzippo/test/fixtures/index_test/index.html
generated
vendored
Normal file
14
node_modules/gzippo/test/fixtures/index_test/index.html
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head><title>Index Test</title></head>
|
||||
<body>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
0
node_modules/gzippo/test/fixtures/js/nestedTest.js
generated
vendored
Normal file
0
node_modules/gzippo/test/fixtures/js/nestedTest.js
generated
vendored
Normal file
BIN
node_modules/gzippo/test/fixtures/space the final frontier/tomg.co.png
generated
vendored
Normal file
BIN
node_modules/gzippo/test/fixtures/space the final frontier/tomg.co.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
1
node_modules/gzippo/test/fixtures/test.js
generated
vendored
Normal file
1
node_modules/gzippo/test/fixtures/test.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
alert("hello");
|
||||
BIN
node_modules/gzippo/test/fixtures/test.js.gzip
generated
vendored
Normal file
BIN
node_modules/gzippo/test/fixtures/test.js.gzip
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/gzippo/test/fixtures/tomg.co.png
generated
vendored
Normal file
BIN
node_modules/gzippo/test/fixtures/tomg.co.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
node_modules/gzippo/test/fixtures/user.gzip
generated
vendored
Normal file
BIN
node_modules/gzippo/test/fixtures/user.gzip
generated
vendored
Normal file
Binary file not shown.
4
node_modules/gzippo/test/fixtures/user.json
generated
vendored
Normal file
4
node_modules/gzippo/test/fixtures/user.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "tomgallacher",
|
||||
"website": "www.tomgallacher.info"
|
||||
}
|
||||
0
node_modules/gzippo/test/fixtures/utf8.gz
generated
vendored
Normal file
0
node_modules/gzippo/test/fixtures/utf8.gz
generated
vendored
Normal file
32
node_modules/gzippo/test/fixtures/utf8.txt
generated
vendored
Normal file
32
node_modules/gzippo/test/fixtures/utf8.txt
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
English: The quick brown fox jumps over the lazy dog.
|
||||
Jamaican: Chruu, a kwik di kwik brong fox a jomp huova di liezi daag de, yu no siit?
|
||||
Irish: "An ḃfuil do ċroí ag bualaḋ ó ḟaitíos an ġrá a ṁeall lena ṗóg éada ó ṡlí do leasa ṫú?" "D'ḟuascail Íosa Úrṁac na hÓiġe Beannaiṫe pór Éava agus Áḋaiṁ."
|
||||
Dutch: Pa's wijze lynx bezag vroom het fikse aquaduct.
|
||||
German: Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. (1)
|
||||
German: Im finſteren Jagdſchloß am offenen Felsquellwaſſer patzte der affig-flatterhafte kauzig-höfliche Bäcker über ſeinem verſifften kniffligen C-Xylophon. (2)
|
||||
Norwegian: Blåbærsyltetøy ("blueberry jam", includes every extra letter used in Norwegian).
|
||||
Swedish: Flygande bäckasiner söka strax hwila på mjuka tuvor.
|
||||
Icelandic: Sævör grét áðan því úlpan var ónýt.
|
||||
Finnish: (5) Törkylempijävongahdus (This is a perfect pangram, every letter appears only once. Translating it is an art on its own, but I'll say "rude lover's yelp". :-D)
|
||||
Finnish: (5) Albert osti fagotin ja töräytti puhkuvan melodian. (Albert bought a bassoon and hooted an impressive melody.)
|
||||
Finnish: (5) On sangen hauskaa, että polkupyörä on maanteiden jokapäiväinen ilmiö. (It's pleasantly amusing, that the bicycle is an everyday sight on the roads.)
|
||||
Polish: Pchnąć w tę łódź jeża lub osiem skrzyń fig.
|
||||
Czech: Příliš žluťoučký kůň úpěl ďábelské kódy.
|
||||
Slovak: Starý kôň na hŕbe kníh žuje tíško povädnuté ruže, na stĺpe sa ďateľ učí kvákať novú ódu o živote.
|
||||
Greek (monotonic): ξεσκεπάζω την ψυχοφθόρα βδελυγμία
|
||||
Greek (polytonic): ξεσκεπάζω τὴν ψυχοφθόρα βδελυγμία
|
||||
Russian: Съешь же ещё этих мягких французских булок да выпей чаю.
|
||||
Russian: В чащах юга жил-был цитрус? Да, но фальшивый экземпляр! ёъ.
|
||||
Bulgarian: Жълтата дюля беше щастлива, че пухът, който цъфна, замръзна като гьон.
|
||||
Sami (Northern): Vuol Ruoŧa geđggiid leat máŋga luosa ja čuovžža.
|
||||
Hungarian: Árvíztűrő tükörfúrógép.
|
||||
Spanish: El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.
|
||||
Portuguese: O próximo vôo à noite sobre o Atlântico, põe freqüentemente o único médico. (3)
|
||||
French: Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus en voyant leurs drôles d'œufs abîmés.
|
||||
Esperanto: Eĥoŝanĝo ĉiuĵaŭde.
|
||||
Hebrew: זה כיף סתם לשמוע איך תנצח קרפד עץ טוב בגן.
|
||||
Japanese (Hiragana):
|
||||
いろはにほへど ちりぬるを
|
||||
わがよたれぞ つねならむ
|
||||
うゐのおくやま けふこえて
|
||||
あさきゆめみじ ゑひもせず (4)
|
||||
BIN
node_modules/gzippo/test/fixtures/utf8.txt.gz
generated
vendored
Normal file
BIN
node_modules/gzippo/test/fixtures/utf8.txt.gz
generated
vendored
Normal file
Binary file not shown.
88
node_modules/gzippo/test/prefexTest.js
generated
vendored
Normal file
88
node_modules/gzippo/test/prefexTest.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var staticProvider,
|
||||
assert = require('assert'),
|
||||
should = require('should'),
|
||||
http = require('http'),
|
||||
gzippo = require('../');
|
||||
|
||||
try {
|
||||
staticProvider = require('connect');
|
||||
} catch (e) {
|
||||
staticProvider = require('express');
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to ./test/fixtures/
|
||||
*/
|
||||
|
||||
var fixturesPath = __dirname + '/fixtures';
|
||||
|
||||
module.exports = {
|
||||
'requesting without a prefix succeeds': function() {
|
||||
var app = staticProvider.createServer(
|
||||
gzippo.staticGzip(fixturesPath)
|
||||
);
|
||||
|
||||
assert.response(app,
|
||||
{
|
||||
url: '/user.json',
|
||||
headers: {
|
||||
'Accept-Encoding':"gzip"
|
||||
}
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=UTF-8');
|
||||
res.headers.should.have.property('content-length', '69');
|
||||
res.headers.should.have.property('content-encoding', 'gzip');
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting with a prefix succeeds': function() {
|
||||
var app = staticProvider.createServer(
|
||||
gzippo.staticGzip(fixturesPath, { prefix: '/resource' })
|
||||
);
|
||||
|
||||
assert.response(app,
|
||||
{
|
||||
url: '/resource/user.json',
|
||||
headers: {
|
||||
'Accept-Encoding':"gzip"
|
||||
}
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=UTF-8');
|
||||
res.headers.should.have.property('content-length', '69');
|
||||
res.headers.should.have.property('content-encoding', 'gzip');
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting with a / prefix succeeds': function() {
|
||||
var app = staticProvider.createServer(
|
||||
gzippo.staticGzip(fixturesPath, { prefix: '/'})
|
||||
);
|
||||
|
||||
assert.response(app,
|
||||
{
|
||||
url: '/user.json',
|
||||
headers: {
|
||||
'Accept-Encoding':"gzip"
|
||||
}
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=UTF-8');
|
||||
res.headers.should.have.property('content-length', '69');
|
||||
res.headers.should.have.property('content-encoding', 'gzip');
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
67
node_modules/gzippo/test/prefix.test.js
generated
vendored
Normal file
67
node_modules/gzippo/test/prefix.test.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
var assert = require('assert')
|
||||
, http = require('http')
|
||||
, fs = require('fs')
|
||||
, connect = require('connect')
|
||||
, join = require('path').join
|
||||
, gzippo = require('../')
|
||||
;
|
||||
var fixtures = join(__dirname, 'fixtures')
|
||||
, port = 32124
|
||||
, app
|
||||
, request
|
||||
;
|
||||
|
||||
// read a fixture file synchronously
|
||||
function file(name) {
|
||||
return fs.readFileSync(join(fixtures, name));
|
||||
}
|
||||
|
||||
describe('gzippo.statisGzip (with prefix)', function() {
|
||||
|
||||
it('should successfully serve a .json file with a path prefix', function(done) {
|
||||
var app = connect.createServer();
|
||||
app.use(gzippo.staticGzip(fixtures, { prefix: '/foo' }));
|
||||
request = require('./request')({ port: port + 5 });
|
||||
|
||||
app.listen(port + 5, function() {
|
||||
request('/foo/user.json', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
|
||||
assert.equal(res.headers['content-type'], 'application/json; charset=UTF-8');
|
||||
assert.equal(data.length, '69');
|
||||
assert.equal(res.headers['content-encoding'], 'gzip');
|
||||
|
||||
assert.deepEqual(data, file('user.gzip'));
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should serve files as expected with a / prefix', function(done) {
|
||||
var app = connect.createServer();
|
||||
app.use(gzippo.staticGzip(fixtures, { prefix: '/' }));
|
||||
request = require('./request')({ port: port + 6});
|
||||
|
||||
app.listen(port + 6, function() {
|
||||
request('/user.json', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
|
||||
assert.equal(res.headers['content-type'], 'application/json; charset=UTF-8');
|
||||
assert.equal(data.length, '69');
|
||||
assert.equal(res.headers['content-encoding'], 'gzip');
|
||||
|
||||
assert.deepEqual(data, file('user.gzip'));
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
51
node_modules/gzippo/test/request.js
generated
vendored
Normal file
51
node_modules/gzippo/test/request.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
var http = require('http')
|
||||
;
|
||||
|
||||
var port;
|
||||
// basic request mocking function
|
||||
module.exports = function (options) {
|
||||
port = options.port || 32123;
|
||||
return request;
|
||||
};
|
||||
|
||||
var request = function(path, headers, callback) {
|
||||
var options = {
|
||||
host: '127.0.0.1',
|
||||
port: port,
|
||||
path: path,
|
||||
headers: headers || {},
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
var req = http.request(options, function(res) {
|
||||
var buffers = []
|
||||
, total = 0;
|
||||
|
||||
res.on('data', function(buf) {
|
||||
buffers.push(buf);
|
||||
total += buf.length;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
var data = new Buffer(total)
|
||||
, offset = 0;
|
||||
|
||||
for (var i = 0; i < buffers.length; i++) {
|
||||
buffers[i].copy(data, offset);
|
||||
offset += buffers[i].length;
|
||||
}
|
||||
|
||||
callback(null, res, data);
|
||||
});
|
||||
|
||||
res.on('error', function(err) {
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', function(err) {
|
||||
callback(err);
|
||||
});
|
||||
|
||||
req.end();
|
||||
};
|
||||
180
node_modules/gzippo/test/staticGzipTest.js
generated
vendored
Normal file
180
node_modules/gzippo/test/staticGzipTest.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var staticProvider,
|
||||
assert = require('assert'),
|
||||
should = require('should'),
|
||||
http = require('http'),
|
||||
gzippo = require('../'),
|
||||
crypto = require('crypto'),
|
||||
fs = require('fs'),
|
||||
shasum = crypto.createHash('sha1');
|
||||
|
||||
try {
|
||||
staticProvider = require('connect');
|
||||
} catch (e) {
|
||||
staticProvider = require('express');
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to ./test/fixtures/
|
||||
*/
|
||||
|
||||
var fixturesPath = __dirname + '/fixtures';
|
||||
|
||||
function getApp() {
|
||||
return staticProvider.createServer(gzippo.staticGzip(fixturesPath, {clientMaxAge: 604800000}));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'requesting gzipped json file succeeds': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/user.json',
|
||||
headers: {
|
||||
'Accept-Encoding':"gzip"
|
||||
}
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
assert.response(getApp(), { url: '/user.gzip' }, function(res) {
|
||||
assert.equal(gzippedData, res.body, "Data is not gzipped");
|
||||
});
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=UTF-8');
|
||||
// res.headers.should.have.property('content-length', '69');
|
||||
res.headers.should.have.property('content-encoding', 'gzip');
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting gzipped js file succeeds': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/test.js',
|
||||
headers: {
|
||||
'Accept-Encoding':"gzip"
|
||||
}
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
assert.response(getApp(), { url: '/test.js.gzip' }, function(res) {
|
||||
assert.equal(gzippedData, res.body, "Data is not gzipped");
|
||||
});
|
||||
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/javascript; charset=UTF-8');
|
||||
res.headers.should.have.property('content-length', '35');
|
||||
res.headers.should.have.property('content-encoding', 'gzip');
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting js file without gzip succeeds': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/test.js'
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
|
||||
fs.readFile(fixturesPath + '/test.js', function (err, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(gzippedData, data, "Data returned does not match file data on filesystem");
|
||||
});
|
||||
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-length', '15');
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting gzipped utf-8 file succeeds': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/utf8.txt',
|
||||
headers: {
|
||||
'Accept-Encoding':"gzip"
|
||||
}
|
||||
},
|
||||
function(res){
|
||||
var gzippedData = res.body;
|
||||
assert.response(getApp(), { url: '/utf8.txt.gz' }, function(res) {
|
||||
assert.equal(gzippedData, res.body, "Data is not gzipped");
|
||||
});
|
||||
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'text/plain; charset=UTF-8');
|
||||
res.headers.should.have.property('content-length', '2031');
|
||||
res.headers.should.have.property('content-encoding', 'gzip');
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting gzipped utf-8 file returns 304': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/utf8.txt',
|
||||
headers: {
|
||||
'Accept-Encoding': "gzip"
|
||||
}
|
||||
},
|
||||
function(res) {
|
||||
res.statusCode.should.equal(200);
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/utf8.txt',
|
||||
headers: {
|
||||
'Accept-Encoding': "gzip",
|
||||
'If-Modified-Since': res.headers['last-modified']
|
||||
}
|
||||
},
|
||||
function(res2) {
|
||||
res2.statusCode.should.equal(304);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
'requesting gzipped utf-8 file returns 200': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/utf8.txt',
|
||||
headers: {
|
||||
'Accept-Encoding': "gzip"
|
||||
}
|
||||
},
|
||||
function(res) {
|
||||
res.statusCode.should.equal(200);
|
||||
}
|
||||
);
|
||||
},
|
||||
'ensuring max age is set on resources which are passed to the default static content provider': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/tomg.co.png'
|
||||
},
|
||||
function(res) {
|
||||
res.headers.should.have.property('cache-control', 'public, max-age=604800');
|
||||
}
|
||||
);
|
||||
},
|
||||
'Ensuring that when viewing a directory a redirect works correctly': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/js'
|
||||
},
|
||||
function(res) {
|
||||
res.statusCode.should.not.equal(301);
|
||||
}
|
||||
);
|
||||
},
|
||||
'ensuring that gzippo works with a space in a static content path': function() {
|
||||
assert.response(getApp(),
|
||||
{
|
||||
url: '/space%20the%20final%20frontier/tomg.co.png'
|
||||
},
|
||||
function(res) {
|
||||
res.statusCode.should.not.equal(404);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
203
node_modules/gzippo/test/test-static.js
generated
vendored
Normal file
203
node_modules/gzippo/test/test-static.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
var assert = require('assert')
|
||||
, fs = require('fs')
|
||||
, express = require('express')
|
||||
, join = require('path').join
|
||||
, gzippo = require('../')
|
||||
;
|
||||
|
||||
var fixtures = join(__dirname, 'fixtures')
|
||||
, port = 32123
|
||||
, app
|
||||
, request = require('./request')({ port: port })
|
||||
;
|
||||
|
||||
// builds a `request` callback which asserts that the response's statusCode is
|
||||
// what we expect
|
||||
function statusCode(expected, callback) {
|
||||
return function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, expected);
|
||||
|
||||
callback();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// read a fixture file synchronously
|
||||
function file(name) {
|
||||
return fs.readFileSync(join(fixtures, name));
|
||||
}
|
||||
|
||||
|
||||
describe('gzippo.staticGzip', function() {
|
||||
|
||||
app = express();
|
||||
app.use(gzippo.staticGzip(fixtures));
|
||||
app.use(app.router);
|
||||
app.listen(port);
|
||||
|
||||
// set up a new server for each test
|
||||
// beforeEach(function(done) {
|
||||
// });
|
||||
|
||||
// afterEach(function() {
|
||||
// app.exit();
|
||||
// });
|
||||
|
||||
|
||||
it('should gzip static .json file', function(done) {
|
||||
request('/user.json', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert.equal(res.headers['content-type'], 'application/json; charset=UTF-8');
|
||||
assert.equal(data.length, '69');
|
||||
assert.equal(res.headers['content-encoding'], 'gzip');
|
||||
|
||||
assert.deepEqual(data, file('user.gzip'));
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// it('should get a route', function(done) {
|
||||
// request('/', { },
|
||||
// function(err, res, data) {
|
||||
// console.log(data.toString());
|
||||
// if (err) throw err;
|
||||
// assert.equal(res.statusCode, 200);
|
||||
|
||||
// assert.deepEqual(data, 'ok');
|
||||
|
||||
// done();
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
|
||||
it('should gzip static .js file', function(done) {
|
||||
request('/test.js', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
|
||||
assert.equal(res.headers['content-type'], 'application/javascript; charset=UTF-8');
|
||||
assert.equal(data.length, '35');
|
||||
assert.equal(res.headers['content-encoding'], 'gzip');
|
||||
|
||||
assert.deepEqual(data, file('test.js.gzip'));
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('should serve a .js file uncompressed when the accept-encoding header has not been set', function(done) {
|
||||
request('/test.js', {}, function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert.equal(data.length, '15');
|
||||
assert.deepEqual(data, file('test.js'));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should successfully gzip a utf-8 file', function(done) {
|
||||
request('/utf8.txt', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
|
||||
assert.equal(res.headers['content-type'], 'text/plain; charset=UTF-8');
|
||||
assert.equal(data.length, '2031');
|
||||
assert.equal(res.headers['content-encoding'], 'gzip');
|
||||
|
||||
assert.deepEqual(data, file('utf8.txt.gz'));
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('should cache a previously gzipped utf-8 file (and respond with a 304 Not Modified)', function(done) {
|
||||
request('/utf8.txt', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
|
||||
var headers = {
|
||||
'Accept-Encoding': 'gzip',
|
||||
'If-Modified-Since': res.headers['last-modified']
|
||||
};
|
||||
|
||||
request('/utf8.txt', headers, statusCode(304, done));
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('should set max age resources which are passed to the default static content provider', function(done) {
|
||||
request('/tomg.co.png', {},
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert.notEqual(res.headers['cache-control'].indexOf('max-age=604800'), -1);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('should allow normal traversal', function(done) {
|
||||
request('/nom/../tomg.co.png', {},
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert.deepEqual(data, file('tomg.co.png'));
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should redirect on directories', function(done) {
|
||||
request('/js', {}, statusCode(301, done));
|
||||
});
|
||||
|
||||
it('should work for paths containing URI-encoded spaces', function(done) {
|
||||
request('/space%20the%20final%20frontier/tomg.co.png', { 'Accept-Encoding': 'gzip' }, statusCode(200, done));
|
||||
});
|
||||
|
||||
|
||||
it('should not let the user access files outside of the static directory (urlencoded)', function(done) {
|
||||
request('/../test-static.js', { 'Accept-Encoding': 'gzip' }, statusCode(403, done));
|
||||
});
|
||||
|
||||
|
||||
it('should not let the user access files outside of the static directory', function(done) {
|
||||
request('/%2e%2e/test-static.js', { 'Accept-Encoding': 'gzip' }, statusCode(403, done));
|
||||
});
|
||||
|
||||
it('should not let the user access files from root of file system', function(done) {
|
||||
request('/etc/password', { 'Accept-Encoding': 'gzip' }, statusCode(404, done));
|
||||
});
|
||||
|
||||
|
||||
it('should serve index.html for directories (if found)', function(done) {
|
||||
request('/index_test/', { 'Accept-Encoding': 'gzip' },
|
||||
function(err, res, data) {
|
||||
if (err) throw err;
|
||||
assert.equal(res.statusCode, 200);
|
||||
// assert.equal(res.headers['content-length'], '616');
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
1230
public/images/BlankBody.js
Normal file
1230
public/images/BlankBody.js
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 128 KiB |
BIN
public/images/BlankBody.svgz
Normal file
BIN
public/images/BlankBody.svgz
Normal file
Binary file not shown.
@@ -40,12 +40,14 @@ $(document).ready(function() {
|
||||
// settings: {width: '10cm', height: '5cm'}, // Additional settings for SVG element
|
||||
// initPath: ''});
|
||||
|
||||
|
||||
$('span.SVGBODY').empty().load("/images/BlankBody.svg", function(){
|
||||
//$("button").button();
|
||||
});
|
||||
|
||||
|
||||
var colors = "0f0 0ff f60 f0f 00f f00".split(' '), i=0;
|
||||
|
||||
$(document).on('click', 'g',(function() {
|
||||
$(document).on('click', '.SVGBODYFilter g',(function() {
|
||||
console.log('click ' + this.id);
|
||||
$(this).children('path').css("fill",'#'+colors[i++%colors.length] +'');
|
||||
})
|
||||
@@ -143,6 +145,9 @@ $(document).ready(function() {
|
||||
var id = $(this).attr('value');
|
||||
$('div#Rightpane').empty().load("/workouts/"+ id + "/recent/", function(){
|
||||
$("button").button();
|
||||
$('span.SVGBODY').empty().load("/images/BlankBody.svg", function(){
|
||||
//$("button").button();
|
||||
});
|
||||
});
|
||||
$('div#Leftpane').empty().load("/users/"+ id + "/sidebar", function(){
|
||||
$("button").button();
|
||||
@@ -154,6 +159,10 @@ $(document).ready(function() {
|
||||
var id = $(this).attr('value');
|
||||
$('div#Rightpane').empty().load(id);
|
||||
$('div#Leftpane').empty().load("/workouts/filters", function(){
|
||||
$('span.SVGBODYFilter').empty().load("/images/BlankBody.svg", function(){
|
||||
//$("button").button();
|
||||
});
|
||||
|
||||
PopulateExerciseList(originalExerciselist);
|
||||
$("ul#exercises").sortable({
|
||||
items: "> li",
|
||||
@@ -170,7 +179,6 @@ $(document).ready(function() {
|
||||
|
||||
});
|
||||
$("button").button();
|
||||
$(document).on('click', 'path#F_x5F_Pectorals', function(){alert('hello2');});
|
||||
});
|
||||
|
||||
$("#top").delegate("button.home-link", "click",function() {
|
||||
@@ -180,6 +188,10 @@ $(document).ready(function() {
|
||||
var id = $(this).attr('value');
|
||||
$('div#Rightpane').empty().load("/workouts/"+ id + "/recent/", function(){
|
||||
$("button").button();
|
||||
console.log('here');
|
||||
$('span.SVGBODY').empty().load("/images/BlankBody.svg", function(){
|
||||
//$("button").button();
|
||||
});
|
||||
});
|
||||
$('div#Leftpane').empty().load("/users/"+ id + "/sidebar", function(){
|
||||
$("button").button();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
body {
|
||||
padding: 50px;
|
||||
xxpadding: 50px;
|
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ list-style-type: none;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
|
||||
.labelli {
|
||||
height : 30px;
|
||||
}
|
||||
|
||||
.floatright {
|
||||
float: right;
|
||||
}
|
||||
@@ -23,6 +28,12 @@ list-style-type: none;
|
||||
clear: right;
|
||||
}
|
||||
|
||||
li.floatleft {
|
||||
display: block;
|
||||
float: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.floatleft {
|
||||
display: block;
|
||||
float: left;
|
||||
@@ -32,12 +43,15 @@ list-style-type: none;
|
||||
#Leftpane {
|
||||
display: block;
|
||||
float: left;
|
||||
xxxwidth: 190px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
#Rightpane {
|
||||
display: block;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#userphoto {
|
||||
|
||||
@@ -2,21 +2,30 @@ h1 New workout
|
||||
|
||||
div#filters
|
||||
h3 Filters
|
||||
label Search
|
||||
input#searchbox (type="text", placeholder="Type here....")
|
||||
label Free Weights
|
||||
input.filter(type="checkbox", checked=true, value="Free Weights")
|
||||
label Bodyweight
|
||||
input.filter(type="checkbox", checked=true, value="Bodyweight")
|
||||
label Exercise Machines
|
||||
input.filter(type="checkbox", checked=true, value='Exercise Machine')
|
||||
label Kettlebells
|
||||
input.filter(type="checkbox", checked=true, value='Kettlebells')
|
||||
label Cardio
|
||||
input.filter(type="checkbox", checked=true, value='Cardio')
|
||||
div
|
||||
object(data='/images/BlankBody.svg', id='BlankBodyFilter', type='image/svg+xml')
|
||||
div.floatleftx
|
||||
label Search
|
||||
input#searchbox (type="text", placeholder="Type here....")
|
||||
span(class="SVGBODYFilter floatleft")
|
||||
span.floatleft
|
||||
ul
|
||||
li.labelli
|
||||
label Free Weights
|
||||
input.filter(type="checkbox", checked=true, value="Free Weights")
|
||||
li.labelli
|
||||
label Bodyweight
|
||||
input.filter(type="checkbox", checked=true, value="Bodyweight")
|
||||
li.labelli
|
||||
label Exercise Machines
|
||||
input.filter(type="checkbox", checked=true, value='Exercise Machine')
|
||||
li.labelli
|
||||
label Kettlebells
|
||||
input.filter(type="checkbox", checked=true, value='Kettlebells')
|
||||
li.labelli
|
||||
label Cardio
|
||||
input.filter(type="checkbox", checked=true, value='Cardio')
|
||||
|
||||
h3 Exercises (dynamically loaded from database)
|
||||
ul#exerciselist
|
||||
li Unpopulated
|
||||
|
||||
div.floatleft
|
||||
h3 Exercises (dynamically loaded from database)
|
||||
ul#exerciselist
|
||||
li Unpopulated
|
||||
|
||||
@@ -9,6 +9,7 @@ h3 Recent workouts:
|
||||
ol
|
||||
each split in element.splits
|
||||
li Reps: #{split.reps} Weight: #{split.weight}
|
||||
span(class="floatleft")
|
||||
include ../../public/images/BlankBody.svg
|
||||
span(class="floatleft SVGBODY")
|
||||
//include ../../public/images/BlankBody.svg
|
||||
span(class="clearright")
|
||||
- });
|
||||
Reference in New Issue
Block a user