fix(handler): 修复 gjson 迁移后的请求校验语义回退
- OpenAI handler: 添加 gjson.ValidBytes 校验 JSON 合法性;model 校验改为 检查 gjson.String 类型而非仅判断非空(拒绝 model:123 等非法类型);stream 字段添加 True/False 类型检查;sjson.SetBytes 返回值显式处理错误 - Sora handler: 添加 gjson.ValidBytes 校验;model 校验同上改为类型检查; messages 校验从 Exists+Type==JSON 改为 IsArray+len>0(拒绝空数组和对象) - 补充 TestOpenAIHandler_GjsonValidation 和更新 TestSoraHandler_ValidationExtraction 覆盖新增的边界校验场景 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -95,15 +95,26 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
|
||||
|
||||
setOpsRequestContext(c, "", false, body)
|
||||
|
||||
// 使用 gjson 只读提取字段做校验,避免完整 Unmarshal
|
||||
reqModel := gjson.GetBytes(body, "model").String()
|
||||
reqStream := gjson.GetBytes(body, "stream").Bool()
|
||||
// 校验请求体 JSON 合法性
|
||||
if !gjson.ValidBytes(body) {
|
||||
h.errorResponse(c, http.StatusBadRequest, "invalid_request_error", "Failed to parse request body")
|
||||
return
|
||||
}
|
||||
|
||||
// 验证 model 必填
|
||||
if reqModel == "" {
|
||||
// 使用 gjson 只读提取字段做校验,避免完整 Unmarshal
|
||||
modelResult := gjson.GetBytes(body, "model")
|
||||
if !modelResult.Exists() || modelResult.Type != gjson.String || modelResult.String() == "" {
|
||||
h.errorResponse(c, http.StatusBadRequest, "invalid_request_error", "model is required")
|
||||
return
|
||||
}
|
||||
reqModel := modelResult.String()
|
||||
|
||||
streamResult := gjson.GetBytes(body, "stream")
|
||||
if streamResult.Exists() && streamResult.Type != gjson.True && streamResult.Type != gjson.False {
|
||||
h.errorResponse(c, http.StatusBadRequest, "invalid_request_error", "invalid stream field type")
|
||||
return
|
||||
}
|
||||
reqStream := streamResult.Bool()
|
||||
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
isCodexCLI := openai.IsCodexCLIRequest(userAgent) || (h.cfg != nil && h.cfg.Gateway.ForceCodexCLI)
|
||||
@@ -111,7 +122,12 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
|
||||
existingInstructions := gjson.GetBytes(body, "instructions").String()
|
||||
if strings.TrimSpace(existingInstructions) == "" {
|
||||
if instructions := strings.TrimSpace(service.GetOpenCodeInstructions()); instructions != "" {
|
||||
body, _ = sjson.SetBytes(body, "instructions", instructions)
|
||||
newBody, err := sjson.SetBytes(body, "instructions", instructions)
|
||||
if err != nil {
|
||||
h.errorResponse(c, http.StatusInternalServerError, "api_error", "Failed to process request")
|
||||
return
|
||||
}
|
||||
body = newBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user