165 lines
4.8 KiB
Go
165 lines
4.8 KiB
Go
/*
|
|
Example:
|
|
|
|
rp1 := reverseproxy.New(ctx, "http://localhost:8080")
|
|
rp2 := reverseproxy.New(ctx, "http://localhost:3001")
|
|
rp3 := reverseproxy.New(ctx, "http://localhost:3002")
|
|
router := router.NewRouter()
|
|
pr1 := router.NewHostRouter("keycloak.z.com")
|
|
pr1.Handler(rp1)
|
|
|
|
go func() {
|
|
s := server.New().Name("proxy1").Port(443).Router(router)
|
|
s.CertKey(CERTS_PATH, "z.com.cert.pem", "z.com.key.pem")
|
|
err := s.ListenAndServeTLS()
|
|
if err != nil {
|
|
log.Println(err.Error())
|
|
}
|
|
}()
|
|
*/
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/zeevdiukman/go-helper"
|
|
"github.com/zeevdiukman/go-reverseproxy"
|
|
"github.com/zeevdiukman/go-router"
|
|
"github.com/zeevdiukman/go-server"
|
|
"github.com/zeevdiukman/zprox/internal/config"
|
|
)
|
|
|
|
// type ReverseProxy struct {
|
|
// Proxy *http.Handler
|
|
// Domain string
|
|
// Router *router.HostRouter
|
|
// }
|
|
|
|
const CERTS_PATH string = "./assets/certs/"
|
|
|
|
type App struct {
|
|
// Routers struct {
|
|
// Maps map[string]*router.HostRouter
|
|
// }
|
|
// map[string]*router.HostRouter
|
|
// Rules map[string]map[string]string
|
|
// Services map[string]string
|
|
DomainRouters DomainRouters
|
|
EntryPoints EntryPoints
|
|
}
|
|
|
|
type DomainRouters map[string]*router.DomainRouter
|
|
type EntryPoints map[string]*EntryPoint
|
|
type EntryPoint struct {
|
|
*server.Server
|
|
*router.Router
|
|
HostRouters HostRouters
|
|
}
|
|
type HostRouters map[string]*router.DomainRouter
|
|
|
|
func New() *App {
|
|
return &App{}
|
|
}
|
|
|
|
func (ep EntryPoints) ForEach(f func(string, *EntryPoint)) {
|
|
forEach(ep, f)
|
|
}
|
|
|
|
func forEach[K comparable, V any](mp map[K]V, f func(K, V)) {
|
|
for k, v := range mp {
|
|
f(k, v)
|
|
}
|
|
}
|
|
|
|
// main is the entry point of the z application.
|
|
// It initializes and configures the application, sets up entry points,
|
|
// configures routers, and starts the servers. It also starts test HTTP servers
|
|
// for demonstration purposes.
|
|
func main() {
|
|
helper.AppRunner(true, func() {
|
|
helper.Clear()
|
|
ctx := context.Background()
|
|
app := New()
|
|
conf := config.NewConfig()
|
|
activeEntryPoints := make(map[string]bool)
|
|
conf.EntryPoints.ForEach(func(entryPointName string, entryPointConfig *config.EntryPoint) {
|
|
conf.HTTP.Routers.ForEach(func(rName string, rConfig *config.Router) {
|
|
if rConfig.EntryPoint == entryPointName {
|
|
activeEntryPoints[entryPointName] = true
|
|
|
|
}
|
|
})
|
|
})
|
|
conf.EntryPoints.ForEach(func(entryPointName string, entryPointConfig *config.EntryPoint) {
|
|
if isUsed, ok := activeEntryPoints[entryPointName]; ok && isUsed {
|
|
if _, ok := app.EntryPoints[entryPointName]; !ok {
|
|
app.EntryPoints = make(map[string]*EntryPoint)
|
|
}
|
|
r := router.NewRouter()
|
|
_, portStr, _ := strings.Cut(entryPointConfig.Address, ":")
|
|
port, _ := strconv.Atoi(portStr)
|
|
s := server.New().Name(entryPointName).Port(port)
|
|
s.Router(r)
|
|
app.EntryPoints[entryPointName] = &EntryPoint{
|
|
Server: s,
|
|
Router: r,
|
|
HostRouters: make(map[string]*router.DomainRouter),
|
|
}
|
|
}
|
|
})
|
|
conf.HTTP.Routers.ForEach(func(rName string, rConfig *config.Router) {
|
|
if isUsed, ok := activeEntryPoints[rConfig.EntryPoint]; ok && isUsed {
|
|
domain := rConfig.Rules.Map["Domain"].Value
|
|
serviceURL := conf.HTTP.Services[rConfig.Service].URL
|
|
if _, ok := app.EntryPoints[rConfig.EntryPoint]; ok {
|
|
entryPoint := app.EntryPoints[rConfig.EntryPoint]
|
|
if _, ok := entryPoint.HostRouters[domain]; !ok {
|
|
entryPoint.HostRouters = make(map[string]*router.DomainRouter)
|
|
}
|
|
rpHandler := reverseproxy.New(ctx, serviceURL)
|
|
r := app.EntryPoints[rConfig.EntryPoint].Router
|
|
hostRouter := r.NewDomainRouter(domain)
|
|
hostRouter.Handler(rpHandler)
|
|
app.EntryPoints[rConfig.EntryPoint].HostRouters[domain] = hostRouter
|
|
}
|
|
}
|
|
})
|
|
app.EntryPoints.ForEach(func(s string, ep *EntryPoint) {
|
|
conf.HTTP.Routers.ForEach(func(rName string, rConfig *config.Router) {
|
|
if s == rConfig.EntryPoint {
|
|
|
|
}
|
|
})
|
|
ep.CertKey(CERTS_PATH, "z.com.cert.pem", "z.com.key.pem")
|
|
go ep.ListenAndServeTLS()
|
|
})
|
|
helper.StartTestHTTPServer(3001, "app1")
|
|
helper.StartTestHTTPServer(3002, "app2")
|
|
})
|
|
|
|
}
|
|
|
|
// func main() {
|
|
// Test()
|
|
// }
|
|
func Test() {
|
|
ctx := context.Background()
|
|
conf := config.NewConfig()
|
|
rp1 := reverseproxy.New(ctx, conf.HTTP.Services["keycloak"].URL)
|
|
rp2 := reverseproxy.New(ctx, conf.HTTP.Services["app1"].URL)
|
|
rp3 := reverseproxy.New(ctx, conf.HTTP.Services["app2"].URL)
|
|
|
|
r := router.NewRouter()
|
|
r.NewDomainRouter(conf.HTTP.Routers["keycloak"].Rules.Map["Domain"].Value).Handler(rp1)
|
|
r.NewDomainRouter(conf.HTTP.Routers["app1"].Rules.Map["Domain"].Value).Handler(rp2)
|
|
r.NewDomainRouter(conf.HTTP.Routers["app2"].Rules.Map["Domain"].Value).Handler(rp3)
|
|
|
|
s := server.New().Name("proxy1").Port(443).Router(r)
|
|
s.CertKey(CERTS_PATH, "z.com.cert.pem", "z.com.key.pem")
|
|
go s.ListenAndServeTLS()
|
|
helper.StartTestHTTPServer(3001, "app1")
|
|
helper.StartTestHTTPServer(3002, "app2")
|
|
select {}
|
|
}
|