fix(tts): voice.enabled=0 真生效,返回 403 voice_disabled
Bug: admin UI 切换"启用/禁用"toggle → DB 字段更新 ✓,
但 controller/tts.go 路由时不查 enabled, 关掉的 voice 仍能正常调通。
admin 关闭形同虚设。
修法: 在 voice 查库命中后, 立即检查 v.Enabled:
- enabled=1 → 走原流程
- enabled=0 → 立即 403, 错误码 voice_disabled
Body 格式(对齐 OpenAI error 规范):
{
"error": {
"code": "voice_disabled",
"message": "voice 'chun' is disabled",
"type": "invalid_request_error"
}
}
为什么 403 (vs 400 / 410):
- 400: 客户端发错 — 不准, voice 存在, 只是被关
- 410: 资源 gone — 不准, 不是永久弃用, 可能再开
- 403: 资源存在但无权用 — 准确, admin 关 = 拒绝调用
(OpenAI 其他端点对禁用资源用 403, 这是惯例)
e2e (本机):
- TEST 1: voice=chun, enabled=1 → 500 (volcano 假 key 401, 路由通了)
- TEST 2: voice=chun, enabled=0 → 403 voice_disabled ✓
- TEST 3: voice=ghost, 不存在 → 400 unknown_voice (原有行为不变)
副作用:
- 没有任何 admin 路径失败 (admin 改 enabled 字段直接生效, 无需 reload)
- metrics 没加新 label (后续可加 voice_disabled 计数, 留给 M4)
未 push (待用户)
This commit is contained in:
+9
-2
@@ -172,9 +172,9 @@ func OpenaiTTSHandler(w http.ResponseWriter, r *http.Request) {
|
||||
v, err := s.VoiceGetByName(req.Voice)
|
||||
if err != nil {
|
||||
if err == store.ErrNotFound {
|
||||
log.Printf("警告: 未知 voice=%s - 路径=%s 客户端=%s", req.Voice, r.URL.Path, middleware.GetClientIP(r))
|
||||
log.Printf("警告: 未知 voice=%q - 路径=%s 客户端=%s", req.Voice, r.URL.Path, middleware.GetClientIP(r))
|
||||
middleware.SendJSONError(w, http.StatusBadRequest,
|
||||
fmt.Sprintf("unknown voice: %s", req.Voice),
|
||||
fmt.Sprintf("unknown voice: '%s'", req.Voice),
|
||||
"invalid_request_error", "unknown_voice")
|
||||
return
|
||||
}
|
||||
@@ -184,6 +184,13 @@ func OpenaiTTSHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
// 覆盖 opts(API key / UID 保留自 setting.TTSOptions)
|
||||
if !v.Enabled {
|
||||
log.Printf("警告: voice=%q 已禁用 - 客户端=%s", req.Voice, middleware.GetClientIP(r))
|
||||
middleware.SendJSONError(w, http.StatusForbidden,
|
||||
fmt.Sprintf("voice '%s' is disabled", req.Voice),
|
||||
"invalid_request_error", "voice_disabled")
|
||||
return
|
||||
}
|
||||
opts.Speaker = v.Speaker
|
||||
opts.ResourceID = v.ResourceID
|
||||
if v.Model != "" {
|
||||
|
||||
Reference in New Issue
Block a user