@nxtedition/lib 15.0.22 → 15.0.24
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/app.js +73 -84
- package/package.json +2 -1
- package/proxy.js +106 -0
package/app.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const os = require('node:os')
|
|
2
2
|
const net = require('node:net')
|
|
3
|
-
const assert = require('node:assert')
|
|
4
3
|
const stream = require('node:stream')
|
|
5
4
|
const { Buffer } = require('node:buffer')
|
|
6
5
|
const { getDockerSecretsSync } = require('./docker-secrets')
|
|
@@ -408,7 +407,6 @@ module.exports = function (appConfig, onTerminate) {
|
|
|
408
407
|
if (appConfig.status) {
|
|
409
408
|
const rxjs = require('rxjs')
|
|
410
409
|
const rx = require('rxjs/operators')
|
|
411
|
-
const undici = require('undici')
|
|
412
410
|
const fp = require('lodash/fp')
|
|
413
411
|
const hashString = require('./hash')
|
|
414
412
|
|
|
@@ -489,89 +487,80 @@ module.exports = function (appConfig, onTerminate) {
|
|
|
489
487
|
)
|
|
490
488
|
: rxjs.of({}),
|
|
491
489
|
ds
|
|
492
|
-
?
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
id: 'app:ds_record_records',
|
|
506
|
-
level: 40,
|
|
507
|
-
code: 'NXT_DEEPSTREAM_RECORDS_RECORDS',
|
|
508
|
-
msg: 'ds: ' + ds.stats.record.records + ' records',
|
|
509
|
-
})
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
if (ds.stats.record.pruning > 100e3) {
|
|
513
|
-
messages.push({
|
|
514
|
-
id: 'app:ds_record_pruning',
|
|
515
|
-
level: 40,
|
|
516
|
-
code: 'NXT_DEEPSTREAM_RECORDS_PRUNING',
|
|
517
|
-
msg: 'ds: ' + ds.stats.record.pruning + ' pruning',
|
|
518
|
-
})
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
if (ds.stats.record.pending > 10e3) {
|
|
522
|
-
messages.push({
|
|
523
|
-
id: 'app:ds_record_pending',
|
|
524
|
-
level: 40,
|
|
525
|
-
code: 'NXT_DEEPSTREAM_RECORDS_PENDING',
|
|
526
|
-
msg: 'ds: ' + ds.stats.record.pending + ' pending',
|
|
527
|
-
})
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if (ds.stats.record.updating > 10e3) {
|
|
531
|
-
messages.push({
|
|
532
|
-
id: 'app:ds_record_updating',
|
|
533
|
-
level: 40,
|
|
534
|
-
code: 'NXT_DEEPSTREAM_RECORDS_UPDATING',
|
|
535
|
-
msg: 'ds: ' + ds.stats.record.updating + ' updating',
|
|
536
|
-
})
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
if (ds.stats.record.patching > 10e3) {
|
|
540
|
-
messages.push({
|
|
541
|
-
id: 'app:ds_record_patching',
|
|
542
|
-
level: 40,
|
|
543
|
-
code: 'NXT_DEEPSTREAM_RECORDS_PATCHING',
|
|
544
|
-
msg: 'ds: ' + ds.stats.record.patching + ' patching',
|
|
545
|
-
})
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
try {
|
|
549
|
-
const { body, statusCode } = await client.request({
|
|
550
|
-
method: 'GET',
|
|
551
|
-
path: '/healthcheck',
|
|
552
|
-
})
|
|
553
|
-
await body.dump()
|
|
554
|
-
assert(statusCode >= 200 && statusCode < 300)
|
|
555
|
-
} catch (err) {
|
|
556
|
-
messages.push({
|
|
557
|
-
id: 'app:ds_http_connection',
|
|
490
|
+
? rxjs.fromEvent(ds, 'connectionStateChanged').pipe(
|
|
491
|
+
rxjs.map((connectionState) =>
|
|
492
|
+
connectionState === 'OPEN'
|
|
493
|
+
? [
|
|
494
|
+
{
|
|
495
|
+
id: 'app:ds_connection_state',
|
|
496
|
+
level: 30,
|
|
497
|
+
msg: 'ds: connected',
|
|
498
|
+
},
|
|
499
|
+
]
|
|
500
|
+
: [
|
|
501
|
+
{
|
|
502
|
+
id: 'app:ds_connection_state',
|
|
558
503
|
level: 40,
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
504
|
+
msg: 'ds: connecting',
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
),
|
|
508
|
+
)
|
|
509
|
+
: rxjs.of([]),
|
|
510
|
+
ds
|
|
511
|
+
? rxjs.timer(0, 10e3).pipe(
|
|
512
|
+
rx.exhaustMap(async () => {
|
|
513
|
+
const messages = []
|
|
514
|
+
|
|
515
|
+
if (ds.stats.record.records > 100e3) {
|
|
516
|
+
messages.push({
|
|
517
|
+
id: 'app:ds_record_records',
|
|
518
|
+
level: 40,
|
|
519
|
+
code: 'NXT_DEEPSTREAM_RECORDS_RECORDS',
|
|
520
|
+
msg: 'ds: ' + ds.stats.record.records + ' records',
|
|
521
|
+
})
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (ds.stats.record.pruning > 100e3) {
|
|
525
|
+
messages.push({
|
|
526
|
+
id: 'app:ds_record_pruning',
|
|
527
|
+
level: 40,
|
|
528
|
+
code: 'NXT_DEEPSTREAM_RECORDS_PRUNING',
|
|
529
|
+
msg: 'ds: ' + ds.stats.record.pruning + ' pruning',
|
|
530
|
+
})
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (ds.stats.record.pending > 10e3) {
|
|
534
|
+
messages.push({
|
|
535
|
+
id: 'app:ds_record_pending',
|
|
536
|
+
level: 40,
|
|
537
|
+
code: 'NXT_DEEPSTREAM_RECORDS_PENDING',
|
|
538
|
+
msg: 'ds: ' + ds.stats.record.pending + ' pending',
|
|
539
|
+
})
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (ds.stats.record.updating > 10e3) {
|
|
543
|
+
messages.push({
|
|
544
|
+
id: 'app:ds_record_updating',
|
|
545
|
+
level: 40,
|
|
546
|
+
code: 'NXT_DEEPSTREAM_RECORDS_UPDATING',
|
|
547
|
+
msg: 'ds: ' + ds.stats.record.updating + ' updating',
|
|
548
|
+
})
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (ds.stats.record.patching > 10e3) {
|
|
552
|
+
messages.push({
|
|
553
|
+
id: 'app:ds_record_patching',
|
|
554
|
+
level: 40,
|
|
555
|
+
code: 'NXT_DEEPSTREAM_RECORDS_PATCHING',
|
|
556
|
+
msg: 'ds: ' + ds.stats.record.patching + ' patching',
|
|
557
|
+
})
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return messages
|
|
561
|
+
}),
|
|
562
|
+
)
|
|
563
|
+
: rxjs.of([]),
|
|
575
564
|
rxjs.timer(0, 10e3),
|
|
576
565
|
].filter(Boolean),
|
|
577
566
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/lib",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.24",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Robert Nagy <robert.nagy@boffins.se>",
|
|
6
6
|
"files": [
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"deepstream.js",
|
|
21
21
|
"logger.js",
|
|
22
22
|
"mime.js",
|
|
23
|
+
"proxy.js",
|
|
23
24
|
"trace.js",
|
|
24
25
|
"weakCache.js",
|
|
25
26
|
"couch.js",
|
package/proxy.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const createError = require('http-errors')
|
|
2
|
+
const net = require('net')
|
|
3
|
+
|
|
4
|
+
// This expression matches hop-by-hop headers.
|
|
5
|
+
// These headers are meaningful only for a single transport-level connection,
|
|
6
|
+
// and must not be retransmitted by proxies or cached.
|
|
7
|
+
const HOP_EXPR =
|
|
8
|
+
/^(te|host|upgrade|trailers|connection|keep-alive|http2-settings|transfer-encoding|proxy-connection|proxy-authenticate|proxy-authorization)$/i
|
|
9
|
+
|
|
10
|
+
// Removes hop-by-hop and pseudo headers.
|
|
11
|
+
// Updates via and forwarded headers.
|
|
12
|
+
// Only hop-by-hop headers may be set using the Connection general header.
|
|
13
|
+
module.exports.reduceHeaders = function reduceHeaders(
|
|
14
|
+
{ id, headers, proxyName, httpVersion, socket },
|
|
15
|
+
fn,
|
|
16
|
+
acc,
|
|
17
|
+
) {
|
|
18
|
+
let via
|
|
19
|
+
let forwarded
|
|
20
|
+
let host
|
|
21
|
+
let authority
|
|
22
|
+
let connection
|
|
23
|
+
|
|
24
|
+
const entries = Object.entries(headers)
|
|
25
|
+
|
|
26
|
+
for (const [key, val] of entries) {
|
|
27
|
+
const len = key.length
|
|
28
|
+
if (len === 3 && !via && key.toLowerCase() === 'via') {
|
|
29
|
+
via = val
|
|
30
|
+
} else if (len === 4 && !host && key.toLowerCase() === 'host') {
|
|
31
|
+
host = val
|
|
32
|
+
} else if (len === 9 && !forwarded && key.toLowerCase() === 'forwarded') {
|
|
33
|
+
forwarded = val
|
|
34
|
+
} else if (len === 10 && !connection && key.toLowerCase() === 'connection') {
|
|
35
|
+
connection = val
|
|
36
|
+
} else if (len === 10 && !authority && key.toLowerCase() === ':authority') {
|
|
37
|
+
authority = val
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let remove
|
|
42
|
+
if (connection && !HOP_EXPR.test(connection)) {
|
|
43
|
+
remove = connection.split(/,\s*/)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const [key, val] of entries) {
|
|
47
|
+
if (key.charAt(0) !== ':' && !remove?.includes(key) && !HOP_EXPR.test(key)) {
|
|
48
|
+
acc = fn(acc, key, val)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (socket) {
|
|
53
|
+
const forwardedHost = authority || host
|
|
54
|
+
acc = fn(
|
|
55
|
+
acc,
|
|
56
|
+
'forwarded',
|
|
57
|
+
(forwarded ? forwarded + ', ' : '') +
|
|
58
|
+
[
|
|
59
|
+
socket.localAddress && `by=${printIp(socket.localAddress, socket.localPort)}`,
|
|
60
|
+
socket.remoteAddress && `for=${printIp(socket.remoteAddress, socket.remotePort)}`,
|
|
61
|
+
`proto=${socket.encrypted ? 'https' : 'http'}`,
|
|
62
|
+
forwardedHost && `host="${forwardedHost}"`,
|
|
63
|
+
].join(';'),
|
|
64
|
+
)
|
|
65
|
+
} else if (forwarded) {
|
|
66
|
+
// The forwarded header should not be included in response.
|
|
67
|
+
throw new createError.BadGateway()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (proxyName) {
|
|
71
|
+
if (via) {
|
|
72
|
+
if (via.split(',').some((name) => name.endsWith(proxyName))) {
|
|
73
|
+
throw new createError.LoopDetected()
|
|
74
|
+
}
|
|
75
|
+
via += ', '
|
|
76
|
+
} else {
|
|
77
|
+
via = ''
|
|
78
|
+
}
|
|
79
|
+
via += `${httpVersion} ${proxyName}`
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (via) {
|
|
83
|
+
acc = fn(acc, 'via', via)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (id) {
|
|
87
|
+
acc = fn(acc, 'request-id', id)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return acc
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function printIp(address, port) {
|
|
94
|
+
const isIPv6 = net.isIPv6(address)
|
|
95
|
+
let str = `${address}`
|
|
96
|
+
if (isIPv6) {
|
|
97
|
+
str = `[${str}]`
|
|
98
|
+
}
|
|
99
|
+
if (port) {
|
|
100
|
+
str = `${str}:${port}`
|
|
101
|
+
}
|
|
102
|
+
if (isIPv6 || port) {
|
|
103
|
+
str = `"${str}"`
|
|
104
|
+
}
|
|
105
|
+
return str
|
|
106
|
+
}
|