Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

More api changes.

  • Loading branch information...
commit e9109999c3bf554ee1afa701cf5bd765396427ec 1 parent fc72efa
@axiak authored
View
32 README.md
@@ -17,7 +17,7 @@ var filternet = require('filternet');
var myProxy = filternet.createProxyServer();
-myProxy.on("interceptResponseContent", function (buffer, response_object, is_ssl, charset, callback) {
+myProxy.on("interceptResponseContent", function (buffer, responseObject, isSsl, charset, callback) {
var content = buffer.toString('utf8');
var css = "<"+"link rel='stylesheet' href='http://axiak.github.com/filternet/blink.css'>";
callback(content.replace(/<\/head>/i, css + "</head>"));
@@ -40,7 +40,7 @@ var myProxy = filternet.createProxyServer({
transSslPort: 8129 // enable transparent ssl proxy
});
-myProxy.on("interceptResponseContent", function (buffer, response_object, is_ssl, charset, callback) {
+myProxy.on("interceptResponseContent", function (buffer, responseObject, isSsl, charset, callback) {
console.log(buffer.toString('utf8'));
callback(buffer);
});
@@ -56,7 +56,7 @@ The main function available is <tt>createProxyServer(opts)</tt> where the option
- port - The port to listen on. Default: 8128
- hostname - The hostname to listen on. Default: server will accept any
-- via - Either the name to give to the VIA header, or false to squelch the VIA header. Default: filternet/0.0.1
+- via - Either the name to give to the VIA header, or false to squelch the VIA header. Default: filternet/0.0.2
- enableCompression - Whether or not to enable HTTP compression. If false, the accept-encoding header will tell the remote server to not compress. Default: true
- recompress - If the response from the server was compressed, this will determine if the proxy will recompress the decompressed content for the client. Default: equal to <tt>enableCompression</tt>
- sslCerts - The mapping of host description to ssl keys/certificates (see SSL Certificates). Default: {}
@@ -71,25 +71,25 @@ This gets called first on every http request or intercepted https request.
If you call <tt>callback(true)</tt>, the proxy server will return a 407 response and complete.
-### Event: enabledCheck <tt>function (callback){}</tt>
+### Event: shouldEnableInterception <tt>function (callback){}</tt>
This is used to disable intercepting. If you run callback(false), the proxy server will run as a normal proxy server would. callback(true) will enable your other listeners.
The default behavior is callback(true)
-### Event: interceptRequest <tt>function (request_options, callback)</tt>
+### Event: interceptRequest <tt>function (requestOptions, callback)</tt>
-request_options is a map of data to be sent to http.request. callback expects request_options to continue the request.
+requestOptions is a map of data to be sent to http.request. callback expects requestOptions to continue the request.
-The default behavior is callback(request_options);
+The default behavior is callback(requestOptions);
-### Event: interceptResponseHeaders: <tt>function (request_info, response_status_code, response_headers, callback)</tt>
+### Event: interceptResponseHeaders: <tt>function (requestInfo, responseStatusCode, responseHeaders, callback)</tt>
-callback expects (response_status_code, response_headers). You can use this method if you want to manipulate the response headers before they get sent.
+callback expects (responseStatusCode, responseHeaders). You can use this method if you want to manipulate the response headers before they get sent.
-The default behavior is callback(response_status_code, response_headers);
+The default behavior is callback(responseStatusCode, responseHeaders);
-### Event: shouldInterceptResponse <tt>function (response, callback)</tt>
+### Event: shouldInterceptResponseContent <tt>function (response, callback)</tt>
Given the response from the remote server, this listener enabled you to decide if the interception should happen or not. Run callback(true) if you intend on intercepting the response content.
@@ -97,21 +97,21 @@ The default behavior is callback(isHtml), where isHtml is true if the content-ty
(The use of the method prevents the proxy server from having to buffer images, etc.)
-### Event: interceptResponseContent <tt>function (buffer, proxy_response, is_ssl, charset, callback)</tt>
+### Event: interceptResponseContent <tt>function (buffer, remoteResponse, isSsl, charset, callback)</tt>
callback expects the content buffer or string to send to the client.
-is_ssl is true if this interception was performed on an https request.
+isSsl is true if this interception was performed on an https request.
-charset is a convenience string which is either the charset from the Content-Type header, or null if none was defined.
+charset is a convenience string which is either the charset from the Content-Type header, or null if none was defined.
Generally, if charset is not null it's safer to run buffer.toString('utf8') to get a string. Otherwise you're probably dealing with binary data.
The default behavior is callback(buffer);
-### Event: error <tt>function (error)</tt>
+### Event: error <tt>function (error, [errorSourceString], [requestInfo])</tt>
-Called on any error that is not a clientError
+Called on any error that is not a clientError. If available an error source string and the requestInfo object will be provided.
If not defined errors actually break the proxy server.
View
28 example/skeletontest.js
@@ -2,45 +2,45 @@ var proxy = require('../lib/proxy.js');
var myProxy = proxy.createProxyServer({
- port: 8080
- });
+ port: 8088 });
// Whether or not to enable custom intercepting at all.
-myProxy.on('enabledCheck', function (callback) {
- callback(true);
+myProxy.on('shouldEnableInterception', function (callback) {
+ callback(false);
});
// Whether or not we should intercept and buffer the proxy response
// The default is to buffer all HTML responses.
-myProxy.on('shouldInterceptResponse', function (proxy_response, callback) {
- var isHtml = (proxy_response.headers['content-type'] &&
- proxy_response.headers['content-type'].toLowerCase().indexOf("html") != -1);
+myProxy.on('shouldInterceptResponseContent', function (proxyResponse, callback) {
+ var isHtml = (proxyResponse.headers['content-type'] &&
+ proxyResponse.headers['content-type'].toLowerCase().indexOf("html") != -1);
callback(isHtml);
});
// You can rewrite the request as it's being sent to the remote server.
// (just headers)
-myProxy.on('interceptRequest', function (request_info, callback) {
- // request_info is the same as the arguments to http.request
- console.log(request_info['host'], request_info['path']);
- callback(request_info);
+myProxy.on('interceptRequest', function (requestInfo, callback) {
+ // requestInfo is the same as the arguments to http.request
+ console.log(requestInfo.host, requestInfo.path);
+ callback(requestInfo);
});
// You can change response headers
-myProxy.on('interceptResponseHeaders', function (request_info, statusCode, headers, callback) {
+myProxy.on('interceptResponseHeaders', function (requestInfo, statusCode, headers, callback) {
callback(statusCode, headers);
});
// You can alter any response body that you said you want to intercept in "shouldInterceptResponse"
// by default this is all HTML responses if 'enabledCheck' is true (default)
// The response object is the standard node http response object.
-myProxy.on('interceptResponseContent', function (buffer, response_object, is_ssl, charset, callback) {
+myProxy.on('interceptResponseContent', function (buffer, response, isSsl, charset, callback) {
callback(buffer);
});
-myProxy.on('error', function (error) {
+myProxy.on('error', function (error, locationInfo) {
+ console.log(locationInfo);
console.log(error.stack);
});
View
20 example/skeletontest_ssl.js
@@ -24,36 +24,36 @@ myProxy.on('shouldReject', function (request, callback) {
// Whether or not to enable custom intercepting at all.
-myProxy.on('enabledCheck', function (callback) {
+myProxy.on('shouldEnableInterception', function (callback) {
callback(true);
});
// Whether or not we should intercept and buffer the proxy response
// The default is to buffer all HTML responses.
-myProxy.on('shouldInterceptResponse', function (proxy_response, callback) {
- var isHtml = (proxy_response.headers['content-type'] &&
- proxy_response.headers['content-type'].toLowerCase().indexOf("html") != -1);
+myProxy.on('shouldInterceptResponseContent', function (proxyResponse, callback) {
+ var isHtml = (proxyResponse.headers['content-type'] &&
+ proxyResponse.headers['content-type'].toLowerCase().indexOf("html") != -1);
callback(isHtml);
});
// You can rewrite the request as it's being sent to the remote server.
// (just headers)
-myProxy.on('interceptRequest', function (request_info, callback) {
- // request_info is the same as the arguments to http.request
- console.log(request_info['host'], request_info['path']);
- callback(request_info);
+myProxy.on('interceptRequest', function (requestInfo, callback) {
+ // requestInfo is the same as the argument object passed to http.request
+ console.log(requestInfo.host, requestInfo.path);
+ callback(requestInfo);
});
// You can change response headers
-myProxy.on('interceptResponseHeaders', function (request_info, statusCode, headers, callback) {
+myProxy.on('interceptResponseHeaders', function (requestInfo, statusCode, headers, callback) {
callback(statusCode, headers);
});
// You can alter any response body that you said you want to intercept in "shouldInterceptResponse"
// by default this is all HTML responses if 'enabledCheck' is true (default)
// The response object is the standard node http response object.
-myProxy.on('interceptResponseContent', function (buffer, response_object, is_ssl, charset, callback) {
+myProxy.on('interceptResponseContent', function (buffer, response, isSsl, charset, callback) {
callback(buffer);
});
View
103 lib/proxy.js
@@ -49,7 +49,7 @@ var fixHeaderCase = function (headers) {
module.exports.createProxyServer = function (opts) {
opts = opts || {};
- var main_port = ~~(opts['port'] || 8128);
+ var mainPort = ~~(opts['port'] || 8128);
var hostname = opts['hostname'];
var enableCompression = opts['enableCompression'];
if (enableCompression === undefined) {
@@ -62,7 +62,7 @@ module.exports.createProxyServer = function (opts) {
var via;
if (opts['via'] === undefined) {
- via = 'filternet/0.0.1';
+ via = 'filternet/0.0.2';
} else if (opts['via'] !== false) {
via = opts['via'];
}
@@ -91,7 +91,7 @@ module.exports.createProxyServer = function (opts) {
};
};
- var serverDefinition = function (is_ssl) { return errorWrapper(function (request, response) {
+ var serverDefinition = function (isSsl) { return errorWrapper(function (request, response) {
var onEnabled = function (enabled) {
var headers = request.headers;
if (enabled) {
@@ -102,13 +102,13 @@ module.exports.createProxyServer = function (opts) {
}
delete headers['proxy-connection'];
}
- var parsed_url = url.parse(request.url);
- var parsed_host = url.parse('http://' + headers['host']);
- var client_ip = request.connection.remoteAddress || request.connection.socket.remoteAddress;
+ var parsedUrl = url.parse(request.url);
+ var parsedHost = url.parse('http://' + headers['host']);
+ var clientIp = request.connection.remoteAddress || request.connection.socket.remoteAddress;
if (headers['x-forwarded-for']) {
- headers['x-forwarded-for'] = headers['x-forwarded-for'] + ', ' + client_ip;
+ headers['x-forwarded-for'] = headers['x-forwarded-for'] + ', ' + clientIp;
} else {
- headers['x-forwarded-for'] = client_ip;
+ headers['x-forwarded-for'] = clientIp;
}
headers['forwarded-for'] = headers['x-forwarded-for'];
@@ -121,36 +121,35 @@ module.exports.createProxyServer = function (opts) {
headers['via'] += ' (' + via + ')';
}
- var request_info = {
- 'host': parsed_url.hostname || parsed_host.hostname,
- 'port': ~~(parsed_url.port || parsed_host.port || (is_ssl ? 443 : 80)),
- 'path': parsed_url.pathname + (parsed_url.search || '') + (parsed_url.hash || ''),
+ var requestInfo = {
+ 'host': parsedUrl.hostname || parsedHost.hostname,
+ 'port': ~~(parsedUrl.port || parsedHost.port || (isSsl ? 443 : 80)),
+ 'path': parsedUrl.pathname + (parsedUrl.search || '') + (parsedUrl.hash || ''),
'method': request.method,
'headers': headers
};
- var runRequest = function (request_info) {
- request_info['headers'] = fixHeaderCase(request_info['headers']);
- var proxy_request = (is_ssl ? https: http).request(request_info, function (proxy_response) {
- var responseEncoding = proxy_response.headers['content-encoding'];
- var isHtml = (proxy_response.headers['content-type'] &&
- proxy_response.headers['content-type'].toLowerCase().indexOf("html") != -1);
+ var runRequest = function (requestInfo) {
+ requestInfo['headers'] = fixHeaderCase(requestInfo['headers']);
+ var proxyRequest = (isSsl ? https: http).request(requestInfo, function (proxyResponse) {
+ var responseEncoding = proxyResponse.headers['content-encoding'];
+ var isHtml = (proxyResponse.headers['content-type'] &&
+ proxyResponse.headers['content-type'].toLowerCase().indexOf("html") != -1);
var writeResponse = function (shouldBuffer) {
var buffer = undefined, bufferLength = 0;
if (shouldBuffer) {
- bufferLength = ~~(proxy_response.headers['content-length'] || 0);
- delete proxy_response.headers['content-length'];
- //buffer = new Buffer(bufferLength);
+ bufferLength = ~~(proxyResponse.headers['content-length'] || 0);
+ delete proxyResponse.headers['content-length'];
buffer = new Buffer(0);
}
- proxy_response.on('error', function (error) {
+ proxyResponse.on('error', function (error) {
response.end();
- emitter.emit('error', error, 'proxyResponse');
+ emitter.emit('error', error, 'proxyResponse', requestInfo);
});
- proxy_response.on('data', function (chunk) {
+ proxyResponse.on('data', function (chunk) {
if (shouldBuffer) {
buffer = Buffer.concat(buffer, chunk);
} else {
@@ -158,20 +157,20 @@ module.exports.createProxyServer = function (opts) {
}
});
- proxy_response.on('end', function () {
+ proxyResponse.on('end', function () {
if (!shouldBuffer) {
response.end();
emitter.emit('completeUnfitered');
return;
}
- var match = (proxy_response.headers['content-type'] || '').match(/charset=([^;]+)/);
+ var match = (proxyResponse.headers['content-type'] || '').match(/charset=([^;]+)/);
var charset = (match ? match[1] : null);
var writeResponse = function(outputBuffer) {
var encoding = recompress ? responseEncoding : undefined;
var writeOutput = function (error, b) {
if (error) {
- emitter.emit('error', error, 'recompressing');
+ emitter.emit('error', error, 'recompressing', requestInfo);
}
response.end(b);
};
@@ -189,10 +188,10 @@ module.exports.createProxyServer = function (opts) {
var setupIntercept = function (error, newBuffer) {
if (error) {
- emitter.emit('error', error, 'decompressing');
+ emitter.emit('error', error, 'decompressing', requestInfo);
}
emitOrRun('interceptResponseContent', function () { writeResponse(newBuffer); },
- newBuffer, proxy_response, is_ssl, charset, writeResponse);
+ newBuffer, proxyResponse, isSsl, charset, writeResponse);
};
switch (responseEncoding) {
case 'gzip':
@@ -208,32 +207,38 @@ module.exports.createProxyServer = function (opts) {
if (shouldBuffer) {
if (!recompress) {
- delete proxy_response.headers['content-encoding'];
+ delete proxyResponse.headers['content-encoding'];
}
emitOrRun('interceptResponseHeaders', function () {
- response.writeHead(proxy_response.statusCode, proxy_response.headers);
- }, request_info, proxy_response.statusCode, proxy_response.headers, function (a, b) { response.writeHead(a, b); } );
+ response.writeHead(proxyResponse.statusCode, proxyResponse.headers);
+ }, requestInfo, proxyResponse.statusCode, proxyResponse.headers, function (a, b) { response.writeHead(a, b); } );
} else {
- response.writeHead(proxy_response.statusCode, proxy_response.headers);
+ response.writeHead(proxyResponse.statusCode, proxyResponse.headers);
}
};
if (!enabled) {
writeResponse(false);
} else {
- emitOrRun('shouldInterceptResponse', function () { writeResponse(isHtml); }, proxy_response, writeResponse);
+ emitOrRun('shouldInterceptResponseContent', function () { writeResponse(isHtml); }, proxyResponse, writeResponse);
}
});
- proxy_request.on('error', function (error) {
- response.end();
- emitter.emit('error', error, 'proxyRequest', request_info);
+ proxyRequest.on('error', function (error) {
+ if (error.code === 'ENOTFOUND') {
+ response.writeHead(504);
+ response.end("Error - host not found: " + requestInfo.host);
+ } else {
+ response.writeHead(503);
+ response.end();
+ }
+ emitter.emit('error', error, 'proxyRequest', requestInfo);
});
- request.on('data', function (chunk) { proxy_request.write(chunk, 'binary'); });
- request.on('end', function (chunk) { proxy_request.end(); });
+ request.on('data', function (chunk) { proxyRequest.write(chunk, 'binary'); });
+ request.on('end', function (chunk) { proxyRequest.end(); });
};
- emitOrRun('interceptRequest', function () { runRequest(request_info); }, request_info, runRequest);
+ emitOrRun('interceptRequest', function () { runRequest(requestInfo); }, requestInfo, runRequest);
};
@@ -242,11 +247,11 @@ module.exports.createProxyServer = function (opts) {
response.writeHead(407, {});
response.end();
} else {
- emitOrRun('enabledCheck', function () { onEnabled(true); }, onEnabled);
+ emitOrRun('shouldEnableInterception', function () { onEnabled(true); }, onEnabled);
}
};
- if (is_ssl) {
+ if (isSsl) {
onReject(false);
} else {
emitOrRun('shouldReject', function () { onReject(false); }, request, onReject);
@@ -255,7 +260,7 @@ module.exports.createProxyServer = function (opts) {
/* Start http server */
var httpServer = http.createServer(serverDefinition(false));
- httpServer.listen(main_port, hostname);
+ httpServer.listen(mainPort, hostname);
httpServer.on('clientError', function (error) { emitter.emit('clientError', error, 'proxyClient'); });
httpServer.on('error', function (error) { emitter.emit('error', error, 'proxyServer'); });
@@ -304,13 +309,13 @@ module.exports.createProxyServer = function (opts) {
}
var sslProxy = function (isEnabled, requesturl, socket, initialData) {
- var parsed_url = url.parse('https://' + requesturl);
- var host_name = parsed_url.hostname.toLowerCase();
+ var parsedUrl = url.parse('https://' + requesturl);
+ var hostName = parsedUrl.hostname.toLowerCase();
- var serverSocketPath = sslExact[host_name];
+ var serverSocketPath = sslExact[hostName];
if (isEnabled && !serverSocketPath) {
for (var i = 0, l = sslRouting.length; i < l; i++) {
- if (host_name.search(sslRouting[i][0]) !== -1) {
+ if (hostName.search(sslRouting[i][0]) !== -1) {
serverSocketPath = sslRouting[i][1];
break;
}
@@ -324,7 +329,7 @@ module.exports.createProxyServer = function (opts) {
if (isEnabled && serverSocketPath) {
clientSocket = net.createConnection(serverSocketPath);
} else {
- clientSocket = net.createConnection(~~(parsed_url.port || 443), host_name);
+ clientSocket = net.createConnection(~~(parsedUrl.port || 443), hostName);
}
clientSocket.on('connect', function () {
@@ -374,7 +379,7 @@ module.exports.createProxyServer = function (opts) {
if (reject) {
socket.end();
} else {
- emitOrRun('enabledCheck', function () { onEnabled(true); }, onEnabled);
+ emitOrRun('shouldEnableInterception', function () { onEnabled(true); }, onEnabled);
}
};
emitOrRun('shouldReject', function () { onReject(false); }, request, onReject);
View
0  lib/regex-escape.js → lib/regexp-escape.js
File renamed without changes
View
2  package.json
@@ -1,6 +1,6 @@
{
"name": "filternet",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "A proxy library that provides easy hooks to manipulate http and https traffic consistently.",
"author": { "name": "Mike Axiak", "email": "mike@axiak.net" },
"repository": {
Please sign in to comment.
Something went wrong with that request. Please try again.