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",