mirror of https://github.com/goproxyio/goproxy
71 lines
1.5 KiB
Go
71 lines
1.5 KiB
Go
package proxy
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
"os"
|
|
"regexp"
|
|
)
|
|
|
|
// A RouterOps provides the proxy host and the external pattern
|
|
type RouterOps struct {
|
|
Pattern string
|
|
Proxy string
|
|
}
|
|
|
|
// A Router is the proxy HTTP server,
|
|
// which implements Route Filter to
|
|
// routing private module or public module .
|
|
type Router struct {
|
|
srv *Server
|
|
proxy *httputil.ReverseProxy
|
|
regex *regexp.Regexp
|
|
}
|
|
|
|
// NewRouter returns a new Router using the given operations.
|
|
func NewRouter(srv *Server, ops *RouterOps) *Router {
|
|
rt := &Router{
|
|
srv: srv,
|
|
}
|
|
if ops != nil {
|
|
if remote, err := url.Parse(ops.Proxy); err == nil {
|
|
proxy := httputil.NewSingleHostReverseProxy(remote)
|
|
director := proxy.Director
|
|
proxy.Director = func(r *http.Request) {
|
|
director(r)
|
|
r.Host = remote.Host
|
|
}
|
|
rt.proxy = proxy
|
|
|
|
rt.proxy.Transport = &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
}
|
|
if regex, err := regexp.Compile(ops.Pattern); err == nil {
|
|
rt.regex = regex
|
|
}
|
|
}
|
|
return rt
|
|
}
|
|
|
|
func (rt *Router) Direct(path string) bool {
|
|
if rt.regex == nil {
|
|
return true
|
|
}
|
|
return rt.regex.Match([]byte(path))
|
|
}
|
|
|
|
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if rt.proxy != nil && rt.Direct(r.URL.Path) {
|
|
fmt.Fprintf(os.Stderr, "------ --- %s [direct]\n", r.URL)
|
|
rt.srv.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
fmt.Fprintf(os.Stderr, "------ --- %s [proxy]\n", r.URL)
|
|
rt.proxy.ServeHTTP(w, r)
|
|
return
|
|
}
|