proxy-chain
Advanced tools
Comparing version 0.1.3 to 0.1.4
@@ -18,2 +18,6 @@ 'use strict'; | ||
var _events = require('events'); | ||
var _events2 = _interopRequireDefault(_events); | ||
var _underscore = require('underscore'); | ||
@@ -52,8 +56,9 @@ | ||
// - Implement this requirement from rfc7230 | ||
// "A proxy MUST forward unrecognized header fields unless the field-name | ||
// is listed in the Connection header field (Section 6.1) or the proxy | ||
// is specifically configured to block, or otherwise transform, such | ||
// fields. Other recipients SHOULD ignore unrecognized header fields. | ||
// These requirements allow HTTP's functionality to be enhanced without | ||
// requiring prior update of deployed intermediaries." | ||
// "A proxy MUST forward unrecognized header fields unless the field-name | ||
// is listed in the Connection header field (Section 6.1) or the proxy | ||
// is specifically configured to block, or otherwise transform, such | ||
// fields. Other recipients SHOULD ignore unrecognized header fields. | ||
// These requirements allow HTTP's functionality to be enhanced without | ||
// requiring prior update of deployed intermediaries." | ||
// - Add param to prepareRequestFunction() that would allow the caller to kill a connection | ||
@@ -90,3 +95,11 @@ // TODO: | ||
var Server = exports.Server = function () { | ||
/** | ||
* Represents the proxy server. | ||
* It emits 'requestFailed' event on unexpected request errors. | ||
*/ | ||
var Server = exports.Server = function (_EventEmitter) { | ||
_inherits(Server, _EventEmitter); | ||
/** | ||
@@ -110,22 +123,25 @@ * Initializes a new instance of Server class. | ||
var _this2 = _possibleConstructorReturn(this, (Server.__proto__ || Object.getPrototypeOf(Server)).call(this)); | ||
options = options || {}; | ||
this.port = options.port || DEFAULT_PROXY_SERVER_PORT; | ||
this.prepareRequestFunction = options.prepareRequestFunction; | ||
this.authRealm = options.authRealm || DEFAULT_AUTH_REALM; | ||
this.verbose = !!options.verbose; | ||
_this2.port = options.port || DEFAULT_PROXY_SERVER_PORT; | ||
_this2.prepareRequestFunction = options.prepareRequestFunction; | ||
_this2.authRealm = options.authRealm || DEFAULT_AUTH_REALM; | ||
_this2.verbose = !!options.verbose; | ||
// Key is handler ID, value is HandlerXxx instance | ||
this.handlers = {}; | ||
this.lastHandlerId = 0; | ||
_this2.handlers = {}; | ||
_this2.lastHandlerId = 0; | ||
this.server = _http2.default.createServer(); | ||
this.server.on('clientError', this.onClientError.bind(this)); | ||
this.server.on('request', this.onRequest.bind(this)); | ||
this.server.on('connect', this.onConnect.bind(this)); | ||
_this2.server = _http2.default.createServer(); | ||
_this2.server.on('clientError', _this2.onClientError.bind(_this2)); | ||
_this2.server.on('request', _this2.onRequest.bind(_this2)); | ||
_this2.server.on('connect', _this2.onConnect.bind(_this2)); | ||
this.stats = { | ||
_this2.stats = { | ||
httpRequestCount: 0, | ||
connectRequestCount: 0 | ||
}; | ||
return _this2; | ||
} | ||
@@ -135,4 +151,4 @@ | ||
key: 'log', | ||
value: function log(str, force) { | ||
if (this.verbose || force) console.log('Server[' + this.port + ']: ' + str); | ||
value: function log(str) { | ||
if (this.verbose) console.log('Server[' + this.port + ']: ' + str); | ||
} | ||
@@ -153,3 +169,3 @@ }, { | ||
value: function onRequest(request, response) { | ||
var _this2 = this; | ||
var _this3 = this; | ||
@@ -164,5 +180,5 @@ this.log(request.method + ' ' + request.url + ' HTTP/' + request.httpVersion); | ||
var handler = new _handler_forward2.default(handlerOpts); | ||
_this2.handlerRun(handler); | ||
_this3.handlerRun(handler); | ||
}).catch(function (err) { | ||
_this2.failRequest(request, err); | ||
_this3.failRequest(request, err); | ||
}); | ||
@@ -180,3 +196,3 @@ } | ||
value: function onConnect(request) { | ||
var _this3 = this; | ||
var _this4 = this; | ||
@@ -188,5 +204,5 @@ this.log(request.method + ' ' + request.url + ' HTTP/' + request.httpVersion); | ||
var handler = handlerOpts.upstreamProxyUrl ? new _handler_tunnel_chain2.default(handlerOpts) : new _handler_tunnel_direct2.default(handlerOpts); | ||
_this3.handlerRun(handler); | ||
_this4.handlerRun(handler); | ||
}).catch(function (err) { | ||
_this3.failRequest(request, err); | ||
_this4.failRequest(request, err); | ||
}); | ||
@@ -204,3 +220,3 @@ } | ||
value: function prepareRequestHandling(request) { | ||
var _this4 = this; | ||
var _this5 = this; | ||
@@ -229,3 +245,3 @@ // console.log('XXX prepareRequestHandling'); | ||
result.trgParsed = (0, _tools.parseHostHeader)(request.url); | ||
_this4.stats.connectRequestCount++; | ||
_this5.stats.connectRequestCount++; | ||
} else { | ||
@@ -252,3 +268,3 @@ // The request should look like: | ||
_this4.stats.httpRequestCount++; | ||
_this5.stats.httpRequestCount++; | ||
} | ||
@@ -258,3 +274,3 @@ result.trgParsed.port = result.trgParsed.port || DEFAULT_TARGET_PORT; | ||
// Authenticate the request using a user function (if provided) | ||
if (!_this4.prepareRequestFunction) return { requestAuthentication: false, upstreamProxyUrl: null }; | ||
if (!_this5.prepareRequestFunction) return { requestAuthentication: false, upstreamProxyUrl: null }; | ||
@@ -288,7 +304,7 @@ // Pause the socket so that no data is lost | ||
// User function returns a result directly or a promise | ||
return _this4.prepareRequestFunction(funcOpts); | ||
return _this5.prepareRequestFunction(funcOpts); | ||
}).then(function (funcResult) { | ||
// If not authenticated, request client to authenticate | ||
if (funcResult && funcResult.requestAuthentication) { | ||
var headers = { 'Proxy-Authenticate': 'Basic realm="' + _this4.authRealm + '"' }; | ||
var headers = { 'Proxy-Authenticate': 'Basic realm="' + _this5.authRealm + '"' }; | ||
throw new RequestError('Credentials required.', 407, headers); | ||
@@ -303,3 +319,3 @@ } | ||
}).finally(function () { | ||
if (_this4.prepareRequestFunction) socket.resume(); | ||
if (_this5.prepareRequestFunction) socket.resume(); | ||
}); | ||
@@ -310,7 +326,7 @@ } | ||
value: function handlerRun(handler) { | ||
var _this5 = this; | ||
var _this6 = this; | ||
this.handlers[handler.id] = handler; | ||
handler.once('destroy', function () { | ||
delete _this5.handlers[handler.id]; | ||
delete _this6.handlers[handler.id]; | ||
}); | ||
@@ -333,4 +349,5 @@ handler.run(); | ||
} else { | ||
this.log('Request failed with unknown error: ' + (err.stack || err), true); | ||
this.log('Request failed with unknown error: ' + (err.stack || err)); | ||
this.sendResponse(request.socket, 500, null, 'Internal server error'); | ||
this.emit('requestFailed', err); | ||
} | ||
@@ -361,6 +378,6 @@ } | ||
// Unfortunately calling end() will not close the socket | ||
// if client refuses to close it. Hence calling destroy. | ||
// TODO: maybe the client will never receive the response, | ||
// maybe we could add the socket to some internal dictionary and close it in close() | ||
socket.destroy(); | ||
// if client refuses to close it. Hence calling destroy after a short while. | ||
setTimeout(function () { | ||
socket.destroy(); | ||
}, 100); | ||
}); | ||
@@ -381,8 +398,8 @@ } catch (err) { | ||
value: function listen(callback) { | ||
var _this6 = this; | ||
var _this7 = this; | ||
return _bluebird2.default.promisify(this.server.listen.bind(this.server))(this.port).then(function () { | ||
_this6.log('Listening...'); | ||
_this7.log('Listening...'); | ||
}).catch(function (err) { | ||
_this6.log('Listen failed: ' + err); | ||
_this7.log('Listen failed: ' + err); | ||
throw err; | ||
@@ -427,2 +444,2 @@ }).nodeify(callback); | ||
return Server; | ||
}(); | ||
}(_events2.default); |
{ | ||
"name": "proxy-chain", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"description": "Node.js implementation of a proxy server (think Squid) with support for SSL, authentication and upstream proxy chaining.", | ||
@@ -5,0 +5,0 @@ "main": "build/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79387
1173