diff --git a/config/config.go b/config/config.go index dd5eabd72..ae11b4bc7 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,9 @@ func Load(filename string, input io.Reader) (Group, error) { if err != nil { return nil, err } + if len(serverBlocks) == 0 { + return Default() + } // Each server block represents one or more servers/addresses. // Iterate each server block and make a config for each one, diff --git a/config/parse/parsing.go b/config/parse/parsing.go index 43b106d5d..bd903503d 100644 --- a/config/parse/parsing.go +++ b/config/parse/parsing.go @@ -21,7 +21,9 @@ func (p *parser) parseAll() ([]ServerBlock, error) { if err != nil { return blocks, err } - blocks = append(blocks, p.block) + if len(p.block.Addresses) > 0 { + blocks = append(blocks, p.block) + } } return blocks, nil @@ -85,21 +87,23 @@ func (p *parser) addresses() error { break } - // Trailing comma indicates another address will follow, which - // may possibly be on the next line - if tkn[len(tkn)-1] == ',' { - tkn = tkn[:len(tkn)-1] - expectingAnother = true - } else { - expectingAnother = false // but we may still see another one on this line - } + if tkn != "" { + // Trailing comma indicates another address will follow, which + // may possibly be on the next line + if tkn[len(tkn)-1] == ',' { + tkn = tkn[:len(tkn)-1] + expectingAnother = true + } else { + expectingAnother = false // but we may still see another one on this line + } - // Parse and save this address - host, port, err := standardAddress(tkn) - if err != nil { - return err + // Parse and save this address + host, port, err := standardAddress(tkn) + if err != nil { + return err + } + p.block.Addresses = append(p.block.Addresses, Address{host, port}) } - p.block.Addresses = append(p.block.Addresses, Address{host, port}) // Advance token and possibly break out of loop or return error hasNext := p.Next() diff --git a/config/parse/parsing_test.go b/config/parse/parsing_test.go index 0ab353176..8fa55fd60 100644 --- a/config/parse/parsing_test.go +++ b/config/parse/parsing_test.go @@ -61,7 +61,7 @@ func TestParseOneAndImport(t *testing.T) { testParseOne := func(input string) (ServerBlock, error) { p := testParser(input) - p.Next() + p.Next() // parseOne doesn't call Next() to start, so we must err := p.parseOne() return p.block, err } @@ -234,6 +234,10 @@ func TestParseOneAndImport(t *testing.T) { "dir1": 1, "dir2": 2, }}, + + {``, false, []Address{}, map[string]int{}}, + + {`""`, false, []Address{}, map[string]int{}}, } { result, err := testParseOne(test.input) @@ -275,6 +279,62 @@ func TestParseOneAndImport(t *testing.T) { } } +func TestParseAll(t *testing.T) { + setupParseTests() + + testParseAll := func(input string) ([]ServerBlock, error) { + p := testParser(input) + return p.parseAll() + } + + for i, test := range []struct { + input string + shouldErr bool + numBlocks int + }{ + {`localhost`, false, 1}, + + {`localhost { + dir1 + }`, false, 1}, + + {`http://localhost https://localhost + dir1 foo bar`, false, 1}, + + {`http://localhost, https://localhost { + dir1 foo bar + }`, false, 1}, + + {`http://host1.com, + http://host2.com, + https://host3.com`, false, 1}, + + {`host1 { + } + host2 { + }`, false, 2}, + + {`""`, false, 0}, + + {``, false, 0}, + } { + results, err := testParseAll(test.input) + + if test.shouldErr && err == nil { + t.Errorf("Test %d: Expected an error, but didn't get one", i) + } + if !test.shouldErr && err != nil { + t.Errorf("Test %d: Expected no error, but got: %v", i, err) + } + + if len(results) != test.numBlocks { + t.Errorf("Test %d: Expected %d server blocks, got %d", + i, test.numBlocks, len(results)) + continue + } + } +} + func setupParseTests() { // Set up some bogus directives for testing ValidDirectives = map[string]struct{}{