Skip to content
Browse files

Initial commit.

  • Loading branch information...
0 parents commit 6075bc368ba7c5663578ebc513dd6e12f00f82bc @tgetgood tgetgood committed Jan 13, 2012
Showing with 210 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +40 −0 app.js
  3. +18 −0 package.json
  4. +85 −0 scriptInjectorProxy.js
  5. +66 −0 solrProxy.js
1 .gitignore
@@ -0,0 +1 @@
+node_modules/*
40 app.js
@@ -0,0 +1,40 @@
+
+var httpProxy = require('http-proxy');
+var url = require('url');
+
+httpProxy.createServer(function(req, res, proxy) {
+
+ var isHtml = false,
+ write = res.write,
+ writeHead = res.writeHead,
+ params = url.parse(req.url, true).query;
+
+ delete req.headers['accept-encoding'];
+
+ res.writeHead = function(code, headers) {
+ isHtml = (headers['content-type'] == 'text/html');
+ writeHead.apply(this, arguments);
+ }
+
+ res.write = function(data, encoding) {
+ if (isHtml) {
+ var str = data.toString();
+ var i = 0;
+ str = str.replace(/<(h[0-9][^>]*)>/g, function(str, match) {
+ if (i == params.header) {
+ str = '<' + match + ' id="header-jump">';
+ }
+ i += 1;
+ return str;
+ });
+ data = new Buffer(str);
+ }
+
+ write.call(this, data, encoding);
+ };
+
+ proxy.proxyRequest(req, res, {
+ host: 'localhost',
+ port: 80,
+ });
+}).listen(9000);
18 package.json
@@ -0,0 +1,18 @@
+{
+ "name": "ew-node-proxies",
+ "version": "0.0.0",
+ "description" :"Various proxies, see headers in code files for specifics.",
+ "Author": "Divers, see individual scripts.",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/evolvingweb/node-proxies.git"
+ },
+ "dependencies": {
+ "http-proxy": "0.8.0",
+ "htmlparser": ">= 1.7.x"
+ },
+ "engines": {
+ "node": ">= 0.6.5"
+ }
+}
+
85 scriptInjectorProxy.js
@@ -0,0 +1,85 @@
+// scriptInjectorProxy.js
+//
+// A proxy that allows you to inject arbitrary javascript into a webpage by
+// passing it through a proxy. Most useful when combined with the following
+// bookmarklet (or some alteration thereof):
+//
+// javascript: document.location = "http://localhost:9000?dest=" + document.location
+//
+// In its simpliest form (that above), the proxy injects jQuery and nothing
+// else. To inject other scripts, add to the GET arguments:
+//
+// &script=example.com/script.js,mysite.localhost/scripts/stuff.js,...
+//
+// Currently jQuery is injected always, without regard to whether or not the
+// site has it to begin with.
+//
+// Created: 06/01/2012
+// Last updated: 13/01/2012
+//
+// Author: Thomas Getgood <thomas@evolvingweb.ca>
+// Available: http://github.com/evolvingweb/node-proxies.git
+
+
+// TODO:
+// * get 'script=' GET argument working.
+// * Fix paths.
+// * Catch 302s and reproxy to the redirected url.
+// * Try to deal with https (it feels like this should be hard, but maybe not).
+
+
+var httpProxy = require('http-proxy');
+var url = require('url');
+
+httpProxy.createServer(function(req, res, proxy) {
+
+ var isHtml = false,
+ write = res.write,
+ writeHead = res.writeHead,
+ params = url.parse(req.url, true).query,
+ dest = params.dest || 'localhost',
+ destination;
+
+ dest = dest.match(/^http/) ? dest : 'http://' + dest;
+ destination = url.parse(dest, true);
+
+ req.headers['host'] = destination.host;
+ req.headers['url'] = destination.href;
+
+ // console.log(dest);
+ // console.log("-------------------------------------------");
+ // console.log(destination);
+
+ // console.log(req.headers);
+
+ // We don't want to deal with gzip...
+ delete req.headers['accept-encoding'];
+
+ res.writeHead = function(code, headers) {
+ isHtml = headers['content-type'] && headers['content-type'].match('text/html');
+ writeHead.apply(this, arguments);
+ }
+
+ res.write = function(data, encoding) {
+ if (isHtml && params.dest) {
+ var str = data.toString();
+ var scriptTag = '<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script>';
+ var baseTag = '<base href="' + (dest.replace(/\/$/, '') || '') + '"/>';
+ // console.log(str);
+ // console.log("\n----------------------------------------------------------\n");
+
+ str = str.replace(/(<head[^>]*>)/, "$1" + "\n" + scriptTag + "\n" + baseTag);
+
+ data = new Buffer(str);
+ }
+
+ write.call(this, data, encoding);
+ };
+
+ proxy.proxyRequest(req, res, {
+ host: destination.host,
+ port: 80,
+ });
+}).listen(9000, function () {
+ console.log("Waiting for requests...");
+});
66 solrProxy.js
@@ -0,0 +1,66 @@
+// solrProxy.js
+//
+// Very simple reverse proxy to sit in front of solr and protect it from
+// malicious queries. Originally intended for use with the AJAX-Solr library,
+// but more generally applicable anyone wishing to expose Solr to the outside
+// world.
+//
+// Created: 09/01/2012
+// Last modified: 13/01/2012
+//
+// Author: Thomas Getgood <thomas@evolvingweb.ca>
+
+
+// Filter applied by proxy:
+//
+// Very restrictive. Loosen with care.
+//
+// Only allow GETs
+//
+// Disable the 'qt' parameter
+// Disable the 'commit' parameter
+// only allow access to /solr/select
+// 100 rows max per query
+
+
+// TODO:
+// * log IPs of offending queries.
+// * log intialisation time so that we can see when it goes down.
+
+
+var httpProxy = require('http-proxy'),
+ url = require('url');
+
+var querySafe = function (params) {
+ var query = path.query;
+ if (params.pathname === '/solr/select' &&
+ query.qt === undefined &&
+ query.commit === undefined &&
+ (query.rows === undefined || query.rows <= 100)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+httpProxy.createServer(function(req, res, proxy) {
+
+ var params = (url.parse(req.url, true));
+
+ if (res.method === 'GET' && querySafe(params)) {
+ proxy.proxyRequest(req, res, {
+ host: 'localhost',
+ port: 8080,
+ });
+ }
+ else {
+ res.writeHead(403, {'Content-Type': 'text/plain'});
+ res.write("Invalid query.\n");
+ res.end();
+ console.log("Request refused:\n" + req);
+ }
+}).listen(8008, function () {
+ console.log("Proxy ready.")
+ });
+

0 comments on commit 6075bc3

Please sign in to comment.
Something went wrong with that request. Please try again.