summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Lavoie <lavofr@gmail.com>2020-06-01 12:43:06 -0400
committerGitHub <noreply@github.com>2020-06-01 10:43:06 -0600
commitfdf2a77feb53cb9dd6de772f811e96a5f6b2d2c4 (patch)
tree9dc596a40de9c076519eed900c1791aabe65f52b
parenta496308f6eb57f8dd2e1598bfb624a3e567aa4e1 (diff)
caddyfile: Add args on imports (#3423)
* caddyfile: Add support for args on imports * caddyfile: Add more import args tests
-rwxr-xr-xcaddyconfig/caddyfile/parse.go33
-rwxr-xr-xcaddyconfig/caddyfile/parse_test.go8
-rw-r--r--caddyconfig/caddyfile/testdata/import_args0.txt1
-rw-r--r--caddyconfig/caddyfile/testdata/import_args1.txt1
-rw-r--r--caddytest/integration/caddyfile_adapt/import_args_file.txt49
-rw-r--r--caddytest/integration/caddyfile_adapt/import_args_snippet.txt83
-rw-r--r--caddytest/integration/testdata/import_respond.txt1
7 files changed, 168 insertions, 8 deletions
diff --git a/caddyconfig/caddyfile/parse.go b/caddyconfig/caddyfile/parse.go
index cdcac26..5cb5b68 100755
--- a/caddyconfig/caddyfile/parse.go
+++ b/caddyconfig/caddyfile/parse.go
@@ -20,7 +20,10 @@ import (
"log"
"os"
"path/filepath"
+ "strconv"
"strings"
+
+ "github.com/caddyserver/caddy/v2"
)
// Parse parses the input just enough to group tokens, in
@@ -292,11 +295,19 @@ func (p *parser) doImport() error {
if importPattern == "" {
return p.Err("Import requires a non-empty filepath")
}
- if p.NextArg() {
- return p.Err("Import takes only one argument (glob pattern or file)")
+
+ // grab remaining args as placeholder replacements
+ args := p.RemainingArgs()
+
+ // add args to the replacer
+ repl := caddy.NewReplacer()
+ for index, arg := range args {
+ repl.Set("args."+strconv.Itoa(index), arg)
}
- // splice out the import directive and its argument (2 tokens total)
- tokensBefore := p.tokens[:p.cursor-1]
+
+ // splice out the import directive and its arguments
+ // (2 tokens, plus the length of args)
+ tokensBefore := p.tokens[:p.cursor-1-len(args)]
tokensAfter := p.tokens[p.cursor+1:]
var importedTokens []Token
@@ -348,10 +359,20 @@ func (p *parser) doImport() error {
}
}
+ // copy the tokens so we don't overwrite p.definedSnippets
+ tokensCopy := make([]Token, len(importedTokens))
+ copy(tokensCopy, importedTokens)
+
+ // run the argument replacer on the tokens
+ for index, token := range tokensCopy {
+ token.Text = repl.ReplaceKnown(token.Text, "")
+ tokensCopy[index] = token
+ }
+
// splice the imported tokens in the place of the import statement
// and rewind cursor so Next() will land on first imported token
- p.tokens = append(tokensBefore, append(importedTokens, tokensAfter...)...)
- p.cursor--
+ p.tokens = append(tokensBefore, append(tokensCopy, tokensAfter...)...)
+ p.cursor -= len(args) + 1
return nil
}
diff --git a/caddyconfig/caddyfile/parse_test.go b/caddyconfig/caddyfile/parse_test.go
index ed15367..12c30c8 100755
--- a/caddyconfig/caddyfile/parse_test.go
+++ b/caddyconfig/caddyfile/parse_test.go
@@ -182,14 +182,17 @@ func TestParseOneAndImport(t *testing.T) {
"host1",
}, []int{1, 2}},
- {`import testdata/import_test1.txt testdata/import_test2.txt`, true, []string{}, []int{}},
-
{`import testdata/not_found.txt`, true, []string{}, []int{}},
{`""`, false, []string{}, []int{}},
{``, false, []string{}, []int{}},
+ // import with args
+ {`import testdata/import_args0.txt a`, false, []string{"a"}, []int{}},
+ {`import testdata/import_args1.txt a b`, false, []string{"a", "b"}, []int{}},
+ {`import testdata/import_args*.txt a b`, false, []string{"a"}, []int{2}},
+
// test cases found by fuzzing!
{`import }{$"`, true, []string{}, []int{}},
{`import /*/*.txt`, true, []string{}, []int{}},
@@ -210,6 +213,7 @@ func TestParseOneAndImport(t *testing.T) {
t.Errorf("Test %d: Expected no error, but got: %v", i, err)
}
+ // t.Logf("%+v\n", result)
if len(result.Keys) != len(test.keys) {
t.Errorf("Test %d: Expected %d keys, got %d",
i, len(test.keys), len(result.Keys))
diff --git a/caddyconfig/caddyfile/testdata/import_args0.txt b/caddyconfig/caddyfile/testdata/import_args0.txt
new file mode 100644
index 0000000..af946fe
--- /dev/null
+++ b/caddyconfig/caddyfile/testdata/import_args0.txt
@@ -0,0 +1 @@
+{args.0} \ No newline at end of file
diff --git a/caddyconfig/caddyfile/testdata/import_args1.txt b/caddyconfig/caddyfile/testdata/import_args1.txt
new file mode 100644
index 0000000..519a92d
--- /dev/null
+++ b/caddyconfig/caddyfile/testdata/import_args1.txt
@@ -0,0 +1 @@
+{args.0} {args.1} \ No newline at end of file
diff --git a/caddytest/integration/caddyfile_adapt/import_args_file.txt b/caddytest/integration/caddyfile_adapt/import_args_file.txt
new file mode 100644
index 0000000..6947f68
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/import_args_file.txt
@@ -0,0 +1,49 @@
+example.com
+
+import testdata/import_respond.txt Groot Rocket
+import testdata/import_respond.txt you "the confused man"
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":443"
+ ],
+ "routes": [
+ {
+ "match": [
+ {
+ "host": [
+ "example.com"
+ ]
+ }
+ ],
+ "handle": [
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "handle": [
+ {
+ "body": "'I am Groot', hears Rocket",
+ "handler": "static_response"
+ },
+ {
+ "body": "'I am you', hears the confused man",
+ "handler": "static_response"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "terminal": true
+ }
+ ]
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/caddytest/integration/caddyfile_adapt/import_args_snippet.txt b/caddytest/integration/caddyfile_adapt/import_args_snippet.txt
new file mode 100644
index 0000000..8d2ff34
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/import_args_snippet.txt
@@ -0,0 +1,83 @@
+(logging) {
+ log {
+ output file /var/log/caddy/{args.0}.access.log
+ }
+}
+
+a.example.com {
+ import logging a.example.com
+}
+
+b.example.com {
+ import logging b.example.com
+}
+----------
+{
+ "logging": {
+ "logs": {
+ "default": {
+ "exclude": [
+ "http.log.access.log0",
+ "http.log.access.log1"
+ ]
+ },
+ "log0": {
+ "writer": {
+ "filename": "/var/log/caddy/a.example.com.access.log",
+ "output": "file"
+ },
+ "include": [
+ "http.log.access.log0"
+ ]
+ },
+ "log1": {
+ "writer": {
+ "filename": "/var/log/caddy/b.example.com.access.log",
+ "output": "file"
+ },
+ "include": [
+ "http.log.access.log1"
+ ]
+ }
+ }
+ },
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":443"
+ ],
+ "routes": [
+ {
+ "match": [
+ {
+ "host": [
+ "a.example.com"
+ ]
+ }
+ ],
+ "terminal": true
+ },
+ {
+ "match": [
+ {
+ "host": [
+ "b.example.com"
+ ]
+ }
+ ],
+ "terminal": true
+ }
+ ],
+ "logs": {
+ "logger_names": {
+ "a.example.com": "log0",
+ "b.example.com": "log1"
+ }
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/caddytest/integration/testdata/import_respond.txt b/caddytest/integration/testdata/import_respond.txt
new file mode 100644
index 0000000..0907fbe
--- /dev/null
+++ b/caddytest/integration/testdata/import_respond.txt
@@ -0,0 +1 @@
+respond "'I am {args.0}', hears {args.1}" \ No newline at end of file