feat: add upload

This commit is contained in:
2025-05-11 19:20:51 +08:00
parent 5de857aca8
commit 98d6dfb6db
4 changed files with 286 additions and 184 deletions

View File

@@ -227,7 +227,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
res.write(msg || 'Not Found App\n');
res.end();
};
if (app === 'ai' || user === 'resources') {
if (app === 'ai' || app === 'resources') {
return aiProxy(req, res, {
createNotFoundPage,
});

View File

@@ -4,8 +4,10 @@ import { filterKeys } from './http-proxy.ts';
import { getUserFromRequest } from '@/utils/get-user.ts';
import { UserPermission, Permission } from '@kevisual/permission';
import { getLoginUser } from '@/middleware/auth.ts';
import busboy from 'busboy';
import { getContentType } from '../get-content-type.ts';
export const aiProxy = async (
const getAiProxy = async (
req: IncomingMessage,
res: ServerResponse,
opts: {
@@ -21,13 +23,13 @@ export const aiProxy = async (
let objectName = '';
let owner = '';
const { user, app } = getUserFromRequest(req);
if (user === 'ai') {
if (app === 'ai') {
const version = params.get('version') || '1.0.0'; // root/ai
objectName = pathname.replace(`/${user}/${app}/`, `${user}/${app}/${version}/`);
owner = user;
} else {
objectName = pathname.replace(`/${user}`, ``); // resources/root/
owner = app;
objectName = pathname.replace(`/${user}/${app}/`, `${user}/`); // resources/root/
owner = user;
}
try {
const stat = await minioClient.statObject(bucketName, objectName);
@@ -70,3 +72,77 @@ export const aiProxy = async (
return false;
}
};
export const getMetadata = (pathname: string) => {
let meta: any = { 'app-source': 'user-app' };
const isHtml = pathname.endsWith('.html');
if (isHtml) {
meta = {
...meta,
'Content-Type': 'text/html; charset=utf-8',
'Cache-Control': 'no-cache',
};
} else {
meta = {
...meta,
'Content-Type': getContentType(pathname),
'Cache-Control': 'max-age=31536000, immutable',
};
}
return meta;
};
export const postProxy = async (req: IncomingMessage, res: ServerResponse, opts: { createNotFoundPage: (msg?: string) => any }) => {
const _u = new URL(req.url, 'http://localhost');
const pathname = _u.pathname;
const params = _u.searchParams;
let objectName = '';
let owner = '';
const { user, app } = getUserFromRequest(req);
if (app === 'ai') {
const version = params.get('version') || '1.0.0'; // root/ai
objectName = pathname.replace(`/${user}/${app}/`, `${user}/${app}/${version}/`);
owner = user;
} else {
objectName = pathname.replace(`/${user}/${app}/`, `${user}/`); // resources/root/
owner = user;
}
const loginUser = await getLoginUser(req);
if (loginUser?.tokenUser?.username !== owner) {
return opts?.createNotFoundPage?.('no permission');
}
const bb = busboy({ headers: req.headers });
bb.on('file', async (name, file, info) => {
try {
await minioClient.putObject(bucketName, objectName, file, undefined, {
...getMetadata(pathname),
});
end({ success: true, name, info }, '上传成功', 200);
} catch (error) {
end({ error: error }, '上传失败', 500);
}
});
const end = (data: any, message?: string, code = 200) => {
res.writeHead(code, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ code: code, data: data, message: message || 'success' }));
};
bb.on('finish', end);
bb.on('error', (err) => {
console.error('Busboy 错误:', err);
end({ error: err }, '文件解析失败', 500);
});
req.pipe(bb);
};
export const aiProxy = async (
req: IncomingMessage,
res: ServerResponse,
opts: {
createNotFoundPage: (msg?: string) => any;
},
) => {
if (req.method === 'POST') {
return postProxy(req, res, opts);
}
return getAiProxy(req, res, opts);
};