111 lines
2.6 KiB
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)
|
|
}
|