Skip to content

Releases: he4rt/reqxide

0.1.1

13 Apr 01:28

Choose a tag to compare

What's Changed

  • Refactor: Move curl exit code descriptions from ProcessTransport into NetworkException::fromCurlExitCode() factory method
  • Cleaner separation of concerns — transport layer delegates error formatting to the exception class

v0.1.0

06 Apr 02:14

Choose a tag to compare

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 exchange
  • TlsOptions::$keySharesLimit — Firefox/Tor key shares limit control
  • 11 new CipherSuite cases (CBC/3DES for Safari 15.x)
  • 2 new SignatureAlgorithm cases (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

29 Mar 14:58

Choose a tag to compare

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 PromiseInterface as required by Guzzle middleware stack
  • FFI segfault resolvedRTLD_DEEPBIND prevents 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 PromiseInterface via Create::promiseFor() instead of raw ResponseInterface (was crashing Guzzle middleware stack)
  • CurlTransport: fixed resource cleanup in finally block
  • CompressionMiddleware: replaced @ error suppression with explicit === false checks

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-Age values now treated as expired per RFC 6265
  • RedirectMiddleware: fixed off-by-one — maxRedirects=10 now 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 // before parse_url so user:pass@host:port parses correctly
  • CompressionMiddleware: return empty string instead of null for empty compressed bodies
  • CurlTransport: handle HTTP header folding (continuation lines)
  • CurlTransport: enable CURLOPT_ENCODING for 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-dev dependency

Installation

composer require he4rt/reqxide:0.0.2

Requires 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

28 Mar 20:25

Choose a tag to compare

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/reqxide

Requires 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

  • GuzzleGuzzleHandlerAdapter as a drop-in handler
  • Laravel — Service provider helper + Facade
  • SymfonySymfonyClientAdapter with request() 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:

  • FfiTransport requires manual libcurl-impersonate installation and may need tuning for FFI callbacks
  • CurlTransport provides 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