126 lines
3.2 KiB
Go
126 lines
3.2 KiB
Go
package routing
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"git.markbailey.dev/cerbervs/ptpp/app/controller"
|
|
"git.markbailey.dev/cerbervs/ptpp/app/handler"
|
|
"git.markbailey.dev/cerbervs/ptpp/app/session"
|
|
"git.markbailey.dev/cerbervs/ptpp/lib/database"
|
|
werror "git.markbailey.dev/cerbervs/ptpp/lib/error"
|
|
"git.markbailey.dev/cerbervs/ptpp/lib/logger"
|
|
"git.markbailey.dev/cerbervs/ptpp/lib/middleware"
|
|
"git.markbailey.dev/cerbervs/ptpp/util"
|
|
)
|
|
|
|
type IRouter interface {
|
|
RegisterRoutes() http.Handler
|
|
}
|
|
|
|
type Route struct {
|
|
Controller controller.IController
|
|
Path string
|
|
Name string
|
|
}
|
|
|
|
type Router struct {
|
|
Mux *http.ServeMux
|
|
Middleware *[]middleware.Func
|
|
BasePath string
|
|
SubRouters []*Router
|
|
Routes []Route
|
|
}
|
|
|
|
var (
|
|
rtr *Router
|
|
rtrOnce sync.Once
|
|
mux *http.ServeMux
|
|
muxOnce sync.Once
|
|
fsOnce sync.Once
|
|
sess session.IManager
|
|
)
|
|
|
|
func (r *Router) HandleAllRequestMethods(route Route, fullPath string) {
|
|
ctx := controller.ControllerCtx{RouterCtx: rtr}
|
|
c := route.Controller.Init(sess, database.ChooseDB(), logger.NewCompositeLogger(), ctx)
|
|
r.Mux.Handle("GET "+fullPath, handler.HandlerFunc(c.Get))
|
|
r.Mux.Handle("OPTIONS "+fullPath, handler.HandlerFunc(c.Options))
|
|
r.Mux.Handle("TRACE "+fullPath, handler.HandlerFunc(c.Trace))
|
|
r.Mux.Handle("PUT "+fullPath, handler.HandlerFunc(c.Put))
|
|
r.Mux.Handle("DELETE "+fullPath, handler.HandlerFunc(c.Delete))
|
|
r.Mux.Handle("POST "+fullPath, handler.HandlerFunc(c.Post))
|
|
r.Mux.Handle("PATCH "+fullPath, handler.HandlerFunc(c.Patch))
|
|
r.Mux.Handle("CONNECT "+fullPath, handler.HandlerFunc(c.Connect))
|
|
}
|
|
|
|
func (r *Router) RegisterRoutes() http.Handler {
|
|
rtrOnce.Do(func() { rtr = r })
|
|
muxOnce.Do(func() { mux = http.NewServeMux(); r.Mux = mux })
|
|
fsOnce.Do(func() { r.RegisterFs() })
|
|
|
|
if r.Mux == nil {
|
|
r.Mux = http.NewServeMux()
|
|
}
|
|
|
|
for _, route := range r.Routes {
|
|
r.HandleAllRequestMethods(route, r.BasePath+route.Path)
|
|
}
|
|
|
|
for _, subRouter := range r.SubRouters {
|
|
r.Mux.Handle(
|
|
"GET "+r.BasePath+subRouter.BasePath,
|
|
http.StripPrefix(subRouter.BasePath, subRouter.RegisterRoutes()),
|
|
)
|
|
}
|
|
|
|
if r.Middleware != nil {
|
|
mw := middleware.Compose(*r.Middleware)
|
|
mctx := middleware.MiddlewareCtx{RouterCtx: rtr}
|
|
return mw(mux, mctx)
|
|
}
|
|
|
|
return mux
|
|
}
|
|
|
|
func (r *Router) RegisterFs() {
|
|
fs := http.FileServer(http.Dir(util.GetFullyQualifiedPath("/public")))
|
|
r.Mux.Handle("GET "+r.BasePath+"public/", http.StripPrefix("/public/", fs))
|
|
}
|
|
|
|
type RouteMapping struct {
|
|
Path string
|
|
Name string
|
|
}
|
|
|
|
func (r *Router) GetFlatRouteList() []RouteMapping {
|
|
routes := []RouteMapping{}
|
|
for _, route := range r.Routes {
|
|
routes = append(routes, RouteMapping{Path: r.BasePath + route.Path, Name: route.Name})
|
|
}
|
|
for _, subRouter := range r.SubRouters {
|
|
routes = append(routes, subRouter.GetFlatRouteList()...)
|
|
}
|
|
return routes
|
|
}
|
|
|
|
func (r *Router) GetRouteByName(name string) (string, error) {
|
|
for _, route := range r.GetFlatRouteList() {
|
|
if route.Name == name {
|
|
return route.Path, nil
|
|
}
|
|
}
|
|
return "", werror.Wrap(errors.New(name+" does not exist"), "Route not found")
|
|
}
|
|
|
|
func init() {
|
|
var err error
|
|
|
|
sess, err = session.NewManager("memory", "ptpp", 3600)
|
|
go sess.GC()
|
|
if err != nil {
|
|
panic(werror.Wrap(err, "Error creating session manager"))
|
|
}
|
|
}
|