tlsclient

package module
v1.8.3 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 30 Imported by: 0

README ΒΆ

TLS Client

Go Reference

A powerful Go HTTP client library that provides advanced TLS fingerprinting capabilities, allowing you to emulate various browsers and devices for web scraping, testing, and automation tasks.

Features

  • 🌐 Browser Emulation: Mimic TLS fingerprints of Chrome, Safari, OkHttp4, and HttpUrlConnection
  • πŸš€ HTTP Protocol Support: HTTP/1.1, HTTP/2, and HTTP/3
  • πŸ—œοΈ Automatic Decompression: Built-in support for gzip, brotli, zstd, and deflate
  • πŸͺ Hooks: Pre-request and post-request hooks for request/response manipulation
  • πŸ“Š Bandwidth Tracking: Monitor network usage and performance
  • 🎯 Certificate Pinning: Enhanced security with certificate validation
  • 🌍 Proxy Support: HTTP, HTTPS, and SOCKS proxy support
  • ⚑ High Performance: Optimized for speed and efficiency

Installation

go get github.com/nukilabs/tlsclient

Quick Start

package main

import (
    "fmt"
    "io"
    "log"
    "net/url"

    "github.com/nukilabs/http"
    "github.com/nukilabs/tlsclient"
    "github.com/nukilabs/tlsclient/profiles"
)

func main() {
    // Create a new client with Chrome profile
    client := tlsclient.New(profiles.Chrome138)
    client.SetProxy(&url.URL{
        Scheme: "http",
        Host:   "localhost:8888",
    })
    
    // Make a GET request
    req, err := client.NewRequest(http.MethodGet, "https://example.com", nil)
    if err != nil {
        log.Fatal(err)
    }

    // Add chrome-like headers
    req.Header = http.Header{
		"sec-ch-ua":                 {"\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\""},
		"sec-ch-ua-mobile":          {"?0"},
		"sec-ch-ua-platform":        {"\"Windows\""},
		"upgrade-insecure-requests": {"1"},
		"user-agent":                {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"},
		"accept":                    {"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"},
		"sec-fetch-site":            {"none"},
		"sec-fetch-mode":            {"navigate"},
		"sec-fetch-user":            {"?1"},
		"sec-fetch-dest":            {"document"},
		"accept-encoding":           {"gzip, deflate, br, zstd"},
		"accept-language":           {"de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"},
		"priority":                  {"u=0, i"},
		http.HeaderOrderKey:         {"sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "upgrade-insecure-requests", "user-agent", "accept", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-user", "sec-fetch-dest", "accept-encoding", "accept-language", "priority"},
	}

    // Perform the request
    res, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    
    // Read and print the response
    body, err := io.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(string(body))
}

Available Profiles

Chrome Browsers
// Chrome versions 120-138
client := tlsclient.New(profiles.Chrome138)  // Latest Chrome
client := tlsclient.New(profiles.Chrome120)  // Older Chrome version
Safari Browsers
// Safari 17
client := tlsclient.New(profiles.Safari17)
Android HttpUrlConnection
// Android API levels 21-35
client := tlsclient.New(profiles.HttpUrlConnectionAndroid(33))  // Android 13
client := tlsclient.New(profiles.HttpUrlConnectionAndroid(21))  // Android 5.0
Android OkHttp4
// Android API levels 21-35
client := tlsclient.New(profiles.Okhttp4Android(33))  // Android 13
client := tlsclient.New(profiles.Okhttp4Android(29))  // Android 10

Configuration Options

Basic Options
client := tlsclient.New(profiles.Chrome138,
    tlsclient.WithTimeout(30*time.Second),  // Set request timeout
    tlsclient.WithNoCookieJar(),            // Disable cookie jar
    tlsclient.WithNoAutoDecompress(),       // Disable automatic decompression
    tlsclient.WithNoFollowRedirects(),      // Disable automatic redirects
)
Advanced Transport Options
client := tlsclient.New(profiles.Chrome138,
    tlsclient.WithTransportOptions(tlsclient.TransportOptions{
        ServerNameOverride: "example.com",
        InsecureSkipVerify: true,
        DisableKeepAlives:  false,
        IdleConnTimeout:    90 * time.Second,
        DisableIPV4:        false,
        DisableIPV6:        false,
    }),
)
Certificate Pinning
client := tlsclient.New(profiles.Chrome138,
    tlsclient.WithAutoPinning(),
)

Redirect Handling

Disable Redirects
client.SetFollowRedirects(false)
Custom Redirect Policy
client.SetRedirectFunc(func(req *http.Request, via []*http.Request) error {
    // Maximum of 5 redirects
    if len(via) >= 5 {
        return errors.New("too many redirects")
    }
    
    // Don't follow redirects to different hosts
    if req.URL.Host != via[0].URL.Host {
        return errors.New("cross-host redirect not allowed")
    }
    
    return nil
})

Proxy Support

// HTTP Proxy
client.SetProxy(&url.URL{
    Scheme: "http",
    Host:   "proxy.example.com:8080",
})

// SOCKS5 Proxy
client.SetProxy(&url.URL{
    Scheme: "socks5",
    Host:   "proxy.example.com:1080",
})

// Authenticated Proxy
client.SetProxy(&url.URL{
    Scheme: "http",
    Host:   "proxy.example.com:8080",
    User:   url.UserPassword("username", "password"),
})

Hooks

Pre-Request Hooks

Pre-hooks run before each request and can modify the request before it is sent.

func AddAuthHeader(client *tlsclient.Client, req *http.Request) (*http.Request, error) {
    req.Header.Set("Authorization", "Bearer my-token")
    return req, nil
}

client.AddPreHooks(AddAuthHeader)
Post-Request Hooks

Post-hooks run after each request and can inspect or modify the response.

func GotBlockedHook(client *tlsclient.Client, req *http.Request, res *http.Response) (*http.Response, error) {
    if res.StatusCode == http.StatusTooManyRequests {
        // Switch to a different proxy if blocked
        client.SetProxy(&url.URL{
            Scheme: "http",
            Host:   "localhost:8889",
        })
    }
    return res, nil
}

client.AddPostHooks(GotBlockedHook)
Managing Hooks
// Set hooks (replaces any existing hooks)
client.SetPreHooks(hook1, hook2)
client.SetPostHooks(hook1, hook2)

// Add hooks (appends to existing hooks)
client.AddPreHooks(hook3)
client.AddPostHooks(hook3)

// Delete all hooks
client.DeletePreHooks()
client.DeletePostHooks()

Best Practices

Connection Reuse
// Reuse the same client for multiple requests
client := tlsclient.New(profiles.Chrome138)

// Make multiple requests with the same client
for _, url := range urls {
    res, err := client.Get(url)
    if err != nil {
        continue
    }
    // Process response...
    res.Body.Close()
}
Resource Management
res, err := client.Get("https://example.com")
if err != nil {
    return err
}
defer res.Body.Close() // Always close response body

// Read response body
body, err := io.ReadAll(res.Body)
if err != nil {
    return err
}

Contributing

We welcome contributions from the community! This TLS Client is constantly evolving, and we'd love your help in making it even better. Here are some ways you can contribute:

🌐 TLS Profiles

We're always looking to expand our browser and device emulation capabilities. If you have access to a browser, device, or HTTP client that isn't currently supported, we'd love to add it!

How to contribute a new TLS profile:

  1. Capture the TLS fingerprint using tools like:

  2. Create the profile by adding it to the appropriate file in /profiles/:

    // profiles/newbrowser.go
    var NewBrowser = ClientProfile{
        ClientHelloSpec: func() *tls.ClientHelloSpec {
            return &tls.ClientHelloSpec{
                CipherSuites: []uint16{
                    // Your cipher suites here
                },
                Extensions: []tls.TLSExtension{
                    // Your extensions here
                },
                // ... other TLS parameters
            }
        },
        Settings: []http2.Setting{
            // HTTP/2 settings
        },
        // ... other profile parameters
    }
    
  3. Add tests in /tests/ to verify the profile works correctly

  4. Update documentation to include the new profile in the README

Browsers/Clients we'd love to see:

  • Firefox (all versions)
  • Edge (Chromium-based)
  • Opera
  • Brave
  • Mobile browsers (iOS Safari, Chrome Mobile, Samsung Internet)
  • HTTP clients (curl, wget, Python requests, etc.)

We appreciate all contributions, no matter how small! πŸ™

Acknowledgments


Β© 2025 nukilabs

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var ErrCertificatePinningFailed = errors.New("tlsclient: certificate pinning failed")

Functions ΒΆ

func DecompressBody ΒΆ

func DecompressBody(res *http.Response)

Types ΒΆ

type Client ΒΆ

type Client struct {
	http.Client

	AutoDecompress bool
	// contains filtered or unexported fields
}

func New ΒΆ

func New(profile profiles.ClientProfile, options ...Option) *Client

func (*Client) AddPostHooks ΒΆ added in v1.7.1

func (c *Client) AddPostHooks(hooks ...PostHook)

func (*Client) AddPreHooks ΒΆ added in v1.7.1

func (c *Client) AddPreHooks(hooks ...PreHook)

func (*Client) Clone ΒΆ added in v1.6.3

func (c *Client) Clone() *Client

func (*Client) CloseIdleConnections ΒΆ

func (c *Client) CloseIdleConnections()

func (*Client) DeletePostHooks ΒΆ added in v1.7.1

func (c *Client) DeletePostHooks()

func (*Client) DeletePreHooks ΒΆ added in v1.7.1

func (c *Client) DeletePreHooks()

func (*Client) Do ΒΆ

func (c *Client) Do(req *http.Request) (*http.Response, error)

func (*Client) Get ΒΆ

func (c *Client) Get(url string) (*http.Response, error)

func (*Client) GetCookieJar ΒΆ

func (c *Client) GetCookieJar() http.CookieJar

func (*Client) GetCookies ΒΆ

func (c *Client) GetCookies(u *url.URL) []*http.Cookie

func (*Client) GetProxy ΒΆ

func (c *Client) GetProxy() any

GetProxy returns the current proxy value. The type depends on what was passed to SetProxy: *url.URL for proxy URLs, net.IP for single direct IPs, or [2]net.IP for dual-stack.

func (*Client) GetSiteCookies ΒΆ added in v1.8.3

func (c *Client) GetSiteCookies(u *url.URL) []*http.Cookie

func (*Client) Head ΒΆ

func (c *Client) Head(url string) (*http.Response, error)

func (*Client) IsInHook ΒΆ added in v1.8.2

func (c *Client) IsInHook() bool

func (*Client) Post ΒΆ

func (c *Client) Post(url, contentType string, body io.Reader) (*http.Response, error)

func (*Client) PostForm ΒΆ

func (c *Client) PostForm(url string, data url.Values) (*http.Response, error)

func (*Client) ResetInHook ΒΆ

func (c *Client) ResetInHook()

func (*Client) SetCookieJar ΒΆ

func (c *Client) SetCookieJar(jar http.CookieJar)

func (*Client) SetCookies ΒΆ

func (c *Client) SetCookies(u *url.URL, cookies []*http.Cookie)

func (*Client) SetFollowRedirects ΒΆ

func (c *Client) SetFollowRedirects(follow bool)

func (*Client) SetInHook ΒΆ added in v1.8.2

func (c *Client) SetInHook(b bool)

func (*Client) SetPostHooks ΒΆ added in v1.7.1

func (c *Client) SetPostHooks(hooks ...PostHook)

func (*Client) SetPreHooks ΒΆ added in v1.7.1

func (c *Client) SetPreHooks(hooks ...PreHook)

func (*Client) SetProxy ΒΆ

func (c *Client) SetProxy(v any) error

SetProxy configures the proxy/dialer for the client. Accepted types:

  • *url.URL: proxy URL (http, https, socks5) or bare IP (no scheme) for direct binding
  • net.IP: direct connection bound to a single local IP
  • [2]net.IP: dual-stack direct connection bound to IPv4 ([0]) and IPv6 ([1])
  • nil: direct connection with no local address binding

func (*Client) SetRedirectFunc ΒΆ

func (c *Client) SetRedirectFunc(f func(req *http.Request, via []*http.Request) error)

type Option ΒΆ

type Option func(*Client)

func WithAutoPinning ΒΆ

func WithAutoPinning() Option

func WithCookieJar ΒΆ added in v1.8.2

func WithCookieJar(jar http.CookieJar) Option

func WithNoAutoDecompress ΒΆ

func WithNoAutoDecompress() Option

func WithNoCookieJar ΒΆ

func WithNoCookieJar() Option

func WithNoFollowRedirects ΒΆ

func WithNoFollowRedirects() Option

func WithPinner ΒΆ added in v1.6.3

func WithPinner(pinner *Pinner) Option

func WithQUICConfig ΒΆ added in v1.5.2

func WithQUICConfig(quicConf *quic.Config) Option

func WithTLSConfig ΒΆ added in v1.5.2

func WithTLSConfig(tlsConf *tls.Config) Option

func WithTimeout ΒΆ

func WithTimeout(timeout time.Duration) Option

func WithTracker ΒΆ

func WithTracker(tracker bandwidth.Tracker) Option

func WithTransportOptions ΒΆ

func WithTransportOptions(opts TransportOptions) Option

type Pinner ΒΆ

type Pinner struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewPinner ΒΆ

func NewPinner(auto bool) *Pinner

func (*Pinner) AddPins ΒΆ

func (p *Pinner) AddPins(hostname string, pins []string)

func (*Pinner) AutoPin ΒΆ

func (p *Pinner) AutoPin(addr string)

func (*Pinner) Fingerprint ΒΆ

func (p *Pinner) Fingerprint(cert *x509.Certificate) string

func (*Pinner) Pin ΒΆ

func (p *Pinner) Pin(certs []*x509.Certificate, addr string) error

type PostHook ΒΆ added in v1.7.1

type PostHook func(*Client, *http.Request, *http.Response) (*http.Response, error)

type PreHook ΒΆ added in v1.7.1

type PreHook func(*Client, *http.Request) (*http.Request, error)

type ProxyError ΒΆ

type ProxyError struct {
	Message string
}

func (ProxyError) Error ΒΆ

func (e ProxyError) Error() string

type RoundTripper ΒΆ

type RoundTripper struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewRoundTripper ΒΆ

func NewRoundTripper(profile profiles.ClientProfile, dialer proxy.ContextDialer, pinner *Pinner, tracker bandwidth.Tracker, tlsConf *tls.Config, quicConf *quic.Config, opts *TransportOptions) *RoundTripper

func (*RoundTripper) CloseIdleConnections ΒΆ added in v1.5.2

func (rt *RoundTripper) CloseIdleConnections()

func (*RoundTripper) RoundTrip ΒΆ

func (rt *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

type TransportOptions ΒΆ

type TransportOptions struct {
	DisableKeepAlives bool
	IdleConnTimeout   time.Duration
	DisableIPV4       bool
	DisableIPV6       bool
	DisableHTTP3      bool
}

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

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