hyper-tls

A minimal HTTPS connector that pairs hyper with native-tls for secure Rust HTTP clients.

Library
Cargo
v0.6.0
201stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
39/100Needs Attention
Development Activity0
Maintenance0
Community76
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
51/100Fair
Architecture68
Code Quality45
Innovation35
Learning Curve55

hyper-tls provides the HTTPS connector most Rust services reach for when building an HTTP client on top of hyper. It implements tower’s Service<Uri> trait so it drops directly into hyper-util’s legacy Client builder, inspecting each request’s scheme and transparently performing a TLS handshake only when the URI is https. Rather than bundling a pure-Rust TLS stack, it delegates the handshake to native-tls, which in turn uses the host operating system’s TLS implementation — OpenSSL on Linux, Secure Transport on macOS, SChannel on Windows — so certificate trust and platform TLS policy come from the OS rather than a vendored trust store.

The crate is intentionally small: a HttpsConnector<T> wrapping an inner connector (defaulting to hyper-util’s HttpConnector) and TLS connector, a MaybeHttpsStream<T> enum unifying plain and TLS-wrapped streams behind hyper’s Read/Write traits, and an optional https_only(true) mode that rejects non-HTTPS URIs outright instead of silently falling back to plain text. It’s the connector used in hyper’s own official examples for making outbound HTTPS requests.

What You Get

  • A Service<Uri>-implementing HttpsConnector<T> ready to hand to hyper-util’s legacy Client builder.
  • A MaybeHttpsStream<T> enum unifying plain and TLS-wrapped streams behind hyper’s Read/Write traits.
  • An HttpsConnecting<T> future type representing the in-flight connect-plus-handshake operation.
  • Optional alpn and vendored Cargo features for HTTP/2 negotiation and bundled-OpenSSL builds.

Common Use Cases

  • Outbound HTTPS calls from Rust backend services and CLIs built on hyper.
  • Enforcing TLS-only connections for security-sensitive clients via https_only(true).
  • Wrapping a custom base connector (e.g. one with connection-pooling tweaks) with TLS support.
  • Building lightweight HTTP clients where OS-native TLS is preferable to a vendored stack.

Under The Hood

Architecture The crate exposes HttpsConnector<T>, which implements tower’s Service<Uri> trait so it can be dropped into hyper-util’s Client builder as a pluggable connector. Its call() method inspects the request URI’s scheme, delegates the underlying TCP connect to the wrapped inner service (defaulting to hyper-util’s HttpConnector), and only layers a TLS handshake through TokioIo adapters when the scheme is https, producing a MaybeHttpsStream<T> enum with Http/Https variants that implement hyper’s Read/Write traits by dispatching to the active branch. With the whole implementation living in two files (client.rs, stream.rs) totaling a few hundred lines, it’s a lean decorator around hyper’s connector abstraction rather than a layered system, but as the sole hyper/native-tls integration point, any change to the core Service<Uri> contract ripples directly into every client built on it.

Tech Stack Built for Rust 2018 edition (minimum Rust version 1.63) against hyper 1.x and hyper-util 0.1 (client-legacy and tokio features), with native-tls 0.2 providing the actual TLS handshake and tokio-native-tls 0.3 wrapping it for async use; tower-service 0.3 supplies the Service trait the connector implements, and bytes handles buffer types. There’s no build script or bespoke tooling — it’s a pure Cargo library crate consumed as a dependency, with optional alpn and vendored Cargo features toggling native-tls’s ALPN support and vendored OpenSSL respectively.

Code Quality No test files exist anywhere in the repository — validation relies entirely on the GitHub Actions CI workflow and the doc-tested example in the crate’s top-level documentation rather than a dedicated test suite. Error handling favors a boxed dyn std::error::Error (BoxError) over a typed error enum, with a single custom ForceHttpsButUriNotHttps struct for the one domain-specific failure case. Naming is consistent, idiomatic Rust, and the crate enables #![deny(missing_docs)] and #![deny(missing_debug_implementations)] at the root, enforcing documentation coverage and Debug implementations at compile time even without a formal test suite.

API Design The public surface is deliberately narrow: HttpsConnector::new() for the common case, HttpsConnector::from((connector, tls)) for swapping in a custom base connector or preconfigured TlsConnector, and https_only(bool) for enforcing HTTPS. Getting started requires almost no boilerplate — the crate’s own README example wires the connector into a Client builder in three lines — though the API doesn’t expose any way to customize TLS certificate verification without dropping to native-tls’s own builder first.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search