Commit 9005a739 authored by Leo Iannacone's avatar Leo Iannacone

update internal libraries

parent 94c2ad3a
1.0.2 / 2014-06-05
==================
* Pass on errors from reading error files
1.0.1 / 2014-04-29 1.0.1 / 2014-04-29
================== ==================
......
# Error Handler # errorhandler
[![NPM version](https://badge.fury.io/js/errorhandler.svg)](http://badge.fury.io/js/errorhandler)
[![Build Status](https://travis-ci.org/expressjs/errorhandler.svg?branch=master)](https://travis-ci.org/expressjs/errorhandler)
[![Coverage Status](https://img.shields.io/coveralls/expressjs/errorhandler.svg?branch=master)](https://coveralls.io/r/expressjs/errorhandler)
Previously `connect.errorHandler()`. Previously `connect.errorHandler()`.
[![Build Status](https://travis-ci.org/expressjs/errorhandler.svg?branch=master)](https://travis-ci.org/expressjs/errorhandler) ## Install
```sh
$ npm install errorhandler
```
Usage: ## API
### errorhandler()
Create new middleware to handle errors and respond with content negotiation.
This middleware is only intended to be used in a development environment, as
the full error stack traces will be send back to the client when an error
occurs.
## Example
```js ```js
var app = require('connect'); var connect = require('connect')
app.use(require('errorhandler')()) var errorhandler = require('errorhandler')
var app = connect()
if (process.env.NODE_ENV === 'development') {
app.use(errorhandler())
}
``` ```
## License ## License
......
/*! /*!
* Connect - errorHandler * errorhandler
* Copyright(c) 2010 Sencha Inc. * Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk * Copyright(c) 2011 TJ Holowaychuk
* MIT Licensed * MIT Licensed
...@@ -55,7 +55,9 @@ exports = module.exports = function errorHandler(){ ...@@ -55,7 +55,9 @@ exports = module.exports = function errorHandler(){
// html // html
if (~accept.indexOf('html')) { if (~accept.indexOf('html')) {
fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){ fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){
if (e) return next(e);
fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){ fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){
if (e) return next(e);
var stack = (err.stack || '') var stack = (err.stack || '')
.split('\n').slice(1) .split('\n').slice(1)
.map(function(v){ return '<li>' + v + '</li>'; }).join(''); .map(function(v){ return '<li>' + v + '</li>'; }).join('');
......
{ {
"name": "errorhandler", "name": "errorhandler",
"description": "connect's default error handler page", "description": "connect's default error handler page",
"version": "1.0.1", "version": "1.0.2",
"author": { "author": {
"name": "Jonathan Ong", "name": "Jonathan Ong",
"email": "me@jongleberry.com", "email": "me@jongleberry.com",
...@@ -10,29 +10,32 @@ ...@@ -10,29 +10,32 @@
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/expressjs/errorhandler.git" "url": "git://github.com/expressjs/errorhandler"
},
"bugs": {
"url": "https://github.com/expressjs/errorhandler/issues"
}, },
"devDependencies": { "devDependencies": {
"connect": "3",
"istanbul": "0.2.10",
"mocha": ">= 1.17.0 < 2", "mocha": ">= 1.17.0 < 2",
"should": ">= 3.0.0 < 4", "should": "~4.0.1",
"supertest": "*", "supertest": "~0.13.0"
"connect": "*"
}, },
"engines": { "engines": {
"node": ">= 0.8" "node": ">= 0.8"
}, },
"scripts": { "scripts": {
"test": "mocha --reporter spec --require should" "test": "mocha --reporter dot test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/"
}, },
"readme": "# Error Handler\n\nPreviously `connect.errorHandler()`.\n\n[![Build Status](https://travis-ci.org/expressjs/errorhandler.svg?branch=master)](https://travis-ci.org/expressjs/errorhandler)\n\nUsage:\n\n```js\nvar app = require('connect');\napp.use(require('errorhandler')())\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", "readme": "# errorhandler\n\n[![NPM version](https://badge.fury.io/js/errorhandler.svg)](http://badge.fury.io/js/errorhandler)\n[![Build Status](https://travis-ci.org/expressjs/errorhandler.svg?branch=master)](https://travis-ci.org/expressjs/errorhandler)\n[![Coverage Status](https://img.shields.io/coveralls/expressjs/errorhandler.svg?branch=master)](https://coveralls.io/r/expressjs/errorhandler)\n\nPreviously `connect.errorHandler()`.\n\n## Install\n\n```sh\n$ npm install errorhandler\n```\n\n## API\n\n### errorhandler()\n\nCreate new middleware to handle errors and respond with content negotiation.\nThis middleware is only intended to be used in a development environment, as\nthe full error stack traces will be send back to the client when an error\noccurs.\n\n## Example\n\n```js\nvar connect = require('connect')\nvar errorhandler = require('errorhandler')\n\nvar app = connect()\n\nif (process.env.NODE_ENV === 'development') {\n app.use(errorhandler())\n}\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
"readmeFilename": "README.md", "readmeFilename": "README.md",
"_id": "errorhandler@1.0.1", "bugs": {
"url": "https://github.com/expressjs/errorhandler/issues"
},
"_id": "errorhandler@1.0.2",
"dist": { "dist": {
"shasum": "b080f545d915536eef71d75e292a4efcdd3f2540" "shasum": "18b3d7cf7f8cc6d34b758dc99fb79afa9697dab3"
}, },
"_from": "errorhandler @*", "_from": "errorhandler @*",
"_resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.0.1.tgz" "_resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.0.2.tgz"
} }
4.4.3 / 2014-06-11
==================
* fix persistence of modified `req.params[name]` from `app.param()`
* deps: accepts@1.0.3
- deps: negotiator@0.4.6
* deps: debug@1.0.2
* deps: send@0.4.3
- Do not throw un-catchable error on file open race condition
- Use `escape-html` for HTML escaping
- deps: debug@1.0.2
- deps: finished@1.2.2
- deps: fresh@0.2.2
* deps: serve-static@1.2.3
- Do not throw un-catchable error on file open race condition
- deps: send@0.4.3
4.4.2 / 2014-06-09
==================
* fix catching errors from top-level handlers
* use `vary` module for `res.vary`
* deps: debug@1.0.1
* deps: proxy-addr@1.0.1
* deps: send@0.4.2
- fix "event emitter leak" warnings
- deps: debug@1.0.1
- deps: finished@1.2.1
* deps: serve-static@1.2.2
- fix "event emitter leak" warnings
- deps: send@0.4.2
* deps: type-is@1.2.1
4.4.1 / 2014-06-02 4.4.1 / 2014-06-02
================== ==================
...@@ -155,6 +188,75 @@ ...@@ -155,6 +188,75 @@
- `app.route()` - Proxy to the app's `Router#route()` method to create a new route - `app.route()` - Proxy to the app's `Router#route()` method to create a new route
- Router & Route - public API - Router & Route - public API
3.10.5 / 2014-06-11
===================
* deps: connect@2.19.6
- deps: body-parser@1.3.1
- deps: compression@1.0.7
- deps: debug@1.0.2
- deps: serve-index@1.1.1
- deps: serve-static@1.2.3
* deps: debug@1.0.2
* deps: send@0.4.3
- Do not throw un-catchable error on file open race condition
- Use `escape-html` for HTML escaping
- deps: debug@1.0.2
- deps: finished@1.2.2
- deps: fresh@0.2.2
3.10.4 / 2014-06-09
===================
* deps: connect@2.19.5
- fix "event emitter leak" warnings
- deps: csurf@1.2.1
- deps: debug@1.0.1
- deps: serve-static@1.2.2
- deps: type-is@1.2.1
* deps: debug@1.0.1
* deps: send@0.4.2
- fix "event emitter leak" warnings
- deps: finished@1.2.1
- deps: debug@1.0.1
3.10.3 / 2014-06-05
===================
* use `vary` module for `res.vary`
* deps: connect@2.19.4
- deps: errorhandler@1.0.2
- deps: method-override@2.0.2
- deps: serve-favicon@2.0.1
* deps: debug@1.0.0
3.10.2 / 2014-06-03
===================
* deps: connect@2.19.3
- deps: compression@1.0.6
3.10.1 / 2014-06-03
===================
* deps: connect@2.19.2
- deps: compression@1.0.4
* deps: proxy-addr@1.0.1
3.10.0 / 2014-06-02
===================
* deps: connect@2.19.1
- deprecate `methodOverride()` -- use `method-override` module directly
- deps: body-parser@1.3.0
- deps: method-override@2.0.1
- deps: multiparty@3.2.8
- deps: response-time@2.0.0
- deps: serve-static@1.2.1
* deps: methods@1.0.1
* deps: send@0.4.1
- Send `max-age` in `Cache-Control` in correct format
3.9.0 / 2014-05-30 3.9.0 / 2014-05-30
================== ==================
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). Fast, unopinionated, minimalist web framework for [node](http://nodejs.org).
[![NPM version](https://badge.fury.io/js/express.svg)](http://badge.fury.io/js/express) [![Build Status](https://travis-ci.org/visionmedia/express.svg?branch=master)](https://travis-ci.org/visionmedia/express) [![Coverage Status](https://img.shields.io/coveralls/visionmedia/express.svg)](https://coveralls.io/r/visionmedia/express) [![Gittip](http://img.shields.io/gittip/visionmedia.svg)](https://www.gittip.com/visionmedia/) [![NPM version](https://badge.fury.io/js/express.svg)](http://badge.fury.io/js/express)
[![Build Status](https://travis-ci.org/visionmedia/express.svg?branch=master)](https://travis-ci.org/visionmedia/express)
[![Coverage Status](https://img.shields.io/coveralls/visionmedia/express.svg)](https://coveralls.io/r/visionmedia/express)
[![Gittip](http://img.shields.io/gittip/visionmedia.svg)](https://www.gittip.com/visionmedia/)
```js ```js
var express = require('express'); var express = require('express');
......
...@@ -14,6 +14,7 @@ var http = require('http'); ...@@ -14,6 +14,7 @@ var http = require('http');
var compileETag = require('./utils').compileETag; var compileETag = require('./utils').compileETag;
var compileTrust = require('./utils').compileTrust; var compileTrust = require('./utils').compileTrust;
var deprecate = require('./utils').deprecate; var deprecate = require('./utils').deprecate;
var resolve = require('path').resolve;
/** /**
* Application prototype. * Application prototype.
...@@ -74,7 +75,7 @@ app.defaultConfiguration = function(){ ...@@ -74,7 +75,7 @@ app.defaultConfiguration = function(){
// default configuration // default configuration
this.set('view', View); this.set('view', View);
this.set('views', process.cwd() + '/views'); this.set('views', resolve('views'));
this.set('jsonp callback name', 'callback'); this.set('jsonp callback name', 'callback');
if (env === 'production') { if (env === 'production') {
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
* Module dependencies. * Module dependencies.
*/ */
var escapeHtml = require('escape-html');
var http = require('http'); var http = require('http');
var path = require('path'); var path = require('path');
var mixin = require('utils-merge'); var mixin = require('utils-merge');
var escapeHtml = require('escape-html');
var sign = require('cookie-signature').sign; var sign = require('cookie-signature').sign;
var normalizeType = require('./utils').normalizeType; var normalizeType = require('./utils').normalizeType;
var normalizeTypes = require('./utils').normalizeTypes; var normalizeTypes = require('./utils').normalizeTypes;
...@@ -18,6 +18,7 @@ var send = require('send'); ...@@ -18,6 +18,7 @@ var send = require('send');
var basename = path.basename; var basename = path.basename;
var extname = path.extname; var extname = path.extname;
var mime = send.mime; var mime = send.mime;
var vary = require('vary');
/** /**
* Response prototype. * Response prototype.
...@@ -735,31 +736,12 @@ res.redirect = function(url){ ...@@ -735,31 +736,12 @@ res.redirect = function(url){
*/ */
res.vary = function(field){ res.vary = function(field){
var self = this; // checks for back-compat
// nothing
if (!field) return this; if (!field) return this;
if (Array.isArray(field) && !field.length) return this;
// array vary(this, field);
if (Array.isArray(field)) {
field.forEach(function(field){
self.vary(field);
});
return;
}
var vary = this.get('Vary');
// append
if (vary) {
vary = vary.split(/ *, */);
if (!~vary.indexOf(field)) vary.push(field);
this.set('Vary', vary.join(', '));
return this;
}
// set
this.set('Vary', field);
return this; return this;
}; };
......
...@@ -245,15 +245,15 @@ proto.handle = function(req, res, done) { ...@@ -245,15 +245,15 @@ proto.handle = function(req, res, done) {
debug('%s %s : %s', layer.handle.name || 'anonymous', layerPath, req.originalUrl); debug('%s %s : %s', layer.handle.name || 'anonymous', layerPath, req.originalUrl);
var arity = layer.handle.length; var arity = layer.handle.length;
if (err) { try {
if (arity === 4) { if (err && arity === 4) {
layer.handle(err, req, res, next); layer.handle(err, req, res, next);
} else if (!err && arity < 4) {
layer.handle(req, res, next);
} else { } else {
next(err); next(err);
} }
} else if (arity < 4) { } catch (err) {
layer.handle(req, res, next);
} else {
next(err); next(err);
} }
} }
...@@ -320,11 +320,19 @@ proto.process_params = function(layer, called, req, res, done) { ...@@ -320,11 +320,19 @@ proto.process_params = function(layer, called, req, res, done) {
} }
// param previously called with same value or error occurred // param previously called with same value or error occurred
if (paramCalled && (paramCalled.err || paramCalled.val === paramVal)) { if (paramCalled && (paramCalled.error || paramCalled.match === paramVal)) {
return param(paramCalled.err); // restore value
req.params[name] = paramCalled.value;
// next param
return param(paramCalled.error);
} }
called[name] = paramCalled = { val: paramVal }; called[name] = paramCalled = {
error: null,
match: paramVal,
value: paramVal
};
try { try {
return paramCallback(); return paramCallback();
...@@ -335,13 +343,20 @@ proto.process_params = function(layer, called, req, res, done) { ...@@ -335,13 +343,20 @@ proto.process_params = function(layer, called, req, res, done) {
// single param callbacks // single param callbacks
function paramCallback(err) { function paramCallback(err) {
if (err && paramCalled) { var fn = paramCallbacks[paramIndex++];
// store updated value
paramCalled.value = req.params[key.name];
if (err) {
// store error // store error
paramCalled.err = err; paramCalled.error = err;
param(err);
return;
} }
var fn = paramCallbacks[paramIndex++]; if (!fn) return param();
if (err || !fn) return param(err);
fn(req, res, paramCallback, paramVal, key.name); fn(req, res, paramCallback, paramVal, key.name);
} }
......
1.0.3 / 2014-06-11
==================
* deps: negotiator@0.4.6
- Order by specificity when quality is the same
1.0.2 / 2014-05-29 1.0.2 / 2014-05-29
================== ==================
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
[![NPM version](https://badge.fury.io/js/accepts.svg)](http://badge.fury.io/js/accepts) [![NPM version](https://badge.fury.io/js/accepts.svg)](http://badge.fury.io/js/accepts)
[![Build Status](https://travis-ci.org/expressjs/accepts.svg?branch=master)](https://travis-ci.org/expressjs/accepts) [![Build Status](https://travis-ci.org/expressjs/accepts.svg?branch=master)](https://travis-ci.org/expressjs/accepts)
[![Coverage Status](https://img.shields.io/coveralls/expressjs/accepts.svg?branch=master)](https://coveralls.io/r/expressjs/accepts)
Higher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use. Higher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.
......
...@@ -31,5 +31,9 @@ ...@@ -31,5 +31,9 @@
"url": "https://github.com/broofa/node-mime/issues" "url": "https://github.com/broofa/node-mime/issues"
}, },
"_id": "mime@1.2.11", "_id": "mime@1.2.11",
"_from": "mime@~1.2.11" "dist": {
"shasum": "2e68433cd8b933cc360926e916e08e705e3bf1ae"
},
"_from": "mime@~1.2.11",
"_resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
} }
...@@ -33,12 +33,15 @@ function parseCharset(s) { ...@@ -33,12 +33,15 @@ function parseCharset(s) {
} }
function getCharsetPriority(charset, accepted) { function getCharsetPriority(charset, accepted) {
return (accepted.filter(function(a) { return (accepted.map(function(a) {
return specify(charset, a); return specify(charset, a);
}).sort(function (a, b) { }).filter(Boolean).sort(function (a, b) {
// revsort if(a.s == b.s) {
return a.q > b.q ? -1 : 1;
} else {
return a.s > b.s ? -1 : 1; return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q; }
})[0] || {s: 0, q:0});
} }
function specify(charset, spec) { function specify(charset, spec) {
...@@ -62,10 +65,15 @@ function preferredCharsets(accept, provided) { ...@@ -62,10 +65,15 @@ function preferredCharsets(accept, provided) {
return provided.map(function(type) { return provided.map(function(type) {
return [type, getCharsetPriority(type, accept)]; return [type, getCharsetPriority(type, accept)];
}).filter(function(pair) { }).filter(function(pair) {
return pair[1] > 0; return pair[1].q > 0;
}).sort(function(a, b) { }).sort(function(a, b) {
// revsort var pa = a[1];
return a[1] > b[1] ? -1 : 1; var pb = b[1];
if(pa.q == pb.q) {
return pa.s < pb.s ? 1 : -1;
} else {
return pa.q < pb.q ? 1 : -1;
}
}).map(function(pair) { }).map(function(pair) {
return pair[0]; return pair[0];
}); });
......
...@@ -66,12 +66,13 @@ function parseEncoding(s) { ...@@ -66,12 +66,13 @@ function parseEncoding(s) {
function getEncodingPriority(encoding, accepted) { function getEncodingPriority(encoding, accepted) {
return (accepted.map(function(a) { return (accepted.map(function(a) {
return specify(encoding, a); return specify(encoding, a);
}).filter(function(a){ }).filter(Boolean).sort(function (a, b) {
return a; if(a.s == b.s) {
}).sort(function (a, b) { return a.q > b.q ? -1 : 1;
// revsort } else {
return a.s > b.s ? -1 : 1; return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q; }
})[0] || {s: 0, q: 0});
} }
function specify(encoding, spec) { function specify(encoding, spec) {
...@@ -94,10 +95,15 @@ function preferredEncodings(accept, provided) { ...@@ -94,10 +95,15 @@ function preferredEncodings(accept, provided) {
return provided.map(function(type) { return provided.map(function(type) {
return [type, getEncodingPriority(type, accept)]; return [type, getEncodingPriority(type, accept)];
}).filter(function(pair) { }).filter(function(pair) {
return pair[1] > 0; return pair[1].q > 0;
}).sort(function(a, b) { }).sort(function(a, b) {
// revsort var pa = a[1];
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; var pb = b[1];
if(pa.q == pb.q) {
return pa.s < pb.s ? 1 : -1;
} else {
return pa.q < pb.q ? 1 : -1;
}
}).map(function(pair) { }).map(function(pair) {
return pair[0]; return pair[0];
}); });
......
...@@ -39,12 +39,13 @@ function parseLanguage(s) { ...@@ -39,12 +39,13 @@ function parseLanguage(s) {
function getLanguagePriority(language, accepted) { function getLanguagePriority(language, accepted) {
return (accepted.map(function(a){ return (accepted.map(function(a){
return specify(language, a); return specify(language, a);
}).filter(function(a){ }).filter(Boolean).sort(function (a, b) {
return a; if(a.s == b.s) {
}).sort(function(a, b){ return a.q > b.q ? -1 : 1;
// revsort } else {
return a.s > b.s ? -1 : 1; return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q; }
})[0] || {s: 0, q: 0});
} }
function specify(language, spec) { function specify(language, spec) {
...@@ -74,10 +75,15 @@ function preferredLanguages(accept, provided) { ...@@ -74,10 +75,15 @@ function preferredLanguages(accept, provided) {
var ret = provided.map(function(type) { var ret = provided.map(function(type) {
return [type, getLanguagePriority(type, accept)]; return [type, getLanguagePriority(type, accept)];
}).filter(function(pair) { }).filter(function(pair) {
return pair[1] > 0; return pair[1].q > 0;
}).sort(function(a, b) { }).sort(function(a, b) {
// revsort var pa = a[1];
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; var pb = b[1];
if(pa.q == pb.q) {
return pa.s < pb.s ? 1 : -1;
} else {
return pa.q < pb.q ? 1 : -1;
}
}).map(function(pair) { }).map(function(pair) {
return pair[0]; return pair[0];
}); });
......
...@@ -46,9 +46,12 @@ function getMediaTypePriority(type, accepted) { ...@@ -46,9 +46,12 @@ function getMediaTypePriority(type, accepted) {
return (accepted.map(function(a) { return (accepted.map(function(a) {
return specify(type, a); return specify(type, a);
}).filter(Boolean).sort(function (a, b) { }).filter(Boolean).sort(function (a, b) {
// revsort if(a.s == b.s) {
return a.q > b.q ? -1 : 1;
} else {
return a.s > b.s ? -1 : 1; return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q; }
})[0] || {s: 0, q: 0});
} }
function specify(type, spec) { function specify(type, spec) {
...@@ -91,10 +94,15 @@ function preferredMediaTypes(accept, provided) { ...@@ -91,10 +94,15 @@ function preferredMediaTypes(accept, provided) {
return provided.map(function(type) { return provided.map(function(type) {
return [type, getMediaTypePriority(type, accept)]; return [type, getMediaTypePriority(type, accept)];
}).filter(function(pair) { }).filter(function(pair) {
return pair[1] > 0; return pair[1].q > 0;
}).sort(function(a, b) { }).sort(function(a, b) {
// revsort var pa = a[1];
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; var pb = b[1];
if(pa.q == pb.q) {
return pa.s < pb.s ? 1 : -1;
} else {
return pa.q < pb.q ? 1 : -1;
}
}).map(function(pair) { }).map(function(pair) {
return pair[0]; return pair[0];
}); });
...@@ -110,5 +118,3 @@ function preferredMediaTypes(accept, provided) { ...@@ -110,5 +118,3 @@ function preferredMediaTypes(accept, provided) {
}); });
} }
} }
{ {
"name": "negotiator", "name": "negotiator",
"description": "HTTP content negotiation", "description": "HTTP content negotiation",
"version": "0.4.5", "version": "0.4.6",
"author": { "author": {
"name": "Federico Romero", "name": "Federico Romero",
"email": "federico.romero@outboxlabs.com" "email": "federico.romero@outboxlabs.com"
...@@ -44,6 +44,10 @@ ...@@ -44,6 +44,10 @@
"url": "https://github.com/federomero/negotiator/issues" "url": "https://github.com/federomero/negotiator/issues"
}, },
"dependencies": {}, "dependencies": {},
"_id": "negotiator@0.4.5", "_id": "negotiator@0.4.6",
"_from": "negotiator@0.4.5" "dist": {
"shasum": "07156737b64fd5c575de0acb7282ecaf9867a1b0"
},
"_from": "negotiator@0.4.6",
"_resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.6.tgz"
} }
{ {
"name": "accepts", "name": "accepts",
"description": "Higher-level content negotiation", "description": "Higher-level content negotiation",
"version": "1.0.2", "version": "1.0.3",
"author": { "author": {
"name": "Jonathan Ong", "name": "Jonathan Ong",
"email": "me@jongleberry.com", "email": "me@jongleberry.com",
...@@ -10,16 +10,14 @@ ...@@ -10,16 +10,14 @@
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/expressjs/accepts.git" "url": "git://github.com/expressjs/accepts"
},
"bugs": {
"url": "https://github.com/expressjs/accepts/issues"
}, },
"dependencies": { "dependencies": {
"mime": "~1.2.11", "mime": "~1.2.11",
"negotiator": "0.4.5" "negotiator": "0.4.6"
}, },
"devDependencies": { "devDependencies": {
"istanbul": "0.2.10",
"mocha": "*", "mocha": "*",
"should": "*" "should": "*"
}, },
...@@ -27,11 +25,19 @@ ...@@ -27,11 +25,19 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
}, },
"scripts": { "scripts": {
"test": "mocha --require should --reporter dot", "test": "mocha --require should --reporter dot test/",
"test-travis": "mocha --require should --reporter spec" "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require should --reporter dot test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require should --reporter spec test/"
}, },
"readme": "# Accepts\n\n[![NPM version](https://badge.fury.io/js/accepts.svg)](http://badge.fury.io/js/accepts)\n[![Build Status](https://travis-ci.org/expressjs/accepts.svg?branch=master)](https://travis-ci.org/expressjs/accepts)\n\nHigher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.\n\nIn addition to negotatior, it allows:\n\n- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.\n- Allows type shorthands such as `json`.\n- Returns `false` when no types match\n- Treats non-existent headers as `*`\n\n## API\n\n### var accept = new Accepts(req)\n\n```js\nvar accepts = require('accepts')\n\nhttp.createServer(function (req, res) {\n var accept = accepts(req)\n})\n```\n\n### accept\\[property\\]\\(\\)\n\nReturns all the explicitly accepted content property as an array in descending priority.\n\n- `accept.types()`\n- `accept.encodings()`\n- `accept.charsets()`\n- `accept.languages()`\n\nThey are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc.\n\nNote: you should almost never do this in a real app as it defeats the purpose of content negotiation.\n\nExample:\n\n```js\n// in Google Chrome\nvar encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate']\n```\n\nSince you probably don't support `sdch`, you should just supply the encodings you support:\n\n```js\nvar encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably\n```\n\n### accept\\[property\\]\\(values, ...\\)\n\nYou can either have `values` be an array or have an argument list of values.\n\nIf the client does not accept any `values`, `false` will be returned.\nIf the client accepts any `values`, the preferred `value` will be return.\n\nFor `accept.types()`, shorthand mime types are allowed.\n\nExample:\n\n```js\n// req.headers.accept = 'application/json'\n\naccept.types('json') // -> 'json'\naccept.types('html', 'json') // -> 'json'\naccept.types('html') // -> false\n\n// req.headers.accept = ''\n// which is equivalent to `*`\n\naccept.types() // -> [], no explicit types\naccept.types('text/html', 'text/json') // -> 'text/html', since it was first\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.", "readme": "# Accepts\n\n[![NPM version](https://badge.fury.io/js/accepts.svg)](http://badge.fury.io/js/accepts)\n[![Build Status](https://travis-ci.org/expressjs/accepts.svg?branch=master)](https://travis-ci.org/expressjs/accepts)\n[![Coverage Status](https://img.shields.io/coveralls/expressjs/accepts.svg?branch=master)](https://coveralls.io/r/expressjs/accepts)\n\nHigher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.\n\nIn addition to negotatior, it allows:\n\n- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.\n- Allows type shorthands such as `json`.\n- Returns `false` when no types match\n- Treats non-existent headers as `*`\n\n## API\n\n### var accept = new Accepts(req)\n\n```js\nvar accepts = require('accepts')\n\nhttp.createServer(function (req, res) {\n var accept = accepts(req)\n})\n```\n\n### accept\\[property\\]\\(\\)\n\nReturns all the explicitly accepted content property as an array in descending priority.\n\n- `accept.types()`\n- `accept.encodings()`\n- `accept.charsets()`\n- `accept.languages()`\n\nThey are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc.\n\nNote: you should almost never do this in a real app as it defeats the purpose of content negotiation.\n\nExample:\n\n```js\n// in Google Chrome\nvar encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate']\n```\n\nSince you probably don't support `sdch`, you should just supply the encodings you support:\n\n```js\nvar encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably\n```\n\n### accept\\[property\\]\\(values, ...\\)\n\nYou can either have `values` be an array or have an argument list of values.\n\nIf the client does not accept any `values`, `false` will be returned.\nIf the client accepts any `values`, the preferred `value` will be return.\n\nFor `accept.types()`, shorthand mime types are allowed.\n\nExample:\n\n```js\n// req.headers.accept = 'application/json'\n\naccept.types('json') // -> 'json'\naccept.types('html', 'json') // -> 'json'\naccept.types('html') // -> false\n\n// req.headers.accept = ''\n// which is equivalent to `*`\n\naccept.types() // -> [], no explicit types\naccept.types('text/html', 'text/json') // -> 'text/html', since it was first\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.",
"readmeFilename": "README.md", "readmeFilename": "README.md",
"_id": "accepts@1.0.2", "bugs": {
"_from": "accepts@1.0.2" "url": "https://github.com/expressjs/accepts/issues"
},
"_id": "accepts@1.0.3",
"dist": {
"shasum": "59c85dc0ca0a1addbbb501b009a9e516b1fb47a2"
},
"_from": "accepts@1.0.3",
"_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.3.tgz"
} }
1.0.2 / 2014-06-10
==================
* browser: update color palette (#113, @gscottolson)
* common: make console logging function configurable (#108, @timoxley)
* node: fix %o colors on old node <= 0.8.x
* Makefile: find node path using shell/which (#109, @timoxley)
1.0.1 / 2014-06-06
==================
* browser: use `removeItem()` to clear localStorage
* browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
* package: add "contributors" section
* node: fix comment typo
* README: list authors
1.0.0 / 2014-06-04
==================
* make ms diff be global, not be scope
* debug: ignore empty strings in enable()
* node: make DEBUG_COLORS able to disable coloring
* *: export the `colors` array
* npmignore: don't publish the `dist` dir
* Makefile: refactor to use browserify
* package: add "browserify" as a dev dependency
* Readme: add Web Inspector Colors section
* node: reset terminal color for the debug content
* node: map "%o" to `util.inspect()`
* browser: map "%j" to `JSON.stringify()`
* debug: add custom "formatters"
* debug: use "ms" module for humanizing the diff
* Readme: add "bash" syntax highlighting
* browser: add Firebug color support
* browser: add colors for WebKit browsers
* node: apply log to `console`
* rewrite: abstract common logic for Node & browsers
* add .jshintrc file
0.8.1 / 2014-04-14
==================
* package: re-add the "component" section
0.8.0 / 2014-03-30
==================
* add `enable()` method for nodejs. Closes #27
* change from stderr to stdout
* remove unnecessary index.js file
0.7.4 / 2013-11-13
==================
* remove "browserify" key from package.json (fixes something in browserify)
0.7.3 / 2013-10-30
==================
* fix: catch localStorage security error when cookies are blocked (Chrome)
* add debug(err) support. Closes #46
* add .browser prop to package.json. Closes #42
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
# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
# BIN directory
BIN := $(THIS_DIR)/node_modules/.bin
# applications
NODE ?= $(shell which node)
NPM ?= $(NODE) $(shell which npm)
BROWSERIFY ?= $(NODE) $(BIN)/browserify
all: dist/debug.js
install: node_modules
clean:
@rm -rf node_modules dist
dist:
@mkdir -p $@
dist/debug.js: node_modules browser.js debug.js dist
@$(BROWSERIFY) \
--standalone debug \
. > $@
node_modules: package.json
@NODE_ENV= $(NPM) install
@touch node_modules
.PHONY: all install clean
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
## Installation ## Installation
``` ```bash
$ npm install debug $ npm install debug
``` ```
...@@ -69,7 +69,7 @@ setInterval(function(){ ...@@ -69,7 +69,7 @@ setInterval(function(){
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=*`. 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:". 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 ## Browser support
...@@ -84,15 +84,54 @@ setInterval(function(){ ...@@ -84,15 +84,54 @@ setInterval(function(){
}, 1000); }, 1000);
setInterval(function(){ setInterval(function(){
a('doing some work'); b('doing some work');
}, 1200); }, 1200);
``` ```
#### Web Inspector Colors
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
option. These are WebKit web inspectors, and the Firebug plugin for Firefox.
Colored output looks something like:
![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
### stderr vs stdout
You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:
Example _stderr.js_:
```js
var debug = require('../');
var log = debug('app:log');
// by default console.log is used
log('goes to stdout!');
var error = debug('app:error');
// set this namespace to log via console.error
error.log = console.error.bind(console); // don't forget to bind to console!
error('goes to stderr');
log('still goes to stdout!');
// set all output to go via console.warn
// overrides all per-namespace log settings
debug.log = console.warn.bind(console);
log('now goes to stderr via console.warn');
error('still goes to stderr, but via console.warn now');
```
## Authors
- TJ Holowaychuk
- Nathan Rajlich
## License ## License
(The MIT License) (The MIT License)
Copyright (c) 2011 TJ Holowaychuk &lt;tj@vision-media.ca&gt; Copyright (c) 2014 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
......
/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
/**
* Colors.
*/
exports.colors = [
'lightseagreen',
'forestgreen',
'goldenrod',
'dodgerblue',
'darkorchid',
'crimson'
];
/**
* Currently only WebKit-based Web Inspectors and the Firebug
* extension (*not* the built-in Firefox web inpector) are
* known to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
function useColors() {
// is webkit? http://stackoverflow.com/a/16459606/376773
return ('WebkitAppearance' in document.documentElement.style) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(window.console && (console.firebug || (console.exception && console.table)));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
return JSON.stringify(v);
};
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs() {
var args = arguments;
var useColors = this.useColors;
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? '%c ' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!useColors) return args
var c = 'color: ' + this.color;
args = [args[0], c, ''].concat(Array.prototype.slice.call(args, 1));
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
return args;
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
// This hackery is required for IE8,
// where the `console.log` function doesn't have 'apply'
return 'object' == typeof console
&& 'function' == typeof console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
localStorage.removeItem('debug');
} else {
localStorage.debug = namespaces;
}
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = localStorage.debug;
} catch(e) {}
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
{
"name": "debug",
"repo": "visionmedia/debug",
"description": "small debugging utility",
"version": "1.0.2",
"keywords": [
"debug",
"log",
"debugger"
],
"main": "browser.js",
"scripts": [
"browser.js",
"debug.js"
],
"dependencies": {
"guille/ms.js": "0.6.1"
}
}
/** /**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*
* Expose `debug()` as the module. * Expose `debug()` as the module.
*/ */
module.exports = debug; exports = module.exports = debug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');
/** /**
* Create a debugger with the given `name`. * The currently active debug mode names, and names to skip.
*/
exports.names = [];
exports.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
* *
* @param {String} name * Valid key names are a single, lowercased letter, i.e. "n".
* @return {Type}
* @api public
*/ */
function debug(name) { exports.formatters = {};
if (!debug.enabled(name)) return function(){};
return function(fmt){ /**
fmt = coerce(fmt); * Previously assigned color.
*/
var curr = new Date; var prevColor = 0;
var ms = curr - (debug[name] || curr);
debug[name] = curr;
fmt = name /**
+ ' ' * Previous log timestamp.
+ fmt */
+ ' +' + debug.humanize(ms);
// This hackery is required for IE8 var prevTime;
// 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. * Select a color.
*
* @return {Number}
* @api private
*/ */
debug.names = []; function selectColor() {
debug.skips = []; return exports.colors[prevColor++ % exports.colors.length];
}
/** /**
* Enables a debug mode by name. This can include modes * Create a debugger with the given `namespace`.
* separated by a colon and wildcards.
* *
* @param {String} name * @param {String} namespace
* @return {Function}
* @api public * @api public
*/ */
debug.enable = function(name) { function debug(namespace) {
try {
localStorage.debug = name;
} catch(e){}
var split = (name || '').split(/[\s,]+/) // define the `disabled` version
, len = split.length; function disabled() {
}
disabled.enabled = false;
for (var i = 0; i < len; i++) { // define the `enabled` version
name = split[i].replace('*', '.*?'); function enabled() {
if (name[0] === '-') {
debug.skips.push(new RegExp('^' + name.substr(1) + '$')); var self = enabled;
// set `diff` timestamp
var curr = +new Date();
var ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
// add the `color` if not set
if (null == self.useColors) self.useColors = exports.useColors();
if (null == self.color && self.useColors) self.color = selectColor();
var args = Array.prototype.slice.call(arguments);
args[0] = exports.coerce(args[0]);
if ('string' !== typeof args[0]) {
// anything else let's inspect with %o
args = ['%o'].concat(args);
} }
else {
debug.names.push(new RegExp('^' + name + '$')); // apply any `formatters` transformations
var index = 0;
args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
// if we encounter an escaped % then don't increase the array index
if (match === '%%') return match;
index++;
var formatter = exports.formatters[format];
if ('function' === typeof formatter) {
var val = args[index];
match = formatter.call(self, val);
// now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
if ('function' === typeof exports.formatArgs) {
args = exports.formatArgs.apply(self, args);
} }
var logFn = exports.log || enabled.log || console.log.bind(console);
logFn.apply(self, args);
} }
}; enabled.enabled = true;
var fn = exports.enabled(namespace) ? enabled : disabled;
fn.namespace = namespace;
return fn;
}
/** /**
* Disable debug output. * Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
* *
* @param {String} namespaces
* @api public * @api public
*/ */
debug.disable = function(){ function enable(namespaces) {
debug.enable(''); exports.save(namespaces);
};
var split = (namespaces || '').split(/[\s,]+/);
var len = split.length;
for (var i = 0; i < len; i++) {
if (!split[i]) continue; // ignore empty strings
namespaces = split[i].replace('*', '.*?');
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
}
/** /**
* Humanize the given `ms`. * Disable debug output.
* *
* @param {Number} m * @api public
* @return {String}
* @api private
*/ */
debug.humanize = function(ms) { function disable() {
var sec = 1000 exports.enable('');
, 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. * Returns true if the given mode name is enabled, false otherwise.
...@@ -107,31 +168,30 @@ debug.humanize = function(ms) { ...@@ -107,31 +168,30 @@ debug.humanize = function(ms) {
* @api public * @api public
*/ */
debug.enabled = function(name) { function enabled(name) {
for (var i = 0, len = debug.skips.length; i < len; i++) { var i, len;
if (debug.skips[i].test(name)) { for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false; return false;
} }
} }
for (var i = 0, len = debug.names.length; i < len; i++) { for (i = 0, len = exports.names.length; i < len; i++) {
if (debug.names[i].test(name)) { if (exports.names[i].test(name)) {
return true; return true;
} }
} }
return false; return false;
}; }
/** /**
* Coerce `val`. * Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/ */
function coerce(val) { function coerce(val) {
if (val instanceof Error) return val.stack || val.message; if (val instanceof Error) return val.stack || val.message;
return val; return val;
} }
// persist
try {
if (window.localStorage) debug.enable(localStorage.debug);
} catch(e){}
/**
* Module dependencies.
*/
var tty = require('tty');
/**
* Expose `debug()` as the module.
*/
module.exports = debug;
/**
* Enabled debuggers.
*/
var names = []
, skips = [];
/**
* 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(1);
/**
* 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) {
fmt = coerce(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.log.apply(this, arguments);
}
function plain(fmt) {
fmt = coerce(fmt);
fmt = new Date().toUTCString()
+ ' ' + name + ' ' + fmt;
console.log.apply(this, arguments);
}
colored.enabled = plain.enabled = true;
return isatty || process.env.DEBUG_COLORS
? colored
: plain;
}
/**
* Coerce `val`.
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
/**
* Enable specified `namespaces` for debugging.
*/
debug.enable = function(namespaces) {
namespaces.split(/[\s,]+/)
.forEach(function(name){
name = name.replace('*', '.*?');
if (name[0] == '-') {
skips.push(new RegExp('^' + name.substr(1) + '$'));
} else {
names.push(new RegExp('^' + name + '$'));
}
});
};
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
debug.enable(process.env.DEBUG || '');
/**
* Module dependencies.
*/
var tty = require('tty');
var util = require('util');
/**
* This is the Node.js implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
/**
* Colors.
*/
exports.colors = [6, 2, 3, 4, 5, 1];
/**
* Is stdout a TTY? Colored output is enabled when `true`.
*/
function useColors() {
var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
if (0 === debugColors.length) {
return tty.isatty(1);
} else {
return '0' !== debugColors
&& 'no' !== debugColors
&& 'false' !== debugColors
&& 'disabled' !== debugColors;
}
}
/**
* Map %o to `util.inspect()`, since Node doesn't do that out of the box.
*/
var inspect = (4 === util.inspect.length ?
// node <= 0.8.x
function (v, colors) {
return util.inspect(v, void 0, void 0, colors);
} :
// node > 0.8.x
function (v, colors) {
return util.inspect(v, { colors: colors });
}
);
exports.formatters.o = function(v) {
return inspect(v, this.useColors)
.replace(/\s*\n\s*/g, ' ');
};
/**
* Adds ANSI color escape codes if enabled.
*
* @api public
*/
function formatArgs() {
var args = arguments;
var useColors = this.useColors;
var name = this.namespace;
if (useColors) {
var c = this.color;
args[0] = ' \u001b[9' + c + 'm' + name + ' '
+ '\u001b[0m'
+ args[0] + '\u001b[3' + c + 'm'
+ ' +' + exports.humanize(this.diff) + '\u001b[0m';
} else {
args[0] = new Date().toUTCString()
+ ' ' + name + ' ' + args[0];
}
return args;
}
/**
* Invokes `console.log()` with the specified arguments.
*/
function log() {
return console.log.apply(console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
if (null == namespaces) {
// If you set a process.env field to null or undefined, it gets cast to the
// string 'null' or 'undefined'. Just delete instead.
delete process.env.DEBUG;
} else {
process.env.DEBUG = namespaces;
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
return process.env.DEBUG;
}
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
exports.enable(load());
# ms.js: miliseconds conversion utility
```js
ms('1d') // 86400000
ms('10h') // 36000000
ms('2h') // 7200000
ms('1m') // 60000
ms('5s') // 5000
ms('100') // 100
```
```js
ms(60000) // "1m"
ms(2 * 60000) // "2m"
ms(ms('10 hours')) // "10h"
```
```js
ms(60000, { long: true }) // "1 minute"
ms(2 * 60000, { long: true }) // "2 minutes"
ms(ms('10 hours', { long: true })) // "10 hours"
```
- Node/Browser compatible. Published as `ms` in NPM.
- If a number is supplied to `ms`, a string with a unit is returned.
- If a string that contains the number is supplied, it returns it as
a number (e.g: it returns `100` for `'100'`).
- If you pass a string with a number and a valid unit, the number of
equivalent ms is returned.
## License
MIT
\ No newline at end of file
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} options
* @return {String|Number}
* @api public
*/
module.exports = function(val, options){
options = options || {};
if ('string' == typeof val) return parse(val);
return options.long
? long(val)
: short(val);
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
if (!match) return;
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'y':
return n * y;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 's':
return n * s;
case 'ms':
return n;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function short(ms) {
if (ms >= d) return Math.round(ms / d) + 'd';
if (ms >= h) return Math.round(ms / h) + 'h';
if (ms >= m) return Math.round(ms / m) + 'm';
if (ms >= s) return Math.round(ms / s) + 's';
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function long(ms) {
return plural(ms, d, 'day')
|| plural(ms, h, 'hour')
|| plural(ms, m, 'minute')
|| plural(ms, s, 'second')
|| ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, n, name) {
if (ms < n) return;
if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
return Math.ceil(ms / n) + ' ' + name + 's';
}
{
"name": "ms",
"version": "0.6.2",
"description": "Tiny ms conversion utility",
"repository": {
"type": "git",
"url": "git://github.com/guille/ms.js.git"
},
"main": "./index",
"devDependencies": {
"mocha": "*",
"expect.js": "*",
"serve": "*"
},
"component": {
"scripts": {
"ms/index.js": "index.js"
}
},
"readme": "# ms.js: miliseconds conversion utility\n\n```js\nms('1d') // 86400000\nms('10h') // 36000000\nms('2h') // 7200000\nms('1m') // 60000\nms('5s') // 5000\nms('100') // 100\n```\n\n```js\nms(60000) // \"1m\"\nms(2 * 60000) // \"2m\"\nms(ms('10 hours')) // \"10h\"\n```\n\n```js\nms(60000, { long: true }) // \"1 minute\"\nms(2 * 60000, { long: true }) // \"2 minutes\"\nms(ms('10 hours', { long: true })) // \"10 hours\"\n```\n\n- Node/Browser compatible. Published as `ms` in NPM.\n- If a number is supplied to `ms`, a string with a unit is returned.\n- If a string that contains the number is supplied, it returns it as\na number (e.g: it returns `100` for `'100'`).\n- If you pass a string with a number and a valid unit, the number of\nequivalent ms is returned.\n\n## License\n\nMIT",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/guille/ms.js/issues"
},
"_id": "ms@0.6.2",
"_from": "ms@0.6.2"
}
...@@ -21,5 +21,9 @@ ...@@ -21,5 +21,9 @@
"readme": "# Merge Descriptors [![Build Status](https://travis-ci.org/component/merge-descriptors.png)](https://travis-ci.org/component/merge-descriptors)\n\nMerge objects using descriptors.\n\n```js\nvar thing = {\n get name() {\n return 'jon'\n }\n}\n\nvar animal = {\n\n}\n\nmerge(animal, thing)\n\nanimal.name === 'jon'\n```\n\n## API\n\n### merge(destination, source)\n\nOverwrites `destination`'s descriptors with `source`'s.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.", "readme": "# Merge Descriptors [![Build Status](https://travis-ci.org/component/merge-descriptors.png)](https://travis-ci.org/component/merge-descriptors)\n\nMerge objects using descriptors.\n\n```js\nvar thing = {\n get name() {\n return 'jon'\n }\n}\n\nvar animal = {\n\n}\n\nmerge(animal, thing)\n\nanimal.name === 'jon'\n```\n\n## API\n\n### merge(destination, source)\n\nOverwrites `destination`'s descriptors with `source`'s.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.",
"readmeFilename": "README.md", "readmeFilename": "README.md",
"_id": "merge-descriptors@0.0.2", "_id": "merge-descriptors@0.0.2",
"_from": "merge-descriptors@0.0.2" "dist": {
"shasum": "64fe67a0481be3b6e66d4e03171af8da8e01d444"
},
"_from": "merge-descriptors@0.0.2",
"_resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz"
} }
...@@ -28,5 +28,9 @@ ...@@ -28,5 +28,9 @@
"url": "https://github.com/component/path-to-regexp/issues" "url": "https://github.com/component/path-to-regexp/issues"
}, },
"_id": "path-to-regexp@0.1.2", "_id": "path-to-regexp@0.1.2",
"_from": "path-to-regexp@0.1.2" "dist": {
"shasum": "0baded381925a3a192624b76d23842a90948c281"
},
"_from": "path-to-regexp@0.1.2",
"_resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz"
} }
1.0.1 / 2014-06-03
==================
* Fix links in npm package
1.0.0 / 2014-05-08 1.0.0 / 2014-05-08
================== ==================
......
# proxy-addr [![Build Status](https://travis-ci.org/expressjs/proxy-addr.svg?branch=master)](https://travis-ci.org/expressjs/proxy-addr) [![NPM version](https://badge.fury.io/js/proxy-addr.svg)](http://badge.fury.io/js/proxy-addr) # proxy-addr
[![NPM version](https://badge.fury.io/js/proxy-addr.svg)](http://badge.fury.io/js/proxy-addr)
[![Build Status](https://travis-ci.org/expressjs/proxy-addr.svg?branch=master)](https://travis-ci.org/expressjs/proxy-addr)
[![Coverage Status](https://img.shields.io/coveralls/expressjs/proxy-addr.svg?branch=master)](https://coveralls.io/r/expressjs/proxy-addr)
Determine address of proxied request Determine address of proxied request
## Install ## Install
npm install proxy-addr ```sh
$ npm install proxy-addr
```
## API ## API
var proxyaddr = require('proxy-addr'); ```js
var proxyaddr = require('proxy-addr')
```
### proxyaddr(req, trust) ### proxyaddr(req, trust)
...@@ -18,23 +26,29 @@ The `trust` argument is a function that returns `true` if you trust ...@@ -18,23 +26,29 @@ The `trust` argument is a function that returns `true` if you trust
the address, `false` if you don't. The closest untrusted address is the address, `false` if you don't. The closest untrusted address is
returned. returned.
proxyaddr(req, function(addr){ return addr === '127.0.0.1' }) ```js
proxyaddr(req, function(addr, i){ return i < 1 }) proxyaddr(req, function(addr){ return addr === '127.0.0.1' })
proxyaddr(req, function(addr, i){ return i < 1 })
```
The `trust` arugment may also be a single IP address string or an The `trust` arugment may also be a single IP address string or an
array of trusted addresses, as plain IP addresses, CIDR-formatted array of trusted addresses, as plain IP addresses, CIDR-formatted
strings, or IP/netmask strings. strings, or IP/netmask strings.
proxyaddr(req, '127.0.0.1') ```js
proxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8']) proxyaddr(req, '127.0.0.1')
proxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0']) proxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])
proxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])
```
This module also supports IPv6. Your IPv6 addresses will be normalized This module also supports IPv6. Your IPv6 addresses will be normalized
automatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`). automatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).
proxyaddr(req, '::1') ```js
proxyaddr(req, ['::1/128', 'fe80::/10']) proxyaddr(req, '::1')
proxyaddr(req, ['fe80::/ffc0::']) proxyaddr(req, ['::1/128', 'fe80::/10'])
proxyaddr(req, ['fe80::/ffc0::'])
```
This module will automatically work with IPv4-mapped IPv6 addresses This module will automatically work with IPv4-mapped IPv6 addresses
as well to support node.js in IPv6-only mode. This means that you do as well to support node.js in IPv6-only mode. This means that you do
...@@ -43,8 +57,10 @@ not have to specify both `::ffff:a00:1` and `10.0.0.1`. ...@@ -43,8 +57,10 @@ not have to specify both `::ffff:a00:1` and `10.0.0.1`.
As a convenience, this module also takes certain pre-defined names As a convenience, this module also takes certain pre-defined names
in addition to IP addresses, which expand into IP addresses: in addition to IP addresses, which expand into IP addresses:
proxyaddr(req, 'loopback') ```js
proxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64']) proxyaddr(req, 'loopback')
proxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])
```
* `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and * `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and
`127.0.0.1`). `127.0.0.1`).
...@@ -65,12 +81,16 @@ Return all the addresses of the request, optionally stopping at the ...@@ -65,12 +81,16 @@ Return all the addresses of the request, optionally stopping at the
first untrusted. This array is ordered from closest to furthest first untrusted. This array is ordered from closest to furthest
(i.e. `arr[0] === req.connection.remoteAddress`). (i.e. `arr[0] === req.connection.remoteAddress`).
proxyaddr.all(req) ```js
proxyaddr.all(req)
```
The optional `trust` argument takes the same arguments as `trust` The optional `trust` argument takes the same arguments as `trust`
does in `proxyaddr(req, trust)`. does in `proxyaddr(req, trust)`.
proxyaddr.all(req, 'loopback') ```js
proxyaddr.all(req, 'loopback')
```
### proxyaddr.compile(val) ### proxyaddr.compile(val)
...@@ -78,13 +98,27 @@ Compiles argument `val` into a `trust` function. This function takes ...@@ -78,13 +98,27 @@ Compiles argument `val` into a `trust` function. This function takes
the same arguments as `trust` does in `proxyaddr(req, trust)` and the same arguments as `trust` does in `proxyaddr(req, trust)` and
returns a function suitable for `proxyaddr(req, trust)`. returns a function suitable for `proxyaddr(req, trust)`.
var trust = proxyaddr.compile('localhost') ```js
var addr = proxyaddr(req, trust) var trust = proxyaddr.compile('localhost')
var addr = proxyaddr(req, trust)
```
This function is meant to be optimized for use against every request. This function is meant to be optimized for use against every request.
It is recommend to compile a trust function up-front for the trusted It is recommend to compile a trust function up-front for the trusted
configuration and pass that to `proxyaddr(req, trust)` for each request. configuration and pass that to `proxyaddr(req, trust)` for each request.
## Testing
```sh
$ npm test
```
## Benchmarks
```sh
$ npm run-script bench
```
## License ## License
[MIT](LICENSE) [MIT](LICENSE)
{ {
"name": "proxy-addr", "name": "proxy-addr",
"description": "Determine address of proxied request", "description": "Determine address of proxied request",
"version": "1.0.0", "version": "1.0.1",
"author": { "author": {
"name": "Douglas Christopher Wilson", "name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com" "email": "doug@somethingdoug.com"
...@@ -14,26 +14,32 @@ ...@@ -14,26 +14,32 @@
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/expressjs/proxy-ip.git" "url": "https://github.com/expressjs/proxy-addr.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/expressjs/proxy-ip/issues" "url": "https://github.com/expressjs/proxy-addr/issues"
}, },
"dependencies": { "dependencies": {
"ipaddr.js": "0.1.2" "ipaddr.js": "0.1.2"
}, },
"devDependencies": { "devDependencies": {
"mocha": "~1.18.2", "benchmark": "1.0.0",
"should": "~3.3.1" "beautify-benchmark": "0.2.4",
"istanbul": "0.2.10",
"mocha": "~1.20.0",
"should": "~4.0.0"
}, },
"engines": { "engines": {
"node": ">= 0.8.0" "node": ">= 0.8.0"
}, },
"scripts": { "scripts": {
"test": "mocha --reporter spec test/" "bench": "node benchmark/index.js",
"test": "mocha --reporter dot test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/"
}, },
"readme": "# proxy-addr [![Build Status](https://travis-ci.org/expressjs/proxy-addr.svg?branch=master)](https://travis-ci.org/expressjs/proxy-addr) [![NPM version](https://badge.fury.io/js/proxy-addr.svg)](http://badge.fury.io/js/proxy-addr)\n\nDetermine address of proxied request\n\n## Install\n\n npm install proxy-addr\n\n## API\n\n var proxyaddr = require('proxy-addr');\n\n### proxyaddr(req, trust)\n\nReturn the address of the request, using the given `trust` parameter.\n\nThe `trust` argument is a function that returns `true` if you trust\nthe address, `false` if you don't. The closest untrusted address is\nreturned.\n\n proxyaddr(req, function(addr){ return addr === '127.0.0.1' })\n proxyaddr(req, function(addr, i){ return i < 1 })\n\nThe `trust` arugment may also be a single IP address string or an\narray of trusted addresses, as plain IP addresses, CIDR-formatted\nstrings, or IP/netmask strings.\n\n proxyaddr(req, '127.0.0.1')\n proxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])\n proxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])\n\nThis module also supports IPv6. Your IPv6 addresses will be normalized\nautomatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).\n\n proxyaddr(req, '::1')\n proxyaddr(req, ['::1/128', 'fe80::/10'])\n proxyaddr(req, ['fe80::/ffc0::'])\n\nThis module will automatically work with IPv4-mapped IPv6 addresses\nas well to support node.js in IPv6-only mode. This means that you do\nnot have to specify both `::ffff:a00:1` and `10.0.0.1`.\n\nAs a convenience, this module also takes certain pre-defined names\nin addition to IP addresses, which expand into IP addresses:\n\n proxyaddr(req, 'loopback')\n proxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])\n\n * `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and\r\n `127.0.0.1`).\n * `linklocal`: IPv4 and IPv6 link-local addresses (like\r\n `fe80::1:1:1:1` and `169.254.0.1`).\n * `uniquelocal`: IPv4 private addresses and IPv6 unique-local\r\n addresses (like `fc00:ac:1ab5:fff::1` and `192.168.0.1`).\n\nWhen `trust` is specified as a function, it will be called for each\naddress to determine if it is a trusted address. The function is\ngiven two arguments: `addr` and `i`, where `addr` is a string of\nthe address to check and `i` is a number that represents the distance\nfrom the socket address.\n\n### proxyaddr.all(req, [trust])\n\nReturn all the addresses of the request, optionally stopping at the\nfirst untrusted. This array is ordered from closest to furthest\n(i.e. `arr[0] === req.connection.remoteAddress`).\n\n proxyaddr.all(req)\n\nThe optional `trust` argument takes the same arguments as `trust`\ndoes in `proxyaddr(req, trust)`.\n\n proxyaddr.all(req, 'loopback')\n\n### proxyaddr.compile(val)\n\nCompiles argument `val` into a `trust` function. This function takes\nthe same arguments as `trust` does in `proxyaddr(req, trust)` and\nreturns a function suitable for `proxyaddr(req, trust)`.\n\n var trust = proxyaddr.compile('localhost')\n var addr = proxyaddr(req, trust)\n\nThis function is meant to be optimized for use against every request.\nIt is recommend to compile a trust function up-front for the trusted\nconfiguration and pass that to `proxyaddr(req, trust)` for each request.\n\n## License\n\n[MIT](LICENSE)\n", "readme": "# proxy-addr\n\n[![NPM version](https://badge.fury.io/js/proxy-addr.svg)](http://badge.fury.io/js/proxy-addr)\n[![Build Status](https://travis-ci.org/expressjs/proxy-addr.svg?branch=master)](https://travis-ci.org/expressjs/proxy-addr)\n[![Coverage Status](https://img.shields.io/coveralls/expressjs/proxy-addr.svg?branch=master)](https://coveralls.io/r/expressjs/proxy-addr)\n\nDetermine address of proxied request\n\n## Install\n\n```sh\n$ npm install proxy-addr\n```\n\n## API\n\n```js\nvar proxyaddr = require('proxy-addr')\n```\n\n### proxyaddr(req, trust)\n\nReturn the address of the request, using the given `trust` parameter.\n\nThe `trust` argument is a function that returns `true` if you trust\nthe address, `false` if you don't. The closest untrusted address is\nreturned.\n\n```js\nproxyaddr(req, function(addr){ return addr === '127.0.0.1' })\nproxyaddr(req, function(addr, i){ return i < 1 })\n```\n\nThe `trust` arugment may also be a single IP address string or an\narray of trusted addresses, as plain IP addresses, CIDR-formatted\nstrings, or IP/netmask strings.\n\n```js\nproxyaddr(req, '127.0.0.1')\nproxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])\nproxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])\n```\n\nThis module also supports IPv6. Your IPv6 addresses will be normalized\nautomatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).\n\n```js\nproxyaddr(req, '::1')\nproxyaddr(req, ['::1/128', 'fe80::/10'])\nproxyaddr(req, ['fe80::/ffc0::'])\n```\n\nThis module will automatically work with IPv4-mapped IPv6 addresses\nas well to support node.js in IPv6-only mode. This means that you do\nnot have to specify both `::ffff:a00:1` and `10.0.0.1`.\n\nAs a convenience, this module also takes certain pre-defined names\nin addition to IP addresses, which expand into IP addresses:\n\n```js\nproxyaddr(req, 'loopback')\nproxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])\n```\n\n * `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and\n `127.0.0.1`).\n * `linklocal`: IPv4 and IPv6 link-local addresses (like\n `fe80::1:1:1:1` and `169.254.0.1`).\n * `uniquelocal`: IPv4 private addresses and IPv6 unique-local\n addresses (like `fc00:ac:1ab5:fff::1` and `192.168.0.1`).\n\nWhen `trust` is specified as a function, it will be called for each\naddress to determine if it is a trusted address. The function is\ngiven two arguments: `addr` and `i`, where `addr` is a string of\nthe address to check and `i` is a number that represents the distance\nfrom the socket address.\n\n### proxyaddr.all(req, [trust])\n\nReturn all the addresses of the request, optionally stopping at the\nfirst untrusted. This array is ordered from closest to furthest\n(i.e. `arr[0] === req.connection.remoteAddress`).\n\n```js\nproxyaddr.all(req)\n```\n\nThe optional `trust` argument takes the same arguments as `trust`\ndoes in `proxyaddr(req, trust)`.\n\n```js\nproxyaddr.all(req, 'loopback')\n```\n\n### proxyaddr.compile(val)\n\nCompiles argument `val` into a `trust` function. This function takes\nthe same arguments as `trust` does in `proxyaddr(req, trust)` and\nreturns a function suitable for `proxyaddr(req, trust)`.\n\n```js\nvar trust = proxyaddr.compile('localhost')\nvar addr = proxyaddr(req, trust)\n```\n\nThis function is meant to be optimized for use against every request.\nIt is recommend to compile a trust function up-front for the trusted\nconfiguration and pass that to `proxyaddr(req, trust)` for each request.\n\n## Testing\n\n```sh\n$ npm test\n```\n\n## Benchmarks\n\n```sh\n$ npm run-script bench\n```\n\n## License\n\n[MIT](LICENSE)\n",
"readmeFilename": "README.md", "readmeFilename": "README.md",
"_id": "proxy-addr@1.0.0", "_id": "proxy-addr@1.0.1",
"_from": "proxy-addr@1.0.0" "_from": "proxy-addr@1.0.1"
} }
0.4.3 / 2014-06-11
==================
* Do not throw un-catchable error on file open race condition
* Use `escape-html` for HTML escaping
* deps: debug@1.0.2
- fix some debugging output colors on node.js 0.8
* deps: finished@1.2.2
* deps: fresh@0.2.2
0.4.2 / 2014-06-09
==================
* fix "event emitter leak" warnings
* deps: debug@1.0.1
* deps: finished@1.2.1
0.4.1 / 2014-06-02 0.4.1 / 2014-06-02
================== ==================
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
var debug = require('debug')('send') var debug = require('debug')('send')
var escapeHtml = require('escape-html')
, parseRange = require('range-parser') , parseRange = require('range-parser')
, Stream = require('stream') , Stream = require('stream')
, mime = require('mime') , mime = require('mime')
...@@ -121,7 +122,7 @@ SendStream.prototype.hidden = function(val){ ...@@ -121,7 +122,7 @@ SendStream.prototype.hidden = function(val){
SendStream.prototype.index = function index(paths){ SendStream.prototype.index = function index(paths){
var index = !paths ? [] : Array.isArray(paths) ? paths : [paths]; var index = !paths ? [] : Array.isArray(paths) ? paths : [paths];
debug('index %j', index); debug('index %o', paths);
this._index = index; this._index = index;
return this; return this;
}; };
...@@ -168,9 +169,18 @@ SendStream.prototype.maxage = function(ms){ ...@@ -168,9 +169,18 @@ SendStream.prototype.maxage = function(ms){
SendStream.prototype.error = function(status, err){ SendStream.prototype.error = function(status, err){
var res = this.res; var res = this.res;
var msg = http.STATUS_CODES[status]; var msg = http.STATUS_CODES[status];
err = err || new Error(msg); err = err || new Error(msg);
err.status = status; err.status = status;
if (this.listeners('error').length) return this.emit('error', err);
// emit if listeners instead of responding
if (this.listeners('error').length) {
return this.emit('error', err);
}
// wipe all existing headers
res._headers = undefined;
res.statusCode = err.status; res.statusCode = err.status;
res.end(msg); res.end(msg);
}; };
...@@ -329,7 +339,7 @@ SendStream.prototype.redirect = function(path){ ...@@ -329,7 +339,7 @@ SendStream.prototype.redirect = function(path){
path += '/'; path += '/';
res.statusCode = 301; res.statusCode = 301;
res.setHeader('Location', path); res.setHeader('Location', path);
res.end('Redirecting to ' + utils.escape(path)); res.end('Redirecting to ' + escapeHtml(path));
}; };
/** /**
...@@ -522,8 +532,8 @@ SendStream.prototype.stream = function(path, options){ ...@@ -522,8 +532,8 @@ SendStream.prototype.stream = function(path, options){
this.emit('stream', stream); this.emit('stream', stream);
stream.pipe(res); stream.pipe(res);
// request finished, done with the fd // response finished, done with the fd
onFinished(req, function onfinished(){ onFinished(res, function onfinished(){
finished = true; finished = true;
stream.destroy(); stream.destroy();
}); });
...@@ -533,6 +543,10 @@ SendStream.prototype.stream = function(path, options){ ...@@ -533,6 +543,10 @@ SendStream.prototype.stream = function(path, options){
// request already finished // request already finished
if (finished) return; if (finished) return;
// clean up stream
finished = true;
stream.destroy();
// no hope in responding // no hope in responding
if (res._header) { if (res._header) {
console.error(err.stack); console.error(err.stack);
...@@ -540,9 +554,8 @@ SendStream.prototype.stream = function(path, options){ ...@@ -540,9 +554,8 @@ SendStream.prototype.stream = function(path, options){
return; return;
} }
// 500 // error
err.status = 500; self.onStatError(err);
self.emit('error', err);
}); });
// end // end
......
...@@ -16,7 +16,11 @@ var crypto = require('crypto'); ...@@ -16,7 +16,11 @@ var crypto = require('crypto');
exports.etag = function etag(path, stat) { exports.etag = function etag(path, stat) {
var tag = String(stat.mtime.getTime()) + ':' + String(stat.size) + ':' + path; var tag = String(stat.mtime.getTime()) + ':' + String(stat.size) + ':' + path;
return 'W/"' + exports.md5(tag, 'base64') + '"'; var str = crypto
.createHash('md5')
.update(tag, 'utf8')
.digest('base64');
return 'W/"' + str + '"';
}; };
/** /**
...@@ -36,39 +40,3 @@ exports.decode = function(path){ ...@@ -36,39 +40,3 @@ exports.decode = function(path){
return -1; 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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
/**
* Return md5 hash of the given string and optional encoding,
* defaulting to hex.
*
* utils.md5('wahoo');
* // => "e493298061761236c96b02ea6aa8a2ad"
*
* @param {String} str
* @param {String} encoding
* @return {String}
* @api private
*/
exports.md5 = function(str, encoding){
return crypto
.createHash('md5')
.update(str, 'utf8')
.digest(encoding || 'hex');
};
1.2.2 / 2014-06-10
==========
* reduce listeners added to emitters
- avoids "event emitter leak" warnings when used multiple times on same request
1.2.1 / 2014-06-08
==================
* fix returned value when already finished
1.2.0 / 2014-06-05
==================
* call callback when called on already-finished socket
1.1.4 / 2014-05-27
==================
* support node.js 0.8
1.1.3 / 2014-04-30
==================
* make sure errors passed as instanceof `Error`
1.1.2 / 2014-04-18
==================
* default the `socket` to passed-in object
1.1.1 / 2014-01-16
==================
* rename module to `finished`
1.1.0 / 2013-12-25
==================
* call callback when called on already-errored socket
1.0.1 / 2013-12-20
==================
* actually pass the error to the callback
1.0.0 / 2013-12-20
==================
* Initial release
# finished [![Build Status](https://travis-ci.org/expressjs/finished.svg?branch=master)](https://travis-ci.org/expressjs/finished) [![NPM Version](https://badge.fury.io/js/finished.svg)](http://badge.fury.io/js/finished) # finished
[![NPM Version](https://badge.fury.io/js/finished.svg)](http://badge.fury.io/js/finished)
[![Build Status](https://travis-ci.org/expressjs/finished.svg?branch=master)](https://travis-ci.org/expressjs/finished)
[![Coverage Status](https://img.shields.io/coveralls/expressjs/finished.svg?branch=master)](https://coveralls.io/r/expressjs/finished)
Execute a callback when a request closes, finishes, or errors. Execute a callback when a request closes, finishes, or errors.
#### Install #### Install
`npm install finished` ```sh
$ npm install finished
```
#### Uses #### Uses
......
/*!
* finished
* Copyright(c) 2014 Jonathan Ong
* MIT Licensed
*/
/**
* Module dependencies.
*/
var first = require('ee-first')
/**
* Variables.
*/
/* istanbul ignore next */
var defer = typeof setImmediate === 'function' var defer = typeof setImmediate === 'function'
? setImmediate ? setImmediate
: process.nextTick : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
module.exports = function (thingie, callback) { /**
* Invoke callback when the response has finished, useful for
* cleaning up resources afterwards.
*
* @param {object} thingie
* @param {function} callback
* @return {object}
* @api public
*/
module.exports = function finished(thingie, callback) {
var socket = thingie.socket || thingie var socket = thingie.socket || thingie
var res = thingie.res || thingie var res = thingie.res || thingie
if (!socket.writable)
return defer(callback) if (res.finished || !socket.writable) {
defer(callback)
socket.on('error', done) return thingie
socket.on('close', done)
res.on('finish', done)
function done(err) {
if (err != null && !(err instanceof Error)) err = null; // suck it node
socket.removeListener('error', done)
socket.removeListener('close', done)
res.removeListener('finish', done)
callback(err)
} }
var listener = res.__onFinished
// create a private single listener with queue
if (!listener || !listener.queue) {
listener = res.__onFinished = function onFinished(err) {
if (res.__onFinished === listener) res.__onFinished = null
var queue = listener.queue || []
while (queue.length) queue.shift()(err)
}
listener.queue = []
// finished on first event
first([
[socket, 'error', 'close'],
[res, 'finish'],
], listener)
}
listener.queue.push(callback)
return thingie return thingie
} }
Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
The MIT License (MIT)
Copyright (c) 2014 Jonathan Ong me@jongleberry.com
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
# EE First
Get the first event in a set of event emitters and event pairs,
then clean up after itself.
module.exports = function first(stuff, done) {
if (!Array.isArray(stuff))
throw new TypeError('arg must be an array of [ee, events...] arrays')
var cleanups = []
for (var i = 0; i < stuff.length; i++) {
var arr = stuff[i]
if (!Array.isArray(arr) || arr.length < 2)
throw new TypeError('each array member must be [ee, events...]')
var ee = arr[0]
for (var j = 1; j < arr.length; j++) {
var event = arr[j]
var fn = listener(event, cleanup)
// listen to the event
ee.on(event, fn)
// push this listener to the list of cleanups
cleanups.push({
ee: ee,
event: event,
fn: fn,
})
}
}
return function (fn) {
done = fn
}
function cleanup() {
var x
for (var i = 0; i < cleanups.length; i++) {
x = cleanups[i]
x.ee.removeListener(x.event, x.fn)
}
done.apply(null, arguments)
}
}
function listener(event, done) {
return function onevent(arg1) {
var args = new Array(arguments.length)
var ee = this
var err = event === 'error'
? arg1
: null
// copy args to prevent arguments escaping scope
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i]
}
done(err, ee, event, args)
}
}
{
"name": "ee-first",
"description": "return the first event in a set of ee/event pairs",
"version": "1.0.3",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/jonathanong/ee-first"
},
"devDependencies": {
"mocha": "1"
},
"scripts": {
"test": "mocha --reporter spec"
},
"readme": "\n# EE First\n\nGet the first event in a set of event emitters and event pairs,\nthen clean up after itself.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/jonathanong/ee-first/issues"
},
"_id": "ee-first@1.0.3",
"dist": {
"shasum": "5d45ac0e0d3155b15f7e13d19cc17f6c77208395"
},
"_from": "ee-first@1.0.3",
"_resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.0.3.tgz"
}
var EventEmitter = require('events').EventEmitter
var assert = require('assert')
var first = require('./')
describe('first', function () {
var ee1 = new EventEmitter()
var ee2 = new EventEmitter()
var ee3 = new EventEmitter()
it('should emit the first event', function (done) {
first([
[ee1, 'a', 'b', 'c'],
[ee2, 'a', 'b', 'c'],
[ee3, 'a', 'b', 'c'],
], function (err, ee, event, args) {
assert.ifError(err)
assert.equal(ee, ee2)
assert.equal(event, 'b')
assert.deepEqual(args, [1, 2, 3])
done()
})
ee2.emit('b', 1, 2, 3)
})
it('it should return an error if event === error', function (done) {
first([
[ee1, 'error', 'b', 'c'],
[ee2, 'error', 'b', 'c'],
[ee3, 'error', 'b', 'c'],
], function (err, ee, event, args) {
assert.equal(err.message, 'boom')
assert.equal(ee, ee3)
assert.equal(event, 'error')
done()
})
ee3.emit('error', new Error('boom'))
})
it('should cleanup after itself', function (done) {
first([
[ee1, 'a', 'b', 'c'],
[ee2, 'a', 'b', 'c'],
[ee3, 'a', 'b', 'c'],
], function (err, ee, event, args) {
assert.ifError(err)
;[ee1, ee2, ee3].forEach(function (ee) {
['a', 'b', 'c'].forEach(function (event) {
assert(!ee.listeners(event).length)
})
})
done()
})
ee1.emit('a')
})
})
{ {
"name": "finished", "name": "finished",
"description": "Execute a callback when a request closes, finishes, or errors", "description": "Execute a callback when a request closes, finishes, or errors",
"version": "1.1.4", "version": "1.2.2",
"author": { "author": {
"name": "Jonathan Ong", "name": "Jonathan Ong",
"email": "me@jongleberry.com", "email": "me@jongleberry.com",
...@@ -10,23 +10,33 @@ ...@@ -10,23 +10,33 @@
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/expressjs/finished.git" "url": "git://github.com/expressjs/finished"
}, },
"bugs": { "dependencies": {
"url": "https://github.com/expressjs/finished/issues" "ee-first": "1.0.3"
}, },
"devDependencies": { "devDependencies": {
"mocha": "*", "istanbul": "0.2.10",
"should": "*" "mocha": "~1.20.1",
"should": "~4.0.1"
}, },
"engine": { "engine": {
"node": ">= 0.8.0" "node": ">= 0.8.0"
}, },
"scripts": { "scripts": {
"test": "mocha --require should --reporter spec" "test": "mocha --reporter spec test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/"
}, },
"readme": "# finished [![Build Status](https://travis-ci.org/expressjs/finished.svg?branch=master)](https://travis-ci.org/expressjs/finished) [![NPM Version](https://badge.fury.io/js/finished.svg)](http://badge.fury.io/js/finished)\n\nExecute a callback when a request closes, finishes, or errors.\n\n#### Install\n\n`npm install finished`\n\n#### Uses\n\nThis is useful for cleaning up streams. For example, you want to destroy any file streams you create on socket errors otherwise you will leak file descriptors.\n\nThis is required to fix what many perceive as issues with node's streams. Relevant:\n\n- [node#6041](https://github.com/joyent/node/issues/6041)\n- [koa#184](https://github.com/koajs/koa/issues/184)\n- [koa#165](https://github.com/koajs/koa/issues/165)\n\n## API\n\n### finished(response, callback)\n\n```js\nvar onFinished = require('finished')\n\nonFinished(res, function (err) {\n // do something maybe\n})\n```\n\n### Examples\n\nThe following code ensures that file descriptors are always closed once the response finishes.\n\n#### Node / Connect / Express\n\n```js\nvar onFinished = require('finished')\n\nfunction (req, res, next) {\n var stream = fs.createReadStream('thingie.json')\n stream.pipe(res)\n onFinished(res, function (err) {\n stream.destroy()\n })\n}\n```\n\n#### Koa\n\n```js\nfunction* () {\n var stream = this.body = fs.createReadStream('thingie.json')\n onFinished(this, function (err) {\n stream.destroy()\n })\n}\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", "readme": "# finished\n\n[![NPM Version](https://badge.fury.io/js/finished.svg)](http://badge.fury.io/js/finished)\n[![Build Status](https://travis-ci.org/expressjs/finished.svg?branch=master)](https://travis-ci.org/expressjs/finished)\n[![Coverage Status](https://img.shields.io/coveralls/expressjs/finished.svg?branch=master)](https://coveralls.io/r/expressjs/finished)\n\nExecute a callback when a request closes, finishes, or errors.\n\n#### Install\n\n```sh\n$ npm install finished\n```\n\n#### Uses\n\nThis is useful for cleaning up streams. For example, you want to destroy any file streams you create on socket errors otherwise you will leak file descriptors.\n\nThis is required to fix what many perceive as issues with node's streams. Relevant:\n\n- [node#6041](https://github.com/joyent/node/issues/6041)\n- [koa#184](https://github.com/koajs/koa/issues/184)\n- [koa#165](https://github.com/koajs/koa/issues/165)\n\n## API\n\n### finished(response, callback)\n\n```js\nvar onFinished = require('finished')\n\nonFinished(res, function (err) {\n // do something maybe\n})\n```\n\n### Examples\n\nThe following code ensures that file descriptors are always closed once the response finishes.\n\n#### Node / Connect / Express\n\n```js\nvar onFinished = require('finished')\n\nfunction (req, res, next) {\n var stream = fs.createReadStream('thingie.json')\n stream.pipe(res)\n onFinished(res, function (err) {\n stream.destroy()\n })\n}\n```\n\n#### Koa\n\n```js\nfunction* () {\n var stream = this.body = fs.createReadStream('thingie.json')\n onFinished(this, function (err) {\n stream.destroy()\n })\n}\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
"readmeFilename": "README.md", "readmeFilename": "README.md",
"_id": "finished@1.1.4", "bugs": {
"_from": "finished@1.1.4" "url": "https://github.com/expressjs/finished/issues"
},
"_id": "finished@1.2.2",
"dist": {
"shasum": "550a69be2fc271c1fd0afa2c700797ea3f7c7ea3"
},
"_from": "finished@1.2.2",
"_resolved": "https://registry.npmjs.org/finished/-/finished-1.2.2.tgz"
} }
...@@ -31,5 +31,9 @@ ...@@ -31,5 +31,9 @@
"url": "https://github.com/broofa/node-mime/issues" "url": "https://github.com/broofa/node-mime/issues"
}, },
"_id": "mime@1.2.11", "_id": "mime@1.2.11",
"_from": "mime@~1.2.11" "dist": {
"shasum": "2e68433cd8b933cc360926e916e08e705e3bf1ae"
},
"_from": "mime@~1.2.11",
"_resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
} }
{ {
"name": "send", "name": "send",
"description": "Better streaming static file server with Range and conditional-GET support", "description": "Better streaming static file server with Range and conditional-GET support",
"version": "0.4.1", "version": "0.4.3",
"author": { "author": {
"name": "TJ Holowaychuk", "name": "TJ Holowaychuk",
"email": "tj@vision-media.ca" "email": "tj@vision-media.ca"
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
"server" "server"
], ],
"dependencies": { "dependencies": {
"debug": "0.8.1", "debug": "1.0.2",
"finished": "1.1.4", "escape-html": "1.0.1",
"fresh": "~0.2.1", "finished": "1.2.2",
"fresh": "0.2.2",
"mime": "1.2.11", "mime": "1.2.11",
"range-parser": "~1.0.0" "range-parser": "~1.0.0"
}, },
...@@ -48,6 +49,10 @@ ...@@ -48,6 +49,10 @@
"bugs": { "bugs": {
"url": "https://github.com/visionmedia/send/issues" "url": "https://github.com/visionmedia/send/issues"
}, },
"_id": "send@0.4.1", "_id": "send@0.4.3",
"_from": "send@0.4.1" "dist": {
"shasum": "20a847abeb294cfa679c9d6a43a03d931037661b"
},
"_from": "send@0.4.3",
"_resolved": "https://registry.npmjs.org/send/-/send-0.4.3.tgz"
} }
1.2.3 / 2014-06-11
==================
* deps: send@0.4.3
- Do not throw un-catchable error on file open race condition
- Use `escape-html` for HTML escaping
- deps: debug@1.0.2
- deps: finished@1.2.2
- deps: fresh@0.2.2
1.2.2 / 2014-06-09
==================
* deps: send@0.4.2
- fix "event emitter leak" warnings
- deps: debug@1.0.1
- deps: finished@1.2.1
1.2.1 / 2014-06-02
==================
* use `escape-html` for escaping
* deps: send@0.4.1
- Send `max-age` in `Cache-Control` in correct format
1.2.0 / 2014-05-29
==================
* deps: send@0.4.0
- Calculate ETag with md5 for reduced collisions
- Fix wrong behavior when index file matches directory
- Ignore stream errors after request ends
- Skip directories in index file search
- deps: debug@0.8.1
1.1.0 / 2014-04-24
==================
* Accept options directly to `send` module
* deps: send@0.3.0
1.0.4 / 2014-04-07
==================
* Resolve relative paths at middleware setup
* Use parseurl to parse the URL from request
1.0.3 / 2014-03-20
==================
* Do not rely on connect-like environments
1.0.2 / 2014-03-06
==================
* deps: send@0.2.0
1.0.1 / 2014-03-05
==================
* Add mime export for back-compat
1.0.0 / 2014-03-05
==================
* Genesis from `connect`
(The MIT License)
Copyright (c) 2010 Sencha Inc.
Copyright (c) 2011 LearnBoost
Copyright (c) 2011 TJ Holowaychuk
Copyright (c) 2014 Douglas Christopher Wilson
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.
# serve-static
[![NPM version](https://badge.fury.io/js/serve-static.svg)](http://badge.fury.io/js/serve-static)
[![Build Status](https://travis-ci.org/expressjs/serve-static.svg?branch=master)](https://travis-ci.org/expressjs/serve-static)
[![Coverage Status](https://img.shields.io/coveralls/expressjs/serve-static.svg?branch=master)](https://coveralls.io/r/expressjs/serve-static)
Previously `connect.static()`.
## Install
```sh
$ npm install serve-static
```
## API
```js
var serveStatic = require('serve-static')
```
### serveStatic(root, options)
Create a new middleware function to serve files from within a given root
directory. The file to serve will be determined by combining `req.url`
with the provided root directory.
Options:
- `hidden` Allow transfer of hidden files. defaults to `false`
- `index` Default file name, defaults to `'index.html'`
- `maxAge` Browser cache maxAge in milliseconds. defaults to `0`
- `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to `true`
## Examples
### Serve files with vanilla node.js http server
```js
var finalhandler = require('finalhandler')
var http = require('http')
var serveStatic = require('serve-static')
// Serve up public/ftp folder
var serve = serveStatic('public/ftp', {'index': ['index.html', 'index.htm']})
// Create server
var server = http.createServer(function(req, res){
var done = finalhandler(req, res)
serve(req, res, done)
})
// Listen
server.listen(3000)
```
### Serve all files from ftp folder
```js
var connect = require('connect')
var serveStatic = require('serve-static')
var app = connect()
app.use(serveStatic('public/ftp', {'index': ['default.html', 'default.htm']}))
app.listen(3000)
```
## License
The MIT License (MIT)
Copyright (c) 2014 Douglas Christopher Wilson
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.
/*!
* serve-static
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module dependencies.
*/
var escapeHtml = require('escape-html');
var parseurl = require('parseurl');
var resolve = require('path').resolve;
var send = require('send');
var url = require('url');
/**
* Static:
*
* Static file server with the given `root` path.
*
* Examples:
*
* var oneDay = 86400000;
* var serveStatic = require('serve-static');
*
* connect()
* .use(serveStatic(__dirname + '/public'))
*
* connect()
* .use(serveStatic(__dirname + '/public', { maxAge: oneDay }))
*
* Options:
*
* - `maxAge` Browser cache maxAge in milliseconds. defaults to 0
* - `hidden` Allow transfer of hidden files. defaults to false
* - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true
* - `index` Default file name, defaults to 'index.html'
*
* Further options are forwarded on to `send`.
*
* @param {String} root
* @param {Object} options
* @return {Function}
* @api public
*/
exports = module.exports = function(root, options){
options = extend({}, options);
// root required
if (!root) throw new TypeError('root path required');
// resolve root to absolute
root = resolve(root);
// default redirect
var redirect = false !== options.redirect;
// setup options for send
options.maxage = options.maxage || options.maxAge || 0;
options.root = root;
return function staticMiddleware(req, res, next) {
if ('GET' != req.method && 'HEAD' != req.method) return next();
var opts = extend({}, options);
var originalUrl = url.parse(req.originalUrl || req.url);
var path = parseurl(req).pathname;
if (path == '/' && originalUrl.pathname[originalUrl.pathname.length - 1] != '/') {
return directory();
}
function directory() {
if (!redirect) return next();
var target;
originalUrl.pathname += '/';
target = url.format(originalUrl);
res.statusCode = 303;
res.setHeader('Location', target);
res.end('Redirecting to ' + escapeHtml(target));
}
function error(err) {
if (404 == err.status) return next();
next(err);
}
send(req, path, opts)
.on('error', error)
.on('directory', directory)
.pipe(res);
};
};
/**
* Expose mime module.
*
* If you wish to extend the mime table use this
* reference to the "mime" module in the npm registry.
*/
exports.mime = send.mime;
/**
* Shallow clone a single object.
*
* @param {Object} obj
* @param {Object} source
* @return {Object}
* @api private
*/
function extend(obj, source) {
if (!source) return obj;
for (var prop in source) {
obj[prop] = source[prop];
}
return obj;
};
{
"name": "serve-static",
"description": "Serve static files",
"version": "1.2.3",
"author": {
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/expressjs/serve-static"
},
"dependencies": {
"escape-html": "1.0.1",
"parseurl": "1.0.1",
"send": "0.4.3"
},
"devDependencies": {
"istanbul": "0.2.10",
"mocha": "~1.20.0",
"should": "~4.0.0",
"supertest": "~0.13.0"
},
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"test": "mocha --reporter dot --require should test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --require should test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --require should test/"
},
"readme": "# serve-static\n\n[![NPM version](https://badge.fury.io/js/serve-static.svg)](http://badge.fury.io/js/serve-static)\n[![Build Status](https://travis-ci.org/expressjs/serve-static.svg?branch=master)](https://travis-ci.org/expressjs/serve-static)\n[![Coverage Status](https://img.shields.io/coveralls/expressjs/serve-static.svg?branch=master)](https://coveralls.io/r/expressjs/serve-static)\n\nPreviously `connect.static()`.\n\n## Install\n\n```sh\n$ npm install serve-static\n```\n\n## API\n\n```js\nvar serveStatic = require('serve-static')\n```\n\n### serveStatic(root, options)\n\nCreate a new middleware function to serve files from within a given root\ndirectory. The file to serve will be determined by combining `req.url`\nwith the provided root directory.\n\nOptions:\n\n- `hidden` Allow transfer of hidden files. defaults to `false`\n- `index` Default file name, defaults to `'index.html'`\n- `maxAge` Browser cache maxAge in milliseconds. defaults to `0`\n- `redirect` Redirect to trailing \"/\" when the pathname is a dir. defaults to `true`\n\n## Examples\n\n### Serve files with vanilla node.js http server\n\n```js\nvar finalhandler = require('finalhandler')\nvar http = require('http')\nvar serveStatic = require('serve-static')\n\n// Serve up public/ftp folder\nvar serve = serveStatic('public/ftp', {'index': ['index.html', 'index.htm']})\n\n// Create server\nvar server = http.createServer(function(req, res){\n var done = finalhandler(req, res)\n serve(req, res, done)\n})\n\n// Listen\nserver.listen(3000)\n```\n\n### Serve all files from ftp folder\n\n```js\nvar connect = require('connect')\nvar serveStatic = require('serve-static')\n\nvar app = connect()\n\napp.use(serveStatic('public/ftp', {'index': ['default.html', 'default.htm']}))\napp.listen(3000)\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Douglas Christopher Wilson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
"readmeFilename": "Readme.md",
"bugs": {
"url": "https://github.com/expressjs/serve-static/issues"
},
"_id": "serve-static@1.2.3",
"dist": {
"shasum": "0d8f17dfa35aff543e12cb9ee964da30e415ede9"
},
"_from": "serve-static@1.2.3",
"_resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.2.3.tgz"
}
1.2.1 / 2014-06-03
==================
* Switch dependency from `mime` to `mime-types@1.0.0`
1.2.0 / 2014-05-11 1.2.0 / 2014-05-11
================== ==================
......
# type-is [![Build Status](https://travis-ci.org/expressjs/type-is.svg?branch=master)](https://travis-ci.org/expressjs/type-is) [![NPM version](https://badge.fury.io/js/type-is.svg)](https://badge.fury.io/js/type-is) # type-is [![Build Status](https://travis-ci.org/expressjs/type-is.svg?branch=master)](https://travis-ci.org/expressjs/type-is) [![NPM version](https://badge.fury.io/js/type-is.svg)](https://badge.fury.io/js/type-is)
Infer the content type of a request. Infer the content-type of a request.
Extracted from [koa](https://github.com/koajs/koa) for general use.
Here's an example body parser: ### Install
```sh
$ npm install type-is
```
## API
```js
var http = require('http')
var is = require('type-is')
http.createServer(function (req, res) {
is(req, ['text/*'])
})
```
### type = is(request, types)
`request` is the node HTTP request. `types` is an array of types.
```js
// req.headers.content-type = 'application/json'
is(req, ['json']) // 'json'
is(req, ['html', 'json']) // 'json'
is(req, ['application/*']) // 'application/json'
is(req, ['application/json']) // 'application/json'
is(req, ['html']) // false
```
#### Each type can be:
- An extension name such as `json`. This name will be returned if matched.
- A mime type such as `application/json`.
- A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched
- A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched.
`false` will be returned if no type matches.
## Examples
#### Example body parser
```js ```js
var is = require('type-is'); var is = require('type-is');
...@@ -31,38 +73,6 @@ function bodyParser(req, res, next) { ...@@ -31,38 +73,6 @@ function bodyParser(req, res, next) {
} }
``` ```
## API
### var type = is(request, types)
```js
var is = require('type-is')
http.createServer(function (req, res) {
is(req, ['text/*'])
})
```
`request` is the node HTTP request. `types` is an array of types. Each type can be:
- An extension name such as `json`. This name will be returned if matched.
- A mime type such as `application/json`.
- A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched
- A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched.
`false` will be returned if no type matches.
Examples:
```js
// req.headers.content-type = 'application/json'
is(req, ['json']) // -> 'json'
is(req, ['html', 'json']) // -> 'json'
is(req, ['application/*']) // -> 'application/json'
is(req, ['application/json']) // -> 'application/json'
is(req, ['html']) // -> false
```
## License ## License
The MIT License (MIT) The MIT License (MIT)
......
var mime = require('mime'); var mime = require('mime-types');
var slice = [].slice; var slice = [].slice;
......
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store*
# Icon?
ehthumbs.db
Thumbs.db
# Node.js #
###########
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
node_modules
npm-debug.log
The MIT License (MIT)
Copyright (c) 2014 Jonathan Ong me@jongleberry.com
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.
build:
node --harmony-generators build.js
test:
node test/mime.js
mocha --require should --reporter spec test/test.js
.PHONY: build test
# mime-types [![Build Status](https://travis-ci.org/expressjs/mime-types.svg?branch=master)](https://travis-ci.org/expressjs/mime-types) [![NPM version](https://badge.fury.io/js/mime-types.svg)](https://badge.fury.io/js/mime-types)
The ultimate javascript content-type utility.
### Install
```sh
$ npm install mime-types
```
#### Similar to [mime](https://github.com/broofa/node-mime) except:
- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.
- No fallbacks, so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.
- Additional mime types are added such as jade and stylus. Feel free to add more!
- Browser support via Browserify and Component by converting lists to JSON files.
Otherwise, the API is compatible.
### Adding Types
If you'd like to add additional types,
simply create a PR adding the type to `custom.json` and
a reference link to the [sources](SOURCES.md).
Do __NOT__ edit `mime.json` or `node.json`.
Those are pulled using `build.js`.
You should only touch `custom.json`.
## API
```js
var mime = require('mime-types')
```
All functions return `false` if input is invalid or not found.
### mime.lookup(path)
Lookup the content-type associated with a file.
```js
mime.lookup('json') // 'application/json'
mime.lookup('.md') // 'text/x-markdown'
mime.lookup('file.html') // 'text/html'
mime.lookup('folder/file.js') // 'application/javascript'
mime.lookup('cats') // false
```
### mime.contentType(type)
Create a full content-type header given a content-type or extension.
```js
mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
mime.contentType('file.json') // 'application/json; charset=utf-8'
```
### mime.extension(type)
Get the default extension for a content-type.
```js
mime.extension('application/octet-stream') // 'bin'
```
### mime.charset(type)
Lookup the implied default charset of a content-type.
```js
mime.charset('text/x-markdown') // 'UTF-8'
```
### mime.types[extension] = type
A map of content-types by extension.
### mime.extensions[type] = [extensions]
A map of extensions by content-type.
### mime.define(types)
Globally add definitions.
`types` must be an object of the form:
```js
{
"<content-type>": [extensions...],
"<content-type>": [extensions...]
}
```
See the `.json` files in `lib/` for examples.
## License
[MIT](LICENSE)
### Sources for custom types
This is a list of sources for any custom mime types.
When adding custom mime types, please link to where you found the mime type,
even if it's from an unofficial source.
- `text/coffeescript` - http://coffeescript.org/#scripts
- `text/x-handlebars-template` - https://handlebarsjs.com/#getting-started
- `text/x-sass` & `text/x-scss` - https://github.com/janlelis/rubybuntu-mime/blob/master/sass.xml
[Sources for node.json types](https://github.com/broofa/node-mime/blob/master/types/node.types)
### Notes on weird types
- `font/opentype` - This type is technically invalid according to the spec. No valid types begin with `font/`. No-one uses the official type of `application/vnd.ms-opentype` as the community standardized `application/x-font-otf`. However, chrome logs nonsense warnings unless opentype fonts are served with `font/opentype`. [[1]](http://stackoverflow.com/questions/2871655/proper-mime-type-for-fonts)
/**
* http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
* https://github.com/broofa/node-mime/blob/master/types/node.types
*
* Convert these text files to JSON for browser usage.
*/
var co = require('co')
var fs = require('fs')
var path = require('path')
var cogent = require('cogent')
function* get(url) {
var res = yield* cogent(url, {
string: true
})
if (res.statusCode !== 200)
throw new Error('got status code ' + res.statusCode + ' from ' + url)
var text = res.text
var json = {}
// http://en.wikipedia.org/wiki/Internet_media_type#Naming
/**
* Mime types and associated extensions are stored in the form:
*
* <type> <ext> <ext> <ext>
*
* And some are commented out with a leading `#` because they have no associated extensions.
* This regexp checks whether a single line matches this format, ignoring lines that are just comments.
* We could also just remove all lines that start with `#` if we want to make the JSON files smaller
* and ignore all mime types without associated extensions.
*/
var re = /^(?:# )?([\w-]+\/[\w\+\.-]+)(?:\s+\w+)*$/
text = text.split('\n')
.filter(Boolean)
.forEach(function (line) {
line = line.trim()
if (!line) return
var match = re.exec(line)
if (!match) return
// remove the leading # and <type> and return all the <ext>s
json[match[1]] = line.replace(/^(?:# )?([\w-]+\/[\w\+\.-]+)/, '')
.split(/\s+/)
.filter(Boolean)
})
fs.writeFileSync('lib/' + path.basename(url).split('.')[0] + '.json',
JSON.stringify(json, null, 2) + '\n')
}
co(function* () {
yield [
get('http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types'),
get('https://raw.githubusercontent.com/broofa/node-mime/master/types/node.types')
]
})()
{
"name": "mime-types",
"description": "ultimate mime type utility",
"version": "0.1.0",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com",
"twitter": "https://twitter.com/jongleberry"
},
"repository": "expressjs/mime-types",
"license": "MIT",
"main": "lib/index.js",
"scripts": ["lib/index.js"],
"json": ["mime.json", "node.json", "custom.json"]
}
{
"text/jade": [
"jade"
],
"text/stylus": [
"stylus",
"styl"
],
"text/less": [
"less"
],
"text/x-sass": [
"sass"
],
"text/x-scss": [
"scss"
],
"text/coffeescript": [
"coffee"
],
"text/x-handlebars-template": [
"hbs"
]
}
// types[extension] = type
exports.types = Object.create(null)
// extensions[type] = [extensions]
exports.extensions = Object.create(null)
// define more mime types
exports.define = define
// store the json files
exports.json = {
mime: require('./mime.json'),
node: require('./node.json'),
custom: require('./custom.json'),
}
exports.lookup = function (string) {
if (!string || typeof string !== "string") return false
string = string.replace(/.*[\.\/\\]/, '').toLowerCase()
if (!string) return false
return exports.types[string] || false
}
exports.extension = function (type) {
if (!type || typeof type !== "string") return false
type = type.match(/^\s*([^;\s]*)(?:;|\s|$)/)
if (!type) return false
var exts = exports.extensions[type[1].toLowerCase()]
if (!exts || !exts.length) return false
return exts[0]
}
// type has to be an exact mime type
exports.charset = function (type) {
// special cases
switch (type) {
case 'application/json': return 'UTF-8'
}
// default text/* to utf-8
if (/^text\//.test(type)) return 'UTF-8'
return false
}
// backwards compatibility
exports.charsets = {
lookup: exports.charset
}
exports.contentType = function (type) {
if (!type || typeof type !== "string") return false
if (!~type.indexOf('/')) type = exports.lookup(type)
if (!type) return false
if (!~type.indexOf('charset')) {
var charset = exports.charset(type)
if (charset) type += '; charset=' + charset.toLowerCase()
}
return type
}
define(exports.json.mime)
define(exports.json.node)
define(exports.json.custom)
function define(json) {
Object.keys(json).forEach(function (type) {
var exts = json[type] || []
exports.extensions[type] = exports.extensions[type] || []
exts.forEach(function (ext) {
if (!~exports.extensions[type].indexOf(ext)) exports.extensions[type].push(ext)
exports.types[ext] = type
})
})
}
{
"text/vtt": [
"vtt"
],
"application/x-chrome-extension": [
"crx"
],
"text/x-component": [
"htc"
],
"text/cache-manifest": [
"manifest"
],
"application/octet-stream": [
"buffer"
],
"application/mp4": [
"m4p"
],
"audio/mp4": [
"m4a"
],
"video/MP2T": [
"ts"
],
"application/x-web-app-manifest+json": [
"webapp"
],
"text/x-lua": [
"lua"
],
"application/x-lua-bytecode": [
"luac"
],
"text/x-markdown": [
"markdown",
"md",
"mkd"
],
"text/plain": [
"ini"
],
"application/dash+xml": [
"mdp"
],
"font/opentype": [
"otf"
],
"application/json": [
"map"
],
"application/xml": [
"xsd"
]
}
{
"name": "mime-types",
"description": "ultimate mime type utility",
"version": "1.0.0",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
},
"contributors": [
{
"name": "Jeremiah Senkpiel",
"email": "fishrock123@rocketmail.com",
"url": "https://searchbeam.jit.su"
}
],
"repository": {
"type": "git",
"url": "git://github.com/expressjs/mime-types"
},
"license": "MIT",
"main": "lib",
"devDependencies": {
"co": "3",
"cogent": "0",
"mocha": "1",
"should": "3"
},
"scripts": {
"test": "make test"
},
"readme": "# mime-types [![Build Status](https://travis-ci.org/expressjs/mime-types.svg?branch=master)](https://travis-ci.org/expressjs/mime-types) [![NPM version](https://badge.fury.io/js/mime-types.svg)](https://badge.fury.io/js/mime-types)\n\nThe ultimate javascript content-type utility.\n\n### Install\n\n```sh\n$ npm install mime-types\n```\n\n#### Similar to [mime](https://github.com/broofa/node-mime) except:\n\n- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.\n- No fallbacks, so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.\n- Additional mime types are added such as jade and stylus. Feel free to add more!\n- Browser support via Browserify and Component by converting lists to JSON files.\n\nOtherwise, the API is compatible.\n\n### Adding Types\n\nIf you'd like to add additional types,\nsimply create a PR adding the type to `custom.json` and\na reference link to the [sources](SOURCES.md).\n\nDo __NOT__ edit `mime.json` or `node.json`.\nThose are pulled using `build.js`.\nYou should only touch `custom.json`.\n\n## API\n\n```js\nvar mime = require('mime-types')\n```\n\nAll functions return `false` if input is invalid or not found.\n\n### mime.lookup(path)\n\nLookup the content-type associated with a file.\n\n```js\nmime.lookup('json') // 'application/json'\nmime.lookup('.md') // 'text/x-markdown'\nmime.lookup('file.html') // 'text/html'\nmime.lookup('folder/file.js') // 'application/javascript'\n\nmime.lookup('cats') // false\n```\n\n### mime.contentType(type)\n\nCreate a full content-type header given a content-type or extension.\n\n```js\nmime.contentType('markdown') // 'text/x-markdown; charset=utf-8'\nmime.contentType('file.json') // 'application/json; charset=utf-8'\n```\n\n### mime.extension(type)\n\nGet the default extension for a content-type.\n\n```js\nmime.extension('application/octet-stream') // 'bin'\n```\n\n### mime.charset(type)\n\nLookup the implied default charset of a content-type.\n\n```js\nmime.charset('text/x-markdown') // 'UTF-8'\n```\n\n### mime.types[extension] = type\n\nA map of content-types by extension.\n\n### mime.extensions[type] = [extensions]\n\nA map of extensions by content-type.\n\n### mime.define(types)\n\nGlobally add definitions.\n`types` must be an object of the form:\n\n```js\n{\n \"<content-type>\": [extensions...],\n \"<content-type>\": [extensions...]\n}\n```\n\nSee the `.json` files in `lib/` for examples.\n\n## License\n\n[MIT](LICENSE)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/expressjs/mime-types/issues"
},
"_id": "mime-types@1.0.0",
"dist": {
"shasum": "33e4be5d71804f65b64e01705aef24b8c6c0d76d"
},
"_from": "mime-types@1.0.0",
"_resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.0.tgz"
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Usage: node test.js * Usage: node test.js
*/ */
var mime = require('./mime'); var mime = require("..");
var assert = require('assert'); var assert = require('assert');
var path = require('path'); var path = require('path');
...@@ -26,8 +26,8 @@ eq('text/plain', mime.lookup('.txt')); // nameless ...@@ -26,8 +26,8 @@ eq('text/plain', mime.lookup('.txt')); // nameless
eq('text/plain', mime.lookup('txt')); // extension-only eq('text/plain', mime.lookup('txt')); // extension-only
eq('text/plain', mime.lookup('/txt')); // extension-less () eq('text/plain', mime.lookup('/txt')); // extension-less ()
eq('text/plain', mime.lookup('\\txt')); // Windows, extension-less eq('text/plain', mime.lookup('\\txt')); // Windows, extension-less
eq('application/octet-stream', mime.lookup('text.nope')); // unrecognized // eq('application/octet-stream', mime.lookup('text.nope')); // unrecognized
eq('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default // eq('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default
// //
// Test extensions // Test extensions
...@@ -43,7 +43,7 @@ eq('html', mime.extension('text/html; charset=UTF-8')); ...@@ -43,7 +43,7 @@ eq('html', mime.extension('text/html; charset=UTF-8'));
eq('html', mime.extension('text/html ; charset=UTF-8')); eq('html', mime.extension('text/html ; charset=UTF-8'));
eq('html', mime.extension('text/html;charset=UTF-8')); eq('html', mime.extension('text/html;charset=UTF-8'));
eq('html', mime.extension('text/Html;charset=UTF-8')); eq('html', mime.extension('text/Html;charset=UTF-8'));
eq(undefined, mime.extension('unrecognized')); eq(false, mime.extension('unrecognized'));
// //
// Test node.types lookups // Test node.types lookups
...@@ -58,27 +58,8 @@ eq('font/opentype', mime.lookup('file.otf')); ...@@ -58,27 +58,8 @@ eq('font/opentype', mime.lookup('file.otf'));
// Test charsets // Test charsets
// //
eq('UTF-8', mime.charsets.lookup('text/plain')); eq('UTF-8', mime.charset('text/plain'));
eq(undefined, mime.charsets.lookup(mime.types.js)); eq(false, mime.charset(mime.types.js));
eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); eq('UTF-8', mime.charset('application/json'))
eq('UTF-8', mime.charsets.lookup('text/something'));
// // eq('fallback', mime.charset('application/octet-stream', 'fallback'));
// Test for overlaps between mime.types and node.types
//
var apacheTypes = new mime.Mime(), nodeTypes = new mime.Mime();
apacheTypes.load(path.join(__dirname, 'types/mime.types'));
nodeTypes.load(path.join(__dirname, 'types/node.types'));
var keys = [].concat(Object.keys(apacheTypes.types))
.concat(Object.keys(nodeTypes.types));
keys.sort();
for (var i = 1; i < keys.length; i++) {
if (keys[i] == keys[i-1]) {
console.warn('Warning: ' +
'node.types defines ' + keys[i] + '->' + nodeTypes.types[keys[i]] +
', mime.types defines ' + keys[i] + '->' + apacheTypes.types[keys[i]]);
}
}
console.log('\nOK');
var assert = require('assert')
var mime = require('..')
var lookup = mime.lookup
var extension = mime.extension
var charset = mime.charset
var contentType = mime.contentType
describe('.lookup()', function () {
it('jade', function () {
assert.equal(lookup('jade'), 'text/jade')
assert.equal(lookup('.jade'), 'text/jade')
assert.equal(lookup('file.jade'), 'text/jade')
assert.equal(lookup('folder/file.jade'), 'text/jade')
})
it('should not error on non-string types', function () {
assert.doesNotThrow(function () {
lookup({ noteven: "once" })
lookup(null)
lookup(true)
lookup(Infinity)
})
})
it('should return false for unknown types', function () {
assert.equal(lookup('.jalksdjflakjsdjfasdf'), false)
})
})
describe('.extension()', function () {
it('should not error on non-string types', function () {
assert.doesNotThrow(function () {
extension({ noteven: "once" })
extension(null)
extension(true)
extension(Infinity)
})
})
it('should return false for unknown types', function () {
assert.equal(extension('.jalksdjflakjsdjfasdf'), false)
})
})
describe('.charset()', function () {
it('should not error on non-string types', function () {
assert.doesNotThrow(function () {
charset({ noteven: "once" })
charset(null)
charset(true)
charset(Infinity)
})
})
it('should return false for unknown types', function () {
assert.equal(charset('.jalksdjflakjsdjfasdf'), false)
})
})
describe('.contentType()', function () {
it('html', function () {
assert.equal(contentType('html'), 'text/html; charset=utf-8')
})
it('text/html; charset=ascii', function () {
assert.equal(contentType('text/html; charset=ascii'), 'text/html; charset=ascii')
})
it('json', function () {
assert.equal(contentType('json'), 'application/json; charset=utf-8')
})
it('application/json', function () {
assert.equal(contentType('application/json'), 'application/json; charset=utf-8')
})
it('jade', function () {
assert.equal(contentType('jade'), 'text/jade; charset=utf-8')
})
it('should not error on non-string types', function () {
assert.doesNotThrow(function () {
contentType({ noteven: "once" })
contentType(null)
contentType(true)
contentType(Infinity)
})
})
it('should return false for unknown types', function () {
assert.equal(contentType('.jalksdjflakjsdjfasdf'), false)
})
})
# 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, if no mime type is found `application/octet-stream` is returned. 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.default_type
Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)
### 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/broofa/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.
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++) {
if (process.env.DEBUG_MIME && this.types[exts]) {
console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
this.types[exts] + ' to ' + type);
}
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) {
this._loading = 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);
this._loading = null;
};
/**
* 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) {
var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase();
return this.extensions[type];
};
// 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;
{
"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": "https://github.com/broofa/node-mime",
"type": "git"
},
"version": "1.2.11",
"readme": "# mime\n\nComprehensive 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.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.default_type\nSets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe 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/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/broofa/node-mime/issues"
},
"_id": "mime@1.2.11",
"_from": "mime@~1.2.11"
}
# What: WebVTT
# Why: To allow formats intended for marking up external text track resources.
# http://dev.w3.org/html5/webvtt/
# Added by: niftylettuce
text/vtt vtt
# 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: HTC support
# Why: To properly render .htc files such as CSS3PIE
# Added by: niftylettuce
text/x-component htc
# What: HTML5 application cache manifes ('.manifest' extension)
# 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 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: Video format, Part of RFC1890
# Why: See https://github.com/bentomas/node-mime/pull/6
# Added by: mjrusso
video/MP2T ts
# 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: Lua file types
# Why: Googling around shows de-facto consensus on these
# Added by: creationix (Issue #45)
text/x-lua lua
application/x-lua-bytecode luac
# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax
# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown
# Added by: avoidwork
text/x-markdown markdown md mkd
# What: ini files
# Why: because they're just text files
# Added by: Matthew Kastor
text/plain ini
# What: DASH Adaptive Streaming manifest
# Why: https://developer.mozilla.org/en-US/docs/DASH_Adaptive_Streaming_for_HTML_5_Video
# Added by: eelcocramer
application/dash+xml mdp
# What: OpenType font files - http://www.microsoft.com/typography/otspec/
# Why: Browsers usually ignore the font MIME types and sniff the content,
# but Chrome, shows a warning if OpenType fonts aren't served with
# the `font/opentype` MIME type: http://i.imgur.com/8c5RN8M.png.
# Added by: alrra
font/opentype otf
{ {
"name": "type-is", "name": "type-is",
"description": "Infer the content type if a request", "description": "Infer the content-type of a request.",
"version": "1.2.0", "version": "1.2.1",
"author": { "author": {
"name": "Jonathan Ong", "name": "Jonathan Ong",
"email": "me@jongleberry.com", "email": "me@jongleberry.com",
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
"url": "git://github.com/expressjs/type-is" "url": "git://github.com/expressjs/type-is"
}, },
"dependencies": { "dependencies": {
"mime": "1.2.11" "mime-types": "1.0.0"
}, },
"devDependencies": { "devDependencies": {
"mocha": "*", "mocha": "*",
...@@ -31,11 +31,15 @@ ...@@ -31,11 +31,15 @@
"scripts": { "scripts": {
"test": "mocha --require should --reporter spec --bail" "test": "mocha --require should --reporter spec --bail"
}, },
"readme": "# type-is [![Build Status](https://travis-ci.org/expressjs/type-is.svg?branch=master)](https://travis-ci.org/expressjs/type-is) [![NPM version](https://badge.fury.io/js/type-is.svg)](https://badge.fury.io/js/type-is)\n\nInfer the content type of a request. \nExtracted from [koa](https://github.com/koajs/koa) for general use.\n\nHere's an example body parser:\n\n```js\nvar is = require('type-is');\nvar parse = require('body');\nvar busboy = require('busboy');\n\nfunction bodyParser(req, res, next) {\n var hasRequestBody = 'content-type' in req.headers\n || 'transfer-encoding' in req.headers;\n if (!hasRequestBody) return next();\n \n switch (is(req, ['urlencoded', 'json', 'multipart'])) {\n case 'urlencoded':\n // parse urlencoded body\n break\n case 'json':\n // parse json body\n break\n case 'multipart':\n // parse multipart body\n break\n default:\n // 415 error code\n }\n}\n```\n\n## API\n\n### var type = is(request, types)\n\n```js\nvar is = require('type-is')\n\nhttp.createServer(function (req, res) {\n is(req, ['text/*'])\n})\n```\n\n`request` is the node HTTP request. `types` is an array of types. Each type can be:\n\n- An extension name such as `json`. This name will be returned if matched.\n- A mime type such as `application/json`.\n- A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched\n- A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched.\n\n`false` will be returned if no type matches.\n\nExamples:\n\n```js\n// req.headers.content-type = 'application/json'\nis(req, ['json']) // -> 'json'\nis(req, ['html', 'json']) // -> 'json'\nis(req, ['application/*']) // -> 'application/json'\nis(req, ['application/json']) // -> 'application/json'\nis(req, ['html']) // -> false\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", "readme": "# type-is [![Build Status](https://travis-ci.org/expressjs/type-is.svg?branch=master)](https://travis-ci.org/expressjs/type-is) [![NPM version](https://badge.fury.io/js/type-is.svg)](https://badge.fury.io/js/type-is)\n\nInfer the content-type of a request.\n\n### Install\n\n```sh\n$ npm install type-is\n```\n\n## API\n\n```js\nvar http = require('http')\nvar is = require('type-is')\n\nhttp.createServer(function (req, res) {\n is(req, ['text/*'])\n})\n```\n\n### type = is(request, types)\n\n`request` is the node HTTP request. `types` is an array of types.\n\n```js\n// req.headers.content-type = 'application/json'\n\nis(req, ['json']) // 'json'\nis(req, ['html', 'json']) // 'json'\nis(req, ['application/*']) // 'application/json'\nis(req, ['application/json']) // 'application/json'\n\nis(req, ['html']) // false\n```\n\n#### Each type can be:\n\n- An extension name such as `json`. This name will be returned if matched.\n- A mime type such as `application/json`.\n- A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched\n- A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched.\n\n`false` will be returned if no type matches.\n\n## Examples\n\n#### Example body parser\n\n```js\nvar is = require('type-is');\nvar parse = require('body');\nvar busboy = require('busboy');\n\nfunction bodyParser(req, res, next) {\n var hasRequestBody = 'content-type' in req.headers\n || 'transfer-encoding' in req.headers;\n if (!hasRequestBody) return next();\n\n switch (is(req, ['urlencoded', 'json', 'multipart'])) {\n case 'urlencoded':\n // parse urlencoded body\n break\n case 'json':\n // parse json body\n break\n case 'multipart':\n // parse multipart body\n break\n default:\n // 415 error code\n }\n}\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
"readmeFilename": "README.md", "readmeFilename": "README.md",
"bugs": { "bugs": {
"url": "https://github.com/expressjs/type-is/issues" "url": "https://github.com/expressjs/type-is/issues"
}, },
"_id": "type-is@1.2.0", "_id": "type-is@1.2.1",
"_from": "type-is@1.2.0" "dist": {
"shasum": "ce92daaf26b7e04e10bcf83489774fb6703fccaf"
},
"_from": "type-is@1.2.1",
"_resolved": "https://registry.npmjs.org/type-is/-/type-is-1.2.1.tgz"
} }
0.1.0 / 2014-06-05
==================
* Support array of fields to set
0.0.0 / 2014-06-04
==================
* Initial release
(The MIT License)
Copyright (c) 2014 Douglas Christopher Wilson
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.
# vary
[![NPM version](https://badge.fury.io/js/vary.svg)](http://badge.fury.io/js/vary)
[![Build Status](https://travis-ci.org/expressjs/vary.svg?branch=master)](https://travis-ci.org/expressjs/vary)
[![Coverage Status](https://img.shields.io/coveralls/expressjs/vary.svg?branch=master)](https://coveralls.io/r/expressjs/vary)
Update the Vary header of a response
## Install
```sh
$ npm install vary
```
## API
```js
var vary = require('vary')
```
### vary(res, field)
Adds the given header `field` to the `Vary` response header of `res`.
This can be a string of a single field or an array of multiple fields.
This will append the header if not already listed, otherwise leaves
it listed in the current location.
```js
vary(res, 'Origin')
vary(res, 'User-Agent')
vary(res, ['Accept', 'Accept-Language', 'Accept-Encoding'])
```
## Testing
```sh
$ npm test
```
## License
[MIT](LICENSE)
/*!
* vary
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module exports.
*/
module.exports = vary;
/**
* Variables.
*/
var separators = /[\(\)<>@,;:\\"\/\[\]\?=\{\}\u0020\u0009]/;
/**
* Mark that a request is varied on a header field.
*
* @param {Object} res
* @param {String|Array} field
* @api public
*/
function vary(res, field) {
if (!res || !res.getHeader || !res.setHeader) {
// quack quack
throw new TypeError('res argument is required');
}
if (!field) {
throw new TypeError('field argument is required');
}
var fields = !Array.isArray(field)
? [String(field)]
: field;
for (var i = 0; i < fields.length; i++) {
if (separators.test(fields[i])) {
throw new TypeError('field argument contains an invalid header');
}
}
var val = res.getHeader('Vary') || ''
var headers = Array.isArray(val)
? val.join(', ')
: String(val);
// existing unspecified vary
if (headers === '*') {
return;
}
// enumerate current values
var vals = headers.toLowerCase().split(/ *, */);
// unspecified vary
if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {
res.setHeader('Vary', '*');
return;
}
for (var i = 0; i < fields.length; i++) {
field = fields[i].toLowerCase();
// append value (case-preserving)
if (vals.indexOf(field) === -1) {
vals.push(field);
headers = headers
? headers + ', ' + fields[i]
: fields[i];
}
}
res.setHeader('Vary', headers);
}
{
"name": "vary",
"description": "Update the Vary header of a response",
"version": "0.1.0",
"author": {
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
"license": "MIT",
"keywords": [
"http",
"res",
"vary"
],
"repository": {
"type": "git",
"url": "git://github.com/expressjs/vary"
},
"devDependencies": {
"istanbul": "0.2.10",
"mocha": "~1.20.0",
"should": "~4.0.0"
},
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"test": "mocha --reporter dot test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/"
},
"readme": "# vary\n\n[![NPM version](https://badge.fury.io/js/vary.svg)](http://badge.fury.io/js/vary)\n[![Build Status](https://travis-ci.org/expressjs/vary.svg?branch=master)](https://travis-ci.org/expressjs/vary)\n[![Coverage Status](https://img.shields.io/coveralls/expressjs/vary.svg?branch=master)](https://coveralls.io/r/expressjs/vary)\n\nUpdate the Vary header of a response\n\n## Install\n\n```sh\n$ npm install vary\n```\n\n## API\n\n```js\nvar vary = require('vary')\n```\n\n### vary(res, field)\n\nAdds the given header `field` to the `Vary` response header of `res`.\nThis can be a string of a single field or an array of multiple fields.\n\nThis will append the header if not already listed, otherwise leaves\nit listed in the current location.\n\n```js\nvary(res, 'Origin')\nvary(res, 'User-Agent')\nvary(res, ['Accept', 'Accept-Language', 'Accept-Encoding'])\n```\n\n## Testing\n\n```sh\n$ npm test\n```\n\n## License\n\n[MIT](LICENSE)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/expressjs/vary/issues"
},
"_id": "vary@0.1.0",
"dist": {
"shasum": "ea44e6dbd18f6309025b76b9b28b6bba13ab62ff"
},
"_from": "vary@0.1.0",
"_resolved": "https://registry.npmjs.org/vary/-/vary-0.1.0.tgz"
}
1.1.1 / 2014-06-11
==================
* deps: accepts@1.0.3
1.1.0 / 2014-05-29 1.1.0 / 2014-05-29
================== ==================
......
...@@ -10,15 +10,15 @@ ...@@ -10,15 +10,15 @@
```js ```js
var express = require('express') var express = require('express')
var directory = require('serve-index') var serveIndex = require('serve-index')
var app = express() var app = express()
app.use(directory('public/ftp', {'icons': true})) app.use(serveIndex('public/ftp', {'icons': true}))
app.listen() app.listen()
``` ```
### directory(path, options) ### serveIndex(path, options)
Returns middlware that serves an index of the directory in the given `path`. Returns middlware that serves an index of the directory in the given `path`.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment