Skip to content

Commit 91594fa

Browse files
author
Philipp Heckel
committed
Support for underscores in server.yml config options
1 parent db613f8 commit 91594fa

9 files changed

+177
-96
lines changed

cmd/access_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var cmdAccess = &cli.Command{
2626
Usage: "Grant/revoke access to a topic, or show access",
2727
UsageText: "ntfy access [USERNAME [TOPIC [PERMISSION]]]",
2828
Flags: flagsAccess,
29-
Before: initConfigFileInputSource("config", flagsAccess),
29+
Before: initConfigFileInputSourceFunc("config", flagsAccess),
3030
Action: execUserAccess,
3131
Category: categoryServer,
3232
Description: `Manage the access control list for the ntfy server.

cmd/app.go

-21
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
package cmd
33

44
import (
5-
"fmt"
65
"github.com/urfave/cli/v2"
7-
"github.com/urfave/cli/v2/altsrc"
8-
"heckel.io/ntfy/util"
96
"os"
107
)
118

@@ -30,21 +27,3 @@ func New() *cli.App {
3027
Commands: commands,
3128
}
3229
}
33-
34-
// initConfigFileInputSource is like altsrc.InitInputSourceWithContext and altsrc.NewYamlSourceFromFlagFunc, but checks
35-
// if the config flag is exists and only loads it if it does. If the flag is set and the file exists, it fails.
36-
func initConfigFileInputSource(configFlag string, flags []cli.Flag) cli.BeforeFunc {
37-
return func(context *cli.Context) error {
38-
configFile := context.String(configFlag)
39-
if context.IsSet(configFlag) && !util.FileExists(configFile) {
40-
return fmt.Errorf("config file %s does not exist", configFile)
41-
} else if !context.IsSet(configFlag) && !util.FileExists(configFile) {
42-
return nil
43-
}
44-
inputSource, err := altsrc.NewYamlSourceFromFile(configFile)
45-
if err != nil {
46-
return err
47-
}
48-
return altsrc.ApplyInputSourceValues(context, inputSource, flags)
49-
}
50-
}

cmd/config_loader.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"github.com/urfave/cli/v2"
6+
"github.com/urfave/cli/v2/altsrc"
7+
"gopkg.in/yaml.v2"
8+
"heckel.io/ntfy/util"
9+
"os"
10+
)
11+
12+
// initConfigFileInputSourceFunc is like altsrc.InitInputSourceWithContext and altsrc.NewYamlSourceFromFlagFunc, but checks
13+
// if the config flag is exists and only loads it if it does. If the flag is set and the file exists, it fails.
14+
func initConfigFileInputSourceFunc(configFlag string, flags []cli.Flag) cli.BeforeFunc {
15+
return func(context *cli.Context) error {
16+
configFile := context.String(configFlag)
17+
if context.IsSet(configFlag) && !util.FileExists(configFile) {
18+
return fmt.Errorf("config file %s does not exist", configFile)
19+
} else if !context.IsSet(configFlag) && !util.FileExists(configFile) {
20+
return nil
21+
}
22+
inputSource, err := newYamlSourceFromFile(configFile, flags)
23+
if err != nil {
24+
return err
25+
}
26+
return altsrc.ApplyInputSourceValues(context, inputSource, flags)
27+
}
28+
}
29+
30+
// newYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath.
31+
//
32+
// This function also maps aliases, so a .yml file can contain short options, or options with underscores
33+
// instead of dashes. See https://github.com/binwiederhier/ntfy/issues/255.
34+
func newYamlSourceFromFile(file string, flags []cli.Flag) (altsrc.InputSourceContext, error) {
35+
var rawConfig map[interface{}]interface{}
36+
b, err := os.ReadFile(file)
37+
if err != nil {
38+
return nil, err
39+
}
40+
if err := yaml.Unmarshal(b, &rawConfig); err != nil {
41+
return nil, err
42+
}
43+
for _, f := range flags {
44+
flagName := f.Names()[0]
45+
for _, flagAlias := range f.Names()[1:] {
46+
if _, ok := rawConfig[flagAlias]; ok {
47+
rawConfig[flagName] = rawConfig[flagAlias]
48+
}
49+
}
50+
}
51+
return altsrc.NewMapInputSource(file, rawConfig), nil
52+
}

cmd/config_loader_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package cmd
2+
3+
import (
4+
"github.com/stretchr/testify/require"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
)
9+
10+
func TestNewYamlSourceFromFile(t *testing.T) {
11+
filename := filepath.Join(t.TempDir(), "server.yml")
12+
contents := `
13+
# Normal options
14+
listen-https: ":10443"
15+
16+
# Note the underscore!
17+
listen_http: ":1080"
18+
19+
# OMG this is allowed now ...
20+
K: /some/file.pem
21+
`
22+
require.Nil(t, os.WriteFile(filename, []byte(contents), 0600))
23+
24+
ctx, err := newYamlSourceFromFile(filename, flagsServe)
25+
require.Nil(t, err)
26+
27+
listenHTTPS, err := ctx.String("listen-https")
28+
require.Nil(t, err)
29+
require.Equal(t, ":10443", listenHTTPS)
30+
31+
listenHTTP, err := ctx.String("listen-http") // No underscore!
32+
require.Nil(t, err)
33+
require.Equal(t, ":1080", listenHTTP)
34+
35+
keyFile, err := ctx.String("key-file") // Long option!
36+
require.Nil(t, err)
37+
require.Equal(t, "/some/file.pem", keyFile)
38+
}

cmd/serve_linux.go

+36-36
Large diffs are not rendered by default.

cmd/user_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var cmdUser = &cli.Command{
2222
Usage: "Manage/show users",
2323
UsageText: "ntfy user [list|add|remove|change-pass|change-role] ...",
2424
Flags: flagsUser,
25-
Before: initConfigFileInputSource("config", flagsUser),
25+
Before: initConfigFileInputSourceFunc("config", flagsUser),
2626
Category: categoryServer,
2727
Subcommands: []*cli.Command{
2828
{

docs/config.md

+42-37
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,11 @@ Each config option can be set in the config file `/etc/ntfy/server.yml` (e.g. `l
775775
CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment
776776
variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
777777

778+
!!! info
779+
All config options can also be defined in the `server.yml` file using underscores instead of dashes, e.g.
780+
`cache_duration` and `cache-duration` are both supported. This is to support stricter YAML parsers that do
781+
not support dashes.
782+
778783
| Config option | Env variable | Format | Default | Description |
779784
|--------------------------------------------|-------------------------------------------------|-----------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
780785
| `base-url` | `NTFY_BASE_URL` | *URL* | - | Public facing base URL of the service (e.g. `https://ntfy.sh`) |
@@ -839,42 +844,42 @@ DESCRIPTION:
839844
ntfy serve --listen-http :8080 # Starts server with alternate port
840845
841846
OPTIONS:
842-
--config value, -c value config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE]
843-
--base-url value, -B value externally visible base URL for this host (e.g. https://ntfy.sh) [$NTFY_BASE_URL]
844-
--listen-http value, -l value ip:port used to as HTTP listen address (default: ":80") [$NTFY_LISTEN_HTTP]
845-
--listen-https value, -L value ip:port used to as HTTPS listen address [$NTFY_LISTEN_HTTPS]
846-
--listen-unix value, -U value listen on unix socket path [$NTFY_LISTEN_UNIX]
847-
--key-file value, -K value private key file, if listen-https is set [$NTFY_KEY_FILE]
848-
--cert-file value, -E value certificate file, if listen-https is set [$NTFY_CERT_FILE]
849-
--firebase-key-file value, -F value Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
850-
--cache-file value, -C value cache file used for message caching [$NTFY_CACHE_FILE]
851-
--cache-duration since, -b since buffer messages for this time to allow since requests (default: 12h0m0s) [$NTFY_CACHE_DURATION]
852-
--auth-file value, -H value auth database file used for access control [$NTFY_AUTH_FILE]
853-
--auth-default-access value, -p value default permissions if no matching entries in the auth database are found (default: "read-write") [$NTFY_AUTH_DEFAULT_ACCESS]
854-
--attachment-cache-dir value cache directory for attached files [$NTFY_ATTACHMENT_CACHE_DIR]
855-
--attachment-total-size-limit value, -A value limit of the on-disk attachment cache (default: 5G) [$NTFY_ATTACHMENT_TOTAL_SIZE_LIMIT]
856-
--attachment-file-size-limit value, -Y value per-file attachment size limit (e.g. 300k, 2M, 100M) (default: 15M) [$NTFY_ATTACHMENT_FILE_SIZE_LIMIT]
857-
--attachment-expiry-duration value, -X value duration after which uploaded attachments will be deleted (e.g. 3h, 20h) (default: 3h) [$NTFY_ATTACHMENT_EXPIRY_DURATION]
858-
--keepalive-interval value, -k value interval of keepalive messages (default: 45s) [$NTFY_KEEPALIVE_INTERVAL]
859-
--manager-interval value, -m value interval of for message pruning and stats printing (default: 1m0s) [$NTFY_MANAGER_INTERVAL]
860-
--web-root value sets web root to landing page (home) or web app (app) (default: "app") [$NTFY_WEB_ROOT]
861-
--smtp-sender-addr value SMTP server address (host:port) for outgoing emails [$NTFY_SMTP_SENDER_ADDR]
862-
--smtp-sender-user value SMTP user (if e-mail sending is enabled) [$NTFY_SMTP_SENDER_USER]
863-
--smtp-sender-pass value SMTP password (if e-mail sending is enabled) [$NTFY_SMTP_SENDER_PASS]
864-
--smtp-sender-from value SMTP sender address (if e-mail sending is enabled) [$NTFY_SMTP_SENDER_FROM]
865-
--smtp-server-listen value SMTP server address (ip:port) for incoming emails, e.g. :25 [$NTFY_SMTP_SERVER_LISTEN]
866-
--smtp-server-domain value SMTP domain for incoming e-mail, e.g. ntfy.sh [$NTFY_SMTP_SERVER_DOMAIN]
867-
--smtp-server-addr-prefix value SMTP email address prefix for topics to prevent spam (e.g. 'ntfy-') [$NTFY_SMTP_SERVER_ADDR_PREFIX]
868-
--global-topic-limit value, -T value total number of topics allowed (default: 15000) [$NTFY_GLOBAL_TOPIC_LIMIT]
869-
--visitor-subscription-limit value number of subscriptions per visitor (default: 30) [$NTFY_VISITOR_SUBSCRIPTION_LIMIT]
870-
--visitor-attachment-total-size-limit value total storage limit used for attachments per visitor (default: "100M") [$NTFY_VISITOR_ATTACHMENT_TOTAL_SIZE_LIMIT]
871-
--visitor-attachment-daily-bandwidth-limit value total daily attachment download/upload bandwidth limit per visitor (default: "500M") [$NTFY_VISITOR_ATTACHMENT_DAILY_BANDWIDTH_LIMIT]
872-
--visitor-request-limit-burst value initial limit of requests per visitor (default: 60) [$NTFY_VISITOR_REQUEST_LIMIT_BURST]
873-
--visitor-request-limit-replenish value interval at which burst limit is replenished (one per x) (default: 5s) [$NTFY_VISITOR_REQUEST_LIMIT_REPLENISH]
874-
--visitor-request-limit-exempt-hosts value hostnames and/or IP addresses of hosts that will be exempt from the visitor request limit [$NTFY_VISITOR_REQUEST_LIMIT_EXEMPT_HOSTS]
875-
--visitor-email-limit-burst value initial limit of e-mails per visitor (default: 16) [$NTFY_VISITOR_EMAIL_LIMIT_BURST]
876-
--visitor-email-limit-replenish value interval at which burst limit is replenished (one per x) (default: 1h0m0s) [$NTFY_VISITOR_EMAIL_LIMIT_REPLENISH]
877-
--behind-proxy, -P if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting) (default: false) [$NTFY_BEHIND_PROXY]
878-
--help, -h show help (default: false)
847+
--config value, -c value config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE]
848+
--base-url value, --base_url value, -B value externally visible base URL for this host (e.g. https://ntfy.sh) [$NTFY_BASE_URL]
849+
--listen-http value, --listen_http value, -l value ip:port used to as HTTP listen address (default: ":80") [$NTFY_LISTEN_HTTP]
850+
--listen-https value, --listen_https value, -L value ip:port used to as HTTPS listen address [$NTFY_LISTEN_HTTPS]
851+
--listen-unix value, --listen_unix value, -U value listen on unix socket path [$NTFY_LISTEN_UNIX]
852+
--key-file value, --key_file value, -K value private key file, if listen-https is set [$NTFY_KEY_FILE]
853+
--cert-file value, --cert_file value, -E value certificate file, if listen-https is set [$NTFY_CERT_FILE]
854+
--firebase-key-file value, --firebase_key_file value, -F value Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
855+
--cache-file value, --cache_file value, -C value cache file used for message caching [$NTFY_CACHE_FILE]
856+
--cache-duration since, --cache_duration since, -b since buffer messages for this time to allow since requests (default: 12h0m0s) [$NTFY_CACHE_DURATION]
857+
--auth-file value, --auth_file value, -H value auth database file used for access control [$NTFY_AUTH_FILE]
858+
--auth-default-access value, --auth_default_access value, -p value default permissions if no matching entries in the auth database are found (default: "read-write") [$NTFY_AUTH_DEFAULT_ACCESS]
859+
--attachment-cache-dir value, --attachment_cache_dir value cache directory for attached files [$NTFY_ATTACHMENT_CACHE_DIR]
860+
--attachment-total-size-limit value, --attachment_total_size_limit value, -A value limit of the on-disk attachment cache (default: 5G) [$NTFY_ATTACHMENT_TOTAL_SIZE_LIMIT]
861+
--attachment-file-size-limit value, --attachment_file_size_limit value, -Y value per-file attachment size limit (e.g. 300k, 2M, 100M) (default: 15M) [$NTFY_ATTACHMENT_FILE_SIZE_LIMIT]
862+
--attachment-expiry-duration value, --attachment_expiry_duration value, -X value duration after which uploaded attachments will be deleted (e.g. 3h, 20h) (default: 3h) [$NTFY_ATTACHMENT_EXPIRY_DURATION]
863+
--keepalive-interval value, --keepalive_interval value, -k value interval of keepalive messages (default: 45s) [$NTFY_KEEPALIVE_INTERVAL]
864+
--manager-interval value, --manager_interval value, -m value interval of for message pruning and stats printing (default: 1m0s) [$NTFY_MANAGER_INTERVAL]
865+
--web-root value, --web_root value sets web root to landing page (home), web app (app) or disabled (disable) (default: "app") [$NTFY_WEB_ROOT]
866+
--smtp-sender-addr value, --smtp_sender_addr value SMTP server address (host:port) for outgoing emails [$NTFY_SMTP_SENDER_ADDR]
867+
--smtp-sender-user value, --smtp_sender_user value SMTP user (if e-mail sending is enabled) [$NTFY_SMTP_SENDER_USER]
868+
--smtp-sender-pass value, --smtp_sender_pass value SMTP password (if e-mail sending is enabled) [$NTFY_SMTP_SENDER_PASS]
869+
--smtp-sender-from value, --smtp_sender_from value SMTP sender address (if e-mail sending is enabled) [$NTFY_SMTP_SENDER_FROM]
870+
--smtp-server-listen value, --smtp_server_listen value SMTP server address (ip:port) for incoming emails, e.g. :25 [$NTFY_SMTP_SERVER_LISTEN]
871+
--smtp-server-domain value, --smtp_server_domain value SMTP domain for incoming e-mail, e.g. ntfy.sh [$NTFY_SMTP_SERVER_DOMAIN]
872+
--smtp-server-addr-prefix value, --smtp_server_addr_prefix value SMTP email address prefix for topics to prevent spam (e.g. 'ntfy-') [$NTFY_SMTP_SERVER_ADDR_PREFIX]
873+
--global-topic-limit value, --global_topic_limit value, -T value total number of topics allowed (default: 15000) [$NTFY_GLOBAL_TOPIC_LIMIT]
874+
--visitor-subscription-limit value, --visitor_subscription_limit value number of subscriptions per visitor (default: 30) [$NTFY_VISITOR_SUBSCRIPTION_LIMIT]
875+
--visitor-attachment-total-size-limit value, --visitor_attachment_total_size_limit value total storage limit used for attachments per visitor (default: "100M") [$NTFY_VISITOR_ATTACHMENT_TOTAL_SIZE_LIMIT]
876+
--visitor-attachment-daily-bandwidth-limit value, --visitor_attachment_daily_bandwidth_limit value total daily attachment download/upload bandwidth limit per visitor (default: "500M") [$NTFY_VISITOR_ATTACHMENT_DAILY_BANDWIDTH_LIMIT]
877+
--visitor-request-limit-burst value, --visitor_request_limit_burst value initial limit of requests per visitor (default: 60) [$NTFY_VISITOR_REQUEST_LIMIT_BURST]
878+
--visitor-request-limit-replenish value, --visitor_request_limit_replenish value interval at which burst limit is replenished (one per x) (default: 5s) [$NTFY_VISITOR_REQUEST_LIMIT_REPLENISH]
879+
--visitor-request-limit-exempt-hosts value, --visitor_request_limit_exempt_hosts value hostnames and/or IP addresses of hosts that will be exempt from the visitor request limit [$NTFY_VISITOR_REQUEST_LIMIT_EXEMPT_HOSTS]
880+
--visitor-email-limit-burst value, --visitor_email_limit_burst value initial limit of e-mails per visitor (default: 16) [$NTFY_VISITOR_EMAIL_LIMIT_BURST]
881+
--visitor-email-limit-replenish value, --visitor_email_limit_replenish value interval at which burst limit is replenished (one per x) (default: 1h0m0s) [$NTFY_VISITOR_EMAIL_LIMIT_REPLENISH]
882+
--behind-proxy, --behind_proxy, -P if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting) (default: false) [$NTFY_BEHIND_PROXY]
883+
--help, -h show help (default: false)
879884
```
880885

docs/releases.md

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
1111
* [Windows](https://ntfy.sh/docs/install/#windows) and [macOS](https://ntfy.sh/docs/install/#macos) builds for the [ntfy CLI](https://ntfy.sh/docs/subscribe/cli/) ([#112](https://github.com/binwiederhier/ntfy/issues/112))
1212
* Ability to disable the web app entirely ([#238](https://github.com/binwiederhier/ntfy/issues/238)/[#249](https://github.com/binwiederhier/ntfy/pull/249), thanks to [@Curid](https://github.com/Curid))
1313
14+
**Bugs:**
15+
16+
* Support underscores in server.yml config options ([#255](https://github.com/binwiederhier/ntfy/issues/255), thanks to [@ajdelgado](https://github.com/ajdelgado))
17+
1418
**Documentation:**
1519
1620
* Typo in install instructions ([#252](https://github.com/binwiederhier/ntfy/pull/252)/[#251](https://github.com/binwiederhier/ntfy/issues/251), thanks to [@oddlama](https://github.com/oddlama))

server/server.yml

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# ntfy server config file
2+
#
3+
# Please refer to the documentation at https://ntfy.sh/docs/config/ for details.
4+
# All options also support underscores (_) instead of dashes (-) to comply with the YAML spec.
25

36
# Public facing base URL of the service (e.g. https://ntfy.sh or https://ntfy.example.com)
47
# This setting is currently only used by the attachments and e-mail sending feature (outgoing mail only).

0 commit comments

Comments
 (0)