@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/index.js
CHANGED
|
@@ -10,7 +10,6 @@ const getPort = require('get-port');
|
|
|
10
10
|
const uniqBy = require('lodash/uniqBy');
|
|
11
11
|
const isEmpty = require('lodash/isEmpty');
|
|
12
12
|
const cloneDeep = require('lodash/cloneDeep');
|
|
13
|
-
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
14
13
|
const {
|
|
15
14
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
16
15
|
ROUTING_RULE_TYPES,
|
|
@@ -23,28 +22,31 @@ const md5 = require('@abtnode/util/lib/md5');
|
|
|
23
22
|
|
|
24
23
|
const promiseRetry = require('promise-retry');
|
|
25
24
|
|
|
26
|
-
const logger = require('@abtnode/logger')(
|
|
25
|
+
const logger = require('@abtnode/logger')('router:nginx:controller');
|
|
27
26
|
|
|
28
27
|
const BaseProvider = require('../base');
|
|
29
|
-
const util = require('./util');
|
|
30
28
|
const {
|
|
31
29
|
addTestServer,
|
|
32
|
-
decideHttpPort,
|
|
33
|
-
decideHttpsPort,
|
|
34
30
|
formatError,
|
|
35
31
|
getNginxLoadModuleDirectives,
|
|
32
|
+
parseNginxConfigArgs,
|
|
33
|
+
getNginxStatus,
|
|
34
|
+
rotateNginxLogFile,
|
|
35
|
+
getMissingModules,
|
|
36
|
+
getMainTemplate,
|
|
37
|
+
} = require('./util');
|
|
38
|
+
const {
|
|
39
|
+
decideHttpPort,
|
|
40
|
+
decideHttpsPort,
|
|
36
41
|
get404Template,
|
|
37
42
|
get502Template,
|
|
38
43
|
get5xxTemplate,
|
|
39
44
|
getWelcomeTemplate,
|
|
40
|
-
parseNginxConfigArgs,
|
|
41
45
|
trimEndSlash,
|
|
42
46
|
concatPath,
|
|
43
47
|
findCertificate,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
getMissingModules,
|
|
47
|
-
} = require('./util');
|
|
48
|
+
formatRoutingTable,
|
|
49
|
+
} = require('../util');
|
|
48
50
|
|
|
49
51
|
const REQUIRED_MODULES = [{ configName: 'with-stream', moduleBinaryName: 'ngx_stream_module.so' }];
|
|
50
52
|
|
|
@@ -52,33 +54,33 @@ const REQUIRED_MODULES = [{ configName: 'with-stream', moduleBinaryName: 'ngx_st
|
|
|
52
54
|
const DID_AUTH_PATH_PREFIX = `${DEFAULT_ADMIN_PATH}/api/did`;
|
|
53
55
|
|
|
54
56
|
// convert wildcard domain and ipDnsDomain template to regex
|
|
55
|
-
const parseServerName = (
|
|
57
|
+
const parseServerName = (domain) => {
|
|
56
58
|
// ipDnsDomain template
|
|
57
|
-
if (
|
|
58
|
-
const name =
|
|
59
|
+
if (domain.includes(SLOT_FOR_IP_DNS_SITE)) {
|
|
60
|
+
const name = domain.replace(/\./g, '\\.').replace(SLOT_FOR_IP_DNS_SITE, '\\d+-\\d+-\\d+-\\d+');
|
|
59
61
|
return `~^${name}$`;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
// wildcard domain
|
|
63
|
-
if (
|
|
64
|
-
const name =
|
|
65
|
+
if (domain.startsWith('*.')) {
|
|
66
|
+
const name = domain.replace('*', '').replace(/\./g, '\\.');
|
|
65
67
|
return `~.+${name}$`;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
return
|
|
70
|
+
return domain;
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
class NginxProvider extends BaseProvider {
|
|
72
74
|
/**
|
|
73
|
-
* @param {string}
|
|
75
|
+
* @param {string} configDir
|
|
74
76
|
* @param {number} httpPort
|
|
75
77
|
* @param {number} httpPort
|
|
76
78
|
* @param {number} cacheDisabled
|
|
77
79
|
*/
|
|
78
|
-
constructor({
|
|
79
|
-
super('nginx
|
|
80
|
-
if (!
|
|
81
|
-
throw new Error('invalid
|
|
80
|
+
constructor({ configDir, httpPort, httpsPort, cacheDisabled, isTest }) {
|
|
81
|
+
super('nginx');
|
|
82
|
+
if (!configDir) {
|
|
83
|
+
throw new Error('invalid configDir');
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
if (shelljs.which('nginx')) {
|
|
@@ -88,30 +90,30 @@ class NginxProvider extends BaseProvider {
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
this.isTest = !!isTest;
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
93
|
+
this.configDir = configDir;
|
|
94
|
+
this.logDir = path.join(this.configDir, 'log');
|
|
95
|
+
this.accessLog = path.join(this.logDir, 'access.log');
|
|
96
|
+
this.errorLog = path.join(this.logDir, 'error.log');
|
|
97
|
+
this.tmpDir = path.join(this.configDir, 'tmp');
|
|
98
|
+
this.certDir = path.join(this.configDir, 'certs');
|
|
99
|
+
this.includesDir = path.join(this.configDir, 'includes');
|
|
100
|
+
this.wwwDir = path.join(this.configDir, 'www');
|
|
99
101
|
|
|
100
|
-
this.
|
|
102
|
+
this.configPath = path.join(this.configDir, 'nginx.conf');
|
|
101
103
|
|
|
102
104
|
this.httpPort = decideHttpPort(httpPort);
|
|
103
105
|
this.httpsPort = decideHttpsPort(httpsPort);
|
|
104
106
|
this.cacheDisabled = !!cacheDisabled;
|
|
105
107
|
|
|
106
108
|
logger.info('nginx provider config', {
|
|
107
|
-
|
|
109
|
+
configDir,
|
|
108
110
|
httpPort: this.httpPort,
|
|
109
111
|
httpsPort: this.httpsPort,
|
|
110
112
|
cacheDisabled: this.cacheDisabled,
|
|
111
113
|
});
|
|
112
114
|
|
|
113
115
|
// ensure directories
|
|
114
|
-
[this.
|
|
116
|
+
[this.configDir, this.logDir, this.tmpDir, this.certDir].forEach((dir) => {
|
|
115
117
|
if (!fs.existsSync(dir)) {
|
|
116
118
|
fs.mkdirSync(dir);
|
|
117
119
|
}
|
|
@@ -123,8 +125,6 @@ class NginxProvider extends BaseProvider {
|
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
async update({ routingTable = [], certificates = [], globalHeaders, services = [], nodeInfo = {} } = {}) {
|
|
126
|
-
logger.info('routing table:', routingTable);
|
|
127
|
-
|
|
128
128
|
if (!Array.isArray(routingTable)) {
|
|
129
129
|
throw new Error('routingTable must be an array');
|
|
130
130
|
}
|
|
@@ -133,9 +133,9 @@ class NginxProvider extends BaseProvider {
|
|
|
133
133
|
|
|
134
134
|
// eslint-disable-next-line consistent-return
|
|
135
135
|
return new Promise((resolve, reject) => {
|
|
136
|
-
const confTemplate =
|
|
137
|
-
logDir: this.
|
|
138
|
-
|
|
136
|
+
const confTemplate = getMainTemplate({
|
|
137
|
+
logDir: this.logDir.replace(this.configDir, '').replace(/^\//, ''),
|
|
138
|
+
tmpDir: this.tmpDir.replace(this.configDir, '').replace(/^\//, ''),
|
|
139
139
|
workerProcess: this.getWorkerProcess(),
|
|
140
140
|
nginxLoadModules: getNginxLoadModuleDirectives(REQUIRED_MODULES, this.readNginxConfigParams()).join(os.EOL),
|
|
141
141
|
});
|
|
@@ -148,90 +148,35 @@ class NginxProvider extends BaseProvider {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
conf.on('flushed', () => resolve());
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
let serverName = site.domain;
|
|
160
|
-
if (site.domain === DOMAIN_FOR_DEFAULT_SITE) {
|
|
161
|
-
serverName = '_';
|
|
162
|
-
addedDefaultServer = true;
|
|
151
|
+
conf.live(this.configPath);
|
|
152
|
+
|
|
153
|
+
const { sites, configs: siteCorsConfigs } = formatRoutingTable(routingTable, (rules, rule) => {
|
|
154
|
+
// TODO: this is really hacky, and should be abstracted out
|
|
155
|
+
if (rule.type === ROUTING_RULE_TYPES.DAEMON && rule.prefix === DEFAULT_ADMIN_PATH) {
|
|
156
|
+
const clonedRule = cloneDeep(rule);
|
|
157
|
+
clonedRule.prefix = DID_AUTH_PATH_PREFIX;
|
|
158
|
+
rules.push(clonedRule);
|
|
163
159
|
}
|
|
164
|
-
|
|
165
|
-
siteCorsConfigs.push({ serverName, corsAllowedOrigins: site.corsAllowedOrigins });
|
|
166
|
-
|
|
167
|
-
if (!rulesMap.has(serverName)) {
|
|
168
|
-
rulesMap.set(serverName, {
|
|
169
|
-
rules: [],
|
|
170
|
-
port: site.port,
|
|
171
|
-
corsAllowedOrigins: site.corsAllowedOrigins,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
(site.rules || []).forEach((x) => {
|
|
176
|
-
const prefix = trimEndSlash(x.from.pathPrefix || '/');
|
|
177
|
-
const groupPrefix = trimEndSlash(x.from.groupPathPrefix || '/');
|
|
178
|
-
const suffix = trimEndSlash(x.from.pathSuffix || '');
|
|
179
|
-
|
|
180
|
-
const rule = {
|
|
181
|
-
ruleId: x.id,
|
|
182
|
-
type: x.to.type,
|
|
183
|
-
prefix,
|
|
184
|
-
groupPrefix,
|
|
185
|
-
suffix,
|
|
186
|
-
};
|
|
187
|
-
if (x.to.type === ROUTING_RULE_TYPES.REDIRECT) {
|
|
188
|
-
rule.redirectCode = x.to.redirectCode || 302;
|
|
189
|
-
rule.url = x.to.url;
|
|
190
|
-
} else {
|
|
191
|
-
rule.port = x.to.port;
|
|
192
|
-
rule.did = x.to.did;
|
|
193
|
-
rule.realDid = x.to.realDid;
|
|
194
|
-
rule.target = trimEndSlash(normalizePathPrefix(x.to.target || '/'));
|
|
195
|
-
rule.services = x.services || [];
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const tmpPath = concatPath(prefix, suffix);
|
|
199
|
-
const tmpRules = rulesMap.get(serverName).rules;
|
|
200
|
-
if (!tmpRules.find(({ prefix: p, suffix: s }) => concatPath(p, s) === tmpPath)) {
|
|
201
|
-
rulesMap.get(serverName).rules.push(rule);
|
|
202
|
-
|
|
203
|
-
if (rule.type === ROUTING_RULE_TYPES.DAEMON && rule.prefix === DEFAULT_ADMIN_PATH) {
|
|
204
|
-
const clonedRule = cloneDeep(rule);
|
|
205
|
-
clonedRule.prefix = DID_AUTH_PATH_PREFIX;
|
|
206
|
-
rulesMap.get(serverName).rules.push(clonedRule);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
160
|
});
|
|
211
161
|
|
|
212
|
-
logger.debug('rule map:', { rulesMap });
|
|
213
|
-
|
|
214
162
|
this._addCorsMap(conf, siteCorsConfigs);
|
|
215
|
-
|
|
216
|
-
// disable server version
|
|
217
163
|
conf.nginx.http._add('server_tokens', 'off');
|
|
218
164
|
this._addGlobalHeaders(conf, globalHeaders);
|
|
219
|
-
|
|
220
165
|
this._addExposeServices(conf, services);
|
|
221
166
|
|
|
167
|
+
logger.info('routing sites:', sites);
|
|
222
168
|
// eslint-disable-next-line no-restricted-syntax
|
|
223
|
-
for (const
|
|
224
|
-
const
|
|
225
|
-
const
|
|
169
|
+
for (const site of sites) {
|
|
170
|
+
const { domain, port, rules, corsAllowedOrigins } = site;
|
|
171
|
+
const certificate = findCertificate(certificates, domain);
|
|
226
172
|
|
|
227
|
-
const parsedServerName = parseServerName(
|
|
228
|
-
|
|
229
|
-
if (isHttps) {
|
|
173
|
+
const parsedServerName = parseServerName(domain);
|
|
174
|
+
if (certificate) {
|
|
230
175
|
// HTTPS configurations
|
|
231
176
|
// update all certs to disk
|
|
232
177
|
certificates.forEach((item) => {
|
|
233
|
-
const crtPath = `${path.join(this.
|
|
234
|
-
const keyPath = `${path.join(this.
|
|
178
|
+
const crtPath = `${path.join(this.certDir, item.domain)}.crt`;
|
|
179
|
+
const keyPath = `${path.join(this.certDir, item.domain)}.key`;
|
|
235
180
|
fs.writeFileSync(crtPath, item.certificate);
|
|
236
181
|
fs.writeFileSync(keyPath, item.privateKey);
|
|
237
182
|
});
|
|
@@ -239,7 +184,7 @@ class NginxProvider extends BaseProvider {
|
|
|
239
184
|
// if match certificate, then add https server
|
|
240
185
|
this._addHttpsServer({
|
|
241
186
|
conf,
|
|
242
|
-
locations:
|
|
187
|
+
locations: rules,
|
|
243
188
|
certificateFileName: certificate.domain,
|
|
244
189
|
serverName: parsedServerName,
|
|
245
190
|
corsAllowedOrigins,
|
|
@@ -248,7 +193,7 @@ class NginxProvider extends BaseProvider {
|
|
|
248
193
|
} else {
|
|
249
194
|
this._addHttpServer({
|
|
250
195
|
conf,
|
|
251
|
-
locations:
|
|
196
|
+
locations: rules,
|
|
252
197
|
serverName: parsedServerName,
|
|
253
198
|
corsAllowedOrigins,
|
|
254
199
|
port,
|
|
@@ -257,7 +202,7 @@ class NginxProvider extends BaseProvider {
|
|
|
257
202
|
}
|
|
258
203
|
}
|
|
259
204
|
|
|
260
|
-
if (
|
|
205
|
+
if (!sites.find((x) => x.domain === '_')) {
|
|
261
206
|
this._addDefaultServer(conf, nodeInfo.port);
|
|
262
207
|
}
|
|
263
208
|
|
|
@@ -267,8 +212,8 @@ class NginxProvider extends BaseProvider {
|
|
|
267
212
|
}
|
|
268
213
|
|
|
269
214
|
async reload() {
|
|
270
|
-
const nginxStatus = await getNginxStatus(this.
|
|
271
|
-
if (nginxStatus.
|
|
215
|
+
const nginxStatus = await getNginxStatus(this.configPath);
|
|
216
|
+
if (nginxStatus.managed) {
|
|
272
217
|
const result = this._exec('reload');
|
|
273
218
|
logger.info('reload:reload', { result: result.stdout });
|
|
274
219
|
return result;
|
|
@@ -296,12 +241,12 @@ class NginxProvider extends BaseProvider {
|
|
|
296
241
|
|
|
297
242
|
// FIXME: 这个函数可以不暴露出去?
|
|
298
243
|
initialize() {
|
|
299
|
-
if (!fs.existsSync(this.
|
|
244
|
+
if (!fs.existsSync(this.configPath)) {
|
|
300
245
|
fs.writeFileSync(
|
|
301
|
-
this.
|
|
302
|
-
|
|
303
|
-
logDir: this.
|
|
304
|
-
|
|
246
|
+
this.configPath,
|
|
247
|
+
getMainTemplate({
|
|
248
|
+
logDir: this.logDir.replace(this.configDir, '').replace(/^\//, ''),
|
|
249
|
+
tmpDir: this.tmpDir.replace(this.configDir, '').replace(/^\//, ''),
|
|
305
250
|
nginxLoadModules: getNginxLoadModuleDirectives(REQUIRED_MODULES, this.readNginxConfigParams()).join(os.EOL),
|
|
306
251
|
workerProcess: this.getWorkerProcess(),
|
|
307
252
|
})
|
|
@@ -310,7 +255,7 @@ class NginxProvider extends BaseProvider {
|
|
|
310
255
|
}
|
|
311
256
|
|
|
312
257
|
async validateConfig() {
|
|
313
|
-
const command = `${this.binPath} -t -c ${this.
|
|
258
|
+
const command = `${this.binPath} -t -c ${this.configPath} -p ${this.configDir}`; // eslint-disable-line no-param-reassign
|
|
314
259
|
const result = shelljs.exec(command, { silent: true });
|
|
315
260
|
if (result.code !== 0) {
|
|
316
261
|
logger.info(`exec ${command} error`, { error: result.stderr });
|
|
@@ -319,41 +264,29 @@ class NginxProvider extends BaseProvider {
|
|
|
319
264
|
}
|
|
320
265
|
|
|
321
266
|
async rotateLogs() {
|
|
322
|
-
const nginxStatus = await getNginxStatus(this.
|
|
323
|
-
if (!nginxStatus.
|
|
267
|
+
const nginxStatus = await getNginxStatus(this.configDir);
|
|
268
|
+
if (!nginxStatus.managed) {
|
|
324
269
|
logger.warn('nginx is not running');
|
|
325
270
|
return;
|
|
326
271
|
}
|
|
327
272
|
|
|
328
273
|
logger.info('start rotate nginx log files');
|
|
329
|
-
const files = [this.
|
|
274
|
+
const files = [this.accessLog, this.errorLog];
|
|
330
275
|
const rotateTasks = files.map(
|
|
331
|
-
(file) => rotateNginxLogFile({ file, nginxPid: nginxStatus.pid, cwd: this.
|
|
276
|
+
(file) => rotateNginxLogFile({ file, nginxPid: nginxStatus.pid, cwd: this.logDir })
|
|
332
277
|
// eslint-disable-next-line function-paren-newline
|
|
333
278
|
);
|
|
334
279
|
await Promise.all(rotateTasks);
|
|
335
280
|
logger.info('rotate nginx log files finished');
|
|
336
281
|
}
|
|
337
282
|
|
|
338
|
-
getWorkerProcess() {
|
|
339
|
-
if (this.isTest) {
|
|
340
|
-
return 1;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (process.env.NODE_ENV === 'production') {
|
|
344
|
-
return os.cpus().length;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return 1;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
283
|
/**
|
|
351
284
|
* execute nginx command, default is to start nginx
|
|
352
285
|
* @param {string} param param of nginx -s {param}
|
|
353
286
|
*/
|
|
354
287
|
_exec(param = '') {
|
|
355
288
|
logger.info('exec', { param });
|
|
356
|
-
let command = `${this.binPath} -c ${this.
|
|
289
|
+
let command = `${this.binPath} -c ${this.configPath} -p ${this.configDir}`; // eslint-disable-line no-param-reassign
|
|
357
290
|
if (param) {
|
|
358
291
|
command = `${command} -s ${param}`;
|
|
359
292
|
}
|
|
@@ -396,6 +329,11 @@ class NginxProvider extends BaseProvider {
|
|
|
396
329
|
return;
|
|
397
330
|
}
|
|
398
331
|
|
|
332
|
+
if (type === ROUTING_RULE_TYPES.DIRECT_RESPONSE) {
|
|
333
|
+
this._addDirectResponseLocation(args);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
399
337
|
if (type === ROUTING_RULE_TYPES.NONE) {
|
|
400
338
|
this._addNotFoundLocation(args);
|
|
401
339
|
return;
|
|
@@ -509,7 +447,7 @@ class NginxProvider extends BaseProvider {
|
|
|
509
447
|
}
|
|
510
448
|
|
|
511
449
|
_addRedirectTypeLocation({ server, url, redirectCode, prefix, suffix }) {
|
|
512
|
-
const
|
|
450
|
+
const cleanUrl = trimEndSlash(url);
|
|
513
451
|
|
|
514
452
|
server._add('location', `${concatPath(prefix, suffix)}`);
|
|
515
453
|
const location = this._getLastLocation(server);
|
|
@@ -517,15 +455,15 @@ class NginxProvider extends BaseProvider {
|
|
|
517
455
|
location._addVerbatimBlock('if ($query_string)', 'set $abt_query_string "?$query_string";');
|
|
518
456
|
|
|
519
457
|
// 如果当前请求的 path 和 prefix 一样,则不需要重写,直接返回重定向地址就可以了
|
|
520
|
-
location._addVerbatimBlock(`if ($uri = ${prefix})`, `return ${redirectCode} ${
|
|
458
|
+
location._addVerbatimBlock(`if ($uri = ${prefix})`, `return ${redirectCode} ${cleanUrl}$abt_query_string;`);
|
|
521
459
|
|
|
522
460
|
// 如果 prefix 是根路径,则不需要重写,直接将当前的请求附加到设置的重定向地址后面
|
|
523
461
|
if (prefix === '/') {
|
|
524
|
-
location._add('return', `${redirectCode} ${
|
|
462
|
+
location._add('return', `${redirectCode} ${cleanUrl}$request_uri`);
|
|
525
463
|
} else {
|
|
526
464
|
// 将当前请求中的 prefix 去掉,然后拼接对应的重定地址
|
|
527
465
|
location._add('rewrite', `^${prefix}(.*) $1`);
|
|
528
|
-
location._add('return', `${redirectCode} ${
|
|
466
|
+
location._add('return', `${redirectCode} ${cleanUrl === '/' ? '' : cleanUrl}$1$abt_query_string`);
|
|
529
467
|
}
|
|
530
468
|
}
|
|
531
469
|
|
|
@@ -545,6 +483,17 @@ class NginxProvider extends BaseProvider {
|
|
|
545
483
|
location._add('proxy_pass', `http://127.0.0.1:${port}`);
|
|
546
484
|
}
|
|
547
485
|
|
|
486
|
+
_addDirectResponseLocation({ server, response, prefix, suffix }) {
|
|
487
|
+
server._add('location', concatPath(prefix, suffix));
|
|
488
|
+
const location = this._getLastLocation(server);
|
|
489
|
+
this._addCommonHeader(location);
|
|
490
|
+
if (response.contentType) {
|
|
491
|
+
location._add('default_type', response.contentType);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
location._add('return', `${response.status} "${response.body}"`);
|
|
495
|
+
}
|
|
496
|
+
|
|
548
497
|
/**
|
|
549
498
|
* The main purpose is to add a slash(/) suffix to the address.
|
|
550
499
|
* @param {object} location nginx-conf location object
|
|
@@ -591,7 +540,7 @@ class NginxProvider extends BaseProvider {
|
|
|
591
540
|
throw new Error('daemonPort is required');
|
|
592
541
|
}
|
|
593
542
|
|
|
594
|
-
server._add('root', this.
|
|
543
|
+
server._add('root', this.wwwDir.replace(this.configDir, '').replace(/^\//, ''));
|
|
595
544
|
server._add('error_page', '404 =404 /_abtnode_404');
|
|
596
545
|
server._add('error_page', '502 =502 /_abtnode_502');
|
|
597
546
|
server._add('error_page', '500 502 503 504 =500 /_abtnode_5xx');
|
|
@@ -616,21 +565,21 @@ class NginxProvider extends BaseProvider {
|
|
|
616
565
|
|
|
617
566
|
_addWwwFiles(nodeInfo) {
|
|
618
567
|
const welcomePage = nodeInfo.enableWelcomePage ? getWelcomeTemplate(nodeInfo) : get404Template(nodeInfo);
|
|
619
|
-
fs.writeFileSync(`${this.
|
|
620
|
-
fs.writeFileSync(`${this.
|
|
621
|
-
fs.writeFileSync(`${this.
|
|
622
|
-
fs.writeFileSync(`${this.
|
|
568
|
+
fs.writeFileSync(`${this.wwwDir}/index.html`, welcomePage); // disable index.html
|
|
569
|
+
fs.writeFileSync(`${this.wwwDir}/404.html`, get404Template(nodeInfo));
|
|
570
|
+
fs.writeFileSync(`${this.wwwDir}/502.html`, get502Template(nodeInfo));
|
|
571
|
+
fs.writeFileSync(`${this.wwwDir}/5xx.html`, get5xxTemplate(nodeInfo));
|
|
623
572
|
}
|
|
624
573
|
|
|
625
574
|
_copyConfigFiles() {
|
|
626
|
-
fs.copySync(path.join(__dirname, 'includes'), this.
|
|
575
|
+
fs.copySync(path.join(__dirname, 'includes'), this.includesDir, {
|
|
627
576
|
overwrite: true,
|
|
628
577
|
});
|
|
629
|
-
fs.copySync(path.join(__dirname, '..', 'www'), this.
|
|
578
|
+
fs.copySync(path.join(__dirname, '..', 'www'), this.wwwDir, { overwrite: true });
|
|
630
579
|
}
|
|
631
580
|
|
|
632
581
|
_ensureDhparam() {
|
|
633
|
-
const targetFile = path.join(this.
|
|
582
|
+
const targetFile = path.join(this.includesDir, 'dhparam.pem');
|
|
634
583
|
if (fs.existsSync(targetFile)) {
|
|
635
584
|
this._isDhparamGenerated = true;
|
|
636
585
|
return;
|
|
@@ -658,19 +607,6 @@ class NginxProvider extends BaseProvider {
|
|
|
658
607
|
}
|
|
659
608
|
}
|
|
660
609
|
|
|
661
|
-
_sortLocations(rules = []) {
|
|
662
|
-
const rulesWithoutSuffix = rules.filter((x) => !x.suffix);
|
|
663
|
-
const rulesWithSuffix = rules
|
|
664
|
-
.filter((x) => x.suffix)
|
|
665
|
-
.sort((a, b) => {
|
|
666
|
-
const lenA = (a.prefix || '').length + (a.prefix || '').length;
|
|
667
|
-
const lenB = (b.prefix || '').length + (b.prefix || '').length;
|
|
668
|
-
return lenB - lenA;
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
return rulesWithoutSuffix.concat(rulesWithSuffix);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
610
|
_addGlobalHeaders(conf, headers) {
|
|
675
611
|
if (!headers || Object.prototype.toString.call(headers) !== '[object Object]') {
|
|
676
612
|
return;
|
|
@@ -746,8 +682,8 @@ class NginxProvider extends BaseProvider {
|
|
|
746
682
|
conf.nginx.http._add('server');
|
|
747
683
|
const httpsServerUnit = this._getLastServer(conf);
|
|
748
684
|
|
|
749
|
-
const crtPath = `${path.join(this.
|
|
750
|
-
const keyPath = `${path.join(this.
|
|
685
|
+
const crtPath = `${path.join(this.certDir, certificateFileName)}.crt`;
|
|
686
|
+
const keyPath = `${path.join(this.certDir, certificateFileName)}.key`;
|
|
751
687
|
|
|
752
688
|
let listen = `${this.httpsPort} ssl`;
|
|
753
689
|
if (serverName === '_') {
|
|
@@ -804,12 +740,19 @@ class NginxProvider extends BaseProvider {
|
|
|
804
740
|
|
|
805
741
|
allowedOrigins.push('default "";');
|
|
806
742
|
conf.nginx.http._addVerbatimBlock(
|
|
807
|
-
`map $http_origin $allow_origin_${md5(parseServerName(corsConfig.
|
|
743
|
+
`map $http_origin $allow_origin_${md5(parseServerName(corsConfig.domain))}`,
|
|
808
744
|
allowedOrigins.join(' ')
|
|
809
745
|
);
|
|
810
746
|
}
|
|
811
747
|
});
|
|
812
748
|
}
|
|
749
|
+
|
|
750
|
+
getLogFilesForToday() {
|
|
751
|
+
return {
|
|
752
|
+
access: this.accessLog,
|
|
753
|
+
error: this.errorLog,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
813
756
|
}
|
|
814
757
|
|
|
815
758
|
NginxProvider.describe = async ({ configDir = '' } = {}) => {
|
|
@@ -846,20 +789,21 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
846
789
|
|
|
847
790
|
if (!binPath) {
|
|
848
791
|
result.available = false;
|
|
849
|
-
result.error =
|
|
792
|
+
result.error =
|
|
793
|
+
'Nginx is not detected, to have nginx installed you can checkout: https://nginx.org/en/docs/install.html.';
|
|
850
794
|
return result;
|
|
851
795
|
}
|
|
852
796
|
|
|
853
797
|
const nginxStatus = await getNginxStatus(configDir);
|
|
854
|
-
if (nginxStatus.running && !nginxStatus.
|
|
798
|
+
if (nginxStatus.running && !nginxStatus.managed) {
|
|
855
799
|
result.available = false;
|
|
856
800
|
result.error =
|
|
857
|
-
'
|
|
801
|
+
'Seems a nginx daemon already running, a controlled nginx is required by Blocklet Server to work properly, please terminate the running nginx daemon before try again.';
|
|
858
802
|
|
|
859
803
|
return result;
|
|
860
804
|
}
|
|
861
805
|
|
|
862
|
-
if (nginxStatus.
|
|
806
|
+
if (nginxStatus.managed) {
|
|
863
807
|
const pidFile = path.join(configDir, 'nginx/nginx.pid');
|
|
864
808
|
if (fs.existsSync(pidFile)) {
|
|
865
809
|
const diskPid = Number(fs.readFileSync(pidFile).toString().trim());
|
|
@@ -882,12 +826,12 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
882
826
|
);
|
|
883
827
|
fs.mkdirSync(tempConfigDirectory, { recursive: true });
|
|
884
828
|
|
|
885
|
-
const nginxProvider = new NginxProvider({
|
|
829
|
+
const nginxProvider = new NginxProvider({ configDir: tempConfigDirectory, isTest: true });
|
|
886
830
|
nginxProvider.initialize();
|
|
887
831
|
|
|
888
|
-
logger.info('check:addTestServer', {
|
|
832
|
+
logger.info('check:addTestServer', { configPath: nginxProvider.configPath });
|
|
889
833
|
await addTestServer({
|
|
890
|
-
|
|
834
|
+
configPath: nginxProvider.configPath,
|
|
891
835
|
port: await getPort(),
|
|
892
836
|
upstreamPort: await getPort(),
|
|
893
837
|
});
|
|
@@ -911,13 +855,5 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
911
855
|
|
|
912
856
|
NginxProvider.getStatus = getNginxStatus;
|
|
913
857
|
NginxProvider.exists = () => !!shelljs.which('nginx');
|
|
914
|
-
NginxProvider.getLogFilesOfCurrentDay = (routerDirectory) => {
|
|
915
|
-
const logDirectory = path.join(routerDirectory, 'log');
|
|
916
|
-
|
|
917
|
-
return {
|
|
918
|
-
access: path.join(logDirectory, 'access.log'),
|
|
919
|
-
error: path.join(logDirectory, 'error.log'),
|
|
920
|
-
};
|
|
921
|
-
};
|
|
922
858
|
|
|
923
859
|
module.exports = NginxProvider;
|