tls_client

package module
v1.29.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: BSD-4-Clause Imports: 36 Imported by: 0

README

TLS-Client

A Go HTTP client that sends requests with a real browser's TLS and HTTP/2 fingerprint. Changing the User-Agent is not enough — servers fingerprint the TLS ClientHello (cipher and extension order, key shares → JA3/JA4) and the HTTP/2 preamble (SETTINGS, window update, header priority, pseudo-header order → the Akamai fingerprint). This client reproduces both from captured browser data, so at the handshake layer it is indistinguishable from the browser it impersonates.

This is a fork of bogdanfinn/tls-client, published as github.com/yqpw75dbyf-droid/tls-client. It builds on fhttp and utls.

For the full design and request flow, see ARCHITECTURE.md.

What this fork adds

  • Opera 92–136 — the full modern line, mapped to the right Chromium base (the offset drifts +14 → +15 → +16 where Opera skipped Chromium 129 and 136).
  • Safari macOS 15.3–26.6 — every point release, grouped by the handshake era it belongs to, with the desktop HTTP/2 differences from iOS.
  • Tor Browser 13.0–16.0 — 15.0 (through 15.0.24) and 16.0 (from the 16.0a13 alpha on Firefox 153 ESR) captured from real installs over a live Tor circuit.
  • Chrome 153–154, Edge 153–154 and Brave 154 — captured from the real browsers; Chrome 154 sends its trust_anchors IDs in one sorted order where 153 shuffled them per process, and Edge and Brave are Chrome without the extension.
  • Firefox and Tor ECH GREASE — the AEAD and payload size now follow NSS exactly: AES-128-GCM or ChaCha20-Poly1305, one size per build, never the AES-256-GCM or alternating sizes no real Firefox sends.
  • Firefox repairs — the profiles now carry the resumption extensions and the real HTTP/2 header-frame priority, instead of accidentally wearing Tor's shape and Chrome's H2 priority.
  • A Python package — import tls_client; tls_client.get(url, preset=...), see python/.
  • Fingerprint fixes verified on the wire, and per-profile tests that fail if a profile drifts from the browser it names.

Features

  • HTTP/1.1, HTTP/2, HTTP/3 with automatic protocol selection
  • Protocol racing (Chrome-style happy eyeballs for HTTP/2 vs HTTP/3)
  • TLS fingerprinting for Chrome, Firefox, Safari, Edge, Opera, Brave, Tor, and mobile app clients
  • Custom fingerprints from a JA3 string plus HTTP/2 and HTTP/3 parameters
  • WebSocket over the same fingerprinted TLS dialer
  • Custom header ordering
  • HTTP and SOCKS4/SOCKS5 proxies (SOCKS5 UDP for HTTP/3)
  • Cookie jar management
  • Certificate pinning
  • Bandwidth tracking
  • Language bindings via a C shared library: Python, Node.js, C#

Install (Go)

go get github.com/yqpw75dbyf-droid/tls-client@latest

Quick start (Go)

package main

import (
	"fmt"
	"io"
	"log"

	http "github.com/bogdanfinn/fhttp"
	tls_client "github.com/yqpw75dbyf-droid/tls-client"
	"github.com/yqpw75dbyf-droid/tls-client/profiles"
)

func main() {
	jar := tls_client.NewCookieJar()
	options := []tls_client.HttpClientOption{
		tls_client.WithTimeoutSeconds(30),
		tls_client.WithClientProfile(profiles.Chrome_153),
		tls_client.WithRandomTLSExtensionOrder(), // Chromium shuffles per connection
		tls_client.WithCookieJar(jar),
	}

	client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
	if err != nil {
		log.Fatal(err)
	}

	req, err := http.NewRequest(http.MethodGet, "https://tls.peet.ws/api/all", nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header = http.Header{
		"accept":          {"*/*"},
		"accept-language": {"en-US,en;q=0.9"},
		"user-agent":      {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36"},
		http.HeaderOrderKey: {"accept", "accept-language", "user-agent"},
	}

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.StatusCode)
	fmt.Println(string(body))
}

Quick start (Python)

import tls_client

r = tls_client.get("https://tls.peet.ws/api/all", preset="chrome_154")
print(r.status_code, r.protocol)

with tls_client.Session(preset="firefox_135") as s:
    s.get("https://example.com")

The Python package drives a compiled C shared library that is not bundled; python/README.md covers building it and the full API.

Profiles

profiles.MappedTLSClients (Go) and tls_client.CLIENT_IDENTIFIERS (Python) list every identifier: Chrome 103–154, Edge 153–154, Firefox 102–148, Safari macOS 15.3–26.6 and iOS, Opera 89–136, Tor Browser 13.x–16, Brave 146 and 154, and app profiles (Nike, Zalando, MMS, Mesh, okhttp, and others).

Getting a profile right

The handshake is only half of looking like a browser. Match the rest too:

  • Chromium (Chrome, Opera, Edge): enable WithRandomTLSExtensionOrder() — real Chrome shuffles its extension order every connection.
  • Safari and Tor: do not shuffle; those engines never do.
  • Tor: route through the Tor daemon (socks5://127.0.0.1:9150 for Tor Browser, 9050 for a standalone tor) and disable HTTP/3. A Tor fingerprint from a non-Tor IP is worse than not impersonating Tor.
  • Every profile: send headers that tell the same story — the right User-Agent, the matching sec-ch-ua (or none, for Firefox/Safari/Tor, which have no client hints), and the browser's real header order.
  • HTTP/3: leave it off (the default) when impersonating a browser. Only the TCP path wears the profile. Over QUIC the TLS hello is Go's default (no ALPS, ECH, certificate compression or trust_anchors, and the EMS, renegotiation and point-format extensions Chrome dropped), the transport parameters are quic-go's, and only Chrome 144 and Firefox 147–148 carry HTTP/3 settings; the other profiles send just the datagram setting. Where a GREASE frame is sent it is the same constant (type 31000000033, empty) on every connection, where Chrome draws a new type and payload each time. TLS GREASE over TCP is fine: it is drawn per connection from one seed, the way BoringSSL does.

Language bindings

The Go core compiles to a C shared library (cffi_dist/) that exposes request, getCookiesFromSession, addCookiesToSession, destroySession, destroyAll, and freeMemory over JSON. Examples for Python, Node.js, C#, and TypeScript are in cffi_dist/.

cd cffi_dist
CGO_ENABLED=1 go build -buildmode=c-shared -o dist/tls-client.so .   # .dll / .dylib per OS

Testing

Test files are kept local only and are not published to the module: *_test.go and the tests/ integration suite are git-ignored. They still run in a local checkout.

go test ./...                 # library + profile tests
# tests/ integration suite needs a SOCKS_5_PROXY env var for the proxy tests

Credits and license

Fork of bogdanfinn/tls-client, itself built on the work of Carcraftz and the refraction-networking/utls project. MIT licensed; see LICENSE.

Documentation

Index

Constants

View Source
const CHROME_MAX_FIELD_SECTION_SIZE = 262144

Variables

View Source
var DefaultBadPinHandler = func(req *http.Request) {
	fmt.Println("this is the default bad pin handler")
}
View Source
var DefaultTimeoutSeconds = 30
View Source
var ErrBadPinDetected = errors.New("bad ssl pin detected")
View Source
var ErrContinueHooks = errors.New("continue hooks")

ErrContinueHooks can be returned (or wrapped) by a PreRequestHookFunc to signal that the error should be logged but hook execution should continue to the next hook. By default any error returned from a hook aborts subsequent hooks and the request.

View Source
var H2SettingsMap = map[string]http2.SettingID{
	"HEADER_TABLE_SIZE":      http2.SettingHeaderTableSize,
	"ENABLE_PUSH":            http2.SettingEnablePush,
	"MAX_CONCURRENT_STREAMS": http2.SettingMaxConcurrentStreams,
	"INITIAL_WINDOW_SIZE":    http2.SettingInitialWindowSize,
	"MAX_FRAME_SIZE":         http2.SettingMaxFrameSize,
	"MAX_HEADER_LIST_SIZE":   http2.SettingMaxHeaderListSize,
	"UNKNOWN_SETTING_7":      0x7,
	"UNKNOWN_SETTING_8":      0x8,
	"UNKNOWN_SETTING_9":      0x9,
}
View Source
var H3SettingsMap = map[string]uint64{
	"QPACK_MAX_TABLE_CAPACITY": 0x1,
	"MAX_FIELD_SECTION_SIZE":   0x6,
	"QPACK_BLOCKED_STREAMS":    0x7,
	"H3_DATAGRAM":              0x33,
}

Functions

func GetSpecFactoryFromJa3String

func GetSpecFactoryFromJa3String(ja3String string, supportedSignatureAlgorithms, supportedDelegatedCredentialsAlgorithms, supportedVersions, keyShareCurves, supportedProtocolsALPN, supportedProtocolsALPS []string, echCandidateCipherSuites []CandidateCipherSuites, candidatePayloads []uint16, certCompressionAlgorithms []string, recordSizeLimit uint16, trustAnchorsPayload string) (func() (tls.ClientHelloSpec, error), error)

func Int64ToInt

func Int64ToInt(x int64) (int, error)

Types

type BadPinHandlerFunc

type BadPinHandlerFunc func(req *http.Request)

type CandidateCipherSuites

type CandidateCipherSuites struct {
	KdfId  string
	AeadId string
}

type CertificatePinner

type CertificatePinner interface {
	Pin(conn *tls.UConn, host string) error
}

func NewCertificatePinner

func NewCertificatePinner(certificatePins map[string][]string) (CertificatePinner, error)

type ContextKeyHeader

type ContextKeyHeader struct{}

Users of context.WithValue should define their own types for keys

type CookieJar

type CookieJar interface {
	http.CookieJar
	GetAllCookies() map[string][]*http.Cookie
}

func NewCookieJar

func NewCookieJar(options ...CookieJarOption) CookieJar

type CookieJarOption

type CookieJarOption func(config *cookieJarConfig)

func WithAllowEmptyCookies

func WithAllowEmptyCookies() CookieJarOption

func WithDebugLogger

func WithDebugLogger() CookieJarOption

func WithLogger

func WithLogger(logger Logger) CookieJarOption

func WithSkipExisting

func WithSkipExisting() CookieJarOption

type HttpClient

type HttpClient interface {
	GetCookies(u *url.URL) []*http.Cookie
	SetCookies(u *url.URL, cookies []*http.Cookie)
	SetCookieJar(jar http.CookieJar)
	GetCookieJar() http.CookieJar
	SetProxy(proxyUrl string) error
	GetProxy() string
	SetFollowRedirect(followRedirect bool)
	GetFollowRedirect() bool
	CloseIdleConnections()
	Do(req *http.Request) (*http.Response, error)
	Get(url string) (resp *http.Response, err error)
	Head(url string) (resp *http.Response, err error)
	Post(url, contentType string, body io.Reader) (resp *http.Response, err error)

	GetBandwidthTracker() bandwidth.BandwidthTracker
	GetDialer() proxy.ContextDialer
	GetTLSDialer() TLSDialerFunc

	AddPreRequestHook(hook PreRequestHookFunc)
	AddPostResponseHook(hook PostResponseHookFunc)
	ResetPreHooks()
	ResetPostHooks()
}

func NewHttpClient

func NewHttpClient(logger Logger, options ...HttpClientOption) (HttpClient, error)

NewHttpClient constructs a new HTTP client with the given logger and client options.

func ProvideDefaultClient

func ProvideDefaultClient(logger Logger) (HttpClient, error)

type HttpClientOption

type HttpClientOption func(config *httpClientConfig)

func WithBandwidthTracker

func WithBandwidthTracker() HttpClientOption

WithBandwidthTracker configures a client to track the bandwidth used by the client.

func WithCatchPanics

func WithCatchPanics() HttpClientOption

WithCatchPanics configures a client to catch all go panics happening during a request and not print the stacktrace.

func WithCertificatePinning

func WithCertificatePinning(certificatePins map[string][]string, handlerFunc BadPinHandlerFunc) HttpClientOption

WithCertificatePinning enables SSL Pinning for the client and will throw an error if the SSL Pin is not matched. Please refer to https://github.com/tam7t/hpkp/#examples in order to see how to generate pins. The certificatePins are a map with the host as key. You can provide a BadPinHandlerFunc or nil as second argument. This function will be executed once a bad ssl pin is detected. BadPinHandlerFunc has to be defined like this: func(req *http.Request){}

func WithCharlesProxy

func WithCharlesProxy(host string, port string) HttpClientOption

WithCharlesProxy configures the HTTP client to use a local running charles as proxy.

host and port can be empty, then default 127.0.0.1 and port 8888 will be used

func WithClientProfile

func WithClientProfile(clientProfile profiles.ClientProfile) HttpClientOption

WithClientProfile configures a TLS client to use the specified client profile.

func WithConnectHeaders

func WithConnectHeaders(headers http.Header) HttpClientOption

WithConnectHeaders configures a client to use the specified headers for the CONNECT request.

func WithCookieJar

func WithCookieJar(jar http.CookieJar) HttpClientOption

WithCookieJar configures a HTTP client to use the specified cookie jar.

func WithCustomRedirectFunc

func WithCustomRedirectFunc(redirectFunc func(req *http.Request, via []*http.Request) error) HttpClientOption

WithCustomRedirectFunc configures an HTTP client to use a custom redirect func. The redirect func have to look like that: func(req *http.Request, via []*http.Request) error Please only provide a custom redirect function if you know what you are doing. Check docs on net/http.Client CheckRedirect

func WithDebug

func WithDebug() HttpClientOption

WithDebug configures a client to log debugging information.

func WithDefaultHeaders

func WithDefaultHeaders(defaultHeaders http.Header) HttpClientOption

WithDefaultHeaders configures a TLS client to use a set of default headers if none are specified on the request.

func WithDialContext

func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) HttpClientOption

WithDialContext sets a custom dialer for TCP connections, allowing advanced networking (Zero-DNS, socket tagging, DPI bypass).

WARNING: This overrides built-in proxy settings. If you need a proxy, you must handle the CONNECT handshake manually. CHECK: https://github.com/yqpw75dbyf-droid/tls-client/pull/218#issuecomment-3858171801

func WithDialer

func WithDialer(dialer net.Dialer) HttpClientOption

WithDialer configures an HTTP client to use the specified dialer. This allows the use of a custom DNS resolver

func WithDisableHttp3

func WithDisableHttp3() HttpClientOption

WithDisableHttp3 configures a client to disable HTTP 3 as the used protocol. Will most likely fall back to HTTP 2

func WithDisableIPV4

func WithDisableIPV4() HttpClientOption

WithDisableIPV4 configures a dialer to use tcp6 network argument

func WithDisableIPV6

func WithDisableIPV6() HttpClientOption

WithDisableIPV6 configures a dialer to use tcp4 network argument

func WithDisableSessionTickets

func WithDisableSessionTickets() HttpClientOption

WithDisableSessionTickets configures a client to disable TLS session ticket caching and resumption.

func WithForceHttp1

func WithForceHttp1() HttpClientOption

WithForceHttp1 configures a client to force HTTP/1.1 as the used protocol.

func WithInsecureSkipVerify

func WithInsecureSkipVerify() HttpClientOption

WithInsecureSkipVerify configures a client to skip SSL certificate verification.

func WithLocalAddr

func WithLocalAddr(localAddr net.TCPAddr) HttpClientOption

WithLocalAddr configures an HTTP client to use the specified local address.

func WithNotFollowRedirects

func WithNotFollowRedirects() HttpClientOption

WithNotFollowRedirects configures an HTTP client to not follow HTTP redirects.

func WithPostHook

func WithPostHook(hook PostResponseHookFunc) HttpClientOption

WithPostHook adds a post-response hook that is called after each request completes. Multiple hooks can be added and they will be executed in the order they were added. All hooks are always executed, even if the request failed or a previous hook panicked.

func WithPreHook

func WithPreHook(hook PreRequestHookFunc) HttpClientOption

WithPreHook adds a pre-request hook that is called before each request is sent. Multiple hooks can be added and they will be executed in the order they were added. If any hook returns an error, the request is aborted and subsequent hooks are not called.

func WithProtocolRacing

func WithProtocolRacing() HttpClientOption

WithProtocolRacing configures a client to race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel. Similar to Chrome's "Happy Eyeballs" approach, this starts both connection types simultaneously and uses whichever connects first. The client will remember which protocol worked for each host and use it directly on subsequent requests. This option is ignored if WithForceHttp1 or WithDisableHttp3 is set.

func WithProxyDialerFactory

func WithProxyDialerFactory(proxyDialerFactory ProxyDialerFactory) HttpClientOption

WithProxyDialerFactory configures an HTTP client to use a custom proxyDialerFactory instead of newConnectDialer(). This allows to implement custom proxy dialer use cases

func WithProxyUrl

func WithProxyUrl(proxyUrl string) HttpClientOption

WithProxyUrl configures an HTTP client to use the specified proxy URL.

proxyUrl should be formatted as:

"http://user:pass@host:port"

func WithRandomTLSExtensionOrder

func WithRandomTLSExtensionOrder() HttpClientOption

WithRandomTLSExtensionOrder configures a TLS client to randomize the order of TLS extensions being sent in the ClientHello.

Placement of GREASE and padding is fixed and will not be affected by this.

func WithServerNameOverwrite

func WithServerNameOverwrite(serverName string) HttpClientOption

WithServerNameOverwrite configures a TLS client to overwrite the server name being used for certificate verification and in the client hello. This option does only work properly if WithInsecureSkipVerify is set to true in addition

func WithTimeout

func WithTimeout(timeout int) HttpClientOption

WithTimeout configures an HTTP client to use the specified request timeout.

timeout is the request timeout in seconds. Deprecated: use either WithTimeoutSeconds or WithTimeoutMilliseconds

func WithTimeoutMilliseconds

func WithTimeoutMilliseconds(timeout int) HttpClientOption

WithTimeoutMilliseconds configures a hard deadline for the entire request lifecycle.

This includes connection time, redirects, and reading the response body. WARNING: If the timer expires, the connection is forcibly closed, even if you are actively downloading data.

- Use 0 to disable the deadline (Unlimited) for large downloads or long-polling. - Default is 30000 milliseconds (30 seconds).

func WithTimeoutSeconds

func WithTimeoutSeconds(timeout int) HttpClientOption

WithTimeoutSeconds configures a hard deadline for the entire request lifecycle.

This includes connection time, redirects, and reading the response body. WARNING: If the timer expires, the connection is forcibly closed, even if you are actively downloading data.

- Use 0 to disable the deadline (Unlimited) for large downloads or long-polling. - Default is 30 seconds.

func WithTransportOptions

func WithTransportOptions(transportOptions *TransportOptions) HttpClientOption

WithTransportOptions configures a client to use the specified transport options.

type Logger

type Logger interface {
	Debug(format string, args ...any)
	Info(format string, args ...any)
	Warn(format string, args ...any)
	Error(format string, args ...any)
}

func NewDebugLogger

func NewDebugLogger(logger Logger) Logger

func NewLogger

func NewLogger() Logger

func NewNoopLogger

func NewNoopLogger() Logger

type PostResponseContext

type PostResponseContext struct {
	Request  *http.Request
	Response *http.Response
	Error    error // Non-nil if request failed
}

PostResponseContext contains response metadata for PostHook handlers.

type PostResponseHookFunc

type PostResponseHookFunc func(ctx *PostResponseContext) error

PostResponseHookFunc is called after each request completes. Return an error to abort subsequent hooks, or wrap ErrContinueHooks to log and continue.

type PreRequestHookFunc

type PreRequestHookFunc func(req *http.Request) error

PreRequestHookFunc is called before each request is sent. Return an error to abort the request, or wrap ErrContinueHooks to log and continue.

type ProxyDialerFactory

type ProxyDialerFactory func(proxyUrlStr string, timeout time.Duration, localAddr *net.TCPAddr, connectHeaders http.Header, logger Logger) (proxy.ContextDialer, error)

type TLSDialerFunc

type TLSDialerFunc func(ctx context.Context, network, addr string) (net.Conn, error)

TLSDialerFunc is a function that dials a TLS connection to the given address. It's used for WebSocket connections to ensure they use the same TLS fingerprinting as regular HTTP requests.

type TransportOptions

type TransportOptions struct {
	// KeyLogWriter is an io.Writer that the TLS client will use to write the
	// TLS master secrets to. This can be used to decrypt TLS connections in
	// Wireshark and other applications.
	KeyLogWriter io.Writer
	// IdleConnTimeout is the maximum amount of time an idle (keep-alive)
	// connection will remain idle before closing itself. Zero means no limit.
	IdleConnTimeout *time.Duration
	// RootCAs is the set of root certificate authorities used to verify
	// the remote server's certificate.
	RootCAs                *x509.CertPool
	Certificates           []tls.Certificate
	MaxIdleConns           int
	MaxIdleConnsPerHost    int
	MaxConnsPerHost        int
	MaxResponseHeaderBytes int64 // Zero means to use a default limit.
	WriteBufferSize        int   // If zero, a default (currently 4KB) is used.
	ReadBufferSize         int   // If zero, a default (currently 4KB) is used.
	DisableKeepAlives      bool
	DisableCompression     bool
}

type Websocket

type Websocket struct {
	// contains filtered or unexported fields
}

func NewWebsocket

func NewWebsocket(logger Logger, options ...WebsocketOption) (*Websocket, error)

NewWebsocket creates a new WebSocket wrapper that uses tls-client for connections. This allows WebSocket connections to use the same TLS fingerprinting and configuration as regular HTTP requests.

Example usage:

// Create HTTP client with ForceHttp1 (required for WebSocket!)
client, _ := NewHttpClient(nil,
    WithClientProfile(profiles.Chrome_150),
    WithForceHttp1(),
)

// Create WebSocket with optional header ordering
headers := http.Header{
    "User-Agent": {"MyBot/1.0"},
    http.HeaderOrderKey: {"host", "upgrade", "connection", "user-agent"},
}

ws, _ := New(nil,
    WithTlsClient(client),
    WithUrl("wss://example.com/ws"),
    WithHeaders(headers),
)

conn, _ := ws.Connect(context.Background())
defer conn.Close()

func (*Websocket) Connect

func (w *Websocket) Connect(ctx context.Context) (*websocket.Conn, error)

type WebsocketOption

type WebsocketOption func(config *websocketConfig)

func WithCookiejar

func WithCookiejar(cookiejar http.CookieJar) WebsocketOption

func WithHandshakeTimeoutMilliseconds

func WithHandshakeTimeoutMilliseconds(timeout int) WebsocketOption

func WithHeaders

func WithHeaders(headers http.Header) WebsocketOption

func WithReadBufferSize

func WithReadBufferSize(readBufferSize int) WebsocketOption

func WithTlsClient

func WithTlsClient(tlsClient HttpClient) WebsocketOption

WithTlsClient sets the tls-client HttpClient to use for the WebSocket connection. The underlying dialer from this client will be used to establish the connection, preserving TLS fingerprinting and other client configurations.

IMPORTANT: WebSocket connections require HTTP/1.1. When creating your HttpClient, you MUST use WithForceHttp1() option to ensure compatibility:

client, _ := NewHttpClient(nil,
    WithClientProfile(profiles.Chrome_150),
    WithForceHttp1(), // Required for WebSocket!
)

func WithUrl

func WithUrl(url string) WebsocketOption

func WithWriteBufferSize

func WithWriteBufferSize(writeBufferSize int) WebsocketOption

Directories

Path Synopsis
tls_client_cffi_src provides and manages a CFFI (C Foreign Function Interface) which allows code in other languages to interact with the module.
tls_client_cffi_src provides and manages a CFFI (C Foreign Function Interface) which allows code in other languages to interact with the module.
example
bandwidth command
Package main shows the bandwidth tracker: how many bytes the client read and wrote on the wire, measured on the connection rather than on the response body, so TLS and header overhead are included.
Package main shows the bandwidth tracker: how many bytes the client read and wrote on the wire, measured on the connection rather than on the response body, so TLS and header overhead are included.
basic command
Package main shows the smallest possible tls-client setup: create a client with a browser profile and perform a GET request.
Package main shows the smallest possible tls-client setup: create a client with a browser profile and perform a GET request.
certificate_pinning command
Package main shows certificate pinning: the request is rejected if the server does not present one of the configured public key hashes.
Package main shows certificate pinning: the request is rejected if the server does not present one of the configured public key hashes.
client_per_worker command
Package main is ./example/concurrency with one change: every worker builds its own tls-client instead of sharing one.
Package main is ./example/concurrency with one change: every worker builds its own tls-client instead of sharing one.
concurrency command
Package main shows one tls-client shared by many goroutines.
Package main shows one tls-client shared by many goroutines.
connection_reuse command
Package main verifies that a client reuses one TCP connection for subsequent requests to the same host, instead of dialing and handshaking again every time.
Package main verifies that a client reuses one TCP connection for subsequent requests to the same host, instead of dialing and handshaking again every time.
cookies command
Package main shows automatic cookie persistence via the cookie jar, plus reading and manually seeding cookies for a URL.
Package main shows automatic cookie persistence via the cookie jar, plus reading and manually seeding cookies for a URL.
custom_profile command
Package main shows how to build a client profile from a raw JA3 string instead of picking one of the bundled browser profiles.
Package main shows how to build a client profile from a raw JA3 string instead of picking one of the bundled browser profiles.
custom_spec command
Package main shows how to build a tls.ClientHelloSpec by hand instead of deriving it from a JA3 string.
Package main shows how to build a tls.ClientHelloSpec by hand instead of deriving it from a JA3 string.
decompress command
Package main shows manual response body decompression.
Package main shows manual response body decompression.
download command
Package main shows downloading a binary response (e.g.
Package main shows downloading a binary response (e.g.
headers command
Package main shows how to set custom request headers and control the exact order they are sent in.
Package main shows how to set custom request headers and control the exact order they are sent in.
hooks command
Package main shows pre-request and post-response hooks: one place to touch every request a client sends and every response it receives, without wrapping each call site.
Package main shows pre-request and post-response hooks: one place to touch every request a client sends and every response it receives, without wrapping each call site.
post command
Package main shows a POST request with a JSON body.
Package main shows a POST request with a JSON body.
protocol_racing command
Package main shows protocol racing: HTTP/3 (QUIC) and HTTP/2 (TCP) are started in parallel and whichever connects first serves the request, similar to Chrome's "Happy Eyeballs" approach.
Package main shows protocol racing: HTTP/3 (QUIC) and HTTP/2 (TCP) are started in parallel and whichever connects first serves the request, similar to Chrome's "Happy Eyeballs" approach.
proxy command
Package main shows how to route requests through a proxy and how to rotate to a different proxy on an existing client without rebuilding it.
Package main shows how to route requests through a proxy and how to rotate to a different proxy on an existing client without rebuilding it.
redirects command
Package main shows how to toggle automatic redirect following at runtime, without rebuilding the client.
Package main shows how to toggle automatic redirect following at runtime, without rebuilding the client.
session_tickets command
Package main shows how to turn off TLS session tickets.
Package main shows how to turn off TLS session tickets.
websocket command
Package main shows a WebSocket connection that reuses the TLS fingerprint of a tls-client.
Package main shows a WebSocket connection that reuses the TLS fingerprint of a tls-client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL