Documentation
ΒΆ
Overview ΒΆ
Package aoni provides a middleware-driven HTTP and WebSocket client built on top of net/http. It is designed for unreliable networks, aggressive firewalls, rotating proxy pools, and environments where deep-packet inspection must be evaded.
Standard HTTP clients are built for stable internal services. aoni fills the gap when connections are unstable, proxies fail frequently, or transport fingerprints must match a specific browser.
Request Pipeline ΒΆ
Every outgoing request passes through four stages:
- RequestModifier chain - declarative header, query, and body setup.
- Middleware chain - rate limiting, retries, circuit breaking, hedging.
- Transport layer - TLS fingerprinting (uTLS), HTTP/3, proxy rotation, TCP/IP spoofing.
- Response decoding - automatic decompression (gzip, brotli, zstd), charset transcoding, and structured binding via Decoder.
Core Types ΒΆ
- Client is the central immutable HTTP client. Every configuration call (Client.WithBaseURL, Client.WithTimeout, etc.) returns a new clone, keeping the original safe for concurrent use.
- LoadBalancer distributes requests across multiple Client instances with health checking and automatic failover.
- ProxyRotator manages a pool of proxy clients with sticky sessions, fault tracking, and recovery.
- Decoder controls how response bodies are deserialized. Built-in implementations: JSONDecoder, XMLDecoder, YAMLDecoder, RawDecoder.
- ProxyIsolatedCookieJar stores cookies separately per proxy URL to prevent session leakage across different exit nodes.
Fingerprint Evasion ΒΆ
aoni can make outbound connections appear as specific browsers:
- Client.WithTLSFingerprint selects a uTLS ClientHello profile (Chrome, Firefox, Safari) for JA3/JA4 matching.
- Client.WithP0fSignature sets TTL, Don't Fragment, and TCP window size to mimic an OS-level network stack.
- [Client.WithOrderedHeaders] controls the HTTP/1.1 header serialization order. For HTTP/2, H2FramedTransport reorders HPACK-encoded HEADERS frames.
- Client.WithH2FramedTransport injects browser-specific SETTINGS and PRIORITY frames into the HTTP/2 connection preface.
Resilience ΒΆ
- Hedging (Client.WithHedging) sends a second request after a delay if the first has not completed, cutting tail latency.
- [AdaptiveLimiter] dynamically adjusts concurrency based on observed RTT, similar to the Vegas TCP congestion algorithm.
- RetryMiddleware retries failed requests with exponential backoff and respects Retry-After headers.
- CircuitBreaker tracks per-host failures and stops sending requests until the host recovers.
Network Protocols ΒΆ
- HTTP/3 over QUIC via Client.WithHTTP3.
- DNS-over-HTTPS (DoHResolver) and DNS-over-TLS (DoTResolver) bypass local ISP DNS interception.
- WebSocket via uTLS with HTTP/2 Extended CONNECT ([RFC 8441]).
Basic Usage ΒΆ
client := aoni.NewClient(nil).
WithBaseURL("https://api.example.com").
WithTimeout(10 * time.Second)
// 1. Get structured data with generics:
user, err := aoni.GetTo[User](ctx, client, "/users/123")
if err != nil {
log.Fatal(err)
}
// 2. Or execute raw requests directly via convenience methods:
resp, err := client.Get(ctx, "/raw-data")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
The full example directory contains runnable programs for each feature.
Index ΒΆ
- Constants
- Variables
- func AppendContextModifier(ctx context.Context, mods ...RequestModifier) context.Context
- func ApplyTCPDelay(ctx context.Context) error
- func CurlCommand(req *http.Request, body []byte) string
- func DecodeByContentType(r io.Reader, contentType string, target any) error
- func DecodeJSON[T any](r io.Reader) (T, error)
- func DecodeTo[T any](r io.Reader, d Decoder) (T, error)
- func DecodeXML[T any](r io.Reader) (T, error)
- func DecodeYAML[T any](r io.Reader) (T, error)
- func DefaultCircuitBreakerCondition(resp *http.Response, err error) bool
- func DefaultRedirectPolicy(maxRedirects int, sensitiveHeaders ...string) func(req *http.Request, via []*http.Request) error
- func Delete(ctx context.Context, c Requester, path string, body any, ...) (*http.Response, error)
- func DeleteTo[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, error)
- func DeleteToEx[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, *http.Response, error)
- func DetectCloudflareChallenge(resp *http.Response) (bool, error)
- func DialWebSocket(ctx context.Context, c *Client, targetURL string, mods ...RequestModifier) (net.Conn, *http.Response, error)
- func DialWebSocketWithConfig(ctx context.Context, c *Client, targetURL string, config DialWebSocketConfig, ...) (net.Conn, *http.Response, error)
- func ExportCookiesJSON(jar http.CookieJar, u *url.URL) (string, error)
- func GeneratePadding(cfg PaddingConfig) []byte
- func Get(ctx context.Context, c Requester, path string, mods ...RequestModifier) (*http.Response, error)
- func GetCacheTTL(ctx context.Context) (time.Duration, bool)
- func GetConnMetadata(ctx context.Context, key string) (any, bool)
- func GetInsecureSkipVerify(ctx context.Context) bool
- func GetProxyOverride(ctx context.Context) (string, bool)
- func GetResponseValidator(ctx context.Context) func(resp *http.Response) error
- func GetTo[Resp any](ctx context.Context, c Requester, path string, mods ...RequestModifier) (*Resp, error)
- func GetToEx[Resp any](ctx context.Context, c Requester, path string, mods ...RequestModifier) (*Resp, *http.Response, error)
- func HostRewriteRules(ctx context.Context) map[string]string
- func ImportCookies(jar http.CookieJar, u *url.URL, cookies []CookieData)
- func ImportCookiesJSON(jar http.CookieJar, u *url.URL, jsonStr string) error
- func MarkModifierError(req *http.Request, err error)
- func MirrorCookies(jar http.CookieJar, sourceURL *url.URL, targetURLs []*url.URL, ...)
- func NewFragmentedConn(conn net.Conn, cfg *FragmentConfig) net.Conn
- func NewProxyClient(cfg ProxyConfig) (*http.Client, error)
- func NewStdClient(c *Client) *http.Client
- func PaddingHeaderName(cfg PaddingConfig) string
- func ParseAutoProxy(proxyStr string) (*url.URL, error)
- func ParseSSE[T any](ctx context.Context, resp *StreamResponse) (<-chan T, <-chan error)
- func Patch(ctx context.Context, c Requester, path string, body any, ...) (*http.Response, error)
- func PatchTo[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, error)
- func PatchToEx[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, *http.Response, error)
- func Post(ctx context.Context, c Requester, path string, body any, ...) (*http.Response, error)
- func PostTo[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, error)
- func PostToEx[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, *http.Response, error)
- func ProxyFuncWithOverride(base func(*http.Request) (*url.URL, error)) func(*http.Request) (*url.URL, error)
- func Put(ctx context.Context, c Requester, path string, body any, ...) (*http.Response, error)
- func PutTo[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, error)
- func PutToEx[Resp any](ctx context.Context, c Requester, path string, body any, ...) (*Resp, *http.Response, error)
- func ReadAllBytes(rb ReplayableBody) ([]byte, error)
- func ReadAllString(rb ReplayableBody) (string, error)
- func StreamChunks(ctx context.Context, resp *StreamResponse) (<-chan string, <-chan error)
- func StreamNDJSON[T any](ctx context.Context, resp *StreamResponse) (<-chan T, <-chan error)
- func StreamSSE[T any](ctx context.Context, c Requester, path string, mods ...RequestModifier) (<-chan T, <-chan error, error)
- func StructToValues(s any) (url.Values, error)
- func TLSConfigWithOverride(ctx context.Context, base *tls.Config) *tls.Config
- func UnwrapTo[T any](c io.Closer) (T, bool)
- func Validate(s any) error
- func WithContextModifier(ctx context.Context, mods ...RequestModifier) context.Context
- type APIError
- type Backend
- type BackoffStrategy
- type BaseResponse
- type BaseResponseProvider
- type BoolInt
- type BridgeError
- type BrowserID
- type CapturedRequest
- type ChallengeDetector
- type ChallengeSolver
- type ChaosConfig
- type CircuitBreaker
- type CircuitBreakerConfig
- type Client
- func (c *Client) BaseResponse() BaseResponse
- func (c *Client) Clone() *Client
- func (c *Client) CloseIdleConnections()
- func (c *Client) Delete(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
- func (c *Client) EnableInspector(addr string) error
- func (c *Client) Get(ctx context.Context, path string, mods ...RequestModifier) (*http.Response, error)
- func (c *Client) HTTP() HTTPDoer
- func (c *Client) Inspector() *TrafficInspector
- func (c *Client) Logger() Logger
- func (c *Client) Patch(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
- func (c *Client) Post(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
- func (c *Client) Put(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
- func (c *Client) Request(ctx context.Context, method, path string, mods ...RequestModifier) (*http.Response, error)
- func (c *Client) Transport() *http.Transport
- func (c *Client) UserAgent() string
- func (c *Client) WithAfterResponse(hook func(resp *http.Response, err error)) *Client
- func (c *Client) WithBaseResponse(provider func() BaseResponse) *Client
- func (c *Client) WithBaseURL(raw string) *Client
- func (c *Client) WithBasicAuth(username, password string) *Client
- func (c *Client) WithBearer(token string) *Client
- func (c *Client) WithBeforeRequest(hook func(req *http.Request)) *Client
- func (c *Client) WithBrowserProfile(browser BrowserID, os profiles.OSKey) *Client
- func (c *Client) WithChallengeDetector(detector ChallengeDetector) *Client
- func (c *Client) WithChallengeSolver(solver ChallengeSolver) *Client
- func (c *Client) WithConnectionPool(cfg ConnectionPoolConfig) *Client
- func (c *Client) WithCookieJar(jar http.CookieJar) *Client
- func (c *Client) WithDNSCache(ttl time.Duration) *Client
- func (c *Client) WithDNSResolver(resolver DNSResolver) *Client
- func (c *Client) WithDoH(endpoint, host string) *Client
- func (c *Client) WithDoT(endpoint, host string) *Client
- func (c *Client) WithDynamicHedging(config *DynamicHedgingConfig) *Client
- func (c *Client) WithFragmentation(cfg FragmentConfig) *Client
- func (c *Client) WithH2FramedTransport(settings HTTP2Settings) *Client
- func (c *Client) WithHTTP2Settings(settings HTTP2Settings) *Client
- func (c *Client) WithHTTP3() *Client
- func (c *Client) WithHTTP3Config(config *QUICMigrationConfig) *Client
- func (c *Client) WithHTTP3Settings(settings HTTP3Settings) *Client
- func (c *Client) WithHappyEyeballs(delay time.Duration) *Client
- func (c *Client) WithHeader(key, value string) *Client
- func (c *Client) WithHeaders(headers map[string]string) *Client
- func (c *Client) WithHedging(d time.Duration) *Client
- func (c *Client) WithHostRewrite(rules map[string]string) *Client
- func (c *Client) WithInsecureSkipVerify() *Client
- func (c *Client) WithJA4Callback(fn func(ja4.Report)) *Client
- func (c *Client) WithLocalAddr(addr string) *Client
- func (c *Client) WithLocalAddrPool(addrs []string) *Client
- func (c *Client) WithLogger(l Logger) *Client
- func (c *Client) WithMaxResponseSize(size int64) *Client
- func (c *Client) WithModifiers(mods ...RequestModifier) *Client
- func (c *Client) WithMultiReadBody(threshold int64) *Client
- func (c *Client) WithOrigin(origin string) *Client
- func (c *Client) WithP0fSignature(sig *p0f.Signature) *Client
- func (c *Client) WithPacketPadding(cfg PaddingConfig) *Client
- func (c *Client) WithPersona(p Persona) *Client
- func (c *Client) WithProfileH2Settings(s profiles.H2Settings) *Client
- func (c *Client) WithProxy(proxyURL *url.URL) *Client
- func (c *Client) WithProxyAwareSessionCache() *Client
- func (c *Client) WithProxyDNS() *Client
- func (c *Client) WithProxyIsolatedCookieJar(jar *ProxyIsolatedCookieJar) *Client
- func (c *Client) WithProxyString(proxyStr string) *Client
- func (c *Client) WithRedirectLimit(max int) *Client
- func (c *Client) WithRefererAutomaton(enabled bool) *Client
- func (c *Client) WithResponseValidator(fn func(resp *http.Response) error) *Client
- func (c *Client) WithSSRFGuard() *Client
- func (c *Client) WithTCPDelay(min, max time.Duration) *Client
- func (c *Client) WithTLSClientHelloID(id utls.ClientHelloID) *Client
- func (c *Client) WithTLSFingerprint(browser BrowserID) *Client
- func (c *Client) WithTimeout(d time.Duration) *Client
- func (c *Client) WithUserAgent(ua string) *Client
- func (c *Client) WithoutHeaders() *Client
- type ClientWithProxy
- type ConcurrentResult
- type ConnectionPoolConfig
- type CookieData
- type CookieStorageBackend
- type DNSError
- type DNSResolver
- type Decoder
- type DecoderFunc
- type DialWebSocketConfig
- type DoHResolver
- type DoTResolver
- type DoerFunc
- type DynamicHedgingConfig
- type FallbackFunc
- type FallbackResolver
- type FastRaceResolver
- type Float64String
- type FragmentConfig
- type H2FramedTransport
- type HTTP2Settings
- type HTTP3Settings
- type HTTPDoer
- type HealthStatus
- type HealthTracker
- type HostRewriteConfig
- type InMemoryDNSCache
- type Int64String
- type JSONDecoderConfig
- type JSONFileCookieStorage
- type JitterStrategy
- type LoadBalancer
- func (lb *LoadBalancer) Close() error
- func (lb *LoadBalancer) Do(req *http.Request) (*http.Response, error)
- func (lb *LoadBalancer) Prewarm(ctx context.Context)
- func (lb *LoadBalancer) Reset()
- func (lb *LoadBalancer) SetWeight(backendURL string, weight int) bool
- func (lb *LoadBalancer) Stats() LoadBalancerStats
- func (lb *LoadBalancer) UpdateBackends(backends ...string)
- func (lb *LoadBalancer) WithClients(clients ...HTTPDoer) *LoadBalancer
- type LoadBalancerConfig
- type LoadBalancerStats
- type LoadBalancingStrategy
- type Logger
- type Middleware
- func AdaptiveLimitMiddleware(limiter *limiter.AdaptiveLimiter) Middleware
- func ChaosMiddleware(cfg ChaosConfig) Middleware
- func CircuitBreakerMiddleware(cb *CircuitBreaker, isFailure func(*http.Response, error) bool) Middleware
- func FallbackMiddleware() Middleware
- func FallbackMiddlewareEx(isFailure func(*http.Response, error) bool) Middleware
- func RateLimitMiddleware(rps float64, burst int) Middleware
- func RecoveryMiddleware(onPanic func(any)) Middleware
- func RetryMiddleware(opts RetryOptions, condition RetryCondition) Middleware
- type NamespaceSocket
- func (ns *NamespaceSocket) Emit(event string, args ...any) error
- func (ns *NamespaceSocket) EmitVolatile(event string, args ...any) error
- func (ns *NamespaceSocket) EmitWithAck(ctx context.Context, event string, args ...any) ([]json.RawMessage, error)
- func (ns *NamespaceSocket) On(event string, handler func(args []json.RawMessage))
- func (ns *NamespaceSocket) OnAny(handler func(event string, args []json.RawMessage))
- type NoResponse
- type PaddingConfig
- type PersistentJar
- type Persona
- type ProgressFunc
- type ProxyAwareSessionCache
- func (c *ProxyAwareSessionCache) Clear()
- func (c *ProxyAwareSessionCache) CurrentProxyKey() string
- func (c *ProxyAwareSessionCache) Get(serverName string) (*utls.ClientSessionState, bool)
- func (c *ProxyAwareSessionCache) Put(serverName string, session *utls.ClientSessionState)
- func (c *ProxyAwareSessionCache) SetProxyKey(key string)
- type ProxyConfig
- type ProxyIsolatedCookieJar
- func (p *ProxyIsolatedCookieJar) Cookies(u *url.URL) []*http.Cookie
- func (p *ProxyIsolatedCookieJar) CookiesForProxy(proxyURL string, u *url.URL) []*http.Cookie
- func (p *ProxyIsolatedCookieJar) GetJar(ctx context.Context) http.CookieJar
- func (p *ProxyIsolatedCookieJar) GetJarForProxy(proxyURL string) http.CookieJar
- func (p *ProxyIsolatedCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie)
- func (p *ProxyIsolatedCookieJar) SetCookiesForProxy(proxyURL string, u *url.URL, cookies []*http.Cookie)
- func (p *ProxyIsolatedCookieJar) WithStorageBackend(backend CookieStorageBackend) *ProxyIsolatedCookieJar
- type ProxyRotator
- func (r *ProxyRotator) Close() error
- func (r *ProxyRotator) Do(req *http.Request) (*http.Response, error)
- func (r *ProxyRotator) Prewarm(ctx context.Context, targetURL string)
- func (r *ProxyRotator) Reset()
- func (r *ProxyRotator) ResetDomainCooldowns()
- func (r *ProxyRotator) Stats() ProxyRotatorStats
- func (r *ProxyRotator) UpdateClients(clients ...ClientWithProxy)
- func (r *ProxyRotator) WithStickySessions(f StickyKeyFunc) *ProxyRotator
- type ProxyRotatorConfig
- type ProxyRotatorStats
- type ProxyRoutedDNSResolver
- type QUICMigrationConfig
- type RTTTracker
- func (t *RTTTracker) AverageRTT() time.Duration
- func (t *RTTTracker) Count() int
- func (t *RTTTracker) MaxRTT() time.Duration
- func (t *RTTTracker) MinRTT() time.Duration
- func (t *RTTTracker) P95() time.Duration
- func (t *RTTTracker) P99() time.Duration
- func (t *RTTTracker) Percentile(p float64) time.Duration
- func (t *RTTTracker) Record(rtt time.Duration)
- func (t *RTTTracker) Reset()
- func (t *RTTTracker) SmoothedRTT() time.Duration
- type ReplayableBody
- type RequestModifier
- func AppendHostRewrite(rules map[string]string) RequestModifier
- func AsCurl() RequestModifier
- func CaptureResponse(target **http.Response) RequestModifier
- func ContextModifiers(ctx context.Context) []RequestModifier
- func Debug() RequestModifier
- func ResetHeaders() RequestModifier
- func Trace(target *TraceInfo) RequestModifier
- func TraceContext() RequestModifier
- func TraceJA4(target *TraceInfo) RequestModifier
- func WithALPN(protocols []string) RequestModifier
- func WithAccept(accept string) RequestModifier
- func WithBasicAuth(username, password string) RequestModifier
- func WithBearer(token string) RequestModifier
- func WithBody(r io.Reader) RequestModifier
- func WithCacheTTL(d time.Duration) RequestModifier
- func WithConnMetadata(key string, val any) RequestModifier
- func WithContentType(ct string) RequestModifier
- func WithCookie(c *http.Cookie) RequestModifier
- func WithCookies(kv map[string]string) RequestModifier
- func WithDecoder(d Decoder) RequestModifier
- func WithDownloadProgress(onProgress ProgressFunc) RequestModifier
- func WithErrorModel(target any) RequestModifier
- func WithFallback(f FallbackFunc) RequestModifier
- func WithForceHTTP1() RequestModifier
- func WithForceHTTP2() RequestModifier
- func WithFormBody(payload any) RequestModifier
- func WithFormValues(values url.Values) RequestModifier
- func WithFragmentation(cfg FragmentConfig) RequestModifier
- func WithHeader(key, value string) RequestModifier
- func WithHeaders(headers map[string]string) RequestModifier
- func WithHedging(delay time.Duration) RequestModifier
- func WithHostRewrite(rules map[string]string) RequestModifier
- func WithIfMatch(etag string) RequestModifier
- func WithIfModifiedSince(t time.Time) RequestModifier
- func WithIfNoneMatch(etag string) RequestModifier
- func WithInsecureSkipVerify() RequestModifier
- func WithJSONBody(payload any) RequestModifier
- func WithJSONDecoder() RequestModifier
- func WithMultiReadBody(threshold int64) RequestModifier
- func WithMultipart(fields map[string]string, files map[string]io.Reader) RequestModifier
- func WithOrderedHeaders(order []string) RequestModifier
- func WithOrigin(origin string) RequestModifier
- func WithP0fSignature(sig *p0f.Signature) RequestModifier
- func WithPadding(cfg PaddingConfig) RequestModifier
- func WithProxyOverride(rawURL string) RequestModifier
- func WithQuery(query any) RequestModifier
- func WithRawDecoder() RequestModifier
- func WithResponseValidator(fn func(resp *http.Response) error) RequestModifier
- func WithRetryPolicy(o RetryOverride) RequestModifier
- func WithStreamingMultipart(fields map[string]string, files map[string]io.Reader) RequestModifier
- func WithTCPDelay(min, max time.Duration) RequestModifier
- func WithTimeout(d time.Duration) RequestModifier
- func WithUploadProgress(onProgress ProgressFunc) RequestModifier
- func WithUserAgent(ua string) RequestModifier
- func WithVar(key string, value any) RequestModifier
- func WithVars(pairs ...any) RequestModifier
- func WithXMLDecoder() RequestModifier
- func WithYAMLDecoder() RequestModifier
- type Requester
- type RetryCondition
- func And(conditions ...RetryCondition) RetryCondition
- func Or(conditions ...RetryCondition) RetryCondition
- func ProxyRetryCondition(rotator *ProxyRotator) RetryCondition
- func RetryOnErr() RetryCondition
- func RetryOnGatewayErrors() RetryCondition
- func RetryOnRateLimit() RetryCondition
- func RetryOnTransientErrors() RetryCondition
- type RetryOptions
- type RetryOverride
- type SQLCookieStorage
- type SSEEvent
- type SocketIOConfig
- type SocketIOConn
- func (s *SocketIOConn) Close() error
- func (s *SocketIOConn) Connected() bool
- func (s *SocketIOConn) Emit(event string, args ...any) error
- func (s *SocketIOConn) EmitVolatile(event string, args ...any) error
- func (s *SocketIOConn) EmitWithAck(ctx context.Context, event string, args ...any) ([]json.RawMessage, error)
- func (s *SocketIOConn) On(event string, handler func(args []json.RawMessage))
- func (s *SocketIOConn) OnAny(handler func(event string, args []json.RawMessage))
- func (s *SocketIOConn) OnClose(handler func())
- func (s *SocketIOConn) OnNamespace(nsp string) *NamespaceSocket
- func (s *SocketIOConn) OnReconnectFailed(handler func())
- func (s *SocketIOConn) OnReconnected(handler func())
- func (s *SocketIOConn) OnReconnecting(handler func(attempt int))
- func (s *SocketIOConn) ReconnectionAttempts() int
- func (s *SocketIOConn) SID() string
- type SourceIPRotator
- type StaticResolver
- type StdlibResolver
- type StickyKeyFunc
- type StreamResponse
- type TCPDelayRange
- type TraceInfo
- type TrafficInspector
- type Transport
- type Uint64String
- type UnixTimestamp
- type Unwrapper
- type ValidationError
- type WebSocketConn
Constants ΒΆ
const DefaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
DefaultUserAgent is the default User-Agent string used for HTTP requests.
Variables ΒΆ
var ( // ErrUnexpectedContentType indicates the response content type // does not match the expected format. A captive portal or // transparent proxy often causes this. ErrUnexpectedContentType = errors.New("aoni: unexpected content-type (possible captive portal or intercept)") // ErrCloudflareChallenge indicates a Cloudflare JS challenge or // CAPTCHA was detected in the response body. ErrCloudflareChallenge = errors.New("aoni: cloudflare challenge detected") // ErrChallengeRequired indicates that a WAF challenge (Cloudflare, CAPTCHA, etc.) // has been detected and solver verification is required. ErrChallengeRequired = errors.New("aoni: challenge verification required") // ErrResponseTooLarge indicates the response exceeded the size // limit configured via [Client.WithMaxResponseSize]. ErrResponseTooLarge = errors.New("aoni: response size limit exceeded") // ErrSSRFBlocked indicates the request was blocked because the // target resolved to a private or loopback address. Returned by // [Client.Request] when [Client.WithSSRFGuard] is enabled. ErrSSRFBlocked = errors.New("aoni: request blocked by SSRF guard") )
var ( // ChromeH2Settings provides HTTP/2 settings matching standard Google Chrome clients. ChromeH2Settings = HTTP2Settings{ HeaderTableSize: 65536, EnablePush: 0, InitialWindowSize: 6291456, MaxHeaderListSize: 262144, ConnectionFlow: 15663105, PriorityWeight: 255, PriorityExclusive: true, } // FirefoxH2Settings provides HTTP/2 settings matching standard Mozilla Firefox clients. FirefoxH2Settings = HTTP2Settings{ InitialStreamID: 3, HeaderTableSize: 65536, EnablePush: 0, InitialWindowSize: 131072, MaxFrameSize: 16384, ConnectionFlow: 12517377, PriorityWeight: 41, } )
var ( // AmazonCDNHeaderPool mimics AWS CloudFront and API Gateway tracing headers. AmazonCDNHeaderPool = []string{ "X-Amz-Trace-Id", "X-Amzn-RequestId", "X-Amz-Cf-Id", } // CloudflareHeaderPool mimics Cloudflare proxy and CDN headers. CloudflareHeaderPool = []string{ "CF-RAY", "CF-Connecting-IP", "CF-Visitor", "CF-IPCountry", } // GenericCDNHeaderPool mixes multiple standard cloud and CDN diagnostics headers. GenericCDNHeaderPool = []string{ "X-Request-ID", "X-Trace-ID", "X-Edge-Cache-Id", "X-Cloud-Trace-Context", "X-Correlation-ID", } )
Predefined realistic header pools to mimic popular Cloud/CDN networks.
var ( // PersonaChrome120Windows mimics Google Chrome 120 on Windows. PersonaChrome120Windows = Persona{ TLSID: utls.HelloChrome_120, H2Settings: ChromeH2Settings, UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", HeaderOrder: []string{ ":method", ":authority", ":scheme", ":path", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "upgrade-insecure-requests", "user-agent", "accept", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-user", "sec-fetch-dest", "referer", "accept-encoding", "accept-language", "cookie", "priority", }, P0fSignature: p0f.Windows10, } // PersonaChrome120Android mimics Google Chrome 120 on Android. PersonaChrome120Android = Persona{ TLSID: utls.HelloChrome_120, H2Settings: ChromeH2Settings, UserAgent: "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", HeaderOrder: []string{ ":method", ":authority", ":scheme", ":path", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "upgrade-insecure-requests", "user-agent", "accept", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-user", "sec-fetch-dest", "referer", "accept-encoding", "accept-language", "cookie", "priority", }, P0fSignature: p0f.Android, } // PersonaFirefox120Windows mimics Mozilla Firefox 120 on Windows. PersonaFirefox120Windows = Persona{ TLSID: utls.HelloFirefox_120, H2Settings: FirefoxH2Settings, UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0", HeaderOrder: []string{ ":method", ":path", ":authority", ":scheme", "user-agent", "accept", "accept-language", "accept-encoding", "referer", "cookie", "upgrade-insecure-requests", "sec-fetch-dest", "sec-fetch-mode", "sec-fetch-site", "sec-fetch-user", "priority", }, P0fSignature: p0f.Windows10, } // PersonaFirefox120Android mimics Mozilla Firefox 120 on Android. PersonaFirefox120Android = Persona{ TLSID: utls.HelloFirefox_120, H2Settings: FirefoxH2Settings, UserAgent: "Mozilla/5.0 (Android 13; Mobile; rv:120.0) Gecko/120.0 Firefox/120.0", HeaderOrder: []string{ ":method", ":path", ":authority", ":scheme", "user-agent", "accept", "accept-language", "accept-encoding", "referer", "cookie", "upgrade-insecure-requests", "sec-fetch-dest", "sec-fetch-mode", "sec-fetch-site", "sec-fetch-user", "priority", }, P0fSignature: p0f.Android, } // PersonaSafari17MacOS mimics Apple Safari 17 on macOS. PersonaSafari17MacOS = Persona{ TLSID: utls.HelloSafari_16_0, H2Settings: HTTP2Settings{ HeaderTableSize: 4096, EnablePush: 0, InitialWindowSize: 2097152, MaxFrameSize: 16384, ConnectionFlow: 10485760, PriorityWeight: 255, }, UserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", HeaderOrder: []string{ ":method", ":scheme", ":path", ":authority", "user-agent", "accept", "accept-language", "accept-encoding", "referer", "cookie", }, P0fSignature: p0f.MacOS, } // PersonaSafari17IOS mimics Apple Safari 17 on iOS. PersonaSafari17IOS = Persona{ TLSID: utls.HelloSafari_16_0, H2Settings: HTTP2Settings{ HeaderTableSize: 4096, EnablePush: 0, InitialWindowSize: 2097152, MaxFrameSize: 16384, ConnectionFlow: 10485760, PriorityWeight: 255, }, UserAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/605.1.15", HeaderOrder: []string{ ":method", ":scheme", ":path", ":authority", "user-agent", "accept", "accept-language", "accept-encoding", "referer", "cookie", }, P0fSignature: p0f.IOS, } )
var ChromeHTTP3Settings = HTTP3Settings{ InitialStreamReceiveWindow: 6291456, MaxStreamReceiveWindow: 6291456, InitialConnectionReceiveWindow: 15728640, MaxConnectionReceiveWindow: 15728640, MaxIncomingStreams: 100, MaxIncomingUniStreams: 100, EnableDatagrams: true, }
ChromeHTTP3Settings provides production-grade QUIC transport presets matching Google Chrome.
var DefaultClient = NewClient(nil)
DefaultClient is the shared default client instance used by global helper functions.
var DefaultSensitiveHeaders = []string{
"Authorization",
"Cookie",
"X-Session-ID",
"X-Access-Token",
"X-Access-Key",
"X-Api-Key",
"X-Auth-Token",
}
DefaultSensitiveHeaders lists headers removed from requests during cross-origin redirects. Used by DefaultRedirectPolicy.
var FirefoxHTTP3Settings = HTTP3Settings{ InitialStreamReceiveWindow: 6291456, MaxStreamReceiveWindow: 6291456, InitialConnectionReceiveWindow: 25165824, MaxConnectionReceiveWindow: 25165824, MaxIncomingStreams: 100, MaxIncomingUniStreams: 100, EnableDatagrams: false, }
FirefoxHTTP3Settings provides production-grade QUIC transport presets matching Mozilla Firefox.
Functions ΒΆ
func AppendContextModifier ΒΆ added in v0.3.0
func AppendContextModifier(ctx context.Context, mods ...RequestModifier) context.Context
AppendContextModifier appends new modifiers to an existing context carrying modifiers, or creates a new one if none are present.
func ApplyTCPDelay ΒΆ added in v0.5.0
ApplyTCPDelay reads the delay range from ctx and sleeps for a uniformly distributed random duration within it. It respects context cancellation. Returns ctx.Err() if the context is cancelled during the sleep, nil otherwise.
func CurlCommand ΒΆ
CurlCommand generates a shell-compatible curl command string from an http.Request and body.
func DecodeByContentType ΒΆ added in v0.3.0
DecodeByContentType automatically parses the stream from r into target by selecting the most appropriate registered decoder based on the parsed MIME-type. Falls back to RawDecoder if the content type is unrecognized or raw binary is returned.
func DecodeJSON ΒΆ added in v0.3.0
DecodeJSON is a convenience helper to directly decode a JSON stream into T.
func DecodeTo ΒΆ added in v0.3.0
DecodeTo decodes the data from r using the provided decoder into a newly allocated T.
func DecodeXML ΒΆ added in v0.3.0
DecodeXML is a convenience helper to directly decode an XML stream into T.
func DecodeYAML ΒΆ added in v0.3.0
DecodeYAML is a convenience helper to directly decode a YAML stream into T.
func DefaultCircuitBreakerCondition ΒΆ
DefaultCircuitBreakerCondition returns true for network errors and HTTP status codes >= 500.
func DefaultRedirectPolicy ΒΆ
func DefaultRedirectPolicy( maxRedirects int, sensitiveHeaders ...string, ) func(req *http.Request, via []*http.Request) error
DefaultRedirectPolicy returns a function suitable for http.Client.CheckRedirect. It stops after maxRedirects and strips sensitiveHeaders on cross-origin redirects. When sensitiveHeaders is empty, DefaultSensitiveHeaders is used.
func Delete ΒΆ
func Delete(ctx context.Context, c Requester, path string, body any, mods ...RequestModifier) (*http.Response, error)
Delete executes a DELETE request through the specified Requester and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func DeleteTo ΒΆ added in v0.4.0
func DeleteTo[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, error)
DeleteTo executes a DELETE request, marshals the body, and decodes the response body into Resp. It returns an APIError if the server responds with a non-2xx status code.
By default, the request body is marshaled to JSON and the response is parsed as JSON.
To send other body formats, pre-serialize the payload and pass it as an io.Reader (e.g. strings.NewReader), then override the Content-Type header using WithContentType. To decode other response formats (such as XML or YAML), pass a decoder modifier, e.g. WithXMLDecoder or WithYAMLDecoder.
func DeleteToEx ΒΆ added in v0.4.0
func DeleteToEx[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, *http.Response, error)
DeleteToEx is like DeleteTo but returns both the parsed response payload and the raw *http.Response.
func DetectCloudflareChallenge ΒΆ added in v0.4.0
DetectCloudflareChallenge checks if the response is a Cloudflare WAF/JS challenge.
func DialWebSocket ΒΆ
func DialWebSocket( ctx context.Context, c *Client, targetURL string, mods ...RequestModifier, ) (net.Conn, *http.Response, error)
DialWebSocket establishes a WebSocket connection using the same uTLS/JA4 pipeline as regular HTTP requests. It respects proxy configuration, source IP rotation, SSRF guards, and Happy Eyeballs dialing.
The returned net.Conn is a full-duplex byte stream over WebSocket. For wss:// connections, the TLS handshake uses the client's configured browser fingerprint (via Client.WithTLSFingerprint), and JA4 fingerprints are computed during the handshake.
Use TraceJA4 to capture both TLS (JA4) and HTTP (JA4H) fingerprints:
info := &aoni.TraceInfo{}
wsConn, resp, err := aoni.DialWebSocket(ctx, client, "wss://example.com/ws",
aoni.WithHeader("Origin", "https://example.com"),
aoni.TraceJA4(info),
)
fmt.Println(info.JA4.JA4) // TLS fingerprint from the WebSocket handshake
func DialWebSocketWithConfig ΒΆ
func DialWebSocketWithConfig( ctx context.Context, c *Client, targetURL string, config DialWebSocketConfig, mods ...RequestModifier, ) (net.Conn, *http.Response, error)
DialWebSocketWithConfig is like DialWebSocket but allows custom buffer sizes.
func ExportCookiesJSON ΒΆ added in v0.3.0
ExportCookiesJSON serializes the exported cookies for the given URL directly into a JSON string.
func GeneratePadding ΒΆ added in v0.2.0
func GeneratePadding(cfg PaddingConfig) []byte
GeneratePadding returns random padding bytes of the configured length range.
func Get ΒΆ
func Get(ctx context.Context, c Requester, path string, mods ...RequestModifier) (*http.Response, error)
Get performs a GET request through the specified Requester and returns the raw http.Response.
func GetCacheTTL ΒΆ added in v0.5.0
GetCacheTTL returns the per-request cache TTL set by WithCacheTTL. The second return value is false when no TTL has been set.
func GetConnMetadata ΒΆ added in v0.5.0
GetConnMetadata retrieves a value previously set by WithConnMetadata.
func GetInsecureSkipVerify ΒΆ added in v0.5.0
GetInsecureSkipVerify reports whether the request carries a per-request InsecureSkipVerify flag set by WithInsecureSkipVerify.
func GetProxyOverride ΒΆ added in v0.5.0
GetProxyOverride returns the per-request proxy URL stored by WithProxyOverride. The second return value is false when no override is set.
func GetResponseValidator ΒΆ added in v0.5.0
GetResponseValidator returns the per-request validator registered by WithResponseValidator, or nil when none is set.
func GetTo ΒΆ added in v0.4.0
func GetTo[Resp any]( ctx context.Context, c Requester, path string, mods ...RequestModifier, ) (*Resp, error)
GetTo performs a GET request and decodes the response body into a new instance of Resp. It returns an APIError if the server responds with a non-2xx status code.
By default, the response is parsed as JSON. To decode other response formats (such as XML or YAML), pass a corresponding decoder modifier, e.g. WithXMLDecoder or WithYAMLDecoder.
func GetToEx ΒΆ added in v0.4.0
func GetToEx[Resp any]( ctx context.Context, c Requester, path string, mods ...RequestModifier, ) (*Resp, *http.Response, error)
GetToEx is like GetTo but returns both the parsed response payload and the raw *http.Response.
func HostRewriteRules ΒΆ added in v0.3.0
HostRewriteRules extracts and returns the active host rewrite rules map from the given context. Returns nil if no rules are configured in the context.
func ImportCookies ΒΆ
func ImportCookies(jar http.CookieJar, u *url.URL, cookies []CookieData)
ImportCookies imports cookies from the browser/automation data into http.CookieJar.
func ImportCookiesJSON ΒΆ added in v0.3.0
ImportCookiesJSON deserializes cookies from a JSON string and imports them into http.CookieJar.
func MarkModifierError ΒΆ added in v0.5.0
MarkModifierError attaches an error to the request context. The Client will check for this error before dispatching the request and return it if present, preventing malformed requests from being sent.
func MirrorCookies ΒΆ added in v0.2.0
func MirrorCookies(jar http.CookieJar, sourceURL *url.URL, targetURLs []*url.URL, cookieNames ...string)
MirrorCookies copies cookies with the specified names from the sourceURL to all targetURLs within a single jar.
func NewFragmentedConn ΒΆ
func NewFragmentedConn(conn net.Conn, cfg *FragmentConfig) net.Conn
NewFragmentedConn wraps a net.Conn with fragmentation and delay settings.
func NewProxyClient ΒΆ
func NewProxyClient(cfg ProxyConfig) (*http.Client, error)
NewProxyClient creates an http.Client configured with proxy transport. It prioritizes ProxyConfig.TransportFactory, then ProxyConfig.Transport, and falls back to a default http.Transport if neither is provided.
If ProxyConfig.ProxyURL is empty, no proxy routing is applied. If ProxyConfig.Timeout is zero, a default 15-second timeout is set.
func NewStdClient ΒΆ added in v0.2.0
NewStdClient returns a standard http.Client whose transport routes all requests through the configured aoni Client pipeline.
The returned client has Jar set to nil to avoid double cookie handling. The aoni ProxyIsolatedCookieJar manages cookies internally.
Usage:
client := aoni.NewClient(nil).
WithTLSFingerprint(aoni.BrowserChrome).
WithDoHResolver()
stdClient := aoni.NewStdClient(client)
// Use with any third-party library
restyClient.SetHTTPClient(stdClient)
func PaddingHeaderName ΒΆ added in v0.2.0
func PaddingHeaderName(cfg PaddingConfig) string
PaddingHeaderName returns a header name for padding. If HeaderPool is configured, a random entry is selected to avoid creating a static DPI fingerprint. Otherwise PaddingHeader is used, falling back to "X-Padding".
func ParseAutoProxy ΒΆ added in v0.4.0
ParseAutoProxy parses a proxy string and detects the protocol.
func ParseSSE ΒΆ
func ParseSSE[T any](ctx context.Context, resp *StreamResponse) (<-chan T, <-chan error)
ParseSSE parses a Server-Sent Event stream and returns a channel of parsed events and an error channel.
func Patch ΒΆ
func Patch(ctx context.Context, c Requester, path string, body any, mods ...RequestModifier) (*http.Response, error)
Patch executes a PATCH request through the specified Requester and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func PatchTo ΒΆ added in v0.4.0
func PatchTo[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, error)
PatchTo executes a PATCH request, marshals the body, and decodes the response body into Resp. It returns an APIError if the server responds with a non-2xx status code.
By default, the request body is marshaled to JSON and the response is parsed as JSON.
To send other body formats, pre-serialize the payload and pass it as an io.Reader (e.g. strings.NewReader), then override the Content-Type header using WithContentType. To decode other response formats (such as XML or YAML), pass a decoder modifier, e.g. WithXMLDecoder or WithYAMLDecoder.
func PatchToEx ΒΆ added in v0.4.0
func PatchToEx[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, *http.Response, error)
PatchToEx is like PatchTo but returns both the parsed response payload and the raw *http.Response.
func Post ΒΆ
func Post(ctx context.Context, c Requester, path string, body any, mods ...RequestModifier) (*http.Response, error)
Post executes a POST request through the specified Requester and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
Use WithFormBody or WithFormValues to create PostForm requests.
func PostTo ΒΆ added in v0.4.0
func PostTo[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, error)
PostTo executes a POST request, marshals the body, and decodes the response body into Resp. It returns an APIError if the server responds with a non-2xx status code.
By default, the request body is marshaled to JSON and the response is parsed as JSON.
To send other body formats, pre-serialize the payload and pass it as an io.Reader (e.g. strings.NewReader), then override the Content-Type header using WithContentType. To decode other response formats (such as XML or YAML), pass a decoder modifier, e.g. WithXMLDecoder or WithYAMLDecoder.
Use WithFormBody or WithFormValues to create PostForm requests.
func PostToEx ΒΆ added in v0.4.0
func PostToEx[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, *http.Response, error)
PostToEx is like PostTo but returns both the parsed response payload and the raw *http.Response.
func ProxyFuncWithOverride ΒΆ added in v0.5.0
func ProxyFuncWithOverride(base func(*http.Request) (*url.URL, error)) func(*http.Request) (*url.URL, error)
ProxyFuncWithOverride wraps a base proxy function (e.g. http.ProxyURL or http.ProxyFromEnvironment) so that a per-request WithProxyOverride value takes precedence. Pass the result as http.Transport.Proxy.
transport.Proxy = aoni.ProxyFuncWithOverride(http.ProxyFromEnvironment)
func Put ΒΆ
func Put(ctx context.Context, c Requester, path string, body any, mods ...RequestModifier) (*http.Response, error)
Put executes a PUT request through the specified Requester and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func PutTo ΒΆ added in v0.4.0
func PutTo[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, error)
PutTo executes a PUT request, marshals the body, and decodes the response body into Resp. It returns an APIError if the server responds with a non-2xx status code.
By default, the request body is marshaled to JSON and the response is parsed as JSON.
To send other body formats, pre-serialize the payload and pass it as an io.Reader (e.g. strings.NewReader), then override the Content-Type header using WithContentType. To decode other response formats (such as XML or YAML), pass a decoder modifier, e.g. WithXMLDecoder or WithYAMLDecoder.
func PutToEx ΒΆ added in v0.4.0
func PutToEx[Resp any]( ctx context.Context, c Requester, path string, body any, mods ...RequestModifier, ) (*Resp, *http.Response, error)
PutToEx is like PutTo but returns both the parsed response payload and the raw *http.Response.
func ReadAllBytes ΒΆ added in v0.3.0
func ReadAllBytes(rb ReplayableBody) ([]byte, error)
ReadAllBytes reads the entire content of a ReplayableBody as a byte slice, and automatically resets the body so it remains completely reusable.
func ReadAllString ΒΆ added in v0.3.0
func ReadAllString(rb ReplayableBody) (string, error)
ReadAllString reads the entire content of a ReplayableBody as a string, and automatically resets the body so it remains completely reusable. This is a high-level helper for quick logging and assertions.
func StreamChunks ΒΆ added in v0.3.0
func StreamChunks(ctx context.Context, resp *StreamResponse) (<-chan string, <-chan error)
StreamChunks reads raw data from the stream chunk-by-chunk and yields them as strings. This is a high-level helper suitable for or real-time streaming.
func StreamNDJSON ΒΆ
func StreamNDJSON[T any](ctx context.Context, resp *StreamResponse) (<-chan T, <-chan error)
StreamNDJSON reads a newline-delimited JSON stream from the StreamResponse body. It parses values concurrently in a background goroutine and pushes them to the returned channel. It automatically closes channels and connection streams when done or on context cancellation.
func StreamSSE ΒΆ
func StreamSSE[T any]( ctx context.Context, c Requester, path string, mods ...RequestModifier, ) (<-chan T, <-chan error, error)
StreamSSE parses incoming Server-Sent Events from the StreamResponse body. It executes a background parsing loop and closes returned channels when done.
func StructToValues ΒΆ
StructToValues encodes a struct into url.Values using "url" or "json" tags. It expands inline structs recursively and supports slices, arrays, and primitive types. Returns an error if the input is not a struct or pointer to a struct.
func TLSConfigWithOverride ΒΆ added in v0.5.0
TLSConfigWithOverride clones base and applies any per-request overrides found in ctx (currently WithInsecureSkipVerify). Returns base unchanged when no overrides are present so no unnecessary allocations occur.
func UnwrapTo ΒΆ added in v0.2.0
UnwrapTo traverses the decorator chain c and returns the first layer that implements the generic type T, as well as true. If no matching layer is found, returns the null value of T and false.
func Validate ΒΆ
Validate checks struct fields for the "validate:required" tag. It returns a ValidationError for the first missing required field.
func WithContextModifier ΒΆ added in v0.2.0
func WithContextModifier(ctx context.Context, mods ...RequestModifier) context.Context
WithContextModifier returns a new context carrying the given RequestModifiers. Third-party libraries that pass context through http.Request will carry these modifiers into the aoni pipeline automatically.
Example with go-resty:
ctx := aoni.WithContextModifier(context.Background(),
aoni.WithHeader("X-Api-Key", "secret"),
aoni.TraceJA4(info),
)
resp, err := restyClient.R().SetContext(ctx).Get("/api/data")
Types ΒΆ
type APIError ΒΆ
APIError wraps a non-2xx HTTP response. StatusCode holds the status code, Body holds the raw response, and Model holds the deserialized error structure when WithErrorModel was used. Inspect with errors.As.
type Backend ΒΆ
type Backend struct {
// URL is the address of the backend server.
URL string
// Weight is the selection weight for the [WeightedRoundRobin] strategy.
Weight int
*HealthTracker
// contains filtered or unexported fields
}
Backend tracks the health and connection state of a single server in the load balancer.
type BackoffStrategy ΒΆ added in v0.3.0
BackoffStrategy Defines the interface for calculating delays before reconnecting. Allows the implementation of custom attenuation strategies (exponential, linear, Fibonacci, etc.).
type BaseResponse ΒΆ
type BaseResponse interface {
// IsSuccess reports whether the response indicates a successful operation.
IsSuccess() bool
// Error returns an error representation if IsSuccess returns false.
Error() error
// SetData sets the data into the response.
SetData(data any)
}
BaseResponse is implemented by user-defined response wrappers that participate in GetTo and similar generic request helpers. The decoder calls IsSuccess, SetData, and Error to route the result.
type BaseResponseProvider ΒΆ
type BaseResponseProvider interface {
BaseResponse() BaseResponse
}
BaseResponseProvider optionally provides a BaseResponse for structured decoding. Implemented by response wrapper types used with Client.WithBaseResponse.
type BoolInt ΒΆ
type BoolInt bool
BoolInt parses booleans from integers or strings in JSON. It maps 1, "1", "true" to true and 0, "0", "false", "null" to false.
func (BoolInt) MarshalJSON ΒΆ added in v0.3.0
MarshalJSON serializes BoolInt back as numeric "1" or "0" JSON representations.
func (*BoolInt) UnmarshalJSON ΒΆ
UnmarshalJSON implements json.Unmarshaler.
type BridgeError ΒΆ added in v0.3.0
BridgeError represents an error occurring during standard-client bridging. It implements the standard error interface and can be unwrapped to retrieve the underlying client or transport errors.
func (*BridgeError) Error ΒΆ added in v0.3.0
func (e *BridgeError) Error() string
Error implements the standard error interface.
func (*BridgeError) Unwrap ΒΆ added in v0.3.0
func (e *BridgeError) Unwrap() error
Unwrap returns the underlying wrapped error.
type BrowserID ΒΆ
type BrowserID int
BrowserID selects a uTLS ClientHello profile for JA3 fingerprint emulation. Pass to Client.WithTLSFingerprint.
const ( // BrowserNone disables TLS fingerprint emulation. BrowserNone BrowserID = iota // BrowserChrome emulates Google Chrome TLS fingerprints. BrowserChrome // BrowserFirefox emulates Mozilla Firefox TLS fingerprints. BrowserFirefox // BrowserSafari emulates Apple Safari TLS fingerprints. BrowserSafari )
type CapturedRequest ΒΆ added in v0.4.0
type CapturedRequest struct {
ID int64 `json:"id"`
Timestamp time.Time `json:"timestamp"`
Method string `json:"method"`
URL string `json:"url"`
Status int `json:"status"`
StatusText string `json:"status_text"`
Duration time.Duration `json:"duration"`
DurationStr string `json:"duration_str"`
RemoteAddr string `json:"remote_addr"`
RequestSize int64 `json:"request_size"`
ResponseSize int64 `json:"response_size"`
JA4 string `json:"ja4"`
JA4Protocol string `json:"ja4_protocol"`
JA4SNI string `json:"ja4_sni"`
H2Settings string `json:"h2_settings"`
RequestHeaders map[string]string `json:"request_headers"`
ResponseHeaders map[string]string `json:"response_headers"`
DNSLookup time.Duration `json:"dns_lookup"`
TCPConn time.Duration `json:"tcp_conn"`
TLSHandshake time.Duration `json:"tls_handshake"`
ServerProcessing time.Duration `json:"server_processing"`
ContentTransfer time.Duration `json:"content_transfer"`
}
CapturedRequest represents a request logged by the traffic inspector.
type ChallengeDetector ΒΆ added in v0.4.0
ChallengeDetector is a function type that decides whether a response represents a WAF challenge. It returns true and the associated error if a challenge is detected.
var DefaultChallengeDetector ChallengeDetector = DetectCloudflareChallenge
DefaultChallengeDetector is the default detector used by Client.
type ChallengeSolver ΒΆ added in v0.4.0
type ChallengeSolver interface {
Solve(ctx context.Context, err error, req *http.Request) (*http.Response, error)
}
ChallengeSolver defines a standard interface to delegate WAF challenge solving to an external driver (like Playwright, Puppeteer, or Selenium).
type ChaosConfig ΒΆ
type ChaosConfig struct {
// FailureRate is the probability (0.0 to 1.0) of randomly returning a 503 error.
FailureRate float64
// LatencyMin is the minimum artificial delay duration applied to requests.
LatencyMin time.Duration
// LatencyMax is the maximum artificial delay duration applied to requests.
LatencyMax time.Duration
}
ChaosConfig defines parameters for ChaosMiddleware.
type CircuitBreaker ΒΆ
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker tracks per-host connection health using a sliding window. After the failure ratio within CircuitBreakerConfig.Window exceeds CircuitBreakerConfig.FailureThreshold, the circuit opens and rejects requests for CircuitBreakerConfig.Cooldown. It then enters half-open and allows a single trial request; success closes it.
func NewCircuitBreaker ΒΆ
func NewCircuitBreaker(cfg CircuitBreakerConfig) *CircuitBreaker
NewCircuitBreaker creates a CircuitBreaker with cfg. Zero fields default to 50% failure threshold, 10s window, 5 min requests, and 5s cooldown.
type CircuitBreakerConfig ΒΆ
type CircuitBreakerConfig struct {
// FailureThreshold is the ratio of failures (0.0 to 1.0) that triggers the open state.
FailureThreshold float64
// Cooldown is the duration the breaker remains open before transitioning to half-open.
Cooldown time.Duration
// MinRequests is the minimum number of requests in a Window before threshold check is active.
MinRequests int
// Window is the sliding time duration over which failures are tracked.
Window time.Duration
}
CircuitBreakerConfig tunes the thresholds for CircuitBreaker. It wraps breaker.Config with a per-host map.
type Client ΒΆ
type Client struct {
// contains filtered or unexported fields
}
Client is an immutable, concurrency-safe HTTP client built on HTTPDoer. Every With* method returns a new clone, so the original remains usable by other goroutines. Use NewClient to create the first instance.
func NewClient ΒΆ
NewClient creates a Client wrapping httpClient. When httpClient is nil a default http.Client with a 15-second timeout and DefaultRedirectPolicy (10 hops) is used. The returned client has DefaultUserAgent set and a transport dialer configured for Happy Eyeballs.
func UnwrapClient ΒΆ
UnwrapClient strips all Unwrapper layers from r and returns the innermost Client. Returns nil if r is not a *Client and no Unwrapper chain leads to one.
func (*Client) BaseResponse ΒΆ
func (c *Client) BaseResponse() BaseResponse
BaseResponse returns a new BaseResponse wrapper if a provider is configured on the client. Returns nil if no provider is set.
func (*Client) Clone ΒΆ
Clone returns a deep copy of c. The cloned client shares nothing mutable with the original - transport, cookie jar, and config structs are all independently copied.
func (*Client) CloseIdleConnections ΒΆ
func (c *Client) CloseIdleConnections()
CloseIdleConnections closes any idle keep-alive connections maintained by the client. This only works if the underlying HTTPDoer is an http.Client.
func (*Client) Delete ΒΆ added in v0.4.0
func (c *Client) Delete(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
Delete executes a DELETE request through the Client and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func (*Client) EnableInspector ΒΆ added in v0.4.0
EnableInspector enables the traffic inspector dashboard at the specified address (e.g. ":8080").
func (*Client) Get ΒΆ added in v0.4.0
func (c *Client) Get(ctx context.Context, path string, mods ...RequestModifier) (*http.Response, error)
Get performs a GET request through the Client and returns the raw http.Response.
func (*Client) Inspector ΒΆ added in v0.4.0
func (c *Client) Inspector() *TrafficInspector
Inspector returns the configured TrafficInspector if enabled.
func (*Client) Logger ΒΆ
Logger returns the logger used by the client. If no logger is set, a no-op logger is returned.
func (*Client) Patch ΒΆ added in v0.4.0
func (c *Client) Patch(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
Patch executes a PATCH request through the Client and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func (*Client) Post ΒΆ added in v0.4.0
func (c *Client) Post(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
Post executes a POST request through the Client and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func (*Client) Put ΒΆ added in v0.4.0
func (c *Client) Put(ctx context.Context, path string, body any, mods ...RequestModifier) (*http.Response, error)
Put executes a PUT request through the Client and returns the raw http.Response.
By default, if the body is a struct or map, it is marshaled to JSON and the request headers "Content-Type" and "Accept" are set to "application/json".
To send other body formats (e.g. XML, YAML, or plain text), pre-serialize the payload and pass it as an io.Reader (e.g. using strings.NewReader or bytes.NewReader), then override the Content-Type header using request modifiers like WithContentType (e.g. WithContentType("application/xml")).
func (*Client) Request ΒΆ
func (c *Client) Request( ctx context.Context, method, path string, mods ...RequestModifier, ) (*http.Response, error)
Request sends an HTTP request and returns the response. path is resolved against Client.WithBaseURL when set; an empty path targets the base URL directly. Nil modifiers are ignored.
Decompression (gzip, brotli, zstd) and charset transcoding to UTF-8 are applied automatically. The response body is wrapped with a GC finalizer so that unclosed bodies eventually release the underlying connection.
Returns ErrSSRFBlocked when SSRF guarding is on and the target resolves to a private or loopback address. Returns ErrResponseTooLarge when a response size limit is configured and the body exceeds it.
func (*Client) Transport ΒΆ
Transport returns the underlying http.Transport of the client. Returns nil if the HTTPDoer is not an http.Client or its transport is not an http.Transport.
func (*Client) WithAfterResponse ΒΆ
WithAfterResponse returns a clone of c that calls hook after every request, regardless of success or failure.
func (*Client) WithBaseResponse ΒΆ
func (c *Client) WithBaseResponse(provider func() BaseResponse) *Client
WithBaseResponse returns a clone of c that uses provider to create BaseResponse wrappers for structured decoding. Pass nil to clear.
func (*Client) WithBaseURL ΒΆ
WithBaseURL returns a clone of c that resolves relative paths in Client.Request against raw. An empty string clears the base URL. If raw is not a valid URL, the original client is returned unchanged.
func (*Client) WithBasicAuth ΒΆ added in v0.2.0
WithBasicAuth returns a clone of c that sends Basic authentication credentials on every request.
func (*Client) WithBearer ΒΆ added in v0.2.0
WithBearer returns a clone of c that sends token as a Bearer Authorization header on every request.
func (*Client) WithBeforeRequest ΒΆ
WithBeforeRequest returns a clone of c that calls hook before every request. Hooks execute in registration order.
func (*Client) WithBrowserProfile ΒΆ added in v0.3.0
WithBrowserProfile configures both the TLS fingerprint, matching HTTP/2 framed settings, and default browser headers (like User-Agent, Sec-Ch-Ua, and Accept orders) in a single call. This prevents fingerprint mismatches between TLS and HTTP/2 layers. Use [WithH2FramedTransport] and WithUserAgent to configure HTTP/2 settings and User-Agent separately.
func (*Client) WithChallengeDetector ΒΆ added in v0.4.0
func (c *Client) WithChallengeDetector(detector ChallengeDetector) *Client
WithChallengeDetector returns a clone of c configured with the specified ChallengeDetector.
func (*Client) WithChallengeSolver ΒΆ added in v0.4.0
func (c *Client) WithChallengeSolver(solver ChallengeSolver) *Client
WithChallengeSolver returns a clone of c configured with the specified ChallengeSolver.
func (*Client) WithConnectionPool ΒΆ
func (c *Client) WithConnectionPool(cfg ConnectionPoolConfig) *Client
WithConnectionPool returns a clone of c with the transport pool tuned to cfg. Fields left at zero keep the existing transport settings. Only effective when the underlying HTTPDoer is an http.Client with an http.Transport.
func (*Client) WithCookieJar ΒΆ
WithCookieJar returns a clone of c that stores and sends cookies through jar. Only effective when the underlying HTTPDoer is an http.Client.
func (*Client) WithDNSCache ΒΆ
WithDNSCache returns a clone of c that caches DNS results for ttl. The cache wraps the current DNS resolver.
func (*Client) WithDNSResolver ΒΆ
func (c *Client) WithDNSResolver(resolver DNSResolver) *Client
WithDNSResolver returns a clone of c that resolves hostnames through resolver instead of the system resolver.
func (*Client) WithDoH ΒΆ added in v0.2.0
WithDoH returns a clone of c that resolves DNS via DNS-over-HTTPS using endpoint as the resolver URL and host as the HTTP Host header. See NewDoHResolver.
func (*Client) WithDoT ΒΆ added in v0.2.0
WithDoT returns a clone of c that resolves DNS via DNS-over-TLS using endpoint as the resolver address and host as the TLS server name. See NewDoTResolver.
func (*Client) WithDynamicHedging ΒΆ added in v0.2.0
func (c *Client) WithDynamicHedging(config *DynamicHedgingConfig) *Client
WithDynamicHedging returns a clone of c that computes the hedging delay dynamically from the p95 RTT of recent requests. When config is nil, DefaultDynamicHedgingConfig values are used.
func (*Client) WithFragmentation ΒΆ
func (c *Client) WithFragmentation(cfg FragmentConfig) *Client
WithFragmentation returns a clone of c that splits the TLS ClientHello across multiple TCP segments according to cfg. See FragmentConfig.
func (*Client) WithH2FramedTransport ΒΆ added in v0.2.0
func (c *Client) WithH2FramedTransport(settings HTTP2Settings) *Client
WithH2FramedTransport returns a clone of c that injects browser- specific SETTINGS and PRIORITY frames into the HTTP/2 connection preface. This makes the HTTP/2 fingerprint match the TLS profile set by Client.WithTLSFingerprint.
func (*Client) WithHTTP2Settings ΒΆ
func (c *Client) WithHTTP2Settings(settings HTTP2Settings) *Client
WithHTTP2Settings returns a clone of c with custom HTTP/2 connection parameters. These values are stored on the client but only take effect when Client.WithH2FramedTransport is also configured.
func (*Client) WithHTTP3 ΒΆ
WithHTTP3 returns a clone of c that sends requests over HTTP/3 (QUIC). Uses DefaultQUICMigrationConfig for migration settings.
func (*Client) WithHTTP3Config ΒΆ added in v0.2.0
func (c *Client) WithHTTP3Config(config *QUICMigrationConfig) *Client
WithHTTP3Config returns a clone of c that sends requests over HTTP/3 (QUIC) with migration settings from config. When config is nil, DefaultQUICMigrationConfig values are used.
func (*Client) WithHTTP3Settings ΒΆ added in v0.4.0
func (c *Client) WithHTTP3Settings(settings HTTP3Settings) *Client
WithHTTP3Settings returns a clone of c configured with custom HTTP/3 (QUIC) settings.
func (*Client) WithHappyEyeballs ΒΆ
WithHappyEyeballs returns a clone of c that staggers parallel connection attempts by delay per address. A duration <= 0 disables staggering and tries all addresses simultaneously.
func (*Client) WithHeader ΒΆ
WithHeader returns a clone of c with key set to value on every outgoing request. Overwrites any existing value for key.
func (*Client) WithHeaders ΒΆ added in v0.5.0
WithHeaders returns a clone of c with updated headers on every outgoing request. Overwrites any existing values for keys.
func (*Client) WithHedging ΒΆ
WithHedging returns a clone of c that dispatches a second request after d if the first has not completed. A duration <= 0 disables hedging.
func (*Client) WithHostRewrite ΒΆ
WithHostRewrite returns a clone of c that resolves hostnames in requests according to rules (host -> ip), while keeping the original hostname for TLS SNI.
func (*Client) WithInsecureSkipVerify ΒΆ added in v0.5.0
WithInsecureSkipVerify returns a clone of c that disables TLS certificate verification for all requests. Use WithInsecureSkipVerify (the RequestModifier variant) to limit the effect to a single request.
func (*Client) WithJA4Callback ΒΆ
WithJA4Callback returns a clone of c that calls fn after each TLS handshake with the ja4.Report. Requires Client.WithTLSFingerprint to be enabled.
func (*Client) WithLocalAddr ΒΆ
WithLocalAddr returns a clone of c that binds outgoing connections to addr. The local address is only used when its IP family (v4/v6) matches the target's family. Ignored when the underlying HTTPDoer is not an http.Client with an http.Transport.
func (*Client) WithLocalAddrPool ΒΆ
WithLocalAddrPool returns a clone of c that round-robins source IP addresses from addrs. Each outgoing connection binds to the next address in the pool. Invalid addresses are silently ignored.
func (*Client) WithLogger ΒΆ
WithLogger returns a clone of c that logs diagnostics through l.
func (*Client) WithMaxResponseSize ΒΆ
WithMaxResponseSize returns a clone of c that rejects response bodies larger than size bytes. A value <= 0 removes the limit.
func (*Client) WithModifiers ΒΆ
func (c *Client) WithModifiers(mods ...RequestModifier) *Client
WithModifiers returns a clone of c that applies mods to every outgoing request before the middleware chain.
func (*Client) WithMultiReadBody ΒΆ
WithMultiReadBody returns a clone of c that caches response bodies smaller than threshold bytes so they can be re-read. A value <= 0 disables caching.
func (*Client) WithOrigin ΒΆ
WithOrigin returns a clone of c that sends origin as the Origin header on every request.
func (*Client) WithP0fSignature ΒΆ
WithP0fSignature returns a clone of c that spoofs TCP/IP fields (TTL, Don't Fragment, window size) to match sig. The spoofing is applied via Dialer.Control before the SYN packet is sent, making the connection appear as the OS described by sig to passive fingerprinters such as p0f.
func (*Client) WithPacketPadding ΒΆ added in v0.2.0
func (c *Client) WithPacketPadding(cfg PaddingConfig) *Client
WithPacketPadding returns a clone of c that constrains TCP MSS and adds random padding headers to disrupt DPI length analysis. See PaddingConfig for available fields.
func (*Client) WithPersona ΒΆ added in v0.4.0
WithPersona returns a clone of c configured with all parameters of the target Persona. This sets up TLS ClientHello ID, HTTP/2 framed settings, default User-Agent, header serialization order, and p0f TCP spoofing signature in a single call, ensuring complete fingerprint consistency across all network layers.
func (*Client) WithProfileH2Settings ΒΆ added in v0.2.0
func (c *Client) WithProfileH2Settings(s profiles.H2Settings) *Client
WithProfileH2Settings returns a clone of c with HTTP/2 settings extracted from s. See H2SettingsFromProfile.
func (*Client) WithProxy ΒΆ added in v0.2.0
WithProxy returns a clone of c configured to route requests through proxyURL. Supported schemes: http, socks5, socks5h (for remote DNS resolution). When proxyURL is nil, proxy routing is disabled.
func (*Client) WithProxyAwareSessionCache ΒΆ added in v0.2.0
WithProxyAwareSessionCache returns a clone of c that resumes TLS sessions via a ProxyAwareSessionCache. The cache is invalidated automatically when the proxy or source IP changes, preventing servers from correlating sessions across different exit nodes.
func (*Client) WithProxyDNS ΒΆ added in v0.2.0
WithProxyDNS returns a clone of c that resolves hostnames through the configured SOCKS5 or HTTP CONNECT proxy instead of the local system resolver. This prevents the local ISP from observing DNS queries.
func (*Client) WithProxyIsolatedCookieJar ΒΆ
func (c *Client) WithProxyIsolatedCookieJar(jar *ProxyIsolatedCookieJar) *Client
WithProxyIsolatedCookieJar returns a clone of c that stores cookies per proxy URL in jar, preventing cross-proxy session leakage. See ProxyIsolatedCookieJar.
func (*Client) WithProxyString ΒΆ added in v0.4.0
WithProxyString returns a clone of c configured to route requests through a proxy string. If the proxy string lacks a scheme (e.g. "user:pass@1.2.3.4:8080"), the protocol (http or socks5) is automatically detected by probing the port or guessing based on the port number.
func (*Client) WithRedirectLimit ΒΆ
WithRedirectLimit returns a clone of c that stops following redirects after max. A value of 0 disables redirects entirely. A negative value restores Go's default behavior (10 hops).
func (*Client) WithRefererAutomaton ΒΆ added in v0.4.0
WithRefererAutomaton returns a clone of c with automatic Referer tracking enabled. Each request will automatically have its "Referer" header set to the URL of the previous request.
func (*Client) WithResponseValidator ΒΆ added in v0.5.0
WithResponseValidator returns a clone of c that calls fn after every successful HTTP round-trip, before the response body is decoded. If fn returns a non-nil error the request is treated as failed. This client-level validator runs before any per-request validator set via the WithResponseValidator RequestModifier; the per-request error wins.
func (*Client) WithSSRFGuard ΒΆ
WithSSRFGuard returns a clone of c that blocks requests resolving to private or loopback IP addresses. Returns ErrSSRFBlocked from Client.Request when triggered.
func (*Client) WithTCPDelay ΒΆ added in v0.5.0
WithTCPDelay returns a clone of c that sleeps for a random duration between min and max before every TCP dial. This simulates human-like connection timing and can confuse bot-detection heuristics. Use WithTCPDelay (the RequestModifier variant) to limit the delay to a single request; per-request values always win over this client-level default.
func (*Client) WithTLSClientHelloID ΒΆ added in v0.4.0
func (c *Client) WithTLSClientHelloID(id utls.ClientHelloID) *Client
WithTLSClientHelloID returns a clone of c that uses the specified uTLS ClientHelloID for TLS ClientHello emulation. Only effective when the underlying HTTPDoer is an http.Client with an http.Transport.
func (*Client) WithTLSFingerprint ΒΆ
WithTLSFingerprint returns a clone of c that uses uTLS to emulate a browser's TLS ClientHello. BrowserNone disables emulation. Only effective when the underlying HTTPDoer is an http.Client with an http.Transport.
func (*Client) WithTimeout ΒΆ
WithTimeout returns a clone of c whose requests time out after d. Only works when the underlying HTTPDoer is an http.Client. A duration <= 0 means no timeout.
func (*Client) WithUserAgent ΒΆ
WithUserAgent returns a clone of c that sends ua as the User-Agent header on every request.
func (*Client) WithoutHeaders ΒΆ added in v0.5.0
WithoutHeaders returns a clone of c with all headers removed.
type ClientWithProxy ΒΆ
ClientWithProxy pairs an HTTPDoer with a proxy URL.
type ConcurrentResult ΒΆ added in v0.4.0
type ConcurrentResult[Resp any] struct { // Index is the position of this result in the original input slice. Index int // Value is the decoded response payload. It is nil when Err is non-nil. Value *Resp // Err is any error returned by the request. It is nil on success. Err error }
ConcurrentResult holds the outcome of a single request in a concurrent fan-out.
func Concurrent ΒΆ added in v0.4.0
func Concurrent[Resp any]( ctx context.Context, c Requester, paths []string, fn func(ctx context.Context, c Requester, path string) (*Resp, error), ) []ConcurrentResult[Resp]
Concurrent executes fn for each path in paths concurrently using the provided Requester, collecting results preserving the original order of paths. The results slice always has the same length as paths. Each request inherits the parent context; individual cancellations do not affect sibling requests.
Example: fan-out GET requests.
results := aoni.Concurrent(ctx, client, paths,
func(ctx context.Context, c aoni.Requester, path string) (*MyType, error) {
return aoni.GetTo[MyType](ctx, c, path)
})
func ConcurrentWithMods ΒΆ added in v0.4.0
func ConcurrentWithMods[Resp any]( ctx context.Context, c Requester, paths []string, mods [][]RequestModifier, fn func(ctx context.Context, c Requester, path string, mods ...RequestModifier) (*Resp, error), ) []ConcurrentResult[Resp]
ConcurrentWithMods is like Concurrent but passes per-request modifiers alongside each path. The mods slice must have the same length as paths, or be nil/empty in which case no per-request modifiers are applied.
type ConnectionPoolConfig ΒΆ
type ConnectionPoolConfig struct {
// MaxIdleConns is the maximum number of idle connections across all hosts.
MaxIdleConns int
// MaxIdleConnsPerHost is the maximum number of idle connections kept per host.
MaxIdleConnsPerHost int
// MaxConnsPerHost is the maximum total number of connections allowed per host.
MaxConnsPerHost int
// IdleConnTimeout is the maximum duration an idle connection is kept open.
IdleConnTimeout time.Duration
// ResponseHeaderTimeout is the maximum duration to wait for reading response headers.
ResponseHeaderTimeout time.Duration
}
ConnectionPoolConfig tunes the http.Transport connection pool. Apply it with Client.WithConnectionPool.
type CookieData ΒΆ
type CookieData struct {
Name string `json:"name"`
Value string `json:"value"`
Domain string `json:"domain"`
Path string `json:"path"`
Expires time.Time `json:"expires"`
HTTPOnly bool `json:"httpOnly"`
Secure bool `json:"secure"`
}
CookieData holds the data for a cookie in a JSON-serializable structure compatible with standard browser automation tools.
func ExportCookies ΒΆ
func ExportCookies(jar http.CookieJar, u *url.URL) []CookieData
ExportCookies prepares cookies for loading into Playwright, Chromedp, or other automation engines.
type CookieStorageBackend ΒΆ added in v0.4.0
type CookieStorageBackend interface {
Save(key string, cookies []CookieData) error
Load(key string) ([]CookieData, error)
}
CookieStorageBackend defines the interface for persisting cookie jar states.
type DNSError ΒΆ added in v0.3.0
type DNSError struct {
// Host is the domain name that was queried for resolution.
Host string
// Resolver is the type of the resolver that failed (e.g., "DoH", "DoT", "InMemoryCache").
Resolver string
// Endpoint is the network address of the DNS server queried, if applicable.
Endpoint string
// Err is the underlying cause of the DNS resolution failure.
Err error
// IsTimeout indicates whether the failure was caused by a network timeout.
IsTimeout bool
}
DNSError represents an error occurring during DNS resolution in the aoni package. It implements the standard error interface and can be unwrapped to retrieve the underlying network or protocol error.
func (*DNSError) Temporary ΒΆ added in v0.3.0
Temporary reports whether the error is temporary. This is required to satisfy the net.Error interface.
type DNSResolver ΒΆ
DNSResolver resolves hostnames to IP addresses.
type Decoder ΒΆ
type Decoder interface {
// Decode reads data from r and unmarshals it into target.
Decode(r io.Reader, target any) error
}
Decoder decodes HTTP response bodies into target structures. Implementations include JSONDecoder, XMLDecoder, YAMLDecoder, and RawDecoder.
var JSONDecoder Decoder = DecoderFunc(func(r io.Reader, target any) error { return json.NewDecoder(r).Decode(target) })
JSONDecoder parses the response body as JSON into target.
var RawDecoder Decoder = rawDecoder{}
RawDecoder reads the entire response body into a byte slice. The target must be a *[]byte.
var XMLDecoder Decoder = DecoderFunc(func(r io.Reader, target any) error { return xml.NewDecoder(r).Decode(target) })
XMLDecoder parses the response body as XML into target.
var YAMLDecoder Decoder = DecoderFunc(func(r io.Reader, target any) error { return yaml.NewDecoder(r).Decode(target) })
YAMLDecoder parses the response body as YAML into target.
func LimitDecoder ΒΆ added in v0.3.0
LimitDecoder wraps an existing decoder, ensuring that no more than maxBytes are read from the input stream during the decoding process. This provides protection against memory exhaustion attacks or oversized payloads.
func NewJSONDecoder ΒΆ added in v0.3.0
func NewJSONDecoder(cfg JSONDecoderConfig) Decoder
NewJSONDecoder creates a custom Decoder configured with the specified parameters.
type DecoderFunc ΒΆ
DecoderFunc adapts a function to the Decoder interface.
type DialWebSocketConfig ΒΆ
type DialWebSocketConfig struct {
// ReadBufferSize sets the gorilla WebSocket read buffer (default 4096).
ReadBufferSize int
// WriteBufferSize sets the gorilla WebSocket write buffer (default 4096).
WriteBufferSize int
}
DialWebSocketConfig holds optional configuration for DialWebSocket.
type DoHResolver ΒΆ
type DoHResolver struct {
Endpoint string // IP-based URL, e.g. "https://1.1.1.1/dns-query"
Host string // Host header override, e.g. "cloudflare-dns.com"
// contains filtered or unexported fields
}
DoHResolver resolves DNS via HTTPS, supporting both A and AAAA records. Uses an isolated http.Client that connects directly to the DoH server by IP, bypassing the system resolver entirely to avoid circular DNS lookups.
func NewDoHResolver ΒΆ
func NewDoHResolver(endpoint, host string) *DoHResolver
NewDoHResolver creates a DoHResolver that queries the given IP-based endpoint. The endpoint should be an IP-based URL (e.g. "https://1.1.1.1/dns-query"), and host is the Host header value (e.g. "cloudflare-dns.com").
func (*DoHResolver) LookupIPAddr ΒΆ
LookupIPAddr queries both A and AAAA records via DoH.
type DoTResolver ΒΆ
type DoTResolver struct {
Endpoint string // e.g. "1.1.1.1:853"
Host string // TLS SNI, e.g. "cloudflare-dns.com"
Timeout time.Duration
TLSConfig *tls.Config
}
DoTResolver resolves DNS over TLS, querying both A and AAAA records. Uses github.com/miekg/dns for reliable DNS packet construction and parsing. If TLSConfig is nil, a default config is used with TLS 1.2 minimum version.
func NewDoTResolver ΒΆ
func NewDoTResolver(endpoint, host string) *DoTResolver
NewDoTResolver creates a DoTResolver with the specified server and TLS hostname.
func (*DoTResolver) LookupIPAddr ΒΆ
LookupIPAddr queries both A and AAAA records over TLS.
type DynamicHedgingConfig ΒΆ added in v0.2.0
type DynamicHedgingConfig struct {
// Tracker is the shared RTT tracker for measuring network latency.
Tracker *RTTTracker
// Percentile is the RTT percentile to use for delay calculation (default: 95).
Percentile float64
// MinDelay is the minimum hedging delay regardless of RTT (default: 50ms).
MinDelay time.Duration
// MaxDelay is the maximum hedging delay cap (default: 2s).
MaxDelay time.Duration
// Multiplier scales the percentile RTT to compute the delay (default: 1.5).
// The dynamic delay = min(MaxDelay, max(MinDelay, p95 * Multiplier)).
Multiplier float64
}
DynamicHedgingConfig configures the dynamic hedging delay calculation.
func DefaultDynamicHedgingConfig ΒΆ added in v0.2.0
func DefaultDynamicHedgingConfig() DynamicHedgingConfig
DefaultDynamicHedgingConfig returns sensible defaults for dynamic hedging.
func (DynamicHedgingConfig) ComputeDelay ΒΆ added in v0.2.0
func (c DynamicHedgingConfig) ComputeDelay() time.Duration
ComputeDelay calculates the dynamic hedging delay based on observed RTT data. If the tracker has insufficient samples (< 10), it returns MinDelay.
type FallbackFunc ΒΆ
FallbackFunc provides an alternate response when a request fails.
func FallbackJSON ΒΆ
func FallbackJSON(statusCode int, data any) FallbackFunc
FallbackJSON returns a FallbackFunc that responds with data serialized as JSON and the given statusCode.
func FallbackString ΒΆ added in v0.3.0
func FallbackString(statusCode int, text string) FallbackFunc
FallbackString returns a FallbackFunc that responds with plain text and the given statusCode.
type FallbackResolver ΒΆ added in v0.3.0
type FallbackResolver struct {
// contains filtered or unexported fields
}
FallbackResolver tries to resolve hostnames using a list of resolvers sequentially. If a resolver fails, it falls back to the next one.
func NewFallbackResolver ΒΆ added in v0.3.0
func NewFallbackResolver(resolvers ...DNSResolver) *FallbackResolver
NewFallbackResolver creates a new FallbackResolver with the given prioritized resolvers.
func (*FallbackResolver) LookupIPAddr ΒΆ added in v0.3.0
LookupIPAddr implements the DNSResolver interface by trying resolvers sequentially.
type FastRaceResolver ΒΆ added in v0.3.0
type FastRaceResolver struct {
// contains filtered or unexported fields
}
FastRaceResolver executes multiple DNS resolutions concurrently and returns the fastest successful result, canceling all other pending queries.
func NewFastRaceResolver ΒΆ added in v0.3.0
func NewFastRaceResolver(resolvers ...DNSResolver) *FastRaceResolver
NewFastRaceResolver instantiates a concurrent FastRaceResolver.
func (*FastRaceResolver) LookupIPAddr ΒΆ added in v0.3.0
LookupIPAddr resolves the host by racing all configured resolvers in parallel.
type Float64String ΒΆ
type Float64String float64
Float64String parses float64 values from string representations in JSON.
func (Float64String) MarshalJSON ΒΆ added in v0.3.0
func (f Float64String) MarshalJSON() ([]byte, error)
MarshalJSON serializes the Float64String back as a JSON string representation.
func (*Float64String) UnmarshalJSON ΒΆ
func (f *Float64String) UnmarshalJSON(b []byte) error
UnmarshalJSON parses JSON byte data into the Float64String target.
type FragmentConfig ΒΆ
type FragmentConfig struct {
ChunkSize int
// LimitBytes specifies the maximum number of bytes to subject to fragmentation.
// Once LimitBytes is exceeded, subsequent writes pass through seamlessly.
// Set to -1 to fragment the entire stream.
LimitBytes int64
MinChunkSize int
MaxChunkSize int
MaxDelay time.Duration
MinDelay time.Duration
}
FragmentConfig specifies the chunk size and inter-chunk delay for connection fragmentation.
type H2FramedTransport ΒΆ added in v0.2.0
H2FramedTransport wraps an *http.Transport to apply HTTP/2 frame impersonation. When DialTLSContext is called, the returned connection is wrapped in [h2framedConn] so that the initial SETTINGS and PRIORITY frames match the target browser fingerprint. If orderedKeys is set, HEADERS frames are also reordered.
func NewH2FramedTransport ΒΆ added in v0.2.0
func NewH2FramedTransport(base *http.Transport, settings HTTP2Settings, orderedKeys ...string) *H2FramedTransport
NewH2FramedTransport creates an H2FramedTransport from an existing transport and HTTP/2 settings. The transport's DialTLSContext is replaced to wrap connections with browser-specific HTTP/2 frame injection.
type HTTP2Settings ΒΆ
type HTTP2Settings struct {
HeaderTableSize uint32
EnablePush uint32
MaxConcurrentStreams uint32
InitialWindowSize uint32
MaxFrameSize uint32
MaxHeaderListSize uint32
ConnectionFlow uint32
InitialStreamID uint32
PriorityStreamDep uint32
PriorityExclusive bool
PriorityWeight uint8
}
HTTP2Settings holds the full set of HTTP/2 connection parameters for browser-grade frame impersonation. Each field maps directly to an HTTP/2 SETTINGS frame parameter or PRIORITY frame value.
func H2SettingsFromProfile ΒΆ added in v0.2.0
func H2SettingsFromProfile(s profiles.H2Settings) HTTP2Settings
H2SettingsFromProfile populates HTTP2Settings from a profiles.H2Settings.
func ParseHTTP2Settings ΒΆ added in v0.3.0
func ParseHTTP2Settings(jsonStr string) (HTTP2Settings, error)
ParseHTTP2Settings parses HTTP/2 settings from a JSON-encoded string. It supports snake_case, camelCase, and PascalCase field names, making it extremely convenient to import settings captured from Wireshark, browser developer tools, or TLS bypass scripts.
type HTTP3Settings ΒΆ added in v0.4.0
type HTTP3Settings struct {
InitialStreamReceiveWindow uint64
MaxStreamReceiveWindow uint64
InitialConnectionReceiveWindow uint64
MaxConnectionReceiveWindow uint64
MaxIncomingStreams int64
MaxIncomingUniStreams int64
EnableDatagrams bool
}
HTTP3Settings holds QUIC flow control and stream parameters for browser-grade HTTP/3 fingerprint impersonation. Each field directly configures the underlying QUIC transport layer parameters.
type HTTPDoer ΒΆ
HTTPDoer executes an http.Request and returns a response. http.Client satisfies this interface. Pass a DoerFunc to adapt a plain function.
func Chain ΒΆ
func Chain(doer HTTPDoer, middlewares ...Middleware) HTTPDoer
Chain wraps doer with middlewares from left to right: the first middleware in the slice executes first. Returns doer unmodified when middlewares is empty.
type HealthStatus ΒΆ added in v0.3.0
type HealthStatus int
HealthStatus represents the detailed state of a tracked endpoint.
const ( // StatusHealthy indicates the endpoint is fully functional with zero consecutive failures. StatusHealthy HealthStatus = iota // StatusDegraded indicates the endpoint is still functional but has experienced some failures. StatusDegraded // StatusUnhealthy indicates the endpoint has exceeded max failures and is currently in cooldown. StatusUnhealthy // StatusRecovering indicates the cooldown has elapsed and the endpoint is ready for a trial request. StatusRecovering )
func (HealthStatus) String ΒΆ added in v0.3.0
func (s HealthStatus) String() string
String returns a human-readable representation of the HealthStatus.
type HealthTracker ΒΆ added in v0.2.0
type HealthTracker struct {
// contains filtered or unexported fields
}
HealthTracker tracks the health state of a single endpoint (proxy or backend) using consecutive failure counting with automatic recovery after a cooldown.
func NewHealthTracker ΒΆ added in v0.2.0
func NewHealthTracker( name string, maxFails uint32, retryAfter time.Duration, onUnhealthy func(string, uint32, time.Duration), onRecovered func(string), ) *HealthTracker
NewHealthTracker creates a HealthTracker with the given parameters. onUnhealthy and onRecovered are called when the state changes; they may be nil.
func (*HealthTracker) CooldownRemaining ΒΆ added in v0.3.0
func (h *HealthTracker) CooldownRemaining() time.Duration
CooldownRemaining returns the time remaining in the cooldown phase. Returns 0 if the endpoint is healthy, recovering, or has no active cooldown.
func (*HealthTracker) FailCount ΒΆ added in v0.3.0
func (h *HealthTracker) FailCount() uint32
FailCount returns the current number of consecutive failures.
func (*HealthTracker) IsAvailable ΒΆ added in v0.2.0
func (h *HealthTracker) IsAvailable() bool
IsAvailable reports whether the endpoint is reachable. An unhealthy endpoint becomes available again after its recovery time elapses.
func (*HealthTracker) MarkFailed ΒΆ added in v0.2.0
func (h *HealthTracker) MarkFailed()
MarkFailed records a failure. When consecutive failures reach maxFails, the endpoint is marked unhealthy until the recovery time elapses.
func (*HealthTracker) MarkSuccess ΒΆ added in v0.2.0
func (h *HealthTracker) MarkSuccess()
MarkSuccess resets the failure counter and marks the endpoint as healthy.
func (*HealthTracker) Reset ΒΆ added in v0.3.0
func (h *HealthTracker) Reset()
Reset clears all failure counters and restores the endpoint to StatusHealthy immediately. If the endpoint was previously unhealthy, it triggers the onRecovered callback if configured.
func (*HealthTracker) Status ΒΆ added in v0.3.0
func (h *HealthTracker) Status() HealthStatus
Status evaluates and returns the precise current status of the endpoint.
type HostRewriteConfig ΒΆ
HostRewriteConfig holds the configuration for host rewrite.
type InMemoryDNSCache ΒΆ
type InMemoryDNSCache struct {
// contains filtered or unexported fields
}
InMemoryDNSCache caches DNS results in memory for the configured TTL.
func NewInMemoryDNSCache ΒΆ
func NewInMemoryDNSCache(ttl time.Duration, r DNSResolver) *InMemoryDNSCache
NewInMemoryDNSCache creates a new InMemoryDNSCache with the given TTL and resolver. A background goroutine periodically evicts expired entries.
func (*InMemoryDNSCache) Close ΒΆ added in v0.2.0
func (c *InMemoryDNSCache) Close()
Close stops the background eviction goroutine.
func (*InMemoryDNSCache) LookupIPAddr ΒΆ
LookupIPAddr looks up the IP addresses for the given host using the cache or resolver.
type Int64String ΒΆ
type Int64String int64
Int64String parses int64 values from string representations in JSON. It safely handles raw integers, JSON null, or empty strings.
func (Int64String) MarshalJSON ΒΆ added in v0.3.0
func (i Int64String) MarshalJSON() ([]byte, error)
MarshalJSON serializes the Int64String back as a JSON string representation.
func (*Int64String) UnmarshalJSON ΒΆ
func (i *Int64String) UnmarshalJSON(b []byte) error
UnmarshalJSON parses JSON byte data into the Int64String target.
type JSONDecoderConfig ΒΆ added in v0.3.0
type JSONDecoderConfig struct {
// DisallowUnknownFields causes the decoder to return an error if the destination
// struct has no matching field for a key in the JSON payload.
DisallowUnknownFields bool
// UseNumber causes the decoder to unmarshal numbers into json.Number instead of float64.
UseNumber bool
}
JSONDecoderConfig holds configuration parameters for creating a custom JSON decoder.
type JSONFileCookieStorage ΒΆ added in v0.4.0
type JSONFileCookieStorage struct {
// contains filtered or unexported fields
}
JSONFileCookieStorage implements CookieStorageBackend using a single JSON file on disk.
func NewJSONFileCookieStorage ΒΆ added in v0.4.0
func NewJSONFileCookieStorage(filePath string) *JSONFileCookieStorage
NewJSONFileCookieStorage creates a new JSONFileCookieStorage at the specified path.
func (*JSONFileCookieStorage) Load ΒΆ added in v0.4.0
func (s *JSONFileCookieStorage) Load(key string) ([]CookieData, error)
Load reads cookies associated with the given key from the JSON file.
func (*JSONFileCookieStorage) Save ΒΆ added in v0.4.0
func (s *JSONFileCookieStorage) Save(key string, cookies []CookieData) error
Save writes the specified cookies associated with the given key to the JSON file.
type JitterStrategy ΒΆ
type JitterStrategy int
JitterStrategy selects the algorithm for computing retry delay noise.
const ( // JitterEqual adds +/- 10% random noise to the exponential backoff. JitterEqual JitterStrategy = iota // JitterFull picks a random duration between zero and the backoff value. JitterFull )
type LoadBalancer ΒΆ
type LoadBalancer struct {
// contains filtered or unexported fields
}
LoadBalancer distributes requests across multiple backend servers. It implements the HTTPDoer interface and can be passed to NewClient. Use NewLoadBalancer to initialize new instances.
func NewLoadBalancer ΒΆ
func NewLoadBalancer(cfg LoadBalancerConfig, backends ...string) (*LoadBalancer, error)
NewLoadBalancer initializes a new LoadBalancer with the given backends. It returns an error if the backends slice is empty. If MaxFails or RetryAfter configuration options are zero, they default to 3 and 30 seconds respectively.
func (*LoadBalancer) Close ΒΆ
func (lb *LoadBalancer) Close() error
Close stops background health check routines.
func (*LoadBalancer) Do ΒΆ
Do executes the HTTP request across healthy backends based on the configured strategy. It clones the original request and overwrites its Scheme and Host to target the chosen backend.
If the chosen backend fails health checks, it is marked as failed. The load balancer then retries other available backends sequentially. If all backends fail, it returns an error wrapping the last encountered failure.
func (*LoadBalancer) Prewarm ΒΆ
func (lb *LoadBalancer) Prewarm(ctx context.Context)
Prewarm opens TCP/TLS connections to all registered backends by executing concurrent HEAD requests to each backend URL.
func (*LoadBalancer) Reset ΒΆ added in v0.3.0
func (lb *LoadBalancer) Reset()
Reset clears all failure counters and restores all backends to healthy states immediately.
func (*LoadBalancer) SetWeight ΒΆ added in v0.3.0
func (lb *LoadBalancer) SetWeight(backendURL string, weight int) bool
SetWeight updates the selection weight of a specific backend. Returns true if the backend was found and updated, false otherwise.
func (*LoadBalancer) Stats ΒΆ added in v0.3.0
func (lb *LoadBalancer) Stats() LoadBalancerStats
Stats evaluates and returns current health statistics of the registered backends.
func (*LoadBalancer) UpdateBackends ΒΆ
func (lb *LoadBalancer) UpdateBackends(backends ...string)
UpdateBackends replaces the entire set of active backends. It resets the selection counter to zero. If the backends slice is empty, the method returns early and makes no changes.
func (*LoadBalancer) WithClients ΒΆ
func (lb *LoadBalancer) WithClients(clients ...HTTPDoer) *LoadBalancer
WithClients applies custom HTTPDoer clients to the corresponding backends. The clients are matched to backends by slice index order. If the number of clients is different from backends, any excess clients are ignored.
type LoadBalancerConfig ΒΆ
type LoadBalancerConfig struct {
// Strategy determines the selection algorithm for choosing a backend.
Strategy LoadBalancingStrategy
// MaxFails is the consecutive failure threshold before a backend is marked unhealthy.
MaxFails uint32
// RetryAfter is the offline cooldown duration for an unhealthy backend.
RetryAfter time.Duration
// HealthCheckURL is the server endpoint probed by background health checks.
HealthCheckURL string
// HealthCheckInterval is the period between sequential background health checks.
HealthCheckInterval time.Duration
}
LoadBalancerConfig defines the tuning and policy settings for a LoadBalancer.
type LoadBalancerStats ΒΆ added in v0.3.0
LoadBalancerStats provides real-time state metrics for the balanced pool.
type LoadBalancingStrategy ΒΆ
type LoadBalancingStrategy int
LoadBalancingStrategy defines the selection algorithm for backends.
const ( // RoundRobin selects backends sequentially in a cyclic order. RoundRobin LoadBalancingStrategy = iota // Random selects backends randomly for each request. Random // WeightedRoundRobin selects backends based on their assigned weights. WeightedRoundRobin )
type Logger ΒΆ
type Logger interface {
Debug(msg string, args ...any)
DebugContext(ctx context.Context, msg string, args ...any)
Info(msg string, args ...any)
InfoContext(ctx context.Context, msg string, args ...any)
Warn(msg string, args ...any)
WarnContext(ctx context.Context, msg string, args ...any)
Error(msg string, args ...any)
ErrorContext(ctx context.Context, msg string, args ...any)
}
Logger is an interface for logging messages.
type Middleware ΒΆ
Middleware wraps an HTTPDoer with additional request/response processing logic. Pass to Chain to compose multiple layers.
func AdaptiveLimitMiddleware ΒΆ
func AdaptiveLimitMiddleware(limiter *limiter.AdaptiveLimiter) Middleware
AdaptiveLimitMiddleware returns a Middleware that gates requests through limiter. Each request acquires a slot before execution and releases it afterward with the observed RTT.
func ChaosMiddleware ΒΆ
func ChaosMiddleware(cfg ChaosConfig) Middleware
ChaosMiddleware returns a Middleware that injects random latency and 503 errors. Useful for testing retry and circuit breaker logic.
func CircuitBreakerMiddleware ΒΆ
func CircuitBreakerMiddleware(cb *CircuitBreaker, isFailure func(*http.Response, error) bool) Middleware
CircuitBreakerMiddleware returns a Middleware that gates requests through cb per host. When the circuit is open the request fails immediately with an error. isFailure determines which responses count as failures; nil uses DefaultCircuitBreakerCondition.
The circuit breaker uses a sliding window: failures are tracked over CircuitBreakerConfig.Window and compared against CircuitBreakerConfig.FailureThreshold ratio.
func FallbackMiddleware ΒΆ
func FallbackMiddleware() Middleware
FallbackMiddleware returns a Middleware that invokes the FallbackFunc registered via WithFallback when the request fails with any error.
func FallbackMiddlewareEx ΒΆ
func FallbackMiddlewareEx(isFailure func(*http.Response, error) bool) Middleware
FallbackMiddlewareEx is like FallbackMiddleware but uses isFailure to decide which responses trigger the fallback. When isFailure is nil, any non-nil error triggers it.
func RateLimitMiddleware ΒΆ
func RateLimitMiddleware(rps float64, burst int) Middleware
RateLimitMiddleware returns a Middleware that blocks when the request rate exceeds rps with burst tolerance. The limiter uses a token bucket algorithm from golang.org/x/time/rate.
func RecoveryMiddleware ΒΆ
func RecoveryMiddleware(onPanic func(any)) Middleware
RecoveryMiddleware catches panics during request execution, calls onPanic with the recovered value (if non-nil), and returns an error.
func RetryMiddleware ΒΆ
func RetryMiddleware(opts RetryOptions, condition RetryCondition) Middleware
RetryMiddleware returns a Middleware that retries requests matching condition up to opts.MaxRetries times. The request body is buffered in memory so it can be replayed. The middleware respects the Retry-After header when present and falls back to exponential backoff with jitter.
If the request carries a WithRetryPolicy override, its values take precedence over the global opts and condition for that request only.
type NamespaceSocket ΒΆ added in v0.2.0
type NamespaceSocket struct {
// contains filtered or unexported fields
}
NamespaceSocket is a namespace-scoped event emitter. Obtain via SocketIOConn.OnNamespace.
func (*NamespaceSocket) Emit ΒΆ added in v0.2.0
func (ns *NamespaceSocket) Emit(event string, args ...any) error
Emit sends a Socket.IO event on this namespace. If the last argument is a func(args []json.RawMessage), it is used as an ACK callback.
func (*NamespaceSocket) EmitVolatile ΒΆ added in v0.2.0
func (ns *NamespaceSocket) EmitVolatile(event string, args ...any) error
EmitVolatile sends an event only if currently connected; silently drops otherwise.
func (*NamespaceSocket) EmitWithAck ΒΆ added in v0.2.0
func (ns *NamespaceSocket) EmitWithAck(ctx context.Context, event string, args ...any) ([]json.RawMessage, error)
EmitWithAck sends an event and blocks until the server acknowledges it or ctx expires.
func (*NamespaceSocket) On ΒΆ added in v0.2.0
func (ns *NamespaceSocket) On(event string, handler func(args []json.RawMessage))
On registers a handler for a specific event on this namespace.
func (*NamespaceSocket) OnAny ΒΆ added in v0.3.0
func (ns *NamespaceSocket) OnAny(handler func(event string, args []json.RawMessage))
OnAny registers a catch-all event listener on this specific namespace that intercepts all incoming Socket.IO events for the namespace.
type NoResponse ΒΆ
type NoResponse struct{}
NoResponse is a sentinel type used to indicate a request that does not return a response body. When used as the response type in generic request helpers like GetTo, the helper automatically drains and closes the response body to prevent resource leaks.
type PaddingConfig ΒΆ added in v0.3.0
type PaddingConfig struct {
// MaxSegmentSize sets the TCP Maximum Segment Size (MSS) at the socket level.
// This forces TCP to fragment data into smaller packets, breaking static
// packet length signatures used by DPI systems. Set to 0 to disable.
// Typical values: 256-512 for strong fragmentation, 1024 for moderate.
MaxSegmentSize int
// MinPaddingBytes is the minimum number of random padding bytes added
// to the start of the request body. A random value between MinPaddingBytes
// and MaxPaddingBytes is chosen per request. Set both to 0 to disable padding.
MinPaddingBytes int
// MaxPaddingBytes is the maximum number of random padding bytes added.
MaxPaddingBytes int
// PaddingHeader is the name of a custom header used to carry padding data.
// If empty and HeaderPool is empty, a default name "X-Padding" is used.
// Ignored when HeaderPool is non-empty.
PaddingHeader string
// HeaderPool is a list of header names used to carry padding data.
// On each request a random name is picked from this pool, making the
// padding header indistinguishable from legitimate CDN or cloud tracing
// headers. When non-empty this field takes precedence over PaddingHeader.
HeaderPool []string
}
PaddingConfig controls MTU fragmentation and packet padding to disrupt DPI signature analysis of packet length patterns.
type PersistentJar ΒΆ added in v0.4.0
PersistentJar wraps http.CookieJar to save state to a CookieStorageBackend.
func (*PersistentJar) SetCookies ΒΆ added in v0.4.0
func (pj *PersistentJar) SetCookies(u *url.URL, cookies []*http.Cookie)
SetCookies implements the http.CookieJar interface.
type Persona ΒΆ added in v0.4.0
type Persona struct {
TLSID utls.ClientHelloID
H2Settings HTTP2Settings
UserAgent string
HeaderOrder []string
P0fSignature *p0f.Signature
}
Persona represents an immutable set of fingerprint parameters matching all layers (TCP/IP, TLS, HTTP/2 settings, headers, and User-Agent).
type ProgressFunc ΒΆ
type ProgressFunc func(current, total int64)
ProgressFunc is called periodically during response body reads. current is the bytes read so far; total is the Content-Length value or -1 if unknown.
type ProxyAwareSessionCache ΒΆ added in v0.2.0
type ProxyAwareSessionCache struct {
// contains filtered or unexported fields
}
ProxyAwareSessionCache wraps the uTLS utls.ClientSessionCache and automatically invalidates cached TLS session tickets when the active proxy or source IP changes. This prevents server-side tracking of a client across different exit IPs via session ticket correlation.
func NewProxyAwareSessionCache ΒΆ added in v0.2.0
func NewProxyAwareSessionCache() *ProxyAwareSessionCache
NewProxyAwareSessionCache creates a new ProxyAwareSessionCache.
func (*ProxyAwareSessionCache) Clear ΒΆ added in v0.3.0
func (c *ProxyAwareSessionCache) Clear()
Clear manually flushes all currently cached TLS sessions.
func (*ProxyAwareSessionCache) CurrentProxyKey ΒΆ added in v0.2.0
func (c *ProxyAwareSessionCache) CurrentProxyKey() string
CurrentProxyKey returns the currently active proxy key.
func (*ProxyAwareSessionCache) Get ΒΆ added in v0.2.0
func (c *ProxyAwareSessionCache) Get(serverName string) (*utls.ClientSessionState, bool)
Get retrieves a cached session for the given server name. If the session was cached under a different proxy key, it returns nil to force a fresh handshake.
func (*ProxyAwareSessionCache) Put ΒΆ added in v0.2.0
func (c *ProxyAwareSessionCache) Put(serverName string, session *utls.ClientSessionState)
Put stores a TLS session ticket.
func (*ProxyAwareSessionCache) SetProxyKey ΒΆ added in v0.2.0
func (c *ProxyAwareSessionCache) SetProxyKey(key string)
SetProxyKey invalidates all cached sessions and starts a fresh session cache for the given proxy key (typically the proxy address or source IP). This ensures that when the proxy changes, no session tickets from the previous proxy are reused, preventing session correlation tracking.
type ProxyConfig ΒΆ
type ProxyConfig struct {
// ProxyURL is the address of the proxy server (e.g. http://user:pass@ip:port).
ProxyURL string
// Timeout is the overall request timeout.
Timeout time.Duration
// InsecureSkipVerify controls whether SSL/TLS certificate verification is bypassed.
InsecureSkipVerify bool
// Transport overrides the default transport settings.
Transport http.RoundTripper
// TransportFactory creates a custom [http.RoundTripper].
TransportFactory func(ProxyConfig) (http.RoundTripper, error)
}
ProxyConfig configures a proxy-supported HTTP client.
type ProxyIsolatedCookieJar ΒΆ
type ProxyIsolatedCookieJar struct {
// contains filtered or unexported fields
}
ProxyIsolatedCookieJar is an isolated cookie jar that stores cookies per proxy URL. It is safe for concurrent use by multiple goroutines.
Cookie isolation works for direct requests: the proxy URL is extracted from the request context and used to select the correct per-proxy jar.
Limitation: during HTTP redirects, the standard library's http.Client calls SetCookies/Cookies without passing the request context. In this case the jar falls back to the default (empty-key) jar. This means per-proxy cookie isolation does not apply to redirect responses. In practice this is rarely an issue because proxy servers typically do not return redirects, and cookies from the target server arrive in the initial response before any redirect.
func NewProxyIsolatedCookieJar ΒΆ
func NewProxyIsolatedCookieJar() *ProxyIsolatedCookieJar
NewProxyIsolatedCookieJar creates a new ProxyIsolatedCookieJar.
func (*ProxyIsolatedCookieJar) Cookies ΒΆ
func (p *ProxyIsolatedCookieJar) Cookies(u *url.URL) []*http.Cookie
Cookies implements the http.CookieJar interface. For direct requests, uses the proxy URL from the request context. For redirects (no context available), falls back to the default jar.
func (*ProxyIsolatedCookieJar) CookiesForProxy ΒΆ added in v0.3.0
CookiesForProxy manually retrieves cookies for a specific proxy URL.
func (*ProxyIsolatedCookieJar) GetJar ΒΆ added in v0.3.0
func (p *ProxyIsolatedCookieJar) GetJar(ctx context.Context) http.CookieJar
GetJar returns the cookie jar for the given context, creating it if necessary.
func (*ProxyIsolatedCookieJar) GetJarForProxy ΒΆ added in v0.3.0
func (p *ProxyIsolatedCookieJar) GetJarForProxy(proxyURL string) http.CookieJar
GetJarForProxy returns the specific http.CookieJar associated with the given proxy URL. This is a high-level helper to manage proxy cookies programmatically.
func (*ProxyIsolatedCookieJar) SetCookies ΒΆ
func (p *ProxyIsolatedCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie)
SetCookies implements the http.CookieJar interface. For direct requests, uses the proxy URL from the request context. For redirects (no context available), falls back to the default jar.
func (*ProxyIsolatedCookieJar) SetCookiesForProxy ΒΆ added in v0.3.0
func (p *ProxyIsolatedCookieJar) SetCookiesForProxy(proxyURL string, u *url.URL, cookies []*http.Cookie)
SetCookiesForProxy manually stores cookies for a specific proxy URL.
func (*ProxyIsolatedCookieJar) WithStorageBackend ΒΆ added in v0.4.0
func (p *ProxyIsolatedCookieJar) WithStorageBackend(backend CookieStorageBackend) *ProxyIsolatedCookieJar
WithStorageBackend configures a persistent storage backend for cookies.
type ProxyRotator ΒΆ
type ProxyRotator struct {
// contains filtered or unexported fields
}
ProxyRotator distributes HTTP requests across a pool of proxy clients. It implements HTTPDoer and supports sticky routing, health monitoring, and dynamic pool replacement.
Create instances with NewProxyRotator.
func NewProxyRotator ΒΆ
func NewProxyRotator(config ProxyRotatorConfig, clients ...ClientWithProxy) (*ProxyRotator, error)
NewProxyRotator creates a ProxyRotator from the given config and clients. It returns an error if clients is empty. Default ProxyRotatorConfig.MaxFails is 3; default ProxyRotatorConfig.RetryAfter is 30 seconds.
func NewProxyRotatorFromStrings ΒΆ added in v0.3.0
func NewProxyRotatorFromStrings(config ProxyRotatorConfig, proxyURLs ...string) (*ProxyRotator, error)
NewProxyRotatorFromStrings creates a ProxyRotator from a list of raw proxy URL strings. It automatically instantiates standard http.Clients configured with the respective proxies. This is a high-level helper to easily set up a rotating pool from proxy list configurations.
func (*ProxyRotator) Close ΒΆ
func (r *ProxyRotator) Close() error
Close stops background routines and closes idle connections.
func (*ProxyRotator) Do ΒΆ
Do performs an HTTP request using the next available client in the pool. It attempts sticky routing first, then falls back to round-robin selection. If a client faults, it is marked unhealthy. Returns an error if all clients fail.
func (*ProxyRotator) Prewarm ΒΆ
func (r *ProxyRotator) Prewarm(ctx context.Context, targetURL string)
Prewarm opens TCP/TLS connections to targetURL through all proxy clients. It sends concurrent HEAD requests to pre-populate transport connection pools.
func (*ProxyRotator) Reset ΒΆ added in v0.3.0
func (r *ProxyRotator) Reset()
Reset clears failure states and restores all registered proxy clients to a healthy state.
func (*ProxyRotator) ResetDomainCooldowns ΒΆ added in v0.4.0
func (r *ProxyRotator) ResetDomainCooldowns()
ResetDomainCooldowns clears all domain-specific cooldowns for all proxies in the pool.
func (*ProxyRotator) Stats ΒΆ added in v0.3.0
func (r *ProxyRotator) Stats() ProxyRotatorStats
Stats evaluates and returns current health statistics of the registered proxy clients.
func (*ProxyRotator) UpdateClients ΒΆ
func (r *ProxyRotator) UpdateClients(clients ...ClientWithProxy)
UpdateClients replaces the active pool and resets all session mappings.
func (*ProxyRotator) WithStickySessions ΒΆ
func (r *ProxyRotator) WithStickySessions(f StickyKeyFunc) *ProxyRotator
WithStickySessions returns a copy of r configured with the given key extractor.
type ProxyRotatorConfig ΒΆ
type ProxyRotatorConfig struct {
// MaxFails is the consecutive error limit before a client is marked unhealthy.
MaxFails uint32
// RetryAfter is the duration for which an unhealthy client is kept offline.
RetryAfter time.Duration
// HealthCheckURL is the endpoint probed during background health checks.
HealthCheckURL string
// HealthCheckInterval sets the frequency of background health checks.
HealthCheckInterval time.Duration
}
ProxyRotatorConfig configures health-checking and recovery for a ProxyRotator.
type ProxyRotatorStats ΒΆ added in v0.3.0
ProxyRotatorStats provides real-time state metrics for the rotating proxy pool.
type ProxyRoutedDNSResolver ΒΆ added in v0.2.0
type ProxyRoutedDNSResolver struct {
// contains filtered or unexported fields
}
ProxyRoutedDNSResolver sends DNS queries through a proxy connection to prevent leaks.
func NewProxyRoutedDNSResolver ΒΆ added in v0.2.0
func NewProxyRoutedDNSResolver( resolver DNSResolver, proxyDial func(ctx context.Context, network, addr string) (net.Conn, error), ) *ProxyRoutedDNSResolver
NewProxyRoutedDNSResolver creates a ProxyRoutedDNSResolver that routes DNS queries through the given proxy dial function.
func (*ProxyRoutedDNSResolver) LookupIPAddr ΒΆ added in v0.2.0
func (r *ProxyRoutedDNSResolver) LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)
LookupIPAddr resolves the host by delegating to the proxy-routed resolver.
type QUICMigrationConfig ΒΆ added in v0.2.0
type QUICMigrationConfig struct {
// EnableMigration enables QUIC Connection Migration (default: true).
// When enabled, the client can survive IP address changes without renegotiating.
EnableMigration bool
// KeepAlivePeriod sends periodic keepalive packets to maintain the connection
// during network transitions. Set to 0 to disable (default: 15s).
KeepAlivePeriod time.Duration
// MaxIdleTimeout is the maximum duration without network activity before
// the connection is closed. Longer values allow more time for migration
// but consume resources (default: 30s).
MaxIdleTimeout time.Duration
// DisablePathMTUDiscovery disables Path MTU Discovery during migration.
// Disable if the network path is unreliable (default: false).
DisablePathMTUDiscovery bool
// InitialPacketSize sets the initial QUIC packet size (default: 1200).
// Lower values improve compatibility with restrictive networks.
InitialPacketSize uint16
}
QUICMigrationConfig controls QUIC Connection Migration for HTTP/3. Migration lets a QUIC connection survive network interface changes (e.g. Wi-Fi to cellular) by tracking connection IDs instead of IP:port tuples. See DefaultQUICMigrationConfig.
func DefaultQUICMigrationConfig ΒΆ added in v0.2.0
func DefaultQUICMigrationConfig() QUICMigrationConfig
DefaultQUICMigrationConfig returns a QUICMigrationConfig with production-ready defaults.
type RTTTracker ΒΆ added in v0.2.0
type RTTTracker struct {
// contains filtered or unexported fields
}
RTTTracker maintains a sliding window of RTT measurements and computes percentile-based values (p95, p99) for dynamic hedging delay calculation. It is safe for concurrent use.
func NewRTTTracker ΒΆ added in v0.2.0
func NewRTTTracker(capacity int) *RTTTracker
NewRTTTracker creates an RTTTracker with the given sample window capacity. A larger capacity provides more stable estimates but reacts slower to changes. A capacity of 100 is recommended for most use cases.
func (*RTTTracker) AverageRTT ΒΆ added in v0.3.0
func (t *RTTTracker) AverageRTT() time.Duration
AverageRTT returns the simple mathematical average (mean) of all recorded RTT samples. Returns 0 if no samples are recorded.
func (*RTTTracker) Count ΒΆ added in v0.2.0
func (t *RTTTracker) Count() int
Count returns the number of recorded samples.
func (*RTTTracker) MaxRTT ΒΆ added in v0.3.0
func (t *RTTTracker) MaxRTT() time.Duration
MaxRTT returns the maximum observed RTT within the current sliding window. Returns 0 if no samples are recorded.
func (*RTTTracker) MinRTT ΒΆ added in v0.2.0
func (t *RTTTracker) MinRTT() time.Duration
MinRTT returns the minimum observed RTT.
func (*RTTTracker) P95 ΒΆ added in v0.2.0
func (t *RTTTracker) P95() time.Duration
P95 returns the 95th percentile RTT.
func (*RTTTracker) P99 ΒΆ added in v0.2.0
func (t *RTTTracker) P99() time.Duration
P99 returns the 99th percentile RTT.
func (*RTTTracker) Percentile ΒΆ added in v0.2.0
func (t *RTTTracker) Percentile(p float64) time.Duration
Percentile returns the given percentile (0-100) of recorded RTT samples. Returns 0 if no samples are recorded.
func (*RTTTracker) Record ΒΆ added in v0.2.0
func (t *RTTTracker) Record(rtt time.Duration)
Record adds an RTT measurement to the tracker.
func (*RTTTracker) Reset ΒΆ added in v0.3.0
func (t *RTTTracker) Reset()
Reset clears all recorded RTT samples and resets the metrics.
func (*RTTTracker) SmoothedRTT ΒΆ added in v0.2.0
func (t *RTTTracker) SmoothedRTT() time.Duration
SmoothedRTT returns the exponentially smoothed RTT (EWMA).
type ReplayableBody ΒΆ
type ReplayableBody interface {
io.ReadCloser
Reset()
}
ReplayableBody represents a response stream that can be reset to the beginning for re-reading (for example, after previewing or logging).
func AsReplayable ΒΆ
func AsReplayable(rc io.ReadCloser) ReplayableBody
AsReplayable turns any io.ReadCloser into a ReplayableBody. If there's already a high-performance buffer (multiReadBody) under the hood, it will return it. If not, it will transparently create a lightweight in-memory buffer for repeated reading.
type RequestModifier ΒΆ
RequestModifier represents a function that alters an http.Request before execution.
func AppendHostRewrite ΒΆ added in v0.3.0
func AppendHostRewrite(rules map[string]string) RequestModifier
AppendHostRewrite returns a RequestModifier that appends new host rewrite rules to the existing HostRewriteConfig in the request context, or creates a new one if none are present.
func AsCurl ΒΆ
func AsCurl() RequestModifier
AsCurl returns a RequestModifier that dumps the equivalent curl command to stderr.
func CaptureResponse ΒΆ
func CaptureResponse(target **http.Response) RequestModifier
CaptureResponse stores the final http.Response pointer in target after the request completes. Useful for inspecting headers or status codes in middleware hooks.
func ContextModifiers ΒΆ added in v0.2.0
func ContextModifiers(ctx context.Context) []RequestModifier
ContextModifiers extracts the RequestModifiers previously stored via WithContextModifier. Returns nil if none are present.
func Debug ΒΆ
func Debug() RequestModifier
Debug returns a RequestModifier that tags the request for verbose logging. The Client must have a Logger set via Client.WithLogger for output to appear.
func ResetHeaders ΒΆ added in v0.5.0
func ResetHeaders() RequestModifier
ResetHeaders returns a modifier that clears all headers from the request.
func Trace ΒΆ
func Trace(target *TraceInfo) RequestModifier
Trace returns a RequestModifier that registers a connection tracer on the active request. Timing metrics are populated inside the provided TraceInfo structure.
func TraceContext ΒΆ added in v0.3.0
func TraceContext() RequestModifier
TraceContext returns a RequestModifier that attaches a new TraceInfo to the request context. This allows developers to retrieve network timing and JA4/JA4H fingerprints using ResponseTrace after the request finishes.
func TraceJA4 ΒΆ
func TraceJA4(target *TraceInfo) RequestModifier
TraceJA4 returns a RequestModifier that populates the JA4 field of the provided TraceInfo. It sets up a shared store in the request context so that Client.WithTLSFingerprint can write the TLS fingerprint during the handshake, and computes the HTTP fingerprint from request headers.
The JA4 report is fully populated after the request completes. The TLS fingerprint (JA4) requires Client.WithTLSFingerprint to be enabled.
Use this modifier alongside Trace for complete timing and fingerprint data:
info := &aoni.TraceInfo{}
client.Get(ctx, "/path", aoni.Trace(info), aoni.TraceJA4(info))
// After request: info.JA4 contains both JA4 and JA4H
func WithALPN ΒΆ
func WithALPN(protocols []string) RequestModifier
WithALPN returns a RequestModifier that sets custom ALPN protocols.
func WithAccept ΒΆ
func WithAccept(accept string) RequestModifier
WithAccept overrides the standard Accept header field.
func WithBasicAuth ΒΆ
func WithBasicAuth(username, password string) RequestModifier
WithBasicAuth applies Basic Authorization credentials.
func WithBearer ΒΆ
func WithBearer(token string) RequestModifier
WithBearer applies a Bearer Token authorization header.
func WithBody ΒΆ
func WithBody(r io.Reader) RequestModifier
WithBody replaces the request body stream with the provided reader.
func WithCacheTTL ΒΆ added in v0.5.0
func WithCacheTTL(d time.Duration) RequestModifier
WithCacheTTL marks the request as cacheable with the given TTL. A caching Middleware (e.g. built with [CacheMiddleware]) should call GetCacheTTL to decide whether and how long to cache the response. A zero or negative duration means "do not cache".
func WithConnMetadata ΒΆ added in v0.5.0
func WithConnMetadata(key string, val any) RequestModifier
WithConnMetadata attaches an arbitrary key-value pair to the request context. Useful for propagating metadata (e.g. proxy IDs, pool tags) into transport hooks, TrafficInspector captures, or structured log output.
Multiple calls with different keys are cumulative. Duplicate keys overwrite the previous value, matching standard context semantics.
func WithContentType ΒΆ
func WithContentType(ct string) RequestModifier
WithContentType overrides the standard Content-Type header field.
func WithCookie ΒΆ
func WithCookie(c *http.Cookie) RequestModifier
WithCookie attaches a single cookie to the request.
func WithCookies ΒΆ
func WithCookies(kv map[string]string) RequestModifier
WithCookies attaches multiple cookies from a key-value map.
func WithDecoder ΒΆ
func WithDecoder(d Decoder) RequestModifier
WithDecoder overrides the response Decoder for this request. The client-level decoder set via Client.WithBaseResponse is ignored when this modifier is present.
func WithDownloadProgress ΒΆ
func WithDownloadProgress(onProgress ProgressFunc) RequestModifier
WithDownloadProgress registers onProgress to be called during response body reads. The callback fires with the bytes-read total and the Content-Length value.
func WithErrorModel ΒΆ
func WithErrorModel(target any) RequestModifier
WithErrorModel tells Client.Request to deserialize non-2xx response bodies into target. Inspect the result with errors.As against APIError.
func WithFallback ΒΆ
func WithFallback(f FallbackFunc) RequestModifier
WithFallback returns a RequestModifier that registers f as the fallback for this request. See FallbackMiddleware.
func WithForceHTTP1 ΒΆ
func WithForceHTTP1() RequestModifier
WithForceHTTP1 returns a RequestModifier that advertises only http/1.1 in ALPN, preventing the server from upgrading to HTTP/2.
func WithForceHTTP2 ΒΆ
func WithForceHTTP2() RequestModifier
WithForceHTTP2 returns a RequestModifier that advertises only h2 in ALPN, forcing the server to use HTTP/2.
func WithFormBody ΒΆ added in v0.4.0
func WithFormBody(payload any) RequestModifier
WithFormBody serializes payload as URL-encoded form values, sets the request body, and adds a Content-Type: application/x-www-form-urlencoded header.
If payload implements io.Reader, it is used directly as the body. Otherwise, Validate is called first, then StructToValues converts the struct to url.Values. Validation or serialization errors are stored in the request context and returned by Client.Request.
func WithFormValues ΒΆ added in v0.4.0
func WithFormValues(values url.Values) RequestModifier
WithFormValues merges the provided url.Values into the request body as application/x-www-form-urlencoded. If the request already has a body, it is replaced. Use WithBody afterwards if you need to combine form data with a custom reader.
func WithFragmentation ΒΆ
func WithFragmentation(cfg FragmentConfig) RequestModifier
WithFragmentation returns a RequestModifier that sets fragmentation configuration on the request context.
func WithHeader ΒΆ
func WithHeader(key, value string) RequestModifier
WithHeader sets the key header field to the given value.
func WithHeaders ΒΆ added in v0.5.0
func WithHeaders(headers map[string]string) RequestModifier
WithHeaders sets new key-value pairs in request headers.
func WithHedging ΒΆ
func WithHedging(delay time.Duration) RequestModifier
WithHedging overrides the client-level hedging delay for this request. A duration <= 0 disables hedging for the request.
func WithHostRewrite ΒΆ
func WithHostRewrite(rules map[string]string) RequestModifier
WithHostRewrite returns a RequestModifier that rewrites the host header based on the provided rules.
func WithIfMatch ΒΆ added in v0.4.0
func WithIfMatch(etag string) RequestModifier
WithIfMatch sets the If-Match request header to the provided ETag value. Typically used with PUT/PATCH/DELETE to ensure the resource has not been modified by another client since it was last fetched (optimistic locking).
func WithIfModifiedSince ΒΆ added in v0.4.0
func WithIfModifiedSince(t time.Time) RequestModifier
WithIfModifiedSince sets the If-Modified-Since request header. The server responds with 304 Not Modified when the resource has not changed since t, avoiding unnecessary payload transfer.
func WithIfNoneMatch ΒΆ added in v0.4.0
func WithIfNoneMatch(etag string) RequestModifier
WithIfNoneMatch sets the If-None-Match request header to the provided ETag value. The server responds with 304 Not Modified when the resource has not changed, allowing the client to use its cached copy.
func WithInsecureSkipVerify ΒΆ added in v0.5.0
func WithInsecureSkipVerify() RequestModifier
WithInsecureSkipVerify returns a RequestModifier that disables TLS certificate verification for this single request. Useful for requests to internal admin panels or self-signed proxies without lowering the security of the entire client.
Only takes effect when the underlying transport honours GetInsecureSkipVerify. The built-in Client wires this automatically for uTLS connections (see Client.WithTLSFingerprint) and plain http.Transport connections.
func WithJSONBody ΒΆ
func WithJSONBody(payload any) RequestModifier
WithJSONBody serializes payload as JSON, sets the request body, and adds a Content-Type: application/json header. Marshaling errors are stored in the request context and retrievable via the body error hook.
func WithJSONDecoder ΒΆ added in v0.3.0
func WithJSONDecoder() RequestModifier
WithJSONDecoder returns a RequestModifier that uses JSONDecoder.
func WithMultiReadBody ΒΆ
func WithMultiReadBody(threshold int64) RequestModifier
WithMultiReadBody returns a RequestModifier that overrides the body caching threshold for a single request. Responses smaller than threshold are buffered in memory so the body can be read multiple times. A value <= 0 disables caching for the request.
func WithMultipart ΒΆ
WithMultipart builds a multipart/form-data body from fields and files, sets Content-Length and Content-Type (with boundary). Encoding errors are stored in the request context and retrievable via the body error hook (same as WithJSONBody).
func WithOrderedHeaders ΒΆ
func WithOrderedHeaders(order []string) RequestModifier
WithOrderedHeaders sets the header serialization order for this HTTP/1.1 request. For HTTP/2, use H2FramedTransport instead.
func WithOrigin ΒΆ
func WithOrigin(origin string) RequestModifier
WithOrigin overrides the standard Origin header field.
func WithP0fSignature ΒΆ
func WithP0fSignature(sig *p0f.Signature) RequestModifier
WithP0fSignature returns a RequestModifier that stores a p0f signature in the request context. When used with Client.WithP0fSignature, the TCP/IP fields (TTL, DF, window size) are spoofed to match the specified OS.
func WithPadding ΒΆ added in v0.3.0
func WithPadding(cfg PaddingConfig) RequestModifier
WithPadding returns a RequestModifier that adds random packet padding headers to the request matching the given PaddingConfig. This is a high-level helper to apply individual padding settings per request.
func WithProxyOverride ΒΆ added in v0.5.0
func WithProxyOverride(rawURL string) RequestModifier
WithProxyOverride returns a RequestModifier that routes this single request through proxyURL, ignoring the client-level proxy setting.
The value is stored in the request context and read by the transport's proxy function via GetProxyOverride. Use GetProxyOverride inside a custom http.Transport.Proxy to honour the override.
Example:
resp, err := client.Get(ctx, "/api", aoni.WithProxyOverride("http://10.0.0.1:8080"))
func WithQuery ΒΆ
func WithQuery(query any) RequestModifier
WithQuery encodes a struct or map as URL query parameters and appends them to the request URL. It safely checks for validation errors using Validate and serialization failures. Any encountered errors are saved to the request context via queryErrorCtxKey. Existing query parameters in the URL are preserved and merged with the new values.
func WithRawDecoder ΒΆ added in v0.3.0
func WithRawDecoder() RequestModifier
WithRawDecoder returns a RequestModifier that uses RawDecoder.
func WithResponseValidator ΒΆ added in v0.5.0
func WithResponseValidator(fn func(resp *http.Response) error) RequestModifier
WithResponseValidator attaches a validation function that is invoked by Client.Request immediately after a successful HTTP round-trip, before the response body is decoded. If fn returns a non-nil error the client treats the request as failed and propagates the error to the caller.
This is the recommended way to implement anti-bot body inspection (e.g. looking for "Access Denied" strings) without writing a full middleware:
WithResponseValidator(func(resp *http.Response) error {
if resp.Header.Get("X-Shield") == "blocked" {
return errors.New("request was shielded")
}
return nil
})
The validator receives the raw *http.Response before any decompression or transcoding has been applied by the client. Do not close resp.Body inside fn.
func WithRetryPolicy ΒΆ added in v0.5.0
func WithRetryPolicy(o RetryOverride) RequestModifier
WithRetryPolicy returns a RequestModifier that overrides the global retry settings for this request. A RetryMiddleware should call GetRetryOverride and prefer the per-request values when present.
Example - disable retries for a critical mutating action:
client.Post(ctx, "/checkout", body, aoni.WithRetryPolicy(aoni.RetryOverride{MaxAttempts: 1}))
Example - aggressive retry for a read-only scrape:
client.Get(ctx, "/prices", aoni.WithRetryPolicy(aoni.RetryOverride{
MaxAttempts: 10,
Backoff: 500 * time.Millisecond,
Condition: aoni.Or(aoni.RetryOnErr(), aoni.RetryOnGatewayErrors()),
}))
func WithStreamingMultipart ΒΆ
WithStreamingMultipart builds a multipart/form-data body using an io.Pipe so that file data is streamed rather than buffered in memory. Content-Length is not set because the total size is unknown until writing completes.
func WithTCPDelay ΒΆ added in v0.5.0
func WithTCPDelay(min, max time.Duration) RequestModifier
WithTCPDelay returns a RequestModifier that introduces a random delay between min and max before the TCP connection is established. This simulates the timing characteristics of a real human connection and can confuse bot-detection heuristics that look for suspiciously uniform request cadences.
The delay is enforced by GetTCPDelay inside the transport dialer. If min > max the values are swapped silently.
func WithTimeout ΒΆ added in v0.4.0
func WithTimeout(d time.Duration) RequestModifier
WithTimeout overrides the deadline for this individual request by deriving a child context with the given duration. It does not affect the client-level timeout configured via Client.WithTimeout.
func WithUploadProgress ΒΆ
func WithUploadProgress(onProgress ProgressFunc) RequestModifier
WithUploadProgress wraps the request body with a [progressReader] that calls onProgress during reads. The total parameter is Content-Length or -1 when unknown.
func WithUserAgent ΒΆ
func WithUserAgent(ua string) RequestModifier
WithUserAgent overrides the standard User-Agent header field.
func WithVar ΒΆ
func WithVar(key string, value any) RequestModifier
WithVar replaces a single placeholder (e.g. "{key}") in the path with an escaped value.
func WithVars ΒΆ
func WithVars(pairs ...any) RequestModifier
WithVars replaces multiple placeholder keys in the path with their respective values. It accepts alternating key-value arguments. If the argument list has an odd length, it returns early and performs no replacements.
func WithXMLDecoder ΒΆ added in v0.3.0
func WithXMLDecoder() RequestModifier
WithXMLDecoder returns a RequestModifier that uses XMLDecoder.
func WithYAMLDecoder ΒΆ added in v0.3.0
func WithYAMLDecoder() RequestModifier
WithYAMLDecoder returns a RequestModifier that uses YAMLDecoder.
type Requester ΒΆ
type Requester interface {
Request(
ctx context.Context,
method, path string,
mods ...RequestModifier,
) (*http.Response, error)
}
Requester sends an HTTP request and returns the response. Client is the primary implementation. Relative paths are resolved against the base URL. Request modifiers are applied before execution.
type RetryCondition ΒΆ
RetryCondition reports whether a failed request should be retried.
func And ΒΆ added in v0.3.0
func And(conditions ...RetryCondition) RetryCondition
And combines multiple RetryCondition functions into a single condition that returns true if ALL of the underlying conditions return true.
func Or ΒΆ added in v0.3.0
func Or(conditions ...RetryCondition) RetryCondition
Or combines multiple RetryCondition functions into a single condition that returns true if ANY of the underlying conditions return true.
func ProxyRetryCondition ΒΆ
func ProxyRetryCondition(rotator *ProxyRotator) RetryCondition
ProxyRetryCondition returns a RetryCondition that retries when rotator considers the response or error a proxy fault.
func RetryOnErr ΒΆ
func RetryOnErr() RetryCondition
RetryOnErr returns a RetryCondition that retries on any non-nil error.
func RetryOnGatewayErrors ΒΆ
func RetryOnGatewayErrors() RetryCondition
RetryOnGatewayErrors returns a RetryCondition that retries on HTTP 502, 503, and 504 status codes.
func RetryOnRateLimit ΒΆ
func RetryOnRateLimit() RetryCondition
RetryOnRateLimit returns a RetryCondition that retries on HTTP 429.
func RetryOnTransientErrors ΒΆ
func RetryOnTransientErrors() RetryCondition
RetryOnTransientErrors returns a RetryCondition that retries on network errors, connection resets, and broken pipes.
type RetryOptions ΒΆ
type RetryOptions struct {
// MaxRetries is the maximum number of retry attempts after the initial failure (0 = no retries).
MaxRetries uint32
// Backoff is the delay before the first retry. Subsequent retries
// use exponential backoff starting from this value.
Backoff time.Duration
// JitterStrategy selects the noise algorithm applied to each delay.
JitterStrategy JitterStrategy
// OnRetry is an optional callback executed before each sleep during retry attempts.
// Provides the attempt count (1-based), the causing error or nil, and the planned backoff delay.
OnRetry func(attempt uint32, err error, delay time.Duration)
}
RetryOptions configures RetryMiddleware.
type RetryOverride ΒΆ added in v0.5.0
type RetryOverride struct {
// MaxAttempts is the maximum number of total attempts (including the first).
// 1 means no retries; 0 is treated as 1 (no retries).
MaxAttempts int
// Backoff is the delay before the first retry. Subsequent retries use
// exponential back-off starting from this value.
Backoff time.Duration
// Condition is called after each failed attempt to decide whether to retry.
// When nil [RetryOnErr] is used as the default.
Condition RetryCondition
}
RetryOverride holds per-request retry settings that override the client-level RetryMiddleware configuration.
func GetRetryOverride ΒΆ added in v0.5.0
func GetRetryOverride(ctx context.Context) (RetryOverride, bool)
GetRetryOverride returns the per-request RetryOverride set by WithRetryPolicy. The second return value is false when no override is present.
type SQLCookieStorage ΒΆ added in v0.4.0
type SQLCookieStorage struct {
// contains filtered or unexported fields
}
SQLCookieStorage implements CookieStorageBackend using any SQL database (SQLite, Postgres, MySQL). It expects a table created with the following schema:
CREATE TABLE IF NOT EXISTS aoni_cookies (
proxy_key TEXT, cookie_data TEXT, PRIMARY KEY (proxy_key)
);
func NewSQLCookieStorage ΒΆ added in v0.4.0
func NewSQLCookieStorage(db *sql.DB) *SQLCookieStorage
NewSQLCookieStorage creates a new SQLCookieStorage with a given database connection.
func (*SQLCookieStorage) InitSchema ΒΆ added in v0.4.0
func (s *SQLCookieStorage) InitSchema() error
InitSchema creates the required table schema.
func (*SQLCookieStorage) Load ΒΆ added in v0.4.0
func (s *SQLCookieStorage) Load(key string) ([]CookieData, error)
Load retrieves cookies associated with the given key from the SQL database.
func (*SQLCookieStorage) Save ΒΆ added in v0.4.0
func (s *SQLCookieStorage) Save(key string, cookies []CookieData) error
Save persists the specified cookies to the SQL database.
type SSEEvent ΒΆ
type SSEEvent struct {
// Event is the event identifier string.
Event string
// Data is the data payload buffer string.
Data string
// ID is the unique event tracking ID.
ID string
// Retry is the reconnection timeout value in milliseconds.
Retry int
}
SSEEvent holds the parsed fields of a Server-Sent Event.
type SocketIOConfig ΒΆ added in v0.2.0
type SocketIOConfig struct {
// Reconnection controls automatic reconnection on unexpected disconnect.
Reconnection bool
// ReconnectionAttempts is the maximum number of reconnection attempts.
// 0 means unlimited.
ReconnectionAttempts int
// ReconnectionDelay is the initial delay before the first reconnection attempt.
// Default: 1s.
ReconnectionDelay time.Duration
// ReconnectionDelayMax is the upper bound for reconnection delay.
// Default: 30s.
ReconnectionDelayMax time.Duration
// JitterFactor controls random delay variation (0..1). Default: 0.5.
JitterFactor float64
// Backoff allows you to set a custom algorithm for calculating delays.
// If nil, the standard exponential backoff is used.
Backoff BackoffStrategy
// ConnectTimeout is the timeout for the full connection handshake (WS + EIO + SIO).
// Default: 20s.
ConnectTimeout time.Duration
// PingTimeout is the maximum time to wait for a pong after sending a ping.
// Default: 20s.
PingTimeout time.Duration
// Namespace is the Socket.IO namespace to connect to. Default: "/".
Namespace string
// Auth is the authentication payload sent in the SIO CONNECT packet.
Auth any
}
SocketIOConfig holds all configurable parameters for a Socket.IO connection. Zero values mean "use default". Passing a zero-valued config is safe.
type SocketIOConn ΒΆ added in v0.2.0
type SocketIOConn struct {
// contains filtered or unexported fields
}
SocketIOConn provides support for working with Socket.IO v5 / Engine.IO v4 servers. Supports event-based communication, namespace multiplexing, acknowledgements, binary data, and automatic reconnection.
func DialSocketIO ΒΆ added in v0.2.0
func DialSocketIO( ctx context.Context, c *Client, targetURL string, config SocketIOConfig, mods ...RequestModifier, ) (*SocketIOConn, error)
DialSocketIO connects to a Socket.IO v5 server via the aoni WebSocket pipeline, performs the Engine.IO v4 handshake and Socket.IO v5 CONNECT, and starts background workers for heartbeats and packet reading.
func NewSocketIOConn ΒΆ added in v0.3.0
func NewSocketIOConn(ctx context.Context, conn net.Conn, config SocketIOConfig) (*SocketIOConn, error)
NewSocketIOConn initializes the Engine.IO v4 and Socket.IO v5 protocols over any existing net.Conn network connection.
func (*SocketIOConn) Close ΒΆ added in v0.2.0
func (s *SocketIOConn) Close() error
Close sends a Socket.IO DISCONNECT and Engine.IO CLOSE, then shuts down the connection. Reconnection is suppressed.
func (*SocketIOConn) Connected ΒΆ added in v0.2.0
func (s *SocketIOConn) Connected() bool
Connected reports whether the connection is currently open.
func (*SocketIOConn) Emit ΒΆ added in v0.2.0
func (s *SocketIOConn) Emit(event string, args ...any) error
Emit sends a Socket.IO event on the default namespace. If the last argument is func(args []json.RawMessage), it is used as an ACK callback.
func (*SocketIOConn) EmitVolatile ΒΆ added in v0.2.0
func (s *SocketIOConn) EmitVolatile(event string, args ...any) error
EmitVolatile sends an event only if currently connected; silently drops otherwise.
func (*SocketIOConn) EmitWithAck ΒΆ added in v0.2.0
func (s *SocketIOConn) EmitWithAck(ctx context.Context, event string, args ...any) ([]json.RawMessage, error)
EmitWithAck sends an event on the default namespace and blocks until the server acknowledges it or ctx expires.
func (*SocketIOConn) On ΒΆ added in v0.2.0
func (s *SocketIOConn) On(event string, handler func(args []json.RawMessage))
On registers a handler for a specific Socket.IO event on the default namespace.
func (*SocketIOConn) OnAny ΒΆ added in v0.3.0
func (s *SocketIOConn) OnAny(handler func(event string, args []json.RawMessage))
OnAny registers a catch-all event listener on the default namespace that intercepts all incoming Socket.IO events.
func (*SocketIOConn) OnClose ΒΆ added in v0.2.0
func (s *SocketIOConn) OnClose(handler func())
OnClose sets the callback invoked when the connection closes.
func (*SocketIOConn) OnNamespace ΒΆ added in v0.2.0
func (s *SocketIOConn) OnNamespace(nsp string) *NamespaceSocket
OnNamespace returns a NamespaceSocket scoped to the given namespace.
func (*SocketIOConn) OnReconnectFailed ΒΆ added in v0.2.0
func (s *SocketIOConn) OnReconnectFailed(handler func())
OnReconnectFailed sets the callback invoked when all reconnection attempts are exhausted.
func (*SocketIOConn) OnReconnected ΒΆ added in v0.2.0
func (s *SocketIOConn) OnReconnected(handler func())
OnReconnected sets the callback invoked after a successful reconnection.
func (*SocketIOConn) OnReconnecting ΒΆ added in v0.2.0
func (s *SocketIOConn) OnReconnecting(handler func(attempt int))
OnReconnecting sets the callback invoked before each reconnection attempt.
func (*SocketIOConn) ReconnectionAttempts ΒΆ added in v0.3.0
func (s *SocketIOConn) ReconnectionAttempts() int
ReconnectionAttempts returns the current consecutive reconnection attempt count.
func (*SocketIOConn) SID ΒΆ added in v0.2.0
func (s *SocketIOConn) SID() string
SID returns the server-assigned session ID.
type SourceIPRotator ΒΆ
type SourceIPRotator struct {
// contains filtered or unexported fields
}
SourceIPRotator is a struct that holds a pool of source IP addresses and rotates between them.
func NewSourceIPRotator ΒΆ
func NewSourceIPRotator(addrs []string) (*SourceIPRotator, error)
NewSourceIPRotator creates a new SourceIPRotator with the given IP addresses.
func (*SourceIPRotator) IPs ΒΆ added in v0.3.0
func (r *SourceIPRotator) IPs() []net.IP
IPs returns a safe copy of the current IP pool addresses.
func (*SourceIPRotator) Next ΒΆ
func (r *SourceIPRotator) Next() net.IP
Next returns the next IP address in the pool and rotates to the next one.
func (*SourceIPRotator) NextForFamily ΒΆ added in v0.3.0
func (r *SourceIPRotator) NextForFamily(isIPv4 bool) net.IP
NextForFamily returns the next IP address in the pool that matches the requested IP family (IPv4 if isIPv4 is true, IPv6 otherwise). Returns nil if no matching IP address family is found in the current pool.
func (*SourceIPRotator) Size ΒΆ added in v0.3.0
func (r *SourceIPRotator) Size() int
Size returns the total number of IP addresses currently registered in the pool.
func (*SourceIPRotator) UpdatePool ΒΆ added in v0.3.0
func (r *SourceIPRotator) UpdatePool(addrs []string) error
UpdatePool dynamically replaces the IP addresses in the pool on the fly. Resets the rotation index to 0. Returns an error if the new list is empty or invalid.
type StaticResolver ΒΆ added in v0.3.0
type StaticResolver struct {
// contains filtered or unexported fields
}
StaticResolver allows overriding DNS lookups with static IP mappings. If a queried host is not registered in the static map, it delegates the lookup to the next fallback resolver.
func NewStaticResolver ΒΆ added in v0.3.0
func NewStaticResolver(mapping map[string][]string, delegate DNSResolver) *StaticResolver
NewStaticResolver creates a new StaticResolver with the given IP mapping and delegate.
func (*StaticResolver) LookupIPAddr ΒΆ added in v0.3.0
LookupIPAddr implements the DNSResolver interface.
type StdlibResolver ΒΆ
StdlibResolver delegates DNS resolution to the system resolver via net.Resolver.
func NewStdlibResolver ΒΆ
func NewStdlibResolver() *StdlibResolver
NewStdlibResolver creates a StdlibResolver with the default resolver.
func (*StdlibResolver) LookupIPAddr ΒΆ
LookupIPAddr delegates to the underlying net.Resolver.
type StickyKeyFunc ΒΆ
StickyKeyFunc extracts a session identifier from a request for sticky routing. Return an empty string to fall back to round-robin rotation.
func StickyKeyFromCookie ΒΆ added in v0.2.0
func StickyKeyFromCookie(cookieName string) StickyKeyFunc
StickyKeyFromCookie returns a function to extract the key from a specific cookie.
func StickyKeyFromHeader ΒΆ added in v0.2.0
func StickyKeyFromHeader(headerName string) StickyKeyFunc
StickyKeyFromHeader returns a function to extract the key from the HTTP header.
type StreamResponse ΒΆ
type StreamResponse struct {
// contains filtered or unexported fields
}
StreamResponse wraps an http.Response and manages connection reading streams. Callers are responsible for calling StreamResponse.Close after read operations complete.
func Stream ΒΆ
func Stream( ctx context.Context, c Requester, path string, mods ...RequestModifier, ) (*StreamResponse, error)
Stream executes a GET request and returns the resulting connection body as StreamResponse. Callers must ensure the returned stream is closed when done.
func StreamWithBody ΒΆ
func StreamWithBody( ctx context.Context, c Requester, method, path string, body io.Reader, mods ...RequestModifier, ) (*StreamResponse, error)
StreamWithBody executes an HTTP request with the provided body and returns a raw StreamResponse.
func (*StreamResponse) Close ΒΆ
func (s *StreamResponse) Close() error
Close closes the underlying network response body stream.
func (*StreamResponse) ContentLength ΒΆ
func (s *StreamResponse) ContentLength() int64
ContentLength returns the response body content length, or -1 if unknown.
func (*StreamResponse) ContentType ΒΆ
func (s *StreamResponse) ContentType() string
ContentType returns the Content-Type header field value.
func (*StreamResponse) Read ΒΆ
func (s *StreamResponse) Read(p []byte) (n int, err error)
Read reads connection body data into p.
func (*StreamResponse) Response ΒΆ
func (s *StreamResponse) Response() *http.Response
Response returns the underlying raw http.Response structure.
func (*StreamResponse) StatusCode ΒΆ
func (s *StreamResponse) StatusCode() int
StatusCode returns the HTTP status code of the response.
type TCPDelayRange ΒΆ added in v0.5.0
TCPDelayRange describes a random jitter window applied before the TCP dial.
func GetTCPDelay ΒΆ added in v0.5.0
func GetTCPDelay(ctx context.Context) (TCPDelayRange, bool)
GetTCPDelay returns the TCPDelayRange stored by WithTCPDelay and blocks for a random duration within that range. Callers inside a dialer should call this before opening the connection.
Returns false when no delay is configured.
type TraceInfo ΒΆ
type TraceInfo struct {
// DNSLookup records the time spent resolving the server's IP address.
DNSLookup time.Duration
// TCPConn records the time spent establishing the TCP connection.
TCPConn time.Duration
// TLSHandshake records the time spent completing the SSL/TLS handshake.
TLSHandshake time.Duration
// ServerProcessing records the time from connection establishment to receiving the first response byte.
ServerProcessing time.Duration
// ContentTransfer records the time spent transferring the response body data.
ContentTransfer time.Duration
// Total records the total execution time for the request.
Total time.Duration
// RequestSize records the request payload size in bytes.
RequestSize int64
// ResponseSize records the response payload size in bytes.
ResponseSize int64
// RemoteAddr holds the IP address and port of the remote server connected to.
RemoteAddr string
// JA4 holds the JA4 fingerprints computed during the request.
// Populated only when [TraceJA4] is used as a request modifier.
JA4 *ja4.Report
}
TraceInfo records network layer timing metrics for a request. Timing fields are fully populated only after the response body is completely read.
func ResponseTrace ΒΆ added in v0.3.0
ResponseTrace extracts the TraceInfo previously captured via TraceContext. Returns nil if no trace was registered on the request.
type TrafficInspector ΒΆ added in v0.4.0
type TrafficInspector struct {
// contains filtered or unexported fields
}
TrafficInspector holds requests history and runs the embedded web server.
func NewTrafficInspector ΒΆ added in v0.4.0
func NewTrafficInspector(addr string) *TrafficInspector
NewTrafficInspector initializes a TrafficInspector on the specified address.
func (*TrafficInspector) Capture ΒΆ added in v0.4.0
func (i *TrafficInspector) Capture(req *http.Request, resp *http.Response, reqErr error, trace *TraceInfo)
Capture logs a request/response pair into the inspector and broadcasts it to live clients.
func (*TrafficInspector) GetRequests ΒΆ added in v0.4.0
func (i *TrafficInspector) GetRequests() []CapturedRequest
GetRequests returns a copy of all currently captured requests in reverse chronological order.
func (*TrafficInspector) Start ΒΆ added in v0.4.0
func (i *TrafficInspector) Start() error
Start spins up the local HTTP server in a background goroutine.
func (*TrafficInspector) Stop ΒΆ added in v0.4.0
func (i *TrafficInspector) Stop() error
Stop terminates the inspector web server.
type Transport ΒΆ added in v0.3.0
type Transport struct {
// BeforeRoundTrip is an optional lifecycle hook executed immediately before
// the request is dispatched through the aoni engine.
// It receives the cloned, pre-configured [Client] and the original request,
// and must return the final [Client] to be used. This allows flexible,
// dynamic transport-level adjustments (such as adding headers, configuring
// authentication, or overriding client settings dynamically).
BeforeRoundTrip func(cloned *Client, origReq *http.Request) *Client
// contains filtered or unexported fields
}
Transport implements http.RoundTripper by routing requests through a configured aoni Client pipeline.
Custom X-Aoni Headers ΒΆ
Transport supports declarative configuration of outbound requests via specialized request headers. This provides a clean way to integrate advanced transport features (like TLS fingerprints, proxy routing, or security policies) into standard HTTP clients or third-party SDKs (such as pocketbase-go, Supabase, or Resty) that allow header customization but lack direct access to context modifiers.
These internal headers are parsed dynamically during RoundTrip, applied to the cloned request's Client configuration, and fully stripped from the outgoing request. The remote server will never see these configuration headers.
Supported headers:
X-Aoni-Proxy: Sets the proxy URL for the current request. Format: A standard URL string (e.g. "http://user:pass@127.0.0.1:8080" or "socks5://127.0.0.1:1080").
X-Aoni-TLS-Fingerprint: Selects a uTLS browser client profile to bypass passive TLS fingerprinting. Values: "chrome", "firefox", "safari", "none".
X-Aoni-Timeout: Sets a request-specific timeout. Format: A duration string parsable by time.ParseDuration (e.g. "10s", "500ms").
X-Aoni-SSRF-Guard: Protects the application by blocking connection attempts to private and loopback IPs. Values: "true", "1".
X-Aoni-Max-Response-Size: Protects against decompression bombs by setting a maximum response body size limit. Format: Integer size in bytes (e.g. "1048576" for 1 MB).
func NewTransport ΒΆ added in v0.3.0
NewTransport returns a new http.RoundTripper (specifically *Transport) configured to route all requests through the provided aoni Client. This allows developers to integrate aoni's advanced transport features into existing http.Client instances simply by swapping the Transport field.
func (*Transport) RoundTrip ΒΆ added in v0.3.0
RoundTrip extracts modifiers from the request context, applies them to the request, and delegates to the full aoni pipeline (SSRF guard, Happy Eyeballs, uTLS/JA4, middleware, proxy rotation, decompression, etc.).
In accordance with standard http.RoundTripper requirements, it returns errors wrapped as *url.Error.
type Uint64String ΒΆ
type Uint64String uint64
Uint64String parses uint64 values from string representations in JSON. It safely handles raw integers, JSON null, or empty strings.
func (Uint64String) MarshalJSON ΒΆ added in v0.3.0
func (u Uint64String) MarshalJSON() ([]byte, error)
MarshalJSON serializes the Uint64String back as a JSON string representation.
func (*Uint64String) UnmarshalJSON ΒΆ
func (u *Uint64String) UnmarshalJSON(b []byte) error
UnmarshalJSON parses JSON byte data into the Uint64String target.
type UnixTimestamp ΒΆ
UnixTimestamp parses Unix timestamps from strings or numbers in JSON.
func (UnixTimestamp) MarshalJSON ΒΆ added in v0.3.0
func (t UnixTimestamp) MarshalJSON() ([]byte, error)
MarshalJSON serializes the UnixTimestamp back as a numeric Unix epoch timestamp.
func (UnixTimestamp) Time ΒΆ
func (t UnixTimestamp) Time() time.Time
Time returns the time.Time value.
func (*UnixTimestamp) UnmarshalJSON ΒΆ
func (t *UnixTimestamp) UnmarshalJSON(b []byte) error
UnmarshalJSON implements json.Unmarshaler.
type Unwrapper ΒΆ
type Unwrapper interface {
Unwrap() Requester
}
Unwrapper allows nested decorators to be peeled away to reach the underlying Requester. Client does not implement this interface; wrapper types returned by NewStdClient or Chain do.
type ValidationError ΒΆ
type ValidationError struct {
Field string
}
ValidationError reports that a required field was missing or invalid during request validation. Inspect with errors.As to access Field.
func (*ValidationError) Error ΒΆ
func (e *ValidationError) Error() string
Error returns a human-readable description of the validation failure.
type WebSocketConn ΒΆ added in v0.3.0
type WebSocketConn interface {
net.Conn
// ReadMessage ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Ρ Π΅Π³ΠΎ ΡΠΈΠΏ
// (TextMessage ΠΈΠ»ΠΈ BinaryMessage) ΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΡΡ Π½Π°Π³ΡΡΠ·ΠΊΡ.
ReadMessage() (messageType int, p []byte, err error)
// WriteMessage ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° (TextMessage ΠΈΠ»ΠΈ BinaryMessage).
WriteMessage(messageType int, data []byte) error
// UnderlyingConn Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π½ΠΈΠ·ΠΊΠΎΡΡΠΎΠ²Π½Π΅Π²ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, *websocket.Conn ΠΈΠ»ΠΈ http2 stream).
UnderlyingConn() any
// CloseChan Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΊΠ°Π½Π°Π», Π·Π°ΠΊΡΡΠ²Π°ΡΡΠΈΠΉΡΡ ΠΏΡΠΈ ΡΠ°Π·ΡΡΠ²Π΅ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ.
CloseChan() <-chan struct{}
}
WebSocketConn represents an active WebSocket connection. It extends the net.Conn interface, allowing the connection to be used with standard Go abstractions, while simultaneously providing direct access to reading/writing typed WebSocket messages (Text/Binary), receiving the low-level socket and monitoring channel closure.
Source Files
ΒΆ
- bridge.go
- challenge.go
- client.go
- concurrent.go
- cookie_storage.go
- cookie_transport.go
- decode.go
- dns.go
- doc.go
- errors.go
- fragment.go
- h2.go
- h3.go
- health.go
- inspector.go
- io.go
- ip.go
- jar.go
- loadbalancer.go
- middleware.go
- options.go
- overrides.go
- padding.go
- persona.go
- proxy.go
- requests.go
- rewrite.go
- rtt.go
- session.go
- socketio.go
- stream.go
- tcp_maxseg_unix.go
- trace.go
- values.go
- websocket.go
- wsconn.go
Directories
ΒΆ
| Path | Synopsis |
|---|---|
|
examples
|
|
|
01_basic_get
command
Example: Basic GET request with typed JSON response.
|
Example: Basic GET request with typed JSON response. |
|
02_path_and_query
command
Example: Path variables and query parameters.
|
Example: Path variables and query parameters. |
|
03_post_json
command
Example: POST with JSON body and custom error model.
|
Example: POST with JSON body and custom error model. |
|
04_headers_auth
command
Example: Bearer token, Basic auth, and custom headers.
|
Example: Bearer token, Basic auth, and custom headers. |
|
05_error_handling
command
Example: Error handling with APIError, ErrCloudflareChallenge, and status codes.
|
Example: Error handling with APIError, ErrCloudflareChallenge, and status codes. |
|
06_proxy_rotation
command
Example: Proxy rotation with sticky sessions and retry middleware.
|
Example: Proxy rotation with sticky sessions and retry middleware. |
|
07_retry_middleware
command
Example: Retry middleware with RetryOptions and retry conditions.
|
Example: Retry middleware with RetryOptions and retry conditions. |
|
08_circuit_breaker
command
Example: Circuit breaker middleware.
|
Example: Circuit breaker middleware. |
|
09_tracing
command
Example: Request tracing and curl command generation.
|
Example: Request tracing and curl command generation. |
|
10_streaming
command
Example: Streaming responses with Stream, StreamSSE, and StreamNDJSON.
|
Example: Streaming responses with Stream, StreamSSE, and StreamNDJSON. |
|
11_ja4_fingerprint
command
Example: JA4 fingerprinting with TLS impersonation.
|
Example: JA4 fingerprinting with TLS impersonation. |
|
12_websocket
command
Example: WebSocket connection and binary message round-trip.
|
Example: WebSocket connection and binary message round-trip. |
|
13_tls_evasion
command
Example: Full TLS evasion stack.
|
Example: Full TLS evasion stack. |
|
14_load_balancer
command
Example: Load balancer with weighted round-robin strategy.
|
Example: Load balancer with weighted round-robin strategy. |
|
15_browser_impersonation
command
Example: Browser impersonation with Chrome and Firefox profiles.
|
Example: Browser impersonation with Chrome and Firefox profiles. |
|
16_p0f_fingerprint
command
Example: p0f fingerprinting
|
Example: p0f fingerprinting |
|
17_socketio
command
Example: Socket.IO client
|
Example: Socket.IO client |
|
18_persona
command
Example: Fingerprint Integrity using the Persona module.
|
Example: Fingerprint Integrity using the Persona module. |
|
19_challenge_solver
command
Example: WAF/Cloudflare Challenge Solver interface.
|
Example: WAF/Cloudflare Challenge Solver interface. |
|
20_inspector
command
Example: Embedded Traffic Inspector
|
Example: Embedded Traffic Inspector |
|
Package ja4 implements JA4+ network fingerprinting algorithms in pure Go.
|
Package ja4 implements JA4+ network fingerprinting algorithms in pure Go. |