add http reverse proxy
This commit is contained in:
parent
65156756bf
commit
44dce55364
|
@ -388,9 +388,9 @@ func muxAll(
|
||||||
*apiHostname = os.Getenv("API_HOSTNAME")
|
*apiHostname = os.Getenv("API_HOSTNAME")
|
||||||
}
|
}
|
||||||
if "" != *apiHostname {
|
if "" != *apiHostname {
|
||||||
listener := httpshim.NewListener()
|
apiListener := httpshim.NewListener()
|
||||||
go func() {
|
go func() {
|
||||||
httpsrv.Serve(listener)
|
httpsrv.Serve(apiListener)
|
||||||
}()
|
}()
|
||||||
fmt.Printf("Will respond to Websocket and API requests to %q\n", *apiHostname)
|
fmt.Printf("Will respond to Websocket and API requests to %q\n", *apiHostname)
|
||||||
mux.HandleTLS(*apiHostname, acme, mux, "[Terminate TLS & Recurse] for "+*apiHostname)
|
mux.HandleTLS(*apiHostname, acme, mux, "[Terminate TLS & Recurse] for "+*apiHostname)
|
||||||
|
@ -398,7 +398,7 @@ func muxAll(
|
||||||
if dbg.Debug {
|
if dbg.Debug {
|
||||||
fmt.Printf("[debug] Accepting API or WebSocket client %q\n", *apiHostname)
|
fmt.Printf("[debug] Accepting API or WebSocket client %q\n", *apiHostname)
|
||||||
}
|
}
|
||||||
listener.Feed(client)
|
apiListener.Feed(client)
|
||||||
if dbg.Debug {
|
if dbg.Debug {
|
||||||
fmt.Printf("[debug] done with %q client\n", *apiHostname)
|
fmt.Printf("[debug] done with %q client\n", *apiHostname)
|
||||||
}
|
}
|
||||||
|
@ -426,6 +426,9 @@ func muxAll(
|
||||||
//}, acme, mux, "[Terminate TLS & Recurse]")
|
//}, acme, mux, "[Terminate TLS & Recurse]")
|
||||||
for _, fwd := range forwards {
|
for _, fwd := range forwards {
|
||||||
//mux.ForwardTCP("*", "localhost:"+fwd.port, 120*time.Second)
|
//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]")
|
mux.ForwardTCP(fwd.pattern, "localhost:"+fwd.port, 120*time.Second, "[Servername Forward]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
27
routemux.go
27
routemux.go
|
@ -67,7 +67,13 @@ func (m *RouteMux) Serve(client net.Conn) error {
|
||||||
if "" == connServername {
|
if "" == connServername {
|
||||||
wconn.SetServername(servername)
|
wconn.SetServername(servername)
|
||||||
} else {
|
} 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)
|
wconn.SetServername(servername)
|
||||||
//panic(errors.New("Can't SetServername() over existing 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
|
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.
|
// HandleTCP creates and returns a connection to a local handler target.
|
||||||
func (m *RouteMux) HandleTCP(servername string, handler Handler, comment ...string) error {
|
func (m *RouteMux) HandleTCP(servername string, handler Handler, comment ...string) error {
|
||||||
// TODO check servername
|
// TODO check servername
|
||||||
|
@ -193,7 +209,14 @@ func (m *RouteMux) HandleTLS(servername string, acme *ACME, next Handler, commen
|
||||||
|
|
||||||
//NewTerminator(acme, handler)(client)
|
//NewTerminator(acme, handler)(client)
|
||||||
//return handler.Serve(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],
|
comment: append(comment, "")[0],
|
||||||
})
|
})
|
||||||
|
|
28
telebit.go
28
telebit.go
|
@ -10,10 +10,14 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
httpshim "git.rootprojects.org/root/telebit/tunnel"
|
||||||
|
|
||||||
"github.com/caddyserver/certmagic"
|
"github.com/caddyserver/certmagic"
|
||||||
"github.com/go-acme/lego/v3/challenge"
|
"github.com/go-acme/lego/v3/challenge"
|
||||||
"github.com/go-acme/lego/v3/challenge/dns01"
|
"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
|
// Forward port-forwards a relay (websocket) client to a target (local) server
|
||||||
func Forward(client net.Conn, target net.Conn, timeout time.Duration) error {
|
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
|
acmecert = magic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO NextProtos: []string{ "h2", "http/1.1" }
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
return acmecert.GetCertificate(hello)
|
return acmecert.GetCertificate(hello)
|
||||||
|
|
2
v1.go
2
v1.go
|
@ -196,7 +196,7 @@ func (p *Parser) unpackV1Header(b []byte, n int) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if "end" == service {
|
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{})
|
p.handler.RouteBytes(p.state.srcAddr, p.state.dstAddr, []byte{})
|
||||||
}
|
}
|
||||||
return b, nil
|
return b, nil
|
||||||
|
|
Loading…
Reference in New Issue