Documentation
¶
Index ¶
- func ApplySignatureAlgorithms(exts []tls.TLSExtension, algs []tls.SignatureScheme)
- func Available() []string
- func AvailableWithInfo() map[string]PresetInfo
- func ClientHelloIDName(id tls.ClientHelloID) (string, bool)
- func DefaultPriorityTable() map[string]ResourcePriority
- func Describe(name string) (string, error)
- func JA3HasExtension(ja3, extID string) bool
- func ParseJA3(ja3 string, extras *JA3Extras) (*tls.ClientHelloSpec, error)
- func PriorityFromUrgency(urgency uint8) uint16
- func PriorityHeaderFromResource(rp ResourcePriority) string
- func Register(name string, preset *Preset)
- func RegisterStrict(name string, preset *Preset) error
- func ResolveClientHelloID(name string) (tls.ClientHelloID, error)
- func SpecFor(id tls.ClientHelloID, seed int64, sigAlgs []tls.SignatureScheme) (*tls.ClientHelloSpec, error)
- func Unregister(name string)
- type AkamaiPresence
- type ClientHints
- type ClientHintsProfile
- type ClientHintsSpec
- type FetchDest
- type FetchMode
- type FetchSite
- type H2FingerprintConfig
- type H3FingerprintConfig
- type HTTP2SettingSpec
- type HTTP2Settings
- type HTTP2Spec
- type HTTP3Spec
- type HeaderCoherence
- type HeaderPair
- type HeaderPairSpec
- type HeaderSpec
- type JA3Extras
- type JA3ExtrasSpec
- type PlatformInfo
- type PoolSpec
- type PoolStrategy
- type Preset
- func AndroidChrome143() *Preset
- func AndroidChrome144() *Preset
- func AndroidChrome145() *Preset
- func AndroidChrome146() *Preset
- func AndroidChrome147() *Preset
- func AndroidChrome148() *Preset
- func AndroidChrome150() *Preset
- func BuildPreset(spec *PresetSpec) (*Preset, error)
- func Chrome133() *Preset
- func Chrome141() *Preset
- func Chrome143() *Preset
- func Chrome143Linux() *Preset
- func Chrome143Windows() *Preset
- func Chrome143macOS() *Preset
- func Chrome144() *Preset
- func Chrome144Linux() *Preset
- func Chrome144Windows() *Preset
- func Chrome144macOS() *Preset
- func Chrome145() *Preset
- func Chrome145Linux() *Preset
- func Chrome145Windows() *Preset
- func Chrome145macOS() *Preset
- func Chrome146() *Preset
- func Chrome146Linux() *Preset
- func Chrome146Windows() *Preset
- func Chrome146macOS() *Preset
- func Chrome147() *Preset
- func Chrome147Linux() *Preset
- func Chrome147Windows() *Preset
- func Chrome147macOS() *Preset
- func Chrome148() *Preset
- func Chrome148Linux() *Preset
- func Chrome148Windows() *Preset
- func Chrome148macOS() *Preset
- func Chrome149() *Preset
- func Chrome149Linux() *Preset
- func Chrome149Windows() *Preset
- func Chrome149macOS() *Preset
- func Chrome150() *Preset
- func Chrome150Linux() *Preset
- func Chrome150Windows() *Preset
- func Chrome150macOS() *Preset
- func Firefox133() *Preset
- func Firefox148() *Preset
- func Get(name string) *Preset
- func GetStrict(name string) *Preset
- func IOSChrome143() *Preset
- func IOSChrome144() *Preset
- func IOSChrome145() *Preset
- func IOSChrome146() *Preset
- func IOSChrome147() *Preset
- func IOSChrome148() *Preset
- func IOSChrome150() *Preset
- func IOSSafari17() *Preset
- func IOSSafari18() *Preset
- func LoadAndBuildPreset(path string) (*Preset, error)
- func LoadAndBuildPresetFromJSON(data []byte) (*Preset, error)
- func LookupCustom(name string) *Preset
- func Safari18() *Preset
- func (p *Preset) H2DisableCookieSplit() bool
- func (p *Preset) H2HPACKIndexingPolicy() string
- func (p *Preset) H2HPACKNeverIndex() []string
- func (p *Preset) H2HasPriorityTable() bool
- func (p *Preset) H2HeaderOrder() []string
- func (p *Preset) H2PriorityFor(dest string) (weight uint16, exclusive bool, headerValue string, ok bool)
- func (p *Preset) H2PseudoHeaderOrder() []string
- func (p *Preset) H2SettingsOrder() []uint16
- func (p *Preset) H2StreamPriorityMode() string
- func (p *Preset) H3EnableDatagrams() bool
- func (p *Preset) H3MaxFieldSectionSize() uint64
- func (p *Preset) H3MaxResponseHeaderBytes() uint64
- func (p *Preset) H3QPACKBlockedStreams() uint64
- func (p *Preset) H3QPACKMaxTableCapacity() uint64
- func (p *Preset) H3QUICAllow0RTT() bool
- func (p *Preset) H3QUICChromeStyleInitial() bool
- func (p *Preset) H3QUICConnectionIDLength() int
- func (p *Preset) H3QUICDisableHelloScramble() bool
- func (p *Preset) H3QUICInitialConnectionReceiveWindow() uint64
- func (p *Preset) H3QUICInitialPacketSize() uint16
- func (p *Preset) H3QUICInitialStreamReceiveWindow() uint64
- func (p *Preset) H3QUICMaxDatagramFrameSize() uint64
- func (p *Preset) H3QUICMaxIncomingStreams() int64
- func (p *Preset) H3QUICMaxIncomingUniStreams() int64
- func (p *Preset) H3QUICTransportParamOrder() string
- func (p *Preset) H3SendGreaseFrames() bool
- func (p *Preset) ResolveClientHints() ClientHints
- type PresetFile
- type PresetInfo
- type PresetPool
- type PresetSpec
- type ProtocolSpec
- type RequestContext
- func FontContext(referrer, targetURL string) RequestContext
- func ImageContext(referrer, targetURL string) RequestContext
- func NavigationContext() RequestContext
- func ScriptContext(referrer, targetURL string) RequestContext
- func StyleContext(referrer, targetURL string) RequestContext
- func XHRContext(referrer, targetURL string) RequestContext
- type ResourcePriority
- type ResourcePrioritySpec
- type SecFetchHeaders
- type TCPFingerprint
- type TCPSpec
- type TLSSpec
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplySignatureAlgorithms ¶ added in v1.6.8
func ApplySignatureAlgorithms(exts []tls.TLSExtension, algs []tls.SignatureScheme)
ApplySignatureAlgorithms replaces the signature_algorithms extension's list in exts with algs when algs is non-empty. It operates on the shared []TLSExtension slice, so the ClientHelloID-direct path (H1, mutating a live UConn's Extensions) and the generated-spec path (H2/H3) use one override.
func AvailableWithInfo ¶ added in v1.6.0
func AvailableWithInfo() map[string]PresetInfo
AvailableWithInfo returns a map of preset names to their supported protocols.
func ClientHelloIDName ¶ added in v1.6.5
func ClientHelloIDName(id tls.ClientHelloID) (string, bool)
ClientHelloIDName returns the canonical string name for a utls ClientHelloID. Suitable for round-trip JSON via Describe. Concrete names are preferred over "-auto" aliases that resolve to the same (Client, Version) pair.
Returns ("", false) for the zero-value ID and for IDs not registered in clientHelloIDs (e.g., randomized variants or hand-built IDs).
func DefaultPriorityTable ¶ added in v1.6.5
func DefaultPriorityTable() map[string]ResourcePriority
DefaultPriorityTable returns a copy of the package-level default priority table. Callers can use this as a starting point when constructing custom per-preset tables, or to inspect the values that will be emitted for presets that don't define their own.
The returned map is a fresh copy; mutating it does not affect future preset lookups.
func Describe ¶ added in v1.6.5
Describe returns a fully-resolved JSON dump of a preset's effective state.
All inheritance is flattened (no based_on in output). Default values produced by H2Config / H3Config getters are emitted explicitly, so a preset built with H2Config=nil and one built with H2Config set to the equivalent Chrome defaults describe to byte-identical JSON.
The result is suitable for round-tripping through LoadAndBuildPresetFromJSON to reconstruct an equivalent preset:
JSON1 := Describe(name) p, _ := LoadAndBuildPresetFromJSON([]byte(JSON1)) Register(p.Name, p) JSON2 := Describe(p.Name) // JSON1 == JSON2 byte-for-byte
Returns an error if the preset is not registered or if it references a utls ClientHelloID that is not in the canonical name registry.
func JA3HasExtension ¶ added in v1.6.5
JA3HasExtension checks if a JA3 string contains a specific TLS extension ID. The extensions field is the third comma-separated part, with dash-separated IDs.
func ParseJA3 ¶ added in v1.6.1
func ParseJA3(ja3 string, extras *JA3Extras) (*tls.ClientHelloSpec, error)
ParseJA3 parses a JA3 fingerprint string into a *tls.ClientHelloSpec. Format: TLSVersion,CipherSuites,Extensions,EllipticCurves,PointFormats Fields use dash-separated decimal values. If extras is nil, sensible defaults (matching modern Chrome) are used.
func PriorityFromUrgency ¶ added in v1.6.5
PriorityFromUrgency converts an RFC 9218 urgency value into the RFC 7540 stream weight Chrome emits on the H2 HEADERS frame. Verified against Chrome 147 captures for urgency 0–4; the formula extrapolates linearly for 5–7 (Chrome doesn't emit those values in practice).
Formula: weight = 256 - (urgency * 73) / 2 (integer division).
Mapping: 0→256, 1→220, 2→183, 3→147, 4→110, 5→74, 6→37, 7→1.
The returned weight is the *effective* weight (1–256). Wire format uses weight-1; conversion happens at the transport boundary.
func PriorityHeaderFromResource ¶ added in v1.6.5
func PriorityHeaderFromResource(rp ResourcePriority) string
PriorityHeaderFromResource renders the RFC 9218 priority: HTTP header value for a ResourcePriority, applying Chrome's emission rules:
urgency=3 (default) + !incremental → "" (omit the header) urgency=3 (default) + incremental → "i" urgency≠3 + !incremental → "u=N" urgency≠3 + incremental → "u=N, i"
EmitHeader=false short-circuits to "" regardless of urgency/incremental (Chrome's async/defer-script behaviour). Caller must skip injection when the result is empty.
func Register ¶ added in v1.6.5
Register adds a custom preset to the registry. It will be found by Get(). Nil presets are ignored. Silently overwrites any existing entry with the same name — use RegisterStrict to surface name collisions instead.
func RegisterStrict ¶ added in v1.6.5
RegisterStrict adds a custom preset to the registry but errors out if the name is already taken — by another custom preset OR by a built-in. JSON loader paths use this so that user-supplied specs can't accidentally shadow a shipped preset like "chrome-latest". Callers who want to update a registered preset should call Unregister(name) first.
func ResolveClientHelloID ¶ added in v1.6.5
func ResolveClientHelloID(name string) (tls.ClientHelloID, error)
ResolveClientHelloID resolves a string name to a utls ClientHelloID. Names use lowercase-hyphenated convention (e.g., "chrome-146-windows").
func SpecFor ¶ added in v1.6.8
func SpecFor(id tls.ClientHelloID, seed int64, sigAlgs []tls.SignatureScheme) (*tls.ClientHelloSpec, error)
SpecFor generates the uTLS ClientHelloSpec for id at the given shuffle seed and overrides its signature_algorithms with sigAlgs (a no-op when sigAlgs is empty, so a stock preset keeps its byte-exact base). Callers pass the TCP list (Preset.SignatureAlgorithms) or the QUIC list (Preset.QUICSignatureAlgorithms). A drop-in replacement for tls.UTLSIdToSpecWithSeed so every transport spec path (H2/H3, fresh and PSK) can share one override point.
func Unregister ¶ added in v1.6.5
func Unregister(name string)
Unregister removes a custom preset from the registry.
Types ¶
type AkamaiPresence ¶ added in v1.6.5
type AkamaiPresence struct {
Settings *HTTP2Settings
PseudoOrder []string
SeenSettings map[uint16]bool // SETTINGS IDs that appeared in the string
HasWindowUpdate bool // WINDOW_UPDATE field had a value
HasStreamWeight bool // PRIORITY field had a non-zero weight
}
AkamaiPresence reports which fields a parsed Akamai shorthand actually specified, so callers can distinguish "set to value X" from "absent / default zero". Without this distinction, applyHTTP2 cannot tell whether to let the akamai value override an inherited discrete-field value.
func ParseAkamaiDetailed ¶ added in v1.6.5
func ParseAkamaiDetailed(akamai string) (*AkamaiPresence, error)
ParseAkamaiDetailed parses an Akamai shorthand and reports which fields were actually present. The plain ParseAkamai delegates to this. Callers that need to overlay an akamai shorthand on top of inherited / discrete fields use this so they only override the slots the shorthand specifies.
type ClientHints ¶ added in v1.0.1
type ClientHints struct {
// Low-entropy hints (always sent by Chrome)
UA string // Sec-Ch-Ua
UAMobile string // Sec-Ch-Ua-Mobile
UAPlatform string // Sec-Ch-Ua-Platform
// High-entropy hints (only sent after Accept-CH)
UAArch string // Sec-Ch-Ua-Arch
UABitness string // Sec-Ch-Ua-Bitness
UAFullVersionList string // Sec-Ch-Ua-Full-Version-List
UAModel string // Sec-Ch-Ua-Model
UAPlatformVersion string // Sec-Ch-Ua-Platform-Version
UAWow64 string // Sec-Ch-Ua-Wow64
}
ClientHints contains browser client hint headers
func GenerateClientHints
deprecated
added in
v1.0.1
func GenerateClientHints(chromeVersion string, platform PlatformInfo, includeHighEntropy bool) ClientHints
GenerateClientHints generates client hint headers for Chrome.
Deprecated: this builds the hints from a bare version + platform and so cannot keep the GREASE brand token / order in sync with a preset's sec-ch-ua. It is no longer used in production. Use Preset.ResolveClientHints, which derives coherent hints from the preset itself.
type ClientHintsProfile ¶ added in v1.6.8
type ClientHintsProfile struct {
FullVersionList string // sec-ch-ua-full-version-list; "" -> derived from sec-ch-ua (brands/order/GREASE preserved, versions expanded)
PlatformVersion string // sec-ch-ua-platform-version override; "" -> platform default (Linux is "")
Arch string // sec-ch-ua-arch; "" -> platform default
Bitness string // sec-ch-ua-bitness; "" -> platform default
Model string // sec-ch-ua-model; "" -> platform default (desktop is "")
Wow64 string // sec-ch-ua-wow64; "" -> "?0"
}
ClientHintsProfile holds preset-level values for the high-entropy UA client hints (the ones Chrome only sends after a host advertises Accept-CH). Every field is optional: an empty field is derived coherently from the preset's low-entropy sec-ch-ua trio and platform (see Preset.ResolveClientHints), so a preset only needs to spell out what differs from the coherent default. This is the single source of truth that keeps full-version-list, arch, platform-version etc. in lockstep with sec-ch-ua + User-Agent.
type ClientHintsSpec ¶ added in v1.6.8
type ClientHintsSpec struct {
FullVersionList string `json:"full_version_list,omitempty"` // sec-ch-ua-full-version-list (exact build from a real capture)
PlatformVersion string `json:"platform_version,omitempty"` // sec-ch-ua-platform-version override
Arch string `json:"arch,omitempty"` // sec-ch-ua-arch
Bitness string `json:"bitness,omitempty"` // sec-ch-ua-bitness
Model string `json:"model,omitempty"` // sec-ch-ua-model
Wow64 string `json:"wow64,omitempty"` // sec-ch-ua-wow64
}
ClientHintsSpec defines high-entropy UA client hint overrides for a preset. Every field is optional; an omitted field is derived from the sec-ch-ua trio (see Preset.ResolveClientHints) so a preset only needs to spell out what differs from the coherent default. Inherited via based_on like other blocks.
type FetchDest ¶ added in v1.0.1
type FetchDest string
FetchDest represents the Sec-Fetch-Dest header value
const ( FetchDestDocument FetchDest = "document" FetchDestEmbed FetchDest = "embed" FetchDestFont FetchDest = "font" FetchDestImage FetchDest = "image" FetchDestManifest FetchDest = "manifest" FetchDestMedia FetchDest = "media" FetchDestObject FetchDest = "object" FetchDestReport FetchDest = "report" FetchDestScript FetchDest = "script" FetchDestServiceWorker FetchDest = "serviceworker" FetchDestStyle FetchDest = "style" FetchDestWorker FetchDest = "worker" FetchDestXHR FetchDest = "empty" // XHR/fetch uses "empty" )
type FetchMode ¶ added in v1.0.1
type FetchMode string
FetchMode represents the Sec-Fetch-Mode header value
const ( FetchModeNavigate FetchMode = "navigate" // FetchModeCORS is for cross-origin requests (fetch API with CORS) FetchModeCORS FetchMode = "cors" // FetchModeNoCORS is for simple requests that don't trigger CORS FetchModeNoCORS FetchMode = "no-cors" // FetchModeSameOrigin is for same-origin requests FetchModeSameOrigin FetchMode = "same-origin" // FetchModeWebSocket is for WebSocket connections FetchModeWebSocket FetchMode = "websocket" )
type FetchSite ¶ added in v1.0.1
type FetchSite string
FetchSite represents the Sec-Fetch-Site header value
type H2FingerprintConfig ¶ added in v1.6.5
type H2FingerprintConfig struct {
HPACKHeaderOrder []string // HPACK wire encoding order. nil = Chrome 143 default.
HPACKIndexingPolicy string // "chrome"/"never"/"always"/"default". "" = "chrome".
HPACKNeverIndex []string // Headers never HPACK-indexed. nil = Chrome default.
StreamPriorityMode string // "chrome"/"default". "" = "chrome".
DisableCookieSplit *bool // nil = true (single field). Chrome+Firefox crumble (false); Safari single (true).
SettingsOrder []uint16 // H2 SETTINGS frame ID order. nil = dynamic from HTTP2Settings.
PseudoHeaderOrder []string // Pseudo-header order. nil = heuristic (Chrome m,a,s,p / Safari m,s,p,a).
// PriorityTable maps sec-fetch-dest values to RFC 7540 stream priorities and
// the matching RFC 9218 priority: header value. Populated for browsers (e.g.
// Chrome 147 desktop) that emit a different urgency per resource type.
//
// When nil, the transport uses HTTP2Settings.StreamWeight / StreamExclusive
// for every request — the legacy single-weight behaviour. When non-nil, the
// transport selects an entry based on the request's sec-fetch-dest header,
// derives the H2 wire weight from urgency via PriorityFromUrgency, and
// injects the priority: header per the RFC 9218 emission rules.
//
// Map keys are sec-fetch-dest values exactly as Chrome emits them
// ("document", "image", "script", "empty", etc.). Lookups are case-sensitive.
PriorityTable map[string]ResourcePriority
}
H2FingerprintConfig controls HTTP/2 fingerprinting behavior beyond SETTINGS frame values. When nil on a Preset, all getters return Chrome defaults. Individual nil/zero fields also fall back to Chrome defaults, so you can override just the fields you need.
type H3FingerprintConfig ¶ added in v1.6.5
type H3FingerprintConfig struct {
QPACKMaxTableCapacity *uint64 // nil = 65536 (Chrome). Safari heuristic fallback.
QPACKBlockedStreams *uint64 // nil = 100
MaxFieldSectionSize *uint64 // nil = 262144 (Chrome). 0 to omit (Safari).
EnableDatagrams *bool // nil = true (Chrome). Safari heuristic fallback.
QUICInitialPacketSize *uint16 // nil = 1250 (Chrome). MASQUE overrides to 1350.
QUICMaxIncomingStreams *int64 // nil = 100
QUICMaxIncomingUniStreams *int64 // nil = 103
QUICAllow0RTT *bool // nil = true
QUICChromeStyleInitial *bool // nil = true
QUICDisableHelloScramble *bool // nil = true
QUICTransportParamOrder string // "chrome"/"random". "" = "chrome".
QUICConnectionIDLength *int // nil = 0 (Chrome empty SCID). Firefox uses 8.
QUICMaxDatagramFrameSize *uint64 // nil = 65536 (Chrome). 0 to use quic-go default (16383).
MaxResponseHeaderBytes *uint64 // nil = 262144
SendGreaseFrames *bool // nil = true
// QUIC flow-control windows. quic-go translates these to wire transport
// parameters initial_max_data (4) and initial_max_stream_data_* (5/6/7).
// nil = quic-go default (~7.5 MB conn, ~512 KB stream). Safari/iOS Chrome
// uses larger conn (16 MB) and smaller per-stream (2 MB) — set both to
// match.
QUICInitialStreamReceiveWindow *uint64 // nil = quic-go default. iOS Chrome sends 2097152.
QUICInitialConnectionReceiveWindow *uint64 // nil = quic-go default. iOS Chrome sends 16777216.
}
H3FingerprintConfig controls HTTP/3 and QUIC fingerprinting behavior. When nil on a Preset, all getters return Chrome defaults (with Safari fallback for presets that have NoRFC7540Priorities set). Individual nil fields fall back to Chrome defaults independently.
type HTTP2SettingSpec ¶ added in v1.6.5
HTTP2SettingSpec represents a single HTTP/2 SETTINGS frame entry.
type HTTP2Settings ¶
type HTTP2Settings struct {
HeaderTableSize uint32
EnablePush bool
MaxConcurrentStreams uint32
InitialWindowSize uint32
MaxFrameSize uint32
MaxHeaderListSize uint32
// Window update and stream settings
ConnectionWindowUpdate uint32
StreamWeight uint16 // Chrome sends 255 on wire (set to 256, code does -1)
StreamExclusive bool
// RFC 9218 - disables RFC 7540 stream priorities
NoRFC7540Priorities bool
}
HTTP2Settings contains HTTP/2 connection settings
func ParseAkamai ¶ added in v1.6.1
func ParseAkamai(akamai string) (*HTTP2Settings, []string, error)
ParseAkamai parses an Akamai HTTP/2 fingerprint string into HTTP2Settings and pseudo-header order.
Format: SETTINGS|WINDOW_UPDATE|PRIORITY|PSEUDO_HEADER_ORDER
SETTINGS: semicolon-separated "id:value" pairs (e.g., "1:65536;3:1000;4:6291456") WINDOW_UPDATE: connection-level window update value PRIORITY: "weight" or "0" (stream weight; 0 means default/not sent) PSEUDO_HEADER_ORDER: comma-separated single-char pseudo-header identifiers
m = :method, a = :authority, s = :scheme, p = :path
Example (Chrome): "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p"
type HTTP2Spec ¶ added in v1.6.5
type HTTP2Spec struct {
// Akamai string (parsed first, then individual fields overlay)
Akamai string `json:"akamai,omitempty"`
// Individual SETTINGS fields (overlay on top of akamai if both set)
HeaderTableSize *uint32 `json:"header_table_size,omitempty"`
EnablePush *bool `json:"enable_push,omitempty"`
MaxConcurrentStreams *uint32 `json:"max_concurrent_streams,omitempty"`
InitialWindowSize *uint32 `json:"initial_window_size,omitempty"`
MaxFrameSize *uint32 `json:"max_frame_size,omitempty"`
MaxHeaderListSize *uint32 `json:"max_header_list_size,omitempty"`
ConnectionWindowUpdate *uint32 `json:"connection_window_update,omitempty"`
StreamWeight *uint16 `json:"stream_weight,omitempty"`
StreamExclusive *bool `json:"stream_exclusive,omitempty"`
NoRFC7540Priorities *bool `json:"no_rfc7540_priorities,omitempty"`
// H2 fingerprinting config
Settings []HTTP2SettingSpec `json:"settings,omitempty"`
SettingsOrder []uint16 `json:"settings_order,omitempty"`
PseudoOrder []string `json:"pseudo_order,omitempty"`
// HPACK config
HPACKHeaderOrder []string `json:"hpack_header_order,omitempty"`
HPACKIndexingPolicy *string `json:"hpack_indexing_policy,omitempty"` // "chrome","never","always","default"
HPACKNeverIndex []string `json:"hpack_never_index,omitempty"`
StreamPriorityMode *string `json:"stream_priority_mode,omitempty"` // "chrome","default"
DisableCookieSplit *bool `json:"disable_cookie_split,omitempty"`
// PriorityTable maps sec-fetch-dest values to per-resource priority
// settings. When populated, the transport emits a per-request RFC 7540
// stream weight (derived from urgency) and RFC 9218 priority: header
// for each request based on its sec-fetch-dest. When omitted, the
// preset's static StreamWeight / StreamExclusive is used for every
// request (legacy single-weight behaviour).
PriorityTable map[string]ResourcePrioritySpec `json:"priority_table,omitempty"`
}
HTTP2Spec defines HTTP/2 fingerprint configuration.
type HTTP3Spec ¶ added in v1.6.5
type HTTP3Spec struct {
QPACKMaxTableCapacity *uint64 `json:"qpack_max_table_capacity,omitempty"`
QPACKBlockedStreams *uint64 `json:"qpack_blocked_streams,omitempty"`
MaxFieldSectionSize *uint64 `json:"max_field_section_size,omitempty"`
EnableDatagrams *bool `json:"enable_datagrams,omitempty"`
QUICInitialPacketSize *uint16 `json:"quic_initial_packet_size,omitempty"`
QUICMaxIncomingStreams *int64 `json:"quic_max_incoming_streams,omitempty"`
QUICMaxIncomingUniStreams *int64 `json:"quic_max_incoming_uni_streams,omitempty"`
QUICAllow0RTT *bool `json:"quic_allow_0rtt,omitempty"`
QUICChromeStyleInitial *bool `json:"quic_chrome_style_initial,omitempty"`
QUICDisableHelloScramble *bool `json:"quic_disable_hello_scramble,omitempty"`
QUICTransportParamOrder *string `json:"quic_transport_param_order,omitempty"` // "chrome","random"
QUICConnectionIDLength *int `json:"quic_connection_id_length,omitempty"`
QUICMaxDatagramFrameSize *uint64 `json:"quic_max_datagram_frame_size,omitempty"`
MaxResponseHeaderBytes *uint64 `json:"max_response_header_bytes,omitempty"`
SendGreaseFrames *bool `json:"send_grease_frames,omitempty"`
// QUIC flow-control windows. These map to quic.Config fields and ultimately
// to wire transport parameters initial_max_data (4) and initial_max_stream_data_*
// (5/6/7). nil = quic-go default. iOS Chrome / Safari uses larger conn (16 MiB)
// + smaller per-stream (2 MiB) than Chrome desktop.
QUICInitialStreamReceiveWindow *uint64 `json:"quic_initial_stream_receive_window,omitempty"`
QUICInitialConnectionReceiveWindow *uint64 `json:"quic_initial_connection_receive_window,omitempty"`
}
HTTP3Spec defines HTTP/3 and QUIC fingerprint configuration.
type HeaderCoherence ¶ added in v1.0.1
type HeaderCoherence struct {
// contains filtered or unexported fields
}
HeaderCoherence provides methods for generating coherent request headers
func NewHeaderCoherence ¶ added in v1.0.1
func NewHeaderCoherence(preset *Preset) *HeaderCoherence
NewHeaderCoherence creates a new HeaderCoherence helper
func (*HeaderCoherence) ApplyToHeaders ¶ added in v1.0.1
func (h *HeaderCoherence) ApplyToHeaders(headers map[string]string, ctx RequestContext)
ApplyToHeaders applies coherent headers to the given header map
func (*HeaderCoherence) GenerateNavigationHeaders ¶ added in v1.0.1
func (h *HeaderCoherence) GenerateNavigationHeaders() map[string]string
GenerateNavigationHeaders returns complete headers for page navigation
func (*HeaderCoherence) GenerateXHRHeaders ¶ added in v1.0.1
func (h *HeaderCoherence) GenerateXHRHeaders(referrer, targetURL string) map[string]string
GenerateXHRHeaders returns complete headers for XHR/fetch requests
type HeaderPair ¶ added in v1.1.1
HeaderPair represents a single header key-value pair for ordered headers
type HeaderPairSpec ¶ added in v1.6.5
HeaderPairSpec is a key-value pair for ordered headers in JSON.
type HeaderSpec ¶ added in v1.6.5
type HeaderSpec struct {
UserAgent string `json:"user_agent,omitempty"`
Values map[string]string `json:"values,omitempty"`
Order []HeaderPairSpec `json:"order,omitempty"`
}
HeaderSpec defines header fingerprint configuration.
type JA3Extras ¶ added in v1.6.1
type JA3Extras struct {
SignatureAlgorithms []tls.SignatureScheme
DelegatedCredentialAlgorithms []tls.SignatureScheme // for ext 34; nil = Chrome defaults
ALPN []string
CertCompAlgs []tls.CertCompressionAlgo
PermuteExtensions bool
RecordSizeLimit uint16 // default: 0x4001
}
JA3Extras provides extension data that JA3 cannot capture. JA3 only encodes extension IDs, not the data within them.
type JA3ExtrasSpec ¶ added in v1.6.5
type JA3ExtrasSpec struct {
SignatureAlgorithms []uint16 `json:"signature_algorithms,omitempty"`
DelegatedCredentialAlgorithms []uint16 `json:"delegated_credential_algorithms,omitempty"`
ALPN []string `json:"alpn,omitempty"`
CertCompression []string `json:"cert_compression,omitempty"`
PermuteExtensions *bool `json:"permute_extensions,omitempty"`
RecordSizeLimit *uint16 `json:"record_size_limit,omitempty"`
}
JA3ExtrasSpec is the JSON representation of JA3Extras.
type PlatformInfo ¶
type PlatformInfo struct {
UserAgentOS string // e.g., "(Windows NT 10.0; Win64; x64)" or "(X11; Linux x86_64)"
Platform string // e.g., "Windows", "Linux", "macOS"
Arch string // e.g., "x86", "arm"
PlatformVersion string // e.g., "10.0.0", "6.12.0", "14.7.0"
FirefoxUserAgentOS string // Firefox has slightly different format
}
PlatformInfo contains platform-specific header values
func GetPlatformInfo ¶
func GetPlatformInfo() PlatformInfo
GetPlatformInfo returns platform-specific info based on runtime OS
type PoolSpec ¶ added in v1.6.5
type PoolSpec struct {
Name string `json:"name"`
Strategy string `json:"strategy"` // "random" or "round-robin"
Presets []PresetSpec `json:"presets"`
}
PoolSpec defines a pool of presets for rotation.
type PoolStrategy ¶ added in v1.6.5
type PoolStrategy int
PoolStrategy determines how presets are selected from a pool.
const ( // PoolRandom selects a random preset each time. PoolRandom PoolStrategy = iota // PoolRoundRobin cycles through presets sequentially. PoolRoundRobin )
type Preset ¶
type Preset struct {
Name string
ClientHelloID tls.ClientHelloID // For TCP/TLS (HTTP/1.1, HTTP/2)
PSKClientHelloID tls.ClientHelloID // For TCP/TLS with PSK (session resumption)
QUICClientHelloID tls.ClientHelloID // For QUIC/HTTP/3 (different TLS extensions)
QUICPSKClientHelloID tls.ClientHelloID // For QUIC/HTTP/3 with PSK (session resumption)
UserAgent string
Headers map[string]string // For backward compatibility
HeaderOrder []HeaderPair // Ordered headers for HTTP/2
ClientHints ClientHintsProfile // High-entropy UA client hint overrides; empty fields are derived from sec-ch-ua (see Preset.ResolveClientHints)
HTTP2Settings HTTP2Settings
TCPFingerprint TCPFingerprint
SupportHTTP3 bool
DisableHTTP2 bool // When true, auto mode skips HTTP/2 and goes straight to HTTP/1.1 (zero value = H2 enabled)
H2Config *H2FingerprintConfig // nil = Chrome defaults for all H2 fingerprinting
H3Config *H3FingerprintConfig // nil = Chrome defaults for all H3/QUIC fingerprinting
JA3 string // JA3 fingerprint string. When set, parsed fresh per connection instead of using ClientHelloID.
JA3Extras *JA3Extras // Supplements JA3 parsing. nil = Chrome defaults.
BasedOn string // For custom presets: name of the parent preset (used by inheritance-loop detection). Empty for built-ins.
// SignatureAlgorithms, when non-empty, replaces the signature_algorithms
// extension emitted on TCP (HTTP/1.1 + HTTP/2), on top of whatever base spec
// the ClientHelloID (or JA3) produces. It lets a preset keep a byte-exact
// hand-tuned base spec (correct ALPS/ECH/key_share/GREASE ordering) while
// changing ONLY the sig-algs — e.g. adding Chrome 150's ML-DSA post-quantum
// codepoints (0x0904-0x0906) on top of the Chrome 146 base. Values are raw
// SignatureScheme (uint16) codepoints, so schemes uTLS has no named constant
// for (like ML-DSA) are still emitted verbatim.
SignatureAlgorithms []tls.SignatureScheme
// QUICSignatureAlgorithms is the HTTP/3 (QUIC) counterpart of
// SignatureAlgorithms. It is separate because a browser's QUIC ClientHello can
// advertise a DIFFERENT sig-algs set than its TCP one — e.g. Chrome 150 sends
// ML-DSA on TCP but NOT on QUIC (QUIC anti-amplification limits make large PQ
// certificate chains impractical), and adds rsa_pkcs1_sha1 there instead.
// Empty = leave the QUIC base ClientHelloID untouched.
QUICSignatureAlgorithms []tls.SignatureScheme
}
Preset represents a browser fingerprint configuration
func AndroidChrome143 ¶ added in v1.0.5
func AndroidChrome143() *Preset
AndroidChrome143 returns Chrome 143 on Android fingerprint preset Note: Chrome on Android uses Chrome's TLS fingerprint (not WebKit restricted like iOS)
func AndroidChrome144 ¶ added in v1.5.10
func AndroidChrome144() *Preset
AndroidChrome144 returns Chrome 144 on Android fingerprint preset
func AndroidChrome145 ¶ added in v1.6.0
func AndroidChrome145() *Preset
AndroidChrome145 returns Chrome 145 on Android fingerprint preset
func AndroidChrome146 ¶ added in v1.6.1
func AndroidChrome146() *Preset
AndroidChrome146 returns Chrome 146 on Android fingerprint preset
func AndroidChrome147 ¶ added in v1.6.5
func AndroidChrome147() *Preset
AndroidChrome147 returns Chrome 147 on Android. Same diff pattern as desktop (UA bump + sec-ch-ua brand rotation); inherits Linux-flavored TLS from chrome-146-android. Falls back to AndroidChrome146.
func AndroidChrome148 ¶ added in v1.6.6
func AndroidChrome148() *Preset
AndroidChrome148 returns Chrome 148 on Android. Same two-header diff pattern as the desktop variants. Falls back to AndroidChrome147.
func AndroidChrome150 ¶ added in v1.6.8
func AndroidChrome150() *Preset
AndroidChrome150 returns Chrome 150 on Android. Android Chrome runs the same Chromium/BoringSSL stack as desktop (the iOS line is the WebKit exception), and the Android TLS base is HelloChrome_146_Linux — identical to desktop Linux — so this preset carries the SAME ML-DSA signature_algorithms override as the desktop chrome-150 line (ML-DSA on TCP, none on QUIC). Headers are the reduced-UA mobile bump: Chrome/150 with the frozen "Android 10; K" model, sec-ch-ua-mobile ?1, sec-ch-ua-platform "Android", and the version-keyed (platform-independent) sec-ch-ua brand shared with desktop 150.
DERIVED (not yet captured from a device): the TLS/JA4 and reduced UA/sec-ch-ua are deterministic, but whether Chrome ships the ML-DSA sig-algs field trial on Android is assumed to match desktop pending a real Android 150 capture. Falls back to AndroidChrome148 if the JSON didn't load.
func BuildPreset ¶ added in v1.6.5
func BuildPreset(spec *PresetSpec) (*Preset, error)
BuildPreset converts a PresetSpec (parsed from JSON) into a Preset. If based_on is set, clones the base preset first and overlays changes.
func Chrome143 ¶
func Chrome143() *Preset
Chrome143 returns the Chrome 143 fingerprint preset with platform-specific TLS fingerprint
func Chrome143Linux ¶ added in v1.0.1
func Chrome143Linux() *Preset
Chrome143Linux returns Chrome 143 with Linux platform and fixed TLS extension order
func Chrome143Windows ¶
func Chrome143Windows() *Preset
Chrome143Windows returns Chrome 143 with Windows platform and fixed TLS extension order
func Chrome143macOS ¶ added in v1.0.1
func Chrome143macOS() *Preset
Chrome143macOS returns Chrome 143 with macOS platform and fixed TLS extension order
func Chrome144 ¶ added in v1.5.10
func Chrome144() *Preset
Chrome144 returns the Chrome 144 fingerprint preset with platform-specific TLS fingerprint
func Chrome144Linux ¶ added in v1.5.10
func Chrome144Linux() *Preset
Chrome144Linux returns Chrome 144 with Linux platform
func Chrome144Windows ¶ added in v1.5.10
func Chrome144Windows() *Preset
Chrome144Windows returns Chrome 144 with Windows platform
func Chrome144macOS ¶ added in v1.5.10
func Chrome144macOS() *Preset
Chrome144macOS returns Chrome 144 with macOS platform
func Chrome145 ¶ added in v1.6.0
func Chrome145() *Preset
Chrome145 returns the Chrome 145 fingerprint preset with platform-specific TLS fingerprint
func Chrome145Linux ¶ added in v1.6.0
func Chrome145Linux() *Preset
Chrome145Linux returns Chrome 145 with Linux platform
func Chrome145Windows ¶ added in v1.6.0
func Chrome145Windows() *Preset
Chrome145Windows returns Chrome 145 with Windows platform
func Chrome145macOS ¶ added in v1.6.0
func Chrome145macOS() *Preset
Chrome145macOS returns Chrome 145 with macOS platform
func Chrome146 ¶ added in v1.6.1
func Chrome146() *Preset
Chrome146 returns the Chrome 146 fingerprint preset with platform-specific TLS fingerprint
func Chrome146Linux ¶ added in v1.6.1
func Chrome146Linux() *Preset
Chrome146Linux returns Chrome 146 with Linux platform
func Chrome146Windows ¶ added in v1.6.1
func Chrome146Windows() *Preset
Chrome146Windows returns Chrome 146 with Windows platform
func Chrome146macOS ¶ added in v1.6.1
func Chrome146macOS() *Preset
Chrome146macOS returns Chrome 146 with macOS platform
func Chrome147 ¶ added in v1.6.5
func Chrome147() *Preset
Chrome147 returns the Chrome 147 fingerprint preset auto-detected from the running OS. Mirrors Chrome146's platform-aware behavior.
func Chrome147Linux ¶ added in v1.6.5
func Chrome147Linux() *Preset
Chrome147Linux returns Chrome 147 with Linux platform. See Chrome147Windows.
func Chrome147Windows ¶ added in v1.6.5
func Chrome147Windows() *Preset
Chrome147Windows returns Chrome 147 with Windows platform.
The preset is provided by the embedded JSON registry (fingerprint/embedded/chrome-147-windows.json), which inherits TLS bytes from chrome-146-windows and overrides only the User-Agent and sec-ch-ua header. If the embedded JSON failed to load, the factory falls back to Chrome146Windows so callers don't get a Chrome146 fallback by accident.
func Chrome147macOS ¶ added in v1.6.5
func Chrome147macOS() *Preset
Chrome147macOS returns Chrome 147 with macOS platform. See Chrome147Windows.
func Chrome148 ¶ added in v1.6.6
func Chrome148() *Preset
Chrome148 returns the Chrome 148 fingerprint preset auto-detected from the running OS.
func Chrome148Linux ¶ added in v1.6.6
func Chrome148Linux() *Preset
Chrome148Linux returns Chrome 148 on Linux. See Chrome148Windows.
func Chrome148Windows ¶ added in v1.6.6
func Chrome148Windows() *Preset
Chrome148Windows returns Chrome 148 on Windows. Wire-level diff vs 147 is two header values: User-Agent version bump and sec-ch-ua brand list rotation (Chromium moved to first position, GREASE brand "Not.A/Brand" v="8" became "Not/A)Brand" v="99"). TLS extension order keeps shuffling per-handshake the same way 147 already does. Embedded JSON only overrides the two header values; everything else inherits from chrome-147-windows. Falls back to Chrome147Windows if the JSON didn't load.
func Chrome148macOS ¶ added in v1.6.6
func Chrome148macOS() *Preset
Chrome148macOS returns Chrome 148 on macOS. See Chrome148Windows.
func Chrome149 ¶ added in v1.6.7
func Chrome149() *Preset
Chrome149 returns the Chrome 149 fingerprint preset auto-detected from the running OS.
func Chrome149Linux ¶ added in v1.6.7
func Chrome149Linux() *Preset
Chrome149Linux returns Chrome 149 on Linux. See Chrome149Windows.
func Chrome149Windows ¶ added in v1.6.7
func Chrome149Windows() *Preset
Chrome149Windows returns Chrome 149 on Windows. The wire-level fingerprint is byte-identical to 148 (verified against a real Chrome 149 capture: JA4 t13d1516h2_8daaf6152771_d8a2da3f94cd, peetprint 1d4ffe9b0e34acac0bd883fa7f79d7b5, and Akamai H2 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p all match 148). The only diff is two header values: the User-Agent version bump and a sec-ch-ua brand rotation (Google Chrome moved to first position, GREASE brand became "Not)A;Brand" v="24"). Embedded JSON overrides just those; everything else inherits from chrome-148-windows. Falls back to Chrome148Windows if the JSON didn't load.
func Chrome149macOS ¶ added in v1.6.7
func Chrome149macOS() *Preset
Chrome149macOS returns Chrome 149 on macOS. See Chrome149Windows.
func Chrome150 ¶ added in v1.6.8
func Chrome150() *Preset
Chrome150 returns the Chrome 150 fingerprint preset auto-detected from the running OS.
func Chrome150Linux ¶ added in v1.6.8
func Chrome150Linux() *Preset
Chrome150Linux returns Chrome 150 on Linux. See Chrome150Windows.
func Chrome150Windows ¶ added in v1.6.8
func Chrome150Windows() *Preset
Chrome150Windows returns Chrome 150 on Windows. The base TLS/H2/QUIC fingerprint is inherited byte-for-byte from the chrome-149 chain; Chrome 150 adds two things over 149, both captured from a real Chrome 150:
- TCP signature_algorithms now prepend the three ML-DSA post-quantum codepoints (0x0904-0x0906 = ML-DSA-44/65/87, draft-ietf-tls-mldsa), giving JA4 t13d1516h2_8daaf6152771_806a8c22fdea. QUIC is left unchanged (Chrome does NOT advertise ML-DSA over QUIC — anti-amplification limits — so JA4 stays q13d0311h3_55b375c5d22e_653d80c3fe9d).
- User-Agent bump and a sec-ch-ua brand rotation (GREASE brand became "Not;A=Brand" v="8", moved to first position).
Embedded JSON overrides just those; everything else inherits. Falls back to Chrome149Windows if the JSON didn't load.
func Chrome150macOS ¶ added in v1.6.8
func Chrome150macOS() *Preset
Chrome150macOS returns Chrome 150 on macOS. See Chrome150Windows.
func Firefox148 ¶ added in v1.6.5
func Firefox148() *Preset
Firefox148 returns the Firefox 148 fingerprint preset using JA3 for TLS. Uses the exact JA3 fingerprint captured from real Firefox 148 on Linux.
func Get ¶
Get returns a preset by name. Checks custom registry first, then built-in presets. Falls back to Chrome146 if not found.
func GetStrict ¶ added in v1.6.5
GetStrict returns a preset by name, returning nil if not found (no fallback).
func IOSChrome143 ¶ added in v1.0.5
func IOSChrome143() *Preset
IOSChrome143 returns Chrome 143 on iOS fingerprint preset Note: iOS Chrome uses WebKit (Apple requirement), so it has Safari's TLS AND HTTP/2 fingerprint WebKit doesn't support Client Hints, so no sec-ch-ua headers
func IOSChrome144 ¶ added in v1.5.10
func IOSChrome144() *Preset
IOSChrome144 returns Chrome 144 on iOS fingerprint preset Note: iOS Chrome uses WebKit (Apple requirement), so it has Safari's TLS AND HTTP/2 fingerprint WebKit doesn't support Client Hints, so no sec-ch-ua headers
func IOSChrome145 ¶ added in v1.6.0
func IOSChrome145() *Preset
IOSChrome145 returns Chrome 145 on iOS fingerprint preset Note: iOS Chrome uses WebKit (Apple requirement), so it has Safari's TLS AND HTTP/2 fingerprint WebKit doesn't support Client Hints, so no sec-ch-ua headers
func IOSChrome146 ¶ added in v1.6.1
func IOSChrome146() *Preset
IOSChrome146 returns Chrome 146 on iOS fingerprint preset Note: iOS Chrome uses WebKit (Apple requirement), so it has Safari's TLS AND HTTP/2 fingerprint WebKit doesn't support Client Hints, so no sec-ch-ua headers
func IOSChrome147 ¶ added in v1.6.5
func IOSChrome147() *Preset
IOSChrome147 returns Chrome 147 on iOS. Embedded JSON only overrides the User-Agent (CriOS major version) — everything else (no sec-ch-ua due to WebKit, Safari TLS via HelloIOS_18, Safari H2 config) inherits unchanged from chrome-146-ios. Falls back to IOSChrome146 if the JSON didn't load.
func IOSChrome148 ¶ added in v1.6.5
func IOSChrome148() *Preset
IOSChrome148 returns Chrome 148 on iOS — captured against real iOS Chrome 148.0.7778.47, with deeper changes than the 147 bump:
- User-Agent: iOS 26_4_2, CriOS/148.0.7778.47
- HTTP/2 wire: SettingsOrder [2,3,4,9] (drops MAX_FRAME_SIZE), pseudo-order m,s,a,p (was m,s,p,a in safariH2Config), ConnectionWindowUpdate 10420225
- HTTP/2 headers: priority added, sec-fetch-user removed, accept-encoding gains zstd, header order completely reshuffled
- HTTP/3 QUIC: 2 MiB stream / 16 MiB connection flow control, 8 max incoming uni streams (vs Chrome's 103). TLS bytes (HelloIOS_18, HelloIOS_18_QUIC) match Chrome 146 iOS exactly — no utls update needed
Note: chrome-146-ios and chrome-147-ios are intentionally NOT updated; this preset captures the deeper iOS-Chrome-specific divergences as of 148 only.
func IOSChrome150 ¶ added in v1.6.8
func IOSChrome150() *Preset
IOSChrome150 returns Chrome 150 on iOS — a pure header/UA bump over the 148 iOS base (User-Agent: iOS 26_5_0, CriOS/150.0.7871.51). The TLS bytes (Safari/WebKit HelloIOS_18) are unchanged, and verified byte-exact against a real iOS 26.5 capture: JA4 t13d2013h2_a09f3c656075_7f0f34a4126d, matching Akamai H2 and peetprint. iOS Chrome does NOT advertise ML-DSA (that is a desktop/Android Chromium-BoringSSL trait; iOS uses Safari's stack), so unlike the desktop chrome-150 line this preset carries no signature_algorithms override. Falls back to IOSChrome148 if the JSON didn't load.
func IOSSafari17 ¶ added in v1.0.5
func IOSSafari17() *Preset
IOSSafari17 returns Safari 17 on iOS fingerprint preset
func IOSSafari18 ¶ added in v1.5.10
func IOSSafari18() *Preset
IOSSafari18 returns Safari 18 on iOS fingerprint preset
func LoadAndBuildPreset ¶ added in v1.6.5
LoadAndBuildPreset is a convenience function: load + build a single preset from a file.
func LoadAndBuildPresetFromJSON ¶ added in v1.6.5
LoadAndBuildPresetFromJSON is a convenience function: parse JSON + build a single preset.
func LookupCustom ¶ added in v1.6.5
LookupCustom returns a registered custom preset by name, or nil if not found. Returns a deep clone to prevent callers from mutating the registry copy.
func Safari18 ¶
func Safari18() *Preset
Safari18 returns the Safari 18 fingerprint preset Note: Safari is macOS-only, so no platform detection needed
func (*Preset) H2DisableCookieSplit ¶ added in v1.6.5
H2DisableCookieSplit reports whether to send the Cookie header as a single field instead of crumbling it into one field per cookie-pair. Chrome and Firefox crumble (false) per RFC 9113 8.2.3 / Chromium HpackEncoder CookieToCrumbs; Safari/WebKit sends a single field (true). Used for both the H2 (sardanioss/net HPACK encoder) and H3 (pre-split in HTTP3Transport) paths.
func (*Preset) H2HPACKIndexingPolicy ¶ added in v1.6.5
H2HPACKIndexingPolicy returns the HPACK indexing policy name.
func (*Preset) H2HPACKNeverIndex ¶ added in v1.6.5
H2HPACKNeverIndex returns headers that should never be HPACK-indexed.
func (*Preset) H2HasPriorityTable ¶ added in v1.6.5
H2HasPriorityTable reports whether this preset will resolve per-dest priority data. Three states:
- H2Config.PriorityTable populated (len > 0) → true (explicit override).
- H2Config.PriorityTable nil or empty AND NoRFC7540Priorities=false → true (inherits the package-level defaultPriorityTable).
- NoRFC7540Priorities=true → false (Safari / iOS Chrome / iOS Safari opt out of RFC 7540 priorities entirely; the wire frame is not emitted).
When false, callers fall back to the legacy HTTP2Settings.StreamWeight / StreamExclusive single-weight behaviour. To genuinely disable priority emission for a single preset, set NoRFC7540Priorities=true on its HTTP2Settings — the priority_table mechanism is purely additive.
func (*Preset) H2HeaderOrder ¶ added in v1.6.5
H2HeaderOrder returns the HPACK wire encoding order for HTTP/2 headers.
func (*Preset) H2PriorityFor ¶ added in v1.6.5
func (p *Preset) H2PriorityFor(dest string) (weight uint16, exclusive bool, headerValue string, ok bool)
H2PriorityFor returns the resolved (weight, exclusive, headerValue) for a given sec-fetch-dest. Resolution order:
- Preset's explicit H2Config.PriorityTable (when populated, len > 0).
- Package-level defaultPriorityTable, but only if the preset uses RFC 7540 priorities (NoRFC7540Priorities=false).
ok=false in two cases:
- the preset opts out of RFC 7540 priorities entirely (Safari etc.), or
- the dest is not registered in whichever table applies.
In both cases the caller should fall back to HTTP2Settings.StreamWeight / StreamExclusive (legacy behaviour).
weight is the effective weight (1–256). The transport converts to wire format (weight-1) at the boundary.
headerValue is the RFC 9218 priority: header value rendered per the emission rules; empty string means "do not inject the header" (caller must skip Set/Add for this request).
Lookup is case-sensitive — Chrome emits "document", "image", etc. as lowercase ASCII. Pass req.Header.Get("Sec-Fetch-Dest") directly.
func (*Preset) H2PseudoHeaderOrder ¶ added in v1.6.5
H2PseudoHeaderOrder returns the pseudo-header order for HTTP/2. nil signals "use heuristic" (Chrome m,a,s,p / Safari m,s,p,a).
func (*Preset) H2SettingsOrder ¶ added in v1.6.5
H2SettingsOrder returns the explicit H2 SETTINGS frame ID order. nil signals "use dynamic builder" (existing behavior).
func (*Preset) H2StreamPriorityMode ¶ added in v1.6.5
H2StreamPriorityMode returns the stream priority mode name.
func (*Preset) H3EnableDatagrams ¶ added in v1.6.5
H3EnableDatagrams returns whether to enable H3 datagrams.
func (*Preset) H3MaxFieldSectionSize ¶ added in v1.6.5
H3MaxFieldSectionSize returns the max field section size. 0 means omit the setting (Safari behavior).
func (*Preset) H3MaxResponseHeaderBytes ¶ added in v1.6.5
H3MaxResponseHeaderBytes returns the max response header bytes.
func (*Preset) H3QPACKBlockedStreams ¶ added in v1.6.5
H3QPACKBlockedStreams returns the QPACK blocked streams limit.
func (*Preset) H3QPACKMaxTableCapacity ¶ added in v1.6.5
H3QPACKMaxTableCapacity returns the QPACK max dynamic table capacity.
func (*Preset) H3QUICAllow0RTT ¶ added in v1.6.5
H3QUICAllow0RTT returns whether to allow 0-RTT.
func (*Preset) H3QUICChromeStyleInitial ¶ added in v1.6.5
H3QUICChromeStyleInitial returns whether to use Chrome-style initial packets.
func (*Preset) H3QUICConnectionIDLength ¶ added in v1.6.5
H3QUICConnectionIDLength returns the QUIC connection ID length in bytes. Chrome uses 0 (empty SCID), Firefox uses 8.
func (*Preset) H3QUICDisableHelloScramble ¶ added in v1.6.5
H3QUICDisableHelloScramble returns whether to disable ClientHello scrambling.
func (*Preset) H3QUICInitialConnectionReceiveWindow ¶ added in v1.6.5
H3QUICInitialConnectionReceiveWindow returns the quic-go InitialConnectionReceiveWindow value (which becomes initial_max_data on the wire). 0 means "use quic-go default" (~7.5 MB). iOS Chrome sets 16 MiB.
func (*Preset) H3QUICInitialPacketSize ¶ added in v1.6.5
H3QUICInitialPacketSize returns the QUIC initial packet size.
func (*Preset) H3QUICInitialStreamReceiveWindow ¶ added in v1.6.5
H3QUICInitialStreamReceiveWindow returns the quic-go InitialStreamReceiveWindow value (which becomes initial_max_stream_data_* on the wire). 0 means "use quic-go default" (~512 KB). iOS Chrome sets 2 MiB.
func (*Preset) H3QUICMaxDatagramFrameSize ¶ added in v1.6.5
H3QUICMaxDatagramFrameSize returns the max_datagram_frame_size transport parameter. Chrome uses 65536, default quic-go is 16383.
func (*Preset) H3QUICMaxIncomingStreams ¶ added in v1.6.5
H3QUICMaxIncomingStreams returns the max incoming bidirectional streams.
func (*Preset) H3QUICMaxIncomingUniStreams ¶ added in v1.6.5
H3QUICMaxIncomingUniStreams returns the max incoming unidirectional streams.
func (*Preset) H3QUICTransportParamOrder ¶ added in v1.6.5
H3QUICTransportParamOrder returns the QUIC transport parameter order mode name.
func (*Preset) H3SendGreaseFrames ¶ added in v1.6.5
H3SendGreaseFrames returns whether to send GREASE frames on the control stream.
func (*Preset) ResolveClientHints ¶ added in v1.6.8
func (p *Preset) ResolveClientHints() ClientHints
ResolveClientHints returns the fully-resolved UA client hints for this preset. The low-entropy trio is taken verbatim from the preset headers; the high-entropy hints come from the preset's ClientHints overrides where set, and are otherwise DERIVED from the trio so they can never drift out of sync. Specifically, an unset full-version-list is built from sec-ch-ua by preserving the exact brand names, order and GREASE token and expanding each major version to "<major>.0.0.0". This is the single coherent source the session layer reads to emit high-entropy hints after a host advertises Accept-CH.
type PresetFile ¶ added in v1.6.5
type PresetFile struct {
Version int `json:"version"`
Preset *PresetSpec `json:"preset,omitempty"`
Pool *PoolSpec `json:"pool,omitempty"`
}
PresetFile is the top-level JSON structure for preset files.
func LoadPresetFromFile ¶ added in v1.6.5
func LoadPresetFromFile(path string) (*PresetFile, error)
LoadPresetFromFile reads and parses a JSON preset file.
func LoadPresetFromJSON ¶ added in v1.6.5
func LoadPresetFromJSON(data []byte) (*PresetFile, error)
LoadPresetFromJSON parses JSON bytes into a PresetFile.
type PresetInfo ¶ added in v1.6.0
type PresetInfo struct {
Protocols []string `json:"protocols"`
}
PresetInfo contains metadata about a preset's protocol support.
type PresetPool ¶ added in v1.6.5
type PresetPool struct {
// contains filtered or unexported fields
}
PresetPool manages a collection of presets with rotation strategies.
func NewPresetPool ¶ added in v1.6.5
func NewPresetPool(name string, strategy PoolStrategy, presets []*Preset) *PresetPool
NewPresetPool creates a pool from pre-built presets. Panics if presets is empty.
func NewPresetPoolFromFile ¶ added in v1.6.5
func NewPresetPoolFromFile(path string) (*PresetPool, error)
NewPresetPoolFromFile loads a pool from a JSON file. Auto-registers all pool presets to the custom registry.
func NewPresetPoolFromJSON ¶ added in v1.6.5
func NewPresetPoolFromJSON(data []byte) (*PresetPool, error)
NewPresetPoolFromJSON loads a pool from JSON bytes. Auto-registers all pool presets to the custom registry.
func (*PresetPool) Close ¶ added in v1.6.5
func (p *PresetPool) Close()
Close unregisters all pool presets from the custom registry.
func (*PresetPool) Get ¶ added in v1.6.5
func (p *PresetPool) Get(index int) *Preset
Get returns a preset by index. Panics if index is out of range.
func (*PresetPool) Name ¶ added in v1.6.5
func (p *PresetPool) Name() string
Name returns the pool name.
func (*PresetPool) Next ¶ added in v1.6.5
func (p *PresetPool) Next() *Preset
Next returns the next preset using round-robin. Lock-free, thread-safe.
func (*PresetPool) Pick ¶ added in v1.6.5
func (p *PresetPool) Pick() *Preset
Pick returns a preset using the pool's configured strategy.
func (*PresetPool) Random ¶ added in v1.6.5
func (p *PresetPool) Random() *Preset
Random returns a random preset from the pool. Thread-safe.
func (*PresetPool) Size ¶ added in v1.6.5
func (p *PresetPool) Size() int
Size returns the number of presets in the pool.
type PresetSpec ¶ added in v1.6.5
type PresetSpec struct {
Name string `json:"name"`
BasedOn string `json:"based_on,omitempty"`
TLS *TLSSpec `json:"tls,omitempty"`
HTTP2 *HTTP2Spec `json:"http2,omitempty"`
HTTP3 *HTTP3Spec `json:"http3,omitempty"`
Headers *HeaderSpec `json:"headers,omitempty"`
ClientHints *ClientHintsSpec `json:"client_hints,omitempty"`
TCP *TCPSpec `json:"tcp,omitempty"`
Protocol *ProtocolSpec `json:"protocols,omitempty"`
}
PresetSpec defines a single preset in JSON.
type ProtocolSpec ¶ added in v1.6.5
type ProtocolSpec struct {
HTTP3 *bool `json:"http3,omitempty"`
// Aliases / extra toggles. H3 is an alias for HTTP3. H2=false disables HTTP/2
// in auto mode (the preset goes straight to HTTP/1.1). Accepting "h2"/"h3"
// matches what users naturally write; previously only "http3" was honored.
H3 *bool `json:"h3,omitempty"`
H2 *bool `json:"h2,omitempty"`
}
ProtocolSpec defines protocol support.
type RequestContext ¶ added in v1.0.1
type RequestContext struct {
// Mode is the fetch mode (navigate, cors, no-cors, same-origin)
Mode FetchMode
// Dest is the resource destination type
Dest FetchDest
// Site is the relationship between request origin and target
Site FetchSite
// IsUserTriggered indicates if the request was user-initiated (affects Sec-Fetch-User)
IsUserTriggered bool
// Referrer is the page that initiated the request (for Sec-Fetch-Site calculation)
Referrer string
// TargetURL is the URL being requested
TargetURL string
}
RequestContext contains information about the request context for header generation
func FontContext ¶ added in v1.6.0
func FontContext(referrer, targetURL string) RequestContext
FontContext returns a RequestContext for font loads
func ImageContext ¶ added in v1.0.1
func ImageContext(referrer, targetURL string) RequestContext
ImageContext returns a RequestContext for image loads
func NavigationContext ¶ added in v1.0.1
func NavigationContext() RequestContext
NavigationContext returns a RequestContext for page navigation
func ScriptContext ¶ added in v1.0.1
func ScriptContext(referrer, targetURL string) RequestContext
ScriptContext returns a RequestContext for script loads
func StyleContext ¶ added in v1.0.1
func StyleContext(referrer, targetURL string) RequestContext
StyleContext returns a RequestContext for stylesheet loads
func XHRContext ¶ added in v1.0.1
func XHRContext(referrer, targetURL string) RequestContext
XHRContext returns a RequestContext for XHR/fetch API requests
type ResourcePriority ¶ added in v1.6.5
type ResourcePriority struct {
Urgency uint8 // 0–7; 3 = default (no `u=` on header)
Incremental bool // RFC 9218 `i` parameter
EmitHeader bool // false → suppress the priority: HTTP header entirely
}
ResourcePriority describes a single browser priority decision for one resource class (sec-fetch-dest). Three orthogonal facts:
- Urgency (0–7) drives the RFC 7540 H2 stream weight via the formula weight = 256 - (urgency * 73) / 2. 3 is Chrome's internal default and emits no `u=` parameter on the priority: header.
- Incremental flag drives the RFC 9218 `i` parameter on the priority: header. The H2 wire frame ignores it (RFC 7540 has no incremental).
- EmitHeader controls whether the priority: HTTP header is sent at all. Chrome omits the header entirely on async/defer scripts even though the wire weight defaults to 147 (urgency=3). The wire frame is still emitted; only the HTTP header is suppressed.
type ResourcePrioritySpec ¶ added in v1.6.5
type ResourcePrioritySpec struct {
Urgency uint8 `json:"urgency"`
Incremental bool `json:"incremental"`
EmitHeader bool `json:"emit_header"`
}
ResourcePrioritySpec is the JSON shape of fingerprint.ResourcePriority. All three fields are required for a complete entry; partial entries inherit zero values (urgency=0 → highest, incremental=false, emit_header=false) which is rarely what a real preset wants — populate explicitly.
type SecFetchHeaders ¶ added in v1.0.1
type SecFetchHeaders struct {
Site string
Mode string
Dest string
User string // "?1" for user-triggered, empty otherwise
}
SecFetchHeaders generates coherent Sec-Fetch-* headers based on context
func GenerateSecFetchHeaders ¶ added in v1.0.1
func GenerateSecFetchHeaders(ctx RequestContext) SecFetchHeaders
GenerateSecFetchHeaders generates Sec-Fetch-* headers for the given context
type TCPFingerprint ¶ added in v1.6.1
type TCPFingerprint struct {
TTL int // IP Time-To-Live: 128=Windows, 64=Linux/macOS/iOS/Android
MSS int // TCP Maximum Segment Size: 1460 for standard Ethernet
WindowSize int // TCP Window Size in SYN: 64240=Win10/11, 65535=Linux/macOS
WindowScale int // TCP Window Scale option: 8=Win10/11, 7=Linux/Android, 6=macOS/iOS
DFBit bool // IP Don't Fragment flag
}
TCPFingerprint contains TCP/IP stack parameters that identify the OS. Anti-bot systems check TTL, window size, and other TCP options in the SYN packet to verify the claimed browser platform matches the actual OS.
func LinuxTCPFingerprint ¶ added in v1.6.1
func LinuxTCPFingerprint() TCPFingerprint
LinuxTCPFingerprint returns TCP fingerprint values for Linux
func MacOSTCPFingerprint ¶ added in v1.6.1
func MacOSTCPFingerprint() TCPFingerprint
MacOSTCPFingerprint returns TCP fingerprint values for macOS
func PlatformTCPFingerprint ¶ added in v1.6.1
func PlatformTCPFingerprint(platform string) TCPFingerprint
PlatformTCPFingerprint returns the TCP fingerprint matching the given platform string. Used by auto-platform presets that detect the running OS at runtime.
func WindowsTCPFingerprint ¶ added in v1.6.1
func WindowsTCPFingerprint() TCPFingerprint
WindowsTCPFingerprint returns TCP fingerprint values for Windows 10/11
type TCPSpec ¶ added in v1.6.5
type TCPSpec struct {
Platform string `json:"platform,omitempty"` // "Windows","macOS","Linux" — shorthand
TTL *int `json:"ttl,omitempty"`
MSS *int `json:"mss,omitempty"`
WindowSize *int `json:"window_size,omitempty"`
WindowScale *int `json:"window_scale,omitempty"`
DFBit *bool `json:"df_bit,omitempty"`
}
TCPSpec defines TCP/IP fingerprint configuration.
type TLSSpec ¶ added in v1.6.5
type TLSSpec struct {
// Mutually exclusive: use client_hello OR ja3, not both
ClientHello string `json:"client_hello,omitempty"` // e.g., "chrome-146-windows"
PSKClientHello string `json:"psk_client_hello,omitempty"` // e.g., "chrome-146-windows-psk"
QUICClientHello string `json:"quic_client_hello,omitempty"` // e.g., "chrome-146-quic"
QUICPSKClientHello string `json:"quic_psk_client_hello,omitempty"`
JA3 string `json:"ja3,omitempty"` // JA3 string
JA3ExtrasSpec *JA3ExtrasSpec `json:"ja3_extras,omitempty"`
// Individual extension data (supplements client_hello or ja3)
SignatureAlgorithms []uint16 `json:"signature_algorithms,omitempty"` // TCP (H1/H2) sig-algs override; overrides the ClientHelloID base
QUICSignatureAlgorithms []uint16 `json:"quic_signature_algorithms,omitempty"` // HTTP/3 (QUIC) sig-algs override; separate because a browser's QUIC set can differ (e.g. Chrome 150 sends ML-DSA on TCP only)
DelegatedCredentialAlgorithms []uint16 `json:"delegated_credential_algorithms,omitempty"`
ALPN []string `json:"alpn,omitempty"`
CertCompression []string `json:"cert_compression,omitempty"` // "brotli", "zlib", "zstd"
PermuteExtensions *bool `json:"permute_extensions,omitempty"`
RecordSizeLimit *uint16 `json:"record_size_limit,omitempty"`
}
TLSSpec defines TLS fingerprint configuration.