Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 58 additions & 50 deletions lib/node-http-proxy/http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ var HttpProxy = exports.HttpProxy = function (options) {
if (!options || !options.target) {
throw new Error('Both `options` and `options.target` are required.');
}

events.EventEmitter.call(this);

var self = this;

//
// Setup basic proxying options:
//
// Setup basic proxying options:
//
// * forward {Object} Options for a forward-proxy (if-any)
// * target {Object} Options for the **sole** proxy target of this instance
//
Expand All @@ -69,23 +69,23 @@ var HttpProxy = exports.HttpProxy = function (options) {
//
// Setup the necessary instances instance variables for
// the `target` and `forward` `host:port` combinations
// used by this instance.
// used by this instance.
//
// * agent {http[s].Agent} Agent to be used by this instance.
// * protocol {http|https} Core node.js module to make requests with.
// * base {Object} Base object to create when proxying containing any https settings.
//
//
function setupProxy (key) {
self[key].agent = httpProxy._getAgent(self[key]);
self[key].protocol = httpProxy._getProtocol(self[key]);
self[key].base = httpProxy._getBase(self[key]);
self[key].base = httpProxy._getBase(self[key]);
}

setupProxy('target');
if (this.forward) {
setupProxy('forward');
if (this.forward) {
setupProxy('forward');
}

//
// Setup opt-in features
//
Expand All @@ -103,7 +103,7 @@ var HttpProxy = exports.HttpProxy = function (options) {
//
this.source = options.source || { host: 'localhost', port: 8000 };
this.source.https = this.source.https || options.https;
this.changeOrigin = options.changeOrigin || false;
this.changeOrigin = options.changeOrigin || false;
};

// Inherit from events.EventEmitter
Expand All @@ -116,14 +116,14 @@ util.inherits(HttpProxy, events.EventEmitter);
// #### @buffer {Object} Result from `httpProxy.buffer(req)`
//
HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
var self = this,
var self = this,
errState = false,
outgoing = new(this.target.base),
reverseProxy;

//
// Add common proxy headers to the request so that they can
// be availible to the proxy target server. If the proxy is
// be availible to the proxy target server. If the proxy is
// part of proxy chain it will append the address:
//
// * `x-forwarded-for`: IP Address of the original request
Expand All @@ -134,23 +134,23 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
if (req.headers['x-forwarded-for']){
var addressToAppend = "," + req.connection.remoteAddress || req.socket.remoteAddress;
req.headers['x-forwarded-for'] += addressToAppend;
}
}
else {
req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.socket.remoteAddress;
}

if (req.headers['x-forwarded-port']){
var portToAppend = "," + req.connection.remotePort || req.socket.remotePort;
req.headers['x-forwarded-port'] += portToAppend;
}
}
else {
req.headers['x-forwarded-port'] = req.connection.remotePort || req.socket.remotePort;
}

if (req.headers['x-forwarded-proto']){
var protoToAppend = "," + req.connection.pair ? 'https' : 'http';
req.headers['x-forwarded-proto'] += protoToAppend;
}
}
else {
req.headers['x-forwarded-proto'] = req.connection.pair ? 'https' : 'http';
}
Expand Down Expand Up @@ -217,7 +217,15 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
outgoing.headers = req.headers;

//
// Open new HTTP request to internal resource with will act
// If the changeOrigin option is specified, change the
// origin of the host header to the target URL! Please
// don't revert this without documenting it!
//
if(this.changeOrigin)
outgoing.headers.host = this.target.host + ':' + this.target.port;

//
// Open new HTTP request to internal resource with will act
// as a reverse proxy pass
//
reverseProxy = this.target.protocol.request(outgoing, function (response) {
Expand Down Expand Up @@ -286,10 +294,10 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
ended = true
if (!errState) {
reverseProxy.removeListener('error', proxyError);

try { res.end() }
catch (ex) { console.error("res.end error: %s", ex.message) }

// Emit the `end` event now that we have completed proxying
self.emit('end', req, res);
}
Expand All @@ -313,19 +321,19 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
// `req` write it to the `reverseProxy` request.
//
req.on('data', function (chunk) {

if (!errState) {
var flushed = reverseProxy.write(chunk);
if (!flushed) {
req.pause();
reverseProxy.once('drain', function () {
try { req.resume() }
try { req.resume() }
catch (er) { console.error("req.resume error: %s", er.message) }
});

//
// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//
setTimeout(function () {
reverseProxy.emit('drain');
Expand Down Expand Up @@ -367,7 +375,7 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
// #### @socket {net.Socket} Socket for the underlying HTTP request
// #### @head {string} Headers for the Websocket request.
// #### @buffer {Object} Result from `httpProxy.buffer(req)`
// Performs a WebSocket proxy operation to the location specified by
// Performs a WebSocket proxy operation to the location specified by
// `this.target`.
//
HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer) {
Expand All @@ -387,10 +395,10 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
//
return socket.destroy();
}

//
// Add common proxy headers to the request so that they can
// be availible to the proxy target server. If the proxy is
// be availible to the proxy target server. If the proxy is
// part of proxy chain it will append the address:
//
// * `x-forwarded-for`: IP Address of the original request
Expand All @@ -401,23 +409,23 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
if (req.headers['x-forwarded-for']){
var addressToAppend = "," + req.connection.remoteAddress || req.connection.socket.remoteAddress;
req.headers['x-forwarded-for'] += addressToAppend;
}
}
else {
req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.connection.socket.remoteAddress;
}

if (req.headers['x-forwarded-port']){
var portToAppend = "," + req.connection.remotePort || req.connection.socket.remotePort;
req.headers['x-forwarded-port'] += portToAppend;
}
}
else {
req.headers['x-forwarded-port'] = req.connection.remotePort || req.connection.socket.remotePort;
}

if (req.headers['x-forwarded-proto']){
var protoToAppend = "," + req.connection.pair ? 'wss' : 'ws';
req.headers['x-forwarded-proto'] += protoToAppend;
}
}
else {
req.headers['x-forwarded-proto'] = req.connection.pair ? 'wss' : 'ws';
}
Expand All @@ -432,7 +440,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
function _socket(socket, keepAlive) {
socket.setTimeout(0);
socket.setNoDelay(true);

if (keepAlive) {
if (socket.setKeepAlive) {
socket.setKeepAlive(true, 0);
Expand All @@ -445,7 +453,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
socket.setEncoding('utf8');
}
}

//
// Setup the incoming client socket.
//
Expand Down Expand Up @@ -474,13 +482,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
if (!flushed) {
proxySocket.pause();
reverseProxy.incoming.socket.once('drain', function () {
try { proxySocket.resume() }
try { proxySocket.resume() }
catch (er) { console.error("proxySocket.resume error: %s", er.message) }
});

//
// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//
setTimeout(function () {
reverseProxy.incoming.socket.emit('drain');
Expand All @@ -506,13 +514,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
if (!flushed) {
reverseProxy.incoming.socket.pause();
proxySocket.once('drain', function () {
try { reverseProxy.incoming.socket.resume() }
try { reverseProxy.incoming.socket.resume() }
catch (er) { console.error("reverseProxy.incoming.socket.resume error: %s", er.message) }
});

//
// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//
setTimeout(function () {
proxySocket.emit('drain');
Expand Down Expand Up @@ -572,7 +580,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
protocolName = this.target.https ? 'https' : 'http',
portUri = getPort(this.source.port),
remoteHost = this.target.host + portUri;

//
// Change headers (if requested).
//
Expand All @@ -591,7 +599,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
outgoing.path = req.url;
outgoing.headers = req.headers;
outgoing.agent = agent;

var reverseProxy = this.target.protocol.request(outgoing);

//
Expand Down Expand Up @@ -678,13 +686,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
if (!flushed) {
revSocket.pause();
socket.once('drain', function () {
try { revSocket.resume() }
try { revSocket.resume() }
catch (er) { console.error("reverseProxy.socket.resume error: %s", er.message) }
});

//
// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//
setTimeout(function () {
socket.emit('drain');
Expand All @@ -693,7 +701,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
}
catch (ex) {
//
// Remove data listener on socket error because the
// Remove data listener on socket error because the
// 'handshake' has failed.
//
revSocket.removeListener('data', handshake);
Expand All @@ -714,8 +722,8 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)

try {
//
// Attempt to write the upgrade-head to the reverseProxy
// request. This is small, and there's only ever one of
// Attempt to write the upgrade-head to the reverseProxy
// request. This is small, and there's only ever one of
// it; no need for pause/resume.
//
// XXX This is very wrong and should be fixed in node's core
Expand Down Expand Up @@ -763,7 +771,7 @@ HttpProxy.prototype.close = function () {
// by `this.forward` ignoring errors and the subsequent response.
//
HttpProxy.prototype._forwardRequest = function (req) {
var self = this,
var self = this,
outgoing = new(this.forward.base),
forwardProxy;

Expand All @@ -778,7 +786,7 @@ HttpProxy.prototype._forwardRequest = function (req) {
outgoing.headers = req.headers;

//
// Open new HTTP request to internal resource with will
// Open new HTTP request to internal resource with will
// act as a reverse proxy pass.
//
forwardProxy = this.forward.protocol.request(outgoing, function (response) {
Expand All @@ -805,13 +813,13 @@ HttpProxy.prototype._forwardRequest = function (req) {
if (!flushed) {
req.pause();
forwardProxy.once('drain', function () {
try { req.resume() }
try { req.resume() }
catch (er) { console.error("req.resume error: %s", er.message) }
});

//
// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//
setTimeout(function () {
forwardProxy.emit('drain');
Expand All @@ -820,7 +828,7 @@ HttpProxy.prototype._forwardRequest = function (req) {
});

//
// At the end of the client request, we are going to
// At the end of the client request, we are going to
// stop the proxied request
//
req.on('end', function () {
Expand Down
4 changes: 2 additions & 2 deletions lib/node-http-proxy/proxy-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ ProxyTable.prototype.getProxyLocation = function (req) {
var route = this.routes[i];
if (target.match(route.route)) {
var pathSegments = route.path.split('/');

if (pathSegments.length > 1) {
// don't include the proxytable path segments in the proxied request url
pathSegments = new RegExp("/" + pathSegments.slice(1).join('/'));
req.url = req.url.replace(pathSegments, '');
}

var location = route.target.split(':'),
host = location[0],
port = location.length === 1 ? 80 : location[1];
Expand Down
Loading