@marcel91200 / caddy Mirror · read-only / commits / c6dec305
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

caddyfile: Add support for env var defaults; add tests (#3682)

* caddyfile: Add support for env var defaults, tests * caddyfile: Use ?? instead, fix redundant cast, remove env chaining * caddyfile: Use : instead

Francis Lavoie committed Nov 23, 2020 at 14:51 UTC c6dec305357868ec9ba7fbc45e6cb70404cc23a6
2 files changed +36 -6
caddyconfig/caddyfile/parse.go
+19 -6
@@ -60,21 +60,31 @@ func replaceEnvVars(input []byte) ([]byte, error) {
60 end += begin + len(spanOpen) // make end relative to input, not begin
61
62 // get the name; if there is no name, skip it
63 - envVarName := input[begin+len(spanOpen) : end]
64 - if len(envVarName) == 0 {
63 + envString := input[begin+len(spanOpen) : end]
64 + if len(envString) == 0 {
65 offset = end + len(spanClose)
66 continue
67 }
68
69 + // split the string into a key and an optional default
70 + envParts := strings.SplitN(string(envString), envVarDefaultDelimiter, 2)
71 +
72 + // do a lookup for the env var, replace with the default if not found
73 + envVarValue, found := os.LookupEnv(envParts[0])
74 + if !found && len(envParts) == 2 {
75 + envVarValue = envParts[1]
76 + }
77 +
78 // get the value of the environment variable
70 - envVarValue := []byte(os.ExpandEnv(os.Getenv(string(envVarName))))
79 + // note that this causes one-level deep chaining
80 + envVarBytes := []byte(envVarValue)
81
82 // splice in the value
83 input = append(input[:begin],
74 - append(envVarValue, input[end+len(spanClose):]...)...)
84 + append(envVarBytes, input[end+len(spanClose):]...)...)
85
86 // continue at the end of the replacement
77 - offset = begin + len(envVarValue)
87 + offset = begin + len(envVarBytes)
88 }
89 return input, nil
90 }
@@ -548,4 +558,7 @@ func (s Segment) Directive() string {
558
559 // spanOpen and spanClose are used to bound spans that
560 // contain the name of an environment variable.
551 -var spanOpen, spanClose = []byte{'{', '$'}, []byte{'}'}
561 +var (
562 + spanOpen, spanClose = []byte{'{', '$'}, []byte{'}'}
563 + envVarDefaultDelimiter = ":"
564 +)
caddyconfig/caddyfile/parse_test.go
+17
@@ -478,6 +478,7 @@ func TestParseAll(t *testing.T) {
478
479 func TestEnvironmentReplacement(t *testing.T) {
480 os.Setenv("FOOBAR", "foobar")
481 + os.Setenv("CHAINED", "$FOOBAR")
482
483 for i, test := range []struct {
484 input string
@@ -523,6 +524,22 @@ func TestEnvironmentReplacement(t *testing.T) {
524 input: "{$FOOBAR}{$FOOBAR}",
525 expect: "foobarfoobar",
526 },
527 + {
528 + input: "{$CHAINED}",
529 + expect: "$FOOBAR", // should not chain env expands
530 + },
531 + {
532 + input: "{$FOO:default}",
533 + expect: "default",
534 + },
535 + {
536 + input: "foo{$BAR:bar}baz",
537 + expect: "foobarbaz",
538 + },
539 + {
540 + input: "foo{$BAR:$FOOBAR}baz",
541 + expect: "foo$FOOBARbaz", // should not chain env expands
542 + },
543 {
544 input: "{$FOOBAR",
545 expect: "{$FOOBAR",