// Package misc provides miscellaneous utility functions for the CLI Proxy API server.// It includes helper functions for HTTP header manipulation and other common operations// that don't fit into more specific packages.package miscimport ( "net/http" "strings")// ScrubProxyAndFingerprintHeaders removes all headers that could reveal// proxy infrastructure, client identity, or browser fingerprints from an// outgoing request. This ensures requests to upstream services look like they// originate directly from a native client rather than a third-party client// behind a reverse proxy.func ScrubProxyAndFingerprintHeaders(req *http.Request) { if req == nil { return } // --- Proxy tracing headers --- req.Header.Del("X-Forwarded-For") req.Header.Del("X-Forwarded-Host") req.Header.Del("X-Forwarded-Proto") req.Header.Del("X-Forwarded-Port") req.Header.Del("X-Real-IP") req.Header.Del("Forwarded") req.Header.Del("Via") // --- Client identity headers --- req.Header.Del("X-Title") req.Header.Del("X-Stainless-Lang") req.Header.Del("X-Stainless-Package-Version") req.Header.Del("X-Stainless-Os") req.Header.Del("X-Stainless-Arch") req.Header.Del("X-Stainless-Runtime") req.Header.Del("X-Stainless-Runtime-Version") req.Header.Del("Http-Referer") req.Header.Del("Referer") // --- Browser / Chromium fingerprint headers --- // These are sent by Electron-based clients (e.g. CherryStudio) using the // Fetch API, but NOT by Node.js https module (which Antigravity uses). req.Header.Del("Sec-Ch-Ua") req.Header.Del("Sec-Ch-Ua-Mobile") req.Header.Del("Sec-Ch-Ua-Platform") req.Header.Del("Sec-Fetch-Mode") req.Header.Del("Sec-Fetch-Site") req.Header.Del("Sec-Fetch-Dest") req.Header.Del("Priority") // --- Encoding negotiation --- // Antigravity (Node.js) sends "gzip, deflate, br" by default; // Electron-based clients may add "zstd" which is a fingerprint mismatch. req.Header.Del("Accept-Encoding")}// EnsureHeader ensures that a header exists in the target header map by checking// multiple sources in order of priority: source headers, existing target headers,// and finally the default value. It only sets the header if it's not already present// and the value is not empty after trimming whitespace.//// Parameters:// - target: The target header map to modify// - source: The source header map to check first (can be nil)// - key: The header key to ensure// - defaultValue: The default value to use if no other source provides a valuefunc EnsureHeader(target http.Header, source http.Header, key, defaultValue string) { if target == nil { return } if source != nil { if val := strings.TrimSpace(source.Get(key)); val != "" { target.Set(key, val) return } } if strings.TrimSpace(target.Get(key)) != "" { return } if val := strings.TrimSpace(defaultValue); val != "" { target.Set(key, val) }}
// Package misc provides miscellaneous utility functions for the CLI Proxy API server.
// It includes helper functions for HTTP header manipulation and other common operations
// that don't fit into more specific packages.
package misc
import (
"net/http"
"strings"
)
// ScrubProxyAndFingerprintHeaders removes all headers that could reveal
// proxy infrastructure, client identity, or browser fingerprints from an
// outgoing request. This ensures requests to upstream services look like they
// originate directly from a native client rather than a third-party client
// behind a reverse proxy.
func ScrubProxyAndFingerprintHeaders(req *http.Request) {
if req == nil {
return
}
// --- Proxy tracing headers ---
req.Header.Del("X-Forwarded-For")
req.Header.Del("X-Forwarded-Host")
req.Header.Del("X-Forwarded-Proto")
req.Header.Del("X-Forwarded-Port")
req.Header.Del("X-Real-IP")
req.Header.Del("Forwarded")
req.Header.Del("Via")
// --- Client identity headers ---
req.Header.Del("X-Title")
req.Header.Del("X-Stainless-Lang")
req.Header.Del("X-Stainless-Package-Version")
req.Header.Del("X-Stainless-Os")
req.Header.Del("X-Stainless-Arch")
req.Header.Del("X-Stainless-Runtime")
req.Header.Del("X-Stainless-Runtime-Version")
req.Header.Del("Http-Referer")
req.Header.Del("Referer")
// --- Browser / Chromium fingerprint headers ---
// These are sent by Electron-based clients (e.g. CherryStudio) using the
// Fetch API, but NOT by Node.js https module (which Antigravity uses).
req.Header.Del("Sec-Ch-Ua")
req.Header.Del("Sec-Ch-Ua-Mobile")
req.Header.Del("Sec-Ch-Ua-Platform")
req.Header.Del("Sec-Fetch-Mode")
req.Header.Del("Sec-Fetch-Site")
req.Header.Del("Sec-Fetch-Dest")
req.Header.Del("Priority")
// --- Encoding negotiation ---
// Antigravity (Node.js) sends "gzip, deflate, br" by default;
// Electron-based clients may add "zstd" which is a fingerprint mismatch.
req.Header.Del("Accept-Encoding")
}
// EnsureHeader ensures that a header exists in the target header map by checking
// multiple sources in order of priority: source headers, existing target headers,
// and finally the default value. It only sets the header if it's not already present
// and the value is not empty after trimming whitespace.
//
// Parameters:
// - target: The target header map to modify
// - source: The source header map to check first (can be nil)
// - key: The header key to ensure
// - defaultValue: The default value to use if no other source provides a value
func EnsureHeader(target http.Header, source http.Header, key, defaultValue string) {
if target == nil {
return
}
if source != nil {
if val := strings.TrimSpace(source.Get(key)); val != "" {
target.Set(key, val)
return
}
}
if strings.TrimSpace(target.Get(key)) != "" {
return
}
if val := strings.TrimSpace(defaultValue); val != "" {
target.Set(key, val)
}
}