1 Star 0 Fork 41

superzhoulin/lessgo

forked from andeyalee/lessgo 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
lessgo.go 12.68 KB
一键复制 编辑 原始数据 按行查看 历史
henrylee2cn 提交于 2017-01-07 00:55 . gofmt -w
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
/*
Package lessgo implements a simple, stable, efficient and flexible web framework for Go.
Author1: https://github.com/henrylee2cn
Author2: https://github.com/changyu72
*/
package lessgo
import (
"errors"
"fmt"
"os"
"os/exec"
"path"
"runtime"
"sync"
_ "github.com/henrylee2cn/lessgo/_fixture"
"github.com/henrylee2cn/lessgo/logs"
"github.com/henrylee2cn/lessgo/session"
"github.com/henrylee2cn/lessgo/utils"
"github.com/henrylee2cn/lessgoext/uuid"
)
type Lessgo struct {
*App
*config
//全局操作列表
apiHandlers []*ApiHandler
//全局中间件列表
apiMiddlewares []*ApiMiddleware
// 路由执行前后的中间件登记
virtBefore []*MiddlewareConfig //处理链中路由操作之前的中间件子链
virtAfter []*MiddlewareConfig //处理链中路由操作之后的中间件子链
virtStatics []*VirtStatic //单独注册的静态目录虚拟路由(无法在Root()下使用)
virtFiles []*VirtFile //单独注册的静态文件虚拟路由(无法在Root()下使用)
// 用于构建最终真实路由的虚拟路由;
// 初始值为源码中定义的路由,之后追加配置中定义的路由;
// 配置路由为空时,复制源码中定义的路由到配置路由;
// 再次运行时,直接读取配置路由覆盖自身;
// 源码因修改产生冲突时,以源码路由为主;
// 修改配置路由时,不允许和源码路由冲突;
// 源码路由只允许在配置中增加子节点。
virtRouter *VirtRouter
home string //根路径"/"对应的url
serverEnable bool //服务是否启用
lock sync.RWMutex
}
const (
NAME = "Lessgo"
VERSION = "0.8"
ADDRESS = "https://github.com/henrylee2cn/lessgo"
banner = `
/- less is more
/- __ __ __ __ __
/- /__/ /_ /_ / / / /
/___ /__ __/ __/ /__/ /__/
/ ` + VERSION + `
__/ ` + "\n"
)
var (
// 全局配置实例
Config = func() *config {
fmt.Printf("%s\n(%s)\n\n", banner, ADDRESS)
c := newConfig()
err := c.LoadMainConfig()
if err != nil {
fmt.Println(err)
}
return c
}()
// 初始化全局Lessgo实例
lessgo = newLessgo()
// 初始化全局App实例
app = newApp()
// 全局运行日志实例(来自数据库的日志除外)
Log = func() logs.Logger {
l := logs.NewLogger(1000)
l.AddAdapter("console", "")
l.AddAdapter("file", `{"filename":"`+LOG_FILE+`"}`)
return l
}()
// 软件自身md5值
Md5 = func() string {
file, _ := exec.LookPath(os.Args[0])
info, _ := os.Stat(file)
return utils.MakeUnique(info.ModTime())
}()
)
// 返回设置的主页
func GetHome() string {
return lessgo.home
}
// 设置主页(内部已默认为"/")
func SetHome(homeurl string) {
lessgo.home = homeurl
}
// 查询网站服务状态
func ServerEnable() bool {
lessgo.lock.RLock()
defer lessgo.lock.RUnlock()
return lessgo.serverEnable
}
// 开启网站服务
func EnableServer() {
lessgo.lock.Lock()
lessgo.serverEnable = true
lessgo.lock.Unlock()
}
// 关闭网站服务
func DisableServer() {
lessgo.lock.Lock()
lessgo.serverEnable = false
lessgo.lock.Unlock()
}
// Session管理平台实例
func Sessions() *session.Manager {
return app.Sessions()
}
// 设置获取请求过程中恐慌Stack信息的函数(内部有默认实现)
func SetPanicStackFunc(fn func(rcv interface{}) string) {
app.SetPanicStackFunc(fn)
}
// 设置失败状态默认的响应操作(内部有默认实现)
func SetFailureHandler(fn func(c *Context, code int, errString string) error) {
app.SetFailureHandler(fn)
}
// 设置捆绑数据处理接口(内部有默认实现)
func SetBinder(b Binder) {
app.SetBinder(b)
}
// 设置html模板处理接口(内部有默认实现)
func SetRenderer(r Renderer) {
app.SetRenderer(r)
}
func TemplateVariable(name string, fn interface{}) {
app.TemplateVariable(name, fn)
}
// 判断当前是否为调试模式
func Debug() bool {
return app.Debug()
}
// 设置运行模式
func SetDebug(on bool) {
app.SetDebug(on)
}
// 判断文件缓存是否开启
func CanMemoryCache() bool {
return app.CanMemoryCache()
}
// 启用文件缓存
func EnableMemoryCache() {
app.memoryCache.SetEnable(true)
}
// 关闭文件缓存
func DisableMemoryCache() {
app.memoryCache.SetEnable(false)
}
// 主动刷新缓存文件
func RefreshMemoryCache() {
app.memoryCache.TriggerScan()
}
// 获取已注册的操作列表
func Handlers() []*ApiHandler {
return lessgo.apiHandlers
}
// 获取已注册的中间件列表
func Middlewares() []*ApiMiddleware {
return lessgo.apiMiddlewares
}
// 返回当前虚拟的路由列表(不含单独注册的静态路由VirtFiles/VirtStatics)
func VirtRoutes() []*VirtRouter {
return lessgo.virtRouter.Progeny()
}
// 返回单独注册的静态文件虚拟路由列表(非Root()下注册)
func VirtFiles() []*VirtFile {
return lessgo.virtFiles
}
// 返回单独注册的静态目录虚拟路由列表(非Root()下注册)
func VirtStatics() []*VirtStatic {
return lessgo.virtStatics
}
// 返回底层注册的路由列表(全部真实注册的路由)
func RealRoutes() []Route {
return app.RealRoutes()
}
// 虚拟路由根节点
func RootRouter() *VirtRouter {
return lessgo.virtRouter
}
// 操作列表(禁止修改)
func ApiHandlerList() []*ApiHandler {
return lessgo.apiHandlers
}
// 添加到处理链最前端的中间件(子链)
func PreUse(middlewares ...interface{}) error {
ms, err := WrapMiddlewareConfigs(middlewares)
if err != nil {
return err
}
lessgo.virtBefore = append(ms, lessgo.virtBefore...)
return nil
}
// 插入到处理链中路由操作前一位的中间件(子链)
func BeforeUse(middlewares ...interface{}) error {
ms, err := WrapMiddlewareConfigs(middlewares)
if err != nil {
return err
}
lessgo.virtBefore = append(lessgo.virtBefore, ms...)
return nil
}
// 插入到处理链中路由操作后一位的中间件(子链)
func AfterUse(middlewares ...interface{}) error {
ms, err := WrapMiddlewareConfigs(middlewares)
if err != nil {
return err
}
lessgo.virtAfter = append(ms, lessgo.virtAfter...)
return nil
}
// 追加到处理链最末端的中间件(子链)
func SufUse(middlewares ...interface{}) error {
ms, err := WrapMiddlewareConfigs(middlewares)
if err != nil {
return err
}
lessgo.virtAfter = append(lessgo.virtAfter, ms...)
return nil
}
// 单独注册静态文件虚拟路由VirtFile(无法在Root()下使用)
func File(path, file string, middlewares ...interface{}) error {
ms, err := WrapMiddlewareConfigs(middlewares)
if err != nil {
return err
}
for _, v := range lessgo.virtFiles {
if v.Path == path {
v.File = file
v.Middlewares = ms
return nil
}
}
lessgo.virtFiles = append(lessgo.virtFiles, &VirtFile{
Path: path,
File: file,
Middlewares: ms,
})
return nil
}
// 单独注册静态目录虚拟路由VirtStatic(无法在Root()下使用)
func Static(prefix, root string, middlewares ...interface{}) error {
ms, err := WrapMiddlewareConfigs(middlewares)
if err != nil {
return err
}
for _, v := range lessgo.virtStatics {
if v.Prefix == prefix {
v.Root = root
v.Middlewares = ms
return nil
}
}
lessgo.virtStatics = append(lessgo.virtStatics, &VirtStatic{
Prefix: prefix,
Root: root,
Middlewares: ms,
})
return nil
}
// 清空用户添加到处理链中路由操作前的所有中间件(子链)
func ResetBefore() {
lessgo.virtBefore = lessgo.virtBefore[:0]
registerBefore()
}
// 清空用户添加到处理链中路由操作后的所有中间件(子链)
func ResetAfter() {
lessgo.virtAfter = lessgo.virtAfter[:0]
registerAfter()
}
// 清空用户单独注册静态目录虚拟路由VirtFile
func ResetStatics() {
lessgo.virtStatics = lessgo.virtStatics[:0]
registerStatics()
}
// 清空用户单独注册静态文件虚拟路由VirtFile
func ResetFiles() {
lessgo.virtFiles = lessgo.virtFiles[:0]
registerFiles()
}
// 创建静态目录服务的操作(用于在Root()下)
func StaticFunc(root string) HandlerFunc {
return func(c *Context) error {
return c.File(path.Join(root, c.PathParamByIndex(0)))
}
}
// 从根路由开始配置虚拟路由(必须在init()中调用)
func Root(nodes ...*VirtRouter) {
var err error
for _, node := range nodes {
if node == nil {
continue
}
err = lessgo.virtRouter.addChild(node)
if err != nil {
Log.Error("%v", err)
}
}
}
// 配置虚拟路由分组(必须在init()中调用)
func Branch(prefix, desc string, nodes ...*VirtRouter) *VirtRouter {
parent := NewGroupVirtRouter(prefix, desc)
parent.Dynamic = false
var err error
for _, node := range nodes {
if node == nil {
continue
}
err = parent.addChild(node)
if err != nil {
Log.Error("%v", err)
}
}
return parent
}
// 配置虚拟路由操作(必须在init()中调用)
func Leaf(prefix string, apiHandler *ApiHandler, middlewares ...*ApiMiddleware) *VirtRouter {
prefix = cleanPrefix(prefix)
ms := make([]*MiddlewareConfig, len(middlewares))
for i, m := range middlewares {
m.init()
ms[i] = m.NewMiddlewareConfig()
}
vr := &VirtRouter{
Id: uuid.New().String(),
Type: HANDLER,
Prefix: prefix,
Enable: true,
Dynamic: false,
Middlewares: ms,
apiHandler: apiHandler.init(),
Hid: apiHandler.id,
}
return vr
}
// 自动转换某些允许的函数为中间件函数.
func WrapMiddleware(h interface{}) MiddlewareFunc {
var x HandlerFunc
switch t := h.(type) {
case MiddlewareFunc:
return t
case func(HandlerFunc) HandlerFunc:
return MiddlewareFunc(t)
case HandlerFunc:
x = t
case func(*Context) error:
x = HandlerFunc(t)
default:
panic("[" + utils.ObjectName(h) + "] can not be converted to MiddlewareFunc.")
}
return func(next HandlerFunc) HandlerFunc {
return func(c *Context) error {
if err := x(c); err != nil {
return err
}
return next(c)
}
}
}
// 自动转换某些允许的对象为中间件配置类型.
func WrapMiddlewareConfigs(middlewares []interface{}) ([]*MiddlewareConfig, error) {
ms := make([]*MiddlewareConfig, len(middlewares))
for i, o := range middlewares {
switch m := o.(type) {
case *MiddlewareConfig:
ms[i] = m
case MiddlewareConfig:
ms[i] = &m
case *ApiMiddleware:
ms[i] = m.init().NewMiddlewareConfig()
case ApiMiddleware:
ms[i] = m.init().NewMiddlewareConfig()
default:
return ms, errors.New("[" + utils.ObjectName(m) + "] can not be converted to *MiddlewareConfig.")
}
}
return ms, nil
}
// Reregister real router
func ReregisterRouter(reasons ...string) {
if len(reasons) > 0 {
if len(reasons[0]) > 0 {
Log.Sys("Begin reregister router...\n[reason] %s\n\n", reasons[0])
} else {
Log.Sys("Begin reregister router...\n\n")
}
defer Log.Sys("Reregister router end.\n\n")
}
var err error
defer func() {
if err != nil {
Log.Error("Creating/Recreating router fails: %s", err.Error())
}
}()
if err = saveVirtRouterConfig(); err != nil {
return
}
if err = isExistMiddlewares(lessgo.virtBefore...); err != nil {
return
}
if err = isExistMiddlewares(lessgo.virtAfter...); err != nil {
return
}
for _, v := range lessgo.virtFiles {
if err = isExistMiddlewares(v.Middlewares...); err != nil {
return
}
}
for _, v := range lessgo.virtStatics {
if err = isExistMiddlewares(v.Middlewares...); err != nil {
return
}
}
// Server pause and clean router
app.resetRouterBegin()
defer app.resetRouterEnd()
// Build real router
app.beforeUse(getMiddlewareFuncs(lessgo.virtBefore)...)
app.afterUse(getMiddlewareFuncs(lessgo.virtAfter)...)
group := app.group(
lessgo.virtRouter.Prefix,
getMiddlewareFuncs(lessgo.virtRouter.Middlewares)...,
)
for _, child := range lessgo.virtRouter.Children {
child.route(group)
}
for _, v := range lessgo.virtFiles {
v.route()
}
for _, v := range lessgo.virtStatics {
v.route()
}
}
// 运行服务
// @param graceExitCallback设置优雅关闭或重启时的收尾函数
func Run(graceExitCallback ...func() error) {
// 添加系统预设的路由操作前的中间件
registerBefore()
// 添加系统预设的路由操作后的中间件
registerAfter()
// 添加系统预设的静态目录虚拟路由
registerStatics()
// 添加系统预设的静态文件虚拟路由
registerFiles()
// 从数据库初始化虚拟路由
initVirtRouterConfig()
// 重建路由
ReregisterRouter()
// 开启最大核心数运行
runtime.GOMAXPROCS(runtime.NumCPU())
// 配置服务器引擎
var (
tlsCertfile string
tlsKeyfile string
)
if Config.Listen.EnableTLS {
tlsCertfile = Config.Listen.HTTPSCertFile
tlsKeyfile = Config.Listen.HTTPSKeyFile
}
if len(graceExitCallback) > 0 {
lessgo.App.SetGraceExitFunc(graceExitCallback[0])
}
// 启动服务
lessgo.App.run(
Config.Listen.Address,
Config.Listen.TLSAddress,
tlsCertfile,
tlsKeyfile,
Config.Listen.ReadTimeout,
Config.Listen.WriteTimeout,
)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/superzhoulin/lessgo.git
git@gitee.com:superzhoulin/lessgo.git
superzhoulin
lessgo
lessgo
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385