package server import ( "fmt" "net/http" "git.secnex.io/secnex/api-gateway/config" "git.secnex.io/secnex/api-gateway/middlewares" "git.secnex.io/secnex/masterlog" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" ) type Gateway struct { router *chi.Mux config config.Configuration apis Apis routes *Routes } func (g *Gateway) configureProxies() { for _, api := range g.apis { masterlog.Info("Configuring proxy", map[string]interface{}{ "id": api.ID, "host": api.Host.Domain, "target": api.Target.URL.String(), }) originalDirector := api.Target.proxy.Director api.Target.proxy.Director = func(r *http.Request) { originalDirector(r) r.Host = api.Host.Domain } } } func NewGateway(cfg *config.Configuration) *Gateway { r := chi.NewRouter() for _, feature := range cfg.Gateway.Features { switch feature { case "request_id": r.Use(middleware.RequestID) case "real_ip": r.Use(middleware.RealIP) case "logger": r.Use(middlewares.LoggerMiddleware) case "host": r.Use(middlewares.HostMiddleware) } } r.Route("/_/health", func(r chi.Router) { r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) }) }) hosts := NewHosts(cfg) targets := NewTargets(cfg) apis := NewApis(cfg, hosts, targets) routes := NewRoutes(cfg, apis) return &Gateway{config: *cfg, router: r, apis: apis, routes: routes} } func (g *Gateway) Start() { masterlog.Info("Starting gateway", map[string]interface{}{ "host": g.config.Gateway.Host, "port": g.config.Gateway.Port, }) g.configureProxies() g.routes.Register(g.router) http.ListenAndServe(fmt.Sprintf("%s:%d", g.config.Gateway.Host, g.config.Gateway.Port), g.router) }