mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
133 lines
4.0 KiB
TypeScript
133 lines
4.0 KiB
TypeScript
import express, { Express, Request, Response } from 'express';
|
||
import cors from 'cors';
|
||
import http from 'http';
|
||
import { log, logDebug, logError } from '../utils/log';
|
||
import { ob11Config } from '@/onebot11/config';
|
||
|
||
type RegisterHandler = (res: Response, payload: any) => Promise<any>
|
||
|
||
export abstract class HttpServerBase {
|
||
name: string = 'NapCatQQ';
|
||
private readonly expressAPP: Express;
|
||
private _server: http.Server | null = null;
|
||
|
||
public get server(): http.Server | null {
|
||
return this._server;
|
||
}
|
||
|
||
private set server(value: http.Server | null) {
|
||
this._server = value;
|
||
}
|
||
|
||
constructor() {
|
||
this.expressAPP = express();
|
||
this.expressAPP.use(cors());
|
||
this.expressAPP.use(express.urlencoded({ extended: true, limit: '5000mb' }));
|
||
this.expressAPP.use((req, res, next) => {
|
||
// 兼容处理没有带content-type的请求
|
||
// log("req.headers['content-type']", req.headers['content-type'])
|
||
req.headers['content-type'] = 'application/json';
|
||
const originalJson = express.json({ limit: '5000mb' });
|
||
// 调用原始的express.json()处理器
|
||
originalJson(req, res, (err) => {
|
||
if (err) {
|
||
logError('Error parsing JSON:', err);
|
||
return res.status(400).send('Invalid JSON');
|
||
}
|
||
next();
|
||
});
|
||
});
|
||
}
|
||
|
||
authorize(req: Request, res: Response, next: () => void) {
|
||
const serverToken = ob11Config.token;
|
||
let clientToken = '';
|
||
const authHeader = req.get('authorization');
|
||
if (authHeader) {
|
||
clientToken = authHeader.split('Bearer ').pop() || '';
|
||
//logDebug('receive http header token', clientToken);
|
||
} else if (req.query.access_token) {
|
||
if (Array.isArray(req.query.access_token)) {
|
||
clientToken = req.query.access_token[0].toString();
|
||
} else {
|
||
clientToken = req.query.access_token.toString();
|
||
}
|
||
//logDebug('receive http url token', clientToken);
|
||
}
|
||
|
||
if (serverToken && clientToken != serverToken) {
|
||
return res.status(403).send(JSON.stringify({ message: 'token verify failed!' }));
|
||
}
|
||
next();
|
||
}
|
||
|
||
start(port: number, host: string) {
|
||
try {
|
||
this.expressAPP.get('/', (req: Request, res: Response) => {
|
||
res.send(`${this.name}已启动`);
|
||
});
|
||
this.listen(port, host);
|
||
} catch (e: any) {
|
||
logError('HTTP服务启动失败', e.toString());
|
||
// httpServerError = "HTTP服务启动失败, " + e.toString()
|
||
}
|
||
}
|
||
|
||
stop() {
|
||
// httpServerError = ""
|
||
if (this.server) {
|
||
this.server.close();
|
||
this.server = null;
|
||
}
|
||
}
|
||
|
||
restart(port: number, host: string) {
|
||
this.stop();
|
||
this.start(port, host);
|
||
}
|
||
|
||
abstract handleFailed(res: Response, payload: any, err: Error): void
|
||
|
||
registerRouter(method: 'post' | 'get' | string, url: string, handler: RegisterHandler) {
|
||
if (!url.startsWith('/')) {
|
||
url = '/' + url;
|
||
}
|
||
|
||
// @ts-expect-error wait fix
|
||
if (!this.expressAPP[method]) {
|
||
const err = `${this.name} register router failed,${method} not exist`;
|
||
logError(err);
|
||
throw err;
|
||
}
|
||
// @ts-expect-error wait fix
|
||
this.expressAPP[method](url, this.authorize, async (req: Request, res: Response) => {
|
||
let payload = req.body;
|
||
if (method == 'get') {
|
||
payload = req.query;
|
||
} else if (req.query) {
|
||
payload = { ...req.query, ...req.body };
|
||
}
|
||
logDebug('收到http请求', url, payload);
|
||
try {
|
||
res.send(await handler(res, payload));
|
||
} catch (e: any) {
|
||
this.handleFailed(res, payload, e);
|
||
}
|
||
});
|
||
}
|
||
|
||
protected listen(port: number, host: string = '0.0.0.0') {
|
||
host = host || '0.0.0.0';
|
||
try {
|
||
this.server = this.expressAPP.listen(port, host, () => {
|
||
const info = `${this.name} started ${host}:${port}`;
|
||
log(info);
|
||
}).on('error', (err) => {
|
||
logError('HTTP服务启动失败', err.toString());
|
||
});
|
||
} catch (e: any) {
|
||
logError('HTTP服务启动失败, 请检查监听的ip地址和端口', e.stack.toString());
|
||
}
|
||
}
|
||
}
|