forked from henszey/etcd-browser
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathserver.js
More file actions
102 lines (87 loc) · 2.84 KB
/
server.js
File metadata and controls
102 lines (87 loc) · 2.84 KB
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
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var etcdHost = process.env.ETCD_HOST || '172.17.42.1';
var etcdPort = process.env.ETCD_PORT || 4001;
var serverPort = process.env.SERVER_PORT || 8000;
var publicDir = 'frontend';
var authUser = process.env.AUTH_USER;
var authPass = process.env.AUTH_PASS;
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
"js": "text/javascript",
"css": "text/css"
};
http.createServer(function serverFile(req, res) {
// authenticaton
if(!auth(req, res)) {
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="MyRealmName"');
res.end('Unauthorized');
return;
}
if(req.url === '/'){
req.url = '/index.html';
} else if(req.url.substr(0, 3) === '/v2') {
// avoid fileExists for /v2 routes
return proxy(req, res);
}
var uri = url.parse(req.url).pathname;
var filename = path.join(process.cwd(), publicDir, uri);
fs.exists(filename, function(exists) {
// proxy if file does not exist
if(!exists) return proxy(req, res);
// serve static file if exists
res.writeHead(200, mimeTypes[path.extname(filename).split(".")[1]]);
fs.createReadStream(filename).pipe(res);
});
}).listen(serverPort, function() {
console.log('proxy /api requests to etcd on ' + etcdHost + ':' + etcdPort);
console.log('etc-browser listening on port ' + serverPort);
});
function proxy(client_req, client_res) {
client_req.pipe(http.request({
hostname: etcdHost,
port: etcdPort,
path: client_req.url,
method: client_req.method
}, function(res) {
// if etcd returns that the requested page has been moved
// to a different location, indicates that the node we are
// querying is not the leader. This will redo the request
// on the leader which is reported by the Location header
if (res.statusCode === 307) {
newHost = url.parse(res.headers['location']).hostname;
client_req.pipe(http.request({
hostname: newHost,
port: etcdPort,
path: client_req.url,
method: client_req.method
}, function(res) {
console.log('Got response: ' + res.statusCode);
res.pipe(client_res, {end: true});
}, {end: true}));
} else {
res.pipe(client_res, {end: true});
}
}, {end: true}));
}
function auth(req, res) {
if(!authUser) return true;
var auth = req.headers.authorization;
if(!auth) return false;
// malformed
var parts = auth.split(' ');
if('basic' != parts[0].toLowerCase()) return false;
if(!parts[1]) return false;
auth = parts[1];
// credentials
auth = new Buffer(auth, 'base64').toString();
auth = auth.match(/^([^:]*):(.*)$/);
if(!auth) return false;
return (auth[1] === authUser && auth[2] === authPass)
}