tcp multiplexing over http connect tunnel

This commit is contained in:
fatedier
2020-03-05 21:47:49 +08:00
committed by GitHub
parent 0b9124d4fd
commit 1db091b381
22 changed files with 565 additions and 26 deletions

View File

@@ -26,6 +26,7 @@ import (
"time"
frpLog "github.com/fatedier/frp/utils/log"
"github.com/fatedier/frp/utils/util"
"github.com/fatedier/golib/pool"
)
@@ -34,16 +35,6 @@ var (
ErrNoDomain = errors.New("no such domain")
)
func getHostFromAddr(addr string) (host string) {
strs := strings.Split(addr, ":")
if len(strs) > 1 {
host = strs[0]
} else {
host = addr
}
return
}
type HttpReverseProxyOptions struct {
ResponseHeaderTimeoutS int64
}
@@ -67,7 +58,7 @@ func NewHttpReverseProxy(option HttpReverseProxyOptions, vhostRouter *VhostRoute
Director: func(req *http.Request) {
req.URL.Scheme = "http"
url := req.Context().Value("url").(string)
oldHost := getHostFromAddr(req.Context().Value("host").(string))
oldHost := util.GetHostFromAddr(req.Context().Value("host").(string))
host := rp.GetRealHost(oldHost, url)
if host != "" {
req.Host = host
@@ -84,7 +75,7 @@ func NewHttpReverseProxy(option HttpReverseProxyOptions, vhostRouter *VhostRoute
DisableKeepAlives: true,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
url := ctx.Value("url").(string)
host := getHostFromAddr(ctx.Value("host").(string))
host := util.GetHostFromAddr(ctx.Value("host").(string))
remote := ctx.Value("remote").(string)
return rp.CreateConnection(host, url, remote)
},
@@ -187,7 +178,7 @@ func (rp *HttpReverseProxy) getVhost(domain string, location string) (vr *VhostR
}
func (rp *HttpReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
domain := getHostFromAddr(req.Host)
domain := util.GetHostFromAddr(req.Host)
location := req.URL.Path
user, passwd, _ := req.BasicAuth()
if !rp.CheckAuth(domain, location, user, passwd) {

View File

@@ -48,7 +48,7 @@ type HttpsMuxer struct {
}
func NewHttpsMuxer(listener net.Listener, timeout time.Duration) (*HttpsMuxer, error) {
mux, err := NewVhostMuxer(listener, GetHttpsHostname, nil, nil, timeout)
mux, err := NewVhostMuxer(listener, GetHttpsHostname, nil, nil, nil, timeout)
return &HttpsMuxer{mux}, err
}

View File

@@ -29,22 +29,25 @@ import (
type muxFunc func(net.Conn) (net.Conn, map[string]string, error)
type httpAuthFunc func(net.Conn, string, string, string) (bool, error)
type hostRewriteFunc func(net.Conn, string) (net.Conn, error)
type successFunc func(net.Conn) error
type VhostMuxer struct {
listener net.Listener
timeout time.Duration
vhostFunc muxFunc
authFunc httpAuthFunc
successFunc successFunc
rewriteFunc hostRewriteFunc
registryRouter *VhostRouters
}
func NewVhostMuxer(listener net.Listener, vhostFunc muxFunc, authFunc httpAuthFunc, rewriteFunc hostRewriteFunc, timeout time.Duration) (mux *VhostMuxer, err error) {
func NewVhostMuxer(listener net.Listener, vhostFunc muxFunc, authFunc httpAuthFunc, successFunc successFunc, rewriteFunc hostRewriteFunc, timeout time.Duration) (mux *VhostMuxer, err error) {
mux = &VhostMuxer{
listener: listener,
timeout: timeout,
vhostFunc: vhostFunc,
authFunc: authFunc,
successFunc: successFunc,
rewriteFunc: rewriteFunc,
registryRouter: NewVhostRouters(),
}
@@ -149,7 +152,15 @@ func (v *VhostMuxer) handle(c net.Conn) {
c.Close()
return
}
xl := xlog.FromContextSafe(l.ctx)
if v.successFunc != nil {
if err := v.successFunc(c); err != nil {
xl.Info("success func failure on vhost connection: %v", err)
c.Close()
return
}
}
// if authFunc is exist and userName/password is set
// then verify user access