infrastructure/modules/nixos/nginx/xvars.nix
2024-04-22 15:10:32 -07:00

114 lines
3.5 KiB
Nix

let
locationModule = { config, virtualHost, lib, ... }: let
inherit (lib.options) mkEnableOption;
cfg = config.xvars;
in {
options.xvars = with lib.types; {
enable = mkEnableOption "$x_variables";
};
config = let
in {
};
};
hostModule = { config, nixosConfig, gensokyo-zone, xvars, lib, ... }: let
inherit (gensokyo-zone.lib) mkJustBefore;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
inherit (lib.strings) concatStringsSep;
inherit (lib.attrsets) attrValues filterAttrs mapAttrs mapAttrsToList;
inherit (lib.lists) any;
cfg = config.xvars;
escapeString = value: if value == "" then ''""'' else toString value;
in {
options = with lib.types; {
xvars = {
enable = mkEnableOption "$x_variables";
parseReferer = mkEnableOption "$x_referer_{scheme,host,path}";
defaults = mkOption {
type = attrsOf (nullOr str);
default = rec {
scheme = "$scheme";
forwarded_for = remote_addr;
remote_addr = "$remote_addr";
forwarded_server = host;
host = "$host";
referer = "$http_referer";
https = "$https";
proxy_host = "$proxy_host";
proxy_port = "$proxy_port";
proxy_hostport = "${proxy_host}:${proxy_port}";
proxy_scheme = null;
};
};
lib = mkOption {
type = attrs;
};
};
locations = mkOption {
type = attrsOf (submoduleWith {
modules = [ locationModule ];
shorthandOnlyDefinesConfig = true;
specialArgs = {
inherit nixosConfig gensokyo-zone xvars;
virtualHost = config;
};
});
};
};
config = let
defaults = concatStringsSep "\n" (mapAttrsToList (
name: value: "set $x_${name} ${escapeString value};"
) (filterAttrs (_: value: value != null) cfg.defaults));
parseReferer = ''
set $hack_referer $http_referer;
if ($hack_referer ~ "^(https?)://([^/]+)(/.*)$") {
${xvars.init "referer_scheme" "$1"}
${xvars.init "referer_host" "$2"}
${xvars.init "referer_path" "$3"}
}
'';
in {
xvars = {
enable = mkMerge [
(mkIf (any (loc: loc.xvars.enable) (attrValues config.locations)) true)
(mkIf cfg.parseReferer true)
];
defaults = mkIf cfg.parseReferer (mkOptionDefault {
referer_scheme = null;
referer_host = null;
referer_path = null;
});
lib = {
get = mapAttrs (name: default: if cfg.enable then "$x_${name}" else assert default != null; default) cfg.defaults;
init = name: value: assert cfg.enable && cfg.defaults ? ${name}; "set $x_${name} ${escapeString value};";
inherit escapeString;
};
};
extraConfig = mkMerge [
(mkIf cfg.enable (mkJustBefore defaults))
(mkIf (cfg.enable && cfg.parseReferer) (mkJustBefore parseReferer))
];
_module.args.xvars = config.xvars.lib;
};
};
in {
config,
lib,
gensokyo-zone,
...
}: let
inherit (lib.options) mkOption;
in {
options = with lib.types; {
services.nginx.virtualHosts = mkOption {
type = attrsOf (submoduleWith {
modules = [ hostModule ];
shorthandOnlyDefinesConfig = true;
specialArgs = {
inherit gensokyo-zone;
nixosConfig = config;
};
});
};
};
}