Skip to content

Commit 4d13156

Browse files
committed
[dist] first
0 parents  commit 4d13156

File tree

9 files changed

+177
-0
lines changed

9 files changed

+177
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
*.swp

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/caronte');

lib/caronte.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
var http = require('http'),
2+
https = require('https'),
3+
url = require('url'),
4+
caronte = require('./caronte'),
5+
events = require('eventemitter2'),
6+
proxy = exports;
7+
8+
/**
9+
* Creates the proxy server.
10+
*
11+
* Examples:
12+
*
13+
* caronte.createProxyServer({ .. }, 8000)
14+
* // => '{ web: [Function], ws: [Function] ... }'
15+
*
16+
* @param {Object} Options Config object passed to the proxy
17+
*
18+
* @return {Object} Proxy Proxy object with handlers for `ws` and `web` requests
19+
*
20+
* @api public
21+
*/
22+
23+
proxy.createProxyServer = function createProxyServer(options) {
24+
if(!options) {
25+
throw new Error([
26+
"`options` is needed and it must have the following layout:",
27+
" ",
28+
" { ",
29+
" target : <url string to be parsed with the url module> ",
30+
" forward: <url string to be parsed with the url module> ",
31+
" ssl : <object to be passed to https.createServer()> ",
32+
" ws : <true/false, if you want to proxy websockets> ",
33+
" xfwd : <true/false, adds x-forward headers> ",
34+
" } ",
35+
" ",
36+
"NOTE: `options.ws` and `options.ssl` are optional ",
37+
" either one or both `options.target` and ",
38+
" `options.forward` must exist "
39+
].join("\n"));
40+
}
41+
42+
['target', 'forward'].forEach(function(key) {
43+
options[key] = url.parse(options[key]);
44+
});
45+
46+
return {
47+
__proto__: new events.EventEmitter2({ wildcard: true, delimiter: ':' }),
48+
web : caronte.createWebProxy(options),
49+
ws : caronte.createWsProxy(options),
50+
listen : function listen(port) {
51+
var server = options.ssl ? http.createServer(this.web) : https.createServer(options.ssl, this.web);
52+
53+
if(options.ws) {
54+
server.on('upgrade', this.ws);
55+
}
56+
57+
return server;
58+
}
59+
};
60+
};
61+

lib/caronte/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
var caronte = exports;
2+
3+
caronte.createWebProxy = require('./web');
4+
caronte.createWsProxy = require('./ws');

lib/caronte/streams/forward.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function ForwardStream() {
2+
3+
}

lib/caronte/streams/proxy.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function ProxyStream() {
2+
3+
}

lib/caronte/web.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
var passes = require('./web/');
2+
3+
module.exports = createWebProxy;
4+
5+
function createWebProxy(options) {
6+
passes = Object.keys(passes).map(function(pass) {
7+
return passes[pass];
8+
});
9+
10+
return function(req, res) {
11+
var self = this;
12+
13+
self.emit('caronte:web:begin', req, res);
14+
15+
passes.forEach(function(pass) {
16+
var event = 'caronte:web:' + pass.name.toLowerCase();
17+
18+
self.emit(event + ':begin', req, res);
19+
pass(req, res, options);
20+
self.emit(event + ':end');
21+
});
22+
23+
self.emit('caronte:web:end');
24+
};
25+
};

lib/caronte/web/index.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
var ForwardStream = require('../streams/forward'),
2+
ProxyStream = require('../streams/proxy'),
3+
passes = exports;
4+
5+
/*!
6+
* List of passes.
7+
*
8+
* A `pass` is just a function that is executed on `req, res, options`
9+
* so that you can easily add new checks while still keeping the base
10+
* flexible.
11+
*
12+
*/
13+
14+
passes.XHeaders = XHeaders;
15+
passes.deleteLength = deleteLength;
16+
passes.timeout = timeout;
17+
passes.stream = stream;
18+
19+
function deleteLength(req, res, options) {
20+
if(req.method === 'DELETE' && !req.headers['content-length']) {
21+
req.headers['content-length'] = '0';
22+
}
23+
}
24+
25+
function timeout(req, res, options) {
26+
if(options.timeout) {
27+
req.socket.setTimeout(options.timeout);
28+
}
29+
}
30+
31+
function XHeaders(req, res, options) {
32+
var values = {
33+
for : req.connection.remoteAddress || req.socket.remoteAddress,
34+
port : req.connection.remotePort || req.socket.remotePort,
35+
proto: req.isSpdy ? 'https' : (req.connection.pair ? 'https' : 'http')
36+
};
37+
38+
['for', 'port', 'proto'].forEach(function(header) {
39+
req.headers['x-forwarded-' + header] =
40+
(req.headers['x-forwarded-' + header] || '') +
41+
(req.headers['x-forwarded-' + header] ? ',' : '') +
42+
values[header]
43+
});
44+
}
45+
46+
function stream(req, res, options) {
47+
if(options.forward) {
48+
req.pipe(new ForwardStream(options.forward));
49+
}
50+
51+
if(options.target) {
52+
return req.pipe(new ProxyStream(res, options)).pipe(res);
53+
}
54+
55+
res.end();
56+
}

package.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name" : "caronte",
3+
"version" : "0.0.0",
4+
"description" : "HTTP proxying for the masses",
5+
"author" : "yawnt <[email protected]>",
6+
7+
"main" : "index.js",
8+
9+
"dependencies" : {
10+
"eventemitter2": "*"
11+
},
12+
"devDependencies": {
13+
"mocha" : "*",
14+
"expect.js": "*",
15+
"dox" : "*"
16+
},
17+
"scripts" : {
18+
"test" : "mocha -t 20000 -R spec -r expect test/*-test.js"
19+
},
20+
21+
"license" : "MIT"
22+
}

0 commit comments

Comments
 (0)