From 3610fdce3612eb27c8c8b8c4f683070d9d32d65d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:32:18 -0500 Subject: [PATCH 01/10] deps: connect@2.29.0 --- History.md | 19 +++++++++++++++++++ package.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index d701954c..fb89295b 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,22 @@ +3.x +=== + + * deps: connect@2.29.0 + - Use `content-type` to parse `Content-Type` headers + - deps: body-parser@~1.12.0 + - deps: compression@~1.4.1 + - deps: connect-timeout@~1.6.0 + - deps: cookie-parser@~1.3.4 + - deps: cookie-signature@1.0.6 + - deps: csurf@~1.7.0 + - deps: errorhandler@~1.3.4 + - deps: express-session@~1.10.3 + - deps: http-errors@~1.3.1 + - deps: response-time@~2.3.0 + - deps: serve-index@~1.6.2 + - deps: serve-static@~1.9.1 + - deps: type-is@~1.6.0 + 3.19.2 / 2015-02-01 =================== diff --git a/package.json b/package.json index e038310f..592d14f9 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ ], "dependencies": { "basic-auth": "1.0.0", - "connect": "2.28.3", + "connect": "2.29.0", "content-disposition": "0.5.0", "commander": "2.6.0", "cookie-signature": "1.0.5", From 829fa34581be0f071433f84518df9d1ee33da82e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:37:28 -0500 Subject: [PATCH 02/10] build: use Travis CI container infrastructure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 1ff243c5..852ac641 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,6 @@ matrix: allow_failures: - node_js: "0.11" fast_finish: true +sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 2ce05047f83697a05043c7b73826cad2f48880cb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:40:51 -0500 Subject: [PATCH 03/10] deps: cookie-signature@1.0.6 --- History.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index fb89295b..3bb53584 100644 --- a/History.md +++ b/History.md @@ -16,6 +16,7 @@ - deps: serve-index@~1.6.2 - deps: serve-static@~1.9.1 - deps: type-is@~1.6.0 + * deps: cookie-signature@1.0.6 3.19.2 / 2015-02-01 =================== diff --git a/package.json b/package.json index 592d14f9..80f38245 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "connect": "2.29.0", "content-disposition": "0.5.0", "commander": "2.6.0", - "cookie-signature": "1.0.5", + "cookie-signature": "1.0.6", "debug": "~2.1.1", "depd": "~1.0.0", "escape-html": "1.0.1", From c2a6c8d3382e9b9ce771b467f0f21910fdd57fe1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:42:02 -0500 Subject: [PATCH 04/10] deps: send@0.12.1 --- History.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 3bb53584..349b925f 100644 --- a/History.md +++ b/History.md @@ -17,6 +17,10 @@ - deps: serve-static@~1.9.1 - deps: type-is@~1.6.0 * deps: cookie-signature@1.0.6 + * deps: send@0.12.1 + - Always read the stat size from the file + - Fix mutating passed-in `options` + - deps: mime@1.3.4 3.19.2 / 2015-02-01 =================== diff --git a/package.json b/package.json index 80f38245..22de15b3 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "parseurl": "~1.3.0", "proxy-addr": "~1.0.6", "range-parser": "~1.0.2", - "send": "0.11.1", + "send": "0.12.1", "utils-merge": "1.0.0", "vary": "~1.0.0", "cookie": "0.1.2", From 69a4869db03c1924cfaeff13147272543e9b2c5f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:43:38 -0500 Subject: [PATCH 05/10] deps: should@~5.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 22de15b3..1e2a7ca5 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "istanbul": "0.3.5", "marked": "0.3.3", "mocha": "~2.1.0", - "should": "~4.6.2", + "should": "~5.0.0", "supertest": "~0.15.0", "hjs": "~0.0.6" }, From f22937f3d158e5fcb194ec201b1a72ff2d84776d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:49:24 -0500 Subject: [PATCH 06/10] Use content-type to parse Content-Type headers --- History.md | 1 + lib/utils.js | 19 ++++++++++++++----- package.json | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/History.md b/History.md index 349b925f..83b8a556 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ 3.x === + * Use `content-type` to parse `Content-Type` headers * deps: connect@2.29.0 - Use `content-type` to parse `Content-Type` headers - deps: body-parser@~1.12.0 diff --git a/lib/utils.js b/lib/utils.js index b9ff7bbd..889b62d5 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,12 +1,19 @@ +/*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ /** * Module dependencies. + * @api private */ +var contentType = require('content-type'); var etag = require('etag'); var mime = require('connect').mime; var proxyaddr = require('proxy-addr'); -var typer = require('media-typer'); /** * toString ref. @@ -393,15 +400,17 @@ exports.compileTrust = function(val) { * @api private */ -exports.setCharset = function(type, charset){ - if (!type || !charset) return type; +exports.setCharset = function setCharset(type, charset) { + if (!type || !charset) { + return type; + } // parse type - var parsed = typer.parse(type); + var parsed = contentType.parse(type); // set charset parsed.parameters.charset = charset; // format type - return typer.format(parsed); + return contentType.format(parsed); }; diff --git a/package.json b/package.json index 1e2a7ca5..e2dca4d9 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "basic-auth": "1.0.0", "connect": "2.29.0", "content-disposition": "0.5.0", + "content-type": "~1.0.1", "commander": "2.6.0", "cookie-signature": "1.0.6", "debug": "~2.1.1", @@ -36,7 +37,6 @@ "escape-html": "1.0.1", "etag": "~1.5.1", "fresh": "0.2.4", - "media-typer": "0.3.0", "methods": "~1.1.1", "mkdirp": "0.5.0", "parseurl": "~1.3.0", From e1057bd7fd485f3ae7f6529ded0353ec78d3bd7d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 22:52:23 -0500 Subject: [PATCH 07/10] build: support Node.js 0.12 closes #2538 --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 852ac641..4af6d31b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,7 @@ language: node_js node_js: - "0.8" - "0.10" - - "0.11" -matrix: - allow_failures: - - node_js: "0.11" - fast_finish: true + - "0.12" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From eaf3318dd39a83ecfa014cbb073883c63f4ef608 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 18 Feb 2015 00:12:28 -0500 Subject: [PATCH 08/10] Generate ETags for all request responses closes #2546 --- History.md | 2 + LICENSE | 2 + lib/response.js | 30 ++++-- test/res.send.js | 257 ++++++++++++++++++++++++----------------------- 4 files changed, 158 insertions(+), 133 deletions(-) diff --git a/History.md b/History.md index 83b8a556..00210c61 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,8 @@ 3.x === + * Generate `ETag`s for all request responses + - No longer restricted to only responses for `GET` and `HEAD` requests * Use `content-type` to parse `Content-Type` headers * deps: connect@2.29.0 - Use `content-type` to parse `Content-Type` headers diff --git a/LICENSE b/LICENSE index d23e93ce..bf9058b4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,8 @@ (The MIT License) Copyright (c) 2009-2013 TJ Holowaychuk +Copyright (c) 2013 Roman Shtylman +Copyright (c) 2014-2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/lib/response.js b/lib/response.js index 9404d34f..08c68f79 100644 --- a/lib/response.js +++ b/lib/response.js @@ -1,5 +1,13 @@ +/*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + /** * Module dependencies. + * @api private */ var contentDisposition = require('content-disposition'); @@ -86,7 +94,6 @@ res.links = function(links){ res.send = function(body){ var req = this.req; - var head = 'HEAD' == req.method; var type; var encoding; var len; @@ -153,12 +160,12 @@ res.send = function(body){ this.set('Content-Length', len); } - // ETag support - var etag = len !== undefined && app.get('etag fn'); - if (etag && ('GET' === req.method || 'HEAD' === req.method)) { - if (!this.get('ETag')) { - etag = etag(body, encoding); - etag && this.set('ETag', etag); + // populate ETag + var etag; + var generateETag = len !== undefined && app.get('etag fn'); + if (typeof generateETag === 'function' && !this.get('ETag')) { + if ((etag = generateETag(body, encoding))) { + this.set('ETag', etag); } } @@ -173,8 +180,13 @@ res.send = function(body){ body = ''; } - // respond - this.end((head ? null : body), encoding); + if (req.method === 'HEAD') { + // skip body for HEAD + this.end(); + } else { + // respond + this.end(body, encoding); + } return this; }; diff --git a/test/res.send.js b/test/res.send.js index ad1a703f..9ad8fd88 100644 --- a/test/res.send.js +++ b/test/res.send.js @@ -1,7 +1,8 @@ -var express = require('../') - , request = require('supertest') - , assert = require('assert'); +var assert = require('assert'); +var express = require('..'); +var methods = require('methods'); +var request = require('supertest'); describe('res', function(){ describe('.send(null)', function(){ @@ -110,10 +111,10 @@ describe('res', function(){ }) }) - it('should set ETag', function(done){ + it('should set ETag', function (done) { var app = express(); - app.use(function(req, res){ + app.use(function (req, res) { var str = Array(1024 * 2).join('-'); res.send(str); }); @@ -121,24 +122,7 @@ describe('res', function(){ request(app) .get('/') .expect('ETag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="') - .end(done); - }) - - it('should not set ETag for non-GET/HEAD', function(done){ - var app = express(); - - app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); - res.send(str); - }); - - request(app) - .post('/') - .end(function(err, res){ - if (err) return done(err); - assert(!res.header.etag, 'has an ETag'); - done(); - }); + .expect(200, done); }) it('should not override Content-Type', function(done){ @@ -199,10 +183,10 @@ describe('res', function(){ }) }) - it('should set ETag', function(done){ + it('should set ETag', function (done) { var app = express(); - app.use(function(req, res){ + app.use(function (req, res) { var str = Array(1024 * 2).join('-'); res.send(new Buffer(str)); }); @@ -210,7 +194,7 @@ describe('res', function(){ request(app) .get('/') .expect('ETag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="') - .end(done); + .expect(200, done); }) it('should not override Content-Type', function(done){ @@ -358,12 +342,12 @@ describe('res', function(){ .expect('{"foo":"bar"}', done); }) - describe('"etag" setting', function(){ - describe('when enabled', function(){ - it('should send ETag', function(done){ + describe('"etag" setting', function () { + describe('when enabled', function () { + it('should send ETag', function (done) { var app = express(); - app.use(function(req, res){ + app.use(function (req, res) { res.send('kajdslfkasdf'); }); @@ -371,76 +355,95 @@ describe('res', function(){ request(app) .get('/') - .expect('etag', 'W/"c-5aee35d8"', done) - }) - - it('should send ETag for empty string response', function(done){ - var app = express() - - app.use(function(req, res){ - res.send('') - }); - - app.enable('etag') - - request(app) - .get('/') - .expect('etag', 'W/"0-0"', done) - }) - - it('should send ETag for long response', function(done){ - var app = express(); - - app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); - res.send(str); - }); - - app.enable('etag'); - - request(app) - .get('/') - .expect('etag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="', done) + .expect('ETag', 'W/"c-5aee35d8"') + .expect(200, done); }); - it('should not override ETag when manually set', function(done){ - var app = express(); + methods.forEach(function (method) { + if (method === 'connect') return; - app.use(function(req, res){ - res.set('etag', '"asdf"'); - res.send(200); - }); + it('should send ETag in response to ' + method.toUpperCase() + ' request', function (done) { + var app = express(); - app.enable('etag'); + app[method]('/', function (req, res) { + res.send('kajdslfkasdf'); + }); - request(app) - .get('/') - .expect('etag', '"asdf"', done) - }); - - it('should not send ETag for res.send()', function(done){ - var app = express() - - app.use(function(req, res){ - res.send() - }); - - app.enable('etag') - - request(app) - .get('/') - .end(function(err, res){ - res.headers.should.not.have.property('etag'); - done(); + request(app) + [method]('/') + .expect('ETag', 'W/"c-5aee35d8"') + .expect(200, done); }) + }); + + it('should send ETag for empty string response', function (done) { + var app = express(); + + app.use(function (req, res) { + res.send(''); + }); + + app.enable('etag'); + + request(app) + .get('/') + .expect('ETag', 'W/"0-0"') + .expect(200, done); + }) + + it('should send ETag for long response', function (done) { + var app = express(); + + app.use(function (req, res) { + var str = Array(1024 * 2).join('-'); + res.send(str); + }); + + app.enable('etag'); + + request(app) + .get('/') + .expect('ETag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="') + .expect(200, done); + }); + + it('should not override ETag when manually set', function (done) { + var app = express(); + + app.use(function (req, res) { + res.set('etag', '"asdf"'); + res.send(200); + }); + + app.enable('etag'); + + request(app) + .get('/') + .expect('ETag', '"asdf"') + .expect(200, done); + }); + + it('should not send ETag for res.send()', function (done) { + var app = express(); + + app.use(function (req, res) { + res.send(); + }); + + app.enable('etag'); + + request(app) + .get('/') + .expect(shouldNotHaveHeader('ETag')) + .expect(200, done); }) }); - describe('when disabled', function(){ - it('should send no ETag', function(done){ + describe('when disabled', function () { + it('should send no ETag', function (done) { var app = express(); - app.use(function(req, res){ + app.use(function (req, res) { var str = Array(1024 * 2).join('-'); res.send(str); }); @@ -449,97 +452,103 @@ describe('res', function(){ request(app) .get('/') - .end(function(err, res){ - res.headers.should.not.have.property('etag'); - done(); - }); + .expect(shouldNotHaveHeader('ETag')) + .expect(200, done); }); - it('should send ETag when manually set', function(done){ + it('should send ETag when manually set', function (done) { var app = express(); app.disable('etag'); - app.use(function(req, res){ + app.use(function (req, res) { res.set('etag', '"asdf"'); res.send(200); }); request(app) .get('/') - .expect('etag', '"asdf"', done) + .expect('ETag', '"asdf"') + .expect(200, done); }); }); - describe('when "strong"', function(){ - it('should send strong ETag', function(done){ - var app = express() + describe('when "strong"', function () { + it('should send strong ETag', function (done) { + var app = express(); app.set('etag', 'strong'); - app.use(function(req, res){ + app.use(function (req, res) { res.send('hello, world!'); }); request(app) .get('/') - .expect('etag', '"Otu60XkfuuPskIiUxJY4cA=="', done) + .expect('ETag', '"Otu60XkfuuPskIiUxJY4cA=="') + .expect(200, done); }) }) - describe('when "weak"', function(){ - it('should send weak ETag', function(done){ - var app = express() + describe('when "weak"', function () { + it('should send weak ETag', function (done) { + var app = express(); app.set('etag', 'weak'); - app.use(function(req, res){ + app.use(function (req, res) { res.send('hello, world!'); }); request(app) .get('/') - .expect('etag', 'W/"d-58988d13"', done) + .expect('ETag', 'W/"d-58988d13"') + .expect(200, done) }) }) - describe('when a function', function(){ - it('should send custom ETag', function(done){ - var app = express() + describe('when a function', function () { + it('should send custom ETag', function (done) { + var app = express(); - app.set('etag', function(body, encoding){ - body.should.equal('hello, world!') - encoding.should.equal('utf8') - return '"custom"' + app.set('etag', function (body, encoding) { + body.should.equal('hello, world!'); + encoding.should.equal('utf8'); + return '"custom"'; }); - app.use(function(req, res){ + app.use(function (req, res) { res.send('hello, world!'); }); request(app) .get('/') - .expect('etag', '"custom"', done) + .expect('ETag', '"custom"') + .expect(200, done); }) - it('should not send falsy ETag', function(done){ - var app = express() + it('should not send falsy ETag', function (done) { + var app = express(); - app.set('etag', function(body, encoding){ - return undefined + app.set('etag', function (body, encoding) { + return undefined; }); - app.use(function(req, res){ + app.use(function (req, res) { res.send('hello, world!'); }); request(app) .get('/') - .end(function(err, res){ - res.headers.should.not.have.property('etag') - done(); - }) + .expect(shouldNotHaveHeader('ETag')) + .expect(200, done); }) }) }) }) + +function shouldNotHaveHeader(header) { + return function (res) { + assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header) + } +} From b40e74d6b6a3c32b9ce1b28ce533e5e322eb502d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 18 Feb 2015 00:59:56 -0500 Subject: [PATCH 09/10] Fix "trust proxy" setting to inherit when app is mounted fixes #2550 fixes #2551 --- History.md | 1 + lib/application.js | 40 +++++++++++++++++- test/app.use.js | 5 ++- test/config.js | 103 ++++++++++++++++++++++++++++++++------------- test/req.ip.js | 17 ++++++++ 5 files changed, 133 insertions(+), 33 deletions(-) diff --git a/History.md b/History.md index 00210c61..ad53053a 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ 3.x === + * Fix `"trust proxy"` setting to inherit when app is mounted * Generate `ETag`s for all request responses - No longer restricted to only responses for `GET` and `HEAD` requests * Use `content-type` to parse `Content-Type` headers diff --git a/lib/application.js b/lib/application.js index 1909fd95..8b287ae5 100644 --- a/lib/application.js +++ b/lib/application.js @@ -1,5 +1,14 @@ +/*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + /** * Module dependencies. + * @api private */ var connect = require('connect') @@ -21,6 +30,13 @@ var merge = require('utils-merge'); var app = exports = module.exports = {}; +/** + * Variable for trust proxy inheritance back-compat + * @api private + */ + +var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default'; + /** * Initialize the server. * @@ -53,14 +69,27 @@ app.defaultConfiguration = function(){ this.set('subdomain offset', 2); this.set('trust proxy', false); + // trust proxy inherit back-compat + Object.defineProperty(this.settings, trustProxyDefaultSymbol, { + configurable: true, + value: true + }); + debug('booting in %s mode', env); // implicit middleware this.use(connect.query()); this.use(middleware.init(this)); - // inherit protos - this.on('mount', function(parent){ + this.on('mount', function onmount(parent) { + // inherit trust proxy + if (this.settings[trustProxyDefaultSymbol] === true + && typeof parent.settings['trust proxy fn'] === 'function') { + delete this.settings['trust proxy']; + delete this.settings['trust proxy fn']; + } + + // inherit protos this.request.__proto__ = parent.request; this.response.__proto__ = parent.response; this.engines.__proto__ = parent.engines; @@ -271,6 +300,13 @@ app.set = function(setting, val){ case 'trust proxy': debug('compile trust proxy %s', val); this.set('trust proxy fn', compileTrust(val)); + + // trust proxy inherit back-compat + Object.defineProperty(this.settings, trustProxyDefaultSymbol, { + configurable: true, + value: false + }); + break; } diff --git a/test/app.use.js b/test/app.use.js index d627bdfe..ab00617e 100644 --- a/test/app.use.js +++ b/test/app.use.js @@ -1,6 +1,7 @@ -var express = require('../') - , request = require('supertest'); +var assert = require('assert'); +var express = require('..'); +var request = require('supertest'); describe('app', function(){ it('should emit "mount" when mounted', function(done){ diff --git a/test/config.js b/test/config.js index 59d38f07..e298e76a 100644 --- a/test/config.js +++ b/test/config.js @@ -1,30 +1,36 @@ -var express = require('../') - , assert = require('assert'); +var assert = require('assert'); +var express = require('..'); -describe('config', function(){ - describe('.set()', function(){ - it('should set a value', function(){ +describe('config', function () { + describe('.set()', function () { + it('should set a value', function () { var app = express(); - app.set('foo', 'bar').should.equal(app); + app.set('foo', 'bar'); + assert.equal(app.get('foo'), 'bar'); }) - it('should return the app when undefined', function(){ + it('should return the app', function () { var app = express(); - app.set('foo', undefined).should.equal(app); + assert.equal(app.set('foo', 'bar'), app); + }) + + it('should return the app when undefined', function () { + var app = express(); + assert.equal(app.set('foo', undefined), app); }) describe('"etag"', function(){ it('should throw on bad value', function(){ - var app = express() - app.set.bind(app, 'etag', 42).should.throw(/unknown value/) + var app = express(); + assert.throws(app.set.bind(app, 'etag', 42), /unknown value/); }) it('should set "etag fn"', function(){ var app = express() var fn = function(){} app.set('etag', fn) - app.get('etag fn').should.equal(fn) + assert.equal(app.get('etag fn'), fn) }) }) @@ -33,7 +39,7 @@ describe('config', function(){ var app = express() var fn = function(){} app.set('trust proxy', fn) - app.get('trust proxy fn').should.equal(fn) + assert.equal(app.get('trust proxy fn'), fn) }) }) }) @@ -41,34 +47,73 @@ describe('config', function(){ describe('.get()', function(){ it('should return undefined when unset', function(){ var app = express(); - assert(undefined === app.get('foo')); + assert.strictEqual(app.get('foo'), undefined); }) it('should otherwise return the value', function(){ var app = express(); app.set('foo', 'bar'); - app.get('foo').should.equal('bar'); + assert.equal(app.get('foo'), 'bar'); }) describe('when mounted', function(){ it('should default to the parent app', function(){ - var app = express() - , blog = express(); + var app = express(); + var blog = express(); app.set('title', 'Express'); app.use(blog); - blog.get('title').should.equal('Express'); + assert.equal(blog.get('title'), 'Express'); }) - + it('should given precedence to the child', function(){ - var app = express() - , blog = express(); + var app = express(); + var blog = express(); app.use(blog); app.set('title', 'Express'); blog.set('title', 'Some Blog'); - blog.get('title').should.equal('Some Blog'); + assert.equal(blog.get('title'), 'Some Blog'); + }) + + it('should inherit "trust proxy" setting', function () { + var app = express(); + var blog = express(); + + function fn() { return false } + + app.set('trust proxy', fn); + assert.equal(app.get('trust proxy'), fn); + assert.equal(app.get('trust proxy fn'), fn); + + app.use(blog); + + assert.equal(blog.get('trust proxy'), fn); + assert.equal(blog.get('trust proxy fn'), fn); + }) + + it('should prefer child "trust proxy" setting', function () { + var app = express(); + var blog = express(); + + function fn1() { return false } + function fn2() { return true } + + app.set('trust proxy', fn1); + assert.equal(app.get('trust proxy'), fn1); + assert.equal(app.get('trust proxy fn'), fn1); + + blog.set('trust proxy', fn2); + assert.equal(blog.get('trust proxy'), fn2); + assert.equal(blog.get('trust proxy fn'), fn2); + + app.use(blog); + + assert.equal(app.get('trust proxy'), fn1); + assert.equal(app.get('trust proxy fn'), fn1); + assert.equal(blog.get('trust proxy'), fn2); + assert.equal(blog.get('trust proxy fn'), fn2); }) }) }) @@ -76,42 +121,42 @@ describe('config', function(){ describe('.enable()', function(){ it('should set the value to true', function(){ var app = express(); - app.enable('tobi').should.equal(app); - app.get('tobi').should.be.true; + assert.equal(app.enable('tobi'), app); + assert.strictEqual(app.get('tobi'), true); }) }) describe('.disable()', function(){ it('should set the value to false', function(){ var app = express(); - app.disable('tobi').should.equal(app); - app.get('tobi').should.be.false; + assert.equal(app.disable('tobi'), app); + assert.strictEqual(app.get('tobi'), false); }) }) describe('.enabled()', function(){ it('should default to false', function(){ var app = express(); - app.enabled('foo').should.be.false; + assert.strictEqual(app.enabled('foo'), false); }) it('should return true when set', function(){ var app = express(); app.set('foo', 'bar'); - app.enabled('foo').should.be.true; + assert.strictEqual(app.enabled('foo'), true); }) }) describe('.disabled()', function(){ it('should default to true', function(){ var app = express(); - app.disabled('foo').should.be.true; + assert.strictEqual(app.disabled('foo'), true); }) it('should return false when set', function(){ var app = express(); app.set('foo', 'bar'); - app.disabled('foo').should.be.false; + assert.strictEqual(app.disabled('foo'), false); }) }) }) diff --git a/test/req.ip.js b/test/req.ip.js index 19d0fee1..3ca575e1 100644 --- a/test/req.ip.js +++ b/test/req.ip.js @@ -35,6 +35,23 @@ describe('req', function(){ .set('X-Forwarded-For', 'client, p1, p2') .expect('p1', done); }) + + it('should return the addr after trusted proxy, from sub app', function (done) { + var app = express(); + var sub = express(); + + app.set('trust proxy', 2); + app.use(sub); + + sub.use(function (req, res, next) { + res.send(req.ip); + }); + + request(app) + .get('/') + .set('X-Forwarded-For', 'client, p1, p2') + .expect(200, 'p1', done); + }) }) describe('when "trust proxy" is disabled', function(){ From 85755e32d9d262db702bee84830462b5275c27e4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 18 Feb 2015 21:25:55 -0500 Subject: [PATCH 10/10] 3.20.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index ad53053a..3a215127 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -3.x -=== +3.20.0 / 2015-02-18 +=================== * Fix `"trust proxy"` setting to inherit when app is mounted * Generate `ETag`s for all request responses diff --git a/package.json b/package.json index e2dca4d9..bc204290 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "express", "description": "Sinatra inspired web development framework", - "version": "3.19.2", + "version": "3.20.0", "author": "TJ Holowaychuk ", "contributors": [ "Aaron Heckmann ",