impcurl-sys 1.1.1

Dynamic FFI bindings for libcurl-impersonate with auto-fetch support
Documentation

impcurl

impcurl-sys impcurl impcurl-ws MIT

Rust WebSocket client with TLS fingerprint impersonation, powered by libcurl-impersonate.

Bypass TLS fingerprinting by impersonating real browser signatures (Chrome, Safari, Firefox, Edge, Tor).

Crates

Crate Description
impcurl-sys Dynamic FFI bindings for libcurl-impersonate with auto-fetch
impcurl Safe blocking wrapper — WebSocket handshake, send, recv
impcurl-ws Async tokio Stream + Sink WebSocket connection

Quick Start

[dependencies]
impcurl-ws = "1.1.1"
futures-util = "0.3"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use futures_util::{SinkExt, StreamExt};
use impcurl_ws::{Message, WsConnection};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mut ws = WsConnection::connect("wss://echo.websocket.org").await?;

    ws.send(Message::Text("hello".to_owned())).await?;

    if let Some(message) = ws.next().await.transpose()? {
        match message {
            Message::Text(text) => println!("{text}"),
            Message::Binary(bytes) => println!("{} bytes", bytes.len()),
            Message::Ping(_) | Message::Pong(_) | Message::Close(_) => {}
        }
    }

    Ok(())
}

Builder API

use impcurl::ImpersonateTarget;
use impcurl_ws::{ControlFrameMode, WsConnection};
use std::time::Duration;

let ws = WsConnection::builder("wss://example.com/ws")
    .header("Origin", "https://example.com")
    .header("User-Agent", "Mozilla/5.0 ...")
    .proxy("socks5h://127.0.0.1:1080")
    .impersonate(ImpersonateTarget::Chrome136)
    .connect_timeout(Duration::from_secs(10))
    .control_frame_mode(ControlFrameMode::Manual)
    .read_buffer_messages(32)
    .write_buffer_messages(32)
    .verbose(true)
    .connect()
    .await?;

Runtime Library

The libcurl-impersonate shared library is resolved in this order:

  1. CURL_IMPERSONATE_LIB env var
  2. Near executable (../lib/ and side-by-side)
  3. IMPCURL_LIB_DIR env var
  4. ~/.impcurl/lib, ~/.cuimp/binaries
  5. Auto-fetch from versioned libcurl-impersonate assets on this repo's GitHub Releases (enabled by default)

impcurl-ws does not expose a lib_path(...) builder escape hatch anymore. Library resolution is treated as deployment configuration rather than a connection-level concern.

TLS CA Bundle (Linux)

impcurl now auto-resolves a CA bundle and applies CURLOPT_CAINFO during websocket setup. Resolution order:

  1. CURL_CA_BUNDLE
  2. SSL_CERT_FILE
  3. Platform defaults (Linux: /etc/ssl/certs/ca-certificates.crt, /etc/pki/tls/certs/ca-bundle.crt, ...)

This removes the need for app-level distro-specific CA symlink hacks in most Linux deployments.

Auto-fetch Controls

Env Var Description
IMPCURL_AUTO_FETCH=0 Disable auto-download
IMPCURL_LIBCURL_VERSION libcurl-impersonate asset version (default current crate version)
IMPCURL_LIBCURL_REPO GitHub repo for libcurl-impersonate assets (default tuchg/impcurl)
IMPCURL_AUTO_FETCH_CACHE_DIR Override fetch cache directory
IMPCURL_DISABLE_AUTO_CAINFO=1 Disable automatic CURLOPT_CAINFO injection

Architecture

impcurl-ws (async tokio client)
  └── impcurl (safe blocking wrapper)
       └── impcurl-sys (dynamic FFI + auto-fetch)
            └── libcurl-impersonate (.so/.dylib/.dll)

On Unix, the async event loop uses CURLMOPT_SOCKETFUNCTION / CURLMOPT_TIMERFUNCTION with tokio::io::unix::AsyncFd for efficient socket-level readiness notification. Non-Unix falls back to curl_multi_poll.

License

MIT

Runtime Asset Release

This repository includes a workflow that publishes versioned libcurl-impersonate assets:

  • GitHub Actions workflow: .github/workflows/release-libcurl-impersonate-assets.yml
  • Local packaging helper: scripts/package_libcurl_assets.sh

Asset naming:

  • impcurl-libcurl-impersonate-v<version>-x86_64-apple-darwin.tar.gz
  • impcurl-libcurl-impersonate-v<version>-aarch64-apple-darwin.tar.gz
  • impcurl-libcurl-impersonate-v<version>-x86_64-unknown-linux-gnu.tar.gz
  • impcurl-libcurl-impersonate-v<version>-aarch64-unknown-linux-gnu.tar.gz
  • impcurl-libcurl-impersonate-v<version>-x86_64-apple-darwin.sha256
  • impcurl-libcurl-impersonate-v<version>-aarch64-apple-darwin.sha256
  • impcurl-libcurl-impersonate-v<version>-x86_64-unknown-linux-gnu.sha256
  • impcurl-libcurl-impersonate-v<version>-aarch64-unknown-linux-gnu.sha256

Note: Linux aarch64 publishing depends on an available ARM64 source image for libcurl-impersonate. macOS assets are packaged by extracting standalone .dylib files from curl-cffi wheels during the release workflow.