diff --git a/caddyfile/parse.go b/caddyfile/parse.go index b136b0c0..be44fc8a 100644 --- a/caddyfile/parse.go +++ b/caddyfile/parse.go @@ -260,7 +260,9 @@ func (p *parser) doImport() error { } if token.Line == importLine { var abs string - if !filepath.IsAbs(importFile) { + if filepath.IsAbs(token.Text) { + abs = token.Text + } else if !filepath.IsAbs(importFile) { abs = filepath.Join(filepath.Dir(absFile), token.Text) } else { abs = filepath.Join(importDir, token.Text) diff --git a/caddyfile/parse_test.go b/caddyfile/parse_test.go index 1e0ca2d2..58d4e8e6 100644 --- a/caddyfile/parse_test.go +++ b/caddyfile/parse_test.go @@ -1,7 +1,9 @@ package caddyfile import ( + "io/ioutil" "os" + "path/filepath" "strings" "testing" ) @@ -249,6 +251,101 @@ func TestParseOneAndImport(t *testing.T) { } } +func TestRecursiveImport(t *testing.T) { + testParseOne := func(input string) (ServerBlock, error) { + p := testParser(input) + p.Next() // parseOne doesn't call Next() to start, so we must + err := p.parseOne() + return p.block, err + } + + isExpected := func(got ServerBlock) bool { + if len(got.Keys) != 1 || got.Keys[0] != "localhost" { + t.Errorf("got keys unexpected: expect localhost, got %v", got.Keys) + return false + } + if len(got.Tokens) != 2 { + t.Errorf("got wrong number of tokens: expect 2, got %d", len(got.Tokens)) + return false + } + if len(got.Tokens["dir1"]) != 1 || len(got.Tokens["dir2"]) != 2 { + t.Errorf("got unexpect tokens: %v", got.Tokens) + return false + } + return true + } + + recursive_file1, err := filepath.Abs("testdata/recursive_import_test1") + if err != nil { + t.Fatal(err) + } + recursive_file2, err := filepath.Abs("testdata/recursive_import_test2") + if err != nil { + t.Fatal(err) + } + + // test relative recursive import + err = ioutil.WriteFile(recursive_file1, []byte( + `localhost + dir1 + import recursive_import_test2`), 0644) + if err != nil { + t.Fatal(err) + } + defer os.Remove(recursive_file1) + + err = ioutil.WriteFile(recursive_file2, []byte("dir2 1"), 0644) + if err != nil { + t.Fatal(err) + } + defer os.Remove(recursive_file2) + + // import absolute path + result, err := testParseOne("import " + recursive_file1) + if err != nil { + t.Fatal(err) + } + if !isExpected(result) { + t.Error("absolute+relative import failed") + } + + // import relative path + result, err = testParseOne("import testdata/recursive_import_test1") + if err != nil { + t.Fatal(err) + } + if !isExpected(result) { + t.Error("relative+relative import failed") + } + + // test absolute recursive import + err = ioutil.WriteFile(recursive_file1, []byte( + `localhost + dir1 + import `+recursive_file2), 0644) + if err != nil { + t.Fatal(err) + } + + // import absolute path + result, err = testParseOne("import " + recursive_file1) + if err != nil { + t.Fatal(err) + } + if !isExpected(result) { + t.Error("absolute+absolute import failed") + } + + // import relative path + result, err = testParseOne("import testdata/recursive_import_test1") + if err != nil { + t.Fatal(err) + } + if !isExpected(result) { + t.Error("relative+absolute import failed") + } +} + func TestParseAll(t *testing.T) { for i, test := range []struct { input string