Skip to content

jonwiggins/urlx

Repository files navigation


urlx
curl, rewritten in Rust.

CI crates.io docs.rs License: MIT


urlx is a memory-safe, from-scratch reimplementation of curl and libcurl. No OpenSSL. No unsafe outside the FFI boundary. 1,300 of curl's own tests pass against urlx.

# It's curl. Just in Rust.
urlx https://example.com
urlx -d '{"key":"val"}' -H 'Content-Type: application/json' https://api.example.com
urlx -Lo file.tar.gz https://example.com/file.tar.gz
urlx -u user:pass --digest https://api.example.com/admin
urlx -Z https://a.com https://b.com https://c.com   # parallel transfers

Why?

curl is one of the most important pieces of software ever written. It's also 180,000 lines of C with a long history of memory safety CVEs. urlx asks: what if we just rewrote it?

  • Memory-safe — zero unsafe in the core library and CLI
  • No OpenSSL — TLS via rustls, with optional OpenSSL for TLS-SRP
  • Drop-in CLI — same flags, same output, same exit codes — 261 long flags, 46 short
  • Drop-in C libraryliburlx-ffi exposes the libcurl C ABI for existing C/C++ programs
  • Idiomatic Rust API — async/sync Easy/Multi handles, thiserror errors, feature-flagged protocols
  • Tested against curl itself — curl's own test suite is the spec

Test Suite Compatibility

urlx is validated against curl's own test suite (tests 1–1400):

Metric Count
Pass 1,300
Skip (debug builds, missing platform features) 92
Permanently excluded (curl source analysis, libcurl C API) 25
Pass rate of evaluated tests 100%

What's Supported

Status
HTTP/1.0, 1.1, 2, 3 (QUIC) Full (HTTP/3 untested)
TLS 1.2 / 1.3 rustls, cert pinning, client certs, STARTTLS
Auth Basic, Digest, Bearer, NTLMv2, SCRAM-SHA-256, AWS SigV4, SASL
FTP / FTPS Upload, resume, directory ops, active & passive, EPSV
SSH / SFTP / SCP Password + pubkey auth, quote commands
SMTP, IMAP, POP3 STARTTLS, SASL, MIME
WebSocket RFC 6455, close codes, fragmentation
MQTT Subscribe, publish
Gopher, DICT, TFTP, RTSP Full
Cookies Netscape format, domain-indexed, PSL, SameSite
HSTS Preload list
Proxy HTTP CONNECT, SOCKS4/4a/5, HTTPS tunnel, proxy auth
DNS Happy Eyeballs, DoH, DoT, custom servers, caching
Decompression gzip, deflate, brotli, zstd
CLI flags 261 long + 46 short (curl has ~250 long)
FFI 156 CURLOPT, 49 CURLINFO, 57 exported C functions

Install

cargo install urlx-cli          # from crates.io
brew install jonwiggins/tap/urlx  # Homebrew

Or build from source:

git clone --recurse-submodules https://github.com/jonwiggins/urlx
cd urlx && cargo build --release

Use as a Rust Library

let mut easy = liburlx::Easy::new();
easy.url("https://httpbin.org/get")?;
let response = easy.perform()?;
println!("{}", response.status());    // 200
println!("{}", response.body_str()?); // {"origin": "..."}
[dependencies]
liburlx = "0.2"

Use as a C Library (libcurl ABI)

#include "urlx.h"

CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);

Link against liburlx_ffi instead of libcurl — no code changes needed.

Architecture

                    ┌─────────────┐
                    │   urlx CLI  │  Drop-in curl replacement
                    └──────┬──────┘
                           │
┌──────────────┐    ┌──────┴──────┐
│ liburlx-ffi  │────│   liburlx   │  Core Rust library
│  (C ABI)     │    │  (Rust API) │
└──────────────┘    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
        ┌─────┴─────┐ ┌───┴───┐ ┌─────┴─────┐
        │ Protocols  │ │  TLS  │ │    DNS    │
        │ HTTP, FTP, │ │rustls │ │  Cache,   │
        │ WS, SMTP...│ │       │ │  HE, DoH  │
        └────────────┘ └───────┘ └───────────┘

Three crates, one workspace:

Crate What it does
liburlx Core transfer library — pure Rust, async/sync API, 20+ feature flags
liburlx-ffi C ABI layer — link against it instead of libcurl
urlx-cli The urlx binary — drop-in curl replacement

Contributing

See CONTRIBUTING.md. The short version:

cargo fmt && cargo clippy --all-targets && cargo test --workspace

Every commit must pass the full guardrail suite. Conventional commits are enforced by CI.

Acknowledgements

urlx would not exist without curl by Daniel Stenberg. curl's behavior is our specification, and its test suite is our acceptance criteria.

Built with tokio, rustls, h2, quinn, and russh.

License

MIT

About

A memory-safe Rust reimplementation of curl and libcurl.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages