feat: router firewall — validate model against OCG whitelist + require messages; block client errors before upstream call (prevents rate-limit pollution)
This commit is contained in:
@@ -459,6 +459,17 @@ class RouterHandler(BaseHTTPRequestHandler):
|
||||
self._json_response({"object": "list", "data": models})
|
||||
|
||||
# ── Chat Completions Proxy ──
|
||||
# 防火墙:OCG 已知模型白名单(2026-08-15 来自官方文档 go.mdx)
|
||||
# 请求 model 不在白名单 → 直接 400,不调用上游,防止错误模型名打到上游触发限流
|
||||
KNOWN_OCG_MODELS = {
|
||||
"deepseek-v4-flash", "deepseek-v4-pro", "kimi-k2.7-code", "kimi-k2.6",
|
||||
"kimi-k2.5", "kimi-k3", "glm-5", "glm-5.1", "glm-5.2", "glm-5.3",
|
||||
"gpt-5.6-luna", "grok-4.5", "hy3", "hy3-preview", "mimo-v2-omni",
|
||||
"mimo-v2-pro", "mimo-v2.5", "mimo-v2.5-pro", "minimax-m2.5",
|
||||
"minimax-m2.7", "minimax-m3", "qwen3.5-plus", "qwen3.6-plus",
|
||||
"qwen3.7-max", "qwen3.7-plus", "qwen3.8-max",
|
||||
}
|
||||
|
||||
def _proxy_chat(self):
|
||||
start = time.time()
|
||||
content_length = int(self.headers.get("Content-Length", 0))
|
||||
@@ -466,6 +477,7 @@ class RouterHandler(BaseHTTPRequestHandler):
|
||||
|
||||
is_stream = False
|
||||
model_name = "unknown"
|
||||
req_data = None
|
||||
if body:
|
||||
try:
|
||||
req_data = json.loads(body)
|
||||
@@ -475,6 +487,21 @@ class RouterHandler(BaseHTTPRequestHandler):
|
||||
except (json.JSONDecodeError, UnicodeDecodeError) as e:
|
||||
log.warning("failed to parse request body (len=%d): %s", len(body), e)
|
||||
|
||||
# ── 防火墙:前置校验,阻止客户端错误传导到上游 ──
|
||||
if not body or not req_data:
|
||||
self._error_response(400, "Empty or invalid request body")
|
||||
return
|
||||
if not model_name or model_name == "unknown":
|
||||
self._error_response(400, "Missing required field: model")
|
||||
return
|
||||
if "messages" not in req_data or not isinstance(req_data.get("messages"), list) or not req_data["messages"]:
|
||||
self._error_response(400, "Missing required field: messages (non-empty list)")
|
||||
return
|
||||
if model_name not in self.KNOWN_OCG_MODELS:
|
||||
log.warning("firewall: blocked unknown model '%s' (client error, no upstream call)", model_name)
|
||||
self._error_response(400, f"Model '{model_name}' is not supported by this router")
|
||||
return
|
||||
|
||||
# 2026-08-13 并发模式:header X-OCG-Mode: concurrent → round-robin 锁 key 轮询
|
||||
concurrent_mode = self.headers.get("X-OCG-Mode", "").lower() == "concurrent"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user