Files
api-gateway/app/server/routes.go

111 lines
2.6 KiB
Go

package server
import (
"net/http"
"strings"
"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"
)
type Routes struct {
routes []Route
}
type Route struct {
ID string
Path string
StripPrefix config.StripPrefix
Security config.Security
Api *Api
}
func NewRoutes(cfg *config.Configuration, apis Apis) *Routes {
routes := make([]Route, 0)
for _, route := range cfg.Routes {
routes = append(routes, Route{
ID: route.ID,
Path: route.Path,
StripPrefix: route.StripPrefix,
Security: route.Security,
Api: apis[route.Api],
})
}
return &Routes{routes: routes}
}
func (rs *Routes) Register(r *chi.Mux) {
for _, route := range rs.routes {
masterlog.Info("Registering route", map[string]interface{}{
"id": route.ID,
"path": route.Path,
"api": route.Api.ID,
"auth_enabled": route.Security.Auth.Enabled,
"auth_header": route.Security.Auth.Header,
"auth_include": route.Security.Auth.Path.Include,
"auth_exclude": route.Security.Auth.Path.Exclude,
})
handler := route.createHandler()
r.Handle(route.Path, handler)
}
}
func (r *Route) createHandler() http.Handler {
// Start with the API (proxy) handler
handler := http.Handler(r.Api)
// Apply middlewares in reverse order (last one wraps first)
// 1. Auth middleware (if enabled)
if r.Security.Auth.Enabled {
masterlog.Debug("Route: Applying Auth middleware", map[string]interface{}{
"path": r.Path,
"header": r.Security.Auth.Header,
})
handler = middlewares.NewAuthMiddleware(
r.Security.Auth.Header,
r.Security.Auth.Type,
r.Security.Auth.Path,
r.Security.Auth.Keys,
handler,
)
}
// 2. Strip prefix middleware (if enabled)
if r.StripPrefix.Enabled {
masterlog.Debug("Route: Applying StripPrefix middleware", map[string]interface{}{
"path": r.Path,
"prefix": r.StripPrefix.Prefix,
})
handler = newStripPrefixMiddleware(r.StripPrefix.Prefix, handler)
}
return handler
}
type stripPrefixMiddleware struct {
prefix string
handler http.Handler
}
func newStripPrefixMiddleware(prefix string, handler http.Handler) http.Handler {
return &stripPrefixMiddleware{
prefix: prefix,
handler: handler,
}
}
func (m *stripPrefixMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Remove prefix from path
if strings.HasPrefix(r.URL.Path, m.prefix) {
r.URL.Path = strings.TrimPrefix(r.URL.Path, m.prefix)
// Ensure path starts with /
if !strings.HasPrefix(r.URL.Path, "/") {
r.URL.Path = "/" + r.URL.Path
}
}
m.handler.ServeHTTP(w, r)
}