rtjscomp 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +16 -9
- package/rtjscomp.js +191 -158
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rtjscomp",
|
|
3
|
-
"
|
|
4
|
-
"license": "Zlib",
|
|
5
|
-
"version": "0.8.1",
|
|
3
|
+
"version": "0.8.2",
|
|
6
4
|
"description": "php-like server but with javascript",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/L3P3/rtjscomp"
|
|
8
|
+
},
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/L3P3/rtjscomp/issues"
|
|
11
|
+
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"ipware": "latest",
|
|
14
14
|
"parse-multipart-data": "latest",
|
|
@@ -19,5 +19,12 @@
|
|
|
19
19
|
},
|
|
20
20
|
"bin": {
|
|
21
21
|
"rtjscomp": "./rtjscomp.js"
|
|
22
|
-
}
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"http",
|
|
25
|
+
"javascript",
|
|
26
|
+
"server"
|
|
27
|
+
],
|
|
28
|
+
"author": "L3P3 <dev@l3p3.de> (https://l3p3.de)",
|
|
29
|
+
"license": "Zlib"
|
|
23
30
|
}
|
package/rtjscomp.js
CHANGED
|
@@ -26,6 +26,7 @@ const AGENT_CHECK_BOT = /bot|googlebot|crawler|spider|robot|crawling|favicon/i;
|
|
|
26
26
|
const AGENT_CHECK_MOBIL = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
|
|
27
27
|
const HTTP_LIST_REG = /,\s*/;
|
|
28
28
|
|
|
29
|
+
let log_verbose = process.argv.includes('-v');
|
|
29
30
|
let port_http = 0;
|
|
30
31
|
let port_https = 0;
|
|
31
32
|
const file_type_mimes = new Map;
|
|
@@ -61,7 +62,7 @@ if (!Object.fromEntries) {
|
|
|
61
62
|
global.globals = rtjscomp;
|
|
62
63
|
global.actions = rtjscomp.actions;
|
|
63
64
|
global.data_load = name => {
|
|
64
|
-
log('[deprecated
|
|
65
|
+
log('[deprecated] load: ' + name);
|
|
65
66
|
try {
|
|
66
67
|
return fs.readFileSync(PATH_DATA + name, 'utf8');
|
|
67
68
|
}
|
|
@@ -70,7 +71,7 @@ global.data_load = name => {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
global.data_save = (name, data) => (
|
|
73
|
-
log('[deprecated
|
|
74
|
+
log('[deprecated] save: ' + name),
|
|
74
75
|
fs.writeFileSync(PATH_DATA + name, data, 'utf8')
|
|
75
76
|
)
|
|
76
77
|
global.number_check_int = number => (
|
|
@@ -81,13 +82,12 @@ global.number_check_uint = number => (
|
|
|
81
82
|
)
|
|
82
83
|
|
|
83
84
|
rtjscomp.data_load = async name => {
|
|
84
|
-
log('load: ' + name);
|
|
85
|
+
if (log_verbose) log('load: ' + PATH_DATA + name);
|
|
85
86
|
const data = await fsp.readFile(PATH_DATA + name, 'utf8').catch(() => null);
|
|
86
87
|
return name.endsWith('.json') ? JSON.parse(data || null) : data;
|
|
87
88
|
}
|
|
88
89
|
rtjscomp.data_load_watch = (name, callback) => (
|
|
89
90
|
file_keep_new(PATH_DATA + name, data => (
|
|
90
|
-
log('load: ' + name),
|
|
91
91
|
callback(
|
|
92
92
|
name.endsWith('.json')
|
|
93
93
|
? JSON.parse(data || null)
|
|
@@ -96,7 +96,7 @@ rtjscomp.data_load_watch = (name, callback) => (
|
|
|
96
96
|
))
|
|
97
97
|
)
|
|
98
98
|
rtjscomp.data_save = (name, data) => (
|
|
99
|
-
log('save: ' + name),
|
|
99
|
+
log_verbose && log('save: ' + PATH_DATA + name),
|
|
100
100
|
fsp.writeFile(
|
|
101
101
|
PATH_DATA + name,
|
|
102
102
|
name.endsWith('.json') ? JSON.stringify(data) : data,
|
|
@@ -119,68 +119,99 @@ const custom_require = path => {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
const services_active = new Map;
|
|
122
|
+
const services_loading = new Set;
|
|
122
123
|
const services_list_react = async () => {
|
|
123
124
|
await Promise.all(
|
|
124
125
|
Array.from(services_active.entries())
|
|
125
126
|
.filter(([path, _]) => !services.has(path))
|
|
126
127
|
.map(([_, service_object]) => service_stop(service_object, true))
|
|
127
128
|
);
|
|
128
|
-
for (const path of services)
|
|
129
|
-
|
|
129
|
+
for (const path of services)
|
|
130
|
+
if (!services_active.has(path)) {
|
|
131
|
+
await service_start(path);
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
const service_start = async path => {
|
|
133
135
|
const service_object = {
|
|
136
|
+
content: null,
|
|
137
|
+
handler_stop: null,
|
|
134
138
|
path,
|
|
135
|
-
start: null,
|
|
136
|
-
started: false,
|
|
137
|
-
stop: null,
|
|
138
139
|
stopped: false,
|
|
139
140
|
};
|
|
140
141
|
|
|
141
142
|
await file_keep_new(PATH_PUBLIC + path + '.service.js', async file_content => {
|
|
142
143
|
if (file_content === null) {
|
|
143
|
-
log('error
|
|
144
|
-
|
|
145
|
-
return;
|
|
144
|
+
log('[error] service file not found: ' + path);
|
|
145
|
+
return service_stop(service_object, true);
|
|
146
146
|
}
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
if (services_loading.size > 0) {
|
|
148
|
+
await Promise.all(Array.from(services_loading));
|
|
149
|
+
}
|
|
150
|
+
const start_promise = service_start_inner(path, service_object, file_content);
|
|
151
|
+
services_loading.add(start_promise);
|
|
152
|
+
await start_promise;
|
|
153
|
+
services_loading.delete(start_promise);
|
|
149
154
|
});
|
|
150
155
|
}
|
|
151
156
|
const service_start_inner = async (path, service_object, file_content) => {
|
|
157
|
+
if (services_active.has(path)) {
|
|
158
|
+
await service_stop_handler(service_object);
|
|
159
|
+
}
|
|
160
|
+
const content_object = service_object.content = {};
|
|
161
|
+
log('start service: ' + path);
|
|
162
|
+
|
|
163
|
+
const start_interval = setInterval(() => {
|
|
164
|
+
log('[warning] still starting service: ' + path);
|
|
165
|
+
}, 1e3);
|
|
166
|
+
|
|
152
167
|
try {
|
|
153
|
-
const fun =
|
|
154
|
-
|
|
155
|
-
`const log=a=>rtjscomp.log(${
|
|
168
|
+
const fun = (0, eval)(
|
|
169
|
+
`(async function(require){const log=a=>rtjscomp.log(${
|
|
156
170
|
JSON.stringify(path + ': ')
|
|
157
|
-
}+a);${file_content}`
|
|
171
|
+
}+a);${file_content + '\n'}})`
|
|
158
172
|
);
|
|
159
|
-
fun.call(
|
|
173
|
+
const result = await fun.call(content_object, custom_require);
|
|
174
|
+
if (service_object.stopped) {
|
|
175
|
+
clearInterval(start_interval);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (typeof result === 'function') {
|
|
179
|
+
service_object.handler_stop = result;
|
|
180
|
+
}
|
|
160
181
|
}
|
|
161
182
|
catch (err) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return;
|
|
183
|
+
clearInterval(start_interval);
|
|
184
|
+
log(`[error] ${path}: ${err.message}`);
|
|
185
|
+
if (service_object.stopped) return;
|
|
186
|
+
return service_stop(service_object, false);
|
|
165
187
|
}
|
|
166
188
|
|
|
167
|
-
|
|
189
|
+
const handler_start = content_object.start;
|
|
190
|
+
if (handler_start) {
|
|
191
|
+
log('[deprecated] service has start method: ' + path);
|
|
192
|
+
delete content_object.start;
|
|
168
193
|
try {
|
|
169
|
-
await
|
|
170
|
-
service_object.start = null;
|
|
171
|
-
service_object.started = true;
|
|
194
|
+
await handler_start();
|
|
172
195
|
}
|
|
173
196
|
catch (err) {
|
|
174
|
-
|
|
175
|
-
log(`error
|
|
176
|
-
return;
|
|
197
|
+
clearInterval(start_interval);
|
|
198
|
+
log(`[error] ${path} start: ${err.message}`);
|
|
199
|
+
return service_stop(service_object, false);
|
|
177
200
|
}
|
|
178
201
|
}
|
|
202
|
+
clearInterval(start_interval);
|
|
203
|
+
|
|
204
|
+
if (content_object.stop) {
|
|
205
|
+
log('[deprecated] service has stop method: ' + path);
|
|
206
|
+
service_object.handler_stop = content_object.stop;
|
|
207
|
+
delete content_object.stop;
|
|
208
|
+
}
|
|
209
|
+
|
|
179
210
|
services_active.set(path, service_object);
|
|
180
|
-
log('service
|
|
211
|
+
if (log_verbose) log('started service: ' + path);
|
|
181
212
|
}
|
|
182
213
|
const services_shutdown = () => (
|
|
183
|
-
log('shutdown services...'),
|
|
214
|
+
log_verbose && log('shutdown services...'),
|
|
184
215
|
Promise.all(
|
|
185
216
|
Array.from(services_active.values())
|
|
186
217
|
.map(service_object => service_stop(service_object, true))
|
|
@@ -190,28 +221,39 @@ const service_stop = async (service_object, forget) => {
|
|
|
190
221
|
service_object.stopped = true;
|
|
191
222
|
if (forget) fs.unwatchFile(PATH_PUBLIC + service_object.path + '.service.js');
|
|
192
223
|
await service_stop_handler(service_object);
|
|
193
|
-
services_active.delete(service_object.path);
|
|
194
|
-
log('service stopped: ' + service_object.path);
|
|
195
224
|
}
|
|
196
225
|
const service_stop_handler = async service_object => {
|
|
197
|
-
|
|
226
|
+
services_active.delete(service_object.path);
|
|
227
|
+
log('stop service: ' + service_object.path);
|
|
228
|
+
const handler_stop = service_object.handler_stop;
|
|
229
|
+
if (handler_stop) {
|
|
230
|
+
const stop_interval = setInterval(() => {
|
|
231
|
+
log('[warning] still stopping service: ' + service_object.path);
|
|
232
|
+
}, 1e3);
|
|
198
233
|
try {
|
|
199
|
-
|
|
200
|
-
|
|
234
|
+
service_object.handler_stop = null;
|
|
235
|
+
await handler_stop();
|
|
201
236
|
}
|
|
202
237
|
catch (err) {
|
|
203
|
-
log(`error
|
|
238
|
+
log(`[error] ${service_object.path} stop: ${err.message}`);
|
|
204
239
|
}
|
|
240
|
+
clearInterval(stop_interval);
|
|
205
241
|
}
|
|
242
|
+
if (log_verbose) log('stopped service: ' + service_object.path);
|
|
206
243
|
}
|
|
207
244
|
global.service_require = path => {
|
|
208
245
|
const service = services_active.get(path);
|
|
209
|
-
if (service) return service;
|
|
246
|
+
if (service != null) return service.content;
|
|
210
247
|
throw new Error('service required: ' + path);
|
|
211
248
|
}
|
|
212
|
-
global.service_require_try = path =>
|
|
213
|
-
services_active.get(path)
|
|
214
|
-
|
|
249
|
+
global.service_require_try = path => {
|
|
250
|
+
const service = services_active.get(path);
|
|
251
|
+
return (
|
|
252
|
+
service != null
|
|
253
|
+
? service.content
|
|
254
|
+
: null
|
|
255
|
+
);
|
|
256
|
+
}
|
|
215
257
|
|
|
216
258
|
const map_generate_bol = (set, data) => {
|
|
217
259
|
set.clear();
|
|
@@ -237,7 +279,7 @@ const map_generate_equ = (map, data) => {
|
|
|
237
279
|
|
|
238
280
|
const file_compare = (curr, prev, path) => (
|
|
239
281
|
curr.mtime > prev.mtime && (
|
|
240
|
-
log('file changed: ' + path),
|
|
282
|
+
log_verbose && log('file changed: ' + path),
|
|
241
283
|
true
|
|
242
284
|
)
|
|
243
285
|
)
|
|
@@ -251,7 +293,9 @@ const file_watch = (path, callback) => (
|
|
|
251
293
|
)
|
|
252
294
|
const file_keep_new = async (path, callback) => {
|
|
253
295
|
try {
|
|
254
|
-
|
|
296
|
+
const data = await fsp.readFile(path, 'utf8');
|
|
297
|
+
if (log_verbose) log('load file: ' + path);
|
|
298
|
+
await callback(data);
|
|
255
299
|
fs.watchFile(path, async (curr, prev) => {
|
|
256
300
|
if (file_compare(curr, prev, path)) {
|
|
257
301
|
await callback(
|
|
@@ -272,7 +316,7 @@ actions.log_clear = () => {
|
|
|
272
316
|
const log = rtjscomp.log = msg => (
|
|
273
317
|
console.log(msg),
|
|
274
318
|
log_history.push(msg),
|
|
275
|
-
spam('log', [msg])
|
|
319
|
+
spam_enabled ? spam('log', [msg]) : undefined
|
|
276
320
|
)
|
|
277
321
|
|
|
278
322
|
const spam_enabled = fs.existsSync('spam.csv');
|
|
@@ -281,17 +325,16 @@ actions.spam_save = async (muted = false) => {
|
|
|
281
325
|
if (!spam_enabled) return;
|
|
282
326
|
|
|
283
327
|
try {
|
|
284
|
-
|
|
328
|
+
const tmp = rtjscomp.spam_history;
|
|
285
329
|
rtjscomp.spam_history = '';
|
|
286
|
-
|
|
330
|
+
await fsp.appendFile('spam.csv', tmp, 'utf8');
|
|
331
|
+
if (log_verbose && !muted) log('spam.csv saved');
|
|
287
332
|
}
|
|
288
333
|
catch (err) {
|
|
289
|
-
log('error
|
|
334
|
+
log('[error] cannot save spam.csv: ' + err.message);
|
|
290
335
|
}
|
|
291
336
|
}
|
|
292
337
|
const spam = (type, data) => {
|
|
293
|
-
if (!spam_enabled) return;
|
|
294
|
-
|
|
295
338
|
rtjscomp.spam_history += (
|
|
296
339
|
Date.now() +
|
|
297
340
|
',' +
|
|
@@ -315,7 +358,7 @@ const request_handle = async (request, response, https) => {
|
|
|
315
358
|
https = request_headers['x-forwarded-proto'] === 'https';
|
|
316
359
|
}
|
|
317
360
|
|
|
318
|
-
spam('request', [https, request.url, request_ip]);
|
|
361
|
+
if (spam_enabled) spam('request', [https, request.url, request_ip]);
|
|
319
362
|
|
|
320
363
|
try {
|
|
321
364
|
const request_url_parsed = url.parse(request.url, false);
|
|
@@ -422,11 +465,11 @@ const request_handle = async (request, response, https) => {
|
|
|
422
465
|
file_function = file_cache_functions.get(path);
|
|
423
466
|
}
|
|
424
467
|
else {
|
|
425
|
-
log(`load ${
|
|
468
|
+
if (log_verbose) log(`load ${
|
|
426
469
|
file_dyn_enabled
|
|
427
470
|
? 'dynam'
|
|
428
471
|
: 'stat'
|
|
429
|
-
}ic file: ${
|
|
472
|
+
}ic file: ${path_real}`);
|
|
430
473
|
|
|
431
474
|
if (
|
|
432
475
|
file_privates.has(path) ||
|
|
@@ -516,14 +559,14 @@ const request_handle = async (request, response, https) => {
|
|
|
516
559
|
}
|
|
517
560
|
|
|
518
561
|
try {
|
|
519
|
-
file_function = eval(code += '}');
|
|
562
|
+
file_function = (0, eval)(code += '}');
|
|
520
563
|
}
|
|
521
564
|
catch (err) {
|
|
522
565
|
throw err.message;
|
|
523
566
|
}
|
|
524
567
|
}
|
|
525
568
|
catch (err) {
|
|
526
|
-
log(
|
|
569
|
+
log(`[error] ${path} compile: ${err}`);
|
|
527
570
|
throw 500;
|
|
528
571
|
}
|
|
529
572
|
|
|
@@ -578,7 +621,7 @@ const request_handle = async (request, response, https) => {
|
|
|
578
621
|
);
|
|
579
622
|
}
|
|
580
623
|
catch (err) {
|
|
581
|
-
log(
|
|
624
|
+
log(`[error] ${path} request query: ${err.message}`);
|
|
582
625
|
throw 400;
|
|
583
626
|
}
|
|
584
627
|
}
|
|
@@ -613,7 +656,7 @@ const request_handle = async (request, response, https) => {
|
|
|
613
656
|
}
|
|
614
657
|
}
|
|
615
658
|
catch (err) {
|
|
616
|
-
log(
|
|
659
|
+
log(`[error] ${path} request body: ${err.message}`);
|
|
617
660
|
throw 400;
|
|
618
661
|
}
|
|
619
662
|
}
|
|
@@ -641,7 +684,7 @@ const request_handle = async (request, response, https) => {
|
|
|
641
684
|
file_function_output = response;
|
|
642
685
|
}
|
|
643
686
|
|
|
644
|
-
spam('execute', [
|
|
687
|
+
if (spam_enabled) spam('execute', [
|
|
645
688
|
path,
|
|
646
689
|
Object.fromEntries(
|
|
647
690
|
Object.entries(file_function_input)
|
|
@@ -653,6 +696,10 @@ const request_handle = async (request, response, https) => {
|
|
|
653
696
|
)
|
|
654
697
|
]);
|
|
655
698
|
|
|
699
|
+
if (services_loading.size > 0) {
|
|
700
|
+
await Promise.all(Array.from(services_loading));
|
|
701
|
+
}
|
|
702
|
+
|
|
656
703
|
try {
|
|
657
704
|
await file_function(
|
|
658
705
|
file_function_input,
|
|
@@ -665,7 +712,7 @@ const request_handle = async (request, response, https) => {
|
|
|
665
712
|
}
|
|
666
713
|
catch (err) {
|
|
667
714
|
if (err instanceof Error) {
|
|
668
|
-
log(`error
|
|
715
|
+
log(`[error] ${path}: ${err.message}`);
|
|
669
716
|
|
|
670
717
|
if (err.message.startsWith('service required: ')) {
|
|
671
718
|
err = 503;
|
|
@@ -698,7 +745,7 @@ const request_handle = async (request, response, https) => {
|
|
|
698
745
|
file_data = fs.createReadStream(path_real);
|
|
699
746
|
}
|
|
700
747
|
|
|
701
|
-
spam('static_send', [path, file_gz_enabled]);
|
|
748
|
+
if (spam_enabled) spam('static_send', [path, file_gz_enabled]);
|
|
702
749
|
response.setHeader('Cache-Control', 'public, max-age=600');
|
|
703
750
|
|
|
704
751
|
if (file_gz_enabled) {
|
|
@@ -718,8 +765,8 @@ const request_handle = async (request, response, https) => {
|
|
|
718
765
|
err = 500;
|
|
719
766
|
}
|
|
720
767
|
|
|
721
|
-
if (err >= 400) {
|
|
722
|
-
log(`error ${err}
|
|
768
|
+
if (err >= 400 && log_verbose) {
|
|
769
|
+
log(`[error] request failed: ${err}; ${request_ip}; ${request.url}`);
|
|
723
770
|
}
|
|
724
771
|
|
|
725
772
|
response.writeHead(err, {
|
|
@@ -733,32 +780,33 @@ const request_handle = async (request, response, https) => {
|
|
|
733
780
|
let exiting = false;
|
|
734
781
|
actions.halt = async () => {
|
|
735
782
|
await Promise.all([
|
|
736
|
-
actions.http_stop(),
|
|
783
|
+
actions.http_stop && actions.http_stop(),
|
|
737
784
|
actions.https_stop && actions.https_stop(),
|
|
738
785
|
services_shutdown(),
|
|
739
|
-
]
|
|
786
|
+
]);
|
|
740
787
|
await actions.spam_save();
|
|
741
788
|
log('stopped everything');
|
|
742
789
|
}
|
|
743
790
|
actions.exit = async status => {
|
|
744
791
|
if (exiting) return;
|
|
792
|
+
exiting = true;
|
|
745
793
|
if (typeof status !== 'number') status = 0;
|
|
746
794
|
await actions.halt();
|
|
747
795
|
log('exiting...');
|
|
748
|
-
exiting = true;
|
|
749
796
|
process.exit(status);
|
|
750
797
|
}
|
|
751
798
|
|
|
752
799
|
process.on('uncaughtException', err => {
|
|
753
|
-
err = err.message || err;
|
|
754
800
|
if (typeof err === 'symbol') err = err.toString();
|
|
755
|
-
log('error uncaughtException: ' + err);
|
|
756
|
-
console.
|
|
801
|
+
log('[error] uncaughtException: ' + (err.message || err));
|
|
802
|
+
console.error(err);
|
|
803
|
+
if (exiting) process.exit(1);
|
|
757
804
|
actions.exit(1);
|
|
758
805
|
});
|
|
759
806
|
process.on('unhandledRejection', err => {
|
|
760
|
-
log('error unhandledRejection: ' + (err.message || err));
|
|
761
|
-
console.
|
|
807
|
+
log('[error] unhandledRejection: ' + (err.message || err));
|
|
808
|
+
console.error(err);
|
|
809
|
+
if (exiting) process.exit(1);
|
|
762
810
|
actions.exit(1);
|
|
763
811
|
});
|
|
764
812
|
process.on('exit', actions.exit);
|
|
@@ -776,7 +824,7 @@ await Promise.all([
|
|
|
776
824
|
fsp.stat(PATH_PUBLIC).catch(_ => null),
|
|
777
825
|
]).then(([stat_config, stat_data, stat_public]) => {
|
|
778
826
|
if (!stat_config) {
|
|
779
|
-
log('
|
|
827
|
+
log('create config template directory');
|
|
780
828
|
fs.mkdirSync(PATH_CONFIG);
|
|
781
829
|
fs.mkdirSync(PATH_CONFIG + 'ssl');
|
|
782
830
|
for (const file of 'file_type_dyns,file_type_mimes,file_type_nocompress,path_aliases,port_http,port_https,services'.split(',')) {
|
|
@@ -798,32 +846,30 @@ await Promise.all([
|
|
|
798
846
|
}
|
|
799
847
|
});
|
|
800
848
|
|
|
849
|
+
file_keep_new(PATH_CONFIG + 'services.txt', data => (
|
|
850
|
+
map_generate_bol(services, data),
|
|
851
|
+
services_list_react()
|
|
852
|
+
));
|
|
853
|
+
|
|
801
854
|
await Promise.all([
|
|
802
855
|
file_keep_new(PATH_CONFIG + 'init.js', data => {
|
|
803
856
|
if (!data) return;
|
|
804
|
-
log('[deprecated
|
|
857
|
+
log('[deprecated] run global init script');
|
|
805
858
|
try {
|
|
806
859
|
var require = custom_require;
|
|
807
|
-
eval(data);
|
|
860
|
+
(0, eval)(data);
|
|
808
861
|
}
|
|
809
862
|
catch (err) {
|
|
810
|
-
log('error
|
|
863
|
+
log('[error] init.js: ' + err.message);
|
|
811
864
|
}
|
|
812
865
|
}),
|
|
813
|
-
file_keep_new(PATH_CONFIG + 'services.txt', async data => {
|
|
814
|
-
log('load service list');
|
|
815
|
-
map_generate_bol(services, data);
|
|
816
|
-
await services_list_react();
|
|
817
|
-
}),
|
|
818
866
|
file_keep_new(PATH_CONFIG + 'file_type_mimes.txt', data => {
|
|
819
|
-
log('load file type map');
|
|
820
867
|
map_generate_equ(file_type_mimes, data);
|
|
821
868
|
if (!file_type_mimes.has('txt')) {
|
|
822
869
|
file_type_mimes.set('txt', 'text/plain; charset=utf-8');
|
|
823
870
|
}
|
|
824
871
|
}),
|
|
825
872
|
file_keep_new(PATH_CONFIG + 'path_aliases.txt', data => {
|
|
826
|
-
log('load path aliases map');
|
|
827
873
|
map_generate_equ(path_aliases, data);
|
|
828
874
|
path_aliases_templates.clear();
|
|
829
875
|
for (const [key, value] of path_aliases.entries()) {
|
|
@@ -843,38 +889,37 @@ await Promise.all([
|
|
|
843
889
|
}
|
|
844
890
|
}),
|
|
845
891
|
file_keep_new(PATH_CONFIG + 'file_type_dyns.txt', data => {
|
|
846
|
-
log('load dynamic file type list');
|
|
847
892
|
map_generate_bol(file_type_dyns, data);
|
|
848
893
|
}),
|
|
849
894
|
file_keep_new(PATH_CONFIG + 'file_type_nocompress.txt', data => {
|
|
850
|
-
log('load non-compressable file list');
|
|
851
895
|
map_generate_bol(file_type_nocompress, data);
|
|
852
896
|
}),
|
|
853
897
|
file_keep_new(PATH_CONFIG + 'file_raws.txt', data => {
|
|
854
898
|
if (!data) return;
|
|
855
|
-
log('load static file list');
|
|
856
899
|
map_generate_bol(file_raws, data);
|
|
857
900
|
}),
|
|
858
901
|
file_keep_new(PATH_CONFIG + 'file_privates.txt', data => {
|
|
859
902
|
if (!data) return;
|
|
860
|
-
log('load private file list');
|
|
861
903
|
map_generate_bol(file_privates, data);
|
|
862
904
|
}),
|
|
863
905
|
file_keep_new(PATH_CONFIG + 'file_blocks.txt', data => {
|
|
864
906
|
if (!data) return;
|
|
865
|
-
log('load blocked file list');
|
|
866
907
|
map_generate_bol(file_blocks, data);
|
|
867
908
|
}),
|
|
868
909
|
]);
|
|
869
910
|
|
|
870
911
|
let connections_count = 0;
|
|
871
|
-
const server_http = http.createServer(
|
|
872
|
-
(request, response) => request_handle(request, response, false)
|
|
873
|
-
);
|
|
874
912
|
let http_status = false;
|
|
875
913
|
let http_status_target = false;
|
|
914
|
+
let http_listened_resolve = null;
|
|
876
915
|
const http_connections = new Map;
|
|
877
|
-
|
|
916
|
+
const server_http = http.createServer(
|
|
917
|
+
(request, response) => request_handle(request, response, false)
|
|
918
|
+
);
|
|
919
|
+
server_http.on('error', err => {
|
|
920
|
+
log('[error] http: ' + err.message);
|
|
921
|
+
http_listened_resolve && http_listened_resolve();
|
|
922
|
+
});
|
|
878
923
|
server_http.on('connection', connection => {
|
|
879
924
|
const id = ++connections_count;
|
|
880
925
|
http_connections.set(id, connection);
|
|
@@ -883,71 +928,67 @@ server_http.on('connection', connection => {
|
|
|
883
928
|
});
|
|
884
929
|
});
|
|
885
930
|
|
|
886
|
-
actions.http_start = () => {
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
log('
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
actions.http_restart = () => {
|
|
898
|
-
if (!http_status) actions.http_start();
|
|
899
|
-
else if (http_status_target) {
|
|
900
|
-
http_status_target = false;
|
|
901
|
-
log('http is restarting...');
|
|
902
|
-
server_http.close(() => {
|
|
903
|
-
http_status = false;
|
|
904
|
-
log('http stopped');
|
|
905
|
-
actions.http_start();
|
|
906
|
-
});
|
|
931
|
+
actions.http_start = async () => {
|
|
932
|
+
await actions.http_stop();
|
|
933
|
+
http_status_target = true;
|
|
934
|
+
log('start http: http://localhost:' + port_http);
|
|
935
|
+
await new Promise(resolve => server_http.listen(port_http, http_listened_resolve = resolve));
|
|
936
|
+
if (http_listened_resolve) http_listened_resolve = null;
|
|
937
|
+
else{
|
|
938
|
+
http_status = true;
|
|
939
|
+
if (log_verbose) log('started http');
|
|
907
940
|
}
|
|
908
941
|
}
|
|
909
942
|
actions.http_stop = async () => {
|
|
910
|
-
if (!http_status_target
|
|
943
|
+
if (!http_status_target) return;
|
|
911
944
|
http_status_target = false;
|
|
912
|
-
log('http
|
|
945
|
+
log('stop http');
|
|
946
|
+
const kill_timeout = setTimeout(actions.http_kill, 5e3);
|
|
913
947
|
await new Promise(resolve => server_http.close(resolve));
|
|
948
|
+
clearTimeout(kill_timeout);
|
|
914
949
|
http_status = false;
|
|
915
|
-
log('http
|
|
950
|
+
if (log_verbose) log('stopped http');
|
|
916
951
|
}
|
|
917
|
-
actions.http_kill = () => {
|
|
918
|
-
if (http_status_target
|
|
919
|
-
log('
|
|
920
|
-
|
|
952
|
+
actions.http_kill = async () => {
|
|
953
|
+
if (http_status_target) return;
|
|
954
|
+
log('kill http');
|
|
955
|
+
await Promise.all(
|
|
956
|
+
Array.from(http_connections.values())
|
|
957
|
+
.map(connection => connection.destroy())
|
|
958
|
+
);
|
|
959
|
+
if (log_verbose) log('killed http');
|
|
921
960
|
http_connections.clear();
|
|
922
961
|
}
|
|
923
962
|
|
|
924
963
|
file_keep_new(PATH_CONFIG + 'port_http.txt', data => {
|
|
925
|
-
log('load http port number');
|
|
926
964
|
if (
|
|
927
965
|
!data ||
|
|
928
966
|
isNaN(data = Number(data)) ||
|
|
929
967
|
!number_check_uint(data)
|
|
930
968
|
) {
|
|
931
|
-
log('error: invalid
|
|
969
|
+
log('[error] http: invalid port number');
|
|
932
970
|
}
|
|
933
971
|
else if (data !== port_http) {
|
|
934
972
|
port_http = data;
|
|
935
|
-
actions.
|
|
973
|
+
actions.http_start();
|
|
936
974
|
}
|
|
937
975
|
});
|
|
938
976
|
|
|
939
977
|
try {
|
|
940
978
|
const https_key = fs.readFileSync(PATH_CONFIG + 'ssl/domain.key');
|
|
941
979
|
const https_cert = fs.readFileSync(PATH_CONFIG + 'ssl/chained.pem');
|
|
980
|
+
let https_status = false;
|
|
981
|
+
let https_status_target = false;
|
|
982
|
+
let https_listened_resolve = null;
|
|
983
|
+
const https_connections = new Map;
|
|
942
984
|
const server_https = require('https').createServer(
|
|
943
985
|
{key: https_key, cert: https_cert},
|
|
944
986
|
(request, response) => request_handle(request, response, true)
|
|
945
987
|
);
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
988
|
+
server_https.on('error', err => {
|
|
989
|
+
log('[error] https: ' + err.message);
|
|
990
|
+
https_listened_resolve && https_listened_resolve();
|
|
991
|
+
});
|
|
951
992
|
server_https.on('connection', connection => {
|
|
952
993
|
const id = ++connections_count;
|
|
953
994
|
https_connections.set(id, connection);
|
|
@@ -956,61 +997,53 @@ try {
|
|
|
956
997
|
});
|
|
957
998
|
});
|
|
958
999
|
|
|
959
|
-
actions.https_start = () => {
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
log('
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
actions.https_restart = () => {
|
|
971
|
-
if (!https_status) actions.https_start();
|
|
972
|
-
else if (https_status_target) {
|
|
973
|
-
https_status_target = false;
|
|
974
|
-
log('https is restarting...');
|
|
975
|
-
server_https.close(function () {
|
|
976
|
-
https_status = false;
|
|
977
|
-
log('https stopped');
|
|
978
|
-
actions.https_start();
|
|
979
|
-
});
|
|
1000
|
+
actions.https_start = async () => {
|
|
1001
|
+
await actions.https_stop();
|
|
1002
|
+
https_status_target = true;
|
|
1003
|
+
log('start https: https://localhost:' + port_https);
|
|
1004
|
+
await new Promise(resolve => server_https.listen(port_https, https_listened_resolve = resolve));
|
|
1005
|
+
if (https_listened_resolve) https_listened_resolve = null;
|
|
1006
|
+
else{
|
|
1007
|
+
https_status = true;
|
|
1008
|
+
if (log_verbose) log('started https');
|
|
980
1009
|
}
|
|
981
1010
|
}
|
|
982
1011
|
actions.https_stop = async () => {
|
|
983
|
-
if (!https_status_target
|
|
1012
|
+
if (!https_status_target) return;
|
|
984
1013
|
https_status_target = false;
|
|
985
|
-
log('https
|
|
1014
|
+
log('stop https');
|
|
1015
|
+
const kill_timeout = setTimeout(actions.https_kill, 5000);
|
|
986
1016
|
await new Promise(resolve => server_https.close(resolve));
|
|
1017
|
+
clearTimeout(kill_timeout);
|
|
987
1018
|
https_status = false;
|
|
988
|
-
log('https
|
|
1019
|
+
if (log_verbose) log('stopped https');
|
|
989
1020
|
}
|
|
990
|
-
actions.https_kill = () => {
|
|
991
|
-
if (https_status_target
|
|
992
|
-
log('
|
|
993
|
-
|
|
1021
|
+
actions.https_kill = async () => {
|
|
1022
|
+
if (https_status_target) return;
|
|
1023
|
+
log('kill https');
|
|
1024
|
+
await Promise.all(
|
|
1025
|
+
Array.from(https_connections.values()).map(connection => connection.destroy())
|
|
1026
|
+
);
|
|
1027
|
+
if (log_verbose) log('killed https');
|
|
994
1028
|
https_connections.clear();
|
|
995
1029
|
}
|
|
996
1030
|
|
|
997
1031
|
file_keep_new(PATH_CONFIG + 'port_https.txt', data => {
|
|
998
|
-
log('load https port number');
|
|
999
1032
|
if (
|
|
1000
1033
|
!data ||
|
|
1001
1034
|
isNaN(data = Number(data)) ||
|
|
1002
1035
|
!number_check_uint(data)
|
|
1003
1036
|
) {
|
|
1004
|
-
log('error: invalid
|
|
1037
|
+
log('[error] https: invalid port number');
|
|
1005
1038
|
}
|
|
1006
1039
|
else if (data !== port_https) {
|
|
1007
1040
|
port_https = data;
|
|
1008
|
-
actions.
|
|
1041
|
+
actions.https_start();
|
|
1009
1042
|
}
|
|
1010
1043
|
});
|
|
1011
1044
|
}
|
|
1012
1045
|
catch (err) {
|
|
1013
|
-
log('https
|
|
1046
|
+
if (log_verbose) log('https: no cert, disabled');
|
|
1014
1047
|
}
|
|
1015
1048
|
|
|
1016
1049
|
})();
|