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).
WithHeader("Accept", "application/json")
resp, err := client.Request(ctx, http.MethodGet, "/users/123")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var user User
if err := aoni.DecodeJSON(resp, &user); err != nil {
log.Fatal(err)
}
The full example directory contains runnable programs for each feature.
Index ΒΆ
- Constants
- Variables
- func CurlCommand(req *http.Request, body []byte) string
- func DefaultCircuitBreakerCondition(resp *http.Response, err error) bool
- func DefaultRedirectPolicy(maxRedirects int, sensitiveHeaders ...string) func(req *http.Request, via []*http.Request) error
- func Delete[Resp any](ctx context.Context, path string, payload any, mods ...RequestModifier) (*Resp, error)
- func DeleteJSON[Resp any](ctx context.Context, c Requester, path string, payload any, ...) (*Resp, 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 GeneratePadding(cfg PacketPaddingConfig) []byte
- func Get[Resp any](ctx context.Context, path string, mods ...RequestModifier) (*Resp, error)
- func GetJSON[Resp any](ctx context.Context, c Requester, path string, mods ...RequestModifier) (*Resp, error)
- func ImportCookies(jar http.CookieJar, u *url.URL, cookies []CookieData)
- 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 PacketPaddingConfig) string
- func ParseSSE[T any](ctx context.Context, resp *StreamResponse) (<-chan T, <-chan error)
- func Patch[Resp any](ctx context.Context, path string, payload any, mods ...RequestModifier) (*Resp, error)
- func PatchJSON[Resp any](ctx context.Context, c Requester, path string, payload any, ...) (*Resp, error)
- func Post[Resp any](ctx context.Context, path string, payload any, mods ...RequestModifier) (*Resp, error)
- func PostForm[Resp any](ctx context.Context, c Requester, path string, payload any, ...) (*Resp, error)
- func PostJSON[Resp any](ctx context.Context, c Requester, path string, payload any, ...) (*Resp, error)
- func Put[Resp any](ctx context.Context, path string, payload any, mods ...RequestModifier) (*Resp, error)
- func PutJSON[Resp any](ctx context.Context, c Requester, path string, payload any, ...) (*Resp, 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 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 BaseResponse
- type BaseResponseProvider
- type BoolInt
- type BrowserID
- 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) HTTP() HTTPDoer
- func (c *Client) Logger() Logger
- 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) 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) WithHappyEyeballs(delay time.Duration) *Client
- func (c *Client) WithHeader(key, value string) *Client
- func (c *Client) WithHedging(d time.Duration) *Client
- func (c *Client) WithHostRewrite(rules map[string]string) *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 PacketPaddingConfig) *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) WithRedirectLimit(max int) *Client
- func (c *Client) WithSSRFGuard() *Client
- func (c *Client) WithTLSFingerprint(browser BrowserID) *Client
- func (c *Client) WithTimeout(d time.Duration) *Client
- func (c *Client) WithUserAgent(ua string) *Client
- type ClientWithProxy
- type ConnectionPoolConfig
- type CookieData
- type DNSResolver
- type Decoder
- type DecoderFunc
- type DialWebSocketConfig
- type DoHResolver
- type DoTResolver
- type DoerFunc
- type DynamicHedgingConfig
- type FallbackFunc
- type Float64String
- type FragmentConfig
- type H2FramedTransport
- type HTTP2Settings
- type HTTPDoer
- type HealthTracker
- type HostRewriteConfig
- type InMemoryDNSCache
- type Int64String
- type JitterStrategy
- type LoadBalancer
- type LoadBalancerConfig
- 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))
- type NoResponse
- type PacketPaddingConfig
- type ProgressFunc
- type ProxyAwareSessionCache
- type ProxyConfig
- type 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) UpdateClients(clients ...ClientWithProxy)
- func (r *ProxyRotator) WithStickySessions(f StickyKeyFunc) *ProxyRotator
- type ProxyRotatorConfig
- type ProxyRoutedDNSResolver
- type QUICMigrationConfig
- type RTTTracker
- func (t *RTTTracker) Count() int
- 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) SmoothedRTT() time.Duration
- type ReplayableBody
- type RequestModifier
- func AsCurl() RequestModifier
- func AsJSON() RequestModifier
- func AsRaw() RequestModifier
- func AsXML() RequestModifier
- func AsYAML() RequestModifier
- func CaptureResponse(target **http.Response) RequestModifier
- func ContextModifiers(ctx context.Context) []RequestModifier
- func Debug() RequestModifier
- func Trace(target *TraceInfo) 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 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 WithFragmentation(cfg FragmentConfig) RequestModifier
- func WithHeader(key, value string) RequestModifier
- func WithHedging(delay time.Duration) RequestModifier
- func WithHostRewrite(rules map[string]string) RequestModifier
- func WithJSONBody(payload any) 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 WithQuery(query any) RequestModifier
- func WithStreamingMultipart(fields map[string]string, files map[string]io.Reader) RequestModifier
- func WithUploadProgress(onProgress ProgressFunc) RequestModifier
- func WithUserAgent(ua string) RequestModifier
- func WithVar(key string, value any) RequestModifier
- func WithVars(pairs ...any) RequestModifier
- type Requester
- type RetryCondition
- type RetryOptions
- 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) 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) SID() string
- type SourceIPRotator
- type StdlibResolver
- type StickyKeyFunc
- type StreamResponse
- type TraceInfo
- type Uint64String
- type UnixTimestamp
- type Unwrapper
- type ValidationError
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") // 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 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.
Functions ΒΆ
func CurlCommand ΒΆ
CurlCommand generates a shell-compatible curl command string from an http.Request and body.
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[Resp any]( ctx context.Context, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
Delete performs a global DELETE request using DefaultClient and decodes the JSON response body.
func DeleteJSON ΒΆ
func DeleteJSON[Resp any]( ctx context.Context, c Requester, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
DeleteJSON marshals the payload to JSON, executes a DELETE request, and decodes the response body. It automatically configures the request headers with Content-Type and Accept set to "application/json".
It validates the payload structure beforehand using Validate. Returns a ValidationError if validation fails.
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 GeneratePadding ΒΆ added in v0.2.0
func GeneratePadding(cfg PacketPaddingConfig) []byte
GeneratePadding returns random padding bytes of the configured length range.
func Get ΒΆ
Get performs a global GET request using DefaultClient and decodes the JSON response body.
func GetJSON ΒΆ
func GetJSON[Resp any]( ctx context.Context, c Requester, path string, mods ...RequestModifier, ) (*Resp, error)
GetJSON performs a GET request and decodes the JSON response body into a new instance of Resp. It returns an APIError if the server responds with a non-2xx status code.
func ImportCookies ΒΆ
func ImportCookies(jar http.CookieJar, u *url.URL, cookies []CookieData)
ImportCookies imports cookies from the browser into aoni.CookieJar.
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 PacketPaddingConfig) 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 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[Resp any]( ctx context.Context, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
Patch performs a global PATCH request using DefaultClient and decodes the JSON response body.
func PatchJSON ΒΆ
func PatchJSON[Resp any]( ctx context.Context, c Requester, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
PatchJSON marshals the payload to JSON, executes a PATCH request, and decodes the response body. It automatically configures the request headers with Content-Type and Accept set to "application/json".
It validates the payload structure beforehand using Validate. Returns a ValidationError if validation fails.
func Post ΒΆ
func Post[Resp any]( ctx context.Context, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
Post performs a global POST request using DefaultClient and decodes the JSON response body.
func PostForm ΒΆ
func PostForm[Resp any]( ctx context.Context, c Requester, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
PostForm marshals the payload, performs a POST request with URL-encoded parameters, and decodes the resulting JSON response body into Resp.
It validates the payload structure beforehand using Validate. Returns a ValidationError if validation fails.
func PostJSON ΒΆ
func PostJSON[Resp any]( ctx context.Context, c Requester, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
PostJSON marshals the payload to JSON, executes a POST request, and decodes the response body. It automatically configures the request headers with Content-Type and Accept set to "application/json".
It validates the payload structure beforehand using Validate. Returns a ValidationError if validation fails.
func Put ΒΆ
func Put[Resp any]( ctx context.Context, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
Put performs a global PUT request using DefaultClient and decodes the JSON response body.
func PutJSON ΒΆ
func PutJSON[Resp any]( ctx context.Context, c Requester, path string, payload any, mods ...RequestModifier, ) (*Resp, error)
PutJSON marshals the payload to JSON, executes a PUT request, and decodes the response body. It automatically configures the request headers with Content-Type and Accept set to "application/json".
It validates the payload structure beforehand using Validate. Returns a ValidationError if validation fails.
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 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 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 GetJSON 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) UnmarshalJSON ΒΆ
UnmarshalJSON implements json.Unmarshaler.
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 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) Logger ΒΆ
Logger returns the logger used by the client. If no logger is set, a no-op logger is returned.
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) 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) 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) 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) 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 PacketPaddingConfig) *Client
WithPacketPadding returns a clone of c that constrains TCP MSS and adds random padding headers to disrupt DPI length analysis. See PacketPaddingConfig for available fields.
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) 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) 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) 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.
type ClientWithProxy ΒΆ
ClientWithProxy pairs an HTTPDoer with a proxy URL.
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.
func ExportCookies ΒΆ
func ExportCookies(jar http.CookieJar, u *url.URL) []CookieData
ExportCookies prepares cookies for loading into Playwright/Chromedp.
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.
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
}
DoTResolver resolves DNS over TLS, querying both A and AAAA records. Uses github.com/miekg/dns for reliable DNS packet construction and parsing.
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.
type Float64String ΒΆ
type Float64String float64
Float64String parses float64 values from string representations in JSON.
func (*Float64String) UnmarshalJSON ΒΆ
func (f *Float64String) UnmarshalJSON(b []byte) error
UnmarshalJSON parses JSON byte data into the Float64String target.
type FragmentConfig ΒΆ
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.
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 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) 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.
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) UnmarshalJSON ΒΆ
func (i *Int64String) UnmarshalJSON(b []byte) error
UnmarshalJSON parses JSON byte data into the Int64String target.
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) 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 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.
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.
type NoResponse ΒΆ
type NoResponse struct{}
NoResponse is a sentinel type used to indicate a request that does not return a response body.
type PacketPaddingConfig ΒΆ added in v0.2.0
type PacketPaddingConfig 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.
//
// Example:
//
// []string{
// "X-Amz-Trace-Id",
// "X-Cloud-Trace-Context",
// "CF-RAY",
// "X-Edge-Cache-Id",
// "X-Request-ID",
// "X-Trace-ID",
// }
HeaderPool []string
}
PacketPaddingConfig controls MTU fragmentation and packet padding to disrupt DPI signature analysis of packet length patterns.
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) 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) 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.
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 (*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) UpdateClients ΒΆ
func (r *ProxyRotator) UpdateClients(clients ...ClientWithProxy)
UpdateClients replaces the active pool and resets all session mappings. If clients is empty, it returns without changes.
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 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) Count ΒΆ added in v0.2.0
func (t *RTTTracker) Count() int
Count returns the number of recorded samples.
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) 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 AsCurl ΒΆ
func AsCurl() RequestModifier
AsCurl returns a RequestModifier that dumps the equivalent curl command to stderr.
func AsJSON ΒΆ
func AsJSON() RequestModifier
AsJSON returns a RequestModifier that uses JSONDecoder.
func AsYAML ΒΆ
func AsYAML() RequestModifier
AsYAML returns a RequestModifier that uses YAMLDecoder.
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 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 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 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 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 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 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 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 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 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 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.
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 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 total number of attempts (1 = 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
}
RetryOptions configures RetryMiddleware.
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
// 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 (*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) 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) 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) Next ΒΆ
func (r *SourceIPRotator) Next() net.IP
Next returns the next IP address in the pool and rotates to the next one.
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 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
// 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.
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) 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) 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.
Source Files
ΒΆ
- bridge.go
- client.go
- cookie_transport.go
- decode.go
- dns.go
- doc.go
- errors.go
- fragment.go
- h2_impersonation.go
- h2framed.go
- health.go
- io.go
- jar.go
- loadbalancer.go
- local_addr.go
- middleware.go
- options.go
- packet_padding.go
- proxy.go
- requests.go
- rewrite.go
- rtt_tracker.go
- session_cache.go
- session_sync.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 |
|
Package ja4 implements JA4+ network fingerprinting algorithms in pure Go.
|
Package ja4 implements JA4+ network fingerprinting algorithms in pure Go. |