From 7dc9b0c9947a40299655c200dff9738390bbab82 Mon Sep 17 00:00:00 2001 From: estelledc Date: Sat, 4 Jul 2026 10:04:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20/health=20=E7=AB=AF=E7=82=B9=E5=85=8D?= =?UTF-8?q?=E9=89=B4=E6=9D=83=EF=BC=8C=E9=81=BF=E5=85=8D=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=8E=A2=E6=B4=BB=E5=9B=A0=20secret=20=E4=B8=8D=E4=B8=80?= =?UTF-8?q?=E8=87=B4=E8=80=8C=E8=AF=AF=E5=88=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:/health 端点要求 path-secret 鉴权。当 config.secret 被清空/轮换后, 现有的监控探活全部 403 → 误判代理不健康 → 状态灯黄灯。 修改: - /health 改为免鉴权(健康检查不含敏感信息,加鉴权反而引入脆弱性) - 同时匹配裸路径和带 secret 前缀的路径,兼容新旧调用方 - 测试从 assert 403 改为 assert 200 Closes #12 --- proxy/csswitch_proxy.py | 8 ++++++-- test/test_proxy_auth.py | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/proxy/csswitch_proxy.py b/proxy/csswitch_proxy.py index 60780dd..22cd21d 100644 --- a/proxy/csswitch_proxy.py +++ b/proxy/csswitch_proxy.py @@ -360,6 +360,12 @@ def _auth_ok(self): return False def do_GET(self): + # /health 免鉴权(健康检查不含敏感信息) + # 注意:path 可能尚未经 _auth_ok 剥离前缀,故同时匹配裸路径和带 secret 前缀的路径。 + if self.path == "/health" or self.path.startswith("/health?") \ + or self.path.endswith("/health") or "/health?" in self.path: + self._send_json(200, {"status": "ok", "provider": PROV_NAME}) + return if not self._auth_ok(): return if self.path.startswith("/v1/models"): @@ -368,8 +374,6 @@ def do_GET(self): log(f"GET /v1/models -> {PROV_NAME}: {', '.join(m[0] for m in PROV['models'])}") self._send_json(200, {"data": data, "has_more": False, "first_id": data[0]["id"], "last_id": data[-1]["id"]}) - elif self.path.startswith("/health"): - self._send_json(200, {"status": "ok", "provider": PROV_NAME}) else: self._send_json(404, {"type": "error", "error": {"type": "not_found_error", "message": self.path}}) diff --git a/test/test_proxy_auth.py b/test/test_proxy_auth.py index a32d3e1..6716ca7 100644 --- a/test/test_proxy_auth.py +++ b/test/test_proxy_auth.py @@ -61,9 +61,10 @@ def test_health_with_secret_ok(self): s, _b = _req(f"{self.base}/{SEC}/health") self.assertEqual(s, 200) - def test_health_without_secret_forbidden(self): + def test_health_without_secret_ok(self): + # /health 免鉴权(自 #12 起),便于监控探活不依赖 secret 一致性 s, _b = _req(f"{self.base}/health") - self.assertEqual(s, 403) + self.assertEqual(s, 200) def test_messages_without_secret_forbidden_and_upstream_untouched(self): before = len(self.hits)