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'
//
exports.createServer = function () {
var args = Array.prototype.slice.call(arguments),
handlers = [],
options = {},
host, port,
server, proxy,
callback,
message,
handler,
silent;
server,
proxy,
host,
port;
//
// Liberally parse arguments of the form:
......@@ -75,18 +77,50 @@ exports.createServer = function () {
case 'string': host = arg; break;
case 'number': port = arg; break;
case 'object': options = arg || {}; break;
case 'function': callback = arg; break;
case 'function': handlers.push(arg); break;
};
});
if (!host && !port && !options) {
//
// Helper function to create intelligent error message(s)
// for the very liberal arguments parsing performed by
// `require('http-proxy').createServer()`.
//
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, then
// this server is improperly configured.
// If `host`, `port` and `options` are all not passed (with valid
// options) then this server is improperly configured.
//
throw new Error('Cannot proxy without port, host, or router.')
throw new Error(message);
return;
}
//
// Hoist up any explicit `host` or `port` arguments
// that have been passed in to the options we will
......@@ -96,28 +130,57 @@ exports.createServer = function () {
options.target.port = options.target.port || port;
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
// an instance of `httpProxy.HttpProxy`.
//
proxy = new HttpProxy(options);
handler = callback
? function (req, res) { callback(req, res, proxy) }
: function (req, res) { proxy.proxyRequest(req, res) };
handler = handlers.length > 1
? exports.stack(handlers, proxy)
: function (req, res) { handlers[0](req, res, proxy) };
server = options.https
? https.createServer(options.https, handler)
: http.createServer(handler);
//server.on('close', function () {
// proxy.close();
//});
proxy.on('routes', function (routes) {
server.emit('routes', routes);
server.on('close', function () {
proxy.close();
});
if (!callback) {
if (handlers.length <= 1) {
//
// If an explicit callback has not been supplied then
// automagically proxy the request using the `HttpProxy`
......@@ -213,6 +276,13 @@ exports.setMaxSockets = function (value) {
//
// ### 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
//
exports.stack = function stack (middlewares, proxy) {
......@@ -235,9 +305,18 @@ exports.stack = function stack (middlewares, proxy) {
return;
}
child(req, res);
}
if (child) {
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;
layer(req, res, next);
};
......
......@@ -671,7 +671,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
//
HttpProxy.prototype.close = function () {
[this.forward, this.target].forEach(function (proxy) {
if (proxy.agent) {
if (proxy && proxy.agent) {
proxy.agent.sockets.forEach(function (socket) {
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