#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:
1 parent
75be24ce9c
commit
54b444b651
1 file changed
+47
@@ -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]}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user