jsir 2.4.8 → 2.5.0
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/cmd/oaa.js +3 -1
- package/deps/room.js +21 -10
- package/deps/server.js +53 -46
- package/deps/util.js +15 -4
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -1470,13 +1470,15 @@ const keywordDef = {
|
|
|
1470
1470
|
log: {
|
|
1471
1471
|
comment: 'View log (type[[lt][le]], index)',
|
|
1472
1472
|
exeFn: async (args) => {
|
|
1473
|
-
let path = `${getLibDataDir()}/log/
|
|
1473
|
+
let path = `${getLibDataDir()}/log/room`
|
|
1474
1474
|
let type = '';
|
|
1475
1475
|
for (let arg of args) {
|
|
1476
1476
|
if (_cmdMap[arg]) {
|
|
1477
1477
|
let pair = parseUniqueName(_cmdMap[arg])
|
|
1478
1478
|
let fileName = pair[0] + '/' + pair[1].split(".")[0]
|
|
1479
1479
|
path = `${getLibDataDir()}/log/${fileName}`
|
|
1480
|
+
} else if (arg === '0') {
|
|
1481
|
+
path = `${getLibDataDir()}/log/jsir`
|
|
1480
1482
|
} else {
|
|
1481
1483
|
type = arg;
|
|
1482
1484
|
}
|
package/deps/room.js
CHANGED
|
@@ -118,19 +118,26 @@ function getSelfIP(nodes) {
|
|
|
118
118
|
|
|
119
119
|
async function getTailscaleNodes() {
|
|
120
120
|
let resp = await e(`${tailscalePath} status`);
|
|
121
|
-
let nodes =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
let nodes = {}
|
|
122
|
+
for (let line of resp.split("\n").map(trim)) {
|
|
123
|
+
if (line.indexOf('offline') !== -1) {
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
let ss = line.split(/\s+/);
|
|
127
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(ss[0])) {
|
|
128
|
+
nodes[ss[0]] = ss[1]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return nodes;
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
async function updateRoomInfo() {
|
|
129
|
-
let
|
|
135
|
+
let nodeMap = await getTailscaleNodes();
|
|
136
|
+
let nodes = Object.keys(nodeMap)
|
|
130
137
|
let ip = getSelfIP(nodes)
|
|
131
138
|
await fileJson(roomDataFile, async room => {
|
|
132
139
|
// 设置roomName
|
|
133
|
-
let name = os.hostname();
|
|
140
|
+
let name = nodeMap[ip] || os.hostname();
|
|
134
141
|
if (!vl(room.name) || room.name !== name) {
|
|
135
142
|
room.name = name;
|
|
136
143
|
debug("set roomName", name)
|
|
@@ -239,9 +246,9 @@ async function _syncSetting(room) {
|
|
|
239
246
|
setting.services = {}
|
|
240
247
|
setting.serviceFns = {}
|
|
241
248
|
for (const room of setting.rooms) {
|
|
242
|
-
for (const pid of Object.keys(room.jsirs ||
|
|
249
|
+
for (const pid of Object.keys(room.jsirs || {})) {
|
|
243
250
|
let jsir = room.jsirs[pid];
|
|
244
|
-
for (const service of Object.keys(jsir.services ||
|
|
251
|
+
for (const service of Object.keys(jsir.services || {})) {
|
|
245
252
|
let serviceFns = jsir.services[service] || [];
|
|
246
253
|
|
|
247
254
|
let existFns = setting.services[service] || [];
|
|
@@ -358,6 +365,10 @@ async function initRoomJsir(room) {
|
|
|
358
365
|
getOr(services, ss[1], []).push(ss[2])
|
|
359
366
|
}
|
|
360
367
|
}
|
|
368
|
+
// 去重
|
|
369
|
+
for (let key of Object.keys(services)) {
|
|
370
|
+
services[key] = [...new Set(services[key])]
|
|
371
|
+
}
|
|
361
372
|
// 初始化jsir
|
|
362
373
|
let lastJsir = room.jsirs[process.pid]
|
|
363
374
|
room.jsirs[process.pid] = {
|
|
@@ -483,7 +494,7 @@ async function reqNode(node, method, url, port, body) {
|
|
|
483
494
|
}
|
|
484
495
|
});
|
|
485
496
|
} finally {
|
|
486
|
-
debug(`
|
|
497
|
+
debug(`Request cost ${Date.now() - time}ms`, JSON.stringify(opt))
|
|
487
498
|
}
|
|
488
499
|
}
|
|
489
500
|
|
package/deps/server.js
CHANGED
|
@@ -33,6 +33,54 @@ function createSign() {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
async function process(routeKey, req, res, params) {
|
|
37
|
+
if (routes[routeKey]) {
|
|
38
|
+
if (!apiReg.test(routeKey)) {
|
|
39
|
+
// 如果不是api接口,则校验签名
|
|
40
|
+
// 取header里的sign字段
|
|
41
|
+
const sign = req.headers['sign'];
|
|
42
|
+
if (sign) {
|
|
43
|
+
const decodedTime = verifySign(sign);
|
|
44
|
+
const currentTime = Date.now();
|
|
45
|
+
|
|
46
|
+
if (decodedTime === null || Math.abs(currentTime - decodedTime) > setting.serverSignExpire) {
|
|
47
|
+
res.writeHead(403, {'Content-Type': 'text/plain'});
|
|
48
|
+
res.end('Forbidden: Invalid Sign');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
// 如果没有sign字段,返回403
|
|
53
|
+
res.writeHead(403, {'Content-Type': 'text/plain'});
|
|
54
|
+
res.end('Forbidden: Missing Sign');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 如果签名通过,继续处理请求
|
|
59
|
+
try {
|
|
60
|
+
let body = '';
|
|
61
|
+
await new Promise((resolve, reject) => {
|
|
62
|
+
// 监听请求数据
|
|
63
|
+
req.on('data', chunk => {
|
|
64
|
+
body += chunk;
|
|
65
|
+
});
|
|
66
|
+
req.on('error', (err) => {
|
|
67
|
+
reject(err)
|
|
68
|
+
});
|
|
69
|
+
req.on('end', async () => {
|
|
70
|
+
resolve()
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
await routes[routeKey](body || params, res);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
res.writeHead(500, {'Content-Type': 'text/plain'});
|
|
76
|
+
res.end(String(isError(e) ? e.message : e));
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
res.writeHead(404, {'Content-Type': 'text/plain'});
|
|
80
|
+
res.end('Not Found');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
36
84
|
// 创建一个 HTTP 服务
|
|
37
85
|
async function createServer(port) {
|
|
38
86
|
const server = http.createServer(async (req, res) => {
|
|
@@ -51,52 +99,11 @@ async function createServer(port) {
|
|
|
51
99
|
const clientIp = req.socket.remoteAddress || req.connection.remoteAddress;
|
|
52
100
|
// 查找对应的路由处理函数
|
|
53
101
|
const routeKey = `${method} ${url}`;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// 取header里的sign字段
|
|
60
|
-
const sign = req.headers['sign'];
|
|
61
|
-
if (sign) {
|
|
62
|
-
const decodedTime = verifySign(sign);
|
|
63
|
-
const currentTime = Date.now();
|
|
64
|
-
|
|
65
|
-
if (decodedTime === null || Math.abs(currentTime - decodedTime) > setting.serverSignExpire) {
|
|
66
|
-
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
67
|
-
res.end('Forbidden: Invalid Sign');
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
} else {
|
|
71
|
-
// 如果没有sign字段,返回403
|
|
72
|
-
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
73
|
-
res.end('Forbidden: Missing Sign');
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// 如果签名通过,继续处理请求
|
|
78
|
-
try {
|
|
79
|
-
let body = '';
|
|
80
|
-
await new Promise((resolve, reject) => {
|
|
81
|
-
// 监听请求数据
|
|
82
|
-
req.on('data', chunk => {
|
|
83
|
-
body += chunk;
|
|
84
|
-
});
|
|
85
|
-
req.on('error', (err) => {
|
|
86
|
-
reject(err)
|
|
87
|
-
});
|
|
88
|
-
req.on('end', async () => {
|
|
89
|
-
resolve()
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
await routes[routeKey](body || params, res);
|
|
93
|
-
} catch (e) {
|
|
94
|
-
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
95
|
-
res.end(String(isError(e) ? e.message:e));
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
99
|
-
res.end('Not Found');
|
|
102
|
+
let time = Date.now();
|
|
103
|
+
try {
|
|
104
|
+
await process(routeKey, req, res, params);
|
|
105
|
+
} finally {
|
|
106
|
+
debug(`Process cost ${Date.now() - time}ms for ${routeKey} from ${clientIp}`);
|
|
100
107
|
}
|
|
101
108
|
});
|
|
102
109
|
|
package/deps/util.js
CHANGED
|
@@ -96,13 +96,23 @@ function syncQueue(task, key) {
|
|
|
96
96
|
return queue.enqueue(task)
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
const
|
|
99
|
+
const roomLog = createLimitLogger(`room.log`, {
|
|
100
100
|
logInfo: false
|
|
101
101
|
});
|
|
102
|
+
const roomError = createLimitLogger(`room.error`, {
|
|
103
|
+
logInfo: false,
|
|
104
|
+
error: true,
|
|
105
|
+
syncLogs: [roomLog]
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const $log = createLimitLogger(`${setting.name}.log`, {
|
|
109
|
+
logInfo: false,
|
|
110
|
+
syncLogs: [roomLog]
|
|
111
|
+
});
|
|
102
112
|
const $error = createLimitLogger(`${setting.name}.error`, {
|
|
103
113
|
logInfo: false,
|
|
104
114
|
error: true,
|
|
105
|
-
syncLogs: [$log]
|
|
115
|
+
syncLogs: [$log, roomError]
|
|
106
116
|
});
|
|
107
117
|
let _globalDraft= createLimitLogger(`draft.log`, {
|
|
108
118
|
logInfo: false,
|
|
@@ -236,12 +246,13 @@ function createConsole(uniqueName) {
|
|
|
236
246
|
let pair = parseUniqueName(uniqueName)
|
|
237
247
|
let fileName = pair[0] + '/' + pair[1].split(".")[0]
|
|
238
248
|
result.$log = createLimitLogger(fileName + '.log', {
|
|
239
|
-
logInfo: false
|
|
249
|
+
logInfo: false,
|
|
250
|
+
syncLogs: [roomLog]
|
|
240
251
|
});
|
|
241
252
|
result.$error = createLimitLogger(fileName + '.error', {
|
|
242
253
|
logInfo: false,
|
|
243
254
|
error: true,
|
|
244
|
-
syncLogs: [result.$log]
|
|
255
|
+
syncLogs: [result.$log, roomError]
|
|
245
256
|
});
|
|
246
257
|
}
|
|
247
258
|
let quite = false
|