Skip to content

Commit 372a10b

Browse files
committed
Merge pull request http-party#1 from rstudio/stripped
Updated package, stripped down to basic HTTP proxy and null out memory leaks.
2 parents cfb25b3 + 026e0ae commit 372a10b

File tree

9 files changed

+176
-1239
lines changed

9 files changed

+176
-1239
lines changed

.travis.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
language: node_js
22
node_js:
3-
- 0.6
43
- 0.8
4+
- "0.10"
5+
- "0.11"
56

67
notifications:
78
email:

README.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
* Written entirely in Javascript
1919
* Easy to use API
2020

21+
22+
node-http-proxy is `<= 0.8.x` compatible, if you're looking for a `>= 0.10` compatible version please check [caronte](https://github.com/nodejitsu/node-http-proxy/tree/caronte)
23+
2124
### When to use node-http-proxy
2225

2326
Let's suppose you were running multiple http application servers, but you only wanted to expose one machine to the internet. You could setup node-http-proxy on that one machine and then reverse-proxy the incoming http requests to locally running services which were not exposed to the outside network.
@@ -345,7 +348,10 @@ var options = {
345348
https: {
346349
SNICallback: function (hostname) {
347350
return certs[hostname];
348-
}
351+
},
352+
cert: myCert,
353+
key: myKey,
354+
ca: [myCa]
349355
},
350356
hostnameOnly: true,
351357
router: {
@@ -515,7 +521,7 @@ server.listen(8080);
515521

516522
### Configuring your Socket limits
517523

518-
By default, `node-http-proxy` will set a 100 socket limit for all `host:port` proxy targets. You can change this in two ways:
524+
By default, `node-http-proxy` will set a 200 socket limit for all `host:port` proxy targets. You can change this in two ways:
519525

520526
1. By passing the `maxSockets` option to `httpProxy.createServer()`
521527
2. By calling `httpProxy.setMaxSockets(n)`, where `n` is the number of sockets you with to use.

lib/node-http-proxy.js

+29-104
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@
2626

2727
var util = require('util'),
2828
http = require('http'),
29-
https = require('https'),
3029
events = require('events'),
31-
maxSockets = 100;
30+
maxSockets = 200;
3231

3332
//
3433
// Expose version information through `pkginfo`.
@@ -38,10 +37,7 @@ require('pkginfo')(module, 'version');
3837
//
3938
// ### Export the relevant objects exposed by `node-http-proxy`
4039
//
41-
var HttpProxy = exports.HttpProxy = require('./node-http-proxy/http-proxy').HttpProxy,
42-
ProxyTable = exports.ProxyTable = require('./node-http-proxy/proxy-table').ProxyTable,
43-
RoutingProxy = exports.RoutingProxy = require('./node-http-proxy/routing-proxy').RoutingProxy;
44-
40+
var HttpProxy = exports.HttpProxy = require('./node-http-proxy/http-proxy').HttpProxy;
4541
//
4642
// ### function createServer ([port, host, options, handler])
4743
// #### @port {number} **Optional** Port to use on the proxy target host.
@@ -82,7 +78,7 @@ exports.createServer = function () {
8278
case 'function': callback = arg; handlers.push(callback); break;
8379
};
8480
});
85-
81+
8682
//
8783
// Helper function to create intelligent error message(s)
8884
// for the very liberal arguments parsing performed by
@@ -91,32 +87,32 @@ exports.createServer = function () {
9187
function validArguments() {
9288
var conditions = {
9389
'port and host': function () {
94-
return port && host;
90+
return port && host;
9591
},
9692
'options.target or options.router': function () {
97-
return options && (options.router ||
93+
return options && (options.router ||
9894
(options.target && options.target.host && options.target.port));
9995
},
10096
'or proxy handlers': function () {
10197
return handlers && handlers.length;
10298
}
10399
}
104-
100+
105101
var missing = Object.keys(conditions).filter(function (name) {
106102
return !conditions[name]();
107103
});
108-
104+
109105
if (missing.length === 3) {
110106
message = 'Cannot proxy without ' + missing.join(', ');
111107
return false;
112108
}
113-
109+
114110
return true;
115-
}
116-
111+
}
112+
117113
if (!validArguments()) {
118114
//
119-
// If `host`, `port` and `options` are all not passed (with valid
115+
// If `host`, `port` and `options` are all not passed (with valid
120116
// options) then this server is improperly configured.
121117
//
122118
throw new Error(message);
@@ -131,7 +127,7 @@ exports.createServer = function () {
131127
options.target = options.target || {};
132128
options.target.port = options.target.port || port;
133129
options.target.host = options.target.host || host;
134-
130+
135131
if (options.target && options.target.host && options.target.port) {
136132
//
137133
// If an explicit `host` and `port` combination has been passed
@@ -144,39 +140,18 @@ exports.createServer = function () {
144140
});
145141
}
146142
else {
147-
//
148-
// If no explicit `host` or `port` combination has been passed then
149-
// we have to assume that this is a "go-anywhere" Proxy (i.e. a `RoutingProxy`).
150-
//
151-
proxy = new RoutingProxy(options);
152-
153-
if (options.router) {
154-
//
155-
// If a routing table has been supplied than we assume
156-
// the user intends us to add the "proxy" middleware layer
157-
// for them
158-
//
159-
handlers.push(function (req, res) {
160-
proxy.proxyRequest(req, res);
161-
});
162-
163-
proxy.on('routes', function (routes) {
164-
server.emit('routes', routes);
165-
});
166-
}
143+
console.error("The modified HTTP Proxy can't be used this way anymore.");
167144
}
168-
145+
169146
//
170147
// Create the `http[s].Server` instance which will use
171148
// an instance of `httpProxy.HttpProxy`.
172149
//
173-
handler = handlers.length > 1
150+
handler = handlers.length > 1
174151
? exports.stack(handlers, proxy)
175152
: function (req, res) { handlers[0](req, res, proxy) };
176-
177-
server = options.https
178-
? https.createServer(options.https, handler)
179-
: http.createServer(handler);
153+
154+
server = http.createServer(handler);
180155

181156
server.on('close', function () {
182157
proxy.close();
@@ -185,8 +160,8 @@ exports.createServer = function () {
185160
if (!callback) {
186161
//
187162
// If an explicit callback has not been supplied then
188-
// automagically proxy the request using the `HttpProxy`
189-
// instance we have created.
163+
// automatically proxy the request using the `HttpProxy`
164+
// instance we have created.
190165
//
191166
server.on('upgrade', function (req, socket, head) {
192167
proxy.proxyWebSocketRequest(req, socket, head);
@@ -223,7 +198,7 @@ exports.createServer = function () {
223198
//
224199
exports.buffer = function (obj) {
225200
var events = [],
226-
onData,
201+
onData,
227202
onEnd;
228203

229204
obj.on('data', onData = function (data, encoding) {
@@ -237,14 +212,14 @@ exports.buffer = function (obj) {
237212
return {
238213
end: function () {
239214
obj.removeListener('data', onData);
240-
obj.removeListener('end', onEnd);
215+
obj.removeListener('end', onEnd);
241216
},
242217
destroy: function () {
243218
this.end();
244219
this.resume = function () {
245220
console.error("Cannot resume buffer after destroying it.");
246221
};
247-
222+
248223
onData = onEnd = events = obj = null;
249224
},
250225
resume: function () {
@@ -276,56 +251,6 @@ exports.setMaxSockets = function (value) {
276251
maxSockets = value;
277252
};
278253

279-
//
280-
// ### function stack (middlewares, proxy)
281-
// #### @middlewares {Array} Array of functions to stack.
282-
// #### @proxy {HttpProxy|RoutingProxy} Proxy instance to
283-
// Iteratively build up a single handler to the `http.Server`
284-
// `request` event (i.e. `function (req, res)`) by wrapping
285-
// each middleware `layer` into a `child` middleware which
286-
// is in invoked by the parent (i.e. predecessor in the Array).
287-
//
288-
// adapted from https://github.com/creationix/stack
289-
//
290-
exports.stack = function stack (middlewares, proxy) {
291-
var handle;
292-
middlewares.reverse().forEach(function (layer) {
293-
var child = handle;
294-
handle = function (req, res) {
295-
var next = function (err) {
296-
if (err) {
297-
if (res._headerSent) {
298-
res.destroy();
299-
}
300-
else {
301-
res.statusCode = 500;
302-
res.setHeader('Content-Type', 'text/plain');
303-
res.end('Internal Server Error');
304-
}
305-
306-
console.error('Error in middleware(s): %s', err.stack);
307-
return;
308-
}
309-
310-
if (child) {
311-
child(req, res);
312-
}
313-
};
314-
315-
//
316-
// Set the prototype of the `next` function to the instance
317-
// of the `proxy` so that in can be used interchangably from
318-
// a `connect` style callback and a true `HttpProxy` object.
319-
//
320-
// e.g. `function (req, res, next)` vs. `function (req, res, proxy)`
321-
//
322-
next.__proto__ = proxy;
323-
layer(req, res, next);
324-
};
325-
});
326-
327-
return handle;
328-
};
329254

330255
//
331256
// ### function _getAgent (host, port, secure)
@@ -345,12 +270,12 @@ exports._getAgent = function _getAgent (options) {
345270
if (!options || !options.host) {
346271
throw new Error('`options.host` is required to create an Agent.');
347272
}
348-
273+
349274
if (!options.port) {
350-
options.port = options.https ? 443 : 80;
275+
options.port = 80;
351276
}
352277

353-
var Agent = options.https ? https.Agent : http.Agent,
278+
var Agent = http.Agent,
354279
agent;
355280

356281
// require('http-proxy').setMaxSockets() should override http's default
@@ -364,11 +289,11 @@ exports._getAgent = function _getAgent (options) {
364289
//
365290
// ### function _getProtocol (options)
366291
// #### @options {Object} Options for the proxy target.
367-
// Returns the appropriate node.js core protocol module (i.e. `http` or `https`)
368-
// based on the `options` supplied.
292+
// Returns the appropriate node.js core protocol module (i.e. `http` or `https`)
293+
// based on the `options` supplied.
369294
//
370295
exports._getProtocol = function _getProtocol (options) {
371-
return options.https ? https : http;
296+
return http;
372297
};
373298

374299

@@ -381,7 +306,7 @@ exports._getProtocol = function _getProtocol (options) {
381306
//
382307
exports._getBase = function _getBase (options) {
383308
var result = function () {};
384-
309+
385310
if (options.https && typeof options.https === 'object') {
386311
['ca', 'cert', 'key'].forEach(function (key) {
387312
if (options.https[key]) {

0 commit comments

Comments
 (0)