diff --git a/src/modules/fm-manager/proxy/ai-proxy-chunk/post-proxy.ts b/src/modules/fm-manager/proxy/ai-proxy-chunk/post-proxy.ts new file mode 100644 index 0000000..22b3adb --- /dev/null +++ b/src/modules/fm-manager/proxy/ai-proxy-chunk/post-proxy.ts @@ -0,0 +1,89 @@ + +import { IncomingMessage, ServerResponse } from 'http'; +import busboy from 'busboy'; +import { parseSearchValue } from '@kevisual/router/src/server/parse-body.ts'; +import { pipeBusboy } from '../../pipe-busboy.ts'; +import { ProxyOptions, getMetadata, getObjectName } from '../ai-proxy.ts'; +export const postProxy = async (req: IncomingMessage, res: ServerResponse, opts: ProxyOptions) => { + const _u = new URL(req.url, 'http://localhost'); + + const pathname = _u.pathname; + const oss = opts.oss; + const params = _u.searchParams; + const force = !!params.get('force'); + const hash = params.get('hash'); + const _fileSize: string = params.get('size'); + let fileSize: number | undefined = undefined; + if (_fileSize) { + fileSize = parseInt(_fileSize, 10); + } + console.log('postProxy', { hash, force, fileSize }); + let meta = parseSearchValue(params.get('meta'), { decode: true }); + if (!hash && !force) { + return opts?.createNotFoundPage?.('no hash'); + } + const { objectName, isOwner } = await getObjectName(req); + if (!isOwner) { + return opts?.createNotFoundPage?.('no permission'); + } + 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' })); + }; + let statMeta: any = {}; + if (!force) { + const check = await oss.checkObjectHash(objectName, hash, meta); + statMeta = check?.metaData || {}; + let isNewMeta = false; + if (check.success && JSON.stringify(meta) !== '{}' && !check.equalMeta) { + meta = { ...statMeta, ...getMetadata(pathname), ...meta }; + isNewMeta = true; + await oss.replaceObject(objectName, { ...meta }); + } + if (check.success) { + return end({ success: true, hash, meta, isNewMeta, equalMeta: check.equalMeta }, '文件已存在'); + } + } + const bb = busboy({ + headers: req.headers, + limits: { + fileSize: 100 * 1024 * 1024, // 100MB + files: 1, + }, + defCharset: 'utf-8', + }); + let fileProcessed = false; + bb.on('file', async (name, file, info) => { + fileProcessed = true; + try { + await oss.putObject( + objectName, + file, + { + ...statMeta, + ...getMetadata(pathname), + ...meta, + }, + { check: false, isStream: true }, + ); + end({ success: true, name, info, isNew: true, hash, meta: meta?.metaData, statMeta }, '上传成功', 200); + + } catch (error) { + console.log('postProxy upload error', error); + end({ error: error }, '上传失败', 500); + } + }); + + bb.on('finish', () => { + // 只有当没有文件被处理时才执行end + if (!fileProcessed) { + end({ success: false }, '没有接收到文件', 400); + } + }); + bb.on('error', (err) => { + console.error('Busboy 错误:', err); + end({ error: err }, '文件解析失败', 500); + }); + + pipeBusboy(req, res, bb); +}; \ No newline at end of file diff --git a/src/modules/fm-manager/proxy/ai-proxy.ts b/src/modules/fm-manager/proxy/ai-proxy.ts index 4290a9c..ce28c37 100644 --- a/src/modules/fm-manager/proxy/ai-proxy.ts +++ b/src/modules/fm-manager/proxy/ai-proxy.ts @@ -12,7 +12,7 @@ import { logger } from '@/modules/logger.ts'; import { pipeBusboy } from '../pipe-busboy.ts'; import { pipeMinioStream } from '../pipe.ts'; import { Readable } from 'stream'; - +import { postProxy } from './ai-proxy-chunk/post-proxy.ts' type FileList = { name: string; prefix?: string; @@ -153,88 +153,6 @@ export const getMetadata = (pathname: string) => { return meta; }; -export const postProxy = async (req: IncomingMessage, res: ServerResponse, opts: ProxyOptions) => { - const _u = new URL(req.url, 'http://localhost'); - - const pathname = _u.pathname; - const oss = opts.oss; - const params = _u.searchParams; - const force = !!params.get('force'); - const hash = params.get('hash'); - const _fileSize: string = params.get('size'); - let fileSize: number | undefined = undefined; - if (_fileSize) { - fileSize = parseInt(_fileSize, 10); - } - let meta = parseSearchValue(params.get('meta'), { decode: true }); - if (!hash && !force) { - return opts?.createNotFoundPage?.('no hash'); - } - const { objectName, isOwner } = await getObjectName(req); - if (!isOwner) { - return opts?.createNotFoundPage?.('no permission'); - } - 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' })); - }; - let statMeta: any = {}; - if (!force) { - const check = await oss.checkObjectHash(objectName, hash, meta); - statMeta = check?.metaData || {}; - let isNewMeta = false; - if (check.success && JSON.stringify(meta) !== '{}' && !check.equalMeta) { - meta = { ...statMeta, ...getMetadata(pathname), ...meta }; - isNewMeta = true; - await oss.replaceObject(objectName, { ...meta }); - } - if (check.success) { - return end({ success: true, hash, meta, isNewMeta, equalMeta: check.equalMeta }, '文件已存在'); - } - } - const bb = busboy({ - headers: req.headers, - limits: { - fileSize: 100 * 1024 * 1024, // 100MB - files: 1, - }, - defCharset: 'utf-8', - }); - let fileProcessed = false; - bb.on('file', async (name, file, info) => { - fileProcessed = true; - try { - await oss.putObject( - objectName, - file, - { - ...statMeta, - ...getMetadata(pathname), - ...meta, - }, - { check: false, isStream: true }, - ); - end({ success: true, name, info, isNew: true, hash, meta: meta?.metaData, statMeta }, '上传成功', 200); - - } catch (error) { - console.log('postProxy upload error', error); - end({ error: error }, '上传失败', 500); - } - }); - - bb.on('finish', () => { - // 只有当没有文件被处理时才执行end - if (!fileProcessed) { - end({ success: false }, '没有接收到文件', 400); - } - }); - bb.on('error', (err) => { - console.error('Busboy 错误:', err); - end({ error: err }, '文件解析失败', 500); - }); - - pipeBusboy(req, res, bb); -}; export const getObjectByPathname = (opts: { pathname: string, version?: string, @@ -377,7 +295,7 @@ export const renameProxy = async (req: IncomingMessage, res: ServerResponse, opt } }; -type ProxyOptions = { +export type ProxyOptions = { createNotFoundPage: (msg?: string) => any; oss?: OssBase; };