's'
This commit is contained in:
@@ -7,6 +7,7 @@ import time
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from urllib.parse import parse_qs
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
@@ -329,22 +330,43 @@ async def handle_business(data: dict) -> str:
|
|||||||
async def _handle_wechat_request(request: Request, app_id: Optional[str], background_tasks: BackgroundTasks) -> str:
|
async def _handle_wechat_request(request: Request, app_id: Optional[str], background_tasks: BackgroundTasks) -> str:
|
||||||
if app_id and app_id != APP_ID:
|
if app_id and app_id != APP_ID:
|
||||||
logger.warning("chatbot app_id mismatch expected=%s actual=%s", APP_ID, app_id)
|
logger.warning("chatbot app_id mismatch expected=%s actual=%s", APP_ID, app_id)
|
||||||
raw_body = (await request.body()).decode("utf-8").strip()
|
raw_body = (await request.body()).decode("utf-8", errors="ignore").strip()
|
||||||
if not raw_body:
|
if not raw_body:
|
||||||
raise HTTPException(status_code=400, detail="empty body")
|
raise HTTPException(status_code=400, detail="empty body")
|
||||||
|
|
||||||
cipher_b64 = raw_body
|
cipher_b64 = raw_body
|
||||||
if "encrypted" in raw_body:
|
# 兼容三种请求体:
|
||||||
|
# 1) 纯密文 base64
|
||||||
|
# 2) JSON: {"encrypted":"..."} / {"encrypt":"..."} / {"Encrypt":"..."}
|
||||||
|
# 3) x-www-form-urlencoded: encrypted=... / encrypt=...
|
||||||
try:
|
try:
|
||||||
outer = json.loads(raw_body)
|
outer = json.loads(raw_body)
|
||||||
if isinstance(outer, dict) and "encrypted" in outer:
|
if isinstance(outer, dict):
|
||||||
cipher_b64 = "".join(str(outer["encrypted"]).split()).strip()
|
for key in ("encrypted", "encrypt", "Encrypt"):
|
||||||
|
val = outer.get(key)
|
||||||
|
if isinstance(val, str) and val.strip():
|
||||||
|
cipher_b64 = val
|
||||||
|
break
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
form = parse_qs(raw_body, keep_blank_values=True)
|
||||||
|
for key in ("encrypted", "encrypt", "Encrypt"):
|
||||||
|
vals = form.get(key) or []
|
||||||
|
if vals and str(vals[0]).strip():
|
||||||
|
cipher_b64 = str(vals[0])
|
||||||
|
break
|
||||||
|
|
||||||
|
cipher_b64 = "".join(str(cipher_b64).split()).strip()
|
||||||
try:
|
try:
|
||||||
decrypted = aes_decrypt_base64(cipher_b64, ENCODING_AES_KEY)
|
decrypted = aes_decrypt_base64(cipher_b64, ENCODING_AES_KEY)
|
||||||
data = _parse_decrypted_payload(decrypted)
|
data = _parse_decrypted_payload(decrypted)
|
||||||
except Exception:
|
except Exception as error:
|
||||||
logger.error("chatbot decrypt failed")
|
logger.error(
|
||||||
|
"chatbot decrypt failed app_id=%s content_type=%s body_prefix=%s err=%s",
|
||||||
|
app_id or "",
|
||||||
|
request.headers.get("content-type", ""),
|
||||||
|
raw_body[:160],
|
||||||
|
error,
|
||||||
|
)
|
||||||
raise HTTPException(status_code=400, detail="decrypt error")
|
raise HTTPException(status_code=400, detail="decrypt error")
|
||||||
|
|
||||||
answer_text = await handle_business(data)
|
answer_text = await handle_business(data)
|
||||||
|
|||||||
Reference in New Issue
Block a user