|
|
@ -31,6 +31,8 @@ type Route struct { |
|
|
|
name string |
|
|
|
name string |
|
|
|
// Error resulted from building a route.
|
|
|
|
// Error resulted from building a route.
|
|
|
|
err error |
|
|
|
err error |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buildVarsFunc BuildVarsFunc |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Match matches the route against the request.
|
|
|
|
// Match matches the route against the request.
|
|
|
@ -360,6 +362,19 @@ func (r *Route) Schemes(schemes ...string) *Route { |
|
|
|
return r.addMatcher(schemeMatcher(schemes)) |
|
|
|
return r.addMatcher(schemeMatcher(schemes)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// BuildVarsFunc --------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// BuildVarsFunc is the function signature used by custom build variable
|
|
|
|
|
|
|
|
// functions (which can modify route variables before a route's URL is built).
|
|
|
|
|
|
|
|
type BuildVarsFunc func(map[string]string) map[string]string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// BuildVarsFunc adds a custom function to be used to modify build variables
|
|
|
|
|
|
|
|
// before a route's URL is built.
|
|
|
|
|
|
|
|
func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route { |
|
|
|
|
|
|
|
r.buildVarsFunc = f |
|
|
|
|
|
|
|
return r |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Subrouter ------------------------------------------------------------------
|
|
|
|
// Subrouter ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// Subrouter creates a subrouter for the route.
|
|
|
|
// Subrouter creates a subrouter for the route.
|
|
|
@ -422,17 +437,20 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) { |
|
|
|
if r.regexp == nil { |
|
|
|
if r.regexp == nil { |
|
|
|
return nil, errors.New("mux: route doesn't have a host or path") |
|
|
|
return nil, errors.New("mux: route doesn't have a host or path") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
values, err := r.prepareVars(pairs...) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
var scheme, host, path string |
|
|
|
var scheme, host, path string |
|
|
|
var err error |
|
|
|
|
|
|
|
if r.regexp.host != nil { |
|
|
|
if r.regexp.host != nil { |
|
|
|
// Set a default scheme.
|
|
|
|
// Set a default scheme.
|
|
|
|
scheme = "http" |
|
|
|
scheme = "http" |
|
|
|
if host, err = r.regexp.host.url(pairs...); err != nil { |
|
|
|
if host, err = r.regexp.host.url(values); err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if r.regexp.path != nil { |
|
|
|
if r.regexp.path != nil { |
|
|
|
if path, err = r.regexp.path.url(pairs...); err != nil { |
|
|
|
if path, err = r.regexp.path.url(values); err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -453,7 +471,11 @@ func (r *Route) URLHost(pairs ...string) (*url.URL, error) { |
|
|
|
if r.regexp == nil || r.regexp.host == nil { |
|
|
|
if r.regexp == nil || r.regexp.host == nil { |
|
|
|
return nil, errors.New("mux: route doesn't have a host") |
|
|
|
return nil, errors.New("mux: route doesn't have a host") |
|
|
|
} |
|
|
|
} |
|
|
|
host, err := r.regexp.host.url(pairs...) |
|
|
|
values, err := r.prepareVars(pairs...) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
host, err := r.regexp.host.url(values) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
@ -473,7 +495,11 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) { |
|
|
|
if r.regexp == nil || r.regexp.path == nil { |
|
|
|
if r.regexp == nil || r.regexp.path == nil { |
|
|
|
return nil, errors.New("mux: route doesn't have a path") |
|
|
|
return nil, errors.New("mux: route doesn't have a path") |
|
|
|
} |
|
|
|
} |
|
|
|
path, err := r.regexp.path.url(pairs...) |
|
|
|
values, err := r.prepareVars(pairs...) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
path, err := r.regexp.path.url(values) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
@ -482,6 +508,26 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) { |
|
|
|
}, nil |
|
|
|
}, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// prepareVars converts the route variable pairs into a map. If the route has a
|
|
|
|
|
|
|
|
// BuildVarsFunc, it is invoked.
|
|
|
|
|
|
|
|
func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { |
|
|
|
|
|
|
|
m, err := mapFromPairs(pairs...) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return r.buildVars(m), nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (r *Route) buildVars(m map[string]string) map[string]string { |
|
|
|
|
|
|
|
if r.parent != nil { |
|
|
|
|
|
|
|
m = r.parent.buildVars(m) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if r.buildVarsFunc != nil { |
|
|
|
|
|
|
|
m = r.buildVarsFunc(m) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return m |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// parentRoute
|
|
|
|
// parentRoute
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
@ -490,6 +536,7 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) { |
|
|
|
type parentRoute interface { |
|
|
|
type parentRoute interface { |
|
|
|
getNamedRoutes() map[string]*Route |
|
|
|
getNamedRoutes() map[string]*Route |
|
|
|
getRegexpGroup() *routeRegexpGroup |
|
|
|
getRegexpGroup() *routeRegexpGroup |
|
|
|
|
|
|
|
buildVars(map[string]string) map[string]string |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// getNamedRoutes returns the map where named routes are registered.
|
|
|
|
// getNamedRoutes returns the map where named routes are registered.
|
|
|
|