89 lines
1.5 KiB
Go
89 lines
1.5 KiB
Go
package httpsrv
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.leolab.info/lib/errs"
|
|
)
|
|
|
|
//Структура маршрута
|
|
// 0.1.0
|
|
type route struct {
|
|
value string
|
|
next map[string]*route
|
|
handler Handler
|
|
s *Server
|
|
}
|
|
|
|
//Создание маршрута
|
|
// 0.1.0
|
|
func newRoute(srv *Server) *route {
|
|
r := &route{
|
|
s: srv,
|
|
next: make(map[string]*route),
|
|
handler: nil,
|
|
}
|
|
return r
|
|
}
|
|
|
|
//Добавление маршрута
|
|
// 0.1.0
|
|
func (r *route) add(path string, h Handler) {
|
|
if path[len(path)-1] == '/' {
|
|
path = path + "index"
|
|
}
|
|
pa := strings.Split(path, "/")
|
|
r.append(pa, h)
|
|
}
|
|
|
|
//Добавление маршрута
|
|
// 0.1.0
|
|
func (r *route) append(pa []string, h Handler) {
|
|
f := pa[0]
|
|
v := ""
|
|
pa = pa[1:]
|
|
if f[0] == '$' {
|
|
v = f[1:]
|
|
f = "$"
|
|
}
|
|
tr, ok := r.next[f]
|
|
if !ok {
|
|
tr = newRoute(r.s)
|
|
r.next[f] = tr
|
|
}
|
|
if f == "$" {
|
|
tr.value = v
|
|
}
|
|
if len(pa) > 0 {
|
|
tr.append(pa, h)
|
|
} else {
|
|
tr.handler = h
|
|
}
|
|
}
|
|
|
|
//Выполнение запроса
|
|
// 0.1.0
|
|
func (r *route) Do(sr *Rec) *Rec {
|
|
f := sr.Next()
|
|
if f != "" {
|
|
if nr, ok := r.next[f]; ok {
|
|
return nr.Do(sr)
|
|
}
|
|
if nr, ok := r.next["$"]; ok {
|
|
r.s.log.Debug("Variable: " + nr.value + " = " + f)
|
|
sr.Req.Vars[nr.value] = f
|
|
return nr.Do(sr)
|
|
}
|
|
r.s.log.Error("Route not found: " + sr.Req.Lnk)
|
|
errs.RaiseError(ErrRouteNotFound, sr.Req.Lnk)
|
|
return NotFound(sr)
|
|
} else {
|
|
if r.handler != nil {
|
|
return r.handler(sr)
|
|
}
|
|
r.s.log.Error("No handler for: " + sr.Req.Lnk)
|
|
errs.RaiseError(ErrNoHandler, sr.Req.Lnk)
|
|
return NoHandler(sr)
|
|
}
|
|
}
|