@ -73,14 +73,17 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash
@@ -73,14 +73,17 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash
tpl [ idxs [ i ] : end ] )
}
// Build the regexp pattern.
varIdx := i / 2
fmt . Fprintf ( pattern , "%s(?P<%s>%s)" , regexp . QuoteMeta ( raw ) , varGroupName ( varIdx ) , patt )
if patt [ 0 ] == '(' && patt [ len ( patt ) - 1 ] == ')' {
fmt . Fprintf ( pattern , "%s%s" , regexp . QuoteMeta ( raw ) , patt )
} else {
fmt . Fprintf ( pattern , "%s(%s)" , regexp . QuoteMeta ( raw ) , patt )
}
// Build the reverse template.
fmt . Fprintf ( reverse , "%s%%s" , raw )
// Append variable name and compiled pattern.
varsN [ varIdx ] = name
varsR [ varIdx ] , err = regexp . Compile ( fmt . Sprintf ( "^%s$" , patt ) )
varsN [ i / 2 ] = name
varsR [ i / 2 ] , err = regexp . Compile ( fmt . Sprintf ( "^%s$" , patt ) )
if err != nil {
return nil , err
}
@ -246,30 +249,17 @@ type routeRegexpGroup struct {
@@ -246,30 +249,17 @@ type routeRegexpGroup struct {
func ( v * routeRegexpGroup ) setMatch ( req * http . Request , m * RouteMatch , r * Route ) {
// Store host variables.
if v . host != nil {
hostVars := v . host . regexp . FindStringSubmatch ( getHost ( req ) )
if hostVars != nil {
subexpNames := v . host . regexp . SubexpNames ( )
varName := 0
for i , name := range subexpNames [ 1 : ] {
if name != "" && name == varGroupName ( varName ) {
m . Vars [ v . host . varsN [ varName ] ] = hostVars [ i + 1 ]
varName ++
}
}
host := getHost ( req )
matches := v . host . regexp . FindStringSubmatchIndex ( host )
if len ( matches ) > 0 {
extractVars ( host , matches , v . host . varsN , m . Vars )
}
}
// Store path variables.
if v . path != nil {
pathVars := v . path . regexp . FindStringSubmatch ( req . URL . Path )
if pathVars != nil {
subexpNames := v . path . regexp . SubexpNames ( )
varName := 0
for i , name := range subexpNames [ 1 : ] {
if name != "" && name == varGroupName ( varName ) {
m . Vars [ v . path . varsN [ varName ] ] = pathVars [ i + 1 ]
varName ++
}
}
matches := v . path . regexp . FindStringSubmatchIndex ( req . URL . Path )
if len ( matches ) > 0 {
extractVars ( req . URL . Path , matches , v . path . varsN , m . Vars )
// Check if we should redirect.
if v . path . strictSlash {
p1 := strings . HasSuffix ( req . URL . Path , "/" )
@ -288,16 +278,10 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
@@ -288,16 +278,10 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
}
// Store query string variables.
for _ , q := range v . queries {
queryVars := q . regexp . FindStringSubmatch ( q . getUrlQuery ( req ) )
if queryVars != nil {
subexpNames := q . regexp . SubexpNames ( )
varName := 0
for i , name := range subexpNames [ 1 : ] {
if name != "" && name == varGroupName ( varName ) {
m . Vars [ q . varsN [ varName ] ] = queryVars [ i + 1 ]
varName ++
}
}
queryUrl := q . getUrlQuery ( req )
matches := q . regexp . FindStringSubmatchIndex ( queryUrl )
if len ( matches ) > 0 {
extractVars ( queryUrl , matches , q . varsN , m . Vars )
}
}
}
@ -315,3 +299,16 @@ func getHost(r *http.Request) string {
@@ -315,3 +299,16 @@ func getHost(r *http.Request) string {
return host
}
func extractVars ( input string , matches [ ] int , names [ ] string , output map [ string ] string ) {
matchesCount := 0
prevEnd := - 1
for i := 2 ; i < len ( matches ) && matchesCount < len ( names ) ; i += 2 {
if prevEnd < matches [ i + 1 ] {
value := input [ matches [ i ] : matches [ i + 1 ] ]
output [ names [ matchesCount ] ] = value
prevEnd = matches [ i + 1 ]
matchesCount ++
}
}
}