support http load balancing

This commit is contained in:
fatedier
2019-07-31 00:41:58 +08:00
parent 5796c27ed5
commit b3ed863021
11 changed files with 329 additions and 110 deletions

View File

@@ -23,7 +23,6 @@ import (
"net"
"net/http"
"strings"
"sync"
"time"
frpLog "github.com/fatedier/frp/utils/log"
@@ -32,8 +31,7 @@ import (
)
var (
ErrRouterConfigConflict = errors.New("router config conflict")
ErrNoDomain = errors.New("no such domain")
ErrNoDomain = errors.New("no such domain")
)
func getHostFromAddr(addr string) (host string) {
@@ -51,21 +49,19 @@ type HttpReverseProxyOptions struct {
}
type HttpReverseProxy struct {
proxy *ReverseProxy
proxy *ReverseProxy
vhostRouter *VhostRouters
responseHeaderTimeout time.Duration
cfgMu sync.RWMutex
}
func NewHttpReverseProxy(option HttpReverseProxyOptions) *HttpReverseProxy {
func NewHttpReverseProxy(option HttpReverseProxyOptions, vhostRouter *VhostRouters) *HttpReverseProxy {
if option.ResponseHeaderTimeoutS <= 0 {
option.ResponseHeaderTimeoutS = 60
}
rp := &HttpReverseProxy{
responseHeaderTimeout: time.Duration(option.ResponseHeaderTimeoutS) * time.Second,
vhostRouter: NewVhostRouters(),
vhostRouter: vhostRouter,
}
proxy := &ReverseProxy{
Director: func(req *http.Request) {
@@ -106,21 +102,18 @@ func NewHttpReverseProxy(option HttpReverseProxyOptions) *HttpReverseProxy {
return rp
}
// Register register the route config to reverse proxy
// reverse proxy will use CreateConnFn from routeCfg to create a connection to the remote service
func (rp *HttpReverseProxy) Register(routeCfg VhostRouteConfig) error {
rp.cfgMu.Lock()
defer rp.cfgMu.Unlock()
_, ok := rp.vhostRouter.Exist(routeCfg.Domain, routeCfg.Location)
if ok {
return ErrRouterConfigConflict
} else {
rp.vhostRouter.Add(routeCfg.Domain, routeCfg.Location, &routeCfg)
err := rp.vhostRouter.Add(routeCfg.Domain, routeCfg.Location, &routeCfg)
if err != nil {
return err
}
return nil
}
// UnRegister unregister route config by domain and location
func (rp *HttpReverseProxy) UnRegister(domain string, location string) {
rp.cfgMu.Lock()
defer rp.cfgMu.Unlock()
rp.vhostRouter.Del(domain, location)
}
@@ -140,6 +133,7 @@ func (rp *HttpReverseProxy) GetHeaders(domain string, location string) (headers
return
}
// CreateConnection create a new connection by route config
func (rp *HttpReverseProxy) CreateConnection(domain string, location string, remoteAddr string) (net.Conn, error) {
vr, ok := rp.getVhost(domain, location)
if ok {
@@ -163,10 +157,8 @@ func (rp *HttpReverseProxy) CheckAuth(domain, location, user, passwd string) boo
return true
}
// getVhost get vhost router by domain and location
func (rp *HttpReverseProxy) getVhost(domain string, location string) (vr *VhostRouter, ok bool) {
rp.cfgMu.RLock()
defer rp.cfgMu.RUnlock()
// first we check the full hostname
// if not exist, then check the wildcard_domain such as *.example.com
vr, ok = rp.vhostRouter.Get(domain, location)