Browse Source

adding ^ and $ to query pattern

pull/101/head
Bay Dodd 11 years ago
parent
commit
a710a8bfa9
  1. 18
      mux_test.go
  2. 23
      regexp.go
  3. 2
      route.go

18
mux_test.go

@ -552,6 +552,24 @@ func TestQueries(t *testing.T) {
path: "", path: "",
shouldMatch: false, shouldMatch: false,
}, },
{
title: "Queries route with regexp pattern with quantifier, match",
route: new(Route).Queries("foo", "{v1:[0-9]{1}}"),
request: newRequest("GET", "http://localhost?foo=1"),
vars: map[string]string{"v1": "1"},
host: "",
path: "",
shouldMatch: true,
},
{
title: "Queries route with regexp pattern with quantifier, regexp does not match",
route: new(Route).Queries("foo", "{v1:[0-9]{1}}"),
request: newRequest("GET", "http://localhost?foo=12"),
vars: map[string]string{},
host: "",
path: "",
shouldMatch: false,
},
} }
for _, test := range tests { for _, test := range tests {

23
regexp.go

@ -35,7 +35,6 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash
defaultPattern := "[^/]+" defaultPattern := "[^/]+"
if matchQuery { if matchQuery {
defaultPattern = "[^?&]+" defaultPattern = "[^?&]+"
matchPrefix = true
} else if matchHost { } else if matchHost {
defaultPattern = "[^.]+" defaultPattern = "[^.]+"
matchPrefix = false matchPrefix = false
@ -53,9 +52,7 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash
varsN := make([]string, len(idxs)/2) varsN := make([]string, len(idxs)/2)
varsR := make([]*regexp.Regexp, len(idxs)/2) varsR := make([]*regexp.Regexp, len(idxs)/2)
pattern := bytes.NewBufferString("") pattern := bytes.NewBufferString("")
if !matchQuery { pattern.WriteByte('^')
pattern.WriteByte('^')
}
reverse := bytes.NewBufferString("") reverse := bytes.NewBufferString("")
var end int var end int
var err error var err error
@ -78,6 +75,7 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash
fmt.Fprintf(pattern, "%s(%s)", regexp.QuoteMeta(raw), patt) fmt.Fprintf(pattern, "%s(%s)", regexp.QuoteMeta(raw), patt)
// Build the reverse template. // Build the reverse template.
fmt.Fprintf(reverse, "%s%%s", raw) fmt.Fprintf(reverse, "%s%%s", raw)
// Append variable name and compiled pattern. // Append variable name and compiled pattern.
varsN[i/2] = name varsN[i/2] = name
varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt)) varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
@ -141,7 +139,7 @@ type routeRegexp struct {
func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
if !r.matchHost { if !r.matchHost {
if r.matchQuery { if r.matchQuery {
return r.regexp.MatchString(req.URL.RawQuery) return r.regexp.MatchString(r.getUrlQuery(req))
} else { } else {
return r.regexp.MatchString(req.URL.Path) return r.regexp.MatchString(req.URL.Path)
} }
@ -175,6 +173,18 @@ func (r *routeRegexp) url(values map[string]string) (string, error) {
return rv, nil return rv, nil
} }
// getUrlQuery returns a single query parameter from a request URL.
// For a URL with foo=bar&baz=ding, we return only the relevant key
// value pair for the routeRegexp.
func (r *routeRegexp) getUrlQuery(req *http.Request) string {
keyVal := strings.Split(r.template, "=")
if len(keyVal) == 0 {
return ""
}
re := regexp.MustCompile(keyVal[0] + "[^&]*")
return re.FindString(req.URL.RawQuery)
}
// braceIndices returns the first level curly brace indices from a string. // braceIndices returns the first level curly brace indices from a string.
// It returns an error in case of unbalanced braces. // It returns an error in case of unbalanced braces.
func braceIndices(s string) ([]int, error) { func braceIndices(s string) ([]int, error) {
@ -246,9 +256,8 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
} }
} }
// Store query string variables. // Store query string variables.
rawQuery := req.URL.RawQuery
for _, q := range v.queries { for _, q := range v.queries {
queryVars := q.regexp.FindStringSubmatch(rawQuery) queryVars := q.regexp.FindStringSubmatch(q.getUrlQuery(req))
if queryVars != nil { if queryVars != nil {
for k, v := range q.varsN { for k, v := range q.varsN {
m.Vars[v] = queryVars[k+1] m.Vars[v] = queryVars[k+1]

2
route.go

@ -336,7 +336,7 @@ func (r *Route) Queries(pairs ...string) *Route {
return nil return nil
} }
for i := 0; i < length; i += 2 { for i := 0; i < length; i += 2 {
if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, true, true); r.err != nil { if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, false, true); r.err != nil {
return r return r
} }
} }

Loading…
Cancel
Save