package middleware import ( "bytes" "io" "strings" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) // LogAnthropicRequest creates a middleware that logs detailed debug info for Anthropic requests. // It logs headers (masking sensitive ones) and a preview of the request body. func LogAnthropicRequest() gin.HandlerFunc { return func(c *gin.Context) { path := c.Request.URL.Path method := c.Request.Method userAgent := c.GetHeader("User-Agent") // Check if it's Claude Code isClaudeCode := strings.Contains(userAgent, "claude-code") || strings.Contains(userAgent, "claude-cli") fields := log.Fields{ "prefix": "CLAUDE_CODE_AUTH_DEBUG", "method": method, "path": path, "user_agent": userAgent, "is_claude_code": isClaudeCode, } // Log Headers (masked) headers := make(map[string]string) for k, v := range c.Request.Header { if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "x-api-key") { headers[k] = "[MASKED]" } else { headers[k] = strings.Join(v, ";") } } fields["headers"] = headers // Peek Body var bodyBytes []byte if c.Request.Body != nil { bodyBytes, _ = io.ReadAll(c.Request.Body) c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) previewLen := 200 if len(bodyBytes) < previewLen { previewLen = len(bodyBytes) } fields["body_preview"] = string(bodyBytes[:previewLen]) } log.WithFields(fields).Debug("Incoming Anthropic Request") c.Next() } }