mirror of
https://github.com/http-party/node-http-proxy.git
synced 2025-12-08 20:59:18 +00:00
[refactor test] Finish removing old test code.
This commit is contained in:
parent
4ae7a5b840
commit
e2dc7f9693
@ -103,14 +103,29 @@ exports.createProxyServer = function (options, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function assignPortsToRoutes (routes)
|
||||
// #### @routes {Object} Routing table to assign ports to
|
||||
//
|
||||
// Assigns dynamic ports to the `routes` for runtime testing.
|
||||
//
|
||||
exports.assignPortsToRoutes = function (routes) {
|
||||
Object.keys(routes).forEach(function (source) {
|
||||
routes[source] = routes[source].replace('{PORT}', helpers.nextPort);
|
||||
});
|
||||
|
||||
return routes;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function parseRoutes (options)
|
||||
// #### @options {Object} Options to use when parsing routes
|
||||
// #### @protocol {string} Protocol to use in the routes
|
||||
// #### @routes {Object} Routes to parse.
|
||||
//
|
||||
// Returns an Array of fully-parsed URLs for the source and
|
||||
// target of `options.routes`.
|
||||
//
|
||||
exports.parseRoutes = function (options) {
|
||||
var protocol = options.protocol || 'http',
|
||||
routes = options.routes;
|
||||
|
||||
@ -9,11 +9,14 @@
|
||||
var assert = require('assert'),
|
||||
async = require('async'),
|
||||
io = require('socket.io'),
|
||||
ws = require('ws'),
|
||||
http = require('./http');
|
||||
|
||||
//
|
||||
// ### function createServerPair (options, callback)
|
||||
// #### @options {Object} Options to create target and proxy server.
|
||||
// #### @target {Object} Options for the target server.
|
||||
// #### @proxy {Object} Options for the proxy server.
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
//
|
||||
// Creates http target and proxy servers
|
||||
@ -24,7 +27,7 @@ exports.createServerPair = function (options, callback) {
|
||||
// 1. Create the target server
|
||||
//
|
||||
function createTarget(next) {
|
||||
exports.createServer(options.target, next);
|
||||
exports.createServer(options.target, next);
|
||||
},
|
||||
//
|
||||
// 2. Create the proxy server
|
||||
@ -35,7 +38,30 @@ exports.createServerPair = function (options, callback) {
|
||||
], callback);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function createServer (options, callback)
|
||||
// #### @options {Object} Options for creating the socket.io or ws server.
|
||||
// #### @raw {boolean} Enables ws.Websocket server.
|
||||
//
|
||||
// Creates a socket.io or ws server using the specified `options`.
|
||||
//
|
||||
exports.createServer = function (options, callback) {
|
||||
return options.raw
|
||||
? exports.createWsServer(options, callback)
|
||||
: exports.createSocketIoServer(options, callback);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function createSocketIoServer (options, callback)
|
||||
// #### @options {Object} Options for creating the socket.io server
|
||||
// #### @port {number} Port to listen on
|
||||
// #### @input {string} Input to expect from the only socket
|
||||
// #### @output {string} Output to send the only socket
|
||||
//
|
||||
// Creates a socket.io server on the specified `options.port` which
|
||||
// will expect `options.input` and then send `options.output`.
|
||||
//
|
||||
exports.createSocketIoServer = function (options, callback) {
|
||||
var server = io.listen(options.port, callback);
|
||||
|
||||
server.sockets.on('connection', function (socket) {
|
||||
@ -46,3 +72,23 @@ exports.createServer = function (options, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function createWsServer (options, callback)
|
||||
// #### @options {Object} Options for creating the ws.Server instance
|
||||
// #### @port {number} Port to listen on
|
||||
// #### @input {string} Input to expect from the only socket
|
||||
// #### @output {string} Output to send the only socket
|
||||
//
|
||||
// Creates a ws.Server instance on the specified `options.port` which
|
||||
// will expect `options.input` and then send `options.output`.
|
||||
//
|
||||
exports.createWsServer = function (options, callback) {
|
||||
var server = new ws.Server({ port: options.port }, callback);
|
||||
|
||||
server.on('connection', function (socket) {
|
||||
socket.on('message', function (data) {
|
||||
assert.equal(data, options.input);
|
||||
socket.send(options.output);
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -72,7 +72,7 @@ vows.describe('node-http-proxy/http/routing-table').addBatch({
|
||||
)
|
||||
], function () {
|
||||
request({
|
||||
uri: 'http://localhost:' + that.port,
|
||||
uri: 'http://127.0.0.1:' + that.port,
|
||||
headers: {
|
||||
host: 'dynamic.com'
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ exports.assertProxied = function (options) {
|
||||
output = options.output || 'hello world from ' + ports.target,
|
||||
req = options.request || {};
|
||||
|
||||
req.uri = req.uri || 'http://localhost:' + ports.proxy;
|
||||
req.uri = req.uri || 'http://127.0.0.1:' + ports.proxy;
|
||||
|
||||
return {
|
||||
topic: function () {
|
||||
@ -79,7 +79,7 @@ exports.assertProxied = function (options) {
|
||||
proxy: {
|
||||
forward: options.forward,
|
||||
target: {
|
||||
host: 'localhost',
|
||||
host: '127.0.0.1',
|
||||
port: ports.target
|
||||
}
|
||||
}
|
||||
@ -110,7 +110,7 @@ exports.assertInvalidProxy = function (options) {
|
||||
var ports = options.ports || helpers.nextPortPair,
|
||||
req = options.request || {};
|
||||
|
||||
req.uri = req.uri || 'http://localhost:' + ports.proxy;
|
||||
req.uri = req.uri || 'http://127.0.0.1:' + ports.proxy;
|
||||
|
||||
return {
|
||||
topic: function () {
|
||||
@ -123,7 +123,7 @@ exports.assertInvalidProxy = function (options) {
|
||||
port: ports.proxy,
|
||||
proxy: {
|
||||
target: {
|
||||
host: 'localhost',
|
||||
host: '127.0.0.1',
|
||||
port: ports.target
|
||||
}
|
||||
}
|
||||
@ -158,13 +158,13 @@ exports.assertForwardProxied = function (options) {
|
||||
"and a valid forward target": exports.assertProxied({
|
||||
forward: {
|
||||
port: forwardPort,
|
||||
host: 'localhost'
|
||||
host: '127.0.0.1'
|
||||
}
|
||||
}),
|
||||
"and an invalid forward target": exports.assertProxied({
|
||||
forward: {
|
||||
port: 9898,
|
||||
host: 'localhost'
|
||||
host: '127.0.0.1'
|
||||
}
|
||||
})
|
||||
};
|
||||
@ -271,7 +271,7 @@ exports.assertProxiedToRoutes = function (options, nested) {
|
||||
"a request to unknown.com": exports.assertRequest({
|
||||
assert: { statusCode: 404 },
|
||||
request: {
|
||||
uri: 'http://localhost:' + port,
|
||||
uri: 'http://127.0.0.1:' + port,
|
||||
headers: {
|
||||
host: 'unknown.com'
|
||||
}
|
||||
@ -285,7 +285,7 @@ exports.assertProxiedToRoutes = function (options, nested) {
|
||||
locations.forEach(function (location) {
|
||||
context[location.source.href] = exports.assertRequest({
|
||||
request: {
|
||||
uri: 'http://localhost:' + port + location.source.path,
|
||||
uri: 'http://127.0.0.1:' + port + location.source.path,
|
||||
headers: {
|
||||
host: location.source.hostname
|
||||
}
|
||||
|
||||
@ -8,15 +8,57 @@
|
||||
|
||||
var assert = require('assert'),
|
||||
io = require('socket.io-client'),
|
||||
WebSocket = require('ws'),
|
||||
helpers = require('../helpers/index');
|
||||
|
||||
//
|
||||
// ### function assertSendRecieve (options)
|
||||
// #### @options {Object} Options for creating this assertion.
|
||||
// #### @raw {boolean} Enables raw `ws.WebSocket`.
|
||||
// #### @uri {string} URI of the proxy server.
|
||||
// #### @input {string} Input to assert sent to the target ws server.
|
||||
// #### @output {string} Output to assert from the taget ws server.
|
||||
//
|
||||
// Creates a `socket.io` or raw `WebSocket` connection and asserts that
|
||||
// `options.input` is sent to and `options.output` is received from the
|
||||
// connection.
|
||||
//
|
||||
exports.assertSendReceive = function (options) {
|
||||
if (!options.raw) {
|
||||
return {
|
||||
topic: function () {
|
||||
var socket = io.connect(options.uri);
|
||||
socket.on('outgoing', this.callback.bind(this, null));
|
||||
socket.emit('incoming', options.input);
|
||||
},
|
||||
"should send input and receive output": function (_, data) {
|
||||
assert.equal(data, options.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
topic: function () {
|
||||
var socket = new WebSocket(options.uri);
|
||||
socket.on('message', this.callback.bind(this, null));
|
||||
socket.on('open', function () {
|
||||
socket.send(options.input);
|
||||
});
|
||||
},
|
||||
"should send input and recieve output": function (_, data, flags) {
|
||||
assert.equal(data, options.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ### function assertProxied (options)
|
||||
// #### @options {Object} Options for this test
|
||||
// #### @latency {number} Latency in milliseconds for the proxy server.
|
||||
// #### @ports {Object} Ports for the request (target, proxy).
|
||||
// #### @input {string} Input to assert sent to the target ws server.
|
||||
// #### @output {string} Output to assert from the taget ws server.
|
||||
// #### @latency {number} Latency in milliseconds for the proxy server.
|
||||
// #### @ports {Object} Ports for the request (target, proxy).
|
||||
// #### @input {string} Input to assert sent to the target ws server.
|
||||
// #### @output {string} Output to assert from the taget ws server.
|
||||
// #### @raw {boolean} Enables raw `ws.Server` usage.
|
||||
//
|
||||
// Creates a complete end-to-end test for requesting against an
|
||||
// http proxy.
|
||||
@ -24,9 +66,14 @@ var assert = require('assert'),
|
||||
exports.assertProxied = function (options) {
|
||||
options = options || {};
|
||||
|
||||
var ports = options.ports || helpers.nextPortPair,
|
||||
input = options.input || 'hello world to ' + ports.target,
|
||||
output = options.output || 'hello world from ' + ports.target;
|
||||
var ports = options.ports || helpers.nextPortPair,
|
||||
input = options.input || 'hello world to ' + ports.target,
|
||||
output = options.output || 'hello world from ' + ports.target,
|
||||
protocol = options.protocol || 'http';
|
||||
|
||||
if (options.raw && !options.protocol) {
|
||||
protocol = 'ws';
|
||||
}
|
||||
|
||||
return {
|
||||
topic: function () {
|
||||
@ -34,29 +81,145 @@ exports.assertProxied = function (options) {
|
||||
target: {
|
||||
input: input,
|
||||
output: output,
|
||||
port: ports.target
|
||||
port: ports.target,
|
||||
raw: options.raw
|
||||
},
|
||||
proxy: {
|
||||
latency: options.latency,
|
||||
port: ports.proxy,
|
||||
proxy: {
|
||||
target: {
|
||||
host: 'localhost',
|
||||
host: '127.0.0.1',
|
||||
port: ports.target
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this.callback);
|
||||
},
|
||||
"the proxy WebSocket": {
|
||||
topic: function () {
|
||||
var socket = io.connect('http://localhost:' + ports.proxy);
|
||||
socket.on('outgoing', this.callback.bind(this, null));
|
||||
socket.emit('incoming', input);
|
||||
},
|
||||
"should send input and receive output": function (_, data) {
|
||||
assert.equal(data, output);
|
||||
}
|
||||
"the proxy Websocket connection": exports.assertSendReceive({
|
||||
uri: protocol + '://127.0.0.1:' + ports.proxy,
|
||||
input: input,
|
||||
output: output,
|
||||
raw: options.raw
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// ### function assertProxiedtoRoutes (options, nested)
|
||||
// #### @options {Object} Options for this ProxyTable-based test
|
||||
// #### @raw {boolean} Enables ws.Server usage.
|
||||
// #### @routes {Object|string} Routes to use for the proxy.
|
||||
// #### @hostnameOnly {boolean} Enables hostnameOnly routing.
|
||||
// #### @nested {Object} Nested vows to add to the returned context.
|
||||
//
|
||||
// Creates a complete end-to-end test for requesting against an
|
||||
// http proxy using `options.routes`:
|
||||
//
|
||||
// 1. Creates target servers for all routes in `options.routes.`
|
||||
// 2. Creates a proxy server.
|
||||
// 3. Ensure Websocket connections to the proxy server for all route targets
|
||||
// can send input and recieve output.
|
||||
//
|
||||
exports.assertProxiedToRoutes = function (options, nested) {
|
||||
//
|
||||
// Assign dynamic ports to the routes to use.
|
||||
//
|
||||
options.routes = helpers.http.assignPortsToRoutes(options.routes);
|
||||
|
||||
//
|
||||
// Parse locations from routes for making assertion requests.
|
||||
//
|
||||
var locations = helpers.http.parseRoutes(options),
|
||||
protocol = options.protocol || 'http',
|
||||
port = helpers.nextPort,
|
||||
context,
|
||||
proxy;
|
||||
|
||||
if (options.raw && !options.protocol) {
|
||||
protocol = 'ws';
|
||||
}
|
||||
|
||||
if (options.filename) {
|
||||
//
|
||||
// If we've been passed a filename write the routes to it
|
||||
// and setup the proxy options to use that file.
|
||||
//
|
||||
fs.writeFileSync(options.filename, JSON.stringify({ router: options.routes }));
|
||||
proxy = { router: options.filename };
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Otherwise just use the routes themselves.
|
||||
//
|
||||
proxy = {
|
||||
hostnameOnly: options.hostnameOnly,
|
||||
router: options.routes
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Create the test context which creates all target
|
||||
// servers for all routes and a proxy server.
|
||||
//
|
||||
context = {
|
||||
topic: function () {
|
||||
var that = this;
|
||||
|
||||
async.waterfall([
|
||||
//
|
||||
// 1. Create all the target servers
|
||||
//
|
||||
async.apply(
|
||||
async.forEach,
|
||||
locations,
|
||||
function createRouteTarget(location, next) {
|
||||
helpers.ws.createServer({
|
||||
raw: options.raw,
|
||||
port: location.target.port,
|
||||
output: 'hello from ' + location.source.href,
|
||||
input: 'hello to ' + location.source.href
|
||||
}, next);
|
||||
}
|
||||
),
|
||||
//
|
||||
// 2. Create the proxy server
|
||||
//
|
||||
async.apply(
|
||||
helpers.http.createProxyServer,
|
||||
{
|
||||
port: port,
|
||||
latency: options.latency,
|
||||
routing: true,
|
||||
proxy: proxy
|
||||
}
|
||||
)
|
||||
], function (_, server) {
|
||||
//
|
||||
// 3. Set the proxy server for later use
|
||||
//
|
||||
that.proxyServer = server;
|
||||
that.callback();
|
||||
});
|
||||
|
||||
//
|
||||
// 4. Assign the port to the context for later use
|
||||
//
|
||||
this.port = port;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Add test assertions for each of the route locations.
|
||||
//
|
||||
locations.forEach(function (location) {
|
||||
context[location.source.href] = exports.assertSendRecieve({
|
||||
uri: protocol + '://127.0.0.1:' + port + location.source.path,
|
||||
output: 'hello from ' + location.source.href,
|
||||
input: 'hello to ' + location.source.href,
|
||||
raw: options.raw
|
||||
});
|
||||
});
|
||||
|
||||
return context;
|
||||
};
|
||||
@ -1,104 +1,25 @@
|
||||
/*
|
||||
node-http-proxy-test.js: http proxy for node.js
|
||||
* routing-tabletest.js: Test for proxying `socket.io` and raw `WebSocket` requests using a ProxyTable.
|
||||
*
|
||||
* (C) 2010 Nodejitsu Inc.
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
Copyright (c) 2010 Charlie Robbins, Marak Squires and Fedor Indutny
|
||||
var vows = require('vows'),
|
||||
macros = require('../macros'),
|
||||
helpers = require('../helpers/index');
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
assert = require('assert'),
|
||||
argv = require('optimist').argv,
|
||||
colors = require('colors'),
|
||||
request = require('request'),
|
||||
vows = require('vows'),
|
||||
websocket = require('../../vendor/websocket'),
|
||||
helpers = require('../helpers');
|
||||
|
||||
try {
|
||||
var utils = require('socket.io/lib/socket.io/utils'),
|
||||
io = require('socket.io');
|
||||
}
|
||||
catch (ex) {
|
||||
console.error('Socket.io is required for this example:');
|
||||
console.error('npm ' + 'install'.green + ' socket.io@0.6.18'.magenta);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var options = helpers.parseProtocol(),
|
||||
testName = [options.source.protocols.ws, options.target.protocols.ws].join('-to-'),
|
||||
runner = new helpers.TestRunner(options);
|
||||
|
||||
vows.describe('node-http-proxy/routing-proxy/' + testName).addBatch({
|
||||
"When using server created by httpProxy.createServer()": {
|
||||
"using proxy table with no latency": {
|
||||
"when an inbound message is sent from a WebSocket client": {
|
||||
topic: function () {
|
||||
var that = this
|
||||
headers = {};
|
||||
|
||||
runner.webSocketTestWithTable({
|
||||
io: io,
|
||||
host: 'localhost',
|
||||
wsprotocol: options.source.protocols.ws,
|
||||
protocol: options.source.protocols.http,
|
||||
router: { 'localhost' : 'localhost:8230' },
|
||||
ports: {
|
||||
target: 8230,
|
||||
proxy: 8231
|
||||
},
|
||||
onListen: function (socket) {
|
||||
socket.on('connection', function (client) {
|
||||
client.on('message', function (msg) {
|
||||
that.callback(null, msg, headers);
|
||||
});
|
||||
});
|
||||
},
|
||||
onWsupgrade: function (req, res) {
|
||||
headers.request = req;
|
||||
headers.response = res.headers;
|
||||
},
|
||||
onOpen: function (ws) {
|
||||
ws.send(utils.encode('from client'));
|
||||
}
|
||||
});
|
||||
},
|
||||
"the target server should receive the message": function (err, msg, headers) {
|
||||
assert.equal(msg, 'from client');
|
||||
},
|
||||
"the origin and sec-websocket-origin headers should match": function (err, msg, headers) {
|
||||
assert.isString(headers.response['sec-websocket-location']);
|
||||
assert.isTrue(headers.response['sec-websocket-location'].indexOf(options.source.protocols.ws) !== -1);
|
||||
assert.equal(headers.request.Origin, headers.response['sec-websocket-origin']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).addBatch({
|
||||
"When the tests are over": {
|
||||
topic: function () {
|
||||
return runner.closeServers();
|
||||
vows.describe('node-http-proxy/ws').addBatch({
|
||||
"With a valid target server": {
|
||||
"and no latency": {
|
||||
"using ws": macros.ws.assertProxied(),
|
||||
"using socket.io": macros.ws.assertProxied({
|
||||
raw: true
|
||||
}),
|
||||
},
|
||||
"the servers should clean up": function () {
|
||||
assert.isTrue(true);
|
||||
}
|
||||
// "and latency": macros.websocket.assertProxied({
|
||||
// latency: 2000
|
||||
// })
|
||||
}
|
||||
}).export(module);
|
||||
}).export(module);
|
||||
@ -10,10 +10,10 @@ var vows = require('vows'),
|
||||
macros = require('../macros'),
|
||||
helpers = require('../helpers/index');
|
||||
|
||||
vows.describe('node-http-proxy/ws').addBatch({
|
||||
vows.describe('node-http-proxy/ws/socket.io').addBatch({
|
||||
"With a valid target server": {
|
||||
"and no latency": macros.ws.assertProxied(),
|
||||
// "and latency": macros.websocket.assertProxied({
|
||||
// "and latency": macros.ws.assertProxied({
|
||||
// latency: 2000
|
||||
// })
|
||||
}
|
||||
|
||||
@ -4,4 +4,20 @@
|
||||
* (C) 2010 Nodejitsu Inc.
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
var vows = require('vows'),
|
||||
macros = require('../macros'),
|
||||
helpers = require('../helpers/index');
|
||||
|
||||
vows.describe('node-http-proxy/ws/WebSocket').addBatch({
|
||||
"With a valid target server": {
|
||||
"and no latency": macros.ws.assertProxied({
|
||||
raw: true
|
||||
}),
|
||||
// "and latency": macros.ws.assertProxied({
|
||||
// raw: true,
|
||||
// latency: 2000
|
||||
// })
|
||||
}
|
||||
}).export(module);
|
||||
Loading…
x
Reference in New Issue
Block a user