Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
f2deda3
add HTTP3 (QUIC) support (#189)
Dharmey747 Jul 18, 2025
c162eeb
added h3 to chrome_133 psk;
bogdanfinn Jul 18, 2025
a2ba361
updated shared library;
bogdanfinn Jul 18, 2025
4f69240
added go 1.24 Dockerfiles;
bogdanfinn Jul 18, 2025
974499a
added tests for content-length header order
bogdanfinn Jul 31, 2025
ee133aa
updated readme;
bogdanfinn Sep 8, 2025
9776609
added option to disable http3;
bogdanfinn Sep 11, 2025
e676315
switched quic-go-utls fork from dharmey to own; (#195)
bogdanfinn Sep 11, 2025
438e771
updated shared library;
bogdanfinn Sep 11, 2025
b657590
added possibility to disable http3 to shared library;
bogdanfinn Sep 11, 2025
620da66
updated shared library;
bogdanfinn Sep 11, 2025
c102fc0
updated readme;
bogdanfinn Sep 17, 2025
06f597e
refs #196: implemented support for socks4 proxies;
bogdanfinn Sep 21, 2025
01d4bf7
Add 'keep_compressed' test (#201)
ypapouski Nov 3, 2025
f7d4154
updated dependencies;
bogdanfinn Nov 3, 2025
96ae9bb
fixed failing test;
bogdanfinn Dec 25, 2025
3651406
updated dependencies to use latest quic-go-utls
bogdanfinn Dec 25, 2025
71e7aa4
Breaking Change: changed default cookiejar in shared library to be fh…
bogdanfinn Dec 25, 2025
1223f68
updated shared library;
bogdanfinn Dec 25, 2025
dab03ee
fixes #191: fixed correct usage of PSK (41) extension in chrome_133;
bogdanfinn Jan 9, 2026
8eb3c52
Add AllowHTTP, set StreamID value (#205)
gunir Jan 10, 2026
5f8f259
Updated utls and fhttp for fixing #194;
bogdanfinn Jan 10, 2026
af6c630
implemented chromes happy eyeballs approach to determine which protoc…
bogdanfinn Jan 10, 2026
264f9a9
updated shared library;
bogdanfinn Jan 10, 2026
6680ed3
fixed shared library code;
bogdanfinn Jan 10, 2026
9e9faaf
updated shared library;
bogdanfinn Jan 10, 2026
32bdb7e
refs #95: implemented websocket support; (#208)
bogdanfinn Jan 11, 2026
e129d5a
fixed name of factory method for websockets;
bogdanfinn Jan 11, 2026
6377e97
Update contributed_browser_profiles.go - Add Firefox 146, 147 (#209)
gunir Jan 16, 2026
514815f
Add EUC-KR encoding for Korean (#207)
ahnse0 Jan 16, 2026
41acb74
added chrome 144, chrome 144 with PSK, firefox 147 without psk browse…
bogdanfinn Jan 16, 2026
2d4093b
fixes #210: allow WithServerNameOverwrite without WithInsecureSkipVer…
bogdanfinn Jan 16, 2026
145b2fd
updated fhttp dependency;
bogdanfinn Jan 21, 2026
9046b9d
feat: HTTP/3 fingerprinting for Chrome 144 and Firefox 147 (#215)
bogdanfinn Jan 26, 2026
635d5fa
Add Safari iOS 26.0, Chrome 146, Chrome 146 PSK, tests (#214)
nihiloid Jan 26, 2026
b516129
[Bug]: ipv6 url error (#212)
zephyr-profile Jan 26, 2026
f85e5c2
fixed websocket connection; (#216)
bogdanfinn Jan 26, 2026
3a1dc16
updated dependencies;
bogdanfinn Feb 3, 2026
725955a
print detected pins in error message in case of "bad ssl pin detected…
AndreaVitale Feb 3, 2026
f4a46b2
updated shared library;
bogdanfinn Feb 4, 2026
a3537d6
Add WithDialContext option for custom socket and DNS management (re-a…
gunir Feb 6, 2026
7250494
feat: prerequest hooks n postrequest hooks (#220)
combo23 Feb 6, 2026
07c8679
Fix client_options.go syntax error (#222)
patyhank Feb 9, 2026
85fb1b0
merge upstream
dgtlctzn Feb 11, 2026
7e840f7
change go version
dgtlctzn Feb 11, 2026
38d249c
update circle go orb
dgtlctzn Feb 11, 2026
517da9a
modify config
dgtlctzn Feb 11, 2026
f081b53
omit nil check for maps (#224)
aarock1234 Feb 13, 2026
674eaed
Automatic Charset Detection of Response Body (#227)
DemBackfisch Feb 26, 2026
3807c96
fix: header order for websockets (#230)
combo23 Mar 3, 2026
01df2cc
add new tls binary
dgtlctzn Mar 5, 2026
343147a
add linux binary
dgtlctzn Mar 6, 2026
3fa74c6
empty commit
dgtlctzn Mar 9, 2026
148c5d6
Merge remote-tracking branch 'upstream/master' into feat/update-tls-w…
dgtlctzn Mar 9, 2026
e180a8d
increase timeout
dgtlctzn Mar 9, 2026
a827f40
increase timeout
dgtlctzn Mar 9, 2026
b968159
remove race
dgtlctzn Mar 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ parameters:
orbs:
pinwheel-cicd: underdog-tech/pinwheel-cicd-orb@1.4
macos: circleci/macos@2.4.0
go: circleci/go@1.7.3
go: circleci/go@3.0.3
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests were failing until updating go and the circle go orb. Required slightly different syntax below.


jobs:
test:
Expand All @@ -17,14 +17,13 @@ jobs:
working_directory: ~/<< pipeline.parameters.service-name >>
steps:
- checkout
- go/install:
version: "1.22.0"
- go/load-cache
- go/mod-download
- go/save-cache
- go/test:
race: true
covermode: "atomic"
- go/with-cache:
steps:
- go/install:
version: "1.24.1"
- go/mod-download
- go/test:
covermode: atomic

workflows:
test:
Expand Down
Binary file added .github/assets/hypersolutions.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ cffi_dist/example_node/index_ftl_cookies.js
cffi_dist/example_node/index_nike_cookies.js
cffi_dist/example_node/node_modules
**/.DS_Store
.tool-versions
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
nodejs 20.9.0
golang 1.24.1
golang 1.24.1
53 changes: 45 additions & 8 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,24 @@ With this library you are able to create a http client implementing an interface
client interface.
This TLS Client allows you to specify the Client (Browser and Version) you want to use, when requesting a server.

The Interface of the HTTP Client looks like the following and extends the base net/http Client Interface by some useful functions.
Most likely you will use the `Do()` function like you did before with net/http Client.
### Features

- ✅ **HTTP/1.1, HTTP/2, HTTP/3** - Full protocol support with automatic negotiation
- ✅ **Protocol Racing** - Chrome-like "Happy Eyeballs" for HTTP/2 vs HTTP/3
- ✅ **TLS Fingerprinting** - Mimic Chrome, Firefox, Safari, and other browsers
- ✅ **HTTP/3 Fingerprinting** - Accurate QUIC/HTTP/3 fingerprints matching real browsers
- ✅ **WebSocket Support** - Maintain TLS fingerprinting over WebSocket connections
- ✅ **Custom Header Ordering** - Control the order of HTTP headers
- ✅ **Proxy Support** - HTTP and SOCKS5 proxies
- ✅ **Cookie Jar Management** - Built-in cookie handling
- ✅ **Certificate Pinning** - Enhanced security with custom certificate validation
- ✅ **Bandwidth Tracking** - Monitor upload/download bandwidth
- ✅ **Language Bindings** - Use from JavaScript (Node.js), Python, and C# via FFI

### Interface

The HTTP Client interface extends the base net/http Client with additional functionality:

```go
type HttpClient interface {
GetCookies(u *url.URL) []*http.Cookie
Expand All @@ -38,9 +54,16 @@ type HttpClient interface {
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
}
```

### Detailed Documentation

https://bogdanfinn.gitbook.io/open-source-oasis/

### Quick Usage Example

Expand All @@ -58,10 +81,10 @@ import (
)

func main() {
jar := tls_client.NewCookieJar()
jar := tls_client.NewCookieJar()
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(profiles.Chrome_120),
tls_client.WithClientProfile(profiles.Chrome_144),
tls_client.WithNotFollowRedirects(),
tls_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument
}
Expand Down Expand Up @@ -109,10 +132,6 @@ func main() {
}
```

### Detailed Documentation

https://bogdanfinn.gitbook.io/open-source-oasis/

### Questions?

Join my discord support server for free: https://discord.gg/7Ej9eJvHqk
Expand All @@ -123,3 +142,21 @@ No Support in DMs!

[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/CaptainBarnius)

---

## 🛡️ Need Antibot Bypass?

<a href="https://hypersolutions.co/?utm_source=github&utm_medium=readme&utm_campaign=tls-client" target="_blank"><img src="https://raw.githubusercontent.com/bogdanfinn/tls-client/master/.github/assets/hypersolutions.jpg" height="47" width="149"></a>

TLS fingerprinting alone isn't enough for modern bot protection. **[Hyper Solutions](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=tls-client)** provides the missing piece - API endpoints that generate valid antibot tokens for:

**Akamai** • **DataDome** • **Kasada** • **Incapsula**

No browser automation. Just simple API calls that return the exact cookies and headers these systems require.

🚀 **[Get Your API Key](https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=tls-client)** | 📖 **[Docs](https://docs.justhyped.dev)** | 💬 **[Discord](https://discord.gg/akamai)**

---

### Powered by
[![JetBrains logo.](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg)](https://jb.gg/OpenSource)
2 changes: 1 addition & 1 deletion cffi_dist/.tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
nodejs 20.10.0
golang 1.20
golang 1.24.1
2 changes: 1 addition & 1 deletion cffi_dist/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ RUN apt-get update -y -q && apt-get upgrade -y -q
RUN apt-get install --no-install-recommends -y -q curl build-essential ca-certificates git gcc g++ bash

# Download Go 1.22 and install it to /usr/local/go
RUN curl -s https://dl.google.com/go/go1.22.3.linux-amd64.tar.gz | tar -v -C /usr/local -xz
RUN curl -s https://dl.google.com/go/go1.24.1.linux-amd64.tar.gz | tar -v -C /usr/local -xz

# Let's people find our Go binaries
ENV PATH $PATH:/usr/local/go/bin
2 changes: 1 addition & 1 deletion cffi_dist/Dockerfile.alpine.compile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.22-alpine3.20
FROM golang:1.24.1-alpine3.21
RUN apk add --no-cache \
git \
gcc \
Expand Down
10 changes: 5 additions & 5 deletions cffi_dist/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ GOOS=darwin CGO_ENABLED=1 GOARCH=amd64 go build -buildmode=c-shared -o ./pinwhee
# # CC is needed when you cross compile from OSX to Linux
# GOOS=linux CGO_ENABLED=1 GOARCH=arm CC="armv7-linux-gnueabihf-gcc" go build -buildmode=c-shared -o ./dist/tls-client-linux-armv7-$1.so

# # CC is needed when you cross compile from OSX to Linux
# CC is needed when you cross compile from OSX to Linux
# echo 'Build Linux Alpine'
# # For some reason my OSX gcc cross compiler does not work. Therefore i use a alpine docker image
# # GOOS=linux CGO_ENABLED=1 GOARCH=amd64 CC="x86_64-linux-musl-gcc" go build -buildmode=c-shared -o ./dist/tls-client-linux-amd64.so
# # Make sure to first build the image based on the Dockerfile.alpine.compile in this directory.
# docker run -v $PWD/../:/tls-client tls-client-alpine-go-1.20 bash -c "cd /tls-client/cffi_dist && GOOS=linux CGO_ENABLED=1 GOARCH=amd64 go build -buildmode=c-shared -o /tls-client/cffi_dist/dist/tls-client-linux-alpine-amd64-$1.so"
# For some reason my OSX gcc cross compiler does not work. Therefore i use a alpine docker image
# GOOS=linux CGO_ENABLED=1 GOARCH=amd64 CC="x86_64-linux-musl-gcc" go build -buildmode=c-shared -o ./dist/tls-client-linux-amd64.so
# Make sure to first build the image based on the Dockerfile.alpine.compile in this directory.
# docker run -v $PWD/../:/tls-client tls-client-alpine-go-1.20 bash -c "cd /tls-client/cffi_dist && GOOS=linux CGO_ENABLED=1 GOARCH=amd64 go build -buildmode=c-shared -buildvcs=false -o /tls-client/cffi_dist/dist/tls-client-linux-alpine-amd64-$1.so"

# CC is needed when you cross compile from OSX to Linux
echo 'Build Linux Ubuntu'
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_csharp/Requester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class RequestPayload
public bool FollowRedirects { get; set; } = true;
public bool InsecureSkipVerify { get; set; } = false;
public bool WithoutCookieJar { get; set; } = false;
public bool WithDefaultCookieJar { get; set; } = false;
public bool WithCustomCookieJar { get; set; } = false;
public bool IsByteRequest { get; set; } = false;
public bool ForceHttp1 { get; set; } = false;
public bool WithDebug { get; set; } = false;
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const requestPayload = {
"followRedirects": true,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"isByteRequest": false,
"catchPanics": false,
"withDebug": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_async.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const requestPayload = {
"followRedirects": false,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"isByteRequest": false,
"forceHttp1": false,
"withRandomTLSExtensionOrder": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_cookies.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const requestPayload = {
"followRedirects": true,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"isByteRequest": false,
"catchPanics": false,
"withDebug": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_custom_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const requestPayload = {
"followRedirects": false,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"isByteRequest": false,
"catchPanics": false,
"forceHttp1": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_ffi_rs.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const requestPayload = {
"followRedirects": true,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"isByteRequest": false,
"catchPanics": false,
"withDebug": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_image.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const requestPayload = {
"followRedirects": false,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"forceHttp1": false,
"withDebug": false,
"withRandomTLSExtensionOrder": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_image_upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const requestPayload = {
"followRedirects": false,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"forceHttp1": false,
"withDebug": false,
"withRandomTLSExtensionOrder": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_node/index_post.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const requestPayload = {
"followRedirects": false,
"insecureSkipVerify": false,
"withoutCookieJar": false,
"withDefaultCookieJar": false,
"withCustomCookieJar": false,
"forceHttp1": false,
"withDebug": false,
"withRandomTLSExtensionOrder": false,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_python/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"withCustomCookieJar": False,
"isByteRequest": False,
"forceHttp1": False,
"withDebug": False,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_python/example_cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"withCustomCookieJar": False,
"isByteRequest": False,
"forceHttp1": False,
"withDebug": False,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_python/example_custom_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"withCustomCookieJar": False,
"isByteRequest": False,
"forceHttp1": False,
"catchPanics": False,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_python/example_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"withCustomCookieJar": False,
"isByteRequest": False,
"forceHttp1": False,
"withDebug": False,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_python/example_image_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"withCustomCookieJar": False,
"isByteRequest": True,
"forceHttp1": False,
"withDebug": False,
Expand Down
2 changes: 1 addition & 1 deletion cffi_dist/example_python/example_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"withCustomCookieJar": False,
"forceHttp1": False,
"withDebug": False,
"withRandomTLSExtensionOrder": False,
Expand Down
6 changes: 3 additions & 3 deletions cffi_dist/example_typescript/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ export class TLSClient implements TLSClientInstance {
const createWrapper = (): LibraryObject<never> => {
const sharedLibraryPath = join(__dirname, './../../dist/');
const sharedLibraryFilename = platform() === 'win32'
? `tls-client-windows-64-1.7.2.dll`
? `tls-client-windows-64-1.12.1.dll`
: arch() === 'arm64'
? `tls-client-darwin-arm64-1.7.2.dylib`
: `tls-client-darwin-amd64-1.7.2.dylib`;
? `tls-client-darwin-arm64-1.12.1.dylib`
: `tls-client-darwin-amd64-1.12.1.dylib`;

return Library(join(sharedLibraryPath, sharedLibraryFilename), {
request: ['string', ['string']],
Expand Down
24 changes: 14 additions & 10 deletions cffi_dist/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@ module tls_client_cffi
go 1.24.1

require (
github.com/bogdanfinn/fhttp v0.6.0
github.com/bogdanfinn/tls-client v1.10.0
github.com/bogdanfinn/fhttp v0.6.8
github.com/bogdanfinn/tls-client v1.14.0
github.com/google/uuid v1.6.0
)

require (
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/bogdanfinn/utls v1.7.3-barnius // indirect
github.com/cloudflare/circl v1.5.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/bdandy/go-errors v1.2.2 // indirect
github.com/bdandy/go-socks4 v1.2.3 // indirect
github.com/bogdanfinn/quic-go-utls v1.0.9-utls // indirect
github.com/bogdanfinn/utls v1.7.7-barnius // indirect
github.com/bogdanfinn/websocket v1.5.5-barnius // indirect
github.com/klauspost/compress v1.18.2 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
)

// replace github.com/bogdanfinn/tls-client => ../
Loading
Loading