Make your first request
This guide will walk you through installing TLS Client and making your first HTTP request with TLS fingerprinting.
Install TLS Client
Add TLS Client to your Go project:go get github.com/bogdanfinn/tls-client
This will also install the required dependencies:
github.com/bogdanfinn/fhttp - Fork of net/http with TLS fingerprinting support
github.com/bogdanfinn/utls - TLS library for client fingerprinting
Create a basic client
Create a new file main.go with the following code:package main
import (
"fmt"
"io"
"log"
http "github.com/bogdanfinn/fhttp"
tls_client "github.com/bogdanfinn/tls-client"
"github.com/bogdanfinn/tls-client/profiles"
)
func main() {
// Create a cookie jar for automatic cookie handling
jar := tls_client.NewCookieJar()
// Configure client options
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_144),
tls_client.WithCookieJar(jar),
}
// Create the client
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
if err != nil {
log.Fatal(err)
}
// Make a request
resp, err := client.Get("https://tls.peet.ws/api/all")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Read the response
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Status: %d\n%s\n", resp.StatusCode, body)
}
We’re using profiles.Chrome_144 to mimic Chrome 144’s TLS fingerprint. See Browser Profiles for all available profiles. Run your code
Run your program:You should see a successful response with status 200 and JSON output containing your TLS fingerprint details.
Make a POST request
Here’s how to make a POST request with custom headers:
package main
import (
"log"
"net/url"
"strings"
http "github.com/bogdanfinn/fhttp"
tls_client "github.com/bogdanfinn/tls-client"
"github.com/bogdanfinn/tls-client/profiles"
)
func main() {
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_144),
}
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
if err != nil {
log.Fatal(err)
}
// Prepare form data
postData := url.Values{}
postData.Add("username", "john")
postData.Add("password", "secret123")
// Create request
req, err := http.NewRequest(
http.MethodPost,
"https://example.com/api/login",
strings.NewReader(postData.Encode()),
)
if err != nil {
log.Fatal(err)
}
// Set headers with custom order
req.Header = http.Header{
"content-type": {"application/x-www-form-urlencoded"},
"accept": {"application/json"},
"accept-language": {"en-US,en;q=0.9"},
"user-agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"},
http.HeaderOrderKey: {
"content-type",
"accept",
"accept-language",
"user-agent",
},
}
// Execute request
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
log.Printf("Status: %d", resp.StatusCode)
}
Header names in HeaderOrderKey must be lowercase. TLS Client will automatically convert them to ensure proper ordering.
Use with proxies
TLS Client supports HTTP and SOCKS5 proxies:
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_144),
tls_client.WithProxyUrl("http://user:[email protected]:8080"),
}
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
You can also change the proxy at runtime:
err := client.SetProxy("http://user:[email protected]:8080")
if err != nil {
log.Fatal(err)
}
Control redirects
By default, TLS Client follows redirects automatically. You can disable this:
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_144),
tls_client.WithNotFollowRedirects(),
}
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
Or toggle it at runtime:
// Disable redirect following
client.SetFollowRedirect(false)
// Re-enable it
client.SetFollowRedirect(true)
Enable debug logging
For debugging, you can enable detailed logging:
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_144),
tls_client.WithDebug(),
}
client, err := tls_client.NewHttpClient(tls_client.NewLogger(), options...)
This will log:
- Request and response headers
- Cookie operations
- Raw bytes sent and received over the wire
- TLS handshake details
Manage cookies
TLS Client includes built-in cookie jar support:
package main
import (
"fmt"
"log"
"net/url"
tls_client "github.com/bogdanfinn/tls-client"
"github.com/bogdanfinn/tls-client/profiles"
)
func main() {
jar := tls_client.NewCookieJar()
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_144),
tls_client.WithCookieJar(jar),
}
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
if err != nil {
log.Fatal(err)
}
// Make a request - cookies are automatically stored
resp, err := client.Get("https://example.com")
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
// Get cookies for a URL
u, _ := url.Parse("https://example.com")
cookies := client.GetCookies(u)
fmt.Printf("Cookies: %v\n", cookies)
}
Next steps
Configuration
Learn about all available client options and how to configure them.
Browser profiles
Explore all available browser profiles and create custom ones.
Advanced usage
Certificate pinning, bandwidth tracking, WebSockets, and more.
Language bindings
Use TLS Client from Node.js, Python, or C# via FFI.