fix: precheck local downloads to avoid JSON file download on quota errors

This commit is contained in:
2026-02-17 19:32:48 +08:00
parent dd6c439eb3
commit 2b700978ad
2 changed files with 91 additions and 10 deletions

View File

@@ -4813,6 +4813,67 @@ app.post('/api/upload', authMiddleware, upload.single('file'), async (req, res)
}
});
// 下载预检(避免前端直接下载到 JSON 错误响应)
app.get('/api/files/download-check', authMiddleware, async (req, res) => {
const filePath = req.query.path;
let storage;
if (!filePath) {
return res.status(400).json({
success: false,
message: '缺少文件路径参数'
});
}
const normalizedPath = path.posix.normalize(filePath);
if (normalizedPath.includes('..') || filePath.includes('\x00')) {
return res.status(400).json({
success: false,
message: '文件路径非法'
});
}
try {
const policyState = enforceDownloadTrafficPolicy(req.user.id, 'download_check');
const latestUser = policyState?.user || UserDB.findById(req.user.id);
if (!latestUser) {
return res.status(401).json({
success: false,
message: '用户不存在'
});
}
const trafficState = getDownloadTrafficState(latestUser);
const { StorageInterface } = require('./storage');
const storageInterface = new StorageInterface(req.user);
storage = await storageInterface.connect();
const fileStats = await storage.stat(normalizedPath);
const fileSize = Math.max(0, Number(fileStats?.size) || 0);
const fileName = normalizedPath.split('/').pop() || 'download.bin';
if (!trafficState.isUnlimited && fileSize > trafficState.remaining) {
return res.status(403).json({
success: false,
message: `下载流量不足:文件 ${formatFileSize(fileSize)},剩余 ${formatFileSize(trafficState.remaining)}`
});
}
res.json({
success: true,
fileName,
fileSize
});
} catch (error) {
console.error('下载预检失败:', error);
res.status(500).json({
success: false,
message: getSafeErrorMessage(error, '下载检查失败,请稍后重试', '下载预检')
});
} finally {
if (storage) await storage.end();
}
});
// 下载文件
app.get('/api/files/download', authMiddleware, async (req, res) => {