mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-08-28 03:29:35 +08:00
feat: add 307 redirect download support
This commit is contained in:
+31
-1
@@ -23,6 +23,7 @@ from services.config import ConfigCenter
|
||||
|
||||
|
||||
CROSS_TRANSFER_TEMP_ROOT = Path("data/tmp/cross_transfer")
|
||||
DIRECT_REDIRECT_CONFIG_KEY = "enable_direct_download_307"
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from services.task_queue import Task
|
||||
@@ -87,6 +88,31 @@ async def resolve_adapter_and_rel(path: str):
|
||||
return adapter_instance, adapter_model, effective_root, rel
|
||||
|
||||
|
||||
async def maybe_redirect_download(adapter_instance, adapter_model, root: str, rel: str):
|
||||
"""若适配器启用了 307 直链,尝试构造重定向响应。"""
|
||||
if not rel or rel.endswith('/'):
|
||||
return None
|
||||
|
||||
config = getattr(adapter_model, "config", {}) or {}
|
||||
if not config.get(DIRECT_REDIRECT_CONFIG_KEY):
|
||||
return None
|
||||
|
||||
handler = getattr(adapter_instance, "get_direct_download_response", None)
|
||||
if not callable(handler):
|
||||
return None
|
||||
|
||||
try:
|
||||
response = await handler(root, rel)
|
||||
except FileNotFoundError:
|
||||
raise
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
if isinstance(response, Response):
|
||||
return response
|
||||
return None
|
||||
|
||||
|
||||
async def _ensure_method(adapter: Any, method: str):
|
||||
func = getattr(adapter, method, None)
|
||||
if not callable(func):
|
||||
@@ -437,7 +463,7 @@ async def rename_path(src: str, dst: str, overwrite: bool = False, return_debug:
|
||||
|
||||
|
||||
async def stream_file(path: str, range_header: str | None):
|
||||
adapter_instance, _, root, rel = await resolve_adapter_and_rel(path)
|
||||
adapter_instance, adapter_model, root, rel = await resolve_adapter_and_rel(path)
|
||||
if not rel or rel.endswith('/'):
|
||||
raise HTTPException(400, detail="Path is a directory")
|
||||
if is_raw_filename(rel):
|
||||
@@ -470,6 +496,10 @@ async def stream_file(path: str, range_header: str | None):
|
||||
except Exception as e:
|
||||
raise HTTPException(500, detail=f"RAW file processing failed: {e}")
|
||||
|
||||
redirect_response = await maybe_redirect_download(adapter_instance, adapter_model, root, rel)
|
||||
if redirect_response is not None:
|
||||
return redirect_response
|
||||
|
||||
stream_impl = getattr(adapter_instance, "stream_file", None)
|
||||
if callable(stream_impl):
|
||||
return await stream_impl(root, rel, range_header)
|
||||
|
||||
Reference in New Issue
Block a user