mirror of
https://github.com/expressjs/express.git
synced 2026-02-26 18:57:43 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86328767fe | ||
|
|
e497d068a1 | ||
|
|
926a71f5ac | ||
|
|
55f5a2dc8d | ||
|
|
fe435e497e | ||
|
|
0c567b3282 | ||
|
|
855176b633 | ||
|
|
b95f2ee820 | ||
|
|
ae92db98f3 | ||
|
|
0b25547ca0 | ||
|
|
548f2865e2 | ||
|
|
ee3f2b073c | ||
|
|
34b6385dc3 | ||
|
|
11529a2ea0 | ||
|
|
b0f8809e3d | ||
|
|
ec1175daa3 | ||
|
|
3a1d9b8289 | ||
|
|
192be8fea3 | ||
|
|
1afcff955b | ||
|
|
224fe05697 | ||
|
|
2dd332b491 | ||
|
|
33e4193f45 | ||
|
|
c163d2f33d | ||
|
|
a715ba6be4 |
53
History.md
53
History.md
@@ -1,3 +1,56 @@
|
||||
3.19.2 / 2015-02-01
|
||||
===================
|
||||
|
||||
* deps: connect@2.28.3
|
||||
- deps: compression@~1.3.1
|
||||
- deps: csurf@~1.6.6
|
||||
- deps: errorhandler@~1.3.3
|
||||
- deps: express-session@~1.10.2
|
||||
- deps: serve-index@~1.6.1
|
||||
- deps: type-is@~1.5.6
|
||||
* deps: proxy-addr@~1.0.6
|
||||
- deps: ipaddr.js@0.1.8
|
||||
|
||||
3.19.1 / 2015-01-20
|
||||
===================
|
||||
|
||||
* deps: connect@2.28.2
|
||||
- deps: body-parser@~1.10.2
|
||||
- deps: serve-static@~1.8.1
|
||||
* deps: send@0.11.1
|
||||
- Fix root path disclosure
|
||||
|
||||
3.19.0 / 2015-01-09
|
||||
===================
|
||||
|
||||
* Fix `OPTIONS` responses to include the `HEAD` method property
|
||||
* Use `readline` for prompt in `express(1)`
|
||||
* deps: commander@2.6.0
|
||||
* deps: connect@2.28.1
|
||||
- deps: body-parser@~1.10.1
|
||||
- deps: compression@~1.3.0
|
||||
- deps: connect-timeout@~1.5.0
|
||||
- deps: csurf@~1.6.4
|
||||
- deps: debug@~2.1.1
|
||||
- deps: errorhandler@~1.3.2
|
||||
- deps: express-session@~1.10.1
|
||||
- deps: finalhandler@0.3.3
|
||||
- deps: method-override@~2.3.1
|
||||
- deps: morgan@~1.5.1
|
||||
- deps: serve-favicon@~2.2.0
|
||||
- deps: serve-index@~1.6.0
|
||||
- deps: serve-static@~1.8.0
|
||||
- deps: type-is@~1.5.5
|
||||
* deps: debug@~2.1.1
|
||||
* deps: methods@~1.1.1
|
||||
* deps: proxy-addr@~1.0.5
|
||||
- deps: ipaddr.js@0.1.6
|
||||
* deps: send@0.11.0
|
||||
- deps: debug@~2.1.1
|
||||
- deps: etag@~1.5.1
|
||||
- deps: ms@0.7.0
|
||||
- deps: on-finished@~2.2.0
|
||||
|
||||
3.18.6 / 2014-12-12
|
||||
===================
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[](https://www.npmjs.org/package/express)
|
||||
[](https://travis-ci.org/strongloop/express)
|
||||
[](https://coveralls.io/r/strongloop/express)
|
||||
[](https://www.gittip.com/dougwilson/)
|
||||
[](https://gratipay.com/dougwilson/)
|
||||
|
||||
```js
|
||||
var express = require('express');
|
||||
|
||||
19
bin/express
19
bin/express
@@ -7,6 +7,7 @@
|
||||
var program = require('commander')
|
||||
, mkdirp = require('mkdirp')
|
||||
, pkg = require('../package.json')
|
||||
, readline = require('readline')
|
||||
, version = pkg.version
|
||||
, os = require('os')
|
||||
, fs = require('fs');
|
||||
@@ -249,7 +250,7 @@ var app = [
|
||||
if (empty || program.force) {
|
||||
createApplicationAt(path);
|
||||
} else {
|
||||
program.confirm('destination is not empty, continue? ', function(ok){
|
||||
confirm('destination is not empty, continue? [y/N] ', function (ok) {
|
||||
if (ok) {
|
||||
process.stdin.destroy();
|
||||
createApplicationAt(path);
|
||||
@@ -261,6 +262,22 @@ var app = [
|
||||
});
|
||||
})(path);
|
||||
|
||||
/**
|
||||
* Prompt for confirmation on STDOUT/STDIN
|
||||
*/
|
||||
|
||||
function confirm(msg, callback) {
|
||||
var rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
rl.question(msg, function (input) {
|
||||
rl.close();
|
||||
callback(/^y|yes|ok|true$/i.test(input));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create application at the given directory `path`.
|
||||
*
|
||||
|
||||
@@ -196,17 +196,32 @@ Router.prototype._options = function(req, res, next){
|
||||
* @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;
|
||||
Router.prototype._optionsFor = function _optionsFor(path) {
|
||||
var options = [];
|
||||
|
||||
for (var i = 0; i < methods.length; i++) {
|
||||
var method = methods[i];
|
||||
|
||||
if (method === 'options') continue;
|
||||
|
||||
var routes = this.map[method];
|
||||
|
||||
// HEAD methods include GET routes
|
||||
if (!routes && method === 'head') {
|
||||
routes = this.map.get;
|
||||
}
|
||||
}).map(function(method){
|
||||
return method.toUpperCase();
|
||||
});
|
||||
|
||||
if (!routes) continue;
|
||||
|
||||
for (var j = 0; j < routes.length; j++) {
|
||||
if (routes[j].match(path)) {
|
||||
options.push(method.toUpperCase());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options.sort();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
24
package.json
24
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "3.18.6",
|
||||
"version": "3.19.2",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
|
||||
@@ -27,22 +27,22 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"basic-auth": "1.0.0",
|
||||
"connect": "2.27.6",
|
||||
"connect": "2.28.3",
|
||||
"content-disposition": "0.5.0",
|
||||
"commander": "1.3.2",
|
||||
"commander": "2.6.0",
|
||||
"cookie-signature": "1.0.5",
|
||||
"debug": "~2.1.0",
|
||||
"debug": "~2.1.1",
|
||||
"depd": "~1.0.0",
|
||||
"escape-html": "1.0.1",
|
||||
"etag": "~1.5.1",
|
||||
"fresh": "0.2.4",
|
||||
"media-typer": "0.3.0",
|
||||
"methods": "1.1.0",
|
||||
"methods": "~1.1.1",
|
||||
"mkdirp": "0.5.0",
|
||||
"parseurl": "~1.3.0",
|
||||
"proxy-addr": "~1.0.4",
|
||||
"proxy-addr": "~1.0.6",
|
||||
"range-parser": "~1.0.2",
|
||||
"send": "0.10.1",
|
||||
"send": "0.11.1",
|
||||
"utils-merge": "1.0.0",
|
||||
"vary": "~1.0.0",
|
||||
"cookie": "0.1.2",
|
||||
@@ -50,13 +50,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"connect-redis": "~1.5.0",
|
||||
"ejs": "2.1.4",
|
||||
"istanbul": "0.3.5",
|
||||
"mocha": "~2.0.0",
|
||||
"should": "~4.3.1",
|
||||
"marked": "0.3.3",
|
||||
"mocha": "~2.1.0",
|
||||
"should": "~4.6.2",
|
||||
"supertest": "~0.15.0",
|
||||
"ejs": "~1.0.0",
|
||||
"hjs": "~0.0.6",
|
||||
"marked": "0.3.2"
|
||||
"hjs": "~0.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
|
||||
@@ -12,8 +12,8 @@ describe('OPTIONS', function(){
|
||||
|
||||
request(app)
|
||||
.options('/users')
|
||||
.expect('GET,PUT')
|
||||
.expect('Allow', 'GET,PUT', done);
|
||||
.expect('GET,HEAD,PUT')
|
||||
.expect('Allow', 'GET,HEAD,PUT', done);
|
||||
})
|
||||
|
||||
it('should not respond if the path is not defined', function(done){
|
||||
@@ -36,8 +36,8 @@ describe('OPTIONS', function(){
|
||||
|
||||
request(app)
|
||||
.options('/other')
|
||||
.expect('GET')
|
||||
.expect('Allow', 'GET', done);
|
||||
.expect('GET,HEAD')
|
||||
.expect('Allow', 'GET,HEAD', done);
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('req', function(){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res._headers = undefined;
|
||||
res._headers = null;
|
||||
res.send(req.fresh);
|
||||
});
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('req', function(){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res._headers = undefined;
|
||||
res._headers = null;
|
||||
res.send(req.stale);
|
||||
});
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ describe('res', function(){
|
||||
it('should be invoked instead of auto-responding', function(done){
|
||||
request(app3)
|
||||
.get('/')
|
||||
.set('Accept: text/html')
|
||||
.set('Accept', 'text/html')
|
||||
.expect('default', done);
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
|
||||
var express = require('../')
|
||||
, res = express.response;
|
||||
var express = require('..');
|
||||
var request = require('supertest');
|
||||
|
||||
describe('res', function(){
|
||||
describe('.get(field)', function(){
|
||||
it('should get the response header field', function(){
|
||||
res.setHeader('Content-Type', 'text/x-foo');
|
||||
res.get('Content-Type').should.equal('text/x-foo');
|
||||
res.get('Content-type').should.equal('text/x-foo');
|
||||
res.get('content-type').should.equal('text/x-foo');
|
||||
it('should get the response header field', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.setHeader('Content-Type', 'text/x-foo');
|
||||
res.send(res.get('Content-Type'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(200, 'text/x-foo', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,41 +1,46 @@
|
||||
|
||||
var express = require('../')
|
||||
, res = express.response;
|
||||
var express = require('..');
|
||||
var request = require('supertest');
|
||||
|
||||
describe('res', function(){
|
||||
|
||||
beforeEach(function() {
|
||||
res.removeHeader('link');
|
||||
});
|
||||
|
||||
describe('.links(obj)', function(){
|
||||
it('should set Link header field', function(){
|
||||
res.links({
|
||||
next: 'http://api.example.com/users?page=2',
|
||||
last: 'http://api.example.com/users?page=5'
|
||||
it('should set Link header field', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.links({
|
||||
next: 'http://api.example.com/users?page=2',
|
||||
last: 'http://api.example.com/users?page=5'
|
||||
});
|
||||
res.end();
|
||||
});
|
||||
|
||||
res.get('link')
|
||||
.should.equal(
|
||||
'<http://api.example.com/users?page=2>; rel="next", '
|
||||
+ '<http://api.example.com/users?page=5>; rel="last"');
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Link', '<http://api.example.com/users?page=2>; rel="next", <http://api.example.com/users?page=5>; rel="last"')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should set Link header field for multiple calls', function() {
|
||||
res.links({
|
||||
next: 'http://api.example.com/users?page=2',
|
||||
last: 'http://api.example.com/users?page=5'
|
||||
it('should set Link header field for multiple calls', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.links({
|
||||
next: 'http://api.example.com/users?page=2',
|
||||
last: 'http://api.example.com/users?page=5'
|
||||
});
|
||||
|
||||
res.links({
|
||||
prev: 'http://api.example.com/users?page=1'
|
||||
});
|
||||
|
||||
res.end();
|
||||
});
|
||||
|
||||
res.links({
|
||||
prev: 'http://api.example.com/users?page=1',
|
||||
});
|
||||
|
||||
res.get('link')
|
||||
.should.equal(
|
||||
'<http://api.example.com/users?page=2>; rel="next", '
|
||||
+ '<http://api.example.com/users?page=5>; rel="last", '
|
||||
+ '<http://api.example.com/users?page=1>; rel="prev"');
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Link', '<http://api.example.com/users?page=2>; rel="next", <http://api.example.com/users?page=5>; rel="last", <http://api.example.com/users?page=1>; rel="prev"')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('supertest')
|
||||
, res = express.response;
|
||||
var express = require('..');
|
||||
var request = require('supertest');
|
||||
|
||||
describe('res', function(){
|
||||
describe('.set(field, value)', function(){
|
||||
@@ -18,10 +17,18 @@ describe('res', function(){
|
||||
.end(done);
|
||||
})
|
||||
|
||||
it('should coerce to a string', function(){
|
||||
res.headers = {};
|
||||
res.set('X-Number', 123);
|
||||
res.get('X-Number').should.equal('123');
|
||||
it('should coerce to a string', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.set('X-Number', 123);
|
||||
res.end(typeof res.get('X-Number'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('X-Number', '123')
|
||||
.expect(200, 'string', done);
|
||||
})
|
||||
})
|
||||
|
||||
@@ -39,11 +46,18 @@ describe('res', function(){
|
||||
.expect('["type=ninja","language=javascript"]', done);
|
||||
})
|
||||
|
||||
it('should coerce to an array of strings', function(){
|
||||
res.headers = {};
|
||||
res.set('X-Numbers', [123, 456]);
|
||||
JSON.stringify(res.get('X-Numbers'))
|
||||
.should.equal('["123","456"]');
|
||||
it('should coerce to an array of strings', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.set('X-Numbers', [123, 456]);
|
||||
res.end(JSON.stringify(res.get('X-Numbers')));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('X-Numbers', '123, 456')
|
||||
.expect(200, '["123","456"]', done);
|
||||
})
|
||||
})
|
||||
|
||||
@@ -65,10 +79,18 @@ describe('res', function(){
|
||||
.end(done);
|
||||
})
|
||||
|
||||
it('should coerce to a string', function(){
|
||||
res.headers = {};
|
||||
res.set({ 'X-Number': 123 });
|
||||
res.get('X-Number').should.equal('123');
|
||||
it('should coerce to a string', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.set({ 'X-Number': 123 });
|
||||
res.end(typeof res.get('X-Number'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('X-Number', '123')
|
||||
.expect(200, 'string', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
105
test/res.vary.js
105
test/res.vary.js
@@ -1,55 +1,96 @@
|
||||
|
||||
var express = require('../')
|
||||
, should = require('should');
|
||||
|
||||
function response() {
|
||||
var res = Object.create(express.response);
|
||||
res._headers = {};
|
||||
return res;
|
||||
}
|
||||
var assert = require('assert');
|
||||
var express = require('..');
|
||||
var request = require('supertest');
|
||||
|
||||
describe('res.vary()', function(){
|
||||
describe('with no arguments', function(){
|
||||
it('should not set Vary', function(){
|
||||
var res = response();
|
||||
res.vary();
|
||||
should.not.exist(res.get('Vary'));
|
||||
it('should not set Vary', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.vary();
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(shouldNotHaveHeader('Vary'))
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an empty array', function(){
|
||||
it('should not set Vary', function(){
|
||||
var res = response();
|
||||
res.vary([]);
|
||||
should.not.exist(res.get('Vary'));
|
||||
it('should not set Vary', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.vary([]);
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(shouldNotHaveHeader('Vary'))
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an array', function(){
|
||||
it('should set the values', function(){
|
||||
var res = response();
|
||||
res.vary(['Accept', 'Accept-Language', 'Accept-Encoding']);
|
||||
res.get('Vary').should.equal('Accept, Accept-Language, Accept-Encoding');
|
||||
it('should set the values', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.vary(['Accept', 'Accept-Language', 'Accept-Encoding']);
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Vary', 'Accept, Accept-Language, Accept-Encoding')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a string', function(){
|
||||
it('should set the value', function(){
|
||||
var res = response();
|
||||
res.vary('Accept');
|
||||
res.get('Vary').should.equal('Accept');
|
||||
it('should set the value', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.vary('Accept');
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Vary', 'Accept')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the value is present', function(){
|
||||
it('should not add it again', function(){
|
||||
var res = response();
|
||||
res.vary('Accept');
|
||||
res.vary('Accept-Encoding');
|
||||
res.vary('Accept-Encoding');
|
||||
res.vary('Accept-Encoding');
|
||||
res.vary('Accept');
|
||||
res.get('Vary').should.equal('Accept, Accept-Encoding');
|
||||
it('should not add it again', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.vary('Accept');
|
||||
res.vary('Accept-Encoding');
|
||||
res.vary('Accept-Encoding');
|
||||
res.vary('Accept-Encoding');
|
||||
res.vary('Accept');
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Vary', 'Accept, Accept-Encoding')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function shouldNotHaveHeader(header) {
|
||||
return function (res) {
|
||||
assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user