package tower import ( "io/fs" "net/http" "path" "github.com/julienschmidt/httprouter" ) type Group struct { prefix string parent *Tower groupMiddlewares []Middleware } func (g *Group) Use(groupMiddlewares ...Middleware) { g.groupMiddlewares = append(g.groupMiddlewares, groupMiddlewares...) } func (g *Group) Group(prefix string, mws ...Middleware) *Group { child := &Group{ parent: g.parent, prefix: buildFullPath(g.prefix, prefix), } child.groupMiddlewares = make([]Middleware, 0, len(g.groupMiddlewares)+len(mws)) child.groupMiddlewares = append(child.groupMiddlewares, g.groupMiddlewares...) child.groupMiddlewares = append(child.groupMiddlewares, mws...) return child } func (g *Group) Static(prefix, dir string) { if prefix == "" || prefix[0] != '/' { prefix = "/" + prefix } if prefix[len(prefix)-1] == '/' { prefix = prefix[:len(prefix)-1] } prefix += "/*filepath" g.parent.router.ServeFiles(buildFullPath(g.prefix, prefix), http.Dir(dir)) } func (g *Group) StaticFS(prefix string, fsys fs.FS) { fileServer := http.FileServer(http.FS(fsys)) handler := func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { fp := p.ByName("filepath") if fp == "" { fp = "/" } fp = path.Clean("/" + fp) req := r.Clone(r.Context()) req.URL.Path = fp fileServer.ServeHTTP(w, req) } g.parent.router.Handle(http.MethodGet, buildFullPath(g.prefix, buildFullPath(prefix, "/*filepath")), handler) g.parent.router.Handle(http.MethodHead, buildFullPath(g.prefix, buildFullPath(prefix, "/*filepath")), handler) } func (g *Group) GET(path string, h Handler, routeMiddlewares ...Middleware) { g.Handle(http.MethodGet, path, h, routeMiddlewares...) } func (g *Group) POST(path string, h Handler, routeMiddlewares ...Middleware) { g.Handle(http.MethodPost, path, h, routeMiddlewares...) } func (g *Group) PUT(path string, h Handler, routeMiddlewares ...Middleware) { g.Handle(http.MethodPut, path, h, routeMiddlewares...) } func (g *Group) PATCH(path string, h Handler, routeMiddlewares ...Middleware) { g.Handle(http.MethodPatch, path, h, routeMiddlewares...) } func (g *Group) DELETE(path string, h Handler, routeMiddlewares ...Middleware) { g.Handle(http.MethodDelete, path, h, routeMiddlewares...) } func (g *Group) Handle(method string, path string, h Handler, routeMiddlewares ...Middleware) { fullPath := buildFullPath(g.prefix, path) mws := make([]Middleware, 0, len(g.groupMiddlewares)+len(routeMiddlewares)) mws = append(mws, g.groupMiddlewares...) mws = append(mws, routeMiddlewares...) g.parent.Handle(method, fullPath, h, mws...) }