mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 06:03:48 +03:00
caddyfile: Refactor; NewFromNextSegment(); fix repeated matchers
Now multiple instances of the same matcher can be used within a named matcher without overwriting previous ones.
This commit is contained in:
parent
eb80165583
commit
15bf9c196c
8 changed files with 76 additions and 13 deletions
|
@ -249,13 +249,20 @@ func (d *Dispenser) RemainingArgs() []string {
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFromNextTokens returns a new dispenser with a copy of
|
// NewFromNextSegment returns a new dispenser with a copy of
|
||||||
// the tokens from the current token until the end of the
|
// the tokens from the current token until the end of the
|
||||||
// "directive" whether that be to the end of the line or
|
// "directive" whether that be to the end of the line or
|
||||||
// the end of a block that starts at the end of the line;
|
// the end of a block that starts at the end of the line;
|
||||||
// in other words, until the end of the segment.
|
// in other words, until the end of the segment.
|
||||||
func (d *Dispenser) NewFromNextTokens() *Dispenser {
|
func (d *Dispenser) NewFromNextSegment() *Dispenser {
|
||||||
tkns := []Token{d.Token()}
|
return NewDispenser(d.NextSegment())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextSegment returns a copy of the tokens from the current
|
||||||
|
// token until the end of the line or block that starts at
|
||||||
|
// the end of the line.
|
||||||
|
func (d *Dispenser) NextSegment() Segment {
|
||||||
|
tkns := Segment{d.Token()}
|
||||||
for d.NextArg() {
|
for d.NextArg() {
|
||||||
tkns = append(tkns, d.Token())
|
tkns = append(tkns, d.Token())
|
||||||
}
|
}
|
||||||
|
@ -282,7 +289,7 @@ func (d *Dispenser) NewFromNextTokens() *Dispenser {
|
||||||
// next iteration of the enclosing loop will
|
// next iteration of the enclosing loop will
|
||||||
// call Next() and consume it
|
// call Next() and consume it
|
||||||
}
|
}
|
||||||
return NewDispenser(tkns)
|
return tkns
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token returns the current token.
|
// Token returns the current token.
|
||||||
|
|
|
@ -368,7 +368,7 @@ func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
subHelper := h
|
subHelper := h
|
||||||
subHelper.Dispenser = h.NewFromNextTokens()
|
subHelper.Dispenser = h.NewFromNextSegment()
|
||||||
|
|
||||||
results, err := dirFunc(subHelper)
|
results, err := dirFunc(subHelper)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -401,7 +401,7 @@ func parseHandle(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
subHelper := h
|
subHelper := h
|
||||||
subHelper.Dispenser = h.NewFromNextTokens()
|
subHelper.Dispenser = h.NewFromNextSegment()
|
||||||
|
|
||||||
results, err := dirFunc(subHelper)
|
results, err := dirFunc(subHelper)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -751,8 +751,16 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
|
||||||
}
|
}
|
||||||
matchers[definitionName] = make(caddy.ModuleMap)
|
matchers[definitionName] = make(caddy.ModuleMap)
|
||||||
|
|
||||||
|
// in case there are multiple instances of the same matcher, concatenate
|
||||||
|
// their tokens (we expect that UnmarshalCaddyfile should be able to
|
||||||
|
// handle more than one segment); otherwise, we'd overwrite other
|
||||||
|
// instances of the matcher in this set
|
||||||
|
tokensByMatcherName := make(map[string][]caddyfile.Token)
|
||||||
for nesting := d.Nesting(); d.NextBlock(nesting); {
|
for nesting := d.Nesting(); d.NextBlock(nesting); {
|
||||||
matcherName := d.Val()
|
matcherName := d.Val()
|
||||||
|
tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...)
|
||||||
|
}
|
||||||
|
for matcherName, tokens := range tokensByMatcherName {
|
||||||
mod, err := caddy.GetModule("http.matchers." + matcherName)
|
mod, err := caddy.GetModule("http.matchers." + matcherName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting matcher module '%s': %v", matcherName, err)
|
return fmt.Errorf("getting matcher module '%s': %v", matcherName, err)
|
||||||
|
@ -761,7 +769,7 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
|
return fmt.Errorf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
|
||||||
}
|
}
|
||||||
err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
|
err = unm.UnmarshalCaddyfile(caddyfile.NewDispenser(tokens))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,54 @@
|
||||||
package httpcaddyfile
|
package httpcaddyfile
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServerType(t *testing.T) {
|
||||||
|
for i, tc := range []struct {
|
||||||
|
input string
|
||||||
|
expectWarn bool
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
input: `http://localhost
|
||||||
|
@debug {
|
||||||
|
query showdebug=1
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expectWarn: false,
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: `http://localhost
|
||||||
|
@debug {
|
||||||
|
query bad format
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expectWarn: false,
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
|
||||||
|
adapter := caddyfile.Adapter{
|
||||||
|
ServerType: ServerType{},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, warnings, err := adapter.Adapt([]byte(tc.input), nil)
|
||||||
|
|
||||||
|
if len(warnings) > 0 != tc.expectWarn {
|
||||||
|
t.Errorf("Test %d warning expectation failed Expected: %v, got %v", i, tc.expectWarn, warnings)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil != tc.expectError {
|
||||||
|
t.Errorf("Test %d error expectation failed Expected: %v, got %s", i, tc.expectError, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSpecificity(t *testing.T) {
|
func TestSpecificity(t *testing.T) {
|
||||||
for i, tc := range []struct {
|
for i, tc := range []struct {
|
||||||
|
|
|
@ -151,7 +151,7 @@ func parseOptStorage(d *caddyfile.Dispenser) (caddy.StorageConverter, error) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("storage module '%s' is not a Caddyfile unmarshaler", mod.ID)
|
return nil, fmt.Errorf("storage module '%s' is not a Caddyfile unmarshaler", mod.ID)
|
||||||
}
|
}
|
||||||
err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
|
err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ func (enc *Encode) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("encoder module '%s' is not a Caddyfile unmarshaler", mod)
|
return fmt.Errorf("encoder module '%s' is not a Caddyfile unmarshaler", mod)
|
||||||
}
|
}
|
||||||
err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
|
err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,7 +520,7 @@ func (m *MatchNegate) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return d.Errf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
|
return d.Errf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
|
||||||
}
|
}
|
||||||
err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
|
err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return d.Errf("load balancing policy module '%s' is not a Caddyfile unmarshaler", mod)
|
return d.Errf("load balancing policy module '%s' is not a Caddyfile unmarshaler", mod)
|
||||||
}
|
}
|
||||||
err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
|
err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -401,7 +401,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return d.Errf("transport module '%s' is not a Caddyfile unmarshaler", mod)
|
return d.Errf("transport module '%s' is not a Caddyfile unmarshaler", mod)
|
||||||
}
|
}
|
||||||
err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
|
err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue