feat: add Nex and Gopher listeners
Reuses md2txt's existing nex and text renderers (both already ship unmodified) -- rendered unwrapped gemtext still works for Gemini/Spartan clients that wrap themselves, but Nex and Gopher clients don't, so those two get the classic 80-column pre-wrap instead. Neither protocol has a redirect status of its own, so Site.resolve_flat() follows the /foo.md -> /foo canonical bounce and the WML-card-only -> parent redirect server-side and hands back real content directly, rather than leaving the two new listeners to invent a redirect convention that doesn't exist on the wire. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
12956a5034
commit
0b67069760
8 changed files with 290 additions and 13 deletions
21
flake.nix
21
flake.nix
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
description = "Serve a folder of Markdown as gemtext, Spartan, WML, and XHTML-MP";
|
||||
description = "Serve a folder of Markdown as gemtext, Nex, Gopher, WML, and XHTML-MP";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
|
@ -93,6 +93,16 @@
|
|||
default = ":8080";
|
||||
description = "HTTP listen address; empty disables it.";
|
||||
};
|
||||
nexAddr = mkOption {
|
||||
type = types.str;
|
||||
default = ":1900";
|
||||
description = "Nex listen address; empty disables it.";
|
||||
};
|
||||
gopherAddr = mkOption {
|
||||
type = types.str;
|
||||
default = ":70";
|
||||
description = "Gopher listen address; empty disables it.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
|
@ -112,12 +122,15 @@
|
|||
++ lib.optionals (cfg.geminiAddr != "") [ "--gemini" cfg.geminiAddr ]
|
||||
++ lib.optionals (cfg.spartanAddr != "") [ "--spartan" cfg.spartanAddr ]
|
||||
++ lib.optionals (cfg.httpAddr != "") [ "--http" cfg.httpAddr ]
|
||||
++ lib.optionals (cfg.nexAddr != "") [ "--nex" cfg.nexAddr ]
|
||||
++ lib.optionals (cfg.gopherAddr != "") [ "--gopher" cfg.gopherAddr ]
|
||||
);
|
||||
DynamicUser = true;
|
||||
StateDirectory = "smolweb";
|
||||
# Spartan's default port (300) and Gemini's TLS handshake
|
||||
# both need this rather than running the whole service as
|
||||
# root -- DynamicUser alone can't bind a privileged port.
|
||||
# Spartan's default port (300), Gopher's default port (70),
|
||||
# and Gemini's TLS handshake all need this rather than
|
||||
# running the whole service as root -- DynamicUser alone
|
||||
# can't bind a privileged port.
|
||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
NoNewPrivileges = true;
|
||||
ProtectSystem = "strict";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue