tvl-depot/users/tazjin/cursed/responder.nix
sterni d47c7fa12b feat(sterni/nix/html): make <html> also emit doctype
This makes the awkward withDoctype utility obsolete which is much nicer.
Technically, this is a BREAKING CHANGE since it was possible to create
valid documents without an <html> tag before:

    withDoctype (lib.concatStrings [ (<head> { } …) (<body> { } …) ])

I don't think this usecase is worth preserving since this can just be
written as

    <html> { } [ (<head> { } …) (<body> { } …) ]

and omitting the <html> tag is not recommended since it should be used
to set the language of the document (which we didn't in the example
above).

Change-Id: Idc5104ce88fe8bee965c076229b79387915c3605
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12907
Autosubmit: sterni <sternenseemann@systemli.org>
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
2024-12-31 09:03:37 +00:00

75 lines
1.8 KiB
Nix

{ depot, ... }:
let
inherit (depot.users.sterni.nix.html)
__findFile
esc
;
# CGI envvars: https://www.instanet.com/cgi/env.html
method = builtins.getEnv "REQUEST_METHOD";
path = builtins.getEnv "PATH_INFO";
rawQuery = builtins.getEnv "QUERY_STRING";
query = with builtins; let
pairs = (filter (s: isString s && s != "") (split "&" rawQuery));
tuples = filter (l: length l > 0) (map (p: filter (s: isString s) (split "=" p)) pairs);
mkAttr = t: {
name = elemAt t 0;
value = elemAt t 1;
};
in
listToAttrs (map mkAttr tuples);
default = let {
hasQuery = if builtins.length (builtins.attrNames query) > 0 then "?" else "";
body = <html> { lang = "en"; } [
(<head> { } [
(<title> { } "some cursed nix")
])
(<body> { } [
(<p> { } "hello volgasprint")
(<p> { } [ method " " path hasQuery rawQuery ])
(<p> { } (builtins.toJSON query))
])
];
};
greeter = withDoctype (<html> { lang = "en"; } [
(<head> { } [
(<title> { } "hello there")
])
(<body> { } [
(<p> { } "hello ${query.name or "unknown"}")
])
]);
weather = let {
town = query.town or "Kazan";
w = builtins.fetchurl "https://wttr.in/${town}?";
rendered = with depot.third_party.nixpkgs; runCommand "weather-${town}" { } ''
cat ${w} | ${ansi2html}/bin/ansi2html > $out
'';
body = builtins.readFile "${rendered}";
};
routes = {
"/other" = (withDoctype (<html> { lang = "en"; } [
(<head> { } [
(<title> { } "other endpoint")
])
(<body> { } [
(<p> { } "this is another route")
])
]));
"/greeter" = greeter;
"/weather" = weather;
}."${path}" or default;
in
depot.web.bubblegum.respond "OK"
{
"Content-Type" = "text/html";
}
routes