@abtnode/router-provider 1.6.21 → 1.6.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/README.md +1 -1
- package/lib/base.js +14 -0
- package/lib/default/daemon.js +316 -0
- package/lib/default/index.js +221 -0
- package/lib/default/proxy.js +567 -0
- package/lib/index.js +19 -19
- package/lib/nginx/includes/params +1 -1
- package/lib/nginx/index.js +115 -179
- package/lib/nginx/util.js +15 -56
- package/lib/util.js +165 -0
- package/package.json +17 -8
- package/lib/none/index.js +0 -50
package/lib/nginx/util.js
CHANGED
|
@@ -8,13 +8,12 @@ const { NginxConfFile } = require('nginx-conf');
|
|
|
8
8
|
const shelljs = require('shelljs');
|
|
9
9
|
const findProcess = require('find-process');
|
|
10
10
|
const moment = require('moment');
|
|
11
|
-
const { MAX_UPLOAD_FILE_SIZE
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const logger = require('@abtnode/logger')(`${require('../../package.json').name}:provider:nginx:util`);
|
|
11
|
+
const { MAX_UPLOAD_FILE_SIZE } = require('@abtnode/constant');
|
|
12
|
+
|
|
13
|
+
const logger = require('@abtnode/logger')('router:nginx:util');
|
|
15
14
|
|
|
16
|
-
const CLIENT_MAX_BODY_SIZE = process.env.MAX_UPLOAD_FILE_SIZE || MAX_UPLOAD_FILE_SIZE;
|
|
17
15
|
const WORKER_CONNECTIONS = 1000 * 10; // 10K
|
|
16
|
+
const CLIENT_MAX_BODY_SIZE = process.env.MAX_UPLOAD_FILE_SIZE || MAX_UPLOAD_FILE_SIZE;
|
|
18
17
|
|
|
19
18
|
const formatError = (errStr) => {
|
|
20
19
|
if (!errStr) {
|
|
@@ -43,10 +42,10 @@ const formatError = (errStr) => {
|
|
|
43
42
|
).join(';');
|
|
44
43
|
};
|
|
45
44
|
|
|
46
|
-
const addTestServer = ({
|
|
45
|
+
const addTestServer = ({ configPath, port, upstreamPort }) =>
|
|
47
46
|
new Promise((resolve, reject) => {
|
|
48
47
|
// eslint-disable-next-line consistent-return
|
|
49
|
-
NginxConfFile.create(
|
|
48
|
+
NginxConfFile.create(configPath, async (err, conf) => {
|
|
50
49
|
if (err) {
|
|
51
50
|
return reject(err);
|
|
52
51
|
}
|
|
@@ -74,7 +73,7 @@ const addTestServer = ({ configFilePath, port, upstreamPort }) =>
|
|
|
74
73
|
);
|
|
75
74
|
|
|
76
75
|
conf.on('flushed', () => resolve());
|
|
77
|
-
conf.live(
|
|
76
|
+
conf.live(configPath);
|
|
78
77
|
conf.flush();
|
|
79
78
|
});
|
|
80
79
|
});
|
|
@@ -131,7 +130,7 @@ const getUserGroup = (username) => {
|
|
|
131
130
|
|
|
132
131
|
const getMainTemplate = ({
|
|
133
132
|
logDir,
|
|
134
|
-
|
|
133
|
+
tmpDir,
|
|
135
134
|
nginxLoadModules = '',
|
|
136
135
|
workerProcess,
|
|
137
136
|
maxBodySize = CLIENT_MAX_BODY_SIZE,
|
|
@@ -152,11 +151,11 @@ http {
|
|
|
152
151
|
default upgrade;
|
|
153
152
|
'' close;
|
|
154
153
|
}
|
|
155
|
-
client_body_temp_path ${path.join(
|
|
156
|
-
proxy_temp_path ${path.join(
|
|
157
|
-
fastcgi_temp_path ${path.join(
|
|
158
|
-
uwsgi_temp_path ${path.join(
|
|
159
|
-
scgi_temp_path ${path.join(
|
|
154
|
+
client_body_temp_path ${path.join(tmpDir, 'client_body')};
|
|
155
|
+
proxy_temp_path ${path.join(tmpDir, 'proxy')};
|
|
156
|
+
fastcgi_temp_path ${path.join(tmpDir, 'fastcgi')};
|
|
157
|
+
uwsgi_temp_path ${path.join(tmpDir, 'uwsgi')};
|
|
158
|
+
scgi_temp_path ${path.join(tmpDir, 'scgi')};
|
|
160
159
|
client_max_body_size ${maxBodySize}m;
|
|
161
160
|
|
|
162
161
|
log_format compression '$remote_addr - $remote_user [$time_local] '
|
|
@@ -174,7 +173,7 @@ http {
|
|
|
174
173
|
const getNginxStatus = async (configPath) => {
|
|
175
174
|
const list = await findProcess('name', /nginx:/);
|
|
176
175
|
const result = {
|
|
177
|
-
|
|
176
|
+
managed: false,
|
|
178
177
|
pid: 0,
|
|
179
178
|
running: false,
|
|
180
179
|
};
|
|
@@ -184,7 +183,7 @@ const getNginxStatus = async (configPath) => {
|
|
|
184
183
|
result.running = true;
|
|
185
184
|
|
|
186
185
|
if (abtnodeNginxProcess) {
|
|
187
|
-
result.
|
|
186
|
+
result.managed = true;
|
|
188
187
|
result.pid = abtnodeNginxProcess.pid;
|
|
189
188
|
}
|
|
190
189
|
|
|
@@ -194,37 +193,6 @@ const getNginxStatus = async (configPath) => {
|
|
|
194
193
|
return result;
|
|
195
194
|
};
|
|
196
195
|
|
|
197
|
-
const decideHttpPort = (port) => port || process.env.ABT_NODE_HTTP_PORT || DEFAULT_HTTP_PORT;
|
|
198
|
-
const decideHttpsPort = (port) => port || process.env.ABT_NODE_HTTPS_PORT || DEFAULT_HTTPS_PORT;
|
|
199
|
-
|
|
200
|
-
const findCertificate = (certs, domain) => {
|
|
201
|
-
const results = certs
|
|
202
|
-
.filter((cert) => [cert.domain, ...(cert.sans || [])].some((d) => checkDomainMatch(d, domain)))
|
|
203
|
-
.sort((d1) => (d1.domain[0] === '*' ? 1 : -1)); // will first match a.b.com, then *.b.com
|
|
204
|
-
return results[0];
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* trim tail slash
|
|
209
|
-
* @param {string} str
|
|
210
|
-
* @returns {string}
|
|
211
|
-
*/
|
|
212
|
-
const trimEndSlash = (str) => {
|
|
213
|
-
if (str && str.length > 1 && str[str.length - 1] === '/') {
|
|
214
|
-
return str.substr(0, str.length - 1);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return str;
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const concatPath = (prefix = '', suffix = '') => {
|
|
221
|
-
if (prefix === '/') {
|
|
222
|
-
return suffix ? `~* .*${suffix}$` : '/';
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return suffix ? `~* ^${prefix}.*${suffix}$` : prefix;
|
|
226
|
-
};
|
|
227
|
-
|
|
228
196
|
const compressFile = ({ sourceFile, targetFile, options = {} }) => {
|
|
229
197
|
if (fs.existsSync(targetFile)) {
|
|
230
198
|
fs.unlinkSync(targetFile);
|
|
@@ -297,16 +265,7 @@ module.exports = {
|
|
|
297
265
|
formatError,
|
|
298
266
|
getMissingModules,
|
|
299
267
|
parseNginxConfigArgs,
|
|
300
|
-
decideHttpPort,
|
|
301
|
-
decideHttpsPort,
|
|
302
|
-
concatPath,
|
|
303
|
-
trimEndSlash,
|
|
304
|
-
findCertificate,
|
|
305
268
|
getNginxStatus,
|
|
306
269
|
rotateNginxLogFile,
|
|
307
270
|
getUserGroup,
|
|
308
|
-
get404Template: (nodeInfo) => template404(nodeInfo),
|
|
309
|
-
get502Template: (nodeInfo) => template502(nodeInfo),
|
|
310
|
-
get5xxTemplate: (nodeInfo) => template5xx(nodeInfo),
|
|
311
|
-
getWelcomeTemplate: (nodeInfo) => templateWelcome(nodeInfo),
|
|
312
271
|
};
|
package/lib/util.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const sortBy = require('lodash/sortBy');
|
|
2
|
+
const isValidDomain = require('is-valid-domain');
|
|
3
|
+
const checkDomainMatch = require('@abtnode/util/lib/check-domain-match');
|
|
4
|
+
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
5
|
+
const { template404, template502, template5xx, templateWelcome } = require('@abtnode/router-templates');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
IP,
|
|
9
|
+
DEFAULT_HTTP_PORT,
|
|
10
|
+
DEFAULT_HTTPS_PORT,
|
|
11
|
+
DEFAULT_IP_DNS_DOMAIN_SUFFIX,
|
|
12
|
+
DOMAIN_FOR_DEFAULT_SITE,
|
|
13
|
+
ROUTING_RULE_TYPES,
|
|
14
|
+
SLOT_FOR_IP_DNS_SITE,
|
|
15
|
+
} = require('@abtnode/constant');
|
|
16
|
+
|
|
17
|
+
const decideHttpPort = (port) => port || process.env.ABT_NODE_HTTP_PORT || DEFAULT_HTTP_PORT;
|
|
18
|
+
const decideHttpsPort = (port) => port || process.env.ABT_NODE_HTTPS_PORT || DEFAULT_HTTPS_PORT;
|
|
19
|
+
|
|
20
|
+
const findCertificate = (certs, domain) => {
|
|
21
|
+
const results = certs
|
|
22
|
+
.filter((cert) => [cert.domain, ...(cert.sans || [])].some((d) => checkDomainMatch(d, domain)))
|
|
23
|
+
.sort((d1) => (d1.domain[0] === '*' ? 1 : -1)); // will first match a.b.com, then *.b.com
|
|
24
|
+
return results[0];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const trimEndSlash = (str) => {
|
|
28
|
+
if (str && str.length > 1 && str[str.length - 1] === '/') {
|
|
29
|
+
return str.substr(0, str.length - 1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return str;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const concatPath = (prefix = '', suffix = '') => {
|
|
36
|
+
if (prefix === '/') {
|
|
37
|
+
return suffix ? `~* .*${suffix}$` : '/';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return suffix ? `~* ^${prefix}.*${suffix}$` : prefix;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const formatRoutingTable = (routingTable, onRule) => {
|
|
44
|
+
const sites = {};
|
|
45
|
+
const configs = [];
|
|
46
|
+
|
|
47
|
+
routingTable.forEach((site) => {
|
|
48
|
+
let { domain } = site;
|
|
49
|
+
if (site.domain === DOMAIN_FOR_DEFAULT_SITE) {
|
|
50
|
+
domain = '_';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
configs.push({ domain, corsAllowedOrigins: site.corsAllowedOrigins });
|
|
54
|
+
|
|
55
|
+
if (!sites[domain]) {
|
|
56
|
+
sites[domain] = {
|
|
57
|
+
domain,
|
|
58
|
+
rules: [],
|
|
59
|
+
port: site.port,
|
|
60
|
+
corsAllowedOrigins: site.corsAllowedOrigins,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
(site.rules || []).forEach((x) => {
|
|
65
|
+
const prefix = trimEndSlash(x.from.pathPrefix || '/');
|
|
66
|
+
const groupPrefix = trimEndSlash(x.from.groupPathPrefix || '/');
|
|
67
|
+
const suffix = trimEndSlash(x.from.pathSuffix || '');
|
|
68
|
+
|
|
69
|
+
const rule = {
|
|
70
|
+
ruleId: x.id,
|
|
71
|
+
type: x.to.type,
|
|
72
|
+
prefix,
|
|
73
|
+
groupPrefix,
|
|
74
|
+
suffix,
|
|
75
|
+
response: x.to.response,
|
|
76
|
+
};
|
|
77
|
+
if (x.to.type === ROUTING_RULE_TYPES.REDIRECT) {
|
|
78
|
+
rule.redirectCode = x.to.redirectCode || 302;
|
|
79
|
+
rule.url = x.to.url;
|
|
80
|
+
} else {
|
|
81
|
+
rule.port = +x.to.port;
|
|
82
|
+
rule.did = x.to.did;
|
|
83
|
+
rule.realDid = x.to.realDid;
|
|
84
|
+
rule.target = trimEndSlash(normalizePathPrefix(x.to.target || '/'));
|
|
85
|
+
rule.services = x.services || [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const tmpPath = concatPath(prefix, suffix);
|
|
89
|
+
const tmpRules = sites[domain].rules;
|
|
90
|
+
if (!tmpRules.find(({ prefix: p, suffix: s }) => concatPath(p, s) === tmpPath)) {
|
|
91
|
+
sites[domain].rules.push(rule);
|
|
92
|
+
if (typeof onRule === 'function') {
|
|
93
|
+
onRule(sites[domain].rules, rule);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const { rules } = sites[domain];
|
|
99
|
+
const rulesWithoutSuffix = sortBy(rules.filter((x) => !x.suffix), (x) => -x.prefix.length); // prettier-ignore
|
|
100
|
+
const rulesWithSuffix = sortBy(rules.filter((x) => x.suffix), (x) => -x.prefix.length); // prettier-ignore
|
|
101
|
+
|
|
102
|
+
sites[domain].rules = rulesWithoutSuffix.concat(rulesWithSuffix);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return { sites: Object.values(sites), configs };
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const isSpecificDomain = (domain) => {
|
|
109
|
+
if (isValidDomain(domain) === false) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (domain.endsWith(DEFAULT_IP_DNS_DOMAIN_SUFFIX)) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return true;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const toSlotDomain = (domain) => {
|
|
121
|
+
if (domain.endsWith(DEFAULT_IP_DNS_DOMAIN_SUFFIX)) {
|
|
122
|
+
const subDomain = domain.split('.').shift();
|
|
123
|
+
const matches = subDomain.match(IP);
|
|
124
|
+
if (matches) {
|
|
125
|
+
return domain.replace(matches[0].slice(1), SLOT_FOR_IP_DNS_SITE);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return domain;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const findRule = (rules, url) =>
|
|
133
|
+
rules.find((x) => {
|
|
134
|
+
const { prefix, suffix = '' } = x;
|
|
135
|
+
if (suffix) {
|
|
136
|
+
return url.startsWith(prefix) && url.endsWith(suffix);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (prefix === '/' && prefix === url) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return url.startsWith(prefix);
|
|
144
|
+
});
|
|
145
|
+
const matchRule = (rules, url) => {
|
|
146
|
+
const rulesWithSuffix = rules.filter((x) => x.suffix);
|
|
147
|
+
const rulesWithoutSuffix = rules.filter((x) => !x.suffix);
|
|
148
|
+
return findRule(rulesWithSuffix, url) || findRule(rulesWithoutSuffix, url);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
module.exports = {
|
|
152
|
+
decideHttpPort,
|
|
153
|
+
decideHttpsPort,
|
|
154
|
+
findCertificate,
|
|
155
|
+
concatPath,
|
|
156
|
+
trimEndSlash,
|
|
157
|
+
formatRoutingTable,
|
|
158
|
+
isSpecificDomain,
|
|
159
|
+
toSlotDomain,
|
|
160
|
+
matchRule,
|
|
161
|
+
get404Template: (info) => template404(info),
|
|
162
|
+
get502Template: (info) => template502(info),
|
|
163
|
+
get5xxTemplate: (info) => template5xx(info),
|
|
164
|
+
getWelcomeTemplate: (info) => templateWelcome(info),
|
|
165
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abtnode/router-provider",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.24",
|
|
4
4
|
"description": "Routing engine implementations for abt node",
|
|
5
5
|
"author": "polunzh <polunzh@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/ArcBlock/blocklet-server#readme",
|
|
@@ -32,25 +32,34 @@
|
|
|
32
32
|
"url": "https://github.com/ArcBlock/blocklet-server/issues"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@abtnode/constant": "1.6.
|
|
36
|
-
"@abtnode/logger": "1.6.
|
|
37
|
-
"@abtnode/router-templates": "1.6.
|
|
38
|
-
"@abtnode/util": "1.6.
|
|
35
|
+
"@abtnode/constant": "1.6.24",
|
|
36
|
+
"@abtnode/logger": "1.6.24",
|
|
37
|
+
"@abtnode/router-templates": "1.6.24",
|
|
38
|
+
"@abtnode/util": "1.6.24",
|
|
39
39
|
"axios": "^0.25.0",
|
|
40
40
|
"debug": "^4.3.3",
|
|
41
41
|
"find-process": "^1.4.3",
|
|
42
42
|
"fkill": "^7.0.1",
|
|
43
43
|
"fs-extra": "^10.0.0",
|
|
44
44
|
"get-port": "^5.1.1",
|
|
45
|
+
"http-proxy": "^1.18.1",
|
|
46
|
+
"is-valid-domain": "^0.1.6",
|
|
45
47
|
"lodash": "^4.17.21",
|
|
48
|
+
"lru-cache": "^7.4.0",
|
|
46
49
|
"moment": "^2.29.1",
|
|
47
50
|
"nginx-conf": "^1.5.0",
|
|
51
|
+
"object-hash": "^3.0.0",
|
|
48
52
|
"promise-retry": "^2.0.1",
|
|
49
53
|
"shelljs": "^0.8.4",
|
|
50
|
-
"tar": "^6.1.0"
|
|
54
|
+
"tar": "^6.1.0",
|
|
55
|
+
"url-join": "^4.0.1",
|
|
56
|
+
"uuid": "^8.3.2",
|
|
57
|
+
"valid-url": "^1.0.9"
|
|
51
58
|
},
|
|
52
59
|
"devDependencies": {
|
|
53
|
-
"
|
|
60
|
+
"bluebird": "^3.7.2",
|
|
61
|
+
"fs-extra": "^10.0.0",
|
|
62
|
+
"needle": "^3.0.0"
|
|
54
63
|
},
|
|
55
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "6bd8792a155ebbbefea6ca3d42c5b59b354d9879"
|
|
56
65
|
}
|
package/lib/none/index.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-empty-function */
|
|
2
|
-
const BaseProvider = require('../base');
|
|
3
|
-
|
|
4
|
-
class NoneProvider extends BaseProvider {
|
|
5
|
-
constructor() {
|
|
6
|
-
super('none');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
async update() {}
|
|
10
|
-
|
|
11
|
-
async reload() {}
|
|
12
|
-
|
|
13
|
-
async start() {}
|
|
14
|
-
|
|
15
|
-
async restart() {}
|
|
16
|
-
|
|
17
|
-
async stop() {}
|
|
18
|
-
|
|
19
|
-
initialize() {}
|
|
20
|
-
|
|
21
|
-
async validateConfig() {}
|
|
22
|
-
|
|
23
|
-
async rotateLogs() {}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
NoneProvider.describe = () => {
|
|
27
|
-
const result = NoneProvider.check();
|
|
28
|
-
return {
|
|
29
|
-
name: 'none',
|
|
30
|
-
description: 'This provider does nothing, you must access blocklets through IP + Port',
|
|
31
|
-
error: result.error,
|
|
32
|
-
available: result.available,
|
|
33
|
-
running: result.running,
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
NoneProvider.check = () => ({
|
|
38
|
-
available: true,
|
|
39
|
-
running: true,
|
|
40
|
-
error: '',
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
NoneProvider.getStatus = () => ({
|
|
44
|
-
pid: 0,
|
|
45
|
-
running: false,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
NoneProvider.exists = () => true;
|
|
49
|
-
|
|
50
|
-
module.exports = NoneProvider;
|