Browse Source

allow skipping specified hosts from Host matcher

introduce SkipHosts(hosts ...string) at the router
level which can be used to allow certain hosts to be
ignored by the Host() matcher, this is some times
necessary for an application which registers handlers
for one domain to be at a completely different style
of operation

One example is S3 APIs when servicing them as path style
v/s bucket as part of the DNS style.
pull/589/head
Harshavardhana 5 years ago
parent
commit
75fbc3e904
  1. 18
      mux.go
  2. 20
      mux_test.go
  3. 6
      regexp.go
  4. 1
      route.go

18
mux.go

@ -82,6 +82,9 @@ type routeConf struct { @@ -82,6 +82,9 @@ type routeConf struct {
// will not redirect
skipClean bool
// If set to a host skips the this host from r.Host() matcher.
skipHosts map[string]struct{}
// Manager for the variables from host and path.
regexp routeRegexpGroup
@ -269,6 +272,21 @@ func (r *Router) UseEncodedPath() *Router { @@ -269,6 +272,21 @@ func (r *Router) UseEncodedPath() *Router {
return r
}
// SkipHosts tells the router to skip the these list of hosts from
// r.Host() rules.
// For eg: "r.Host("{subdomain}.domain.com") will match "test.subdomain.com"
// and you would want to skip the matcher for `test.subdomain.com`.
//
// Go regexes do not support PCRE style lookahead/lookbehind like
// features, this function is a way to provide this functionality.
func (r *Router) SkipHosts(hosts ...string) *Router {
r.skipHosts = map[string]struct{}{}
for _, host := range hosts {
r.skipHosts[host] = struct{}{}
}
return r
}
// ----------------------------------------------------------------------------
// Route factories
// ----------------------------------------------------------------------------

20
mux_test.go

@ -51,6 +51,16 @@ type routeTest struct { @@ -51,6 +51,16 @@ type routeTest struct {
shouldRedirect bool // whether the request should result in a redirect
}
func skipRoute(tpl string, skipHosts ...string) *Route {
skipRoute := &Route{}
skipRoute.skipHosts = map[string]struct{}{}
for _, host := range skipHosts {
skipRoute.skipHosts[host] = struct{}{}
}
skipRoute.Host(tpl)
return skipRoute
}
func TestHost(t *testing.T) {
tests := []routeTest{
@ -216,6 +226,16 @@ func TestHost(t *testing.T) { @@ -216,6 +226,16 @@ func TestHost(t *testing.T) {
hostTemplate: `{v-1:[a-z]{3}}.{v-2:[a-z]{3}}.{v-3:[a-z]{3}}`,
shouldMatch: true,
},
{
title: "Host route match should skip specific hosts when specified",
route: skipRoute("{subdomain}.domain.com", "test.domain.com"), // skip matching 'test.domain.com'
request: newRequest("GET", "http://test.domain.com"),
vars: map[string]string{},
host: "test.domain.com",
path: "",
hostTemplate: `{subdomain}.domain.com`,
shouldMatch: false,
},
}
for _, test := range tests {
t.Run(test.title, func(t *testing.T) {

6
regexp.go

@ -17,6 +17,7 @@ import ( @@ -17,6 +17,7 @@ import (
type routeRegexpOptions struct {
strictSlash bool
useEncodedPath bool
skipHosts map[string]struct{}
}
type regexpType int
@ -180,6 +181,11 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { @@ -180,6 +181,11 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
host = host[:i]
}
}
if len(r.options.skipHosts) > 0 {
if _, ok := r.options.skipHosts[host]; ok {
return false
}
}
return r.regexp.MatchString(host)
}

1
route.go

@ -186,6 +186,7 @@ func (r *Route) addRegexpMatcher(tpl string, typ regexpType) error { @@ -186,6 +186,7 @@ func (r *Route) addRegexpMatcher(tpl string, typ regexpType) error {
rr, err := newRouteRegexp(tpl, typ, routeRegexpOptions{
strictSlash: r.strictSlash,
useEncodedPath: r.useEncodedPath,
skipHosts: r.skipHosts,
})
if err != nil {
return err

Loading…
Cancel
Save