Shorenet protocol fixtures

Endpoints that return a fixed, documented shape, for testing protocol tooling. Every response is deterministic: the same request returns the same bytes.

There are two layers. A hostname fixes the handshake — the transport, the TLS version, the cipher and signature choices, the ALPN. A path selects the exchange that follows. Most paths work on most hostnames, so you can hold one constant and vary the other.

Hostnames — the handshake

Each one presents its own certificate and negotiates exactly what it says.

HostnameNegotiates
lab.shorenet.co.ukThe estate apex: the endpoint list, over HTTP/1.1 or HTTP/2
h1.lab.shorenet.co.ukHTTP/1.1 over TLS 1.3
h2.lab.shorenet.co.ukHTTP/2 over TLS 1.3
ws9573.lab.shorenet.co.uk:9573TLS 1.3 on a non-standard port
resume.lab.shorenet.co.ukTLS 1.3 resumption / 0-RTT
h1.lab.shorenet.co.uk:80Plain HTTP/1.1, no TLS
kex-x25519.lab.shorenet.co.ukgroup X25519
kex-p256.lab.shorenet.co.ukgroup secp256r1
kex-p384.lab.shorenet.co.ukgroup secp384r1
kex-mlkem768.lab.shorenet.co.ukgroup X25519MLKEM768 (post-quantum hybrid; what current Chrome/Edge/Firefox send by default)
kex-hrr.lab.shorenet.co.ukHelloRetryRequest: the server insists on a group the client did not key-share
resume-psk.lab.shorenet.co.ukPSK resumption, no early data
resume-ticket.lab.shorenet.co.ukSession tickets issued on one connection and used on the next
ech-own.lab.shorenet.co.ukECH with keys this server holds; the ECHConfig is published in an HTTPS record
ech-reject.lab.shorenet.co.ukECH offered but rejected, with retry_configs returned
ech-grease.lab.shorenet.co.ukNo real ECH; the client sends GREASE ECH (what Chrome does by default)

Hostnames that speak no HTTP

These negotiate a non-HTTP application protocol, or none at all. After the handshake they echo whatever you send, byte for byte. There are no paths on these.

HostnameNegotiates
noalpn.lab.shorenet.co.ukTLS 1.3, the server selects no ALPN
dot.lab.shorenet.co.ukTLS 1.3, ALPN dot (DNS over TLS, RFC 7858)
alpn.lab.shorenet.co.ukTLS 1.3, a custom non-HTTP ALPN

Paths — the exchange

PathBehaviour
/f/ce-identityHTTP 200, Content-Encoding: identity, 43-byte image/gif.
/f/ce-noneHTTP 200, Content-Encoding: none, same 43-byte body, untransformed.
/f/ce-utf8HTTP 200, Content-Encoding: utf-8, body untransformed. Variants: v626, v7132.
/f/ce-gzipHTTP 200, a correctly gzip-encoded body.
/f/ce-gzip-mislabelledHTTP 200, gzip bytes labelled Content-Encoding: deflate.
/f/status-{code}A bare response at that status. Variants: 200, 204, 206, 304, 404, 500.
/f/bulk-bodyHTTP 200, a large deterministic body. Variants: mb2, mb8, mb32.
/f/sse-trickletext/event-stream, a fixed number of events at a fixed spacing, then the stream held open for 30 s and closed by the server. Set the count with ?n= (1, 5, 20 or 100) and the gap in milliseconds with ?ms= (10, 50, 250 or 1000); any other value is refused with 400.
/f/body-slowHTTP 200, body written one byte at a time, 50 ms apart. Set the length with ?n= (8, 64 or 256 bytes); any other value is refused with 400.
/f/h1-keepalive-gzipIdentical gzip responses (Content-Length 1990, 5430 B decoded) on one keep-alive connection. Request it repeatedly on the same connection.
/f/close-delimited302, Connection: close, no Content-Length and no Transfer-Encoding, empty body, then close_notify then FIN.
/f/ws-echoWebSocket upgrade, then a byte-exact echo.
/f/ws-ce-noneWebSocket upgrade whose 101 carries Content-Encoding: none.
/f/h2-trailersResponse trailers after DATA.
/f/ech-h3HTTP 200, text/plain.
/f/probeHTTP 200, a short deterministic body.