-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.js
110 lines (95 loc) · 2.82 KB
/
app.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
101
102
103
104
105
106
107
108
109
110
'use strict';
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
// Config parameters.
var config = {
incomingPort: null,
outgoingPort: null,
outgoingHost: 'localhost',
root: '.'
};
function parseConfig(args) {
var keys = ['incomingPort', 'outgoingPort', 'outgoingHost', 'root'];
args.forEach(function (arg, index) {
var key = keys[index];
config[key] = arg;
});
}
var args = process.argv.slice(2);
parseConfig(args);
// Validate config parameters.
if (!config.incomingPort) {
console.error('Error: missing incoming port');
process.exit(1);
}
if (!config.outgoingPort) {
console.error('Error: missing outgoing port');
process.exit(1);
}
// Set up server.
http.createServer(function (req, res) {
var files = searchPath(req);
var result = readFirstExisting(files);
if (result !== null) {
var file = result.file;
var contents = result.contents;
// TODO Should probably set content type...
console.log('Serving', file);
return res.end(contents);
}
var proxyReq = proxy(req, res);
console.log('Proxying to', proxyReq.method, proxyReq.path);
}).listen(config.incomingPort, function () {
console.log('Listening on port', config.incomingPort);
console.log('Proxying to', config.outgoingHost + ':' + config.outgoingPort);
console.log('Serving directory', config.root);
});
function searchPath(req) {
var urlPath = url.parse(req.url).pathname;
var filePath = path.join(config.root, urlPath);
// TODO Use `req` (method, headers, etc.) to create more precise matches.
return [
filePath,
path.join(filePath, 'index')
];
}
function readFirstExisting(files) {
for (var index in files) {
var file = files[index];
try {
var contents = fs.readFileSync(file, 'utf-8');
return {file: file, contents: contents};
} catch (ignored) {
}
}
return null;
}
function proxy(req, res) {
var method = req.method;
var url = req.url;
var headers = req.headers;
var options = {
hostname: config.outgoingHost,
port: config.outgoingPort,
path: url,
method: method,
headers: headers
};
var proxyReq = http.request(options, function (proxyRes) {
// Pipe status code and headers.
var statusCode = proxyRes.statusCode;
var headers = proxyRes.headers;
res.writeHead(statusCode, headers);
// Pipe response body.
proxyRes.pipe(res);
}).on('error', function (err) {
console.error('Failed proxying to', proxyReq.method, proxyReq.path);
//console.debug(err);
res.statusCode = 502;
res.end();
});
req.pipe(proxyReq);
return proxyReq;
}