mirror of
https://github.com/expressjs/express.git
synced 2026-02-27 11:09:29 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e850cb3ea3 | ||
|
|
13d3efe8df | ||
|
|
d6ecf785a2 | ||
|
|
a38bdf6758 | ||
|
|
5aa9670120 | ||
|
|
8ad8cb93cc | ||
|
|
610e172fcf | ||
|
|
6942070a21 | ||
|
|
e283200511 | ||
|
|
54a192a5c5 | ||
|
|
c3bd65eda2 | ||
|
|
3de81e0147 |
11
bin/express
11
bin/express
@@ -16,6 +16,7 @@ var exec = require('child_process').exec
|
||||
|
||||
program
|
||||
.version(version)
|
||||
.usage('[options] [dir]')
|
||||
.option('-s, --sessions', 'add session support')
|
||||
.option('-e, --ejs', 'add ejs engine support (defaults to jade)')
|
||||
.option('-J, --jshtml', 'add jshtml engine support (defaults to jade)')
|
||||
@@ -208,11 +209,11 @@ var app = [
|
||||
, ' * Module dependencies.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'var express = require(\'express\')'
|
||||
, ' , routes = require(\'./routes\')'
|
||||
, ' , user = require(\'./routes/user\')'
|
||||
, ' , http = require(\'http\')'
|
||||
, ' , path = require(\'path\');'
|
||||
, 'var express = require(\'express\');'
|
||||
, 'var routes = require(\'./routes\');'
|
||||
, 'var user = require(\'./routes/user\');'
|
||||
, 'var http = require(\'http\');'
|
||||
, 'var path = require(\'path\');'
|
||||
, ''
|
||||
, 'var app = express();'
|
||||
, ''
|
||||
|
||||
@@ -46,6 +46,7 @@ app.init = function(){
|
||||
app.defaultConfiguration = function(){
|
||||
// default settings
|
||||
this.enable('x-powered-by');
|
||||
this.enable('etag');
|
||||
this.set('env', process.env.NODE_ENV || 'development');
|
||||
this.set('subdomain offset', 2);
|
||||
debug('booting in %s mode', this.get('env'));
|
||||
@@ -184,7 +185,7 @@ app.engine = function(ext, fn){
|
||||
* could automatically load a user's information from the database without
|
||||
* any additional code,
|
||||
*
|
||||
* The callback uses the samesignature as middleware, the only differencing
|
||||
* The callback uses the same signature as middleware, the only differencing
|
||||
* being that the value of the placeholder is passed, in this case the _id_
|
||||
* of the user. Once the `next()` function is invoked, just like middleware
|
||||
* it will continue on to execute the route, or subsequent parameter functions.
|
||||
|
||||
@@ -82,6 +82,9 @@ res.send = function(body){
|
||||
var head = 'HEAD' == req.method;
|
||||
var len;
|
||||
|
||||
// settings
|
||||
var app = this.app;
|
||||
|
||||
// allow status / body
|
||||
if (2 == arguments.length) {
|
||||
// res.send(body, status) backwards compat
|
||||
@@ -128,7 +131,7 @@ res.send = function(body){
|
||||
|
||||
// ETag support
|
||||
// TODO: W/ support
|
||||
if (len > 1024 && 'GET' == req.method) {
|
||||
if (app.settings.etag && len > 1024 && 'GET' == req.method) {
|
||||
if (!this.get('ETag')) {
|
||||
this.set('ETag', etag(body));
|
||||
}
|
||||
|
||||
@@ -103,6 +103,9 @@ Router.prototype._dispatch = function(req, res, next){
|
||||
// match route
|
||||
req.route = route = self.matchRequest(req, i);
|
||||
|
||||
// implied OPTIONS
|
||||
if (!route && 'OPTIONS' == req.method) return self._options(req, res);
|
||||
|
||||
// no route
|
||||
if (!route) return next(err);
|
||||
debug('matched %s %s', route.method, route.path);
|
||||
@@ -170,6 +173,41 @@ Router.prototype._dispatch = function(req, res, next){
|
||||
})(0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond to __OPTIONS__ method.
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @param {ServerResponse} res
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._options = function(req, res){
|
||||
var path = parse(req).pathname
|
||||
, body = this._optionsFor(path).join(',');
|
||||
res.set('Allow', body).send(body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an array of HTTP verbs or "options" for `path`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._optionsFor = function(path){
|
||||
var self = this;
|
||||
return methods.filter(function(method){
|
||||
var routes = self.map[method];
|
||||
if (!routes || 'options' == method) return;
|
||||
for (var i = 0, len = routes.length; i < len; ++i) {
|
||||
if (routes[i].match(path)) return true;
|
||||
}
|
||||
}).map(function(method){
|
||||
return method.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to match a route for `req`
|
||||
* with optional starting index of `i`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "3.3.4",
|
||||
"version": "3.3.5",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{
|
||||
@@ -22,15 +22,15 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": "2.8.4",
|
||||
"connect": "2.8.5",
|
||||
"commander": "1.2.0",
|
||||
"range-parser": "0.0.4",
|
||||
"mkdirp": "0.3.5",
|
||||
"cookie": "0.1.0",
|
||||
"buffer-crc32": "0.2.1",
|
||||
"fresh": "0.1.0",
|
||||
"fresh": "0.2.0",
|
||||
"methods": "0.0.1",
|
||||
"send": "0.1.3",
|
||||
"send": "0.1.4",
|
||||
"cookie-signature": "1.0.1",
|
||||
"debug": "*"
|
||||
},
|
||||
|
||||
37
test/app.options.js
Normal file
37
test/app.options.js
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
|
||||
describe('OPTIONS', function(){
|
||||
it('should default to the routes defined', function(done){
|
||||
var app = express();
|
||||
|
||||
app.del('/', function(){});
|
||||
app.get('/users', function(req, res){});
|
||||
app.put('/users', function(req, res){});
|
||||
|
||||
request(app)
|
||||
.options('/users')
|
||||
.expect('GET,PUT')
|
||||
.expect('Allow', 'GET,PUT', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('app.options()', function(){
|
||||
it('should override the default behavior', function(done){
|
||||
var app = express();
|
||||
|
||||
app.options('/users', function(req, res){
|
||||
res.set('Allow', 'GET');
|
||||
res.send('GET');
|
||||
});
|
||||
|
||||
app.get('/users', function(req, res){});
|
||||
app.put('/users', function(req, res){});
|
||||
|
||||
request(app)
|
||||
.options('/users')
|
||||
.expect('GET')
|
||||
.expect('Allow', 'GET', done);
|
||||
})
|
||||
})
|
||||
@@ -53,7 +53,7 @@ app3.use(function(req, res, next){
|
||||
})
|
||||
});
|
||||
|
||||
describe('req', function(){
|
||||
describe('res', function(){
|
||||
describe('.format(obj)', function(){
|
||||
describe('with canonicalized mime types', function(){
|
||||
test(app);
|
||||
@@ -79,14 +79,14 @@ function test(app) {
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/html; q=.5, application/json, */*; q=.1')
|
||||
.expect('{"message":"hey"}', done);
|
||||
.expect({"message":"hey"}, done);
|
||||
})
|
||||
|
||||
it('should allow wildcard type/subtypes', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/html; q=.5, application/*, */*; q=.1')
|
||||
.expect('{"message":"hey"}', done);
|
||||
.expect({"message":"hey"}, done);
|
||||
})
|
||||
|
||||
it('should default the Content-Type', function(done){
|
||||
|
||||
@@ -318,4 +318,62 @@ describe('res', function(){
|
||||
.get('/?callback=foo')
|
||||
.expect('{"foo":"bar"}', done);
|
||||
})
|
||||
|
||||
describe('"etag" setting', function(){
|
||||
describe('when enabled', function(){
|
||||
it('should send ETag ', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
var str = Array(1024 * 2).join('-');
|
||||
res.send(str);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('etag', '"-1498647312"');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when disabled', function(){
|
||||
it('should send no ETag', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
var str = Array(1024 * 2).join('-');
|
||||
res.send(str);
|
||||
});
|
||||
|
||||
app.disable('etag');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.not.have.property('etag');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should send ETag when manually set', function(done){
|
||||
var app = express();
|
||||
|
||||
app.disable('etag');
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('etag', 1);
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('etag');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user