mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Merge pull request #319 from mbanzon/issue-304
parser: Allow use of environment variables in tokens
This commit is contained in:
commit
837ee9f042
2 changed files with 102 additions and 0 deletions
|
@ -71,6 +71,8 @@ func (p *parser) addresses() error {
|
||||||
for {
|
for {
|
||||||
tkn := p.Val()
|
tkn := p.Val()
|
||||||
|
|
||||||
|
tkn = getValFromEnv(tkn)
|
||||||
|
|
||||||
// special case: import directive replaces tokens during parse-time
|
// special case: import directive replaces tokens during parse-time
|
||||||
if tkn == "import" && p.isNewLine() {
|
if tkn == "import" && p.isNewLine() {
|
||||||
err := p.doImport()
|
err := p.doImport()
|
||||||
|
@ -241,6 +243,7 @@ func (p *parser) directive() error {
|
||||||
} else if p.Val() == "}" && nesting == 0 {
|
} else if p.Val() == "}" && nesting == 0 {
|
||||||
return p.Err("Unexpected '}' because no matching opening brace")
|
return p.Err("Unexpected '}' because no matching opening brace")
|
||||||
}
|
}
|
||||||
|
p.tokens[p.cursor].text = getValFromEnv(p.tokens[p.cursor].text)
|
||||||
p.block.Tokens[dir] = append(p.block.Tokens[dir], p.tokens[p.cursor])
|
p.block.Tokens[dir] = append(p.block.Tokens[dir], p.tokens[p.cursor])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,3 +330,26 @@ func (sb serverBlock) HostList() []string {
|
||||||
}
|
}
|
||||||
return sbHosts
|
return sbHosts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getValFromEnv(s string) string {
|
||||||
|
s = replaceEnvReferences(s, "{$", "}")
|
||||||
|
s = replaceEnvReferences(s, "{%", "%}")
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func replaceEnvReferences(s, refStart, refEnd string) string {
|
||||||
|
index := strings.Index(s, refStart)
|
||||||
|
for index != -1 {
|
||||||
|
endIndex := strings.Index(s, refEnd)
|
||||||
|
if endIndex != -1 {
|
||||||
|
ref := s[index : endIndex+len(refEnd)]
|
||||||
|
s = strings.Replace(s, ref, os.Getenv(ref[len(refStart):len(ref)-len(refEnd)]), -1)
|
||||||
|
} else {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
index = strings.Index(s, refStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package parse
|
package parse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -364,6 +365,81 @@ func TestParseAll(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnvironmentReplacement(t *testing.T) {
|
||||||
|
setupParseTests()
|
||||||
|
|
||||||
|
os.Setenv("MY_PORT", "8080")
|
||||||
|
os.Setenv("MY_ADDRESS", "servername.com")
|
||||||
|
os.Setenv("MY_ADDRESS2", "127.0.0.1")
|
||||||
|
|
||||||
|
for i, test := range []struct {
|
||||||
|
input string
|
||||||
|
addresses [][]address // addresses per server block, in order
|
||||||
|
}{
|
||||||
|
{`{$MY_ADDRESS}`, [][]address{
|
||||||
|
{{"servername.com", ""}},
|
||||||
|
}},
|
||||||
|
|
||||||
|
{`{$MY_ADDRESS}:{$MY_PORT}`, [][]address{
|
||||||
|
[]address{{"servername.com", "8080"}},
|
||||||
|
}},
|
||||||
|
|
||||||
|
{`{$MY_ADDRESS2}:1234 {
|
||||||
|
}
|
||||||
|
localhost:{$MY_PORT} {
|
||||||
|
}`, [][]address{
|
||||||
|
[]address{{"127.0.0.1", "1234"}},
|
||||||
|
[]address{{"localhost", "8080"}},
|
||||||
|
}},
|
||||||
|
|
||||||
|
{`{%MY_ADDRESS%}`, [][]address{
|
||||||
|
{{"servername.com", ""}},
|
||||||
|
}},
|
||||||
|
|
||||||
|
{`{%MY_ADDRESS%}:{%MY_PORT%}`, [][]address{
|
||||||
|
[]address{{"servername.com", "8080"}},
|
||||||
|
}},
|
||||||
|
|
||||||
|
{`{%MY_ADDRESS2%}:1234 {
|
||||||
|
}
|
||||||
|
localhost:{%MY_PORT%} {
|
||||||
|
}`, [][]address{
|
||||||
|
[]address{{"127.0.0.1", "1234"}},
|
||||||
|
[]address{{"localhost", "8080"}},
|
||||||
|
}},
|
||||||
|
} {
|
||||||
|
p := testParser(test.input)
|
||||||
|
blocks, err := p.parseAll()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Test %d: Expected no error, but got: %v", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(blocks) != len(test.addresses) {
|
||||||
|
t.Errorf("Test %d: Expected %d server blocks, got %d",
|
||||||
|
i, len(test.addresses), len(blocks))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for j, block := range blocks {
|
||||||
|
if len(block.Addresses) != len(test.addresses[j]) {
|
||||||
|
t.Errorf("Test %d: Expected %d addresses in block %d, got %d",
|
||||||
|
i, len(test.addresses[j]), j, len(block.Addresses))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for k, addr := range block.Addresses {
|
||||||
|
if addr.Host != test.addresses[j][k].Host {
|
||||||
|
t.Errorf("Test %d, block %d, address %d: Expected host to be '%s', but was '%s'",
|
||||||
|
i, j, k, test.addresses[j][k].Host, addr.Host)
|
||||||
|
}
|
||||||
|
if addr.Port != test.addresses[j][k].Port {
|
||||||
|
t.Errorf("Test %d, block %d, address %d: Expected port to be '%s', but was '%s'",
|
||||||
|
i, j, k, test.addresses[j][k].Port, addr.Port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setupParseTests() {
|
func setupParseTests() {
|
||||||
// Set up some bogus directives for testing
|
// Set up some bogus directives for testing
|
||||||
ValidDirectives = map[string]struct{}{
|
ValidDirectives = map[string]struct{}{
|
||||||
|
|
Loading…
Reference in a new issue