fix(agent): 外部Dify Agent 手动跟随http->https 301重定向并保持POST(测试连接+运行期);qihuyun.com直连

This commit is contained in:
deploy committed 2026-07-15 14:30:24 +08:00
1 parent d274733fb3
commit 4d57987aa5
2 files changed
+111 -46

No files matched your search

+42 -1
View File
@@ -35,6 +35,29 @@ def _short_err(e: Exception) -> str:
return str(e)[:160]
def _post_follow(url: str, headers: dict, json_body: dict, timeout: float = 15.0):
"""POST 并手动跟随 301/302/307/308 重定向(**保持 POST 方法与请求体**)。
背景:Dify 若填写 http:// 地址会 301 永久重定向到 https://;httpx 内建
follow_redirects 对 301/302 会把 POST 降级为 GET(浏览器行为),导致对
/v1/chat-messages 变成 GET → 405 method_not_allowed。故手动跟随并保持 POST。
容器内 env 有坏代理(502),必须 trust_env=False 直连。
"""
cur = url
last = None
for _ in range(4):
last = httpx.post(cur, headers=headers, json=json_body, timeout=timeout,
trust_env=False, follow_redirects=False)
if last.status_code in (301, 302, 307, 308):
loc = last.headers.get("location")
if not loc:
return last
cur = loc if loc.startswith("http") else str(httpx.URL(cur).join(loc))
continue
return last
return last
def verify_agent_connectivity(platform: str, endpoint: str, api_key: str) -> dict:
"""
接入 Agent 前的连通性 + 鉴权校验。
@@ -58,7 +81,7 @@ def verify_agent_connectivity(platform: str, endpoint: str, api_key: str) -> dic
}
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
try:
r = httpx.post(url, headers=headers, json=payload, timeout=15.0, trust_env=False)
r = _post_follow(url, headers, payload, timeout=15.0)
except Exception as e:
return {"ok": False, "verified": False, "detail": f"无法连接 Dify 地址:{_short_err(e)}"}
if r.status_code == 200:
@@ -68,6 +91,24 @@ def verify_agent_connectivity(platform: str, endpoint: str, api_key: str) -> dic
if r.status_code == 404:
return {"ok": False, "verified": False,
"detail": "地址路径不正确(404),应为 .../v1/chat-messages"}
if r.status_code in (301, 302, 307, 308):
loc = r.headers.get("location") or ""
return {"ok": False, "verified": False,
"detail": f"地址被重定向({r.status_code})到 {loc or '未知'};"
f"请直接填写重定向后的地址(通常把 http:// 改为 https://)"}
if r.status_code == 400:
# 400 需区分两种情况:
# (a) 到达应用且鉴权通过,但 Dify 应用/工作流内部执行报错(invalid_param + Run failed)
# (b) 纯参数错误
body = (r.text or "")
low = body.lower()
if ("run failed" in low or "error code" in low or "workflow" in low
or "node" in low or "-500" in body):
return {"ok": True, "verified": True,
"detail": "连通且 API Key 有效;但你的 Dify 应用内部执行报错:"
f"{body[:180]}。这是你自建 Dify 应用/工作流本身的问题"
"(例如代码节点沙箱缺少 python3),请在 Dify 侧修复。"}
return {"ok": False, "verified": False, "detail": f"参数错误(400):{body[:180]}"}
return {"ok": False, "verified": False, "detail": f"Dify 返回状态码 {r.status_code}"}
# n8n / coze / 其他:仅做可达性探测(HEAD,避免触发 webhook 副作用)