Skip to content
CryoCryo home
StdlibNetworking

net

Standing up a TCP server or an HTTP endpoint should not need external dependencies. net provides addressing and sockets at the base, with TLS and the HTTP, HTTP/2, and WebSocket layers on top.

public module net::addr;
public module net::socket;
public module net::dns;
public module net::tls;
public module net::https;
public module net::ws;
public module net::http;
public module net::http2;
ModuleWhat it holds
net::addrIpAddr, SocketAddr, Url
net::socketTcpStream, TcpListener, UdpSocket, and their futures
dnsresolve, lookup, and the async Resolve
net::tlsTlsConnector, TlsAcceptor, TlsStream over OpenSSL
httpsHttpsClient, one-shot requests over TLS
net::httpHTTP/1.1: Request, Response, Router, HttpServer, Client
net::http2HTTP/2 with HPACK: Http2Connection, Http2Client, Http2Server
net::wsWebSocket: WebSocket<S>, Message

net::sys is the per-platform socket shim underneath all of it — BSD sockets on POSIX, Winsock on Windows — and has no page; nothing in it is meant to be called from outside net.

Everything that waits is a future

There is deliberately no blocking connect, accept, read, or write anywhere in net. bind stays a plain call because binding does not wait; every other operation is a future — TcpConnect, TcpAccept, TcpRead, TcpWrite, and their UDP and TLS counterparts — driven by an Executor whose reactor the operation registers with when the socket is not ready.

Each operation owns everything it touches — the socket, and for a read or write the buffer too — and hands it all back in its output rather than borrowing. Cryo has no lifetimes, so a borrowing future could not express "the socket outlives this operation", and a buffer named by a raw pointer into the caller's frame would be written through a stale address once the future is moved between polls. Owning the handle also states the discipline: while an operation is in flight nobody else holds that socket, so two reads cannot interleave on one connection.

In practice you rarely drive these futures by hand. TcpStream and TlsStream implement AsyncTransport, so wrapping one in a BufStream gives you read_line, read_exact, send, and the rest — and that is what the HTTP and WebSocket layers do.

Deliberately out of scope

  • Unix-domain and raw sockets. Easy to add; nothing has needed them.
  • Chunked transfer-encoding and HTTP/1.1 pipelining. The HTTP/1.1 server does keep-alive — persistent connections, read timeouts, Connection: close opt-out — but each request within a connection is still served sequentially.
  • URL percent-decoding and normalisation. net::addr::url returns parts verbatim.