Commit 598fe2e3 authored by indexzero's avatar indexzero

[api doc] Rebuilt httpProxy.createServer() with the newer high-level RoutingProxy API

parent 5927ecd6
...@@ -56,12 +56,14 @@ var HttpProxy = exports.HttpProxy = require('./node-http-proxy/http-proxy' ...@@ -56,12 +56,14 @@ var HttpProxy = exports.HttpProxy = require('./node-http-proxy/http-proxy'
// //
exports.createServer = function () { exports.createServer = function () {
var args = Array.prototype.slice.call(arguments), var args = Array.prototype.slice.call(arguments),
handlers = [],
options = {}, options = {},
host, port, message,
server, proxy,
callback,
handler, handler,
silent; server,
proxy,
host,
port;
// //
// Liberally parse arguments of the form: // Liberally parse arguments of the form:
...@@ -75,16 +77,48 @@ exports.createServer = function () { ...@@ -75,16 +77,48 @@ exports.createServer = function () {
case 'string': host = arg; break; case 'string': host = arg; break;
case 'number': port = arg; break; case 'number': port = arg; break;
case 'object': options = arg || {}; break; case 'object': options = arg || {}; break;
case 'function': callback = arg; break; case 'function': handlers.push(arg); break;
}; };
}); });
if (!host && !port && !options) {
// //
// If `host`, `port` and `options` are all not passed, then // Helper function to create intelligent error message(s)
// this server is improperly configured. // for the very liberal arguments parsing performed by
// `require('http-proxy').createServer()`.
// //
throw new Error('Cannot proxy without port, host, or router.') function validArguments() {
var conditions = {
'port and host': function () {
return port && host;
},
'options.target or options.router': function () {
return options && (options.router ||
(options.target && options.target.host && options.target.port));
},
'or proxy handlers': function () {
return handlers && handlers.length;
}
}
var missing = Object.keys(conditions).filter(function (name) {
return !conditions[name]();
});
if (missing.length === 3) {
message = 'Cannot proxy without ' + missing.join(', ');
return false;
}
return true;
}
if (!validArguments()) {
//
// If `host`, `port` and `options` are all not passed (with valid
// options) then this server is improperly configured.
//
throw new Error(message);
return;
} }
// //
...@@ -96,28 +130,57 @@ exports.createServer = function () { ...@@ -96,28 +130,57 @@ exports.createServer = function () {
options.target.port = options.target.port || port; options.target.port = options.target.port || port;
options.target.host = options.target.host || host; options.target.host = options.target.host || host;
if (options.target && options.target.host && options.target.port) {
//
// If an explicit `host` and `port` combination has been passed
// to `.createServer()` then instantiate a hot-path optimized
// `HttpProxy` object and add the "proxy" middleware layer.
//
proxy = new HttpProxy(options);
handlers.push(function (req, res) {
proxy.proxyRequest(req, res);
});
}
else {
//
// If no explicit `host` or `port` combination has been passed then
// we have to assume that this is a "go-anywhere" Proxy (i.e. a `RoutingProxy`).
//
proxy = new RoutingProxy(options);
if (options.router) {
//
// If a routing table has been supplied than we assume
// the user intends us to add the "proxy" middleware layer
// for them
//
handlers.push(function (req, res) {
proxy.proxyRequest(req, res);
});
proxy.on('routes', function (routes) {
server.emit('routes', routes);
});
}
}
// //
// Create the `http[s].Server` instance which will use // Create the `http[s].Server` instance which will use
// an instance of `httpProxy.HttpProxy`. // an instance of `httpProxy.HttpProxy`.
// //
proxy = new HttpProxy(options); handler = handlers.length > 1
handler = callback ? exports.stack(handlers, proxy)
? function (req, res) { callback(req, res, proxy) } : function (req, res) { handlers[0](req, res, proxy) };
: function (req, res) { proxy.proxyRequest(req, res) };
server = options.https server = options.https
? https.createServer(options.https, handler) ? https.createServer(options.https, handler)
: http.createServer(handler); : http.createServer(handler);
//server.on('close', function () { server.on('close', function () {
// proxy.close(); proxy.close();
//});
proxy.on('routes', function (routes) {
server.emit('routes', routes);
}); });
if (!callback) { if (handlers.length <= 1) {
// //
// If an explicit callback has not been supplied then // If an explicit callback has not been supplied then
// automagically proxy the request using the `HttpProxy` // automagically proxy the request using the `HttpProxy`
...@@ -213,6 +276,13 @@ exports.setMaxSockets = function (value) { ...@@ -213,6 +276,13 @@ exports.setMaxSockets = function (value) {
// //
// ### function stack (middlewares, proxy) // ### function stack (middlewares, proxy)
// #### @middlewares {Array} Array of functions to stack.
// #### @proxy {HttpProxy|RoutingProxy} Proxy instance to
// Iteratively build up a single handler to the `http.Server`
// `request` event (i.e. `function (req, res)`) by wrapping
// each middleware `layer` into a `child` middleware which
// is in invoked by the parent (i.e. predecessor in the Array).
//
// adapted from https://github.com/creationix/stack // adapted from https://github.com/creationix/stack
// //
exports.stack = function stack (middlewares, proxy) { exports.stack = function stack (middlewares, proxy) {
...@@ -235,9 +305,18 @@ exports.stack = function stack (middlewares, proxy) { ...@@ -235,9 +305,18 @@ exports.stack = function stack (middlewares, proxy) {
return; return;
} }
if (child) {
child(req, res); child(req, res);
} }
};
//
// Set the prototype of the `next` function to the instance
// of the `proxy` so that in can be used interchangably from
// a `connect` style callback and a true `HttpProxy` object.
//
// e.g. `function (req, res, next)` vs. `function (req, res, proxy)`
//
next.__proto__ = proxy; next.__proto__ = proxy;
layer(req, res, next); layer(req, res, next);
}; };
......
...@@ -671,7 +671,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer) ...@@ -671,7 +671,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
// //
HttpProxy.prototype.close = function () { HttpProxy.prototype.close = function () {
[this.forward, this.target].forEach(function (proxy) { [this.forward, this.target].forEach(function (proxy) {
if (proxy.agent) { if (proxy && proxy.agent) {
proxy.agent.sockets.forEach(function (socket) { proxy.agent.sockets.forEach(function (socket) {
socket.end(); socket.end();
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment