获取文件响应(代理模式)
(self, file_code: FileCodes)
| 1142 | return await get_file_url(file_code.code) |
| 1143 | |
| 1144 | async def get_file_response(self, file_code: FileCodes): |
| 1145 | """获取文件响应(代理模式)""" |
| 1146 | try: |
| 1147 | filename = file_code.prefix + file_code.suffix |
| 1148 | url = self._build_url(await file_code.get_file_path()) |
| 1149 | content_length = None # 初始化为 None,表示未知大小 |
| 1150 | |
| 1151 | # 创建ClientSession并复用(包含认证头) |
| 1152 | session = aiohttp.ClientSession(headers={ |
| 1153 | "Authorization": f"Basic {base64.b64encode(f'{settings.webdav_username}:{settings.webdav_password}'.encode()).decode()}" |
| 1154 | }) |
| 1155 | |
| 1156 | # 尝试发送HEAD请求获取Content-Length |
| 1157 | try: |
| 1158 | async with session.head(url) as resp: |
| 1159 | if resp.status == 200 and 'Content-Length' in resp.headers: |
| 1160 | content_length = int(resp.headers['Content-Length']) |
| 1161 | except Exception: |
| 1162 | # 如果HEAD请求失败,则不提供 Content-Length |
| 1163 | pass |
| 1164 | |
| 1165 | async def stream_generator(): |
| 1166 | try: |
| 1167 | async with session.get(url) as resp: |
| 1168 | if resp.status != 200: |
| 1169 | raise HTTPException( |
| 1170 | status_code=resp.status, |
| 1171 | detail=f"文件获取失败{resp.status}: {await resp.text()}", |
| 1172 | ) |
| 1173 | chunk_size = 65536 |
| 1174 | while True: |
| 1175 | chunk = await resp.content.read(chunk_size) |
| 1176 | if not chunk: |
| 1177 | break |
| 1178 | yield chunk |
| 1179 | finally: |
| 1180 | await session.close() |
| 1181 | |
| 1182 | encoded_filename = quote(filename, safe='') |
| 1183 | headers = { |
| 1184 | "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}" |
| 1185 | } |
| 1186 | if content_length is not None: |
| 1187 | headers["Content-Length"] = str(content_length) |
| 1188 | return StreamingResponse( |
| 1189 | stream_generator(), |
| 1190 | media_type="application/octet-stream", |
| 1191 | headers=headers |
| 1192 | ) |
| 1193 | except aiohttp.ClientError as e: |
| 1194 | raise HTTPException( |
| 1195 | status_code=503, detail=f"WebDAV连接异常: {str(e)}") |
| 1196 | |
| 1197 | async def save_chunk(self, upload_id: str, chunk_index: int, chunk_data: bytes, chunk_hash: str, save_path: str): |
| 1198 | """保存分片到 WebDAV""" |
nothing calls this directly
no test coverage detected