mirror of https://github.com/goproxyio/goproxy
add router mode
parent
434ee94b61
commit
769cffd5df
27
README.md
27
README.md
|
@ -10,9 +10,36 @@ A global proxy for go modules. see: [https://goproxy.io](https://goproxy.io)
|
|||
make
|
||||
|
||||
## Started
|
||||
|
||||
|
||||
### Proxy mode
|
||||
|
||||
./bin/goproxy -listen=0.0.0.0:80 -cacheDir=/tmp/test
|
||||
|
||||
### Router mode
|
||||
|
||||
Use the -proxy flag switch to "Router mode", which
|
||||
implements route filter to routing private module
|
||||
or public module .
|
||||
|
||||
```
|
||||
direct
|
||||
+----------------------------------> private repo
|
||||
|
|
||||
match|pattern
|
||||
|
|
||||
+---+---+ +----------+
|
||||
go get +-------> |goproxy| +-------> |goproxy.io| +---> golang.org/x/net
|
||||
+-------+ +----------+
|
||||
router mode proxy mode
|
||||
```
|
||||
|
||||
In Router mode, use the -exclude flag set pattern , direct to the repo which
|
||||
match the module path, pattern are matched to the full path specified, not only
|
||||
to the host component.
|
||||
|
||||
./bin/goproxy -listen=0.0.0.0:80 -cacheDir=/tmp/test -proxy https://goproxy.io -exclude "git.private.domain/[abc]"
|
||||
|
||||
## Use docker image
|
||||
|
||||
docker run -d -p80:8081 goproxy/goproxy
|
||||
|
|
26
main.go
26
main.go
|
@ -42,8 +42,12 @@ const listExpire = 5 * time.Minute
|
|||
|
||||
var listen string
|
||||
var cacheDir string
|
||||
var proxyHost string
|
||||
var excludeHost string
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&excludeHost, "exclude", "", "exclude host pattern")
|
||||
flag.StringVar(&proxyHost, "proxy", "", "next hop proxy for go modules")
|
||||
flag.StringVar(&cacheDir, "cacheDir", "", "go modules cache dir")
|
||||
flag.StringVar(&listen, "listen", "0.0.0.0:8081", "service listen address")
|
||||
flag.Parse()
|
||||
|
@ -64,6 +68,10 @@ func main() {
|
|||
var env struct {
|
||||
GOPATH string
|
||||
}
|
||||
if cacheDir != "" {
|
||||
downloadRoot = filepath.Join(cacheDir, "pkg/mod/cache/download")
|
||||
os.Setenv("GOPATH", cacheDir)
|
||||
}
|
||||
if err := goJSON(&env, "go", "env", "-json", "GOPATH"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -73,12 +81,20 @@ func main() {
|
|||
}
|
||||
downloadRoot = filepath.Join(list[0], "pkg/mod/cache/download")
|
||||
|
||||
if cacheDir != "" {
|
||||
downloadRoot = filepath.Join(cacheDir, "pkg/mod/cache/download")
|
||||
os.Setenv("GOPATH", cacheDir)
|
||||
var handle http.Handler
|
||||
if proxyHost != "" {
|
||||
fmt.Fprintf(os.Stderr, "ProxyHost %s\n", proxyHost)
|
||||
if excludeHost != "" {
|
||||
fmt.Fprintf(os.Stderr, "ExcludeHost %s\n", excludeHost)
|
||||
}
|
||||
handle = &logger{proxy.NewRouter(proxy.NewServer(new(ops)), &proxy.RouterOps{
|
||||
Pattern: excludeHost,
|
||||
Proxy: proxyHost,
|
||||
})}
|
||||
} else {
|
||||
handle = &logger{proxy.NewServer(new(ops))}
|
||||
}
|
||||
|
||||
log.Fatal(http.ListenAndServe(listen, &logger{proxy.NewServer(new(ops))}))
|
||||
log.Fatal(http.ListenAndServe(listen, handle))
|
||||
}
|
||||
|
||||
// goJSON runs the go command and parses its JSON output into dst.
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
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 {
|
||||
rt.proxy = httputil.NewSingleHostReverseProxy(remote)
|
||||
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.Stdout, "[direct] %s\n", r.URL)
|
||||
rt.srv.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "[proxy] %s\n", r.URL)
|
||||
rt.proxy.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue