Skip to content

Instantly share code, notes, and snippets.

@sporkmonger
Created December 3, 2009 04:51
Show Gist options
  • Save sporkmonger/247896 to your computer and use it in GitHub Desktop.
Save sporkmonger/247896 to your computer and use it in GitHub Desktop.
var sys = require('sys'),
http = require('http');
var STATUS_CODES = {
100 : 'Continue',
101 : 'Switching Protocols',
200 : 'OK',
201 : 'Created',
202 : 'Accepted',
203 : 'Non-Authoritative Information',
204 : 'No Content',
205 : 'Reset Content',
206 : 'Partial Content',
300 : 'Multiple Choices',
301 : 'Moved Permanently',
302 : 'Moved Temporarily',
303 : 'See Other',
304 : 'Not Modified',
305 : 'Use Proxy',
400 : 'Bad Request',
401 : 'Unauthorized',
402 : 'Payment Required',
403 : 'Forbidden',
404 : 'Not Found',
405 : 'Method Not Allowed',
406 : 'Not Acceptable',
407 : 'Proxy Authentication Required',
408 : 'Request Time-out',
409 : 'Conflict',
410 : 'Gone',
411 : 'Length Required',
412 : 'Precondition Failed',
413 : 'Request Entity Too Large',
414 : 'Request-URI Too Large',
415 : 'Unsupported Media Type',
500 : 'Internal Server Error',
501 : 'Not Implemented',
502 : 'Bad Gateway',
503 : 'Service Unavailable',
504 : 'Gateway Time-out',
505 : 'HTTP Version not supported'
};
function OutgoingRequest(method, uri, version, headers, body) {
this.method = method;
this.uri = uri;
this.httpVersion = version;
this.headers = headers;
this.body = body;
this.createClient = function() {
var uriRegexp =
/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/;
var match = uriRegexp.exec(this.uri);
this.parsedUri = {
"scheme": match[2],
"authority": match[4],
"path": match[5],
"query": match[7],
"fragment": match[9]
};
this.parsedUri['requestUri'] = this.parsedUri['path'];
if (this.parsedUri['query']) {
this.parsedUri['requestUri'] += "?" + this.parsedUri['query'];
}
var hostname = this.parsedUri.authority.split(":");
var host = hostname[0];
var port = hostname[1];
this.headers['host'] = this.parsedUri.authority;
if (this.body && this.body.length > 0) {
this.headers['content-length'] = this.body.length;
}
this.headers['accept-encoding'] = null;
return http.createClient(port || 80, host);
}
}
exports.OutgoingRequest = OutgoingRequest;
exports.rewriteAuthority = function(request, newAuthority) {
if (!request.parsedUri) {
request.parsedUri = http.parseUri(request.uri);
}
var currentAuthority = request.parsedUri['authority'];
var authorityIndex = request.uri.indexOf(currentAuthority);
var prefix = request.uri.substring(0, authorityIndex);
var suffix = request.uri.substring(authorityIndex + currentAuthority.length);
request.uri = prefix + newAuthority + suffix;
}
function Proxy() {
process.EventEmitter.call(this);
}
sys.inherits(Proxy, process.EventEmitter);
exports.Proxy = Proxy;
exports.createProxy = function() {
var proxy = new Proxy();
proxy.server = http.createServer(function (request, response) {
var incomingRequestBody = '';
request.addListener("body", function(chunk) {
incomingRequestBody += chunk;
})
request.addListener("complete", function() {
var outgoingRequest = new OutgoingRequest(
request.method,
request.uri.full,
request.httpVersion,
request.headers,
incomingRequestBody
);
proxy.emit("request", outgoingRequest);
var client = outgoingRequest.createClient();
var requestUri = outgoingRequest.parsedUri['requestUri'] || "/";
var clientRequest = null;
switch(outgoingRequest.method) {
case "DELETE":
clientRequest = client.del(requestUri, outgoingRequest.headers);
break;
case "PUT":
clientRequest = client.put(requestUri, outgoingRequest.headers);
break;
case "POST":
clientRequest = client.post(requestUri, outgoingRequest.headers);
break;
case "HEAD":
clientRequest = client.head(requestUri, outgoingRequest.headers);
break;
case "GET":
default:
clientRequest = client.get(requestUri, outgoingRequest.headers);
break;
}
if (outgoingRequest.body && outgoingRequest.body.length > 0) {
clientRequest.sendBody(outgoingRequest.body);
}
//
// var content = outgoingRequest.method + ' ' +
// outgoingRequest.parsedUri['requestUri'] +
// ' HTTP/' + outgoingRequest.httpVersion;
// content += '\r\n';
// for (var header in outgoingRequest.headers) {
// content += header + ': ' + outgoingRequest.headers[header] + '\r\n';
// }
// content += '\r\n';
//
// if (outgoingRequest.method == "POST") {
// sys.puts('<' + outgoingRequest.uri + '>');
// sys.print(content + incomingRequestBody + '\r\n\r\n');
// }
//
clientRequest.finish(function (incomingResponse) {
incomingResponse.setBodyEncoding("binary");
var incomingBody = '';
incomingResponse.addListener("body", function (chunk) {
incomingBody += chunk;
});
incomingResponse.addListener("complete", function () {
response.sendHeader(
incomingResponse.statusCode,
incomingResponse.headers
);
response.sendBody(incomingBody, "binary");
response.finish();
//
// var rawResponse = incomingResponse.statusCode + ' ' +
// (STATUS_CODES[incomingResponse.statusCode] || 'Unknown') + '\r\n';
// for (var header in incomingResponse.headers) {
// rawResponse +=
// header + ': ' + incomingResponse.headers[header] + '\r\n';
// }
// rawResponse += '\r\n';
// if (incomingResponse.headers['content-type'] &&
// incomingResponse.headers['content-type'].indexOf('text') >= 0) {
// rawResponse += incomingBody + '\r\n\r\n';
// } else {
// rawResponse += '<non-text body omitted>\r\n\r\n';
// }
// if (outgoingRequest.method == "POST") {
// sys.puts(rawResponse);
// }
//
});
});
})
});
proxy.listen = function(port) {
proxy.server.listen(port);
}
return proxy;
};
var sys = require('sys');
var http = require('http');
var intercept = require('./intercept');
var proxy = intercept.createProxy();
proxy.listen(8000);
proxy.addListener("request", function(request) {
delete request.headers['if-modified-since'];
delete request.headers['if-none-modified'];
delete request.headers['cache-control'];
var newUri = http.parseUri(request.uri);
if (newUri.host == "savedbythegoog.appspot.com") {
intercept.rewriteAuthority(request, "localhost:8082");
}
});
sys.puts('Proxy running at http://127.0.0.1:8000/');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment