Passed
Push — master ( 9f45dd...1c9b1d )
by Evgeny
01:33
created

lib/network.js (1 issue)

Severity
1
var IP = null;
2
var args = null;
3
var machine = null;
4
var request = null;
5
6
var get_protocol = function() {
7
	return 'http' + (args.https && 's' || '') + '://';
8
};
9
10
var get_req = function(req, host) {
11
	return new Promise(function(resolve) {
12
		return request({
13
			url: host + req.originalUrl,
14
			headers: {'docker-server': 'force', 'content-type': 'application/json', 'authorization': req.get('Authorization')},
15
			body: req.body && JSON.stringify(req.body) || undefined,
16
			method: req.method
17
		}, function (err, res, body) {
18
			// console.debug('request:', host, err, typeof body, body);
19
			if (err) {
20
				console.error('err:', host, err);
21
				return resolve({'body': [err], 'host': host});
22
			}
23
			
24
			try {
25
				return resolve({'body': typeof body === 'string' && JSON.parse(body) || body, 'host': host});
26
			} catch(e) {
27
				if (body.startsWith('error')) {
28
					body = {'error': body};
29
				} else {
30
					console.error('Error in get_req on', host, ':', e, typeof body, body);
31
				}
32
				
33
				return resolve({'body': [body], 'host': host});
34
			}
35
		});
36
	});
37
};
38
39
var handle_cluster_request = function(req, res, next) {
40
	return function(ip) {
41
		if (ip === IP) {
42
			next();
43
		} else {
44
			get_req(req, ip).then(function(ip_obj) {
45
				res.send(ip_obj.body || null);
46
			});
47
		}
48
	};
49
};
50
51
var handle_cluster = function(req, res, next) {
52
	if (req.method === 'PUT') {
53
		machine.next(IP).then(handle_cluster_request(req, res, next));
54
	} else if(~['GET', 'DELETE', 'POST'].indexOf(req.method)) {
55
		machine.all(IP).then(function(ips) {
56
			var promises = [];
57
			for (var i in ips) {
58
				if (ips.hasOwnProperty(i)) {
59
					promises.push(get_req(req, ips[i].host));
60
				}
61
			}
62
			
63
			return Promise.all(promises).then(function(responses) {
64
				var response = [];
65
				for (var i = 0; i < responses.length; ++i) {
66
					// Add the host to each result for more clearance for the client.
67
					if (responses[i].body.length) {
68
						for (var j in responses[i].body) {
0 ignored issues
show
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
69
							responses[i].body.host = responses[i].host;
70
						}
71
					} else {
72
						responses[i].body.host = responses[i].host;
73
					}
74
					response = response.concat(responses[i].body);
75
				}
76
				
77
				res.send(response);
78
			});
79
		});
80
	} else {
81
		res.sendStatus(400);
82
	}
83
};
84
85
86
module.exports = function(cli_args) {
87
	args = cli_args;
88
	
89
	return {
90
		'get_protocol': get_protocol,
91
		'check': function(token) {
92
			return function (req, res, next) {
93
				if (req.get('Authorization') === token) {
94
					next();
95
				} else {
96
					res.sendStatus(401);
97
				}
98
			};
99
		},
100
		'protocol': function(app) {
101
			if (args.https) {
102
				const fs = require('fs');
103
				
104
				if (fs.existsSync('/certs/privkey.pem') && fs.existsSync('/certs/cert.pem')) {
105
					try {
106
						return require('https').createServer({
107
							key: fs.readFileSync('/certs/privkey.pem', 'utf8'),
108
							cert: fs.readFileSync('/certs/cert.pem', 'utf8'),
109
							ca: fs.existsSync('/certs/chain.pem') && fs.readFileSync('/certs/chain.pem', 'utf8') || undefined
110
						}, app);
111
					} catch (e) {
112
						console.error('Could not start secure server:', e);
113
						return require('http').createServer(app);
114
					}
115
				}
116
			}
117
			
118
			return require('http').createServer(app);
119
		},
120
		'balance': function(port) {
121
			if (args.cluster) {
122
				IP = get_protocol() + require('ip').address() + ':' + port;
123
				machine = require('./machine.js')(args);
124
				request = require('request');
125
				
126
				machine.cpu(IP);
127
				setInterval(function() { machine.cpu(IP); }, 30000);
128
			}
129
			
130
			return function (req, res, next) {
131
				if (args.cluster && req.get('docker-server') !== 'force') {
132
					handle_cluster(req, res, next);
133
				} else {
134
					next();
135
				}
136
			};
137
		}
138
	};
139
};