Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

http-proxy

Package Overview
Dependencies
Maintainers
3
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http-proxy - npm Package Compare versions

Comparing version 0.8.1 to 0.8.2

.travis.yml

81

lib/node-http-proxy.js

@@ -82,5 +82,5 @@ /*

case 'function': callback = arg; handlers.push(callback); break;
};
}
});
//

@@ -94,6 +94,6 @@ // Helper function to create intelligent error message(s)

'port and host': function () {
return port && host;
return port && host;
},
'options.target or options.router': function () {
return options && (options.router ||
return options && (options.router ||
(options.target && options.target.host && options.target.port));

@@ -104,8 +104,8 @@ },

}
}
};
var missing = Object.keys(conditions).filter(function (name) {
return !conditions[name]();
});
if (missing.length === 3) {

@@ -115,13 +115,12 @@ message = 'Cannot proxy without ' + missing.join(', ');

}
return true;
}
}
if (!validArguments()) {
//
// If `host`, `port` and `options` are all not passed (with valid
// If `host`, `port` and `options` are all not passed (with valid
// options) then this server is improperly configured.
//
throw new Error(message);
return;
}

@@ -137,3 +136,3 @@

options.target.host = options.target.host || host;
if (options.target && options.target.host && options.target.port) {

@@ -156,8 +155,8 @@ //

proxy = new RoutingProxy(options);
if (options.router) {
//
// If a routing table has been supplied than we assume
// If a routing table has been supplied than we assume
// the user intends us to add the "proxy" middleware layer
// for them
// for them
//

@@ -167,9 +166,9 @@ handlers.push(function (req, res) {

});
proxy.on('routes', function (routes) {
server.emit('routes', routes);
});
}
}
}
//

@@ -179,6 +178,6 @@ // Create the `http[s].Server` instance which will use

//
handler = handlers.length > 1
handler = handlers.length > 1
? exports.stack(handlers, proxy)
: function (req, res) { handlers[0](req, res, proxy) };
server = options.https

@@ -195,4 +194,4 @@ ? https.createServer(options.https, handler)

// If an explicit callback has not been supplied then
// automagically proxy the request using the `HttpProxy`
// instance we have created.
// automagically proxy the request using the `HttpProxy`
// instance we have created.
//

@@ -234,3 +233,3 @@ server.on('upgrade', function (req, socket, head) {

var events = [],
onData,
onData,
onEnd;

@@ -253,7 +252,7 @@

this.end();
this.resume = function () {
console.error("Cannot resume buffer after destroying it.");
};
onData = onEnd = events = obj = null;
this.resume = function () {
console.error("Cannot resume buffer after destroying it.");
};
onData = onEnd = events = obj = null;
},

@@ -292,6 +291,6 @@ resume: function () {

// #### @middlewares {Array} Array of functions to stack.
// #### @proxy {HttpProxy|RoutingProxy} Proxy instance to
// #### @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
// each middleware `layer` into a `child` middleware which
// is in invoked by the parent (i.e. predecessor in the Array).

@@ -310,3 +309,3 @@ //

res.destroy();
}
}
else {

@@ -317,7 +316,7 @@ res.statusCode = 500;

}
console.error('Error in middleware(s): %s', err.stack);
return;
}
if (child) {

@@ -361,3 +360,3 @@ child(req, res);

}
if (!options.port) {

@@ -370,4 +369,4 @@ options.port = options.https ? 443 : 80;

agent = new Agent({
host: options.host,
agent = new Agent({
host: options.host,
port: options.port

@@ -379,3 +378,3 @@ });

return agent;
}
};

@@ -385,4 +384,4 @@ //

// #### @options {Object} Options for the proxy target.
// Returns the appropriate node.js core protocol module (i.e. `http` or `https`)
// based on the `options` supplied.
// Returns the appropriate node.js core protocol module (i.e. `http` or `https`)
// based on the `options` supplied.
//

@@ -403,3 +402,3 @@ exports._getProtocol = function _getProtocol (options) {

var result = function () {};
if (options.https && typeof options.https === 'object') {

@@ -406,0 +405,0 @@ ['ca', 'cert', 'key'].forEach(function (key) {

@@ -55,10 +55,10 @@ /*

}
events.EventEmitter.call(this);
var self = this;
//
// Setup basic proxying options:
//
// Setup basic proxying options:
//
// * forward {Object} Options for a forward-proxy (if-any)

@@ -73,3 +73,3 @@ // * target {Object} Options for the **sole** proxy target of this instance

// the `target` and `forward` `host:port` combinations
// used by this instance.
// used by this instance.
//

@@ -79,14 +79,14 @@ // * agent {http[s].Agent} Agent to be used by this instance.

// * 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');
}
//

@@ -109,3 +109,3 @@ // Setup opt-in features

this.source.https = this.source.https || options.https;
this.changeOrigin = options.changeOrigin || false;
this.changeOrigin = options.changeOrigin || false;
};

@@ -123,3 +123,3 @@

HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
var self = this,
var self = this,
errState = false,

@@ -131,3 +131,3 @@ outgoing = new(this.target.base),

// 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:

@@ -143,3 +143,3 @@ //

req.headers['x-forwarded-for'] += addressToAppend;
}
}
else {

@@ -152,3 +152,3 @@ req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.socket.remoteAddress;

req.headers['x-forwarded-port'] += portToAppend;
}
}
else {

@@ -159,5 +159,5 @@ req.headers['x-forwarded-port'] = req.connection.remotePort || req.socket.remotePort;

if (req.headers['x-forwarded-proto']){
var protoToAppend = "," + (req.connection.pair) ? 'https' : 'http';
var protoToAppend = "," + (req.connection.pair ? 'https' : 'http');
req.headers['x-forwarded-proto'] += protoToAppend;
}
}
else {

@@ -221,11 +221,21 @@ req.headers['x-forwarded-proto'] = req.connection.pair ? 'https' : 'http';

//
outgoing.host = this.target.host;
outgoing.port = this.target.port;
outgoing.agent = this.target.agent;
outgoing.method = req.method;
outgoing.path = req.url;
outgoing.headers = req.headers;
outgoing.host = this.target.host;
outgoing.hostname = this.target.hostname;
outgoing.port = this.target.port;
outgoing.agent = this.target.agent;
outgoing.method = req.method;
outgoing.path = req.url;
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

@@ -291,14 +301,15 @@ //

//
var ended = false
var ended = false;
response.on('close', function () {
if(!ended) response.emit('end')
})
if (!ended) { response.emit('end') }
});
response.on('end', function () {
ended = true
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

@@ -327,3 +338,3 @@ self.emit('end', req, res);

req.on('data', function (chunk) {
if (!errState) {

@@ -334,9 +345,9 @@ var flushed = reverseProxy.write(chunk);

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.
//

@@ -383,3 +394,3 @@ setTimeout(function () {

// #### @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`.

@@ -404,6 +415,6 @@ //

}
//
// 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:

@@ -419,3 +430,3 @@ //

req.headers['x-forwarded-for'] += addressToAppend;
}
}
else {

@@ -428,3 +439,3 @@ req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.connection.socket.remoteAddress;

req.headers['x-forwarded-port'] += portToAppend;
}
}
else {

@@ -435,5 +446,5 @@ 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';
var protoToAppend = "," + (req.connection.pair ? 'wss' : 'ws');
req.headers['x-forwarded-proto'] += protoToAppend;
}
}
else {

@@ -453,3 +464,3 @@ req.headers['x-forwarded-proto'] = req.connection.pair ? 'wss' : 'ws';

socket.setNoDelay(true);
if (keepAlive) {

@@ -467,3 +478,3 @@ if (socket.setKeepAlive) {

}
//

@@ -497,9 +508,9 @@ // Setup the incoming client socket.

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.
//

@@ -530,9 +541,9 @@ setTimeout(function () {

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.
//

@@ -582,7 +593,7 @@ setTimeout(function () {

});
};
}
function getPort (port) {
port = port || 80;
return port - 80 === 0 ? '' : ':' + port
return port - 80 === 0 ? '' : ':' + port;
}

@@ -598,3 +609,3 @@

remoteHost = this.target.host + portUri;
//

@@ -618,3 +629,3 @@ // Change headers (if requested).

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

@@ -706,3 +717,3 @@

socket.once('drain', function () {
try { revSocket.resume() }
try { revSocket.resume() }
catch (er) { console.error("reverseProxy.socket.resume error: %s", er.message) }

@@ -713,3 +724,3 @@ });

// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//

@@ -723,3 +734,3 @@ setTimeout(function () {

//
// Remove data listener on socket error because the
// Remove data listener on socket error because the
// 'handshake' has failed.

@@ -745,4 +756,4 @@ //

//
// 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.

@@ -795,3 +806,3 @@ //

HttpProxy.prototype._forwardRequest = function (req) {
var self = this,
var self = this,
outgoing = new(this.forward.base),

@@ -811,3 +822,3 @@ forwardProxy;

//
// Open new HTTP request to internal resource with will
// Open new HTTP request to internal resource with will
// act as a reverse proxy pass.

@@ -839,3 +850,3 @@ //

forwardProxy.once('drain', function () {
try { req.resume() }
try { req.resume() }
catch (er) { console.error("req.resume error: %s", er.message) }

@@ -846,3 +857,3 @@ });

// Force the `drain` event in 100ms if it hasn't
// happened on its own.
// happened on its own.
//

@@ -856,3 +867,3 @@ setTimeout(function () {

//
// 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

@@ -859,0 +870,0 @@ //

@@ -45,2 +45,3 @@ /*

this.silent = options.silent || options.silent !== true;
this.target = options.target || {};
this.hostnameOnly = options.hostnameOnly === true;

@@ -95,15 +96,58 @@

var self = this;
this.router = router;
if (this.hostnameOnly === false) {
var self = this;
this.routes = [];
Object.keys(router).forEach(function (path) {
var route = new RegExp('^' + path, 'i');
if (!/http[s]?/.test(router[path])) {
router[path] = (self.target.https ? 'https://' : 'http://')
+ router[path];
}
var target = url.parse(router[path]),
defaultPort = self.target.https ? 443 : 80;
//
// Setup a robust lookup table for the route:
//
// {
// source: {
// regexp: /^foo.com/i,
// sref: 'foo.com',
// url: {
// protocol: 'http:',
// slashes: true,
// host: 'foo.com',
// hostname: 'foo.com',
// href: 'http://foo.com/',
// pathname: '/',
// path: '/'
// }
// },
// {
// target: {
// sref: '127.0.0.1:8000/',
// url: {
// protocol: 'http:',
// slashes: true,
// host: '127.0.0.1:8000',
// hostname: '127.0.0.1',
// href: 'http://127.0.0.1:8000/',
// pathname: '/',
// path: '/'
// }
// },
//
self.routes.push({
route: route,
target: router[path],
path: path
source: {
regexp: new RegExp('^' + path, 'i'),
sref: path,
url: url.parse('http://' + path)
},
target: {
sref: target.hostname + ':' + (target.port || defaultPort) + target.path,
url: target
}
});

@@ -126,3 +170,3 @@ });

var target = req.headers.host.split(':')[0];
if (this.hostnameOnly == true) {
if (this.hostnameOnly === true) {
if (this.router.hasOwnProperty(target)) {

@@ -143,18 +187,26 @@ var location = this.router[target].split(':'),

var route = this.routes[i];
if (target.match(route.route)) {
var requrl = url.parse(req.url);
//add the 'http://'' to get around a url.parse bug, it won't actually be used.
var targeturl = url.parse('http://'+route.target);
var pathurl = url.parse('http://'+route.path);
if (target.match(route.source.regexp)) {
//
// Attempt to perform any path replacement for differences
// between the source path and the target path. This replaces the
// path's part of the URL to the target's part of the URL.
//
// 1. Parse the request URL
// 2. Replace any portions of the source path with the target path
// 3. Set the request URL to the formatted URL with replacements.
//
var parsed = url.parse(req.url);
//This replaces the path's part of the URL to the target's part of the URL.
requrl.pathname = requrl.pathname.replace(pathurl.pathname, targeturl.pathname);
req.url = url.format(requrl);
parsed.pathname = parsed.pathname.replace(
route.source.url.pathname,
route.target.url.pathname
);
var host = targeturl.hostname,
port = targeturl.port || 80;
req.url = url.format(parsed);
return {
port: port,
host: host
protocol: route.target.url.protocol.replace(':', ''),
host: route.target.url.hostname,
port: route.target.url.port
|| (this.target.https ? 443 : 80)
};

@@ -161,0 +213,0 @@ }

@@ -50,4 +50,4 @@ /*

//
this.source = options.source || { host: 'localhost', port: 8000 };
this.https = this.source.https || options.https;
this.source = options.source || { host: 'localhost', port: 8000 };
this.https = this.source.https || options.https;
this.enable = options.enable;

@@ -92,4 +92,3 @@ this.forward = options.forward;

options.target.https = this.target && this.target.https ||
options.target && options.target.https ||
options.https;
options.target && options.target.https;

@@ -107,8 +106,11 @@ //

this.proxies[key] = new HttpProxy(options);
if (this.listeners('proxyError').length > 0) {
this.proxies[key].on('proxyError', this.emit.bind(this, 'proxyError'));
}
if (this.listeners('webSocketProxyError').length > 0) {
this.proxies[key].on('webSocketProxyError', this.emit.bind(this, 'webSocketProxyError'));
}
this.proxies[key].on('start', this.emit.bind(this, 'start'));

@@ -126,3 +128,7 @@ this.proxies[key].on('forward', this.emit.bind(this, 'forward'));

RoutingProxy.prototype.remove = function (options) {
var key = this._getKey(options);
var key = this._getKey(options),
proxy = this.proxies[key];
delete this.proxies[key];
return proxy;
};

@@ -168,2 +174,4 @@

options = options || {};
var location;

@@ -208,4 +216,10 @@ //

var key = this._getKey(options),
proxy;
proxy;
if ((this.target && this.target.https)
|| (location && location.protocol === 'https')) {
options.target = options.target || {};
options.target.https = true;
}
if (!this.proxies[key]) {

@@ -234,2 +248,6 @@ this.add(options);

var location,
proxy,
key;
if (this.proxyTable && !options.host) {

@@ -246,4 +264,3 @@ location = this.proxyTable.getProxyLocation(req);

var key = this._getKey(options),
proxy;
key = this._getKey(options);

@@ -269,3 +286,2 @@ if (!this.proxies[key]) {

throw new Error('options.host and options.port or options.target are required.');
return;
}

@@ -277,2 +293,2 @@

].join(':');
}
};
{
"name": "http-proxy",
"version": "0.8.1",
"version": "0.8.2",
"description": "A full-featured http reverse proxy for node.js",

@@ -21,3 +21,3 @@ "author": "Nodejitsu Inc. <info@nodejitsu.com>",

"colors": "0.x.x",
"optimist": "0.2.x",
"optimist": "0.3.x",
"pkginfo": "0.2.x"

@@ -27,5 +27,7 @@ },

"request": "1.9.x",
"vows": "0.5.x",
"vows": "0.6.x",
"async": "0.1.x",
"socket.io": "0.6.17"
"socket.io": "0.9.6",
"socket.io-client": "0.9.6",
"ws": "0.4.21"
},

@@ -37,5 +39,5 @@ "main": "./lib/node-http-proxy",

"scripts": {
"test": "npm run-script test-http && npm run-script test-https && npm run-script test-core",
"test-http": "vows --spec && vows --spec --target=secure",
"test-https": "vows --spec --source=secure && vows --spec --source=secure --target=secure",
"test": "npm run-script test-http && npm run-script test-https",
"test-http": "vows --spec && vows --spec --target=https",
"test-https": "vows --spec --proxy=https && vows --spec --proxy=https --target=https",
"test-core": "test/core/run"

@@ -42,0 +44,0 @@ },

@@ -227,11 +227,9 @@ # node-http-proxy

var server = httpProxy.createServer(function (req, res, proxy) {
var buffer = httpProxy.buffer(req);
var buffer = httpProxy.buffer(req);
proxy.proxyRequest(req, res, {
host: '127.0.0.1',
port: 9000,
buffer: buffer
});
proxy.proxyRequest(req, res, {
host: '127.0.0.1',
port: 9000,
buffer: buffer
});
});

@@ -297,2 +295,63 @@

### Using two certificates
Suppose that your reverse proxy will handle HTTPS traffic for two different domains `fobar.com` and `barbaz.com`.
If you need to use two different certificates you can take advantage of [Server Name Indication](http://en.wikipedia.org/wiki/Server_Name_Indication).
``` js
var https = require('https'),
path = require("path"),
fs = require("fs"),
crypto = require("crypto");
//
// generic function to load the credentials context from disk
//
function getCredentialsContext (cer) {
return crypto.createCredentials({
key: fs.readFileSync(path.join(__dirname, 'certs', cer + '.key')),
cert: fs.readFileSync(path.join(__dirname, 'certs', cer + '.crt'))
}).context;
}
//
// A certificate per domain hash
//
var certs = {
"fobar.com": getCredentialsContext("foobar"),
"barbaz.com": getCredentialsContext("barbaz")
};
//
// Proxy options
//
var options = {
https: {
SNICallback: function(hostname){
return certs[hostname];
}
},
hostnameOnly: true,
router: {
'fobar.com': '127.0.0.1:8001',
'barbaz.com': '127.0.0.1:8002'
}
};
//
// Create a standalone HTTPS proxy server
//
httpProxy.createServer(options).listen(8001);
//
// Create the target HTTPS server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('hello https\n');
res.end();
}).listen(8000);
```
### Proxying to HTTPS from HTTPS

@@ -299,0 +358,0 @@ Proxying from HTTPS to HTTPS is essentially the same as proxying from HTTPS to HTTP, but you must include the `target` option in when calling `httpProxy.createServer` or instantiating a new instance of `HttpProxy`.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc