asai-nodejs-host 0.1.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/AsaiHost.js +532 -0
- package/AsaiHost.ts +522 -0
- package/asai-nodejs-host/index.js +1 -0
- package/index.js +1 -0
- package/package.json +25 -0
package/AsaiHost.js
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
49
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
50
|
+
if (ar || !(i in from)) {
|
|
51
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
52
|
+
ar[i] = from[i];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
|
+
};
|
|
57
|
+
module.exports = function ($asai, opt) {
|
|
58
|
+
var _a, _b, _c;
|
|
59
|
+
var sysWork = opt.sysWork, apiWork = opt.apiWork, wsWork = opt.wsWork;
|
|
60
|
+
var fs = require("fs");
|
|
61
|
+
var path = require("path");
|
|
62
|
+
var url = require("url");
|
|
63
|
+
// 读取配置文件
|
|
64
|
+
if (!((_a = $asai.hostconfig) === null || _a === void 0 ? void 0 : _a.ip)) {
|
|
65
|
+
$asai.hostconfig.ip = getIp();
|
|
66
|
+
}
|
|
67
|
+
// 通过环境变量控制日志输出
|
|
68
|
+
// if (process.env.NODE_ENV === 'production') {
|
|
69
|
+
// console.log = () => {}; // 关闭调试日志
|
|
70
|
+
// }
|
|
71
|
+
console.log("\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B");
|
|
72
|
+
// 获取http或https的服务
|
|
73
|
+
// const http: any = require('http2');
|
|
74
|
+
var http = require("http");
|
|
75
|
+
var https = require("https");
|
|
76
|
+
// 获取当前时间
|
|
77
|
+
function getNowTime() {
|
|
78
|
+
var datanow = new Date();
|
|
79
|
+
return (datanow.getMonth() +
|
|
80
|
+
1 +
|
|
81
|
+
"-" +
|
|
82
|
+
datanow.getDate() +
|
|
83
|
+
" " +
|
|
84
|
+
datanow.getHours() +
|
|
85
|
+
":" +
|
|
86
|
+
datanow.getMinutes() +
|
|
87
|
+
":" +
|
|
88
|
+
datanow.getSeconds() +
|
|
89
|
+
"." +
|
|
90
|
+
datanow.getMilliseconds());
|
|
91
|
+
}
|
|
92
|
+
// 获取本机IP地址
|
|
93
|
+
function getIp() {
|
|
94
|
+
var ifaces = require("os").networkInterfaces();
|
|
95
|
+
for (var el in ifaces) {
|
|
96
|
+
var iface = ifaces[el];
|
|
97
|
+
if (iface && iface.length) {
|
|
98
|
+
for (var i = 0; i < iface.length; i++) {
|
|
99
|
+
var elc = iface[i];
|
|
100
|
+
if (elc.family === "IPv4" &&
|
|
101
|
+
elc.address !== "127.0.0.1" &&
|
|
102
|
+
!elc.internal) {
|
|
103
|
+
return elc.address;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return "";
|
|
109
|
+
}
|
|
110
|
+
function getHTTPServer() {
|
|
111
|
+
try {
|
|
112
|
+
if ($asai.hostconfig.httptype.includes("https")) {
|
|
113
|
+
https.AsCreateServer = function (callback) {
|
|
114
|
+
return https.createServer($asai.hostconfig.httpscert, callback);
|
|
115
|
+
};
|
|
116
|
+
return https;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
http.AsCreateServer = http.createServer;
|
|
120
|
+
return http;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.log(666.907, err);
|
|
125
|
+
http.AsCreateServer = http.createServer;
|
|
126
|
+
return http;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function getWsUserinfo(req) {
|
|
130
|
+
var _a;
|
|
131
|
+
try {
|
|
132
|
+
var headers = Object.fromEntries(Array.from({ length: req.rawHeaders.length / 2 }, function (_, i) { return [
|
|
133
|
+
req.rawHeaders[i * 2].toLowerCase(),
|
|
134
|
+
req.rawHeaders[i * 2 + 1],
|
|
135
|
+
]; }));
|
|
136
|
+
var userinfo = (_a = headers["sec-websocket-protocol"]) === null || _a === void 0 ? void 0 : _a.split("##");
|
|
137
|
+
return deUserInfo(userinfo);
|
|
138
|
+
}
|
|
139
|
+
catch (err) { }
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
// Ws请求头校验
|
|
143
|
+
function checkWsHeader(req) {
|
|
144
|
+
req.Userinfo = getWsUserinfo(req);
|
|
145
|
+
console.log(666.2001, "WS", req.Userinfo[0]);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
function getHttpUserinfo(req) {
|
|
149
|
+
var _a;
|
|
150
|
+
try {
|
|
151
|
+
var headers = Object.fromEntries(Array.from({ length: req.rawHeaders.length / 2 }, function (_, i) { return [
|
|
152
|
+
req.rawHeaders[i * 2].toLowerCase(),
|
|
153
|
+
req.rawHeaders[i * 2 + 1],
|
|
154
|
+
]; }));
|
|
155
|
+
var userinfo = (_a = headers["userinfo"]) === null || _a === void 0 ? void 0 : _a.split("##");
|
|
156
|
+
return deUserInfo(userinfo);
|
|
157
|
+
}
|
|
158
|
+
catch (err) { }
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
// tcp请求头校验
|
|
162
|
+
function checkHttpHeader(req) {
|
|
163
|
+
req.Userinfo = getHttpUserinfo(req);
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
function deUserInfo(userinfo) {
|
|
167
|
+
if (userinfo[2]) {
|
|
168
|
+
userinfo[2] = $asai.$lib.AsCode.asdecode(userinfo[2], $asai.hostconfig.asaisn);
|
|
169
|
+
userinfo[0] = $asai.$lib.AsCode.asdecode(userinfo[0], userinfo[2]);
|
|
170
|
+
userinfo[1] = $asai.$lib.AsCode.asdecode(userinfo[1], userinfo[2]);
|
|
171
|
+
}
|
|
172
|
+
return userinfo;
|
|
173
|
+
}
|
|
174
|
+
// 代理服务器
|
|
175
|
+
if ((_b = $asai.hostconfig) === null || _b === void 0 ? void 0 : _b.proxyhosts) {
|
|
176
|
+
// 循环启动配置中的服务
|
|
177
|
+
Object.keys($asai.hostconfig.proxyhosts).forEach(function (el) {
|
|
178
|
+
startProxyServer(el);
|
|
179
|
+
});
|
|
180
|
+
// 启动代理服务器
|
|
181
|
+
function startProxyServer(proxyhost) {
|
|
182
|
+
var proxycfg = $asai.hostconfig.proxyhosts[proxyhost];
|
|
183
|
+
if (!proxycfg.url && proxycfg.port) {
|
|
184
|
+
proxycfg.url =
|
|
185
|
+
$asai.hostconfig.httptype + $asai.hostconfig.ip + ":" + proxycfg.port;
|
|
186
|
+
}
|
|
187
|
+
if (proxycfg.url) {
|
|
188
|
+
var http_1 = getHTTPServer();
|
|
189
|
+
var proxyServer = http_1.AsCreateServer(function (req, res) {
|
|
190
|
+
// 启用Keep-Alive复用连接
|
|
191
|
+
var agent = new http_1.Agent({ keepAlive: true });
|
|
192
|
+
var forwardRequest = http_1.request(__assign({ agent: agent, method: req.method }, url.parse(proxycfg.url + req.url)), function (forwardRes) {
|
|
193
|
+
// 设置响应头(可以选择性地转发原始响应头)
|
|
194
|
+
Object.keys(forwardRes.headers).forEach(function (key) {
|
|
195
|
+
res.setHeader(key, forwardRes.headers[key]);
|
|
196
|
+
});
|
|
197
|
+
res.statusCode = forwardRes.statusCode;
|
|
198
|
+
console.log(666.001, getHttpUserinfo(req));
|
|
199
|
+
res.setHeader("Userinfo", getHttpUserinfo(req));
|
|
200
|
+
// 转发响应数据
|
|
201
|
+
req.pipe(forwardRequest); // 自动处理背压
|
|
202
|
+
forwardRes.pipe(res);
|
|
203
|
+
// forwardRes.pipe(res, { end: true }); // 手动数据传递
|
|
204
|
+
});
|
|
205
|
+
// 处理转发请求的错误
|
|
206
|
+
forwardRequest.on("error", function (err) {
|
|
207
|
+
console.error("Error during forward request:", err);
|
|
208
|
+
res.writeHead(502); // Bad Gateway
|
|
209
|
+
res.end("Bad Gateway");
|
|
210
|
+
});
|
|
211
|
+
// 转发请求数据
|
|
212
|
+
req.pipe(forwardRequest, { end: true });
|
|
213
|
+
// 请求超时
|
|
214
|
+
forwardRequest.setTimeout(50000, function () {
|
|
215
|
+
forwardRequest.destroy();
|
|
216
|
+
res.writeHead(504);
|
|
217
|
+
res.end("Gateway Timeout");
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
if (proxycfg.proxyip) {
|
|
221
|
+
proxyServer.listen(proxycfg.proxyport || $asai.hostconfig.proxyport, proxycfg.proxyip, function () {
|
|
222
|
+
console.log("[".concat(proxyhost, "] Start At ").concat(getNowTime(), "."));
|
|
223
|
+
console.log("\u001B[45;28mProxy Server ".concat($asai.hostconfig.httptype).concat(proxycfg.proxyip, ":").concat(proxycfg.proxyport || $asai.hostconfig.proxyport, "\u001B[0m"));
|
|
224
|
+
console.log("================================================");
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
proxyServer.listen(proxycfg.proxyport || $asai.hostconfig.proxyport, function () {
|
|
229
|
+
console.log("[".concat(proxyhost, "] Start At ").concat(getNowTime(), "."));
|
|
230
|
+
console.log("\u001B[45;28mProxy server ".concat($asai.hostconfig.httptype, "localhost:").concat(proxycfg.proxyport || $asai.hostconfig.proxyport, "\u001B[0m"));
|
|
231
|
+
console.log("================================================");
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// 网页与文件服务器
|
|
238
|
+
if ((_c = $asai.hostconfig) === null || _c === void 0 ? void 0 : _c.hosts) {
|
|
239
|
+
$asai.startHTTPServer = startHTTPServer;
|
|
240
|
+
// 循环启动配置中的服务
|
|
241
|
+
Object.keys($asai.hostconfig.hosts).forEach(function (el) {
|
|
242
|
+
startHTTPServer(el);
|
|
243
|
+
});
|
|
244
|
+
// 创建WS服务
|
|
245
|
+
function createWSHost(hostdir) {
|
|
246
|
+
try {
|
|
247
|
+
if (!$asai.serversws[hostdir]) {
|
|
248
|
+
var _a = require("ws"), WebSocket_1 = _a.WebSocket, WebSocketServer = _a.WebSocketServer;
|
|
249
|
+
var wsopt = {};
|
|
250
|
+
// ws的配置项
|
|
251
|
+
$asai.serversws[hostdir] = new WebSocketServer({
|
|
252
|
+
server: $asai.servershttp[hostdir],
|
|
253
|
+
// 附加配置信息
|
|
254
|
+
perMessageDeflate: false, // 关闭压缩减少CPU开销
|
|
255
|
+
// perMessageDeflate: {
|
|
256
|
+
// zlibDeflateOptions: {
|
|
257
|
+
// // See zlib defaults.
|
|
258
|
+
// chunkSize: 1024,
|
|
259
|
+
// memLevel: 7,
|
|
260
|
+
// level: 3,
|
|
261
|
+
// },
|
|
262
|
+
// zlibInflateOptions: {
|
|
263
|
+
// chunkSize: 10 * 1024,
|
|
264
|
+
// },
|
|
265
|
+
// // Other options settable:
|
|
266
|
+
// clientNoContextTakeover: true, // Defaults to negotiated value.
|
|
267
|
+
// serverNoContextTakeover: true, // Defaults to negotiated value.
|
|
268
|
+
// serverMaxWindowBits: 10, // Defaults to negotiated value.
|
|
269
|
+
// // Below options specified as default values.
|
|
270
|
+
// concurrencyLimit: 10, // Limits zlib concurrency for perf.
|
|
271
|
+
// threshold: 1024, // Size (in bytes) below which messages
|
|
272
|
+
// // should not be compressed if context takeover is disabled.
|
|
273
|
+
// },
|
|
274
|
+
});
|
|
275
|
+
// 服务器ws服务关闭操作,清空定时器
|
|
276
|
+
function wsServerClose() {
|
|
277
|
+
if ($asai.tasksws[hostdir] &&
|
|
278
|
+
typeof $asai.tasksws[hostdir] === "object") {
|
|
279
|
+
Object.values($asai.tasksws[hostdir]).forEach(function (el) {
|
|
280
|
+
el && clearInterval(el);
|
|
281
|
+
});
|
|
282
|
+
$asai.tasksws[hostdir] = {};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// 服务端异常错误关闭
|
|
286
|
+
$asai.serversws[hostdir].on("error", function () {
|
|
287
|
+
wsServerClose();
|
|
288
|
+
$asai.hostconfig.log && console.log(666.303, "WS Server error!");
|
|
289
|
+
});
|
|
290
|
+
// 服务端异常关闭
|
|
291
|
+
$asai.serversws[hostdir].on("close", function () {
|
|
292
|
+
wsServerClose();
|
|
293
|
+
$asai.hostconfig.log && console.log(666.301, "WS Server close!");
|
|
294
|
+
});
|
|
295
|
+
if ($asai.hostconfig.status.connectionsws) {
|
|
296
|
+
// 初始化记录ws服务连接
|
|
297
|
+
if (!$asai.connectionsws[hostdir]) {
|
|
298
|
+
$asai.connectionsws[hostdir] = new WeakMap();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// 服务被连接后...
|
|
302
|
+
$asai.serversws[hostdir].on("connection", function (ws, req) {
|
|
303
|
+
if (!$asai.tasksws[hostdir]) {
|
|
304
|
+
$asai.tasksws[hostdir] = {};
|
|
305
|
+
}
|
|
306
|
+
if (!(ws === null || ws === void 0 ? void 0 : ws.tasksws)) {
|
|
307
|
+
ws.tasksws = {};
|
|
308
|
+
}
|
|
309
|
+
if (checkWsHeader(req)) {
|
|
310
|
+
$asai.hostconfig.log &&
|
|
311
|
+
console.log(666.2002, req.Userinfo, "wsClient connection!");
|
|
312
|
+
function closeWs() {
|
|
313
|
+
ws.close();
|
|
314
|
+
}
|
|
315
|
+
if ($asai.hostconfig.status.connectionsws &&
|
|
316
|
+
(!req.Userinfo[0] ||
|
|
317
|
+
!req.Userinfo[2] ||
|
|
318
|
+
$asai.connectionsws[hostdir][req.Userinfo[0]])) {
|
|
319
|
+
// 连接用户信息不符合条件,已存在同账户的登录
|
|
320
|
+
closeWs();
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
$asai.hostconfig.log && console.log(666.2006, "ok!");
|
|
324
|
+
// 正常登录
|
|
325
|
+
var _a = req.Userinfo || [], us = _a[0], lv = _a[1], tk = _a[2];
|
|
326
|
+
ws.Userinfo = { us: us, lv: lv, tk: tk }; // 赋值给ws
|
|
327
|
+
if ($asai.hostconfig.status.connectionsws) {
|
|
328
|
+
$asai.connectionsws[hostdir][req.Userinfo[0]] = ws;
|
|
329
|
+
}
|
|
330
|
+
// 发送消息
|
|
331
|
+
$asai.serversws[hostdir].sendws = function (msg, type, curws) {
|
|
332
|
+
if (type) {
|
|
333
|
+
// 广播消息
|
|
334
|
+
// wsopt.ulen = 0;
|
|
335
|
+
$asai.serversws[hostdir].clients.forEach(function (client) {
|
|
336
|
+
// wsopt.ulen++;
|
|
337
|
+
if ((type == 2 || client !== curws) &&
|
|
338
|
+
client.readyState == WebSocket_1.OPEN) {
|
|
339
|
+
client.send(msg);
|
|
340
|
+
}
|
|
341
|
+
console.info(666.801, client.Userinfo);
|
|
342
|
+
});
|
|
343
|
+
// $asai.hostconfig.log &&
|
|
344
|
+
// console.log(666.808, "wsClient Public!", wsopt.ulen);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
// api方式回复消息
|
|
348
|
+
curws.send(msg);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
//监听客户端发来的消息
|
|
352
|
+
ws.on("message", function (msg) {
|
|
353
|
+
wsWork(msg, ws, hostdir, req);
|
|
354
|
+
});
|
|
355
|
+
// 客户端关闭
|
|
356
|
+
ws.on("close", function (err) {
|
|
357
|
+
$asai.hostconfig.log &&
|
|
358
|
+
console.log(666.103, req.Userinfo[0] + " wsClient close!", err);
|
|
359
|
+
if ($asai.hostconfig.status.connectionsws) {
|
|
360
|
+
// 关闭点对点客户端的任务
|
|
361
|
+
if (ws.tasksws && typeof ws.tasksws === "object") {
|
|
362
|
+
Object.values(ws.tasksws).forEach(function (el) {
|
|
363
|
+
el && clearInterval(el);
|
|
364
|
+
});
|
|
365
|
+
ws.tasksws = null;
|
|
366
|
+
}
|
|
367
|
+
if (req.Userinfo[0] &&
|
|
368
|
+
$asai.connectionsws[hostdir][req.Userinfo[0]]) {
|
|
369
|
+
delete $asai.connectionsws[hostdir][req.Userinfo[0]];
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
catch (err) { }
|
|
379
|
+
return $asai.serversws[hostdir];
|
|
380
|
+
}
|
|
381
|
+
// 请求的文件相对路径
|
|
382
|
+
function getFilePath(hostdir, requrl) {
|
|
383
|
+
var filePath = "" + requrl;
|
|
384
|
+
if (filePath == "/" || filePath == "") {
|
|
385
|
+
filePath = "/index.html";
|
|
386
|
+
}
|
|
387
|
+
if (hostdir == "home") {
|
|
388
|
+
filePath = "." + filePath;
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
filePath = "./" + hostdir + filePath;
|
|
392
|
+
}
|
|
393
|
+
return filePath;
|
|
394
|
+
}
|
|
395
|
+
// 读取服务器上文件
|
|
396
|
+
function fsReadFile(hostdirs, requrl) {
|
|
397
|
+
var _this = this;
|
|
398
|
+
return new Promise(function (resolve, reject) {
|
|
399
|
+
// 尝试顺序读取多个路径
|
|
400
|
+
var tryRead = function () {
|
|
401
|
+
var args_1 = [];
|
|
402
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
403
|
+
args_1[_i] = arguments[_i];
|
|
404
|
+
}
|
|
405
|
+
return __awaiter(_this, __spreadArray([], args_1, true), void 0, function (index) {
|
|
406
|
+
var filePath;
|
|
407
|
+
if (index === void 0) { index = 0; }
|
|
408
|
+
return __generator(this, function (_a) {
|
|
409
|
+
if (index >= hostdirs.length)
|
|
410
|
+
return [2 /*return*/, reject(404)];
|
|
411
|
+
filePath = getFilePath(hostdirs[index], requrl);
|
|
412
|
+
fs.readFile(filePath, function (err, data) {
|
|
413
|
+
if (err)
|
|
414
|
+
tryRead(index + 1);
|
|
415
|
+
else
|
|
416
|
+
resolve({ resdata: data, filepath: filePath });
|
|
417
|
+
});
|
|
418
|
+
return [2 /*return*/];
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
tryRead();
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
// 启动HTTP服务
|
|
426
|
+
function startHTTPServer(hostdir) {
|
|
427
|
+
// 初始化服务配置
|
|
428
|
+
var hostcfg = $asai.hostconfig.hosts[hostdir];
|
|
429
|
+
try {
|
|
430
|
+
if (!$asai.servershttp[hostdir]) {
|
|
431
|
+
if (hostcfg.mimetypes) {
|
|
432
|
+
Object.assign(hostcfg.mimetypes, $asai.hostconfig.mimetypes);
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
hostcfg.mimetypes = $asai.hostconfig.mimetypes;
|
|
436
|
+
}
|
|
437
|
+
// 创建服务
|
|
438
|
+
var http_2 = getHTTPServer();
|
|
439
|
+
$asai.servershttp[hostdir] = http_2.AsCreateServer(function (req, res) {
|
|
440
|
+
if (checkHttpHeader(req)) {
|
|
441
|
+
if (req.url.startsWith("/sys")) {
|
|
442
|
+
sysWork(req, res, hostdir);
|
|
443
|
+
}
|
|
444
|
+
else if (req.url.startsWith("/api")) {
|
|
445
|
+
apiWork(req, res, hostdir);
|
|
446
|
+
}
|
|
447
|
+
else if (hostcfg.hostdirs) {
|
|
448
|
+
fsReadFile(hostcfg.hostdirs, req.url)
|
|
449
|
+
.then(function (resfile) {
|
|
450
|
+
res.writeHead(200, {
|
|
451
|
+
"Content-Encoding": "gzip",
|
|
452
|
+
"Content-Type": hostcfg.mimetypes[path.extname(resfile.filepath)] ||
|
|
453
|
+
"application/octet-stream",
|
|
454
|
+
"Cache-Control": "public, max-age=3600", // 客户端缓存1小时
|
|
455
|
+
});
|
|
456
|
+
// 提前处理压缩数据为.gz
|
|
457
|
+
fs.createReadStream("file.gz").pipe(res);
|
|
458
|
+
res.end(resfile.resdata);
|
|
459
|
+
})
|
|
460
|
+
.catch(function (err) {
|
|
461
|
+
if (err === 404) {
|
|
462
|
+
res.writeHead(404, {
|
|
463
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
464
|
+
});
|
|
465
|
+
res.end("File not found!");
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
res.writeHead(500, {
|
|
469
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
470
|
+
});
|
|
471
|
+
res.end("".concat(err, " error!"));
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
res.writeHead(404, {
|
|
477
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
478
|
+
});
|
|
479
|
+
res.end("404");
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
res.writeHead(502, {
|
|
484
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
485
|
+
});
|
|
486
|
+
res.end("502");
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
hostcfg.ws && createWSHost(hostdir); // 创建ws服务
|
|
490
|
+
// 启动服务
|
|
491
|
+
if (hostcfg.ip || $asai.hostconfig.ip) {
|
|
492
|
+
$asai.servershttp[hostdir].listen(hostcfg.port, hostcfg.ip || $asai.hostconfig.ip, function () {
|
|
493
|
+
console.log("[".concat(hostdir, "] Start At ").concat(getNowTime(), "."));
|
|
494
|
+
hostcfg.ws &&
|
|
495
|
+
console.log("\u001B[44;28mWS Server ".concat($asai.hostconfig.wstype +
|
|
496
|
+
(hostcfg.ip || $asai.hostconfig.ip), ":").concat(hostcfg.port, "\u001B[0m"));
|
|
497
|
+
console.log("\u001B[42;28mHTTP Server ".concat($asai.hostconfig.httptype +
|
|
498
|
+
(hostcfg.ip || $asai.hostconfig.ip), ":").concat(hostcfg.port, "\u001B[0m"));
|
|
499
|
+
console.log("================================================");
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
$asai.servershttp[hostdir].listen(hostcfg.port, function () {
|
|
504
|
+
console.log("[".concat(hostdir, "] Start At ").concat(getNowTime(), "."));
|
|
505
|
+
hostcfg.ws &&
|
|
506
|
+
console.log("\u001B[41;28mWS Server".concat($asai.hostconfig.wstype, "localhost:").concat(hostcfg.port, "\u001B[0m"));
|
|
507
|
+
console.log("\u001B[42;28mHTTP Server ".concat($asai.hostconfig.httptype, "localhost:").concat(hostcfg.port, "\u001B[0m"));
|
|
508
|
+
console.log("================================================");
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
catch (err) {
|
|
514
|
+
console.log(666.303, err);
|
|
515
|
+
}
|
|
516
|
+
if ($asai.hostconfig.status.connectionshttp) {
|
|
517
|
+
// 记录http服务连接(先删除连接用户,再操作node服务,成功几率更大,但记录用户会造成变量变大)
|
|
518
|
+
$asai.servershttp[hostdir].on("connection", function (connection) {
|
|
519
|
+
if (!$asai.connectionshttp[hostdir]) {
|
|
520
|
+
$asai.connectionshttp[hostdir] = new Set();
|
|
521
|
+
}
|
|
522
|
+
$asai.connectionshttp[hostdir].add(connection);
|
|
523
|
+
// 处理关闭服务
|
|
524
|
+
connection.on("close", function () {
|
|
525
|
+
$asai.connectionshttp[hostdir].delete(connection);
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
return $asai.servershttp[hostdir];
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
};
|