Skip to content
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ property will be populated with an object. This object will have numeric propert
corresponding to each wildcard (or capture group if RegExp object provided) and the
`hostname` that was matched.

Where the `hostname` of the request comes from depends on the type of server you're running.
If you're running a raw Node.js/connect server, this comes from [`req.headers.host`](https://nodejs.org/dist/latest/docs/api/http.html#http_message_headers).
If you're running an express v3 server, this comes from [`req.host`](http://expressjs.com/en/3x/api.html#req.host).
If you're running an express v4 server, this comes from [`req.hostname`](http://expressjs.com/en/4x/api.html#req.hostname).

```js
// for match of "foo.bar.example.com:8080" against "*.*.example.com":
req.vhost.host === 'foo.bar.example.com:8080'
Expand Down
4 changes: 3 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ function vhost (hostname, handle) {
*/

function hostnameof (req) {
var host = req.headers.host
var host = req.hostname || // express v4
req.host || // express v3
req.headers.host // http

if (!host) {
return
Expand Down
100 changes: 98 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

var assert = require('assert')
var http = require('http')
var request = require('supertest')
Expand All @@ -22,6 +21,48 @@ describe('vhost(hostname, server)', function () {
.expect(200, 'tobi', done)
})

it('should route by `req.hostname` (express v4)', function (done) {
var vhosts = []

vhosts.push(vhost('anotherhost.com', anotherhost))
vhosts.push(vhost('loki.com', loki))

var app = createServer(vhosts)

app.on('request', function (req) {
req.hostname = 'anotherhost.com'
})

function anotherhost (req, res) { res.end('anotherhost') }
function loki (req, res) { res.end('loki') }

request(app)
.get('/')
.set('Host', 'tobi.com')
.expect(200, 'anotherhost', done)
})

it('should route by `req.host` (express v3)', function (done) {
var vhosts = []

vhosts.push(vhost('anotherhost.com', anotherhost))
vhosts.push(vhost('loki.com', loki))

var app = createServer(vhosts)

app.on('request', function (req) {
req.host = 'anotherhost.com'
})

function anotherhost (req, res) { res.end('anotherhost') }
function loki (req, res) { res.end('loki') }

request(app)
.get('/')
.set('Host', 'tobi.com')
.expect(200, 'anotherhost', done)
})

it('should ignore port in Host', function (done) {
var app = createServer('tobi.com', function (req, res) {
res.end('tobi')
Expand All @@ -44,6 +85,59 @@ describe('vhost(hostname, server)', function () {
.expect(200, 'loopback', done)
})

it('should support IPv6 literal in Host with no port', function (done) {
var app = createServer('[::1]', function (req, res) {
res.end('loopback')
})

request(app)
.get('/')
.set('Host', '::1')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a valid Host header. Don't need to test that, imo.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, from briefly reading the ipv6 wiki page i falsely assumed that they didnt need to have square brackets if there was no port.

.expect(200, 'loopback', done)
})

it('should support IPv6 literal in `req.host` with port (express v5)', function (done) {
var app = createServer('[::1]', function (req, res) {
res.end('loopback')
})

app.on('request', function (req) {
req.host = '[::1]:8080'
})

request(app)
.get('/')
.expect(200, 'loopback', done)
})

it('should support IPv6 literal in `req.hostname` (express v4)', function (done) {
var app = createServer('[::1]', function (req, res) {
res.end('loopback')
})

app.on('request', function (req) {
req.hostname = '::1'
})

request(app)
.get('/')
.expect(200, 'loopback', done)
})

it('should support IPv6 literal in `req.host` without port (express v3)', function (done) {
var app = createServer('[::1]', function (req, res) {
res.end('loopback')
})

app.on('request', function (req) {
req.host = '::1'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a valid req.host.

})

request(app)
.get('/')
.expect(200, 'loopback', done)
})

it('should 404 unless matched', function (done) {
var vhosts = []

Expand Down Expand Up @@ -231,6 +325,8 @@ function createServer (hostname, server) {
vhost(req, res, next)
}

next()
// Running tests on next tick so we can modify the request object via
// the `request` event on http.Server
process.nextTick(next)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be done some different way.

})
}