diff --git a/History.md b/History.md index d8d1d5b2..5df9e78a 100644 --- a/History.md +++ b/History.md @@ -8,7 +8,9 @@ unreleased - use to set headers on successful file transfer * add `mergeParams` option to `Router` - merges `req.params` from parent routes + * add `req.hostname` -- correct name for what `req.host` returns * deprecate things with `depd` module + * deprecate `req.host` -- use `req.hostname` instead * fix behavior when handling request without routes * fix handling when `route.all` is only route * invoke `router.param()` only when route matches diff --git a/lib/request.js b/lib/request.js index e7e7f8e9..514175b0 100644 --- a/lib/request.js +++ b/lib/request.js @@ -330,7 +330,7 @@ defineGetter(req, 'ips', function ips() { defineGetter(req, 'subdomains', function subdomains() { var offset = this.app.get('subdomain offset'); - return (this.host || '') + return (this.hostname || '') .split('.') .reverse() .slice(offset); @@ -348,7 +348,7 @@ defineGetter(req, 'path', function path() { }); /** - * Parse the "Host" header field hostname. + * Parse the "Host" header field to a hostname. * * When the "trust proxy" setting trusts the socket * address, the "X-Forwarded-Host" header field will @@ -358,7 +358,7 @@ defineGetter(req, 'path', function path() { * @api public */ -defineGetter(req, 'host', function host(){ +defineGetter(req, 'hostname', function hostname(){ var trust = this.app.get('trust proxy fn'); var host = this.get('X-Forwarded-Host'); @@ -379,6 +379,12 @@ defineGetter(req, 'host', function host(){ : host; }); +// TODO: change req.host to return host in next major + +defineGetter(req, 'host', deprecate.function(function host(){ + return this.hostname; +}, 'req.host: Use req.hostname instead')); + /** * Check if the request is fresh, aka * Last-Modified and/or the ETag diff --git a/test/req.hostname.js b/test/req.hostname.js new file mode 100644 index 00000000..65c2be81 --- /dev/null +++ b/test/req.hostname.js @@ -0,0 +1,138 @@ + +var express = require('../') + , request = require('supertest') + , assert = require('assert'); + +describe('req', function(){ + describe('.hostname', function(){ + it('should return the Host when present', function(done){ + var app = express(); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .post('/') + .set('Host', 'example.com') + .expect('example.com', done); + }) + + it('should strip port number', function(done){ + var app = express(); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .post('/') + .set('Host', 'example.com:3000') + .expect('example.com', done); + }) + + it('should return undefined otherwise', function(done){ + var app = express(); + + app.use(function(req, res){ + req.headers.host = null; + res.end(String(req.hostname)); + }); + + request(app) + .post('/') + .expect('undefined', done); + }) + + it('should work with IPv6 Host', function(done){ + var app = express(); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .post('/') + .set('Host', '[::1]') + .expect('[::1]', done); + }) + + it('should work with IPv6 Host and port', function(done){ + var app = express(); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .post('/') + .set('Host', '[::1]:3000') + .expect('[::1]', done); + }) + + describe('when "trust proxy" is enabled', function(){ + it('should respect X-Forwarded-Host', function(done){ + var app = express(); + + app.enable('trust proxy'); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .get('/') + .set('Host', 'localhost') + .set('X-Forwarded-Host', 'example.com:3000') + .expect('example.com', done); + }) + + it('should ignore X-Forwarded-Host if socket addr not trusted', function(done){ + var app = express(); + + app.set('trust proxy', '10.0.0.1'); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .get('/') + .set('Host', 'localhost') + .set('X-Forwarded-Host', 'example.com') + .expect('localhost', done); + }) + + it('should default to Host', function(done){ + var app = express(); + + app.enable('trust proxy'); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .get('/') + .set('Host', 'example.com') + .expect('example.com', done); + }) + }) + + describe('when "trust proxy" is disabled', function(){ + it('should ignore X-Forwarded-Host', function(done){ + var app = express(); + + app.use(function(req, res){ + res.end(req.hostname); + }); + + request(app) + .get('/') + .set('Host', 'localhost') + .set('X-Forwarded-Host', 'evil') + .expect('localhost', done); + }) + }) + }) +})