claw-transport
Async byte-stream transport trait with pluggable TLS backends.
Provides a Transport trait that abstracts over byte-stream
connections (TLS, plain TCP, WebSocket tunnels). No Send bound is
required, making it compatible with single-threaded runtimes like WASM.
Two built-in backends:
native— tokio + rustls (direct TCP+TLS for native apps)wasm— epoxy-tls JS bridge (TLS through a Wisp/WebSocket proxy for browsers)
Both backends support implicit TLS and STARTTLS.
Quick start
[]
# For native (tokio) apps:
= { = "0.1", = ["native"] }
= { = "1", = ["macros", "rt-multi-thread"] }
# For WASM/browser apps:
# claw-transport = { version = "0.1", features = ["wasm"] }
The Transport trait
Contract:
sendwrites all provided bytes or returns an error.recvblocks until data is available. An emptyVecindicates a timeout. Connection closure returns an error.is_connectedis a best-effort check;truedoes not guarantee the nextsend/recvwill succeed.
Examples
Native: implicit TLS (IMAPS, SMTPS)
use TlsStream;
use Transport;
async
Native: STARTTLS (SMTP port 587)
Connect with plain TCP, exchange EHLO/STARTTLS at the protocol level, then upgrade to TLS:
use TlsStream;
use Transport;
async
WASM: TLS through a Wisp proxy
In a browser/WASM environment, connections go through a WebSocket-based Wisp proxy. The backend relays raw TCP bytes; TLS is handled entirely in the browser via epoxy-tls.
use TlsStream;
use Transport;
async
WASM: STARTTLS through a Wisp proxy
use TlsStream;
use Transport;
async
WASM: certificate trust management
When a server has an invalid or expired certificate, the WASM backend provides interactive trust management:
use TlsStream;
async
Custom transport
Implement Transport for any byte-stream:
use Transport;
Then use it with any protocol client (claw-imap, claw-smtp):
use ImapClient;
async
API overview
Transport trait
| Method | Description |
|---|---|
send(data) |
Write all bytes to the remote peer |
recv() |
Read available bytes (empty Vec on timeout) |
is_connected() |
Best-effort liveness check |
native::TlsStream
| Method | Description |
|---|---|
connect() |
TCP+TLS (implicit TLS, 30s timeout) |
connect_plain() |
Plain TCP (for STARTTLS, 30s timeout) |
start_tls() |
Upgrade plain TCP to TLS (30s timeout) |
is_tls() |
Check if currently using TLS |
is_connected() |
Connection liveness check |
wasm::TlsStream
| Method | Description |
|---|---|
connect() |
TLS through Wisp proxy |
connect_plain() |
Plain TCP through Wisp proxy (for STARTTLS) |
start_tls() |
Upgrade to TLS (epoxy-tls/forge.js handshake) |
trust_host() |
Bypass cert validation for a host (page session) |
is_host_trusted() |
Check if a host is trusted |
is_connected() |
Connection liveness check |
Timeouts
All blocking operations have a 30-second timeout:
- TCP connect (native)
- TLS handshake (native)
- Recv / wait-for-data (both native and WASM)
On timeout, recv returns Ok(Vec::new()) per the Transport contract.
Connect and handshake timeouts return TlsError::Timeout.
Features
| Feature | Dependencies | Target |
|---|---|---|
native |
tokio, tokio-rustls, webpki-roots | Native apps |
wasm |
wasm-bindgen, js-sys | Browsers |
Both features are off by default. Enable exactly one for your target platform.
License
MIT