2017-11-16 19:21:02 +01:00
|
|
|
{config, pkgs, lib, ...}:
|
|
|
|
let
|
|
|
|
cfg = config.services.nghttpx;
|
|
|
|
|
|
|
|
# renderHost :: Either ServerOptions Path -> String
|
|
|
|
renderHost = server:
|
|
|
|
if builtins.isString server
|
|
|
|
then "unix://${server}"
|
|
|
|
else "${server.host},${builtins.toString server.port}";
|
|
|
|
|
|
|
|
# Filter out submodule parameters whose value is null or false or is
|
|
|
|
# the key _module.
|
|
|
|
#
|
|
|
|
# filterParams :: ParamsSubmodule -> ParamsSubmodule
|
|
|
|
filterParams = p:
|
|
|
|
lib.filterAttrs
|
|
|
|
(n: v: ("_module" != n) && (null != v) && (false != v))
|
|
|
|
(lib.optionalAttrs (null != p) p);
|
|
|
|
|
|
|
|
# renderBackend :: BackendSubmodule -> String
|
|
|
|
renderBackend = backend:
|
|
|
|
let
|
|
|
|
host = renderHost backend.server;
|
|
|
|
patterns = lib.concatStringsSep ":" backend.patterns;
|
|
|
|
|
|
|
|
# Render a set of backend parameters, this is somewhat
|
|
|
|
# complicated because nghttpx backend patterns can be entirely
|
|
|
|
# omitted and the params may be given as a mixed collection of
|
|
|
|
# 'key=val' pairs or atoms (e.g: 'proto=h2;tls')
|
|
|
|
params =
|
|
|
|
lib.mapAttrsToList
|
|
|
|
(n: v:
|
|
|
|
if builtins.isBool v
|
|
|
|
then n
|
|
|
|
else if builtins.isString v
|
|
|
|
then "${n}=${v}"
|
|
|
|
else "${n}=${builtins.toString v}")
|
|
|
|
(filterParams backend.params);
|
|
|
|
|
|
|
|
# NB: params are delimited by a ";" which is the same delimiter
|
|
|
|
# to separate the host;[pattern];[params] sections of a backend
|
|
|
|
sections =
|
|
|
|
builtins.filter (e: "" != e) ([
|
|
|
|
host
|
|
|
|
patterns
|
|
|
|
]++params);
|
|
|
|
formattedSections = lib.concatStringsSep ";" sections;
|
|
|
|
in
|
|
|
|
"backend=${formattedSections}";
|
|
|
|
|
|
|
|
# renderFrontend :: FrontendSubmodule -> String
|
|
|
|
renderFrontend = frontend:
|
|
|
|
let
|
|
|
|
host = renderHost frontend.server;
|
|
|
|
params0 =
|
|
|
|
lib.mapAttrsToList
|
|
|
|
(n: v: if builtins.isBool v then n else v)
|
|
|
|
(filterParams frontend.params);
|
|
|
|
|
|
|
|
# NB: nghttpx doesn't accept "tls", you must omit "no-tls" for
|
|
|
|
# the default behavior of turning on TLS.
|
|
|
|
params1 = lib.remove "tls" params0;
|
|
|
|
|
|
|
|
sections = [ host] ++ params1;
|
|
|
|
formattedSections = lib.concatStringsSep ";" sections;
|
|
|
|
in
|
|
|
|
"frontend=${formattedSections}";
|
|
|
|
|
|
|
|
configurationFile = pkgs.writeText "nghttpx.conf" ''
|
|
|
|
${lib.optionalString (null != cfg.tls) ("private-key-file="+cfg.tls.key)}
|
|
|
|
${lib.optionalString (null != cfg.tls) ("certificate-file="+cfg.tls.crt)}
|
|
|
|
|
|
|
|
user=nghttpx
|
|
|
|
|
|
|
|
${lib.concatMapStringsSep "\n" renderFrontend cfg.frontends}
|
|
|
|
${lib.concatMapStringsSep "\n" renderBackend cfg.backends}
|
|
|
|
|
|
|
|
backlog=${builtins.toString cfg.backlog}
|
|
|
|
backend-address-family=${cfg.backend-address-family}
|
|
|
|
|
|
|
|
workers=${builtins.toString cfg.workers}
|
|
|
|
rlimit-nofile=${builtins.toString cfg.rlimit-nofile}
|
|
|
|
|
|
|
|
${lib.optionalString cfg.single-thread "single-thread=yes"}
|
|
|
|
${lib.optionalString cfg.single-process "single-process=yes"}
|
|
|
|
|
|
|
|
${cfg.extraConfig}
|
|
|
|
'';
|
|
|
|
in
|
|
|
|
{ imports = [
|
|
|
|
./nghttpx-options.nix
|
|
|
|
];
|
|
|
|
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
|
|
|
|
|
|
users.groups.nghttpx = { };
|
|
|
|
users.users.nghttpx = {
|
|
|
|
group = config.users.groups.nghttpx.name;
|
2019-10-12 22:25:28 +02:00
|
|
|
isSystemUser = true;
|
2017-11-16 19:21:02 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
systemd.services = {
|
|
|
|
nghttpx = {
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
after = [ "network.target" ];
|
|
|
|
script = ''
|
|
|
|
${pkgs.nghttp2}/bin/nghttpx --conf=${configurationFile}
|
|
|
|
'';
|
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
Restart = "on-failure";
|
|
|
|
RestartSec = 60;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|