mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-01 16:20:25 +00:00
Add streaming file upload and download actions
Introduces new OneBot actions for streaming file upload and download, including chunked file transfer with memory/disk management and SHA256 verification. Adds CleanStreamTempFile, DownloadFileStream, UploadFileStream, and TestStreamDownload actions, updates action routing and network adapters to support streaming via HTTP and WebSocket, and provides Python test scripts for concurrent upload testing.
This commit is contained in:
@@ -9,7 +9,7 @@ export class OB11HttpSSEServerAdapter extends OB11HttpServerAdapter {
|
||||
if (req.path === '/_events') {
|
||||
this.createSseSupport(req, res);
|
||||
} else {
|
||||
super.httpApiRequest(req, res);
|
||||
super.httpApiRequest(req, res, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
|
||||
}
|
||||
}
|
||||
|
||||
async httpApiRequest(req: Request, res: Response) {
|
||||
async httpApiRequest(req: Request, res: Response, request_sse: boolean = false) {
|
||||
let payload = req.body;
|
||||
if (req.method == 'get') {
|
||||
payload = req.query;
|
||||
@@ -117,17 +117,31 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
|
||||
return res.json(hello);
|
||||
}
|
||||
const actionName = req.path.split('/')[1];
|
||||
const payload_echo = payload['echo'];
|
||||
const real_echo = payload_echo ?? Math.random().toString(36).substring(2, 15);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const action = this.actions.get(actionName as any);
|
||||
if (action) {
|
||||
try {
|
||||
const result = await action.handle(payload, this.name, this.config);
|
||||
let stream = false;
|
||||
const result = await action.handle(payload, this.name, this.config, {
|
||||
send: request_sse ? async (data: object) => {
|
||||
this.onEvent({ ...OB11Response.ok(data, real_echo), type: 'sse-action' } as unknown as OB11EmitEventContent);
|
||||
} : async (data: object) => {
|
||||
stream = true;
|
||||
res.write(JSON.stringify({ ...OB11Response.ok(data, real_echo), type: 'stream-action' }) + "\r\n\r\n");
|
||||
}
|
||||
}, real_echo);
|
||||
if (stream) {
|
||||
res.write(JSON.stringify({ ...result, type: 'stream-action' }) + "\r\n\r\n");
|
||||
return res.end();
|
||||
};
|
||||
return res.json(result);
|
||||
} catch (error: unknown) {
|
||||
return res.json(OB11Response.error((error as Error)?.stack?.toString() || (error as Error)?.message || 'Error Handle', 200));
|
||||
return res.json(OB11Response.error((error as Error)?.stack?.toString() || (error as Error)?.message || 'Error Handle', 200, real_echo));
|
||||
}
|
||||
} else {
|
||||
return res.json(OB11Response.error('不支持的Api ' + actionName, 200));
|
||||
return res.json(OB11Response.error('不支持的Api ' + actionName, 200, real_echo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,11 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketCli
|
||||
this.checkStateAndReply<unknown>(OB11Response.error('不支持的Api ' + receiveData.action, 1404, echo));
|
||||
return;
|
||||
}
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name, this.config);
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name, this.config, {
|
||||
send: async (data: object) => {
|
||||
this.checkStateAndReply<unknown>({ ...OB11Response.ok(data, echo ?? '') });
|
||||
}
|
||||
});
|
||||
this.checkStateAndReply<unknown>({ ...retdata });
|
||||
}
|
||||
async reload(newConfig: WebsocketClientConfig) {
|
||||
|
||||
@@ -186,7 +186,11 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
|
||||
this.checkStateAndReply<unknown>(OB11Response.error('不支持的API ' + receiveData.action, 1404, echo), wsClient);
|
||||
return;
|
||||
}
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name, this.config);
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name, this.config, {
|
||||
send: async (data: object) => {
|
||||
this.checkStateAndReply<unknown>({ ...OB11Response.ok(data, echo ?? '') }, wsClient);
|
||||
}
|
||||
});
|
||||
this.checkStateAndReply<unknown>({ ...retdata }, wsClient);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user