Each subdirectory is a self-contained Pony program demonstrating a different part of the stallion library. Ordered from simplest to most involved.
Greeting server that responds with "Hello, World!" by default, or "Hello, {name}!" when a ?name=X query parameter is provided. Demonstrates the core API: a listener actor implements lori.TCPListenerActor, creates connection actors in _on_accept, and each connection actor uses HTTPServerActor, HTTPServer, Request, Responder, ResponseBuilder, and ServerConfig. Start here if you're new to the library.
HTTP server that handles HEAD correctly: a GET gets a body, a HEAD gets the same headers, including Content-Length, with no body. Demonstrates branching on Request.method and building a response that omits the body chunk for HEAD. Stallion sends exactly what the handler builds and never rewrites a response, so suppressing the body is the handler's responsibility.
Visit counter that reads the visits cookie from incoming requests, increments it, and sets it back via Set-Cookie. Demonstrates both Request.cookies for reading cookies parsed from request headers and SetCookieBuilder for building validated Set-Cookie response headers with secure defaults.
Content negotiation server that responds with JSON or plain text based on the client's Accept header. Returns 406 Not Acceptable when the client doesn't accept either format. Demonstrates ContentNegotiation.from_request() for selecting a response content type and matching on ContentNegotiationResult.
HTTPS server using SSL/TLS. Demonstrates creating an SSLContext, loading certificate and key files, and passing the context to connection actors via _on_accept. Actors use HTTPServer.ssl instead of HTTPServer to create an HTTPS connection.
Request processing deadline that sets a 5-second timer then delegates to a worker actor. If the worker responds before the deadline, the timer is cancelled and the result is sent. If the deadline fires first, the server responds with 408 Request Timeout. Demonstrates HTTPServer.set_timer(), HTTPServer.cancel_timer(), and on_timer() on HTTPServerLifecycleEventReceiver in a deadline pattern.
Streams responses using chunked transfer encoding with flow-controlled delivery driven by on_chunk_sent() callbacks. Demonstrates matching on StartChunkedResponseResult from start_chunked_response(), then using send_chunk(), finish_response(), and on_chunk_sent() on Responder and HTTPServerLifecycleEventReceiver. The actor sends the first chunk in on_request(), then each on_chunk_sent() callback triggers the next chunk — natural backpressure without timers or manual windowing.
Reads a small amount from each connection before handing the scheduler back. Demonstrates setting read_buffer_size on ServerConfig. A connection reads up to that many bytes in one scheduler turn and then queues itself to continue later, which is what bounds how much work one busy connection does per turn.