diff --git a/config/parser.go b/config/parser.go index 61859442f..1c8cc2c87 100644 --- a/config/parser.go +++ b/config/parser.go @@ -19,6 +19,7 @@ type ( other []locationContext // tokens to be 'parsed' later by middleware generators scope *locationContext // the current location context (path scope) being populated unused *token // sometimes a token will be read but not immediately consumed + eof bool // if we encounter a valid EOF in a hard place } // locationContext represents a location context diff --git a/config/parser_test.go b/config/parser_test.go index 43a482aa5..79fe0d3e6 100644 --- a/config/parser_test.go +++ b/config/parser_test.go @@ -211,6 +211,53 @@ func TestParserBasicWithAlternateAddressStyles(t *testing.T) { t.Fatalf("Expected root for conf of %s to be '/test/www', but got: %s", conf.Address(), conf.Root) } } + + p = &parser{filename: "test"} + input = `host:port, http://host:port, http://host, https://host:port, host` + p.lexer.load(strings.NewReader(input)) + + confs, err = p.parse() + if err != nil { + t.Fatalf("Expected no errors, but got '%s'", err) + } + if len(confs) != 5 { + t.Fatalf("Expected 5 configurations, but got %d: %#v", len(confs), confs) + } + + if confs[0].Host != "host" { + t.Errorf("Expected conf[0] Host='host', got '%#v'", confs[0]) + } + if confs[0].Port != "port" { + t.Errorf("Expected conf[0] Port='port', got '%#v'", confs[0]) + } + + if confs[1].Host != "host" { + t.Errorf("Expected conf[1] Host='host', got '%#v'", confs[1]) + } + if confs[1].Port != "port" { + t.Errorf("Expected conf[1] Port='port', got '%#v'", confs[1]) + } + + if confs[2].Host != "host" { + t.Errorf("Expected conf[2] Host='host', got '%#v'", confs[2]) + } + if confs[2].Port != "http" { + t.Errorf("Expected conf[2] Port='http', got '%#v'", confs[2]) + } + + if confs[3].Host != "host" { + t.Errorf("Expected conf[3] Host='host', got '%#v'", confs[3]) + } + if confs[3].Port != "port" { + t.Errorf("Expected conf[3] Port='port', got '%#v'", confs[3]) + } + + if confs[4].Host != "host" { + t.Errorf("Expected conf[4] Host='host', got '%#v'", confs[4]) + } + if confs[4].Port != defaultPort { + t.Errorf("Expected conf[4] Port='%s', got '%#v'", defaultPort, confs[4].Port) + } } func TestParserImport(t *testing.T) { diff --git a/config/parsing.go b/config/parsing.go index 376ccc7d0..aba880dc1 100644 --- a/config/parsing.go +++ b/config/parsing.go @@ -38,18 +38,25 @@ func (p *parser) addresses() error { // address gets host and port in a format accepted by net.Dial address := func(str string) (host, port string, err error) { + var schemePort string + if strings.HasPrefix(str, "https://") { - port = "https" - host = str[8:] - return + schemePort = "https" + str = str[8:] } else if strings.HasPrefix(str, "http://") { - port = "http" - host = str[7:] - return + schemePort = "http" + str = str[7:] } else if !strings.Contains(str, ":") { str += ":" + defaultPort } + host, port, err = net.SplitHostPort(str) + if err != nil && schemePort != "" { + host = str + port = schemePort // assume port from scheme + err = nil + } + return } @@ -88,6 +95,10 @@ func (p *parser) addresses() error { if !expectingAnother && p.line() > startLine { break } + if !hasNext { + p.eof = true + break // EOF + } } return nil @@ -115,6 +126,12 @@ func (p *parser) addressBlock() error { }) p.scope = &p.other[0] + if p.eof { + // this happens if the Caddyfile consists of only + // a line of addresses and nothing else + return nil + } + err := p.directives() if err != nil { return err