94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package router
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.lumeweb.com/LumeWeb/portal/config"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
)
|
|
|
|
type RoutableAPI interface {
|
|
Name() string
|
|
Can(w http.ResponseWriter, r *http.Request) bool
|
|
Handle(w http.ResponseWriter, r *http.Request)
|
|
Routes() (*httprouter.Router, error)
|
|
}
|
|
|
|
type APIRouter struct {
|
|
apis map[string]RoutableAPI
|
|
apiDomain map[string]string
|
|
apiHandlers map[string]http.Handler
|
|
logger *zap.Logger
|
|
config *config.Manager
|
|
}
|
|
|
|
// Implement the ServeHTTP method on our new type
|
|
func (hs APIRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if handler := hs.getHandlerByDomain(r.Host); handler != nil {
|
|
handler.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
for _, api := range hs.apis {
|
|
if api.Can(w, r) {
|
|
api.Handle(w, r)
|
|
return
|
|
}
|
|
}
|
|
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
func (hs *APIRouter) RegisterAPI(impl RoutableAPI) {
|
|
name := impl.Name()
|
|
hs.apis[name] = impl
|
|
hs.apiDomain[name+"."+hs.config.Config().Core.Domain] = name
|
|
}
|
|
|
|
func (hs *APIRouter) getHandlerByDomain(domain string) http.Handler {
|
|
if apiName := hs.apiDomain[domain]; apiName != "" {
|
|
return hs.getHandler(apiName)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (hs *APIRouter) getHandler(protocol string) http.Handler {
|
|
if handler := hs.apiHandlers[protocol]; handler == nil {
|
|
if proto := hs.apis[protocol]; proto == nil {
|
|
hs.logger.Fatal("Protocol not found", zap.String("protocol", protocol))
|
|
return nil
|
|
}
|
|
|
|
routes, err := hs.apis[protocol].Routes()
|
|
|
|
if err != nil {
|
|
hs.logger.Fatal("Error getting routes", zap.Error(err))
|
|
return nil
|
|
}
|
|
|
|
hs.apiHandlers[protocol] = routes
|
|
}
|
|
|
|
return hs.apiHandlers[protocol]
|
|
}
|
|
|
|
func NewAPIRouter() *APIRouter {
|
|
return &APIRouter{
|
|
apis: make(map[string]RoutableAPI),
|
|
apiHandlers: make(map[string]http.Handler),
|
|
apiDomain: make(map[string]string),
|
|
}
|
|
}
|
|
|
|
func (hs *APIRouter) SetLogger(logger *zap.Logger) {
|
|
hs.logger = logger
|
|
}
|
|
|
|
func (hs *APIRouter) SetConfig(config *config.Manager) {
|
|
hs.config = config
|
|
}
|