Skip to content

Commit

Permalink
Match subpaths correctly when path contains trailing slash
Browse files Browse the repository at this point in the history
  • Loading branch information
liggitt committed Apr 27, 2017
1 parent 214e4c3 commit 7b4335d
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 1 deletion.
19 changes: 18 additions & 1 deletion pkg/router/template/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,24 @@ func generateRouteRegexp(hostname, path string, wildcard bool) string {
}
}

return fmt.Sprintf("^%s(|:[0-9]+)%s(|/.*)$", hostRE, regexp.QuoteMeta(path))
portRE := "(:[0-9]+)?"

// build the correct subpath regex, depending on whether path ends with a segment separator
var pathRE, subpathRE string
switch {
case strings.TrimRight(path, "/") == "":
// Special-case paths consisting solely of "/" to match a root request to "" as well
pathRE = ""
subpathRE = "(/.*)?"
case strings.HasSuffix(path, "/"):
pathRE = regexp.QuoteMeta(path)
subpathRE = "(.*)?"
default:
pathRE = regexp.QuoteMeta(path)
subpathRE = "(/.*)?"
}

return "^" + hostRE + portRE + pathRE + subpathRE + "$"
}

// Generates the host name to use for serving/certificate matching.
Expand Down
140 changes: 140 additions & 0 deletions pkg/router/template/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/md5"
"fmt"
"reflect"
"regexp"
"testing"

kapi "k8s.io/kubernetes/pkg/api"
Expand Down Expand Up @@ -670,3 +671,142 @@ func TestAddRouteEdgeTerminationInsecurePolicy(t *testing.T) {
}
}
}

func TestGenerateRouteRegexp(t *testing.T) {
tests := []struct {
name string
hostname string
path string
wildcard bool

match []string
nomatch []string
}{
{
name: "no path",
hostname: "example.com",
path: "",
wildcard: false,
match: []string{
"example.com",
"example.com:80",
"example.com/",
"example.com/sub",
"example.com/sub/",
},
nomatch: []string{"other.com"},
},
{
name: "root path with trailing slash",
hostname: "example.com",
path: "/",
wildcard: false,
match: []string{
"example.com",
"example.com:80",
"example.com/",
"example.com/sub",
"example.com/sub/",
},
nomatch: []string{"other.com"},
},
{
name: "subpath with trailing slash",
hostname: "example.com",
path: "/sub/",
wildcard: false,
match: []string{
"example.com/sub/",
"example.com/sub/subsub",
},
nomatch: []string{
"other.com",
"example.com",
"example.com:80",
"example.com/",
"example.com/sub", // path with trailing slash doesn't match URL without
"example.com/subpar", // path segment boundary match required
},
},
{
name: "subpath without trailing slash",
hostname: "example.com",
path: "/sub",
wildcard: false,
match: []string{
"example.com/sub",
"example.com/sub/",
"example.com/sub/subsub",
},
nomatch: []string{
"other.com",
"example.com",
"example.com:80",
"example.com/",
"example.com/subpar", // path segment boundary match required
},
},
{
name: "wildcard",
hostname: "www.example.com",
path: "/",
wildcard: true,
match: []string{
"www.example.com",
"www.example.com/",
"www.example.com/sub",
"www.example.com/sub/",
"www.example.com:80",
"www.example.com:80/",
"www.example.com:80/sub",
"www.example.com:80/sub/",
"foo.example.com",
"foo.example.com/",
"foo.example.com/sub",
"foo.example.com/sub/",
},
nomatch: []string{
"wwwexample.com",
"foo.bar.example.com",
},
},
{
name: "non-wildcard",
hostname: "www.example.com",
path: "/",
wildcard: false,
match: []string{
"www.example.com",
"www.example.com/",
"www.example.com/sub",
"www.example.com/sub/",
"www.example.com:80",
"www.example.com:80/",
"www.example.com:80/sub",
"www.example.com:80/sub/",
},
nomatch: []string{
"foo.example.com",
"foo.example.com/",
"foo.example.com/sub",
"foo.example.com/sub/",
"wwwexample.com",
"foo.bar.example.com",
},
},
}

for _, tt := range tests {
r := regexp.MustCompile(generateRouteRegexp(tt.hostname, tt.path, tt.wildcard))
for _, s := range tt.match {
if !r.Match([]byte(s)) {
t.Errorf("%s: expected %s to match %s, but didn't", tt.name, r, s)
}
}
for _, s := range tt.nomatch {
if r.Match([]byte(s)) {
t.Errorf("%s: expected %s not to match %s, but did", tt.name, r, s)
}
}
}
}

0 comments on commit 7b4335d

Please sign in to comment.