mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 12:42:34 +02:00
small refactoring
This commit is contained in:
parent
d3684b62b7
commit
0a34a23ea2
7 changed files with 70 additions and 66 deletions
|
@ -8,4 +8,4 @@ app: # alias
|
||||||
# optional, defaults to empty
|
# optional, defaults to empty
|
||||||
path:
|
path:
|
||||||
# optional
|
# optional
|
||||||
path_mode:
|
path_mode:
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ImageNamePortMap = map[string]string{
|
ImageNamePortMap = map[string]string{
|
||||||
|
@ -60,6 +64,19 @@ const (
|
||||||
keyPath = "certs/priv.key"
|
keyPath = "certs/priv.key"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: default + per proxy
|
||||||
|
var transport = &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
DialContext: (&net.Dialer{
|
||||||
|
Timeout: 60 * time.Second,
|
||||||
|
KeepAlive: 60 * time.Second,
|
||||||
|
}).DialContext,
|
||||||
|
MaxIdleConns: 1000,
|
||||||
|
MaxIdleConnsPerHost: 1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientUrlFromEnv = "FROM_ENV"
|
||||||
|
|
||||||
const configPath = "config.yml"
|
const configPath = "config.yml"
|
||||||
|
|
||||||
const StreamStopListenTimeout = 1 * time.Second
|
const StreamStopListenTimeout = 1 * time.Second
|
||||||
|
|
|
@ -63,14 +63,16 @@ func (p *Provider) getContainerProxyConfigs(container types.Container, clientHos
|
||||||
}
|
}
|
||||||
if config.Port == "" {
|
if config.Port == "" {
|
||||||
// no ports exposed or specified
|
// no ports exposed or specified
|
||||||
|
p.Logf("Build", "no ports exposed for %s, ignored", container_name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if config.Scheme == "" {
|
if config.Scheme == "" {
|
||||||
if strings.HasSuffix(config.Port, "443") {
|
switch {
|
||||||
|
case strings.HasSuffix(config.Port, "443"):
|
||||||
config.Scheme = "https"
|
config.Scheme = "https"
|
||||||
} else if strings.HasPrefix(container.Image, "sha256:") {
|
case strings.HasPrefix(container.Image, "sha256:"):
|
||||||
config.Scheme = "http"
|
config.Scheme = "http"
|
||||||
} else {
|
default:
|
||||||
imageSplit := strings.Split(container.Image, "/")
|
imageSplit := strings.Split(container.Image, "/")
|
||||||
imageSplit = strings.Split(imageSplit[len(imageSplit)-1], ":")
|
imageSplit = strings.Split(imageSplit[len(imageSplit)-1], ":")
|
||||||
imageName := imageSplit[0]
|
imageName := imageSplit[0]
|
||||||
|
@ -92,8 +94,7 @@ func (p *Provider) getContainerProxyConfigs(container types.Container, clientHos
|
||||||
config.Host = clientHost
|
config.Host = clientHost
|
||||||
case container.HostConfig.NetworkMode == "host":
|
case container.HostConfig.NetworkMode == "host":
|
||||||
config.Host = "host.docker.internal"
|
config.Host = "host.docker.internal"
|
||||||
case config.LoadBalance == "true":
|
case config.LoadBalance == "true", config.LoadBalance == "1":
|
||||||
case config.LoadBalance == "1":
|
|
||||||
for _, network := range container.NetworkSettings.Networks {
|
for _, network := range container.NetworkSettings.Networks {
|
||||||
config.Host = network.IPAddress
|
config.Host = network.IPAddress
|
||||||
break
|
break
|
||||||
|
@ -185,5 +186,4 @@ func (p *Provider) grWatchDockerChanges() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var dockerUrlRegex = regexp.MustCompile(`^(?P<scheme>\w+)://(?P<host>[^:]+)(?P<port>:\d+)?(?P<path>/.*)?$`)
|
// var dockerUrlRegex = regexp.MustCompile(`^(?P<scheme>\w+)://(?P<host>[^:]+)(?P<port>:\d+)?(?P<path>/.*)?$`)
|
||||||
const clientUrlFromEnv = "FROM_ENV"
|
|
|
@ -25,7 +25,7 @@ func (p *Provider) getFileProxyConfigs() ([]*ProxyConfig, error) {
|
||||||
|
|
||||||
for alias, cfg := range configMap {
|
for alias, cfg := range configMap {
|
||||||
cfg.Alias = alias
|
cfg.Alias = alias
|
||||||
err = cfg.SetDefault()
|
err = cfg.SetDefaults()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,10 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
@ -20,15 +18,6 @@ type HTTPRoute struct {
|
||||||
Proxy *httputil.ReverseProxy
|
Proxy *httputil.ReverseProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
func isValidProxyPathMode(mode string) bool {
|
|
||||||
switch mode {
|
|
||||||
case ProxyPathMode_Forward, ProxyPathMode_Sub, ProxyPathMode_RemovedPath:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHTTPRoute(config *ProxyConfig) (*HTTPRoute, error) {
|
func NewHTTPRoute(config *ProxyConfig) (*HTTPRoute, error) {
|
||||||
url, err := url.Parse(fmt.Sprintf("%s://%s:%s", config.Scheme, config.Host, config.Port))
|
url, err := url.Parse(fmt.Sprintf("%s://%s:%s", config.Scheme, config.Host, config.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -124,6 +113,24 @@ func (p *httpLoadBalancePool) Pick() *HTTPRoute {
|
||||||
return p.pool[index%len(p.pool)]
|
return p.pool[index%len(p.pool)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *HTTPRoute) RemoveFromRoutes() {
|
||||||
|
routes.HTTPRoutes.Delete(r.Alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dummy implementation for Route interface
|
||||||
|
func (r *HTTPRoute) SetupListen() {}
|
||||||
|
func (r *HTTPRoute) Listen() {}
|
||||||
|
func (r *HTTPRoute) StopListening() {}
|
||||||
|
|
||||||
|
func isValidProxyPathMode(mode string) bool {
|
||||||
|
switch mode {
|
||||||
|
case ProxyPathMode_Forward, ProxyPathMode_Sub, ProxyPathMode_RemovedPath:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func redirectToTLS(w http.ResponseWriter, r *http.Request) {
|
func redirectToTLS(w http.ResponseWriter, r *http.Request) {
|
||||||
// Redirect to the same host but with HTTPS
|
// Redirect to the same host but with HTTPS
|
||||||
var redirectCode int
|
var redirectCode int
|
||||||
|
@ -158,23 +165,3 @@ func httpProxyHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
route.Proxy.ServeHTTP(w, r)
|
route.Proxy.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *HTTPRoute) RemoveFromRoutes() {
|
|
||||||
routes.HTTPRoutes.Delete(r.Alias)
|
|
||||||
}
|
|
||||||
|
|
||||||
// dummy implementation for Route interface
|
|
||||||
func (r *HTTPRoute) SetupListen() {}
|
|
||||||
func (r *HTTPRoute) Listen() {}
|
|
||||||
func (r *HTTPRoute) StopListening() {}
|
|
||||||
|
|
||||||
// TODO: default + per proxy
|
|
||||||
var transport = &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
|
||||||
DialContext: (&net.Dialer{
|
|
||||||
Timeout: 60 * time.Second,
|
|
||||||
KeepAlive: 60 * time.Second,
|
|
||||||
}).DialContext,
|
|
||||||
MaxIdleConns: 1000,
|
|
||||||
MaxIdleConnsPerHost: 1000,
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ type ProxyConfig struct {
|
||||||
Path string // http proxy only
|
Path string // http proxy only
|
||||||
PathMode string `yaml:"path_mode"` // http proxy only
|
PathMode string `yaml:"path_mode"` // http proxy only
|
||||||
|
|
||||||
provider *Provider
|
provider *Provider
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxyConfig(provider *Provider) ProxyConfig {
|
func NewProxyConfig(provider *Provider) ProxyConfig {
|
||||||
|
@ -21,7 +21,7 @@ func NewProxyConfig(provider *Provider) ProxyConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by `GetFileProxyConfigs`
|
// used by `GetFileProxyConfigs`
|
||||||
func (cfg *ProxyConfig) SetDefault() error {
|
func (cfg *ProxyConfig) SetDefaults() error {
|
||||||
if cfg.Alias == "" {
|
if cfg.Alias == "" {
|
||||||
return fmt.Errorf("alias is required")
|
return fmt.Errorf("alias is required")
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,28 @@ type Route interface {
|
||||||
RemoveFromRoutes()
|
RemoveFromRoutes()
|
||||||
}
|
}
|
||||||
|
|
||||||
var routes = initRoutes()
|
func NewRoute(cfg *ProxyConfig) (Route, error) {
|
||||||
|
if isStreamScheme(cfg.Scheme) {
|
||||||
|
id := cfg.GetID()
|
||||||
|
if routes.StreamRoutes.Contains(id) {
|
||||||
|
return nil, fmt.Errorf("duplicated %s stream %s, ignoring", cfg.Scheme, id)
|
||||||
|
}
|
||||||
|
route, err := NewStreamRoute(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
routes.StreamRoutes.Set(id, route)
|
||||||
|
return route, nil
|
||||||
|
} else {
|
||||||
|
routes.HTTPRoutes.Ensure(cfg.Alias)
|
||||||
|
route, err := NewHTTPRoute(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
routes.HTTPRoutes.Get(cfg.Alias).Add(cfg.Path, route)
|
||||||
|
return route, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isValidScheme(s string) bool {
|
func isValidScheme(s string) bool {
|
||||||
for _, v := range ValidSchemes {
|
for _, v := range ValidSchemes {
|
||||||
|
@ -45,25 +66,4 @@ func initRoutes() *Routes {
|
||||||
return &r
|
return &r
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRoute(cfg *ProxyConfig) (Route, error) {
|
var routes = initRoutes()
|
||||||
if isStreamScheme(cfg.Scheme) {
|
|
||||||
id := cfg.GetID()
|
|
||||||
if routes.StreamRoutes.Contains(id) {
|
|
||||||
return nil, fmt.Errorf("duplicated %s stream %s, ignoring", cfg.Scheme, id)
|
|
||||||
}
|
|
||||||
route, err := NewStreamRoute(cfg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
routes.StreamRoutes.Set(id, route)
|
|
||||||
return route, nil
|
|
||||||
} else {
|
|
||||||
routes.HTTPRoutes.Ensure(cfg.Alias)
|
|
||||||
route, err := NewHTTPRoute(cfg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
routes.HTTPRoutes.Get(cfg.Alias).Add(cfg.Path, route)
|
|
||||||
return route, nil
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue