| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- package service
- import (
- "net/http"
- "strings"
- "github.com/gin-gonic/gin"
- "github.com/Wei-Shaw/sub2api/internal/pkg/tlsfingerprint"
- "github.com/Wei-Shaw/sub2api/internal/pkg/xai"
- )
- // Fixed CLI identity aliases — single source of truth is internal/pkg/xai.
- const (
- grokClientVersionHeader = xai.CLIStableVersion
- grokClientIdentifierHeader = xai.CLIClientIdentifier
- grokClientModeHeader = xai.CLIClientMode
- )
- // defaultGrokUpstreamUserAgent is the pinned Grok CLI / workspace UA.
- // Grok upstream must not forward Claude Code / Codex / browser client UAs.
- func defaultGrokUpstreamUserAgent() string {
- return xai.CLIUserAgent(xai.ResolveCLIVersion())
- }
- func applyDefaultGrokUpstreamHeaders(req *http.Request) {
- if req == nil {
- return
- }
- // Always stamp CLI identity. Do not preserve inbound client UA (Claude Code,
- // Codex, curl, etc.) — xAI chat/CLI surfaces fingerprint the client string.
- req.Header.Set("User-Agent", defaultGrokUpstreamUserAgent())
- req.Header.Set("x-grok-client-version", xai.ResolveCLIVersion())
- req.Header.Set("x-grok-client-identifier", grokClientIdentifierHeader)
- }
- func applyGrokTLSProfileHeaders(req *http.Request, profile *tlsfingerprint.Profile) {
- // HEAD Profile is TLS-only (no HTTP UserAgent/Originator fields). Always stamp CLI identity.
- applyDefaultGrokUpstreamHeaders(req)
- _ = profile
- }
- // openAITLSFingerprintRuntime is the resolved TLS fingerprint routing result
- // used by OpenAI/Grok outbound header application. Defined here so Grok header
- // helpers compile even when the full OpenAI TLS router is not present on HEAD.
- type openAITLSFingerprintRuntime struct {
- Profile *tlsfingerprint.Profile
- UpstreamUserAgent string
- UpstreamOriginator string
- Matched bool
- }
- func applyGrokRuntimeHeaders(req *http.Request, runtime openAITLSFingerprintRuntime) {
- applyDefaultGrokUpstreamHeaders(req)
- if req == nil {
- return
- }
- // Apply Originator only; force CLI UA after so router overrides cannot
- // leak Codex/Claude Code identity onto Grok upstream.
- if originator := strings.TrimSpace(runtime.UpstreamOriginator); originator != "" {
- req.Header.Set("Originator", originator)
- }
- req.Header.Set("User-Agent", defaultGrokUpstreamUserAgent())
- }
- // resolveGrokUpstreamUserAgent always returns the pinned Grok CLI User-Agent.
- // Inbound client UAs (Claude Code, Codex, browsers, libraries) are never forwarded.
- func resolveGrokUpstreamUserAgent(_ *gin.Context) string {
- return defaultGrokUpstreamUserAgent()
- }
|