Browse Source

Merge pull request #120 from shkw/reduce-variable-name-restriction

Reduce variable name restriction
pull/119/merge
Kamil Kisiel 11 years ago
parent
commit
e330fd08a3
  1. 90
      mux_test.go
  2. 25
      regexp.go

90
mux_test.go

@ -144,6 +144,33 @@ func TestHost(t *testing.T) { @@ -144,6 +144,33 @@ func TestHost(t *testing.T) {
path: "",
shouldMatch: false,
},
{
title: "Host route with hyphenated name and pattern, match",
route: new(Route).Host("aaa.{v-1:[a-z]{3}}.ccc"),
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
vars: map[string]string{"v-1": "bbb"},
host: "aaa.bbb.ccc",
path: "",
shouldMatch: true,
},
{
title: "Host route with hyphenated name and pattern, additional capturing group, match",
route: new(Route).Host("aaa.{v-1:[a-z]{2}(b|c)}.ccc"),
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
vars: map[string]string{"v-1": "bbb"},
host: "aaa.bbb.ccc",
path: "",
shouldMatch: true,
},
{
title: "Host route with multiple hyphenated names and patterns, match",
route: new(Route).Host("{v-1:[a-z]{3}}.{v-2:[a-z]{3}}.{v-3:[a-z]{3}}"),
request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
vars: map[string]string{"v-1": "aaa", "v-2": "bbb", "v-3": "ccc"},
host: "aaa.bbb.ccc",
path: "",
shouldMatch: true,
},
{
title: "Path route with single pattern with pipe, match",
route: new(Route).Path("/{category:a|b/c}"),
@ -278,6 +305,33 @@ func TestPath(t *testing.T) { @@ -278,6 +305,33 @@ func TestPath(t *testing.T) {
path: "/a/product_name/1",
shouldMatch: true,
},
{
title: "Path route with hyphenated name and pattern, match",
route: new(Route).Path("/111/{v-1:[0-9]{3}}/333"),
request: newRequest("GET", "http://localhost/111/222/333"),
vars: map[string]string{"v-1": "222"},
host: "",
path: "/111/222/333",
shouldMatch: true,
},
{
title: "Path route with multiple hyphenated names and patterns, match",
route: new(Route).Path("/{v-1:[0-9]{3}}/{v-2:[0-9]{3}}/{v-3:[0-9]{3}}"),
request: newRequest("GET", "http://localhost/111/222/333"),
vars: map[string]string{"v-1": "111", "v-2": "222", "v-3": "333"},
host: "",
path: "/111/222/333",
shouldMatch: true,
},
{
title: "Path route with multiple hyphenated names and patterns with pipe, match",
route: new(Route).Path("/{product-category:a|(b/c)}/{product-name}/{product-id:[0-9]+}"),
request: newRequest("GET", "http://localhost/a/product_name/1"),
vars: map[string]string{"product-category": "a", "product-name": "product_name", "product-id": "1"},
host: "",
path: "/a/product_name/1",
shouldMatch: true,
},
}
for _, test := range tests {
@ -633,6 +687,42 @@ func TestQueries(t *testing.T) { @@ -633,6 +687,42 @@ func TestQueries(t *testing.T) {
path: "",
shouldMatch: false,
},
{
title: "Queries route with hyphenated name, match",
route: new(Route).Queries("foo", "{v-1}"),
request: newRequest("GET", "http://localhost?foo=bar"),
vars: map[string]string{"v-1": "bar"},
host: "",
path: "",
shouldMatch: true,
},
{
title: "Queries route with multiple hyphenated names, match",
route: new(Route).Queries("foo", "{v-1}", "baz", "{v-2}"),
request: newRequest("GET", "http://localhost?foo=bar&baz=ding"),
vars: map[string]string{"v-1": "bar", "v-2": "ding"},
host: "",
path: "",
shouldMatch: true,
},
{
title: "Queries route with hyphenate name and pattern, match",
route: new(Route).Queries("foo", "{v-1:[0-9]+}"),
request: newRequest("GET", "http://localhost?foo=10"),
vars: map[string]string{"v-1": "10"},
host: "",
path: "",
shouldMatch: true,
},
{
title: "Queries route with hyphenated name and pattern with quantifier, additional capturing group",
route: new(Route).Queries("foo", "{v-1:[0-9]{1}(a|b)}"),
request: newRequest("GET", "http://localhost?foo=1a"),
vars: map[string]string{"v-1": "1a"},
host: "",
path: "",
shouldMatch: true,
},
{
title: "Queries route with empty value, should match",
route: new(Route).Queries("foo", ""),

25
regexp.go

@ -10,6 +10,7 @@ import ( @@ -10,6 +10,7 @@ import (
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
)
@ -72,13 +73,14 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash @@ -72,13 +73,14 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash
tpl[idxs[i]:end])
}
// Build the regexp pattern.
fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), name, patt)
varIdx := i / 2
fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(varIdx), patt)
// Build the reverse template.
fmt.Fprintf(reverse, "%s%%s", raw)
// Append variable name and compiled pattern.
varsN[i/2] = name
varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
varsN[varIdx] = name
varsR[varIdx], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
if err != nil {
return nil, err
}
@ -224,6 +226,11 @@ func braceIndices(s string) ([]int, error) { @@ -224,6 +226,11 @@ func braceIndices(s string) ([]int, error) {
return idxs, nil
}
// varGroupName builds a capturing group name for the indexed variable.
func varGroupName(idx int) string {
return "v" + strconv.Itoa(idx)
}
// ----------------------------------------------------------------------------
// routeRegexpGroup
// ----------------------------------------------------------------------------
@ -244,8 +251,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) @@ -244,8 +251,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
subexpNames := v.host.regexp.SubexpNames()
varName := 0
for i, name := range subexpNames[1:] {
if name != "" && v.host.varsN[varName] == name {
m.Vars[name] = hostVars[i+1]
if name != "" && name == varGroupName(varName) {
m.Vars[v.host.varsN[varName]] = hostVars[i+1]
varName++
}
}
@ -258,8 +265,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) @@ -258,8 +265,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
subexpNames := v.path.regexp.SubexpNames()
varName := 0
for i, name := range subexpNames[1:] {
if name != "" && v.path.varsN[varName] == name {
m.Vars[name] = pathVars[i+1]
if name != "" && name == varGroupName(varName) {
m.Vars[v.path.varsN[varName]] = pathVars[i+1]
varName++
}
}
@ -286,8 +293,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) @@ -286,8 +293,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
subexpNames := q.regexp.SubexpNames()
varName := 0
for i, name := range subexpNames[1:] {
if name != "" && q.varsN[varName] == name {
m.Vars[name] = queryVars[i+1]
if name != "" && name == varGroupName(varName) {
m.Vars[q.varsN[varName]] = queryVars[i+1]
varName++
}
}

Loading…
Cancel
Save