[package]
edition = "2024"
rust-version = "1.96"
name = "leyline-http"
version = "0.1.3"
authors = ["Thomas Gardiner <thomas@manaforge.tech>"]
build = "build.rs"
exclude = ["profiles/captures/"]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "HTTP client that mimics browsers on the wire"
homepage = "https://github.com/manaforged/leyline-http"
documentation = "https://docs.rs/leyline-http"
readme = "README.md"
keywords = [
"tls",
"fingerprint",
"http",
"browser",
"ja4",
]
categories = [
"web-programming::http-client",
"cryptography",
]
license = "MIT"
repository = "https://github.com/manaforged/leyline-http"
resolver = "2"
[package.metadata.cargo_check_external_types]
allowed_external_types = [
"http",
"http::*",
"bytes::*",
"serde_core::*",
"serde_json::*",
"futures_core::*",
"url::*",
"tokio::io::async_write::AsyncWrite",
"tower_service::*",
]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
features = ["full"]
[package.metadata.cargo-machete]
ignore = ["md-5"]
[features]
bench-internals = []
charset = ["dep:encoding_rs"]
compression-brotli = ["dep:brotli"]
compression-deflate = ["dep:flate2"]
compression-gzip = ["dep:flate2"]
compression-zstd = ["dep:zstd"]
default = [
"charset",
"compression-gzip",
"compression-brotli",
"compression-deflate",
"compression-zstd",
"multipart",
"websocket",
"http3",
"html",
]
full = [
"compression-gzip",
"compression-brotli",
"compression-deflate",
"compression-zstd",
"multipart",
"websocket",
"http3",
"tower",
"socks",
"charset",
"html",
]
html = ["multipart"]
http3 = ["dep:leyline-quiche"]
multipart = []
socks = []
test-util = []
tower = ["dep:tower-service"]
websocket = ["dep:tokio-tungstenite"]
[lib]
name = "leyline"
path = "src/lib.rs"
[[example]]
name = "api_client"
path = "examples/api_client.rs"
[[example]]
name = "audit"
path = "examples/audit.rs"
[[example]]
name = "browser_tab"
path = "examples/browser_tab.rs"
required-features = ["html"]
[[example]]
name = "concurrent"
path = "examples/concurrent.rs"
[[example]]
name = "cookies"
path = "examples/cookies.rs"
[[example]]
name = "crawler"
path = "examples/crawler.rs"
[[example]]
name = "device"
path = "examples/device.rs"
required-features = ["html"]
[[example]]
name = "download"
path = "examples/download.rs"
[[example]]
name = "headers"
path = "examples/headers.rs"
[[example]]
name = "http3"
path = "examples/http3.rs"
required-features = ["http3"]
[[example]]
name = "multipart"
path = "examples/multipart.rs"
required-features = ["multipart"]
[[example]]
name = "oneliner"
path = "examples/oneliner.rs"
[[example]]
name = "post_json"
path = "examples/post_json.rs"
[[example]]
name = "presets"
path = "examples/presets.rs"
[[example]]
name = "retry"
path = "examples/retry.rs"
[[example]]
name = "stock_monitor"
path = "examples/stock_monitor.rs"
[[example]]
name = "streaming"
path = "examples/streaming.rs"
[[example]]
name = "trace"
path = "examples/trace.rs"
[[example]]
name = "websocket"
path = "examples/websocket.rs"
required-features = ["websocket"]
[[test]]
name = "accounts_and_forms"
path = "tests/accounts_and_forms.rs"
[[test]]
name = "body_cap"
path = "tests/body_cap.rs"
[[test]]
name = "cfnetwork_live"
path = "tests/cfnetwork_live.rs"
[[test]]
name = "claim_guard"
path = "tests/claim_guard.rs"
[[test]]
name = "connect_timeout"
path = "tests/connect_timeout.rs"
[[test]]
name = "content_encoding"
path = "tests/content_encoding.rs"
[[test]]
name = "cookie_lifetime"
path = "tests/cookie_lifetime.rs"
[[test]]
name = "core_digest"
path = "tests/core_digest.rs"
[[test]]
name = "core_multipart"
path = "tests/core_multipart.rs"
required-features = ["multipart"]
[[test]]
name = "core_retry"
path = "tests/core_retry.rs"
[[test]]
name = "core_streaming"
path = "tests/core_streaming.rs"
[[test]]
name = "core_wire_fidelity"
path = "tests/core_wire_fidelity.rs"
[[test]]
name = "crawl_identity"
path = "tests/crawl_identity.rs"
[[test]]
name = "crawling"
path = "tests/crawling.rs"
[[test]]
name = "credentials_hidden"
path = "tests/credentials_hidden.rs"
[[test]]
name = "deadlines_and_lifecycle"
path = "tests/deadlines_and_lifecycle.rs"
[[test]]
name = "devices"
path = "tests/devices.rs"
[[test]]
name = "digest_redirects"
path = "tests/digest_redirects.rs"
[[test]]
name = "env_proxy_fail_closed"
path = "tests/env_proxy_fail_closed.rs"
[[test]]
name = "env_socks_proxy"
path = "tests/env_socks_proxy.rs"
[[test]]
name = "ergonomics"
path = "tests/ergonomics.rs"
[[test]]
name = "error_body_budget"
path = "tests/error_body_budget.rs"
[[test]]
name = "fingerprint_conformance"
path = "tests/fingerprint_conformance.rs"
required-features = ["bench-internals"]
[[test]]
name = "forms_and_relay"
path = "tests/forms_and_relay.rs"
[[test]]
name = "future_size"
path = "tests/future_size.rs"
[[test]]
name = "h1_error_body"
path = "tests/h1_error_body.rs"
[[test]]
name = "h1_failures"
path = "tests/h1_failures.rs"
[[test]]
name = "h2_backpressure"
path = "tests/h2_backpressure.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_body_cap"
path = "tests/h2_body_cap.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_cancel_safety"
path = "tests/h2_cancel_safety.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_connect_method"
path = "tests/h2_connect_method.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_continuation_timeout"
path = "tests/h2_continuation_timeout.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_error_prefix"
path = "tests/h2_error_prefix.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_extended_connect"
path = "tests/h2_extended_connect.rs"
required-features = [
"bench-internals",
"websocket",
]
[[test]]
name = "h2_fallback_upgrade"
path = "tests/h2_fallback_upgrade.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_flow_control_e2e"
path = "tests/h2_flow_control_e2e.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_flow_overflow"
path = "tests/h2_flow_overflow.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_frame_roundtrip"
path = "tests/h2_frame_roundtrip.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_hostile_server"
path = "tests/h2_hostile_server.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_informational_e2e"
path = "tests/h2_informational_e2e.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_message_length"
path = "tests/h2_message_length.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_multiplex"
path = "tests/h2_multiplex.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_output_budget"
path = "tests/h2_output_budget.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_pool_stall"
path = "tests/h2_pool_stall.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_recv_window"
path = "tests/h2_recv_window.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_refused_retry"
path = "tests/h2_refused_retry.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_resend"
path = "tests/h2_resend.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_rst_flood"
path = "tests/h2_rst_flood.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_rst_flood_e2e"
path = "tests/h2_rst_flood_e2e.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_shutdown_streaming_e2e"
path = "tests/h2_shutdown_streaming_e2e.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_stream_delivery"
path = "tests/h2_stream_delivery.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_stream_lifecycle"
path = "tests/h2_stream_lifecycle.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_stream_state"
path = "tests/h2_stream_state.rs"
required-features = ["bench-internals"]
[[test]]
name = "h2_write_batching"
path = "tests/h2_write_batching.rs"
required-features = ["bench-internals"]
[[test]]
name = "h3_body_cap"
path = "tests/h3_body_cap.rs"
[[test]]
name = "h3_error_prefix"
path = "tests/h3_error_prefix.rs"
[[test]]
name = "h3_request_rejected"
path = "tests/h3_request_rejected.rs"
[[test]]
name = "h3_stream_errors"
path = "tests/h3_stream_errors.rs"
[[test]]
name = "h3_stream_limit"
path = "tests/h3_stream_limit.rs"
[[test]]
name = "h3_timeout"
path = "tests/h3_timeout.rs"
[[test]]
name = "h3_timing"
path = "tests/h3_timing.rs"
[[test]]
name = "host_limit_hops"
path = "tests/host_limit_hops.rs"
[[test]]
name = "hpack_encoding"
path = "tests/hpack_encoding.rs"
required-features = ["bench-internals"]
[[test]]
name = "http_semantics"
path = "tests/http_semantics.rs"
[[test]]
name = "https_proxy"
path = "tests/https_proxy.rs"
required-features = ["bench-internals"]
[[test]]
name = "identity_switch"
path = "tests/identity_switch.rs"
[[test]]
name = "limit_settings"
path = "tests/limit_settings.rs"
[[test]]
name = "limits_and_state"
path = "tests/limits_and_state.rs"
[[test]]
name = "pages_and_limits"
path = "tests/pages_and_limits.rs"
[[test]]
name = "parity_builder"
path = "tests/parity_builder.rs"
[[test]]
name = "pool_h1_framing"
path = "tests/pool_h1_framing.rs"
required-features = ["bench-internals"]
[[test]]
name = "pool_h1_injection"
path = "tests/pool_h1_injection.rs"
required-features = ["bench-internals"]
[[test]]
name = "pool_h1_keepalive"
path = "tests/pool_h1_keepalive.rs"
required-features = ["bench-internals"]
[[test]]
name = "pool_reconnect_storm"
path = "tests/pool_reconnect_storm.rs"
required-features = ["bench-internals"]
[[test]]
name = "pool_stats"
path = "tests/pool_stats.rs"
required-features = ["bench-internals"]
[[test]]
name = "pq_key_shares"
path = "tests/pq_key_shares.rs"
[[test]]
name = "profile_builtin"
path = "tests/profile_builtin.rs"
required-features = ["bench-internals"]
[[test]]
name = "profile_validation"
path = "tests/profile_validation.rs"
required-features = ["bench-internals"]
[[test]]
name = "proxy_identity"
path = "tests/proxy_identity.rs"
[[test]]
name = "proxy_rebind"
path = "tests/proxy_rebind.rs"
[[test]]
name = "proxy_rules"
path = "tests/proxy_rules.rs"
[[test]]
name = "public_debug"
path = "tests/public_debug.rs"
[[test]]
name = "read_until"
path = "tests/read_until.rs"
[[test]]
name = "recovery"
path = "tests/recovery.rs"
[[test]]
name = "redirect_host"
path = "tests/redirect_host.rs"
[[test]]
name = "referers_hints_and_proxies"
path = "tests/referers_hints_and_proxies.rs"
[[test]]
name = "response_header_timeout"
path = "tests/response_header_timeout.rs"
[[test]]
name = "responses_and_errors"
path = "tests/responses_and_errors.rs"
[[test]]
name = "retry_rules"
path = "tests/retry_rules.rs"
[[test]]
name = "retry_unsent_redirect"
path = "tests/retry_unsent_redirect.rs"
[[test]]
name = "samesite_cookies"
path = "tests/samesite_cookies.rs"
[[test]]
name = "server_chosen_urls"
path = "tests/server_chosen_urls.rs"
[[test]]
name = "session_clone"
path = "tests/session_clone.rs"
[[test]]
name = "session_lifecycle"
path = "tests/session_lifecycle.rs"
[[test]]
name = "sessions_and_devices"
path = "tests/sessions_and_devices.rs"
[[test]]
name = "smoke"
path = "tests/smoke.rs"
required-features = ["http3"]
[[test]]
name = "soak"
path = "tests/soak.rs"
[[test]]
name = "state_files"
path = "tests/state_files.rs"
[[test]]
name = "status_and_retry"
path = "tests/status_and_retry.rs"
[[test]]
name = "timeouts"
path = "tests/timeouts.rs"
[[test]]
name = "tls_behaviour"
path = "tests/tls_behaviour.rs"
[[test]]
name = "tls_client_hello_order"
path = "tests/tls_client_hello_order.rs"
[[test]]
name = "tls_floor"
path = "tests/tls_floor.rs"
[[test]]
name = "tls_happy_eyeballs"
path = "tests/tls_happy_eyeballs.rs"
required-features = ["bench-internals"]
[[test]]
name = "tls_peet"
path = "tests/tls_peet.rs"
required-features = [
"bench-internals",
"http3",
"websocket",
]
[[test]]
name = "tls_pinning_hostname"
path = "tests/tls_pinning_hostname.rs"
required-features = ["bench-internals"]
[[test]]
name = "tls_system_trust_live"
path = "tests/tls_system_trust_live.rs"
[[test]]
name = "tls_trust_scope"
path = "tests/tls_trust_scope.rs"
required-features = ["bench-internals"]
[[test]]
name = "trace_unwind"
path = "tests/trace_unwind.rs"
[[test]]
name = "websocket_messages"
path = "tests/websocket_messages.rs"
[[test]]
name = "websocket_subprotocol"
path = "tests/websocket_subprotocol.rs"
required-features = ["websocket"]
[[test]]
name = "wire_headers"
path = "tests/wire_headers.rs"
[dependencies.base64]
version = "0.22"
[dependencies.brotli]
version = "8.0.2"
optional = true
[dependencies.bytes]
version = "1.9.0"
[dependencies.encoding_rs]
version = "0.8"
optional = true
[dependencies.flate2]
version = "1.1"
features = ["zlib-rs"]
optional = true
default-features = false
[dependencies.futures-util]
version = "0.3"
[dependencies.hex]
version = "0.4"
[dependencies.http]
version = "1"
[dependencies.leyline-bssl]
version = "=0.1.3"
[dependencies.leyline-bssl-tokio]
version = "=0.1.3"
[dependencies.leyline-quiche]
version = "=0.1.3"
features = ["boringssl-bssl-crate"]
optional = true
default-features = false
[dependencies.libc]
version = "0.2.185"
[dependencies.lru]
version = "0.18"
[dependencies.md-5]
version = "0.10"
[dependencies.psl]
version = "2.1"
[dependencies.rand]
version = "0.9"
[dependencies.serde]
version = "1.0.145"
features = ["derive"]
[dependencies.serde_json]
version = "1"
[dependencies.sha2]
version = "0.10"
[dependencies.socket2]
version = "0.6"
features = ["all"]
[dependencies.thiserror]
version = "2.0.7"
[dependencies.tokio]
version = "1.37"
features = [
"net",
"rt",
"time",
"io-util",
"net",
"rt",
"time",
"io-util",
"macros",
"fs",
"sync",
]
[dependencies.tokio-tungstenite]
version = "0.26"
optional = true
[dependencies.tokio-util]
version = "0.7.5"
features = ["io"]
[dependencies.toml]
version = "0.9"
features = [
"parse",
"serde",
"std",
]
default-features = false
[dependencies.tower-service]
version = "0.3"
optional = true
[dependencies.tracing]
version = "0.1.36"
[dependencies.url]
version = "2"
features = ["serde"]
[dependencies.zstd]
version = "0.13"
optional = true
[dev-dependencies.base64]
version = "0.22"
[dev-dependencies.brotli]
version = "8.0.2"
[dev-dependencies.bytes]
version = "1.9.0"
[dev-dependencies.flate2]
version = "1.1"
features = ["zlib-rs"]
default-features = false
[dev-dependencies.futures-util]
version = "0.3"
[dev-dependencies.leyline-bssl]
version = "=0.1.3"
[dev-dependencies.leyline-bssl-tokio]
version = "=0.1.3"
[dev-dependencies.leyline-quiche]
version = "=0.1.3"
features = [
"boringssl-bssl-crate",
"internal",
]
default-features = false
[dev-dependencies.serde_json]
version = "1"
[dev-dependencies.tokio]
version = "1.37"
features = [
"net",
"rt",
"time",
"io-util",
"full",
]
[dev-dependencies.tokio-util]
version = "0.7.5"
features = ["io"]
[dev-dependencies.url]
version = "2"
[dev-dependencies.zstd]
version = "0.13"
[build-dependencies.serde]
version = "1.0.145"
features = ["derive"]
[build-dependencies.toml]
version = "0.9"
features = [
"parse",
"serde",
"std",
]
default-features = false
[target."cfg(windows)".dependencies.windows-sys]
version = "0.61"
features = [
"Win32_Security_Cryptography",
"Win32_Foundation",
]
[lints.clippy]
dbg_macro = "deny"
rc_mutex = "deny"
todo = "deny"
undocumented_unsafe_blocks = "deny"
unimplemented = "deny"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(leyline_unstable_bssl)"]