From 4bfa69bffaa8431df10d13f863121418e7a10439 Mon Sep 17 00:00:00 2001 From: yangjianbo Date: Sat, 14 Feb 2026 09:53:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(openai):=20=E4=BB=85=E8=AE=B0=E5=BD=95=20co?= =?UTF-8?q?dex=5Fcli=5Fonly=20=E6=8B=92=E7=BB=9D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=B9=B6=E8=BE=93=E5=87=BA=E8=AF=A6=E7=BB=86=20User-Agent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/service/openai_gateway_service.go | 18 ++++++++++++++++-- ...enai_gateway_service_codex_cli_only_test.go | 9 +++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index 697be994..3f02a8f5 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -313,7 +313,6 @@ func logCodexCLIOnlyDetection(ctx context.Context, c *gin.Context, account *Acco } log := logger.FromContext(ctx).With(fields...) if result.Matched { - log.Warn("OpenAI codex_cli_only 允许官方客户端请求") return } log.Warn("OpenAI codex_cli_only 拒绝非官方客户端请求") @@ -333,7 +332,7 @@ func appendCodexCLIOnlyRejectedRequestFields(fields []zap.Field, c *gin.Context, zap.String("request_host", strings.TrimSpace(req.Host)), zap.String("request_client_ip", strings.TrimSpace(c.ClientIP())), zap.String("request_remote_addr", strings.TrimSpace(req.RemoteAddr)), - zap.String("request_user_agent", strings.TrimSpace(req.Header.Get("User-Agent"))), + zap.String("request_user_agent", buildDetailedUserAgent(req.Header.Values("User-Agent"))), zap.String("request_content_type", strings.TrimSpace(req.Header.Get("Content-Type"))), zap.Int64("request_content_length", req.ContentLength), zap.Bool("request_stream", requestStream), @@ -352,6 +351,21 @@ func appendCodexCLIOnlyRejectedRequestFields(fields []zap.Field, c *gin.Context, return fields } +func buildDetailedUserAgent(values []string) string { + if len(values) == 0 { + return "" + } + result := make([]string, 0, len(values)) + for _, value := range values { + v := strings.TrimSpace(value) + if v == "" { + continue + } + result = append(result, v) + } + return strings.Join(result, " | ") +} + func snapshotCodexCLIOnlyHeaders(header http.Header) map[string]string { if len(header) == 0 { return nil diff --git a/backend/internal/service/openai_gateway_service_codex_cli_only_test.go b/backend/internal/service/openai_gateway_service_codex_cli_only_test.go index 3d7caf8b..ed6b1167 100644 --- a/backend/internal/service/openai_gateway_service_codex_cli_only_test.go +++ b/backend/internal/service/openai_gateway_service_codex_cli_only_test.go @@ -103,7 +103,7 @@ func TestLogCodexCLIOnlyDetection_NilSafety(t *testing.T) { }) } -func TestLogCodexCLIOnlyDetection_LogsBothMatchedAndRejected(t *testing.T) { +func TestLogCodexCLIOnlyDetection_OnlyLogsRejected(t *testing.T) { logSink, restore := captureStructuredLog(t) defer restore() @@ -119,7 +119,7 @@ func TestLogCodexCLIOnlyDetection_LogsBothMatchedAndRejected(t *testing.T) { Reason: CodexClientRestrictionReasonNotMatchedUA, }, nil) - require.True(t, logSink.ContainsMessage("OpenAI codex_cli_only 允许官方客户端请求")) + require.False(t, logSink.ContainsMessage("OpenAI codex_cli_only 允许官方客户端请求")) require.True(t, logSink.ContainsMessage("OpenAI codex_cli_only 拒绝非官方客户端请求")) } @@ -131,7 +131,8 @@ func TestLogCodexCLIOnlyDetection_RejectedIncludesRequestDetails(t *testing.T) { rec := httptest.NewRecorder() c, _ := gin.CreateTestContext(rec) c.Request = httptest.NewRequest(http.MethodPost, "/v1/responses?trace=1", bytes.NewReader(nil)) - c.Request.Header.Set("User-Agent", "curl/8.0") + c.Request.Header.Add("User-Agent", "curl/8.0") + c.Request.Header.Add("User-Agent", "Codex/1.2.3 (cli)") c.Request.Header.Set("Content-Type", "application/json") c.Request.Header.Set("OpenAI-Beta", "assistants=v2") @@ -143,7 +144,7 @@ func TestLogCodexCLIOnlyDetection_RejectedIncludesRequestDetails(t *testing.T) { Reason: CodexClientRestrictionReasonNotMatchedUA, }, body) - require.True(t, logSink.ContainsFieldValue("request_user_agent", "curl/8.0")) + require.True(t, logSink.ContainsFieldValue("request_user_agent", "curl/8.0 | Codex/1.2.3 (cli)")) require.True(t, logSink.ContainsFieldValue("request_model", "gpt-5.2")) require.True(t, logSink.ContainsFieldValue("request_query", "trace=1")) require.True(t, logSink.ContainsFieldValue("request_prompt_cache_key_sha256", hashSensitiveValueForLog("pc-123")))