/
route.go
134 lines (115 loc) · 2.98 KB
/
route.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package router
import (
"github.com/volts-dev/volts/registry"
)
const (
Normal RoutePosition = iota
Before
After
Replace // the route replace origin
)
type RoutePosition byte
func (self RoutePosition) String() string {
return [...]string{"Normal", "Before", "After", "Replace"}[self]
}
type (
// route 路,表示一个Link 连接地址"../webgo/"
// 提供基础数据参数供Handler处理
route struct {
group *TGroup
Id int // 用于定位
Path string // !NOTE! Path存储路由绑定的URL 网络路径
PathDelimitChar byte // URL分割符 "/"或者"."
FilePath string // 短存储路径
Position RoutePosition //
handlers []*handler // 最终处理器 合并主处理器+次处理器 代理处理器
Methods []string // 方法
Host []string //
Url *TUrl // 提供Restful 等Controller.Action
Action string // 动作名称[包含模块名,动作名] "Model.Action", "/index.html","/filename.png"
}
)
var idQueue int = 0 //id 自动递增值
func RouteToEndpiont(r *route) *registry.Endpoint {
ep := ®istry.Endpoint{
//Name: r.
Method: r.Methods,
Path: r.Path,
Host: r.Host,
//Metadata: make(map[string]string),
}
//ep.Metadata["Path"] = r.Path
//ep.Metadata["FilePath"] = r.FilePath
//ep.Metadata["Type"] = r.Type.String()
return ep
}
func EndpiontToRoute(ep *registry.Endpoint) *route {
r := newRoute(
nil,
ep.Method,
nil,
ep.Path,
"",
"",
"",
)
return r
}
func newRoute(group *TGroup, methods []string, url *TUrl, path, filePath, name, action string) *route {
r := &route{
group: group,
Id: idQueue + 1,
Url: url,
Path: path,
PathDelimitChar: '/',
FilePath: filePath,
Action: action, //
Methods: methods,
handlers: make([]*handler, 0),
}
if url != nil {
r.Path = url.Path
}
return r
}
func (self *route) Group() *TGroup {
return self.group
}
// TODO 管理Ctrl 顺序 before center after
// 根据不同Action 名称合并Ctrls
func (self *route) CombineHandler(from *route) {
switch from.Position {
case Before:
self.handlers = append(from.handlers, self.handlers...)
case After:
self.handlers = append(self.handlers, from.handlers...)
default:
// 替换路由会直接替换 主控制器 但不会影响其他Hook 进来的控制器
self.handlers = from.handlers
}
}
// 剥离目标路由
// TODO 优化
func (self *route) StripHandler(target *route) {
srvs := make([]*registry.Service, 0)
var match bool
for _, ctr := range self.handlers {
if ctr.Type != LocalHandler {
for _, srv := range ctr.Services {
match = false
for _, hd := range target.handlers {
for _, s := range hd.Services {
if !srv.Equal(s) {
match = true
break
}
}
}
if !match {
srvs = append(srvs, srv)
}
}
ctr.Services = srvs
}
}
}