#967 implement media_relay endpoint - fix WeChat bot image relay

media_relay was a stub (empty function body). Now implements actual image/video streaming relay from S3 to WeChat clients, with domain whitelist and httpx streaming. Fixes WeChat bot image generation responses not rendered.
This commit is contained in:
qihu-bot committed 2026-08-11 21:31:15 +08:00
1 parent 75be24ce9c
commit 54b444b651
1 file changed
+47
+47
View File
@@ -155,6 +155,17 @@ _MEDIA_RELAY_ALLOWED = ("agnes-ai.com", "agnes-ai.space", "qihuyun.com")
# Media relay client (trust_env=False to bypass proxy for image fetches)
_media_client = None
def _get_media_client():
global _media_client
if _media_client is None:
_media_client = httpx.Client(timeout=30.0, follow_redirects=True, trust_env=False)
return _media_client
@router.get("/media/relay")
@@ -197,6 +208,42 @@ async def media_relay(url: str = Query(...)):
"""
import urllib.parse as _up
import httpx
from fastapi.responses import StreamingResponse
host = (_up.urlparse(url).hostname or "").lower()
# 白名单域名检查
allowed = ("siliconflow.cn", "s3.siliconflow.cn", "aliyuncs.com", "tencentcos.cn",
"qpic.cn", "alicdn.com", "api.openai.com", "myqcloud.com")
if not any(a in host for a in allowed):
raise HTTPException(status_code=400, detail="unsupported media host")
try:
client = _get_media_client()
resp = client.get(url, timeout=30.0, follow_redirects=True)
if resp.status_code != 200:
raise HTTPException(status_code=502, detail=f"upstream returned {resp.status_code}")
ct = resp.headers.get("content-type", "application/octet-stream")
cl = resp.headers.get("content-length")
headers = {}
if ct:
headers["content-type"] = ct
if cl:
headers["content-length"] = cl
headers["cache-control"] = "public, max-age=3600"
return StreamingResponse(
resp.iter_bytes(chunk_size=65536),
status_code=200,
headers=headers,
media_type=ct
)
except httpx.TimeoutException:
raise HTTPException(status_code=504, detail="upstream timeout")
except Exception as e:
raise HTTPException(status_code=502, detail=f"relay error: {str(e)[:200]}")