|
|
|
@ -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] |
|
|
|
|