[Pkg-javascript-commits] [node-vhost] 01/02: Imported Upstream version 2.0.0
Leo Iannacone
l3on-guest at moszumanska.debian.org
Sat Jun 14 16:16:10 UTC 2014
This is an automated email from the git hooks/post-receive script.
l3on-guest pushed a commit to branch master
in repository node-vhost.
commit 37d04cdb7307bbaf0a5b0d159528bab54f6c33bf
Author: Leo Iannacone <l3on at ubuntu.com>
Date: Sat Jun 14 18:05:03 2014 +0200
Imported Upstream version 2.0.0
---
.npmignore | 2 +
.travis.yml | 11 +++
HISTORY.md | 15 ++++
README.md | 137 ++++++++++++++++++++++++++++++++
index.js | 179 ++++++++++++++++++++++++++++++++++++++++++
package.json | 25 ++++++
test/test.js | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 621 insertions(+)
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..fcf9ef9
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,2 @@
+coverage/
+test/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..1ff243c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,11 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
+ - "0.11"
+matrix:
+ allow_failures:
+ - node_js: "0.11"
+ fast_finish: true
+script: "npm run-script test-travis"
+after_script: "npm install coveralls at 2.10.0 && cat ./coverage/lcov.info | coveralls"
diff --git a/HISTORY.md b/HISTORY.md
new file mode 100644
index 0000000..848399e
--- /dev/null
+++ b/HISTORY.md
@@ -0,0 +1,15 @@
+2.0.0 / 2014-06-08
+==================
+
+ * Accept `RegExp` object for `hostname`
+ * Provide `req.vhost` object
+ * Remove old invocation of `server.onvhost`
+ * String `hostname` with `*` behaves more like SSL certificates
+ - Matches 1 or more characters instead of zero
+ - No longer matches "." characters
+ * Support IPv6 literal in `Host` header
+
+1.0.0 / 2014-03-05
+==================
+
+ * Genesis from `connect`
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e238daf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,137 @@
+# vhost
+
+[![NPM version](https://badge.fury.io/js/vhost.svg)](http://badge.fury.io/js/vhost)
+[![Build Status](https://travis-ci.org/expressjs/vhost.svg?branch=master)](https://travis-ci.org/expressjs/vhost)
+[![Coverage Status](https://img.shields.io/coveralls/expressjs/vhost.svg?branch=master)](https://coveralls.io/r/expressjs/vhost)
+
+Previously `connect.vhost()`.
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost')
+```
+
+### vhost(hostname, server)
+
+Create a new middleware function to hand off request to `server` when the incoming
+host for the request matches `hostname`.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+// for match of "foo.bar.example.com:8080" against "*.*.example.com":
+req.vhost.host === 'foo.bar.example.com:8080'
+req.vhost.hostname === 'foo.bar.example.com'
+req.vhost.length === 2
+req.vhost[0] === 'foo'
+req.vhost[1] === 'bar'
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect')
+var serveStatic = require('serve-static')
+var vhost = require('vhost')
+
+var mailapp = connect()
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect()
+staticapp.use(serveStatic('public'))
+
+// create main app
+var app = connect()
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp))
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp))
+
+// add middlewares and main usage to app
+
+app.listen(3000)
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect')
+var serveStatic = require('serve-static')
+var vhost = require('vhost')
+
+var mainapp = connect()
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect()
+
+userapp.user(function(req, res, next){
+ var username = req.vhost[0] // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url
+ req.url = '/' + username + req.url
+
+ next()
+})
+userapp.use(serveStatic('public'))
+
+// create main app
+var app = connect()
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp))
+app.use(vhost('www.userpages.local', mainapp))
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp)
+
+app.listen(3000)
+```
+
+## License
+
+The MIT License (MIT)
+
+Copyright (c) 2014 Jonathan Ong me at jongleberry.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..60059e5
--- /dev/null
+++ b/index.js
@@ -0,0 +1,179 @@
+
+/*!
+ * vhost
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * Copyright(c) 2014 Jonathan Ong
+ * MIT Licensed
+ */
+
+/**
+ * vhost:
+ *
+ * Setup vhost for the given `hostname` and `server`.
+ *
+ * connect()
+ * .use(connect.vhost('foo.com', fooApp))
+ * .use(connect.vhost('bar.com', barApp))
+ * .use(connect.vhost('*.com', mainApp))
+ *
+ * The `server` may be a Connect server, a callable function,
+ * or a regular Node `http.Server`.
+ *
+ * @param {string|RegExp} hostname
+ * @param {function|Server} server
+ * @return {Function}
+ * @api public
+ */
+
+module.exports = function vhost(hostname, server){
+ if (!hostname) {
+ throw new TypeError('argument hostname is required')
+ }
+
+ if (!server) {
+ throw new Error('argument server is required')
+ }
+
+ // create a handle for the server
+ var handle = createHandle(server)
+
+ // create regular expression for hostname
+ var regexp = hostregexp(hostname)
+
+ return function vhost(req, res, next){
+ var vhostdata = vhostof(req, regexp)
+
+ if (!vhostdata) {
+ return next()
+ }
+
+ // populate
+ req.vhost = vhostdata
+
+ // handle
+ handle(req, res, next)
+ };
+};
+
+/**
+ * Create handle to server.
+ *
+ * @param {function|Server} server
+ * @return {function}
+ * @api private
+ */
+
+function createHandle(server){
+ if (typeof server === 'function') {
+ // callable servers are the handle
+ return server
+ } else if (typeof server.emit === 'function') {
+ // emit request event on server
+ return function handle(req, res) {
+ server.emit('request', req, res)
+ }
+ }
+
+ throw new TypeError('argument server is unsupported')
+}
+
+/**
+ * Get hostname of request.
+ *
+ * @param (object} req
+ * @return {string}
+ * @api private
+ */
+
+function hostnameof(req){
+ var host = req.headers.host
+
+ if (!host) {
+ return
+ }
+
+ var offset = host[0] === '['
+ ? host.indexOf(']') + 1
+ : 0
+ var index = host.indexOf(':', offset)
+
+ return index !== -1
+ ? host.substring(0, index)
+ : host
+}
+
+/**
+ * Determine if object is RegExp.
+ *
+ * @param (object} val
+ * @return {boolean}
+ * @api private
+ */
+
+function isregexp(val){
+ return Object.prototype.toString.call(val) === '[object RegExp]'
+}
+
+/**
+ * Generate RegExp for given hostname value.
+ *
+ * @param (string|RegExp} val
+ * @api private
+ */
+
+function hostregexp(val){
+ var source = !isregexp(val)
+ ? String(val).replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1').replace(/\*/g, '([^\.]+)')
+ : val.source
+
+ // force leading anchor matching
+ if (source[0] !== '^') {
+ source = '^' + source
+ }
+
+ // force trailing anchor matching
+ source = source.replace(/(\\*)(.)$/, function(s, b, c){
+ return c !== '$' || b.length % 2 === 1
+ ? s + '$'
+ : s
+ })
+
+ return new RegExp(source, 'i')
+}
+
+/**
+ * Get the vhost data of the request for RegExp
+ *
+ * @param (object} req
+ * @param (RegExp} regexp
+ * @return {object}
+ * @api private
+ */
+
+function vhostof(req, regexp){
+ var host = req.headers.host
+ var hostname = hostnameof(req)
+
+ if (!hostname) {
+ return
+ }
+
+ var match = regexp.exec(hostname)
+
+ if (!match) {
+ return
+ }
+
+ var obj = Object.create(null)
+
+ obj.host = host
+ obj.hostname = hostname
+ obj.length = match.length - 1
+
+ for (var i = 1; i < match.length; i++) {
+ obj[i - 1] = match[i]
+ }
+
+ return obj
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d293205
--- /dev/null
+++ b/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "vhost",
+ "description": "virtual domain hosting",
+ "version": "2.0.0",
+ "author": "Jonathan Ong <me at jongleberry.com> (http://jongleberry.com)",
+ "contributors": [
+ "Douglas Christopher Wilson <doug at somethingdoug.com>"
+ ],
+ "license": "MIT",
+ "repository": "expressjs/vhost",
+ "devDependencies": {
+ "istanbul": "0.2.10",
+ "mocha": "~1.20.1",
+ "should": "~4.0.1",
+ "supertest": "~0.13.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ },
+ "scripts": {
+ "test": "mocha --reporter dot test/",
+ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/",
+ "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/"
+ }
+}
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..779606f
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,252 @@
+
+var http = require('http')
+var request = require('supertest')
+var should = require('should')
+var vhost = require('..')
+
+describe('vhost(hostname, server)', function(){
+ it('should route by Host', function(done){
+ var vhosts = []
+
+ vhosts.push(vhost('tobi.com', tobi))
+ vhosts.push(vhost('loki.com', loki))
+
+ var app = createServer(vhosts)
+
+ function tobi(req, res) { res.end('tobi') }
+ function loki(req, res) { res.end('loki') }
+
+ request(app)
+ .get('/')
+ .set('Host', 'tobi.com')
+ .expect(200, 'tobi', done)
+ })
+
+ it('should ignore port in Host', function(done){
+ var app = createServer('tobi.com', function (req, res) {
+ res.end('tobi')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'tobi.com:8080')
+ .expect(200, 'tobi', done)
+ })
+
+ it('should support IPv6 literal in Host', function(done){
+ var app = createServer('[::1]', function (req, res) {
+ res.end('loopback')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', '[::1]:8080')
+ .expect(200, 'loopback', done)
+ })
+
+ it('should 404 unless matched', function(done){
+ var vhosts = []
+
+ vhosts.push(vhost('tobi.com', tobi))
+ vhosts.push(vhost('loki.com', loki))
+
+ var app = createServer(vhosts)
+
+ function tobi(req, res) { res.end('tobi') }
+ function loki(req, res) { res.end('loki') }
+
+ request(app.listen())
+ .get('/')
+ .set('Host', 'ferrets.com')
+ .expect(404, done)
+ })
+
+ it('should 404 without Host header', function(done){
+ var vhosts = []
+
+ vhosts.push(vhost('tobi.com', tobi))
+ vhosts.push(vhost('loki.com', loki))
+
+ var app = createServer(vhosts)
+
+ function tobi(req, res) { res.end('tobi') }
+ function loki(req, res) { res.end('loki') }
+
+ request(app.listen())
+ .get('/')
+ .unset('Host')
+ .expect(404, done)
+ })
+
+ describe('arguments', function(){
+ describe('hostname', function(){
+ it('should be required', function(){
+ vhost.bind().should.throw(/hostname.*required/)
+ })
+
+ it('should accept string', function(){
+ vhost.bind(null, 'loki.com', function(){}).should.not.throw()
+ })
+
+ it('should accept RegExp', function(){
+ vhost.bind(null, /loki\.com/, function(){}).should.not.throw()
+ })
+ })
+
+ describe('server', function(){
+ it('should be required', function(){
+ vhost.bind(null, 'loki.com').should.throw(/server.*required/)
+ })
+
+ it('should accept function', function(){
+ vhost.bind(null, 'loki.com', function(){}).should.not.throw()
+ })
+
+ it('should accept http server', function(){
+ vhost.bind(null, 'loki.com', http.createServer()).should.not.throw()
+ })
+
+ it('should reject plain object', function(){
+ vhost.bind(null, 'loki.com', {}).should.throw(/server.*unsupported/)
+ })
+ })
+ })
+
+ describe('with string hostname', function(){
+ it('should support wildcards', function(done){
+ var app = createServer('*.ferrets.com', function(req, res){
+ res.end('wildcard!')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'loki.ferrets.com')
+ .expect(200, 'wildcard!', done)
+ })
+
+ it('should restrict wildcards to single part', function(done){
+ var app = createServer('*.ferrets.com', function(req, res){
+ res.end('wildcard!')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'foo.loki.ferrets.com')
+ .expect(404, done)
+ })
+
+ it('should treat dot as a dot', function(done){
+ var app = createServer('a.b.com', function(req, res){
+ res.end('tobi')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'aXb.com')
+ .expect(404, done)
+ })
+
+ it('should match entire string', function(done){
+ var app = createServer('.com', function(req, res){
+ res.end('commercial')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'foo.com')
+ .expect(404, done)
+ })
+
+ it('should populate req.vhost', function(done){
+ var app = createServer('user-*.*.com', function(req, res){
+ var keys = Object.keys(req.vhost).sort()
+ var arr = keys.map(function(k){ return [k, req.vhost[k]] })
+ res.end(JSON.stringify(arr))
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'user-bob.foo.com:8080')
+ .expect(200, '[["0","bob"],["1","foo"],["host","user-bob.foo.com:8080"],["hostname","user-bob.foo.com"],["length",2]]', done)
+ })
+ })
+
+ describe('with RegExp hostname', function(){
+ it('should match using RegExp', function(done){
+ var app = createServer(/[tl]o[bk]i\.com/, function(req, res){
+ res.end('tobi')
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'toki.com')
+ .expect(200, 'tobi', done)
+ })
+
+ it('should match entire hostname', function(done){
+ var vhosts = []
+
+ vhosts.push(vhost(/\.tobi$/, tobi))
+ vhosts.push(vhost(/^loki\./, loki))
+
+ var app = createServer(vhosts)
+
+ function tobi(req, res) { res.end('tobi') }
+ function loki(req, res) { res.end('loki') }
+
+ request(app)
+ .get('/')
+ .set('Host', 'loki.tobi.com')
+ .expect(404, done)
+ })
+
+ it('should populate req.vhost', function(done){
+ var app = createServer(/user-(bob|joe)\.([^\.]+)\.com/, function(req, res){
+ var keys = Object.keys(req.vhost).sort()
+ var arr = keys.map(function(k){ return [k, req.vhost[k]] })
+ res.end(JSON.stringify(arr))
+ })
+
+ request(app)
+ .get('/')
+ .set('Host', 'user-bob.foo.com:8080')
+ .expect(200, '[["0","bob"],["1","foo"],["host","user-bob.foo.com:8080"],["hostname","user-bob.foo.com"],["length",2]]', done)
+ })
+ })
+
+ describe('server', function(){
+ it('should support http.Servers', function(done){
+ var loki = http.createServer(function(req, res){ res.end('loki') })
+ var app = createServer('loki.com', loki)
+
+ request(app)
+ .get('/')
+ .set('Host', 'loki.com')
+ .expect('loki', done)
+ })
+ })
+})
+
+function createServer(hostname, server) {
+ var vhosts = !Array.isArray(hostname)
+ ? [vhost(hostname, server)]
+ : hostname
+
+ return http.createServer(function onRequest(req, res) {
+ var index = 0
+
+ function next(err) {
+ var vhost = vhosts[index++]
+
+ if (!vhost || err) {
+ res.statusCode = err ? (err.status || 500) : 404
+ res.end(err ? err.message : 'oops')
+ return
+ }
+
+ vhost(req, res, next)
+ }
+
+ next()
+ })
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-vhost.git
More information about the Pkg-javascript-commits
mailing list