Skip to content

Commit

Permalink
Merge pull request #553 from herbrandson/master
Browse files Browse the repository at this point in the history
Added new case insensitive matcher
  • Loading branch information
magiconair authored Oct 29, 2018
2 parents b44a9b3 + 972d851 commit cba6849
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 5 deletions.
2 changes: 1 addition & 1 deletion config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func load(cmdline, environ, envprefix []string, props *properties.Properties) (c
return nil, fmt.Errorf("invalid proxy.strategy: %s", cfg.Proxy.Strategy)
}

if cfg.Proxy.Matcher != "prefix" && cfg.Proxy.Matcher != "glob" {
if cfg.Proxy.Matcher != "prefix" && cfg.Proxy.Matcher != "glob" && cfg.Proxy.Matcher != "iprefix" {
return nil, fmt.Errorf("invalid proxy.matcher: %s", cfg.Proxy.Matcher)
}

Expand Down
7 changes: 7 additions & 0 deletions config/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ func TestLoad(t *testing.T) {
return cfg
},
},
{
args: []string{"-proxy.matcher", "iprefix"},
cfg: func(cfg *Config) *Config {
cfg.Proxy.Matcher = "iprefix"
return cfg
},
},
{
args: []string{"-proxy.noroutestatus", "555"},
cfg: func(cfg *Config) *Config {
Expand Down
6 changes: 4 additions & 2 deletions docs/content/ref/proxy.matcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ title: "proxy.matcher"
* `prefix`: prefix matching
* `glob`: glob matching

When `prefix` matching is enabled then the route path must be a
prefix of the request URI, e.g. `/foo` matches `/foo`, `/foot` but
When `prefix` matching is enabled then the route path must be a
prefix of the request URI, e.g. `/foo` matches `/foo`, `/foot` but
not `/fo`.

When `glob` matching is enabled the route is evaluated according to
Expand All @@ -19,6 +19,8 @@ function.
For example, `/foo*` matches `/foo`, `/fool` and `/fools`. Also, `/foo/*/bar`
matches `/foo/x/bar`.

`iprefix` matching is similar to `prefix`, except it uses a case insensitive comparison

The default is

proxy.matcher = prefix
1 change: 1 addition & 0 deletions fabio.properties
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
#
# prefix: prefix matching
# glob: glob matching
# iprefix: case-insensitive prefix matching
#
# The default is
#
Expand Down
14 changes: 12 additions & 2 deletions route/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ type matcher func(uri string, r *Route) bool
// Matcher contains the available matcher functions.
// Update config/load.go#load after updating.
var Matcher = map[string]matcher{
"prefix": prefixMatcher,
"glob": globMatcher,
"prefix": prefixMatcher,
"glob": globMatcher,
"iprefix": iPrefixMatcher,
}

// prefixMatcher matches path to the routes' path.
Expand All @@ -23,3 +24,12 @@ func prefixMatcher(uri string, r *Route) bool {
func globMatcher(uri string, r *Route) bool {
return r.Glob.Match(uri)
}

// iPrefixMatcher matches path to the routes' path ignoring case
func iPrefixMatcher(uri string, r *Route) bool {
// todo(fs): if this turns out to be a performance issue we should cache
// todo(fs): strings.ToLower(r.Path) in r.PathLower
lowerURI := strings.ToLower(uri)
lowerPath := strings.ToLower(r.Path)
return strings.HasPrefix(lowerURI, lowerPath)
}
21 changes: 21 additions & 0 deletions route/matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,24 @@ func TestGlobMatcher(t *testing.T) {
})
}
}

func TestIPrefixMatcher(t *testing.T) {
tests := []struct {
uri string
matches bool
route *Route
}{
{uri: "/foo", matches: false, route: &Route{Path: "/fool"}},
{uri: "/foo", matches: true, route: &Route{Path: "/foo"}},
{uri: "/Fool", matches: true, route: &Route{Path: "/foo"}},
{uri: "/foo", matches: true, route: &Route{Path: "/Foo"}},
}

for _, tt := range tests {
t.Run(tt.uri, func(t *testing.T) {
if got, want := iPrefixMatcher(tt.uri, tt.route), tt.matches; got != want {
t.Fatalf("got %v want %v", got, want)
}
})
}
}

0 comments on commit cba6849

Please sign in to comment.