You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
3.5 KiB
168 lines
3.5 KiB
/* |
|
------------------------------------------------------------------------------------------------------------------------ |
|
####### kong ####### Copyright (c) 2021-2022 losyme ################################################ MIT License ####### |
|
------------------------------------------------------------------------------------------------------------------------ |
|
*/ |
|
|
|
package router |
|
|
|
import ( |
|
"net/http" |
|
"strings" |
|
|
|
"forge.chapril.org/losyme/errors" |
|
"forge.chapril.org/losyme/kong/context" |
|
) |
|
|
|
type SubRouter struct { |
|
rrType context.RendererType |
|
ctxPool *context.Pool |
|
middlewares []Middleware |
|
routes *segment |
|
OnNotFound HandlerFunc |
|
} |
|
|
|
func newSubRouter(rrt context.RendererType) *SubRouter { |
|
return &SubRouter{ |
|
rrType: rrt, |
|
ctxPool: context.NewPool(), |
|
routes: &segment{}, |
|
} |
|
} |
|
|
|
func (sr *SubRouter) findSegment(path string) *segment { |
|
seg := sr.routes |
|
|
|
for _, ps := range strings.Split(strings.Trim(path, "/"), "/") { |
|
if ps == "" { |
|
continue |
|
} |
|
|
|
seg = seg.next(ps) |
|
} |
|
|
|
return seg |
|
} |
|
|
|
func (sr *SubRouter) Use(mdlw ...Middleware) { |
|
sr.middlewares = append(sr.middlewares, mdlw...) |
|
} |
|
|
|
func (sr *SubRouter) Add(method, path string, handler HandlerFunc) { |
|
seg := sr.findSegment(path) |
|
|
|
if seg.handlers == nil { |
|
seg.handlers = make(map[string]HandlerFunc) |
|
} |
|
|
|
seg.handlers[strings.ToUpper(method)] = handler |
|
} |
|
|
|
func (sr *SubRouter) Any(path string, handler HandlerFunc) { |
|
sr.Add("*", path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Delete(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodDelete, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Get(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodGet, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Head(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodHead, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Options(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodOptions, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Patch(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodPatch, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Post(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodPost, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Put(path string, handler HandlerFunc) { |
|
sr.Add(http.MethodPut, path, handler) |
|
} |
|
|
|
func (sr *SubRouter) Group(path string, fn func(*Group)) { |
|
fn(&Group{ |
|
sr: sr, |
|
path: path, |
|
}) |
|
} |
|
|
|
func (sr *SubRouter) ServeFiles(path string, fs http.FileSystem) error { |
|
const param = "filepath" |
|
const suffix = "/:" + param |
|
|
|
if len(path) < 10 || path[len(path)-10:] != suffix { |
|
return errors.New("path must end with "+suffix, "path", path) ////////////////////////////////////////////////// |
|
} |
|
|
|
fileServer := http.FileServer(fs) |
|
|
|
sr.Get(path, func(c *context.Context) error { |
|
c.Request.URL.Path = c.Param(param) |
|
fileServer.ServeHTTP(c.Response, c.Request) |
|
|
|
return nil |
|
}) |
|
|
|
return nil |
|
} |
|
|
|
func (sr *SubRouter) match(path string, ctx *context.Context, ms *middlewares) *segment { |
|
var ps string |
|
seg := sr.routes |
|
|
|
for path != "" { |
|
i := strings.Index(path, "/") |
|
if i == -1 { |
|
ps = path |
|
path = "" |
|
} else if i == 0 { |
|
path = path[1:] |
|
continue |
|
} else { |
|
ps = path[:i] |
|
path = path[i+1:] |
|
} |
|
|
|
if seg.routes == nil { |
|
return nil |
|
} |
|
|
|
tmp, ok := seg.routes[ps] |
|
if !ok { |
|
for _, t := range seg.routes { |
|
if t.param != "" { |
|
ok = true |
|
tmp = t |
|
ctx.AddParam(t.param, ps) |
|
|
|
break |
|
} |
|
} |
|
|
|
if !ok { |
|
return nil |
|
} |
|
} |
|
|
|
seg = tmp |
|
|
|
ms.list = append(ms.list, seg.middlewares...) |
|
} |
|
|
|
return seg |
|
} |
|
|
|
/* |
|
######################################################################################################## @(°_°)@ ####### |
|
*/
|
|
|