Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[api] First commit of http-proxy

  • Loading branch information...
commit 30b68c153270619119ec36615bb54ee7a2816ecc 0 parents
@indexzero indexzero authored
0  README.md
No changes.
120 lib/node-proxy.js
@@ -0,0 +1,120 @@
+/*
+ * node-proxy.js: Reverse proxy for node.js
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var sys = require('sys'),
+ http = require('http'),
+ events = require('events');
+
+//
+// Creates a new instance of NodeProxy
+//
+//exports.create = function (req, res) {
+// return new exports.nodeProxy(req, res);
+//};
+
+//
+// The NodeProxy factory
+//
+exports.NodeProxy = function () {
+ var self = this;
+ this.emitter = new(events.EventEmitter);
+
+ // If we were passed more than two arguments,
+ // assume they are request and response.
+ if(arguments.length >= 2) {
+ this.init(arguments[0], arguments[1]);
+ }
+};
+
+exports.NodeProxy.prototype = {
+ toArray: function (obj){
+ var len = obj.length,
+ arr = new Array(len);
+ for (var i = 0; i < len; ++i) {
+ arr[i] = obj[i];
+ }
+ return arr;
+ },
+
+ init: function (req, res) {
+ this.events = [];
+
+ this.onData = function () {
+ self.events.push(["data"].concat(self.toArray(arguments)));
+ };
+ this.onEnd = function () {
+ self.events.push(["end"].concat(self.toArray(arguments)));
+ };
+
+ req.addListener("data", this.onData);
+ req.addListener("end", this.onEnd);
+ },
+
+ proxyRequest: function (server, port, req, res) {
+ // Remark: nodeProxy.body exists solely for testability
+ this.body = '';
+ var self = this;
+
+ // Open new HTTP request to internal resource with will act as a reverse proxy pass
+ var c = http.createClient(port, server);
+
+ // Make request to internal server, passing along the method and headers
+ var reverse_proxy = c.request(req.method, req.url, req.headers);
+
+ // Add a listener for the connection timeout event
+ reverse_proxy.connection.addListener('error', function(err) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+
+ if(req.method !== 'HEAD') {
+ res.write('Not a HEAD request');
+ }
+
+ res.end();
+ });
+
+ // Add a listener for the reverse_proxy response event
+ reverse_proxy.addListener("response", function (response) {
+ // Set the response headers of the client response
+ res.writeHead(response.statusCode, response.headers);
+
+ // Add event handler for the proxied response in chunks
+ response.addListener("data", function (chunk) {
+ if(req.method !== 'HEAD') {
+ res.write(chunk, 'binary');
+ this.body += chunk;
+ }
+ });
+
+ // Add event listener for end of proxied response
+ response.addListener("end", function () {
+ res.end();
+ });
+ });
+
+ // Chunk the client request body as chunks from the proxied request come in
+ req.addListener("data", function (chunk) {
+ reverse_proxy.write(chunk, 'binary');
+ })
+
+ // At the end of the client request, we are going to stop the proxied request
+ req.addListener("end", function () {
+ // Remark: Emit the end event for testability
+ self.emitter.emit('something', self.body);
+
+ reverse_proxy.end();
+ });
+
+ req.removeListener('data', this.onData);
+ req.removeListener('end', this.onEnd);
+
+ // Rebroadcast any events that have been buffered
+ for (var i = 0, len = this.events.length; i < len; ++i) {
+ req.emit.apply(req, this.events[i]);
+ }
+ }
+};
75 test/node-proxy-test.js
@@ -0,0 +1,75 @@
+/*
+ * node-proxy-test.js: Tests for node-proxy. Reverse proxy for node.js
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var vows = require('vows'),
+ sys = require('sys'),
+ assert = require('assert'),
+ http = require('http');
+
+require.paths.unshift(require('path').join(__dirname, '../lib/'));
+
+var NodeProxy = require('node-proxy').NodeProxy;
+
+//
+// Simple 'hello world' response for test purposes
+//
+var helloWorld = function(req, res) {
+ res.sendHeader(200, {'Content-Type': 'text/plain'});
+ res.write('hello world')
+ res.end();
+};
+
+//
+// Creates the reverse proxy server
+//
+var startProxy = function (server, port, proxy) {
+ http.createServer(function (req, res){
+ // Initialize the nodeProxy and start proxying the request
+ proxy.init(req, res);
+ proxy.proxyRequest(server, port, req, res);
+ }).listen(8080);
+};
+
+//
+// Creates the 'hellonode' server
+//
+var startProxyTarget = function () {
+ http.createServer(function (req, res) {
+ helloWorld(req, res);
+ }).listen(8081);
+};
+
+//
+// The default test bootstrapper
+//
+var startProxyTest = function () {
+ var proxy = new (NodeProxy);
+ startProxy('127.0.0.1', 8081, proxy);
+ startProxyTarget();
+ return proxy;
+};
+
+var proxy = startProxyTest();
+proxy.emitter.addListener('something', function (body) {
+ sys.puts(body);
+})
+
+/*vows.describe('node-proxy').addBatch({
+ "When an incoming request is proxied to the helloNode server" : {
+ topic: function () {
+ var proxy = startProxyTest();
+ proxy.emitter.addListener('end', this.callback);
+ var client = http.createClient(8080, '127.0.0.1');
+ client.request('GET', '/');
+ },
+ "it should received 'hello world'": function (num) {
+ sys.puts('got callback');
+ //assert.equal(body, 'hello world');
+ }
+ }
+}).export(module);*/
Please sign in to comment.
Something went wrong with that request. Please try again.