HappyGopher Gets Dynamic Pages 2026-07-26 HappyGopher started as a deliberately small static Gopher server: point it at a directory, give it some files and menus, and let it serve them without dragging in a web framework, database, or JavaScript. That still works, but static files can only get you so far. The latest development branch adds dynamic Gopher pages through a small IGopherPage interface. Each page claims an exact selector and writes its response directly to the connection stream. The request flow is now roughly: Client sends selector | v Dynamic page resolver | page found? / \ yes no | | v v Run page Serve static content The first real use of this system is an integration with HappyQOTD, my quote service. HappyGopher now exposes two dynamic selectors: /qotd Returns the current Quote of the Day. /random-quote Requests and returns a random quote. The integration uses a typed HttpClient to call the HappyQOTD HTTP API. The Gopher page then converts the returned data into an ordinary type-0 text response containing the quote, author, and source. In other words, the path looks like this: Gopher client -> HappyGopher -> HappyQOTD HTTP API -> JSON -> Gopher text -> terminating dot -> client This is all controlled by configuration. If the HappyQOTD integration is disabled, its client and pages are not registered. If enabled, HappyGopher validates the base URL and timeout during startup before permitting the service to operate. The implementation also handles an unavailable API, missing quotes, request timeouts, multiline text, CRLF wire formatting, and dot-stuffing for lines that begin with a period. I tested the new pages using multiple independent Gopher clients. Gophie correctly displayed the generated pages and consumed the terminating dot. Another simpler client displayed the raw terminator, which was useful for confirming what was actually transmitted over the wire. The result is not a web page awkwardly exposed through Gopher. To the client, it is just another normal Gopher document. That is the part I like. HappyGopher can remain a small static server while gaining optional dynamic resources and external integrations without turning into a giant application framework. The dynamic-page contract is tiny, the static-content fallback is unchanged, and future integrations can follow the same pattern. So yes, I am now using dependency injection, options validation, typed HTTP clients, async I/O, telemetry, and dynamic routing to return approximately 132 bytes of plain text followed by a dot. .