mirror of
https://github.com/zebrajr/express.git
synced 2025-12-06 00:19:48 +01:00
parent
a01326adac
commit
997a558a73
|
|
@ -1,6 +1,7 @@
|
|||
unreleased
|
||||
==========
|
||||
|
||||
* accept multiple callbacks to `app.use()`
|
||||
* add explicit "Rosetta Flash JSONP abuse" protection
|
||||
- previous versions are not vulnerable; this is just explicit protection
|
||||
* catch errors in multiple `req.param(name, fn)` handlers
|
||||
|
|
|
|||
|
|
@ -147,41 +147,49 @@ app.handle = function(req, res, done) {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.use = function use(path, fn){
|
||||
app.use = function use(path, fn) {
|
||||
var mount_app;
|
||||
var mount_path;
|
||||
|
||||
// default path to '/'
|
||||
if (arguments.length < 2) {
|
||||
fn = path;
|
||||
path = '/';
|
||||
// check for .use(path, app) or .use(app) signature
|
||||
if (arguments.length <= 2) {
|
||||
mount_path = typeof path === 'string'
|
||||
? path
|
||||
: '/';
|
||||
mount_app = typeof path === 'function'
|
||||
? path
|
||||
: fn;
|
||||
}
|
||||
|
||||
// express app
|
||||
if (fn.handle && fn.set) mount_app = fn;
|
||||
// setup router
|
||||
this.lazyrouter();
|
||||
var router = this._router;
|
||||
|
||||
// restore .app property on req and res
|
||||
if (mount_app) {
|
||||
debug('.use app under %s', path);
|
||||
// express app
|
||||
if (mount_app && mount_app.handle && mount_app.set) {
|
||||
debug('.use app under %s', mount_path);
|
||||
mount_app.mountpath = path;
|
||||
fn = function(req, res, next) {
|
||||
mount_app.parent = this;
|
||||
|
||||
// restore .app property on req and res
|
||||
router.use(mount_path, function mounted_app(req, res, next) {
|
||||
var orig = req.app;
|
||||
mount_app.handle(req, res, function(err) {
|
||||
req.__proto__ = orig.request;
|
||||
res.__proto__ = orig.response;
|
||||
next(err);
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
this.lazyrouter();
|
||||
this._router.use(path, fn);
|
||||
|
||||
// mounted an app
|
||||
if (mount_app) {
|
||||
mount_app.parent = this;
|
||||
// mounted an app
|
||||
mount_app.emit('mount', this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// pass-through use
|
||||
router.use.apply(router, arguments);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ var mixin = require('utils-merge');
|
|||
var debug = require('debug')('express:router');
|
||||
var parseUrl = require('parseurl');
|
||||
var slice = Array.prototype.slice;
|
||||
var toString = Object.prototype.toString;
|
||||
var utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Initialize a new `Router` with the given `options`.
|
||||
|
|
@ -394,37 +396,47 @@ proto.process_params = function(layer, called, req, res, done) {
|
|||
* handlers can operate without any code changes regardless of the "prefix"
|
||||
* pathname.
|
||||
*
|
||||
* @param {String|Function} route
|
||||
* @param {Function} fn
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
proto.use = function(path, fn){
|
||||
proto.use = function use(fn) {
|
||||
var offset = 0;
|
||||
var path = '/';
|
||||
var self = this;
|
||||
|
||||
// default path to '/'
|
||||
if (arguments.length < 2) {
|
||||
fn = path;
|
||||
path = '/';
|
||||
}
|
||||
|
||||
if (typeof fn !== 'function') {
|
||||
var type = {}.toString.call(fn);
|
||||
var msg = 'Router.use() requires callback functions but got a ' + type;
|
||||
throw new Error(msg);
|
||||
offset = 1;
|
||||
path = fn;
|
||||
}
|
||||
|
||||
var layer = new Layer(path, {
|
||||
sensitive: this.caseSensitive,
|
||||
strict: false,
|
||||
end: false
|
||||
}, fn);
|
||||
var callbacks = utils.flatten(slice.call(arguments, offset));
|
||||
|
||||
layer.route = undefined;
|
||||
if (callbacks.length === 0) {
|
||||
throw new TypeError('Router.use() requires callback function');
|
||||
}
|
||||
|
||||
// add the middleware
|
||||
debug('use %s %s', path || '/', fn.name || 'anonymous');
|
||||
callbacks.forEach(function (fn) {
|
||||
if (typeof fn !== 'function') {
|
||||
var type = toString.call(fn);
|
||||
var msg = 'Router.use() requires callback function but got a ' + type;
|
||||
throw new TypeError(msg);
|
||||
}
|
||||
|
||||
// add the middleware
|
||||
debug('use %s %s', path, fn.name || '<anonymous>');
|
||||
|
||||
var layer = new Layer(path, {
|
||||
sensitive: self.caseSensitive,
|
||||
strict: false,
|
||||
end: false
|
||||
}, fn);
|
||||
|
||||
layer.route = undefined;
|
||||
|
||||
self.stack.push(layer);
|
||||
});
|
||||
|
||||
this.stack.push(layer);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ describe('app', function(){
|
|||
app.use(blog);
|
||||
})
|
||||
|
||||
it('should reject numbers', function(){
|
||||
it('should reject missing functions', function(){
|
||||
var app = express();
|
||||
app.use.bind(app, 3).should.throw(/Number/);
|
||||
app.use.bind(app, 3).should.throw(/requires callback function/);
|
||||
})
|
||||
|
||||
describe('.use(app)', function(){
|
||||
|
|
@ -87,6 +87,32 @@ describe('app', function(){
|
|||
})
|
||||
|
||||
describe('.use(middleware)', function(){
|
||||
it('should accept multiple arguments', function (done) {
|
||||
var app = express();
|
||||
|
||||
function fn1(req, res, next) {
|
||||
res.setHeader('x-fn-1', 'hit');
|
||||
next();
|
||||
}
|
||||
|
||||
function fn2(req, res, next) {
|
||||
res.setHeader('x-fn-2', 'hit');
|
||||
next();
|
||||
}
|
||||
|
||||
app.use(fn1, fn2, function fn3(req, res) {
|
||||
res.setHeader('x-fn-3', 'hit');
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('x-fn-1', 'hit')
|
||||
.expect('x-fn-2', 'hit')
|
||||
.expect('x-fn-3', 'hit')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should invoke middleware for all requests', function (done) {
|
||||
var app = express();
|
||||
var cb = after(3, done);
|
||||
|
|
@ -122,6 +148,32 @@ describe('app', function(){
|
|||
.expect(200, 'saw GET /bar', done);
|
||||
})
|
||||
|
||||
it('should accept multiple arguments', function (done) {
|
||||
var app = express();
|
||||
|
||||
function fn1(req, res, next) {
|
||||
res.setHeader('x-fn-1', 'hit');
|
||||
next();
|
||||
}
|
||||
|
||||
function fn2(req, res, next) {
|
||||
res.setHeader('x-fn-2', 'hit');
|
||||
next();
|
||||
}
|
||||
|
||||
app.use('/foo', fn1, fn2, function fn3(req, res) {
|
||||
res.setHeader('x-fn-3', 'hit');
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/foo')
|
||||
.expect('x-fn-1', 'hit')
|
||||
.expect('x-fn-2', 'hit')
|
||||
.expect('x-fn-3', 'hit')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should invoke middleware for all requests starting with path', function (done) {
|
||||
var app = express();
|
||||
var cb = after(3, done);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user