Comparar commits
15 Commits
remove-connect
...
master
| Autor | SHA1 | Data | |
|---|---|---|---|
| f8b954bcd9 | |||
| caa25b506d | |||
| 6911815171 | |||
| 0719e5f402 | |||
| 07b731add0 | |||
| d42d8f5b07 | |||
| 143e72dd85 | |||
| 6835289564 | |||
| 1396e0855d | |||
| 6a7363e4ae | |||
| 9bc63d92a0 | |||
| 6b05f60bad | |||
| 25e6629bcc | |||
| 0796c1d2d2 | |||
| aac1d52c4f |
+1
-2
@@ -1,4 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
- "0.10"
|
||||
|
||||
+7
-4
@@ -3,16 +3,19 @@
|
||||
|
||||
* remove:
|
||||
- express(1) - moved to [express-generator](https://github.com/expressjs/generator)
|
||||
- `req.accepted*` - use `req.accepts*()` instead
|
||||
- `app.configure` - use logic in your own app code
|
||||
- `express.createServer()` - it has been deprecated for a long time. Use `express()`
|
||||
- `app.configure` - use logic in your own app code
|
||||
- `app.router` - is removed
|
||||
- `req.accepted*` - use `req.accepts*()` instead
|
||||
- `res.location` - relative URL resolution is removed
|
||||
- all bundled middleware except `static`
|
||||
* change:
|
||||
- `app.route` -> `app.mountpath` when mounting an express app in another express app
|
||||
- `json spaces` no longer enabled by default in development
|
||||
- `req.accepts*` -> `req.accepts*s` - i.e. `req.acceptsEncoding` -> `req.acceptsEncodings`
|
||||
- `req.params` is now an object instead of an array
|
||||
- `json spaces` no longer enabled by default in development
|
||||
- `res.locals` is no longer a function. It is a plain js object. Treat it as such.
|
||||
- `app.route` -> `app.mountpath` when mounting an express app in another express app
|
||||
- `res.headerSent` -> `res.headersSent` to match node.js ServerResponse object
|
||||
* refactor:
|
||||
- `req.accepts*` with [accepts](https://github.com/expressjs/accepts)
|
||||
- `req.is` with [type-is](https://github.com/expressjs/type-is)
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
*/
|
||||
|
||||
var express = require('../..')
|
||||
, hash = require('./pass').hash;
|
||||
, hash = require('./pass').hash
|
||||
, bodyParser = require('body-parser')
|
||||
, cookieParser = require('cookie-parser')
|
||||
, session = require('express-session')
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
@@ -14,9 +17,9 @@ app.set('views', __dirname + '/views');
|
||||
|
||||
// middleware
|
||||
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.cookieParser('shhhh, very secret'));
|
||||
app.use(express.session());
|
||||
app.use(bodyParser());
|
||||
app.use(cookieParser('shhhh, very secret'));
|
||||
app.use(session());
|
||||
|
||||
// Session-persisted message middleware
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
var express = require('../..')
|
||||
, logger = require('morgan')
|
||||
, app = express();
|
||||
|
||||
app.set('views', __dirname);
|
||||
@@ -14,11 +15,11 @@ while (n--) {
|
||||
pets.push({ name: 'Jane', age: 6, species: 'ferret' });
|
||||
}
|
||||
|
||||
app.use(express.logger('dev'));
|
||||
app.use(logger('dev'));
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('pets', { pets: pets });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express listening on port 3000');
|
||||
console.log('Express listening on port 3000');
|
||||
|
||||
@@ -4,17 +4,19 @@
|
||||
*/
|
||||
|
||||
var express = require('../../');
|
||||
var favicon = require('static-favicon');
|
||||
var cookie-parser = require('cookie-parser');
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
// ignore GET /favicon.ico
|
||||
app.use(express.favicon());
|
||||
app.use(favicon());
|
||||
|
||||
// pass a secret to cookieParser() for signed cookies
|
||||
app.use(express.cookieParser('manny is cool'));
|
||||
app.use(cookieParser('manny is cool'));
|
||||
|
||||
// add req.session cookie support
|
||||
app.use(express.cookieSession());
|
||||
app.use(cookieSession());
|
||||
|
||||
// do something with the session
|
||||
app.use(count);
|
||||
@@ -29,4 +31,4 @@ function count(req, res) {
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express server listening on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
, app = module.exports = express();
|
||||
, app = module.exports = express()
|
||||
, favicon = require('static-favicon')
|
||||
, logger = require('morgan')
|
||||
, cookieParser = require('cookie-parser')
|
||||
, bodyParser = require('body-parser')
|
||||
|
||||
|
||||
// add favicon() before logger() so
|
||||
@@ -12,20 +16,20 @@ var express = require('../../')
|
||||
// logged, because this middleware
|
||||
// reponds to /favicon.ico and does not
|
||||
// call next()
|
||||
app.use(express.favicon());
|
||||
app.use(favicon());
|
||||
|
||||
// custom log format
|
||||
if ('test' != process.env.NODE_ENV)
|
||||
app.use(express.logger(':method :url'));
|
||||
app.use(logger(':method :url'));
|
||||
|
||||
// parses request cookies, populating
|
||||
// req.cookies and req.signedCookies
|
||||
// when the secret is passed, used
|
||||
// when the secret is passed, used
|
||||
// for signing the cookies.
|
||||
app.use(express.cookieParser('my secret here'));
|
||||
app.use(cookieParser('my secret here'));
|
||||
|
||||
// parses json, x-www-form-urlencoded, and multipart/form-data
|
||||
app.use(express.bodyParser());
|
||||
app.use(bodyParser());
|
||||
|
||||
app.get('/', function(req, res){
|
||||
if (req.cookies.remember) {
|
||||
@@ -51,4 +55,4 @@ app.post('/', function(req, res){
|
||||
if (!module.parent){
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
*/
|
||||
|
||||
var express = require('../..')
|
||||
, logger = require('morgan')
|
||||
, app = express()
|
||||
, bodyParser = require('body-parser')
|
||||
, api = express();
|
||||
|
||||
// app middleware
|
||||
@@ -12,8 +14,8 @@ app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// api middleware
|
||||
|
||||
api.use(express.logger('dev'));
|
||||
api.use(express.bodyParser());
|
||||
api.use(logger('dev'));
|
||||
api.use(bodyParser());
|
||||
|
||||
/**
|
||||
* CORS support.
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
var express = require('../../')
|
||||
, app = module.exports = express()
|
||||
, logger = require('morgan')
|
||||
, favicon = require('static-favicon')
|
||||
, silent = 'test' == process.env.NODE_ENV;
|
||||
|
||||
// general config
|
||||
@@ -21,9 +23,9 @@ if ('production' == app.settings.env) {
|
||||
app.disable('verbose errors');
|
||||
}
|
||||
|
||||
app.use(express.favicon());
|
||||
app.use(favicon());
|
||||
|
||||
silent || app.use(express.logger('dev'));
|
||||
silent || app.use(logger('dev'));
|
||||
|
||||
// Routes
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
, logger = require('morgan')
|
||||
, app = module.exports = express()
|
||||
, test = app.get('env') == 'test';
|
||||
|
||||
if (!test) app.use(express.logger('dev'));
|
||||
if (!test) app.use(logger('dev'));
|
||||
|
||||
// error handling middleware have an arity of 4
|
||||
// instead of the typical (req, res, next),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
var express = require('../..')
|
||||
, logger = require('morgan')
|
||||
, app = express();
|
||||
|
||||
app.set('view engine', 'jade');
|
||||
@@ -23,7 +24,7 @@ User.prototype.toJSON = function(){
|
||||
}
|
||||
};
|
||||
|
||||
app.use(express.logger('dev'));
|
||||
app.use(logger('dev'));
|
||||
|
||||
// earlier on expose an object
|
||||
// that we can tack properties on.
|
||||
@@ -57,4 +58,4 @@ app.get('/user', function(req, res){
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('app listening on port 3000');
|
||||
console.log('app listening on port 3000');
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
var express = require('../..');
|
||||
var logger = require('morgan');
|
||||
var session = require('express-session');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var bodyParser = require('body-parser');
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
@@ -25,20 +29,17 @@ app.response.message = function(msg){
|
||||
};
|
||||
|
||||
// log
|
||||
if (!module.parent) app.use(express.logger('dev'));
|
||||
if (!module.parent) app.use(logger('dev'));
|
||||
|
||||
// serve static files
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// session support
|
||||
app.use(express.cookieParser('some secret here'));
|
||||
app.use(express.session());
|
||||
app.use(cookieParser('some secret here'));
|
||||
app.use(session());
|
||||
|
||||
// parse request bodies (req.body)
|
||||
app.use(express.bodyParser());
|
||||
|
||||
// support _method (PUT in forms etc)
|
||||
app.use(express.methodOverride());
|
||||
app.use(bodyParser());
|
||||
|
||||
// expose the "messages" local variable when views are rendered
|
||||
app.use(function(req, res, next){
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
var express = require('../..')
|
||||
, app = express()
|
||||
, logger = require('morgan')
|
||||
, cookieParser = require('cookie-parser')
|
||||
, bodyParser = require('body-parser')
|
||||
, site = require('./site')
|
||||
, post = require('./post')
|
||||
, user = require('./user');
|
||||
@@ -13,10 +16,9 @@ var express = require('../..')
|
||||
|
||||
app.set('view engine', 'jade');
|
||||
app.set('views', __dirname + '/views');
|
||||
app.use(express.logger('dev'));
|
||||
app.use(express.cookieParser());
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(logger('dev'));
|
||||
app.use(cookieParser());
|
||||
app.use(bodyParser());
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// General
|
||||
|
||||
@@ -7,8 +7,6 @@ var express = require('../..');
|
||||
|
||||
var app = express();
|
||||
|
||||
app.use(express.logger('dev'));
|
||||
|
||||
// Required by session() middleware
|
||||
// pass the secret for signed cookies
|
||||
// (required by session())
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
var express = require('../..');
|
||||
var logger = require('morgan');
|
||||
var app = express();
|
||||
|
||||
// log requests
|
||||
app.use(express.logger('dev'));
|
||||
app.use(logger('dev'));
|
||||
|
||||
// express on its own has no notion
|
||||
// of a "file". The express.static()
|
||||
@@ -41,4 +42,4 @@ console.log('listening on port 3000');
|
||||
console.log('try:');
|
||||
console.log(' GET /hello.txt');
|
||||
console.log(' GET /js/app.js');
|
||||
console.log(' GET /css/style.css');
|
||||
console.log(' GET /css/style.css');
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
var express = require('../..');
|
||||
var logger = require('morgan');
|
||||
|
||||
/*
|
||||
edit /etc/hosts:
|
||||
@@ -16,7 +17,7 @@ edit /etc/hosts:
|
||||
|
||||
var main = express();
|
||||
|
||||
main.use(express.logger('dev'));
|
||||
main.use(logger('dev'));
|
||||
|
||||
main.get('/', function(req, res){
|
||||
res.send('Hello from main app!')
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var connect = require('connect')
|
||||
, mixin = require('utils-merge')
|
||||
var mixin = require('utils-merge')
|
||||
, escapeHtml = require('escape-html')
|
||||
, Router = require('./router')
|
||||
, methods = require('methods')
|
||||
, middleware = require('./middleware')
|
||||
, middleware = require('./middleware/init')
|
||||
, query = require('./middleware/query')
|
||||
, debug = require('debug')('express:application')
|
||||
, View = require('./view')
|
||||
, http = require('http');
|
||||
@@ -99,7 +99,7 @@ app.lazyrouter = function() {
|
||||
strict: this.enabled('strict routing')
|
||||
});
|
||||
|
||||
this._router.use(connect.query());
|
||||
this._router.use(query());
|
||||
this._router.use(middleware.init(this));
|
||||
}
|
||||
};
|
||||
@@ -138,7 +138,7 @@ app.handle = function(req, res, done) {
|
||||
|
||||
// log to stderr in a non-test env
|
||||
if ('test' != env) console.error(err.stack || err.toString());
|
||||
if (res.headerSent) return req.socket.destroy();
|
||||
if (res.headersSent) return req.socket.destroy();
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader('Content-Length', Buffer.byteLength(msg));
|
||||
if ('HEAD' == req.method) return res.end();
|
||||
@@ -214,6 +214,8 @@ app.use = function(route, fn){
|
||||
*/
|
||||
|
||||
app.route = function(path){
|
||||
this.lazyrouter();
|
||||
return this._router.route(path);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+8
-18
@@ -4,8 +4,7 @@
|
||||
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var connect = require('connect')
|
||||
, merge = require('merge-descriptors')
|
||||
var merge = require('merge-descriptors')
|
||||
, mixin = require('utils-merge')
|
||||
|
||||
var proto = require('./application')
|
||||
@@ -14,18 +13,15 @@ var proto = require('./application')
|
||||
, req = require('./request')
|
||||
, res = require('./response')
|
||||
|
||||
// monkey patch ServerResponse methods
|
||||
require('./patch')
|
||||
|
||||
/**
|
||||
* Expose `createApplication()`.
|
||||
*/
|
||||
|
||||
exports = module.exports = createApplication;
|
||||
|
||||
/**
|
||||
* Expose mime.
|
||||
*/
|
||||
|
||||
exports.mime = connect.mime;
|
||||
|
||||
/**
|
||||
* Create an express application.
|
||||
*
|
||||
@@ -47,13 +43,6 @@ function createApplication() {
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose connect.middleware as express.*
|
||||
* for example `express.logger` etc.
|
||||
*/
|
||||
|
||||
merge(exports, connect.middleware);
|
||||
|
||||
/**
|
||||
* Expose the prototypes.
|
||||
*/
|
||||
@@ -69,7 +58,8 @@ exports.response = res;
|
||||
exports.Route = Route;
|
||||
exports.Router = Router;
|
||||
|
||||
// Error handler title
|
||||
|
||||
exports.errorHandler.title = 'Express';
|
||||
/**
|
||||
* Expose middleware
|
||||
*/
|
||||
|
||||
exports.static = require('./middleware/static');
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
/**
|
||||
* Initialization middleware, exposing the
|
||||
* request and response to eachother, as well
|
||||
@@ -30,3 +23,4 @@ exports.init = function(app){
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
var qs = require('qs');
|
||||
var parseUrl = require('../utils').parseUrl;
|
||||
|
||||
/**
|
||||
* Query:
|
||||
*
|
||||
* Automatically parse the query-string when available,
|
||||
* populating the `req.query` object using
|
||||
* [qs](https://github.com/visionmedia/node-querystring).
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* .use(connect.query())
|
||||
* .use(function(req, res){
|
||||
* res.end(JSON.stringify(req.query));
|
||||
* });
|
||||
*
|
||||
* The `options` passed are provided to qs.parse function.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function query(options){
|
||||
return function query(req, res, next){
|
||||
if (!req.query) {
|
||||
req.query = ~req.url.indexOf('?')
|
||||
? qs.parse(parseUrl(req).query, options)
|
||||
: {};
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
/*!
|
||||
* Connect - static
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var send = require('send')
|
||||
, utils = require('../utils')
|
||||
, parse = utils.parseUrl
|
||||
, url = require('url');
|
||||
|
||||
/**
|
||||
* Static:
|
||||
*
|
||||
* Static file server with the given `root` path.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* var oneDay = 86400000;
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.static(__dirname + '/public'))
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.static(__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'
|
||||
*
|
||||
* @param {String} root
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function(root, options){
|
||||
options = options || {};
|
||||
|
||||
// root required
|
||||
if (!root) throw new Error('static() root path required');
|
||||
|
||||
// default redirect
|
||||
var redirect = false !== options.redirect;
|
||||
|
||||
return function staticMiddleware(req, res, next) {
|
||||
if ('GET' != req.method && 'HEAD' != req.method) return next();
|
||||
var originalUrl = url.parse(req.originalUrl);
|
||||
var path = parse(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 ' + utils.escape(target));
|
||||
}
|
||||
|
||||
function error(err) {
|
||||
if (404 == err.status) return next();
|
||||
next(err);
|
||||
}
|
||||
|
||||
send(req, path)
|
||||
.maxage(options.maxAge || 0)
|
||||
.root(root)
|
||||
.index(options.index || 'index.html')
|
||||
.hidden(options.hidden)
|
||||
.on('error', error)
|
||||
.on('directory', directory)
|
||||
.pipe(res);
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*!
|
||||
* Connect
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http');
|
||||
var ServerResponse = http.ServerResponse;
|
||||
|
||||
// apply only once
|
||||
if (ServerResponse.prototype._hasConnectPatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
// original methods
|
||||
var setHeader = ServerResponse.prototype.setHeader;
|
||||
var writeHead = ServerResponse.prototype.writeHead;
|
||||
|
||||
/**
|
||||
* Set header `field` to `val`, special-casing
|
||||
* the `Set-Cookie` field for multiple support.
|
||||
*
|
||||
* @param {String} field
|
||||
* @param {String} val
|
||||
* @api public
|
||||
*/
|
||||
|
||||
ServerResponse.prototype.setHeader = function(field, val){
|
||||
var key = field.toLowerCase();
|
||||
|
||||
if ('content-type' == key && this.charset) {
|
||||
val += '; charset=' + this.charset;
|
||||
}
|
||||
|
||||
return setHeader.call(this, field, val);
|
||||
};
|
||||
|
||||
ServerResponse.prototype.writeHead = function(statusCode, reasonPhrase, headers){
|
||||
if (typeof reasonPhrase === 'object') headers = reasonPhrase;
|
||||
if (typeof headers === 'object') {
|
||||
Object.keys(headers).forEach(function(key){
|
||||
this.setHeader(key, headers[key]);
|
||||
}, this);
|
||||
}
|
||||
if (!this._emittedHeader) this.emit('header');
|
||||
this._emittedHeader = true;
|
||||
return writeHead.call(this, statusCode, reasonPhrase);
|
||||
};
|
||||
|
||||
ServerResponse.prototype._hasConnectPatch = true;
|
||||
+2
-4
@@ -7,11 +7,9 @@ var accepts = require('accepts');
|
||||
var typeis = require('type-is');
|
||||
var http = require('http')
|
||||
, utils = require('./utils')
|
||||
, connect = require('connect')
|
||||
, fresh = require('fresh')
|
||||
, parseRange = require('range-parser')
|
||||
, parse = connect.utils.parseUrl
|
||||
, mime = connect.mime;
|
||||
, parse = utils.parseUrl
|
||||
|
||||
/**
|
||||
* Request prototype.
|
||||
@@ -191,7 +189,7 @@ req.range = function(size){
|
||||
*
|
||||
* To utilize request bodies, `req.body`
|
||||
* should be an object. This can be done by using
|
||||
* the `connect.bodyParser()` middleware.
|
||||
* the `bodyParser()` middleware.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Mixed} [defaultValue]
|
||||
|
||||
+20
-39
@@ -4,7 +4,6 @@
|
||||
|
||||
var http = require('http')
|
||||
, path = require('path')
|
||||
, connect = require('connect')
|
||||
, mixin = require('utils-merge')
|
||||
, escapeHtml = require('escape-html')
|
||||
, sign = require('cookie-signature').sign
|
||||
@@ -14,10 +13,10 @@ var http = require('http')
|
||||
, statusCodes = http.STATUS_CODES
|
||||
, cookie = require('cookie')
|
||||
, send = require('send')
|
||||
, mime = connect.mime
|
||||
, resolve = require('url').resolve
|
||||
, basename = path.basename
|
||||
, extname = path.extname;
|
||||
, extname = path.extname
|
||||
, mime = send.mime
|
||||
|
||||
/**
|
||||
* Response prototype.
|
||||
@@ -312,13 +311,13 @@ res.sendfile = function(path, options, fn){
|
||||
|
||||
// clean up
|
||||
cleanup();
|
||||
if (!self.headerSent) self.removeHeader('Content-Disposition');
|
||||
if (!self.headersSent) self.removeHeader('Content-Disposition');
|
||||
|
||||
// callback available
|
||||
if (fn) return fn(err);
|
||||
|
||||
// list in limbo if there's no callback
|
||||
if (self.headerSent) return;
|
||||
if (self.headersSent) return;
|
||||
|
||||
// delegate
|
||||
next(err);
|
||||
@@ -353,7 +352,7 @@ res.sendfile = function(path, options, fn){
|
||||
* Optionally providing an alternate attachment `filename`,
|
||||
* and optional callback `fn(err)`. The callback is invoked
|
||||
* when the data transfer is complete, or when an error has
|
||||
* ocurred. Be sure to check `res.headerSent` if you plan to respond.
|
||||
* ocurred. Be sure to check `res.headersSent` if you plan to respond.
|
||||
*
|
||||
* This method uses `res.sendfile()`.
|
||||
*
|
||||
@@ -589,7 +588,7 @@ res.cookie = function(name, val, options){
|
||||
options = mixin({}, options);
|
||||
var secret = this.req.secret;
|
||||
var signed = options.signed;
|
||||
if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
|
||||
if (signed && !secret) throw new Error('cookieParser("secret") required for signed cookies');
|
||||
if ('number' == typeof val) val = val.toString();
|
||||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
|
||||
if (signed) val = 's:' + sign(val, secret);
|
||||
@@ -598,7 +597,18 @@ res.cookie = function(name, val, options){
|
||||
options.maxAge /= 1000;
|
||||
}
|
||||
if (null == options.path) options.path = '/';
|
||||
this.set('Set-Cookie', cookie.serialize(name, String(val), options));
|
||||
var headerVal = cookie.serialize(name, String(val), options);
|
||||
|
||||
// supports multiple 'res.cookie' calls by getting previous value
|
||||
var prev = this.get('Set-Cookie');
|
||||
if (prev) {
|
||||
if (Array.isArray(prev)) {
|
||||
headerVal = prev.concat(headerVal);
|
||||
} else {
|
||||
headerVal = [prev, headerVal];
|
||||
}
|
||||
}
|
||||
this.set('Set-Cookie', headerVal);
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -613,47 +623,18 @@ res.cookie = function(name, val, options){
|
||||
*
|
||||
* res.location('/foo/bar').;
|
||||
* res.location('http://example.com');
|
||||
* res.location('../login'); // /blog/post/1 -> /blog/login
|
||||
*
|
||||
* Mounting:
|
||||
*
|
||||
* When an application is mounted and `res.location()`
|
||||
* is given a path that does _not_ lead with "/" it becomes
|
||||
* relative to the mount-point. For example if the application
|
||||
* is mounted at "/blog", the following would become "/blog/login".
|
||||
*
|
||||
* res.location('login');
|
||||
*
|
||||
* While the leading slash would result in a location of "/login":
|
||||
*
|
||||
* res.location('/login');
|
||||
* res.location('../login');
|
||||
*
|
||||
* @param {String} url
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.location = function(url){
|
||||
var app = this.app
|
||||
, req = this.req
|
||||
, path;
|
||||
var req = this.req;
|
||||
|
||||
// "back" is an alias for the referrer
|
||||
if ('back' == url) url = req.get('Referrer') || '/';
|
||||
|
||||
// relative
|
||||
if (!~url.indexOf('://') && 0 != url.indexOf('//')) {
|
||||
// relative to path
|
||||
if ('.' == url[0]) {
|
||||
path = req.originalUrl.split('?')[0];
|
||||
path = path + ('/' == path[path.length - 1] ? '' : '/');
|
||||
url = resolve(path, url);
|
||||
// relative to mount-point
|
||||
} else if ('/' != url[0]) {
|
||||
path = app.path();
|
||||
url = path + '/' + url;
|
||||
}
|
||||
}
|
||||
|
||||
// Respond
|
||||
this.set('Location', url);
|
||||
return this;
|
||||
|
||||
+99
-70
@@ -3,36 +3,38 @@
|
||||
*/
|
||||
|
||||
var Route = require('./route')
|
||||
, Layer = require('./layer')
|
||||
, utils = require('../utils')
|
||||
, methods = require('methods')
|
||||
, debug = require('debug')('express:router')
|
||||
, parse = require('connect').utils.parseUrl;
|
||||
|
||||
/**
|
||||
* Expose `Router` constructor.
|
||||
*/
|
||||
|
||||
exports = module.exports = Router;
|
||||
, parseUrl = utils.parseUrl;
|
||||
|
||||
/**
|
||||
* Initialize a new `Router` with the given `options`.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
* @return {Router} which is an callable function
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Router(options) {
|
||||
var proto = module.exports = function(options) {
|
||||
options = options || {};
|
||||
var self = this;
|
||||
|
||||
self.params = {};
|
||||
self._params = [];
|
||||
self.caseSensitive = options.caseSensitive;
|
||||
self.strict = options.strict;
|
||||
self.stack = [];
|
||||
function router(req, res, next) {
|
||||
router.handle(req, res, next);
|
||||
};
|
||||
|
||||
self.middleware = self.handle.bind(self);
|
||||
}
|
||||
// mixin Router class functions
|
||||
router.__proto__ = proto;
|
||||
|
||||
router.params = {};
|
||||
router._params = [];
|
||||
router.caseSensitive = options.caseSensitive;
|
||||
router.strict = options.strict;
|
||||
router.stack = [];
|
||||
|
||||
return router;
|
||||
};
|
||||
|
||||
/**
|
||||
* Map the given param placeholder `name`(s) to the given callback.
|
||||
@@ -68,7 +70,7 @@ function Router(options) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.param = function(name, fn){
|
||||
proto.param = function(name, fn){
|
||||
// param logic
|
||||
if ('function' == typeof name) {
|
||||
this._params.push(name);
|
||||
@@ -106,7 +108,7 @@ Router.prototype.param = function(name, fn){
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype.handle = function(req, res, done) {
|
||||
proto.handle = function(req, res, done) {
|
||||
var self = this;
|
||||
|
||||
debug('dispatching %s %s', req.method, req.url);
|
||||
@@ -126,7 +128,7 @@ Router.prototype.handle = function(req, res, done) {
|
||||
var options = [];
|
||||
|
||||
// middleware and routes
|
||||
var stack = this.stack;
|
||||
var stack = self.stack;
|
||||
|
||||
// for options requests, respond with a default if nothing else responds
|
||||
if (method === 'options') {
|
||||
@@ -159,65 +161,75 @@ Router.prototype.handle = function(req, res, done) {
|
||||
removed = '';
|
||||
|
||||
try {
|
||||
var path = parse(req).pathname;
|
||||
var path = parseUrl(req).pathname;
|
||||
if (undefined == path) path = '/';
|
||||
|
||||
if (!layer.match(path)) return next(err);
|
||||
|
||||
// route object and not middleware
|
||||
var route = layer.route;
|
||||
|
||||
// handle route
|
||||
// if final route, then we support options
|
||||
if (route) {
|
||||
// we don't run any routs with error first
|
||||
if (err || !route.match(path)) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
req.params = route.params;
|
||||
req.route = route;
|
||||
|
||||
// we can now dispatch to the route
|
||||
if (method === 'options' && !route.methods['options']) {
|
||||
options.push.apply(options, route._options());
|
||||
}
|
||||
}
|
||||
|
||||
return self.process_params(route, req, res, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
req.params = layer.params;
|
||||
|
||||
// this should be done for the layer
|
||||
return self.process_params(layer, req, res, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (route) {
|
||||
return layer.handle(req, res, next);
|
||||
}
|
||||
|
||||
trim_prefix();
|
||||
});
|
||||
|
||||
return next(err);
|
||||
|
||||
function trim_prefix() {
|
||||
var c = path[layer.path.length];
|
||||
if (c && '/' != c && '.' != c) return next(err);
|
||||
|
||||
// Trim off the part of the url that matches the route
|
||||
// middleware (.use stuff) needs to have the path stripped
|
||||
debug('trim prefix (%s) from url %s', removed, req.url);
|
||||
removed = layer.path;
|
||||
req.url = protohost + req.url.substr(protohost.length + removed.length);
|
||||
|
||||
// Ensure leading slash
|
||||
if (!fqdn && '/' != req.url[0]) {
|
||||
req.url = '/' + req.url;
|
||||
slashAdded = true;
|
||||
}
|
||||
|
||||
debug('%s %s : %s', layer.handle.name || 'anonymous', layer.path, req.originalUrl);
|
||||
var arity = layer.handle.length;
|
||||
if (err) {
|
||||
if (arity === 4) {
|
||||
layer.handle(err, req, res, next);
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
|
||||
route.dispatch(req, res, next);
|
||||
});
|
||||
}
|
||||
|
||||
// skip this layer if the path doesn't match.
|
||||
if (0 != path.toLowerCase().indexOf(layer.path.toLowerCase())) return next(err);
|
||||
|
||||
var c = path[layer.path.length];
|
||||
if (c && '/' != c && '.' != c) return next(err);
|
||||
|
||||
// Trim off the part of the url that matches the route
|
||||
// middleware (.use stuff) needs to have the path stripped
|
||||
debug('trim prefix (%s) from url %s', removed, req.url);
|
||||
removed = layer.path;
|
||||
req.url = protohost + req.url.substr(protohost.length + removed.length);
|
||||
|
||||
// Ensure leading slash
|
||||
if (!fqdn && '/' != req.url[0]) {
|
||||
req.url = '/' + req.url;
|
||||
slashAdded = true;
|
||||
}
|
||||
|
||||
debug('%s %s : %s', layer.handle.name || 'anonymous', layer.path, req.originalUrl);
|
||||
var arity = layer.handle.length;
|
||||
if (err) {
|
||||
if (arity === 4) {
|
||||
layer.handle(err, req, res, next);
|
||||
} else if (arity < 4) {
|
||||
layer.handle(req, res, next);
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
} else if (arity < 4) {
|
||||
layer.handle(req, res, next);
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
@@ -231,13 +243,18 @@ Router.prototype.handle = function(req, res, done) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype.process_params = function(route, req, res, done) {
|
||||
proto.process_params = function(route, req, res, done) {
|
||||
var self = this;
|
||||
var params = this.params;
|
||||
|
||||
// captured parameters from the route, keys and values
|
||||
var keys = route.keys || [];
|
||||
|
||||
// fast track
|
||||
if (keys.length === 0) {
|
||||
return done();
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
var paramIndex = 0;
|
||||
var key;
|
||||
@@ -301,7 +318,7 @@ Router.prototype.process_params = function(route, req, res, done) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.use = function(route, fn){
|
||||
proto.use = function(route, fn){
|
||||
|
||||
// default route to '/'
|
||||
if ('string' != typeof route) {
|
||||
@@ -314,10 +331,16 @@ Router.prototype.use = function(route, fn){
|
||||
route = route.slice(0, -1);
|
||||
}
|
||||
|
||||
var layer = Layer(route, {
|
||||
sensitive: this.caseSensitive,
|
||||
strict: this.strict,
|
||||
end: false
|
||||
}, fn);
|
||||
|
||||
// add the middleware
|
||||
debug('use %s %s', route || '/', fn.name || 'anonymous');
|
||||
this.stack.push({ path: route, handle: fn });
|
||||
|
||||
this.stack.push(layer);
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -334,13 +357,18 @@ Router.prototype.use = function(route, fn){
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.route = function(path){
|
||||
var route = new Route(path, {
|
||||
sensitive: this.caseSensitive,
|
||||
strict: this.strict
|
||||
});
|
||||
proto.route = function(path){
|
||||
var route = new Route(path);
|
||||
|
||||
this.stack.push({ path: path, route: route });
|
||||
var layer = Layer(path, {
|
||||
sensitive: this.caseSensitive,
|
||||
strict: this.strict,
|
||||
end: true
|
||||
}, route.dispatch.bind(route));
|
||||
|
||||
layer.route = route;
|
||||
|
||||
this.stack.push(layer);
|
||||
return route;
|
||||
};
|
||||
|
||||
@@ -354,7 +382,7 @@ Router.prototype.route = function(path){
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.all = function(path, fn) {
|
||||
proto.all = function(path, fn) {
|
||||
var route = this.route(path);
|
||||
methods.forEach(function(method){
|
||||
route[method](fn);
|
||||
@@ -363,9 +391,10 @@ Router.prototype.all = function(path, fn) {
|
||||
|
||||
// create Router#VERB functions
|
||||
methods.forEach(function(method){
|
||||
Router.prototype[method] = function(path, fn){
|
||||
proto[method] = function(path, fn){
|
||||
var self = this;
|
||||
self.route(path)[method](fn);
|
||||
return self;
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
var utils = require('../utils')
|
||||
, debug = require('debug')('express:router:layer')
|
||||
|
||||
function Layer(path, options, fn) {
|
||||
if (!(this instanceof Layer)) {
|
||||
return new Layer(path, options, fn);
|
||||
}
|
||||
|
||||
debug('new %s', path);
|
||||
options = options || {};
|
||||
this.path = path;
|
||||
this.params = {};
|
||||
this.regexp = utils.pathRegexp(path
|
||||
, this.keys = []
|
||||
, options.sensitive
|
||||
, options.strict
|
||||
, options.end);
|
||||
this.handle = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this route matches `path`, if so
|
||||
* populate `.params`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Layer.prototype.match = function(path){
|
||||
var keys = this.keys
|
||||
, params = this.params = {}
|
||||
, m = this.regexp.exec(path)
|
||||
, n = 0;
|
||||
|
||||
if (!m) return false;
|
||||
|
||||
for (var i = 1, len = m.length; i < len; ++i) {
|
||||
var key = keys[i - 1];
|
||||
|
||||
try {
|
||||
var val = 'string' == typeof m[i]
|
||||
? decodeURIComponent(m[i])
|
||||
: m[i];
|
||||
} catch(e) {
|
||||
var err = new Error("Failed to decode param '" + m[i] + "'");
|
||||
err.status = 400;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
params[key.name] = val;
|
||||
} else {
|
||||
params[n++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
module.exports = Layer;
|
||||
+3
-58
@@ -3,8 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, debug = require('debug')('express:router:route')
|
||||
var debug = require('debug')('express:router:route')
|
||||
, methods = require('methods')
|
||||
|
||||
/**
|
||||
@@ -14,75 +13,21 @@ var utils = require('../utils')
|
||||
module.exports = Route;
|
||||
|
||||
/**
|
||||
* Initialize `Route` with the given HTTP `method`, `path`,
|
||||
* and an array of `callbacks` and `options`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `sensitive` enable case-sensitive routes
|
||||
* - `strict` enable strict matching for trailing slashes
|
||||
* Initialize `Route` with the given `path`,
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} options.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Route(path, options) {
|
||||
function Route(path) {
|
||||
debug('new %s', path);
|
||||
options = options || {};
|
||||
this.path = path;
|
||||
this.params = {};
|
||||
this.regexp = utils.pathRegexp(path
|
||||
, this.keys = []
|
||||
, options.sensitive
|
||||
, options.strict);
|
||||
|
||||
this.stack = undefined;
|
||||
|
||||
// route handlers for various http methods
|
||||
this.methods = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this route matches `path`, if so
|
||||
* populate `.params`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Route.prototype.match = function(path){
|
||||
var keys = this.keys
|
||||
, params = this.params = {}
|
||||
, m = this.regexp.exec(path)
|
||||
, n = 0;
|
||||
|
||||
if (!m) return false;
|
||||
|
||||
for (var i = 1, len = m.length; i < len; ++i) {
|
||||
var key = keys[i - 1];
|
||||
|
||||
try {
|
||||
var val = 'string' == typeof m[i]
|
||||
? decodeURIComponent(m[i])
|
||||
: m[i];
|
||||
} catch(e) {
|
||||
var err = new Error("Failed to decode param '" + m[i] + "'");
|
||||
err.status = 400;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
params[key.name] = val;
|
||||
} else {
|
||||
params[n++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {Array} supported HTTP methods
|
||||
* @api private
|
||||
|
||||
+30
-4
@@ -3,8 +3,9 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var mime = require('connect').mime
|
||||
, crc32 = require('buffer-crc32');
|
||||
var mime = require('send').mime;
|
||||
var crc32 = require('buffer-crc32');
|
||||
var parse = require('url').parse;
|
||||
|
||||
/**
|
||||
* toString ref.
|
||||
@@ -131,11 +132,12 @@ function acceptParams(str, index) {
|
||||
* @param {Array} keys
|
||||
* @param {Boolean} sensitive
|
||||
* @param {Boolean} strict
|
||||
* @param {Boolean} end (whether to append $ to regex)
|
||||
* @return {RegExp}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
exports.pathRegexp = function(path, keys, sensitive, strict, end) {
|
||||
if (toString.call(path) == '[object RegExp]') return path;
|
||||
if (Array.isArray(path)) path = '(' + path.join('|') + ')';
|
||||
path = path
|
||||
@@ -154,5 +156,29 @@ exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
})
|
||||
.replace(/([\/.])/g, '\\$1')
|
||||
.replace(/\*/g, '(.*)');
|
||||
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
||||
return new RegExp('^' + path + ((end) ? '$' : ''), sensitive ? '' : 'i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the `req` url with memoization.
|
||||
*
|
||||
* @param {ServerRequest} req
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.parseUrl = function(req){
|
||||
var parsed = req._parsedUrl;
|
||||
if (parsed && parsed.href == req.url) {
|
||||
return parsed;
|
||||
} else {
|
||||
parsed = parse(req.url);
|
||||
|
||||
if (parsed.auth && !parsed.protocol && ~parsed.href.indexOf('//')) {
|
||||
// This parses pathnames, and a strange pathname like //r@e should work
|
||||
parsed = parse(req.url.replace(/@/g, '%40'));
|
||||
}
|
||||
|
||||
return req._parsedUrl = parsed;
|
||||
}
|
||||
};
|
||||
|
||||
+8
-3
@@ -22,19 +22,19 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": "2.12.0",
|
||||
"accepts": "1.0.0",
|
||||
"type-is": "1.0.0",
|
||||
"range-parser": "1.0.0",
|
||||
"cookie": "0.1.0",
|
||||
"buffer-crc32": "0.2.1",
|
||||
"fresh": "0.2.1",
|
||||
"fresh": "0.2.2",
|
||||
"methods": "0.1.0",
|
||||
"send": "0.2.0",
|
||||
"cookie-signature": "1.0.3",
|
||||
"merge-descriptors": "0.0.2",
|
||||
"utils-merge": "1.0.0",
|
||||
"escape-html": "1.0.1",
|
||||
"qs": "0.6.6",
|
||||
"debug": ">= 0.7.3 < 1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -46,7 +46,12 @@
|
||||
"should": "~2.1.1",
|
||||
"connect-redis": "~1.4.5",
|
||||
"marked": "0.2.10",
|
||||
"supertest": "~0.8.1"
|
||||
"supertest": "~0.8.1",
|
||||
"body-parser": "1.0.0",
|
||||
"cookie-parser": "1.0.1",
|
||||
"static-favicon": "1.0.0",
|
||||
"express-session": "1.0.1",
|
||||
"morgan": "1.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"express",
|
||||
|
||||
@@ -9,7 +9,6 @@ var app = express()
|
||||
, blog = express()
|
||||
, admin = express();
|
||||
|
||||
// app.use(express.logger('dev'))
|
||||
blog.use('/admin', admin);
|
||||
app.use('/blog', blog);
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
@@ -6,15 +6,6 @@ var express = require('../')
|
||||
|
||||
describe('Route', function(){
|
||||
|
||||
describe('.match', function(){
|
||||
it('should match', function(){
|
||||
var route = new Route('/foo/bar');
|
||||
|
||||
assert(route.match('/foo/bar'));
|
||||
assert(!route.match('/foo/baz'));
|
||||
})
|
||||
})
|
||||
|
||||
describe('.all', function(){
|
||||
it('should add handler', function(done){
|
||||
var route = new Route('/foo');
|
||||
|
||||
+60
-1
@@ -6,7 +6,31 @@ var express = require('../')
|
||||
|
||||
describe('Router', function(){
|
||||
|
||||
describe('.middleware', function(){
|
||||
it('should return a function with router methods', function() {
|
||||
var router = Router();
|
||||
assert(typeof router == 'function');
|
||||
|
||||
var router = new Router();
|
||||
assert(typeof router == 'function');
|
||||
|
||||
assert(typeof router.get == 'function');
|
||||
assert(typeof router.handle == 'function');
|
||||
assert(typeof router.use == 'function');
|
||||
});
|
||||
|
||||
it('should support .use of other routers', function(done) {
|
||||
var router = Router();
|
||||
var another = Router();
|
||||
|
||||
another.get('/bar', function(req, res) {
|
||||
res.done();
|
||||
});
|
||||
router.use('/foo', another);
|
||||
|
||||
router.handle({ url: '/foo/bar', method: 'GET' }, { done: done });
|
||||
});
|
||||
|
||||
describe('.handle', function(){
|
||||
it('should dispatch', function(done){
|
||||
var router = new Router();
|
||||
|
||||
@@ -94,4 +118,39 @@ describe('Router', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('.param', function() {
|
||||
it('should call param function when routing VERBS', function(done) {
|
||||
var router = new Router();
|
||||
|
||||
router.param('id', function(req, res, next, id) {
|
||||
assert.equal(id, '123');
|
||||
next();
|
||||
});
|
||||
|
||||
router.get('/foo/:id/bar', function(req, res, next) {
|
||||
assert.equal(req.params.id, '123');
|
||||
next();
|
||||
});
|
||||
|
||||
router.handle({ url: '/foo/123/bar', method: 'get' }, {}, done);
|
||||
});
|
||||
|
||||
it('should call param function when routing middleware', function(done) {
|
||||
var router = new Router();
|
||||
|
||||
router.param('id', function(req, res, next, id) {
|
||||
assert.equal(id, '123');
|
||||
next();
|
||||
});
|
||||
|
||||
router.use('/foo/:id/bar', function(req, res, next) {
|
||||
assert.equal(req.params.id, '123');
|
||||
assert.equal(req.url, '/baz');
|
||||
next();
|
||||
});
|
||||
|
||||
router.handle({ url: '/foo/123/bar/baz', method: 'get' }, {}, done);
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('auth', function(){
|
||||
it('should redirect to /login', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(redirects(/\/login$/, done))
|
||||
.end(redirects(/login$/, done))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('auth', function(){
|
||||
it('should redirect to /login', function(done){
|
||||
request(app)
|
||||
.get('/restricted')
|
||||
.end(redirects(/\/login$/,done))
|
||||
.end(redirects(/login$/,done))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -36,7 +36,7 @@ describe('auth', function(){
|
||||
.post('/login')
|
||||
.type('urlencoded')
|
||||
.send('username=not-tj&password=foobar')
|
||||
.end(redirects(/\/login$/, done))
|
||||
.end(redirects(/login$/, done))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -31,7 +31,7 @@ describe('OPTIONS', function(){
|
||||
var router = new express.Router();
|
||||
|
||||
router.get('/users', function(req, res){});
|
||||
app.use(router.middleware);
|
||||
app.use(router);
|
||||
app.get('/other', function(req, res){});
|
||||
|
||||
request(app)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
var express = require('../')
|
||||
, request = require('./support/http')
|
||||
|
||||
describe('app.route', function(){
|
||||
it('should return a new route', function(done){
|
||||
var app = express();
|
||||
|
||||
app.route('/foo')
|
||||
.get(function(req, res) {
|
||||
res.send('get');
|
||||
})
|
||||
.post(function(req, res) {
|
||||
res.send('post');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.post('/foo')
|
||||
.expect('post', done);
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,8 @@ var express = require('../')
|
||||
describe('app.router', function(){
|
||||
describe('methods supported', function(){
|
||||
methods.forEach(function(method){
|
||||
if (method === 'connect') return;
|
||||
|
||||
it('should include ' + method.toUpperCase(), function(done){
|
||||
if (method == 'delete') method = 'del';
|
||||
var app = express();
|
||||
|
||||
@@ -4,16 +4,6 @@ var express = require('../')
|
||||
, assert = require('assert');
|
||||
|
||||
describe('exports', function(){
|
||||
it('should expose connect middleware', function(){
|
||||
express.should.have.property('bodyParser');
|
||||
express.should.have.property('session');
|
||||
express.should.have.property('static');
|
||||
})
|
||||
|
||||
it('should expose .mime', function(){
|
||||
assert(express.mime == require('connect').mime, 'express.mime should be connect.mime');
|
||||
})
|
||||
|
||||
it('should expose Router', function(){
|
||||
express.Router.should.be.a.Function;
|
||||
})
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
, request = require('./support/http')
|
||||
, bodyParser = require('body-parser')
|
||||
|
||||
describe('req', function(){
|
||||
describe('.param(name, default)', function(){
|
||||
@@ -33,7 +34,7 @@ describe('req', function(){
|
||||
it('should check req.body', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.bodyParser());
|
||||
app.use(bodyParser());
|
||||
|
||||
app.use(function(req, res){
|
||||
res.end(req.param('name'));
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
, request = require('./support/http')
|
||||
, cookieParser = require('cookie-parser')
|
||||
|
||||
describe('req', function(){
|
||||
describe('.signedCookies', function(){
|
||||
it('should return a signed JSON cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('secret'));
|
||||
app.use(cookieParser('secret'));
|
||||
|
||||
app.use(function(req, res){
|
||||
if ('/set' == req.path) {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
var express = require('../')
|
||||
, request = require('./support/http')
|
||||
, mixin = require('utils-merge')
|
||||
, cookie = require('cookie');
|
||||
, cookie = require('cookie')
|
||||
, cookieParser = require('cookie-parser')
|
||||
|
||||
describe('res', function(){
|
||||
describe('.cookie(name, object)', function(){
|
||||
@@ -46,13 +47,14 @@ describe('res', function(){
|
||||
app.use(function(req, res){
|
||||
res.cookie('name', 'tobi');
|
||||
res.cookie('age', 1);
|
||||
res.cookie('gender', '?');
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
var val = ['name=tobi; Path=/', 'age=1; Path=/'];
|
||||
var val = ['name=tobi; Path=/', 'age=1; Path=/', 'gender=%3F; Path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
@@ -134,7 +136,7 @@ describe('res', function(){
|
||||
it('should generate a signed JSON cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('foo bar baz'));
|
||||
app.use(cookieParser('foo bar baz'));
|
||||
|
||||
app.use(function(req, res){
|
||||
res.cookie('user', { name: 'tobi' }, { signed: true }).end();
|
||||
@@ -155,7 +157,7 @@ describe('res', function(){
|
||||
it('should set a signed cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('foo bar baz'));
|
||||
app.use(cookieParser('foo bar baz'));
|
||||
|
||||
app.use(function(req, res){
|
||||
res.cookie('name', 'tobi', { signed: true }).end();
|
||||
|
||||
@@ -18,171 +18,5 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading //', function(){
|
||||
it('should pass through scheme-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('//cuteoverload.com').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '//cuteoverload.com');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading /', function(){
|
||||
it('should construct scheme-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('/login').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ./', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('./edit').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/1/edit');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ../', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('../new').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/new');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ./ and containing ..', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('./skip/../../new').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/new');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('without leading /', function(){
|
||||
it('should construct mount-point relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('login').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when mounted', function(){
|
||||
describe('deeply', function(){
|
||||
it('should respect the mount-point', function(done){
|
||||
var app = express()
|
||||
, blog = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.location('login').end();
|
||||
});
|
||||
|
||||
app.use('/blog', blog);
|
||||
blog.use('/admin', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog/admin')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/blog/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('omitting leading /', function(){
|
||||
it('should respect the mount-point', function(done){
|
||||
var app = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.location('admin/login').end();
|
||||
});
|
||||
|
||||
app.use('/blog', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/blog/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('providing leading /', function(){
|
||||
it('should ignore mount-point', function(done){
|
||||
var app = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.location('/admin/login').end();
|
||||
});
|
||||
|
||||
app.use('/blog', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+1
-73
@@ -105,7 +105,7 @@ describe('res', function(){
|
||||
.set('Host', 'http://example.com')
|
||||
.set('Accept', 'text/html')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('<p>Moved Temporarily. Redirecting to <a href="/<lame>">/<lame></a></p>');
|
||||
res.text.should.equal('<p>Moved Temporarily. Redirecting to <a href="<lame>"><lame></a></p>');
|
||||
done();
|
||||
})
|
||||
})
|
||||
@@ -169,76 +169,4 @@ describe('res', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('responses redirected to relative paths', function(){
|
||||
function create(depth, parent) {
|
||||
var app = express();
|
||||
|
||||
if (parent) {
|
||||
parent.use('/depth' + depth, app);
|
||||
}
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.redirect('./index');
|
||||
});
|
||||
|
||||
app.get('/index', function(req, res){
|
||||
res.json({ depth: depth, content: 'index' });
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
var root = create(0);
|
||||
var depth1 = create(1, root);
|
||||
var depth2 = create(2, depth1);
|
||||
var depth3 = create(3, depth2);
|
||||
|
||||
root.use('/depth2', depth2);
|
||||
root.use('/depth3', depth3);
|
||||
|
||||
it('should not contain redundant leading slashes in the location header', function(done){
|
||||
request(root)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.location.search(/^\/{2}/).should.equal(-1);
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should preserve context when redirecting nested applications at any depth', function(done){
|
||||
request(root)
|
||||
.get('/depth1')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/depth1/index');
|
||||
|
||||
request(root)
|
||||
.get('/depth1/depth2')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/depth1/depth2/index');
|
||||
|
||||
request(root)
|
||||
.get('/depth1/depth2/depth3')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/depth1/depth2/depth3/index');
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
it('should redirect correctly for nested applications that have been remounted', function(done){
|
||||
request(root)
|
||||
.get('/depth2')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/depth2/index');
|
||||
request(root)
|
||||
.get('/depth3')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/depth3/index');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -42,7 +42,7 @@ describe('res', function(){
|
||||
app.use(function(req, res){
|
||||
res.sendfile('test/fixtures/nope.html', function(err){
|
||||
++calls;
|
||||
assert(!res.headerSent);
|
||||
assert(!res.headersSent);
|
||||
res.send(err.message);
|
||||
});
|
||||
});
|
||||
@@ -77,7 +77,7 @@ describe('res', function(){
|
||||
|
||||
app.use(function(req, res){
|
||||
res.sendfile('test/fixtures/foo/../user.html', function(err){
|
||||
assert(!res.headerSent);
|
||||
assert(!res.headersSent);
|
||||
++calls;
|
||||
res.send(err.message);
|
||||
});
|
||||
@@ -95,7 +95,7 @@ describe('res', function(){
|
||||
|
||||
app.use(function(req, res){
|
||||
res.sendfile('test/fixtures/user.html', function(err){
|
||||
assert(!res.headerSent);
|
||||
assert(!res.headersSent);
|
||||
req.socket.listeners('error').should.have.length(1); // node's original handler
|
||||
done();
|
||||
});
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário