mirror of https://github.com/goproxyio/goproxy
use path.Match instead of regexp
parent
4c04e3c06b
commit
6141bae547
2
main.go
2
main.go
|
@ -87,7 +87,7 @@ func main() {
|
||||||
if excludeHost != "" {
|
if excludeHost != "" {
|
||||||
fmt.Fprintf(os.Stderr, "ExcludeHost %s\n", excludeHost)
|
fmt.Fprintf(os.Stderr, "ExcludeHost %s\n", excludeHost)
|
||||||
}
|
}
|
||||||
handle = &logger{proxy.NewRouter(proxy.NewServer(new(ops)), &proxy.RouterOps{
|
handle = &logger{proxy.NewRouter(proxy.NewServer(new(ops)), &proxy.RouterOptions{
|
||||||
Pattern: excludeHost,
|
Pattern: excludeHost,
|
||||||
Proxy: proxyHost,
|
Proxy: proxyHost,
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -7,11 +7,12 @@ import (
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"path"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A RouterOps provides the proxy host and the external pattern
|
// A RouterOps provides the proxy host and the external pattern
|
||||||
type RouterOps struct {
|
type RouterOptions struct {
|
||||||
Pattern string
|
Pattern string
|
||||||
Proxy string
|
Proxy string
|
||||||
}
|
}
|
||||||
|
@ -20,18 +21,18 @@ type RouterOps struct {
|
||||||
// which implements Route Filter to
|
// which implements Route Filter to
|
||||||
// routing private module or public module .
|
// routing private module or public module .
|
||||||
type Router struct {
|
type Router struct {
|
||||||
srv *Server
|
srv *Server
|
||||||
proxy *httputil.ReverseProxy
|
proxy *httputil.ReverseProxy
|
||||||
regex *regexp.Regexp
|
pattern string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter returns a new Router using the given operations.
|
// NewRouter returns a new Router using the given operations.
|
||||||
func NewRouter(srv *Server, ops *RouterOps) *Router {
|
func NewRouter(srv *Server, opts *RouterOptions) *Router {
|
||||||
rt := &Router{
|
rt := &Router{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
}
|
}
|
||||||
if ops != nil {
|
if opts != nil {
|
||||||
if remote, err := url.Parse(ops.Proxy); err == nil {
|
if remote, err := url.Parse(opts.Proxy); err == nil {
|
||||||
proxy := httputil.NewSingleHostReverseProxy(remote)
|
proxy := httputil.NewSingleHostReverseProxy(remote)
|
||||||
director := proxy.Director
|
director := proxy.Director
|
||||||
proxy.Director = func(r *http.Request) {
|
proxy.Director = func(r *http.Request) {
|
||||||
|
@ -44,18 +45,16 @@ func NewRouter(srv *Server, ops *RouterOps) *Router {
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if regex, err := regexp.Compile(ops.Pattern); err == nil {
|
rt.pattern = opts.Pattern
|
||||||
rt.regex = regex
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rt
|
return rt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt *Router) Direct(path string) bool {
|
func (rt *Router) Direct(path string) bool {
|
||||||
if rt.regex == nil {
|
if rt.pattern == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return rt.regex.Match([]byte(path))
|
return GlobsMatchPath(rt.pattern, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -68,3 +67,47 @@ func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
rt.proxy.ServeHTTP(w, r)
|
rt.proxy.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GlobsMatchPath reports whether any path prefix of target
|
||||||
|
// matches one of the glob patterns (as defined by path.Match)
|
||||||
|
// in the comma-separated globs list.
|
||||||
|
// It ignores any empty or malformed patterns in the list.
|
||||||
|
func GlobsMatchPath(globs, target string) bool {
|
||||||
|
for globs != "" {
|
||||||
|
// Extract next non-empty glob in comma-separated list.
|
||||||
|
var glob string
|
||||||
|
if i := strings.Index(globs, ","); i >= 0 {
|
||||||
|
glob, globs = globs[:i], globs[i+1:]
|
||||||
|
} else {
|
||||||
|
glob, globs = globs, ""
|
||||||
|
}
|
||||||
|
if glob == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// A glob with N+1 path elements (N slashes) needs to be matched
|
||||||
|
// against the first N+1 path elements of target,
|
||||||
|
// which end just before the N+1'th slash.
|
||||||
|
n := strings.Count(glob, "/")
|
||||||
|
prefix := target
|
||||||
|
// Walk target, counting slashes, truncating at the N+1'th slash.
|
||||||
|
for i := 0; i < len(target); i++ {
|
||||||
|
if target[i] == '/' {
|
||||||
|
if n == 0 {
|
||||||
|
prefix = target[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if n > 0 {
|
||||||
|
// Not enough prefix elements.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matched, _ := path.Match(glob, prefix)
|
||||||
|
if matched {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue