Releases: he4rt/reqxide
0.1.1
v0.1.0
What's New
32 New Browser Presets from curl_impersonate
Expanded coverage from 12 to 44 browser fingerprint profiles, matching all presets supported by curl_impersonate.
Chrome Desktop (16 new): v99, v100, v101, v104, v107, v110, v116, v119, v120, v123, v124, v133a, v136, v142, v145, v146
Chrome Android (2 new): v99Android, v131Android
Firefox (3 new): v133, v144, v147
Safari (8 new): v153, v155, v170, v172iOS, v184, v184iOS, v260, v260iOS
Edge (2 new): v99, v101
Tor (1 new): v145 — Firefox 128-based Tor Browser profile with Sec-GPC header
Infrastructure
KeyShare::X25519Kyber768Draft00— Chrome 124 post-quantum key exchangeTlsOptions::$keySharesLimit— Firefox/Tor key shares limit control- 11 new
CipherSuitecases (CBC/3DES for Safari 15.x) - 2 new
SignatureAlgorithmcases (legacy SHA1 for Firefox/Safari/Tor)
AI Integration (Boost)
- Guidelines and skills for AI-assisted code generation
- Development skill: profile creation, era architecture, curl_impersonate porting
- Usage skill: navigation vs XHR vs beacon patterns, Saloon/Guzzle integration
Bug Fixes
- Validate magic bytes before decompression in CompressionMiddleware
- HTTP message compatibility improvements
Full Changelog: 0.0.2...0.1.0
0.0.2 — Bugfixes, Audit Hardening & Guzzle Adapter Fix
Reqxide 0.0.2
Warning: This package is under active development and not yet stable.
Highlights
- 3 rounds of codebase audits — 11 runtime bugs found and fixed
- Guzzle adapter fix — now returns
PromiseInterfaceas required by Guzzle middleware stack - FFI segfault resolved —
RTLD_DEEPBINDprevents symbol collision with ext/curl - PHP 8.4 compatible — typed class constants restored (PHP 8.3 feature, not 8.5)
Bug Fixes
Critical
- GuzzleHandlerAdapter: returns
PromiseInterfaceviaCreate::promiseFor()instead of rawResponseInterface(was crashing Guzzle middleware stack) - CurlTransport: fixed resource cleanup in finally block
- CompressionMiddleware: replaced
@error suppression with explicit=== falsechecks
Security
- RedirectMiddleware: strip request body on 303/301/302 method change to GET — prevents leaking POST data to redirect targets (RFC 7231 §6.4.4)
- RedirectMiddleware: strips sensitive headers (Authorization, Cookie) on cross-origin redirects
RFC Compliance
- Cookie.isExpired(): negative
Max-Agevalues now treated as expired per RFC 6265 - RedirectMiddleware: fixed off-by-one —
maxRedirects=10now allows exactly 10 redirects, not 11 - RedirectMiddleware: RFC 3986 §5.2.4 dot-segment normalization for relative redirect paths
Correctness
- RetryBudget: cast to float in ratio division to prevent integer precision loss
- RetryPolicy: default classifier only retries idempotent methods (GET, HEAD, PUT, DELETE, OPTIONS) per RFC 7231 §4.2.2
- RetryPolicy.delayMs(): cap exponent at 16 to prevent integer overflow
- Proxy.parse(): prefix address with
//beforeparse_urlsouser:pass@host:portparses correctly - CompressionMiddleware: return empty string instead of null for empty compressed bodies
- CurlTransport: handle HTTP header folding (continuation lines)
- CurlTransport: enable
CURLOPT_ENCODINGfor native brotli/gzip/zstd decompression
FFI Transport
- Resolved segfault caused by ext/curl symbol collision using
dlopen()+RTLD_DEEPBIND - Implemented response body/header capture via temp files
- Disabled from auto-detection (known issues documented as @todo) — opt-in only
Enhancements
- RequestBuilder.query(): merges params instead of overwriting
- ProfileInterface: added
originalHeaderMap()accessor method - FfiTransport: 30+ magic numbers replaced with named class constants
- TransportFactory: CurlTransport is now the default (most reliable)
- Guzzle added as
suggest+require-devdependency
Installation
composer require he4rt/reqxide:0.0.2Requires PHP 8.4+
Quality
- 730 unit tests, 1276 assertions
- PHPStan level max — zero errors
- 100% type coverage
Full Changelog
See 0.0.1...0.0.2
v0.0.1 - Initial Alpha Release
Reqxide v0.0.1 — Initial Alpha Release
PHP 8.5+ TLS/HTTP fingerprinting library for browser emulation. Ported from Rust's wreq.
What is Reqxide?
Anti-bot systems (Cloudflare, Akamai, DataDome) fingerprint TLS handshakes and HTTP/2 frames to detect bots. Reqxide lets your PHP requests produce the same JA3/JA4 fingerprints as real browsers.
Installation
composer require he4rt/reqxideRequires PHP 8.5+
Quick Start
use Reqxide\Client;
use Reqxide\Emulation\Browser;
$client = Client::builder()
->emulation(Browser::Chrome131)
->build();
$response = $client->get('https://example.com')->send();What's Included
Browser Emulation (5 browsers, 12 profiles)
| Browser | Versions | Highlights |
|---|---|---|
| Chrome | 128, 129, 130, 131 | GREASE, ECH, X25519MLKEM768 (130+) |
| Firefox | 135, 136 | FFDHE curves, Sec-Fetch headers, different pseudo-header order |
| Safari | 18 (macOS, iPad, iOS) | Minimal fingerprint, no GREASE/ECH |
| Edge | 131 | Chromium base with Edge-specific branding |
| OkHttp | 4, 5 | HTTP/1.1 only, Android client fingerprint |
Each profile controls: TLS cipher suites, elliptic curves, signature algorithms, ALPN, key shares, GREASE, ECH, extension permutation, HTTP/2 SETTINGS order, pseudo-header order, window sizes, header ordering, and default headers.
PSR-18 Client
Fully PSR-18 compliant (ClientInterface) — drop-in replacement for any PSR-18 consumer.
// Convenience API
$response = $client->get('https://api.example.com/users')->send();
$response = $client->post('https://api.example.com/users')
->json(['name' => 'Daniel'])
->bearerToken('token')
->send();
// PSR-18 standard
$response = $client->sendRequest($psrRequest);Middleware Pipeline
- CookieMiddleware — automatic cookie persistence via RFC 6265 compliant CookieJar
- RedirectMiddleware — follows 3xx, strips sensitive headers on cross-origin
- RetryMiddleware — exponential backoff with budget-based retry (20% max extra load)
- CompressionMiddleware — gzip/deflate/brotli/zstd decompression
Three Transport Backends
| Transport | Fingerprint Control | Requires |
|---|---|---|
FfiTransport |
Full (TLS + HTTP/2 + headers) | PHP FFI + libcurl-impersonate |
CurlTransport |
Partial (ciphers, curves, ALPN) | ext-curl |
ProcessTransport |
Full (via binary flags) | curl-impersonate binary |
Proxy Support
HTTP, HTTPS, SOCKS4, SOCKS5 with optional authentication.
use Reqxide\Proxy\Proxy;
$client = Client::builder()
->emulation(Browser::Chrome131)
->proxy(Proxy::socks5('127.0.0.1:1080'))
->build();Framework Adapters
- Guzzle —
GuzzleHandlerAdapteras a drop-in handler - Laravel — Service provider helper + Facade
- Symfony —
SymfonyClientAdapterwithrequest()method
Quality
- 726 unit tests, 1268 assertions
- 15 integration tests (TLS fingerprint verification via tls.peet.ws)
- PHPStan level max — zero errors
- 100% type coverage
- Laravel Pint formatted
Fingerprint Accuracy
Verified against tls.peet.ws:
Chrome 131: JA3=9e2da15d3e1b6931c6fbaa3f9ac9cd89 JA4=t13d913h2_f91f431d341e_882d495ac381
Firefox 136: JA3=bdc242f0548bc1fcc45d12edc713b8e1 JA4=t13d1513h2_8daaf6152771_882d495ac381
Alpha Disclaimer
This is an alpha release for early testing. The API may change before 1.0. Known limitations:
FfiTransportrequires manual libcurl-impersonate installation and may need tuning for FFI callbacksCurlTransportprovides partial fingerprinting (ext-curl can't control HTTP/2 SETTINGS order or GREASE)- Browser profiles are based on known fingerprint data; real-world accuracy depends on the transport backend used
Full Changelog
28 commits — see commit history