优化 postProxy 函数以支持从请求头获取文件大小;添加 renameProxy 函数以处理文件重命名;修复 isLocalhost 函数的格式问题
This commit is contained in:
@@ -163,7 +163,10 @@ export const postProxy = async (req: IncomingMessage, res: ServerResponse, opts:
|
||||
const _fileSize: string = params.get('size');
|
||||
let fileSize: number | undefined = undefined;
|
||||
if (_fileSize) {
|
||||
fileSize = parseInt(_fileSize, 10)
|
||||
fileSize = parseInt(_fileSize, 10);
|
||||
} else if (req.headers['content-length']) {
|
||||
// 如果 URL 参数没有 size,尝试从请求头获取
|
||||
fileSize = parseInt(req.headers['content-length'], 10);
|
||||
}
|
||||
let meta = parseSearchValue(params.get('meta'), { decode: true });
|
||||
if (!hash && !force) {
|
||||
@@ -216,6 +219,7 @@ export const postProxy = async (req: IncomingMessage, res: ServerResponse, opts:
|
||||
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);
|
||||
}
|
||||
});
|
||||
@@ -233,6 +237,24 @@ export const postProxy = async (req: IncomingMessage, res: ServerResponse, opts:
|
||||
|
||||
pipeBusboy(req, res, bb);
|
||||
};
|
||||
export const getObjectByPathname = (opts: {
|
||||
pathname: string,
|
||||
version?: string,
|
||||
}) => {
|
||||
const [_, user, app] = opts.pathname.split('/');
|
||||
let prefix = '';
|
||||
let replaceKey = '';
|
||||
if (app === 'ai') {
|
||||
const version = opts?.version || '1.0.0';
|
||||
replaceKey = `/${user}/${app}/`;
|
||||
prefix = `${user}/${app}/${version}/`;
|
||||
} else {
|
||||
replaceKey = `/${user}/${app}/`;
|
||||
prefix = `${user}/`; // root/resources
|
||||
}
|
||||
let objectName = opts.pathname.replace(replaceKey, prefix);
|
||||
return { prefix, replaceKey, objectName, user, app };
|
||||
}
|
||||
export const getObjectName = async (req: IncomingMessage, opts?: { checkOwner?: boolean }) => {
|
||||
const _u = new URL(req.url, 'http://localhost');
|
||||
const pathname = decodeURIComponent(_u.pathname);
|
||||
@@ -270,14 +292,90 @@ export const deleteProxy = async (req: IncomingMessage, res: ServerResponse, opt
|
||||
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' }));
|
||||
};
|
||||
try {
|
||||
await oss.deleteObject(objectName);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ success: true, message: 'delete success', objectName }));
|
||||
// 如果以 / 结尾,删除该前缀下的所有对象(文件夹)
|
||||
if (objectName.endsWith('/')) {
|
||||
const objects = await oss.listObjects<true>(objectName, { recursive: true });
|
||||
if (objects.length > 0) {
|
||||
const objectNames = objects.map((obj: any) => obj.name);
|
||||
await minioClient.removeObjects(bucketName, objectNames);
|
||||
}
|
||||
end({ success: true, objectName, deletedCount: objects.length }, 'delete success', 200);
|
||||
} else {
|
||||
await oss.deleteObject(objectName);
|
||||
end({ success: true, objectName }, 'delete success', 200);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('deleteProxy error', error);
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ success: false, error: error }));
|
||||
end({ success: false, error }, 'delete failed', 500);
|
||||
}
|
||||
};
|
||||
|
||||
export const renameProxy = async (req: IncomingMessage, res: ServerResponse, opts: ProxyOptions) => {
|
||||
const { objectName, isOwner, user } = await getObjectName(req);
|
||||
let oss = opts.oss;
|
||||
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' }));
|
||||
};
|
||||
|
||||
const _u = new URL(req.url, 'http://localhost');
|
||||
let newName = _u.searchParams.get('newName');
|
||||
if (!newName) {
|
||||
return end({ success: false }, 'newName parameter required', 400);
|
||||
}
|
||||
// 解码 URL 编码的路径
|
||||
newName = decodeURIComponent(newName);
|
||||
if (!newName.startsWith('/')) {
|
||||
newName = '/' + newName;
|
||||
}
|
||||
const newUrl = new URL(newName, 'http://localhost');
|
||||
const version = _u.searchParams.get('version') || '1.0.0';
|
||||
const newNamePath = newUrl.pathname;
|
||||
// 确保 newName 有正确的前缀路径
|
||||
|
||||
const newObject = getObjectByPathname({ pathname: newNamePath, version });
|
||||
const { user: newUser, objectName: newObjectName } = newObject;
|
||||
if (newUser !== user) {
|
||||
return end({ success: false }, '文件重命名只能在同一用户下进行', 400);
|
||||
}
|
||||
try {
|
||||
const isDir = objectName.endsWith('/');
|
||||
let copiedCount = 0;
|
||||
|
||||
if (isDir) {
|
||||
// 重命名文件夹:复制所有对象到新前缀,然后删除原对象
|
||||
const objects = await oss.listObjects<true>(objectName, { recursive: true });
|
||||
for (const obj of objects) {
|
||||
const oldKey = obj.name;
|
||||
const newKey = oldKey.replace(objectName, newObjectName);
|
||||
console.log('rename dir object', oldKey, newKey);
|
||||
await minioClient.copyObject(bucketName, newKey, `/${bucketName}/${oldKey}`);
|
||||
copiedCount++;
|
||||
}
|
||||
// 删除原对象
|
||||
const objectNames = objects.map((obj: any) => obj.name);
|
||||
if (objectNames.length > 0) {
|
||||
await minioClient.removeObjects(bucketName, objectNames);
|
||||
}
|
||||
} else {
|
||||
// 重命名文件
|
||||
await minioClient.copyObject(bucketName, newObjectName, `/${bucketName}/${objectName}`);
|
||||
await oss.deleteObject(objectName);
|
||||
copiedCount = 1;
|
||||
}
|
||||
|
||||
end({ success: true, objectName, newObjectName, copiedCount }, 'rename success', 200);
|
||||
} catch (error) {
|
||||
logger.error('renameProxy error', error);
|
||||
end({ success: false, error }, 'rename failed', 500);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -296,6 +394,9 @@ export const aiProxy = async (req: IncomingMessage, res: ServerResponse, opts: P
|
||||
if (req.method === 'DELETE') {
|
||||
return deleteProxy(req, res, opts);
|
||||
}
|
||||
if (req.method === 'PUT') {
|
||||
return renameProxy(req, res, opts);
|
||||
}
|
||||
|
||||
return getAiProxy(req, res, opts);
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ export const getDNS = (req: http.IncomingMessage) => {
|
||||
};
|
||||
|
||||
export const isLocalhost = (hostName: string) => {
|
||||
if(!hostName) {
|
||||
if (!hostName) {
|
||||
return false;
|
||||
}
|
||||
return hostName.includes('localhost') || hostName.includes('192.168');
|
||||
|
||||
Reference in New Issue
Block a user