@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1'use strict';
2
3var JX = require('./lib/javelin').JX;
4var http = require('http');
5var https = require('https');
6var util = require('util');
7var fs = require('fs');
8
9function parse_command_line_arguments(argv) {
10 var args = {
11 test: false,
12 debug: false,
13 config: null
14 };
15
16 for (var ii = 2; ii < argv.length; ii++) {
17 var arg = argv[ii];
18 var matches = arg.match(/^--([^=]+)=(.*)$/);
19 if (!matches) {
20 throw new Error('Unknown argument "' + arg + '"!');
21 }
22 if (!(matches[1] in args)) {
23 throw new Error('Unknown argument "' + matches[1] + '"!');
24 }
25 args[matches[1]] = matches[2];
26 }
27
28 return args;
29}
30
31function parse_config(args) {
32 var data = fs.readFileSync(args.config);
33 return JSON.parse(data);
34}
35
36require('./lib/AphlictLog');
37
38var debug = new JX.AphlictLog();
39
40var args = parse_command_line_arguments(process.argv);
41var config = parse_config(args);
42
43if (args.test || args.debug) {
44 debug.addConsole(console);
45 debug.setTrace(true);
46}
47
48function set_exit_code(code) {
49 process.on('exit', function() {
50 process.exit(code);
51 });
52}
53
54process.on('uncaughtException', function(err) {
55 var context = null;
56 if (err.code == 'EACCES') {
57 context = util.format(
58 'Unable to open file ("%s"). Check that permissions are set ' +
59 'correctly.',
60 err.path);
61 }
62
63 var message = [
64 '\n<<< UNCAUGHT EXCEPTION! >>>',
65 ];
66 if (context) {
67 message.push(context);
68 }
69 message.push(err.stack);
70
71 debug.log(message.join('\n\n'));
72 set_exit_code(1);
73});
74
75try {
76 require('ws');
77} catch (ex) {
78 throw new Error(
79 'You need to install the Node.js "ws" module for websocket support. ' +
80 'See "Notifications User Guide: Setup and Configuration" in the ' +
81 'documentation for instructions. ' + ex.toString());
82}
83
84// NOTE: Require these only after checking for the "ws" module, since they
85// depend on it.
86
87require('./lib/AphlictAdminServer');
88require('./lib/AphlictClientServer');
89require('./lib/AphlictPeerList');
90require('./lib/AphlictPeer');
91
92var ii;
93
94var logs = config.logs || [];
95for (ii = 0; ii < logs.length; ii++) {
96 debug.addLog(logs[ii].path);
97}
98
99var servers = [];
100for (ii = 0; ii < config.servers.length; ii++) {
101 var spec = config.servers[ii];
102
103 spec.listen = spec.listen || '0.0.0.0';
104
105 if (spec['ssl.key']) {
106 spec['ssl.key'] = fs.readFileSync(spec['ssl.key']);
107 }
108
109 if (spec['ssl.cert']){
110 spec['ssl.cert'] = fs.readFileSync(spec['ssl.cert']);
111 if (spec['ssl.chain']){
112 spec['ssl.cert'] += "\n" + fs.readFileSync(spec['ssl.chain']);
113 }
114 }
115
116 servers.push(spec);
117}
118
119// If we're just doing a configuration test, exit here before starting any
120// servers.
121if (args.test) {
122 debug.log('Configuration test OK.');
123 set_exit_code(0);
124 return;
125}
126
127debug.log('Starting servers (service PID %d).', process.pid);
128
129for (ii = 0; ii < logs.length; ii++) {
130 debug.log('Logging to "%s".', logs[ii].path);
131}
132
133var aphlict_servers = [];
134var aphlict_clients = [];
135var aphlict_admins = [];
136for (ii = 0; ii < servers.length; ii++) {
137 var server = servers[ii];
138 var is_client = (server.type == 'client');
139
140 var http_server;
141 if (server['ssl.key']) {
142 var https_config = {
143 key: server['ssl.key'],
144 cert: server['ssl.cert'],
145 };
146
147 http_server = https.createServer(https_config);
148 } else {
149 http_server = http.createServer();
150 }
151
152 var aphlict_server;
153 if (is_client) {
154 aphlict_server = new JX.AphlictClientServer(http_server);
155 } else {
156 aphlict_server = new JX.AphlictAdminServer(http_server);
157 }
158
159 aphlict_server.setLogger(debug);
160 aphlict_server.listen(server.port, server.listen);
161
162 debug.log(
163 'Started %s server (Port %d, %s).',
164 server.type,
165 server.port,
166 server['ssl.key'] ? 'With SSL' : 'No SSL');
167
168 aphlict_servers.push(aphlict_server);
169
170 if (is_client) {
171 aphlict_clients.push(aphlict_server);
172 } else {
173 aphlict_admins.push(aphlict_server);
174 }
175}
176
177var peer_list = new JX.AphlictPeerList();
178
179debug.log(
180 'This server has fingerprint "%s".',
181 peer_list.getFingerprint());
182
183var cluster = config.cluster || [];
184for (ii = 0; ii < cluster.length; ii++) {
185 var peer = cluster[ii];
186
187 var peer_client = new JX.AphlictPeer()
188 .setHost(peer.host)
189 .setPort(peer.port)
190 .setProtocol(peer.protocol);
191
192 peer_list.addPeer(peer_client);
193}
194
195for (ii = 0; ii < aphlict_admins.length; ii++) {
196 var admin_server = aphlict_admins[ii];
197 admin_server.setClientServers(aphlict_clients);
198 admin_server.setPeerList(peer_list);
199}
200
201for (ii = 0; ii < aphlict_clients.length; ii++) {
202 var client_server = aphlict_clients[ii];
203 client_server.setAdminServers(aphlict_admins);
204}