@nxtedition/lib 15.0.21 → 15.0.23

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.
Files changed (3) hide show
  1. package/app.js +2 -10
  2. package/package.json +2 -1
  3. package/proxy.js +106 -0
package/app.js CHANGED
@@ -98,14 +98,13 @@ module.exports = function (appConfig, onTerminate) {
98
98
  // process.env.name is the pm2 name of the process
99
99
  appConfig.instanceId ?? appConfig.containerId ?? process.env.name ?? os.hostname()
100
100
 
101
- const userAgent = globalThis.userAgent = (
101
+ const userAgent = (globalThis.userAgent =
102
102
  appConfig.userAgent ??
103
103
  (serviceName &&
104
104
  `${serviceName}/${
105
105
  serviceVersion || '*'
106
106
  } (module:${serviceModule}; instance:${serviceInstanceId}) Node/${process.version}`) ??
107
- null
108
- )
107
+ null)
109
108
 
110
109
  const terminate = async (finalLogger) => {
111
110
  finalLogger ??= logger
@@ -685,7 +684,6 @@ module.exports = function (appConfig, onTerminate) {
685
684
  // const undici = require('undici')
686
685
  const compose = require('koa-compose')
687
686
  const { createServer } = require('./http')
688
- const createError = require('http-errors')
689
687
 
690
688
  const httpConfig = { ...appConfig.http, ...config.http }
691
689
 
@@ -731,12 +729,6 @@ module.exports = function (appConfig, onTerminate) {
731
729
  return next()
732
730
  }
733
731
  },
734
- (ctx, next) => {
735
- if (toobusy && toobusy()) {
736
- throw new createError.ServiceUnavailable('too busy')
737
- }
738
- return next()
739
- },
740
732
  appConfig.http.request
741
733
  ? appConfig.http.request
742
734
  : typeof appConfig.http === 'function'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "15.0.21",
3
+ "version": "15.0.23",
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
+ }