Skip to main content

Crate yawc

Crate yawc 

Source
Expand description

§yawc

WebSocket (RFC 6455) with permessage-deflate compression (RFC 7692). Autobahn compliant. Supports WASM targets.

§Features

  • reqwest: WebSocket via reqwest HTTP client
  • axum: WebSocket extractor for axum
  • http2: WebSockets over HTTP/2 via extended CONNECT (RFC 8441)
  • zlib: Advanced compression with window size control
  • json: JSON serialization support

§Runtime Support

yawc is built on tokio’s I/O traits but can work with other async runtimes through simple adapters. While the library uses tokio internally for its codec and I/O operations, you can integrate it with runtimes like smol, async-std, or others by implementing trait bridges between their I/O traits and tokio’s AsyncRead/AsyncWrite.

See the client_smol.rs example for a complete demonstration of using yawc with the smol runtime.

§Client Example

use futures::{SinkExt, StreamExt};
use yawc::{WebSocket, frame::OpCode};

async fn connect() -> yawc::Result<()> {
    let mut ws = WebSocket::connect("wss://echo.websocket.org".parse()?).await?;

    while let Some(frame) = ws.next().await {
        match frame.opcode() {
            OpCode::Text | OpCode::Binary => ws.send(frame).await?,
            OpCode::Ping => {
                // Pong is sent automatically, but ping is still returned
                // so you can observe it if needed
            }
            _ => {}
        }
    }
    Ok(())
}

§SOCKS5 Proxy

A client connection can be dialled through a SOCKS5 proxy (RFC 1928) by handing the builder a Proxy:

use yawc::{Proxy, WebSocket};

let ws = WebSocket::connect("wss://echo.websocket.org".parse()?)
    .with_proxy(Proxy::socks5("socks5h://user:pass@127.0.0.1:1080".parse()?)?)
    .await?;

socks5h:// leaves the target hostname for the proxy to resolve, socks5:// resolves it locally, and credentials in the URL turn on RFC 1929 username/password authentication. TLS runs end to end through the tunnel, so the proxy sees only ciphertext on a wss:// connection.

§Protocol Handling

yawc automatically handles WebSocket control frames:

  • Ping frames: Automatically responded to with pongs, but still returned to your application
  • Pong frames: Passed through without special handling
  • Close frames: Automatically acknowledged, then returned before closing the connection

§Server Example

use http_body_util::Empty;
use futures::StreamExt;
use hyper::{Request, body::{Incoming, Bytes}, Response};
use yawc::WebSocket;

async fn upgrade(mut req: Request<Incoming>) -> yawc::Result<Response<Empty<Bytes>>> {
    let (response, fut) = WebSocket::upgrade(&mut req)?;

    tokio::spawn(async move {
        if let Ok(mut ws) = fut.await {
            while let Some(frame) = ws.next().await {
                // Process frames
            }
        }
    });

    Ok(response)
}

§WebSockets over HTTP/2

With the http2 feature, connections can be carried over a single HTTP/2 stream using the RFC 8441 extended CONNECT handshake instead of the HTTP/1.1 Upgrade handshake. Only the handshake changes: framing, masking and permessage-deflate are the same.

The client stays on HTTP/1.1 unless asked otherwise, so this changes nothing for existing code. Ask for HTTP/2 explicitly when the server is known to support it:

async fn connect() -> yawc::Result<()> {
    use yawc::{HttpVersion, WebSocket};

    let ws = WebSocket::connect("wss://example.com/chat".parse()?)
        .http_version(HttpVersion::Http2)
        .await?;
    Ok(())
}

There is deliberately no automatic negotiation. Agreeing on h2 over ALPN says the peer speaks HTTP/2, not that it implements RFC 8441, and most deployments serve h2 for ordinary requests while accepting WebSockets over HTTP/1.1 only. Choosing HTTP/2 against such a peer fails rather than silently downgrading, so the choice stays with the caller who knows what the server does. To try HTTP/2 and fall back, see HttpVersion::Http2.

On the server, WebSocket::upgrade handles both handshakes already. The one extra step is calling enable_connect_protocol() on hyper’s HTTP/2 server builder, which is what advertises SETTINGS_ENABLE_CONNECT_PROTOCOL. See the http2_server example.

Modules§

close
codecNon-WebAssembly
codec
frame
Frame
http2http2 and non-WebAssembly
WebSockets over HTTP/2 (RFC 8441).
streamingNon-WebAssembly
Low-level streaming WebSocket layer for manual fragment control.

Structs§

DeflateOptionsNon-WebAssembly
Configuration options for WebSocket message compression using the Deflate algorithm.
FragmentationNon-WebAssembly
Configuration for WebSocket message fragmentation.
IncomingUpgradeaxum
Represents an incoming WebSocket upgrade request that can be converted into a WebSocket connection.
OptionsNon-WebAssembly
Configuration options for a WebSocket connection.
ProxyNon-WebAssembly
A SOCKS5 proxy to dial through.
ReadHalfNon-WebAssembly
The read half of a WebSocket connection, responsible for receiving and processing incoming messages.
UpgradeFutNon-WebAssembly
Future that completes the WebSocket upgrade process on a server, returning a WebSocket stream.
WebSocketNon-WebAssembly
WebSocket stream for both clients and servers.
WebSocketBuilderNon-WebAssembly
Builder for establishing WebSocket connections with customizable options.
WriteHalfNon-WebAssembly
Write half of the WebSocket connection.

Enums§

HttpStreamNon-WebAssembly
An enum representing the underlying WebSocket stream types based on the enabled features.
HttpVersionhttp2
The HTTP version used to carry a WebSocket connection.
MaybeTlsStreamNon-WebAssembly
A stream that might be protected with TLS.
ReplyCodeNon-WebAssembly
The reply code a proxy returns when it refuses a CONNECT (RFC 1928 section 6).
RoleNon-WebAssembly
The role the WebSocket stream is taking.
Socks5ErrorNon-WebAssembly
Everything that can go wrong talking to a SOCKS5 proxy.
WebSocketError
Errors that can occur during WebSocket operations.

Constants§

MAX_PAYLOAD_READNon-WebAssembly
The maximum allowed payload size for reading, set to 1 MiB.
MAX_READ_BUFFERNon-WebAssembly
The maximum allowed read buffer size, set to 2 MiB.

Type Aliases§

CompressionLevelNon-WebAssembly
Type alias for the compression level used in WebSocket compression settings.
HttpRequestNon-WebAssembly
Type alias for HTTP requests used in WebSocket connection handling.
HttpRequestBuilderNon-WebAssembly
Type alias for HTTP request builders used in WebSocket client connection setup.
HttpResponseNon-WebAssembly
Type alias for HTTP responses used during WebSocket upgrade.
HttpWebSocketNon-WebAssembly
Type alias for server-side WebSocket connections from HTTP upgrades or when using reqwest.
Result
Result type for WebSocket operations.
TcpWebSocketNon-WebAssembly
Type alias for WebSocket connections established via connect.
UpgradeResultNon-WebAssembly
The result type returned by WebSocket upgrade operations.