New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle missing Host: header #1579
Changes from all commits
823093c
1731031
bdd61a2
2798c5b
4f08f52
de85476
cfbd895
d283256
7fa0290
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
|
||
/** | ||
* Module dependencies. | ||
*/ | ||
|
@@ -445,7 +444,9 @@ req.__defineGetter__('auth', function(){ | |
|
||
req.__defineGetter__('subdomains', function(){ | ||
var offset = this.app.get('subdomain offset'); | ||
return this.get('Host') | ||
var host = this.get('Host'); | ||
if (!host) return []; | ||
return host | ||
.split('.') | ||
.reverse() | ||
.slice(offset); | ||
|
@@ -472,7 +473,10 @@ req.__defineGetter__('path', function(){ | |
req.__defineGetter__('host', function(){ | ||
var trustProxy = this.app.get('trust proxy'); | ||
var host = trustProxy && this.get('X-Forwarded-Host'); | ||
host = host || this.get('Host'); | ||
if (host === false || host === undefined) // If X-Forwarded-Host is present but empty, return it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this doesn't make sense to me, if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The point of these There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but why would you want an empty string? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To make it possible to distinguish between missing headers and empty headers. I don't know how useful that is in practice, but I put it in case people want it. |
||
host = this.get('Host'); | ||
if (host === undefined) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. likewise the host wont be falsey, so just |
||
return null; | ||
return host.split(':')[0]; | ||
}); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
|
||
var express = require('../') | ||
, request = require('./support/http'); | ||
|
||
|
||
describe('req', function(){ | ||
describe('.host', function(){ | ||
describe('when X-Forwarded-Host is present', function(){ | ||
describe('when "trust proxy" is enabled', function(){ | ||
it('should return the forwarded header', function (done){ | ||
var app = express(); | ||
|
||
app.enable('trust proxy'); | ||
|
||
app.use(function (req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('Host', 'proxy.example.com:80') | ||
.set('X-Forwarded-Host', 'example.com:80') | ||
.expect('example.com', done); | ||
}) | ||
|
||
it('should return the forwarded header even if empty', function (done){ | ||
var app = express(); | ||
|
||
app.enable('trust proxy'); | ||
|
||
app.use(function (req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('Host', 'proxy.example.com:80') | ||
.set('X-Forwarded-Host', '') | ||
.expect('', done); | ||
}) | ||
|
||
it('should return null when there are no headers', function (done){ | ||
var app = express(); | ||
|
||
app.enable('trust proxy'); | ||
|
||
app.use(function (req, res, next){ | ||
res.send(JSON.stringify(req.host)); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.unset('Host') | ||
.expect('null', done); | ||
}) | ||
}) | ||
|
||
describe('when "trust proxy" is disabled', function(){ | ||
it('should return null when there is no Host header', function (done){ | ||
var app = express(); | ||
|
||
app.use(function (req, res, next){ | ||
res.send(JSON.stringify(req.host)); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('X-Forwarded-Host', 'example.com:80') | ||
.unset('Host') | ||
.expect('null', done); | ||
}) | ||
|
||
it('should return empty string when there is an empty Host header', function (done){ | ||
var app = express(); | ||
|
||
app.use(function (req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('X-Forwarded-Host', 'example.com:80') | ||
.set('Host', '') | ||
.expect('', done); | ||
}) | ||
|
||
it('should return the actual host address', function(done){ | ||
var app = express(); | ||
|
||
app.use(function(req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('Host', 'proxy.example.com:80') | ||
.set('X-Forwarded-Host', 'example.com:80') | ||
.expect('proxy.example.com', done); | ||
}) | ||
}) | ||
}) | ||
|
||
describe('when X-Forwarded-Host is not present', function (){ | ||
it('should return the domain only', function(done){ | ||
var app = express(); | ||
|
||
app.use(function(req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('Host', 'example.com:8080') | ||
.expect('example.com', done); | ||
}) | ||
|
||
it('should return the domain only even when there is no port', function(done){ | ||
var app = express(); | ||
|
||
app.use(function(req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('Host', 'example.com') | ||
.expect('example.com', done); | ||
}) | ||
|
||
it('should return null when there is no Host header', function (done){ | ||
var app = express(); | ||
|
||
app.use(function(req, res, next){ | ||
res.send(JSON.stringify(req.host)); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.unset('Host') | ||
.expect('null', done); | ||
}) | ||
|
||
it('should return empty string when there is an empty Host header', function (done){ | ||
var app = express(); | ||
|
||
app.use(function (req, res, next){ | ||
res.send(req.host); | ||
}); | ||
|
||
request(app) | ||
.get('/') | ||
.set('Host', '') | ||
.expect('', done); | ||
}) | ||
}) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
|
||
module.exports = require('supertest'); | ||
module.exports = require('supertest'); | ||
module.exports.Test.prototype.unset = function (field) { | ||
this.request().removeHeader(field); | ||
return this; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could use
this.host
here since we already handle itThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; in fact,
subdomains
currently ignorestrust proxy
completely, which is a bug.