This commit is contained in:
jxxghp
2025-09-13 10:12:40 +08:00
parent 8481fd38ce
commit f0fc64c517
+9 -7
View File
@@ -11,6 +11,7 @@ import aiofiles
import pillow_avif # noqa 用于自动注册AVIF支持 import pillow_avif # noqa 用于自动注册AVIF支持
from PIL import Image from PIL import Image
from anyio import Path as AsyncPath from anyio import Path as AsyncPath
from app.helper.sites import SitesHelper # noqa # noqa
from fastapi import APIRouter, Body, Depends, HTTPException, Header, Request, Response from fastapi import APIRouter, Body, Depends, HTTPException, Header, Request, Response
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
@@ -31,7 +32,6 @@ from app.helper.mediaserver import MediaServerHelper
from app.helper.message import MessageHelper from app.helper.message import MessageHelper
from app.helper.progress import ProgressHelper from app.helper.progress import ProgressHelper
from app.helper.rule import RuleHelper from app.helper.rule import RuleHelper
from app.helper.sites import SitesHelper # noqa # noqa
from app.helper.subscribe import SubscribeHelper from app.helper.subscribe import SubscribeHelper
from app.helper.system import SystemHelper from app.helper.system import SystemHelper
from app.log import logger from app.log import logger
@@ -52,19 +52,20 @@ async def fetch_image(
proxy: bool = False, proxy: bool = False,
use_cache: bool = False, use_cache: bool = False,
if_none_match: Optional[str] = None, if_none_match: Optional[str] = None,
allowed_domains: Optional[set[str]] = None) -> Response: allowed_domains: Optional[set[str]] = None) -> Optional[Response]:
""" """
处理图片缓存逻辑,支持HTTP缓存和磁盘缓存 处理图片缓存逻辑,支持HTTP缓存和磁盘缓存
""" """
if not url: if not url:
raise HTTPException(status_code=404, detail="URL not provided") return None
if allowed_domains is None: if allowed_domains is None:
allowed_domains = set(settings.SECURITY_IMAGE_DOMAINS) allowed_domains = set(settings.SECURITY_IMAGE_DOMAINS)
# 验证URL安全性 # 验证URL安全性
if not SecurityUtils.is_safe_url(url, allowed_domains): if not SecurityUtils.is_safe_url(url, allowed_domains):
raise HTTPException(status_code=404, detail="Unsafe URL") logger.warn(f"Blocked unsafe image URL: {url}")
return None
# 缓存路径 # 缓存路径
sanitized_path = SecurityUtils.sanitize_url_path(url) sanitized_path = SecurityUtils.sanitize_url_path(url)
@@ -98,15 +99,16 @@ async def fetch_image(
response = await AsyncRequestUtils(ua=settings.NORMAL_USER_AGENT, proxies=proxies, referer=referer, response = await AsyncRequestUtils(ua=settings.NORMAL_USER_AGENT, proxies=proxies, referer=referer,
accept_type="image/avif,image/webp,image/apng,*/*").get_res(url=url) accept_type="image/avif,image/webp,image/apng,*/*").get_res(url=url)
if not response: if not response:
raise HTTPException(status_code=502, detail="Failed to fetch the image from the remote server") logger.warn(f"Failed to fetch image from URL: {url}")
return None
# 验证下载的内容是否为有效图片 # 验证下载的内容是否为有效图片
try: try:
content = response.content content = response.content
Image.open(io.BytesIO(content)).verify() Image.open(io.BytesIO(content)).verify()
except Exception as e: except Exception as e:
logger.debug(f"Invalid image format for URL {url}: {e}") logger.warn(f"Invalid image format for URL {url}: {e}")
raise HTTPException(status_code=502, detail="Invalid image format") return None
# 获取请求响应头 # 获取请求响应头
response_headers = response.headers response_headers = response.headers