Skip to content

Commit

Permalink
[api doc] Rebuilt httpProxy.createServer() with the newer high-level …
Browse files Browse the repository at this point in the history
…RoutingProxy API
  • Loading branch information
indexzero committed Sep 9, 2011
1 parent 5927ecd commit 598fe2e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 24 deletions.
File renamed without changes.
125 changes: 102 additions & 23 deletions lib/node-http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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`
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
};
Expand Down
2 changes: 1 addition & 1 deletion lib/node-http-proxy/http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down

0 comments on commit 598fe2e

Please sign in to comment.