package router import ( "bp.jydev.jianyu360.cn/BaseService/gateway/common/db" . "bp.jydev.jianyu360.cn/BaseService/gateway/common/gatecode" "fmt" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/util/gconv" "log" "regexp" ) type Manager struct { eqRouters map[string]*Router regexRouter map[*regexp.Regexp]*Router } // InitRouterManager 初始化系统代理路由 // 支持完全匹配和正则匹配 func InitRouterManager() (*Manager, error) { res := db.GateWatMySql.Query("SELECT status,middleground_code,url,function_code,check_sess,check_power,check_auth,check_status,check_blacklist,timeout,remark,appid,deduct_source FROM front_proxy") if res == nil || len(*res) == 0 { return nil, fmt.Errorf("未发现可用路由") } // 初始化 routerManager routerManager := &Manager{ eqRouters: make(map[string]*Router), regexRouter: make(map[*regexp.Regexp]*Router), } for _, row := range *res { // 获取路由信息 router := gconv.String(row["url"]) routerRule := &Router{ Status: gconv.Int(row["status"]), SessCheck: gconv.Int(row["check_sess"]), PowerCheck: gconv.Int(row["check_power"]), AccountCheck: gconv.Int(row["check_status"]), AuthCheck: gconv.Int(row["check_auth"]), BlackCheck: gconv.Int(row["check_blacklist"]) == 1, Deduct: gconv.Int(row["deduct_source"]), FuncCode: gconv.String(row["function_code"]), MiddleCode: gconv.String(row["middleground_code"]), AppId: gconv.String(row["appid"]), ReqUrl: router, TimeOut: gconv.Int64(row["timeout"]), Remark: gconv.String(row["remark"]), } // 判断路由匹配方式是完全匹配还是正则匹配 (此处逻辑参考x-web框架) if regexp.QuoteMeta(router) == router { routerManager.eqRouters[router] = routerRule } else { reg, err := regexp.Compile(router) if err != nil { log.Printf("路由%s装载异常 %v\n", router, err) } routerManager.regexRouter[reg] = routerRule } } return routerManager, nil } // GetRouterRule 获取路由规则 // 根据用户请求地址匹配路由规则,优先绝对匹配后用正则匹配。 func (m *Manager) GetRouterRule(url string) (*Router, error) { routerRule, exists := m.eqRouters[url] if !exists { for reg, thisRouterRule := range m.regexRouter { if reg.MatchString(url) { routerRule = thisRouterRule } } } if routerRule == nil { return nil, NewErrorWithCode(GATEWAY_ROUTER_NOTFIND, fmt.Sprintf("未找到请求地址%s,请检查是否注册到数据库\n", url)) } // 路由状态判断 if routerRule.Status != 1 { return nil, NewErrorWithCode(GATEWAY_ROUTER_UPHOLD, fmt.Sprintf("接口状态:%d\n", routerRule.Status)) } return routerRule, nil } // InfusionContext 注入通用结构体gContext func (m *Manager) InfusionContext(r *ghttp.Request) (err error) { var router *Router var GCtx = &GContext{ Sess: &JySession{}, RouterRule: &Router{}, } router, err = m.GetRouterRule(r.RequestURI) if err != nil { r.SetCtxVar(GContextKey, GCtx) return } GCtx.RouterRule = router //获取session jySess, _ := InitJySessionContext(r) GCtx.Sess = jySess r.SetCtxVar(GContextKey, GCtx) return }