add http reverse proxy

This commit is contained in:
AJ ONeal 2020-07-21 03:29:49 -06:00
parent 65156756bf
commit 44dce55364
4 changed files with 60 additions and 6 deletions

View File

@ -388,9 +388,9 @@ func muxAll(
*apiHostname = os.Getenv("API_HOSTNAME")
}
if "" != *apiHostname {
listener := httpshim.NewListener()
apiListener := httpshim.NewListener()
go func() {
httpsrv.Serve(listener)
httpsrv.Serve(apiListener)
}()
fmt.Printf("Will respond to Websocket and API requests to %q\n", *apiHostname)
mux.HandleTLS(*apiHostname, acme, mux, "[Terminate TLS & Recurse] for "+*apiHostname)
@ -398,7 +398,7 @@ func muxAll(
if dbg.Debug {
fmt.Printf("[debug] Accepting API or WebSocket client %q\n", *apiHostname)
}
listener.Feed(client)
apiListener.Feed(client)
if dbg.Debug {
fmt.Printf("[debug] done with %q client\n", *apiHostname)
}
@ -426,6 +426,9 @@ func muxAll(
//}, acme, mux, "[Terminate TLS & Recurse]")
for _, fwd := range forwards {
//mux.ForwardTCP("*", "localhost:"+fwd.port, 120*time.Second)
if "https" == fwd.scheme {
mux.ReverseProxyHTTP(fwd.pattern, "localhost:"+fwd.port, 120*time.Second, "[Servername Reverse Proxy]")
}
mux.ForwardTCP(fwd.pattern, "localhost:"+fwd.port, 120*time.Second, "[Servername Forward]")
}

View File

@ -67,7 +67,13 @@ func (m *RouteMux) Serve(client net.Conn) error {
if "" == connServername {
wconn.SetServername(servername)
} else {
fmt.Printf("Has servername: current=%s new=%s\n", connServername, servername)
if connServername != servername {
fmt.Fprintf(
os.Stderr,
"[mux] Mismatch Servername: (current) %s != (new) %s\n",
connServername, servername,
)
}
wconn.SetServername(servername)
//panic(errors.New("Can't SetServername() over existing servername"))
}
@ -152,6 +158,16 @@ func (m *RouteMux) ForwardTCP(servername string, target string, timeout time.Dur
return nil
}
func (m *RouteMux) ReverseProxyHTTP(servername string, target string, timeout time.Duration, comment ...string) error {
m.routes = append(m.routes, meta{
addr: servername,
terminate: false,
handler: NewReverseProxier(target, timeout),
comment: append(comment, "")[0],
})
return nil
}
// HandleTCP creates and returns a connection to a local handler target.
func (m *RouteMux) HandleTCP(servername string, handler Handler, comment ...string) error {
// TODO check servername
@ -193,7 +209,14 @@ func (m *RouteMux) HandleTLS(servername string, acme *ACME, next Handler, commen
//NewTerminator(acme, handler)(client)
//return handler.Serve(client)
return next.Serve(TerminateTLS(wconn, acme))
go func() {
if err := next.Serve(TerminateTLS(wconn, acme)); nil != err {
fmt.Fprintf(os.Stderr, "error Terminating TLS: %s\n", err)
}
}()
// at this point, we've handled it
// TODO could we move termination further in?
return nil
}),
comment: append(comment, "")[0],
})

View File

@ -10,10 +10,14 @@ import (
"io/ioutil"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"strings"
"time"
httpshim "git.rootprojects.org/root/telebit/tunnel"
"github.com/caddyserver/certmagic"
"github.com/go-acme/lego/v3/challenge"
"github.com/go-acme/lego/v3/challenge/dns01"
@ -64,6 +68,29 @@ func NewForwarder(target string, timeout time.Duration) HandlerFunc {
}
}
func NewReverseProxier(target string, timeout time.Duration) HandlerFunc {
// TODO accept listener?
proxyListener := httpshim.NewListener()
myURL, err := url.Parse("http://" + target)
if nil != err {
panic(err)
}
// TODO headers
proxyHandler := httputil.NewSingleHostReverseProxy(myURL)
proxyServer := &http.Server{
Handler: proxyHandler,
}
go func() {
proxyServer.Serve(proxyListener)
}()
return func(client net.Conn) error {
// TODO Peek to see if this is HTTP
proxyListener.Feed(client)
return nil
}
}
// Forward port-forwards a relay (websocket) client to a target (local) server
func Forward(client net.Conn, target net.Conn, timeout time.Duration) error {
@ -234,6 +261,7 @@ func TerminateTLS(client net.Conn, acme *ACME) net.Conn {
acmecert = magic
}
// TODO NextProtos: []string{ "h2", "http/1.1" }
tlsConfig := &tls.Config{
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
return acmecert.GetCertificate(hello)

2
v1.go
View File

@ -196,7 +196,7 @@ func (p *Parser) unpackV1Header(b []byte, n int) ([]byte, error) {
}
if "end" == service {
fmt.Println("[debug] unpackV1 end")
fmt.Printf("[codec] [v1] unpack control message: 'end'\n")
p.handler.RouteBytes(p.state.srcAddr, p.state.dstAddr, []byte{})
}
return b, nil