forked from chook/dynalite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamite-proxy.js
executable file
·100 lines (80 loc) · 2.52 KB
/
dynamite-proxy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env node
const TABLE_NAME_HEADER = "x-table-name";
const fs = require("fs");
const http = require('http');
const httpProxy = require('http-proxy');
const argv = require('minimist')(process.argv.slice(2));
if (argv.help) {
return console.log([
'',
'Usage: node dynamite-proxy.js [options]',
'',
'A proxy http server for the real dynalite instance',
'',
'Options:',
'--help Display this help message and exit',
'--port <port> The port for the proxy to listen on',
'--dynamite <number> The number of dynamo db instances behind this proxy',
'--tablesMappingPath <path> A json table mapping file',
''
].join('\n'))
}
var port = argv.port;
var dynamiteCount = argv.dynamite;
var tablesMappingPath = argv.tablesMappingPath;
if (!port) {
return console.log("--port is missing");
}
if (!dynamiteCount) {
return console.log("--dynamite is missing");
}
if (!tablesMappingPath || !fs.existsSync(tablesMappingPath)) {
return console.log("--tablesMappingPath is missing (or the file is not exists)");
}
var tableNamesMapping;
try {
var content = fs.readFileSync(tablesMappingPath);
tableNamesMapping = JSON.parse(content);
} catch (e) {
console.log("Error reading " + tablesMappingPath);
return console.log(e);
}
var agent = new http.Agent({ keepAlive: true });
var proxy = httpProxy.createProxyServer({agent: agent});
// We use redirect instead of proxy in order to avoid the amount of connections
// between the proxy and dynalite.
//
var useRedirect = true;
const requestHandler = (request, response) => {
var tableName = request.headers[TABLE_NAME_HEADER];
var targetInstancePort = calcPortByTableName(port + 1, tableName, dynamiteCount);
var targetUrl = 'http://127.0.0.1:' + targetInstancePort;
if (useRedirect) {
response.writeHead(307, {
'Location': targetUrl
});
response.end();
} else {
proxy.web(request, response, { target: targetUrl }, function(error) {
res.statusCode = 500;
res.write(error.toString());
res.end();
});
}
}
const server = http.createServer(requestHandler)
server.listen(argv.port);
console.log("Dynamite count: " + dynamiteCount);
console.log("Tables mapping file: " + tablesMappingPath);
console.log("Proxy listening on port " + argv.port);
calcPortByTableName = function(basePort, tableName, dynamiteCount) {
let mapping;
if (tableName) {
mapping = tableNamesMapping[tableName.toLowerCase()];
}
if (!mapping) {
mapping = tableNamesMapping["default"];
}
let offset = (mapping % dynamiteCount);
return basePort + offset;
}