Skip to content

Releases: North-web-dev/impersonate-http

v0.6.0 — verified Akamai HTTP/2 fingerprint parity

Choose a tag to compare

@North-web-dev North-web-dev released this 25 Oct 18:27

HTTP/2 (Akamai) fingerprint: verified, byte-level

The frame-level HTTP/2 client (introduced in v0.2.0) drives the connection over uTLS with http2.Framer + hpack, emitting the browser's SETTINGS, connection WINDOW_UPDATE and pseudo-header order instead of Go's net/http2 defaults. This release makes that parity verifiable and honest.

Added

  • Byte-level unit tests (http2_wire_test.go) — assert the exact preface + SETTINGS + WINDOW_UPDATE bytes the client writes (an independent hand-rolled byte reference plus a fully literal Chrome expectation), and that HEADERS carries each profile's four pseudo-headers in order followed by the regular headers in HeaderOrder. No network needed.
  • cmd/measure is now reflector-configurable — -url flag / REFLECTOR_URL env; tolerates reflectors that expose the Akamai string at the top level. Added chrome_android.

Verified (real measurements)

Measured against two independent reflectors — tls.peet.ws and fp.shshbshsnang.shop — which agree per profile:

Profile Emitted Akamai h2 Match
chrome / edge / chrome_android 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p ✅ byte-exact (canonical Chromium)
firefox 1:65536;4:131072;5:16384|12517377|0|m,p,a,s ✅ byte-exact
safari 3:100;4:4194304|10420225|0|m,s,p,a ✅ values & pseudo-order; see caveat
ios 3:100;4:2097152|10420225|0|m,s,p,a ✅ values & pseudo-order; see caveat

Honest caveat: Safari/iOS SETTINGS values and pseudo-order are correct for WebKit, but public fingerprint DBs disagree on SETTINGS ordering and the exact WINDOW_UPDATE increment, and these were not cross-checked against a real device. See the README parity table.

CI green (build / vet / gofmt / test on Go 1.25).

v0.5.0 — measured parity table + docs overhaul

Choose a tag to compare

@North-web-dev North-web-dev released this 25 Oct 15:14

Documentation and release polish. No breaking API changes; no behavioural change to the library.

Highlights

  • Real measured parity table in the README: JA4, JA3, and HTTP/2 (Akamai) fingerprints for every profile (chrome, edge, firefox, safari, ios), captured with go run ./cmd/measure against tls.peet.ws on 2026-10-25 (uTLS v1.8.2). Reproducible — no hand-written values.
  • Corrected the Chrome fingerprint claim. Chrome shuffles its TLS extension order on every connection (Chromium >= 110), so its JA3 is non-deterministic by design. The old README listed a single fixed Chrome JA3, which was misleading; JA4 (which sorts extensions) is now presented as the identifier to match on.
  • Honest Edge caveat: uTLS HelloEdge_Auto does not reproduce Chromiums per-connection extension shuffle, so the Edge ClientHello is close but not shuffle-identical to real Edge 131. Use Chrome` if you need the shuffle.
  • 30-second quickstart with a complete, runnable example.
  • What it does / does not do section (no HTTP/3, regular-header order is best-effort, no JS/DOM) and a factual comparison to curl_cffi (Python + CGo/libcurl) and utls (TLS layer only).
  • Godoc: documented the exported Profile type and all its fields.

Verified

go build ./..., go vet ./..., and go test ./... -race all pass (Go 1.25.3). CI green.

Full changelog: v0.4.0...v0.5.0

v0.4.0

Choose a tag to compare

@North-web-dev North-web-dev released this 07 Jul 03:53

Proxy support, a language-agnostic HTTP fetch API, and a new mobile profile.

Highlights

  • Proxy support — route any client through a socks5:// or http(s):// proxy (with credentials) via WithProxy, or plug in your own dialer with WithDialer. WithTimeout sets the client timeout.
  • HTTP fetch API (cmd/serve) — wrap the library in a service: POST /fetch a URL + profile, get the response fetched with that browser's exact TLS/HTTP2 fingerprint. br/zstd/gzip bodies are decoded for you. Endpoints: /fetch, /profiles, /usage, /healthz.
  • Per-key rate limits & quotas — run the API with -key (single key) or -keys keys.json for per-key requests/sec and daily quotas. Auth via Authorization: Bearer or X-API-Key; open when no key is set.
  • chrome_android profile — mobile Chrome (Android UA, sec-ch-ua-mobile: ?1). Six profiles total: chrome, chrome_android, firefox, safari, edge, ios.
  • Docker — multi-stage build to a distroless image.

Install

go get github.com/North-web-dev/impersonate-http@v0.4.0

Non-breaking: New, NewTransport, and NewByName now take optional Options; existing calls are unchanged.

v0.3.0 — WebSocket support

Choose a tag to compare

@North-web-dev North-web-dev released this 03 Jul 12:42

Browser-fingerprinted WebSocket (wss://).

Expose Profile.DialTLSContext / Profile.Dial — a uTLS dialer that does the browser-exact TLS handshake and hands back the conn, so any WebSocket client (coder/websocket, gorilla/websocket) gets JA3/JA4-identical wss connections.

websocket.Dial(ctx, "wss://host", &websocket.DialOptions{
    HTTPClient: &http.Client{Transport: impersonate.NewTransport(impersonate.Chrome)},
})

Also: a cmd/measure fingerprint self-check, and the profiles are now cross-referenced with the new fingerprint-db. HTTP/3 (QUIC) on the roadmap.

v0.2.0 — browser-exact HTTP/2 fingerprint

Choose a tag to compare

@North-web-dev North-web-dev released this 02 Jul 16:47

v0.2 nails the HTTP/2 (Akamai) fingerprint too — not just TLS.

A custom HTTP/2 client (on http2.Framer + hpack) emits the browser's exact SETTINGS order+values, WINDOW_UPDATE increment, and pseudo-header order.

Verified against tools.scrapfly.io — Chrome:

1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p

byte-identical to real Chrome (JA3/JA4 + Akamai h2 both match).

Now defeats both TLS and HTTP/2 fingerprinting — the combination Cloudflare/Akamai/DataDome actually score.

v0.1.0 — browser-exact TLS fingerprint

Choose a tag to compare

@North-web-dev North-web-dev released this 02 Jul 16:31

A drop-in Go *http.Client whose TLS ClientHello is byte-identical to a real browser (Chrome/Firefox/Safari/Edge/iOS) — survive JA3/JA4 fingerprinting without a headless browser, CGo, or curl.

client := impersonate.New(impersonate.Chrome)
resp, _ := client.Get("https://example.com")

Verified against tls.peet.ws — each profile's JA4 matches the real browser (Chrome t13d1516h2_8daaf6152771).

Scope: TLS (JA3/JA4) + default headers are browser-exact. HTTP/2 frame-level (Akamai) fingerprint is Go's stack for now — browser-exact h2 is the v0.2 roadmap, documented honestly.

Only deps: uTLS + x/net. MIT.