|
22 | 22 | from core.response import APIResponse |
23 | 23 | from core.settings import data_root, settings |
24 | 24 | from apps.base.models import FileCodes, UploadChunk |
25 | | -from core.utils import get_file_url |
| 25 | +from core.utils import get_file_url, sanitize_filename |
26 | 26 | from fastapi.responses import FileResponse |
27 | 27 |
|
28 | 28 |
|
@@ -109,10 +109,16 @@ def _save(self, file, save_path): |
109 | 109 | chunk = file.read(self.chunk_size) |
110 | 110 |
|
111 | 111 | async def save_file(self, file: UploadFile, save_path: str): |
112 | | - save_path = self.root_path / save_path |
113 | | - if not save_path.parent.exists(): |
114 | | - save_path.parent.mkdir(parents=True) |
115 | | - await asyncio.to_thread(self._save, file.file, save_path) |
| 112 | + path_obj = Path(save_path) |
| 113 | + directory = str(path_obj.parent) |
| 114 | + # 提取原始文件名并进行清理 |
| 115 | + filename = await sanitize_filename(path_obj.name) |
| 116 | + # 构建安全的完整保存路径 |
| 117 | + safe_save_path = self.root_path / directory / filename |
| 118 | + # 确保目录存在 |
| 119 | + if not safe_save_path.parent.exists(): |
| 120 | + safe_save_path.parent.mkdir(parents=True) |
| 121 | + await asyncio.to_thread(self._save, file.file, safe_save_path) |
116 | 122 |
|
117 | 123 | async def delete_file(self, file_code: FileCodes): |
118 | 124 | save_path = self.root_path / await file_code.get_file_path() |
@@ -447,7 +453,7 @@ def _get_path_str(self, path): |
447 | 453 |
|
448 | 454 | def _save(self, file, save_path): |
449 | 455 | content = file.file.read() |
450 | | - name = file.filename |
| 456 | + name = save_path(file.filename) |
451 | 457 | path = self._get_path_str(save_path) |
452 | 458 | self.root_path.get_by_path(path).upload(name, content).execute_query() |
453 | 459 |
|
@@ -627,16 +633,20 @@ async def _delete_empty_dirs(self, file_path: str, session: aiohttp.ClientSessio |
627 | 633 |
|
628 | 634 | async def save_file(self, file: UploadFile, save_path: str): |
629 | 635 | """保存文件(自动创建目录)""" |
630 | | - # 分离文件名和目录路径 |
631 | 636 | path_obj = Path(save_path) |
632 | 637 | directory_path = str(path_obj.parent) |
| 638 | + # 提取原始文件名并进行清理 |
| 639 | + filename = await sanitize_filename(path_obj.name) |
| 640 | + # 构建安全的保存路径 |
| 641 | + safe_save_path = str(Path(directory_path) / filename) |
| 642 | + |
633 | 643 | try: |
634 | 644 | # 先创建目录结构 |
635 | 645 | await self._mkdir_p(directory_path) |
636 | 646 | # 上传文件 |
637 | | - url = self._build_url(save_path) |
| 647 | + url = self._build_url(safe_save_path) |
638 | 648 | async with aiohttp.ClientSession(auth=self.auth) as session: |
639 | | - content = await file.read() # 注意:大文件需要分块读取 |
| 649 | + content = await file.read() |
640 | 650 | async with session.put( |
641 | 651 | url, data=content, headers={ |
642 | 652 | "Content-Type": file.content_type} |
|
0 commit comments