@abtnode/router-provider 1.6.30 → 1.6.31
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/lib/default/daemon.js +7 -13
- package/lib/default/index.js +29 -0
- package/lib/default/proxy.js +1 -0
- package/lib/nginx/index.js +37 -11
- package/lib/nginx/util.js +7 -5
- package/lib/util.js +44 -3
- package/package.json +7 -6
package/lib/default/daemon.js
CHANGED
|
@@ -4,11 +4,7 @@ const fs = require('fs-extra');
|
|
|
4
4
|
const get = require('lodash/get');
|
|
5
5
|
const joinUrl = require('url-join');
|
|
6
6
|
const checkDomainMatch = require('@abtnode/util/lib/check-domain-match');
|
|
7
|
-
const {
|
|
8
|
-
DEFAULT_IP_DNS_DOMAIN_SUFFIX,
|
|
9
|
-
ROUTING_RULE_TYPES,
|
|
10
|
-
WELLKNOWN_SERVICE_PATH_PREFIX,
|
|
11
|
-
} = require('@abtnode/constant');
|
|
7
|
+
const { DEFAULT_IP_DOMAIN_SUFFIX, ROUTING_RULE_TYPES, WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
|
|
12
8
|
|
|
13
9
|
const logger = require('@abtnode/logger')('router:default:daemon', { filename: 'engine' });
|
|
14
10
|
|
|
@@ -65,15 +61,13 @@ const createRequestHandler = (id) => (req, res, target) => {
|
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
|
|
68
|
-
// FIXME logic related to server gateway should not in provider
|
|
69
|
-
const rewritePathPrefix = rule.prefix.replace(WELLKNOWN_SERVICE_PATH_PREFIX, '') || '/';
|
|
70
|
-
|
|
71
64
|
if (rule.type === ROUTING_RULE_TYPES.GENERAL_PROXY) {
|
|
72
|
-
//
|
|
65
|
+
// do not rewrite for internal servers
|
|
66
|
+
} else if (rule.prefix.includes(WELLKNOWN_SERVICE_PATH_PREFIX)) {
|
|
67
|
+
// do not rewrite for service requests
|
|
73
68
|
} else {
|
|
74
|
-
req.url = req.url.substr(
|
|
69
|
+
req.url = joinUrl(rule.target, req.url.substr(rule.prefix.length));
|
|
75
70
|
}
|
|
76
|
-
|
|
77
71
|
if (req.url.startsWith('/') === false) {
|
|
78
72
|
req.url = `/${req.url}`;
|
|
79
73
|
}
|
|
@@ -86,7 +80,7 @@ const createRequestHandler = (id) => (req, res, target) => {
|
|
|
86
80
|
req.headers['X-Blocklet-Real-Did'] = rule.realDid;
|
|
87
81
|
}
|
|
88
82
|
|
|
89
|
-
req.headers['X-Path-Prefix'] =
|
|
83
|
+
req.headers['X-Path-Prefix'] = rule.prefix.replace(WELLKNOWN_SERVICE_PATH_PREFIX, '') || '/';
|
|
90
84
|
req.headers['X-Group-Path-Prefix'] = rule.groupPrefix || '/';
|
|
91
85
|
|
|
92
86
|
if (rule.type === ROUTING_RULE_TYPES.BLOCKLET) {
|
|
@@ -281,7 +275,7 @@ const updateConfig = (reload = false) => {
|
|
|
281
275
|
updateConfig();
|
|
282
276
|
|
|
283
277
|
// create main server
|
|
284
|
-
const defaultCert = config.certs.find((x) => x.domain.endsWith(
|
|
278
|
+
const defaultCert = config.certs.find((x) => x.domain.endsWith(DEFAULT_IP_DOMAIN_SUFFIX));
|
|
285
279
|
const main = new ProxyServer({
|
|
286
280
|
xfwd: true,
|
|
287
281
|
onError,
|
package/lib/default/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const http = require('http');
|
|
3
4
|
const shelljs = require('shelljs');
|
|
4
5
|
const get = require('lodash/get');
|
|
5
6
|
const omit = require('lodash/omit');
|
|
@@ -15,6 +16,7 @@ const BaseProvider = require('../base');
|
|
|
15
16
|
const {
|
|
16
17
|
decideHttpPort,
|
|
17
18
|
decideHttpsPort,
|
|
19
|
+
getUsablePorts,
|
|
18
20
|
get404Template,
|
|
19
21
|
get502Template,
|
|
20
22
|
get5xxTemplate,
|
|
@@ -70,6 +72,10 @@ class DefaultProvider extends BaseProvider {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
async reload() {
|
|
75
|
+
if (process.env.NODE_ENV === 'development') {
|
|
76
|
+
return this.start();
|
|
77
|
+
}
|
|
78
|
+
|
|
73
79
|
await pm2.connectAsync();
|
|
74
80
|
|
|
75
81
|
// ensure daemon is live
|
|
@@ -218,4 +224,27 @@ DefaultProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
218
224
|
return result;
|
|
219
225
|
};
|
|
220
226
|
|
|
227
|
+
DefaultProvider.getUsablePorts = async () =>
|
|
228
|
+
getUsablePorts(
|
|
229
|
+
'default',
|
|
230
|
+
(port) =>
|
|
231
|
+
new Promise((resolve) => {
|
|
232
|
+
try {
|
|
233
|
+
const server = http.createServer();
|
|
234
|
+
|
|
235
|
+
server.once('error', () => {
|
|
236
|
+
server.close();
|
|
237
|
+
resolve(false);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
server.listen(port, (err) => {
|
|
241
|
+
server.close();
|
|
242
|
+
resolve(!err);
|
|
243
|
+
});
|
|
244
|
+
} catch (err) {
|
|
245
|
+
resolve(false);
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
);
|
|
249
|
+
|
|
221
250
|
module.exports = DefaultProvider;
|
package/lib/default/proxy.js
CHANGED
|
@@ -93,6 +93,7 @@ module.exports = class ReverseProxy {
|
|
|
93
93
|
|
|
94
94
|
// @link: https://github.com/http-party/node-http-proxy/issues/1401
|
|
95
95
|
this.proxy.on('proxyRes', (proxyRes) => {
|
|
96
|
+
delete proxyRes.headers['x-powered-by'];
|
|
96
97
|
this.opts.headers.forEach((x) => {
|
|
97
98
|
proxyRes.headers[x.key] = x.value;
|
|
98
99
|
});
|
package/lib/nginx/index.js
CHANGED
|
@@ -38,6 +38,7 @@ const {
|
|
|
38
38
|
const {
|
|
39
39
|
decideHttpPort,
|
|
40
40
|
decideHttpsPort,
|
|
41
|
+
getUsablePorts,
|
|
41
42
|
get404Template,
|
|
42
43
|
get502Template,
|
|
43
44
|
get5xxTemplate,
|
|
@@ -781,7 +782,6 @@ NginxProvider.describe = async ({ configDir = '' } = {}) => {
|
|
|
781
782
|
* @param {string} param.configDir nginx config directory
|
|
782
783
|
*/
|
|
783
784
|
NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
784
|
-
logger.info('check nginx provider');
|
|
785
785
|
logger.info('check formal config directory', { configDir });
|
|
786
786
|
const binPath = shelljs.which('nginx');
|
|
787
787
|
const result = {
|
|
@@ -823,24 +823,24 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
823
823
|
}
|
|
824
824
|
}
|
|
825
825
|
|
|
826
|
-
const
|
|
826
|
+
const tmpDir = path.join(
|
|
827
827
|
os.tmpdir(),
|
|
828
|
-
`
|
|
828
|
+
`test_nginx_provider-${Date.now()}-${Math.ceil(Math.random() * 10000)}`,
|
|
829
829
|
CONFIG_FOLDER_NAME
|
|
830
830
|
);
|
|
831
|
-
fs.mkdirSync(
|
|
831
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
832
832
|
|
|
833
|
-
const
|
|
834
|
-
|
|
833
|
+
const provider = new NginxProvider({ configDir: tmpDir, isTest: true });
|
|
834
|
+
provider.initialize();
|
|
835
835
|
|
|
836
|
-
logger.info('check:addTestServer', { configPath:
|
|
836
|
+
logger.info('check:addTestServer', { configPath: provider.configPath });
|
|
837
837
|
await addTestServer({
|
|
838
|
-
configPath:
|
|
838
|
+
configPath: provider.configPath,
|
|
839
839
|
port: await getPort(),
|
|
840
840
|
upstreamPort: await getPort(),
|
|
841
841
|
});
|
|
842
842
|
|
|
843
|
-
const missingModules = getMissingModules(
|
|
843
|
+
const missingModules = getMissingModules(provider.readNginxConfigParams());
|
|
844
844
|
|
|
845
845
|
if (missingModules.length > 0) {
|
|
846
846
|
result.available = false;
|
|
@@ -850,9 +850,10 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
850
850
|
return result;
|
|
851
851
|
}
|
|
852
852
|
|
|
853
|
-
await
|
|
853
|
+
await provider.start();
|
|
854
|
+
await provider.stop();
|
|
854
855
|
|
|
855
|
-
|
|
856
|
+
fs.rmdirSync(tmpDir, { recursive: true });
|
|
856
857
|
|
|
857
858
|
return result;
|
|
858
859
|
};
|
|
@@ -860,4 +861,29 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
860
861
|
NginxProvider.getStatus = getNginxStatus;
|
|
861
862
|
NginxProvider.exists = () => !!shelljs.which('nginx');
|
|
862
863
|
|
|
864
|
+
NginxProvider.getUsablePorts = async () =>
|
|
865
|
+
getUsablePorts('nginx', async (port) => {
|
|
866
|
+
try {
|
|
867
|
+
const configDir = path.join(
|
|
868
|
+
os.tmpdir(),
|
|
869
|
+
`test_nginx_provider-${Date.now()}-${Math.ceil(Math.random() * 10000)}`,
|
|
870
|
+
CONFIG_FOLDER_NAME
|
|
871
|
+
);
|
|
872
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
873
|
+
|
|
874
|
+
const provider = new NginxProvider({ configDir, isTest: true });
|
|
875
|
+
provider.initialize();
|
|
876
|
+
|
|
877
|
+
await addTestServer({ configPath: provider.configPath, port });
|
|
878
|
+
await provider.start();
|
|
879
|
+
await provider.stop();
|
|
880
|
+
|
|
881
|
+
fs.rmdirSync(configDir, { recursive: true });
|
|
882
|
+
|
|
883
|
+
return true;
|
|
884
|
+
} catch (err) {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
|
|
863
889
|
module.exports = NginxProvider;
|
package/lib/nginx/util.js
CHANGED
|
@@ -57,20 +57,22 @@ const addTestServer = ({ configPath, port, upstreamPort }) =>
|
|
|
57
57
|
|
|
58
58
|
location / {
|
|
59
59
|
if ($uri = /admin/did-connect) {include includes/cors-strict; include includes/security;}
|
|
60
|
-
return 200 'Hello
|
|
60
|
+
return 200 'Hello Blocklet Server!';
|
|
61
61
|
}
|
|
62
62
|
`
|
|
63
63
|
);
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
if (upstreamPort) {
|
|
66
|
+
conf.nginx._addVerbatimBlock(
|
|
67
|
+
'stream',
|
|
68
|
+
`
|
|
68
69
|
server {
|
|
69
70
|
listen ${upstreamPort} udp;
|
|
70
71
|
proxy_pass 127.0.0.1:${port};
|
|
71
72
|
}
|
|
72
73
|
`
|
|
73
|
-
|
|
74
|
+
);
|
|
75
|
+
}
|
|
74
76
|
|
|
75
77
|
conf.on('flushed', () => resolve());
|
|
76
78
|
conf.live(configPath);
|
package/lib/util.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const getPort = require('get-port');
|
|
5
|
+
const portUsed = require('port-used');
|
|
1
6
|
const sortBy = require('lodash/sortBy');
|
|
2
7
|
const isValidDomain = require('is-valid-domain');
|
|
3
8
|
const checkDomainMatch = require('@abtnode/util/lib/check-domain-match');
|
|
@@ -8,7 +13,7 @@ const {
|
|
|
8
13
|
IP,
|
|
9
14
|
DEFAULT_HTTP_PORT,
|
|
10
15
|
DEFAULT_HTTPS_PORT,
|
|
11
|
-
|
|
16
|
+
DEFAULT_IP_DOMAIN_SUFFIX,
|
|
12
17
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
13
18
|
ROUTING_RULE_TYPES,
|
|
14
19
|
SLOT_FOR_IP_DNS_SITE,
|
|
@@ -110,7 +115,7 @@ const isSpecificDomain = (domain) => {
|
|
|
110
115
|
return false;
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
if (domain.endsWith(
|
|
118
|
+
if (domain.endsWith(DEFAULT_IP_DOMAIN_SUFFIX)) {
|
|
114
119
|
return false;
|
|
115
120
|
}
|
|
116
121
|
|
|
@@ -118,7 +123,7 @@ const isSpecificDomain = (domain) => {
|
|
|
118
123
|
};
|
|
119
124
|
|
|
120
125
|
const toSlotDomain = (domain) => {
|
|
121
|
-
if (domain.endsWith(
|
|
126
|
+
if (domain.endsWith(DEFAULT_IP_DOMAIN_SUFFIX)) {
|
|
122
127
|
const subDomain = domain.split('.').shift();
|
|
123
128
|
const matches = subDomain.match(IP);
|
|
124
129
|
if (matches) {
|
|
@@ -148,9 +153,45 @@ const matchRule = (rules, url) => {
|
|
|
148
153
|
return findRule(rulesWithSuffix, url) || findRule(rulesWithoutSuffix, url);
|
|
149
154
|
};
|
|
150
155
|
|
|
156
|
+
const isPortOccupied = (port) => portUsed.check(port);
|
|
157
|
+
const getUsablePort = async (preferredPorts, hasPortPermission) => {
|
|
158
|
+
for (const port of preferredPorts) {
|
|
159
|
+
const occupied = await isPortOccupied(port);
|
|
160
|
+
if (!occupied) {
|
|
161
|
+
const listenable = await hasPortPermission(port);
|
|
162
|
+
if (listenable) {
|
|
163
|
+
return port;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return getPort();
|
|
169
|
+
};
|
|
170
|
+
const getUsablePorts = async (provider, hasPortPermission) => {
|
|
171
|
+
const file = path.join(process.env.PM2_HOME, `${provider}-preferred-ports.json`);
|
|
172
|
+
if (fs.existsSync(file)) {
|
|
173
|
+
const config = fs.readJsonSync(file);
|
|
174
|
+
if (config.httpPort && config.httpsPort) {
|
|
175
|
+
return config;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const [httpPort, httpsPort] = await Promise.all([
|
|
180
|
+
getUsablePort([80, 8080], hasPortPermission),
|
|
181
|
+
getUsablePort([443, 8443], hasPortPermission),
|
|
182
|
+
]);
|
|
183
|
+
|
|
184
|
+
const config = { httpPort, httpsPort };
|
|
185
|
+
fs.writeJsonSync(file, config);
|
|
186
|
+
return config;
|
|
187
|
+
};
|
|
188
|
+
|
|
151
189
|
module.exports = {
|
|
152
190
|
decideHttpPort,
|
|
153
191
|
decideHttpsPort,
|
|
192
|
+
getUsablePorts,
|
|
193
|
+
getUsablePort,
|
|
194
|
+
isPortOccupied,
|
|
154
195
|
findCertificate,
|
|
155
196
|
concatPath,
|
|
156
197
|
trimEndSlash,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abtnode/router-provider",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.31",
|
|
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,10 +32,10 @@
|
|
|
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.31",
|
|
36
|
+
"@abtnode/logger": "1.6.31",
|
|
37
|
+
"@abtnode/router-templates": "1.6.31",
|
|
38
|
+
"@abtnode/util": "1.6.31",
|
|
39
39
|
"axios": "^0.25.0",
|
|
40
40
|
"debug": "^4.3.3",
|
|
41
41
|
"find-process": "^1.4.3",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"moment": "^2.29.1",
|
|
50
50
|
"nginx-conf": "^1.5.0",
|
|
51
51
|
"object-hash": "^3.0.0",
|
|
52
|
+
"port-used": "^2.0.8",
|
|
52
53
|
"promise-retry": "^2.0.1",
|
|
53
54
|
"shelljs": "^0.8.4",
|
|
54
55
|
"tar": "^6.1.0",
|
|
@@ -61,5 +62,5 @@
|
|
|
61
62
|
"fs-extra": "^10.0.0",
|
|
62
63
|
"needle": "^3.0.0"
|
|
63
64
|
},
|
|
64
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "ccda31a16ac6b606d34336fcc6db0b2aff15c32e"
|
|
65
66
|
}
|