-
Notifications
You must be signed in to change notification settings - Fork 18
/
http_router.go
154 lines (132 loc) · 6.21 KB
/
http_router.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package server
import (
"github.com/gin-gonic/gin"
"net/http"
"time"
)
type HandlerFunc[Context any] func(ctx Context)
type ContextPacker[Context any] func(ctx *gin.Context) Context
type HttpRouter[Context any] struct {
srv *Server
group gin.IRouter
packer ContextPacker[Context]
}
func (slf *HttpRouter[Context]) handlesConvert(handlers []HandlerFunc[Context]) []gin.HandlerFunc {
var handles []gin.HandlerFunc
for i := 0; i < len(handlers); i++ {
handler := handlers[i]
handles = append(handles, func(ctx *gin.Context) {
slf.srv.hitMessageStatistics()
defer func() {
slf.srv.messageCounter.Add(-1)
}()
hc := slf.packer(ctx)
var now = time.Now()
handler(hc)
slf.srv.low(nil, now, slf.srv.asyncLowMessageDuration, true, "HTTP ["+ctx.Request.Method+"] "+ctx.Request.RequestURI)
})
}
return handles
}
// Handle 使用给定的路径和方法注册新的请求句柄和中间件
// - 最后一个处理程序应该是真正的处理程序,其他处理程序应该是可以而且应该在不同路由之间共享的中间件。
func (slf *HttpRouter[Context]) Handle(httpMethod, relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
handles := slf.handlesConvert(handlers)
slf.group.Handle(httpMethod, relativePath, handles...)
return slf
}
// POST 是 Handle("POST", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) POST(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodPost, relativePath, handlers...)
}
// GET 是 Handle("GET", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) GET(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodGet, relativePath, handlers...)
}
// DELETE 是 Handle("DELETE", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) DELETE(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodDelete, relativePath, handlers...)
}
// PATCH 是 Handle("PATCH", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) PATCH(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodPatch, relativePath, handlers...)
}
// PUT 是 Handle("PUT", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) PUT(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodPut, relativePath, handlers...)
}
// OPTIONS 是 Handle("OPTIONS", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) OPTIONS(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodOptions, relativePath, handlers...)
}
// HEAD 是 Handle("HEAD", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) HEAD(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodHead, relativePath, handlers...)
}
// CONNECT 是 Handle("CONNECT", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) CONNECT(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodConnect, relativePath, handlers...)
}
// TRACE 是 Handle("TRACE", path, handlers) 的快捷方式
func (slf *HttpRouter[Context]) TRACE(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
return slf.Handle(http.MethodTrace, relativePath, handlers...)
}
// Any 注册一个匹配所有 HTTP 方法的路由
// - GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
func (slf *HttpRouter[Context]) Any(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
for _, m := range []string{
http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodHead,
http.MethodOptions, http.MethodDelete, http.MethodConnect, http.MethodTrace} {
slf.Handle(m, relativePath, handlers...)
}
return slf
}
// Match 注册一个匹配指定 HTTP 方法的路由
// - GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
func (slf *HttpRouter[Context]) Match(methods []string, relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
for _, m := range methods {
slf.Handle(m, relativePath, handlers...)
}
return slf
}
// StaticFile 注册单个路由以便为本地文件系统的单个文件提供服务。
// - 例如: StaticFile("favicon.ico", "./resources/favicon.ico")
func (slf *HttpRouter[Context]) StaticFile(relativePath, filepath string) *HttpRouter[Context] {
slf.group.StaticFile(relativePath, filepath)
return slf
}
// StaticFileFS 与 `StaticFile` 类似,但可以使用自定义的 `http.FileSystem` 代替。
// - 例如: StaticFileFS("favicon.ico", "./resources/favicon.ico", Dir{".", false})
// - 由于依赖于 gin.Engine 默认情况下使用:gin.Dir
func (slf *HttpRouter[Context]) StaticFileFS(relativePath, filepath string, fs http.FileSystem) *HttpRouter[Context] {
slf.group.StaticFileFS(relativePath, filepath, fs)
return slf
}
// Static 提供来自给定文件系统根目录的文件。
// - 例如: Static("/static", "/var/www")
func (slf *HttpRouter[Context]) Static(relativePath, root string) *HttpRouter[Context] {
slf.group.StaticFS(relativePath, gin.Dir(root, false))
return slf
}
// StaticFS 与 `Static` 类似,但可以使用自定义的 `http.FileSystem` 代替。
// - 例如: StaticFS("/static", Dir{"/var/www", false})
// - 由于依赖于 gin.Engine 默认情况下使用:gin.Dir
func (slf *HttpRouter[Context]) StaticFS(relativePath string, fs http.FileSystem) *HttpRouter[Context] {
slf.group.StaticFS(relativePath, fs)
return slf
}
// Group 创建一个新的路由组。您应该添加所有具有共同中间件的路由。
// - 例如: v1 := slf.Group("/v1")
func (slf *HttpRouter[Context]) Group(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context] {
group := slf.group.Group(relativePath, slf.handlesConvert(handlers)...)
return &HttpRouter[Context]{
srv: slf.srv,
group: group,
packer: slf.packer,
}
}
// Use 将中间件附加到路由组。
func (slf *HttpRouter[Context]) Use(middleware ...HandlerFunc[Context]) *HttpRouter[Context] {
slf.group.Use(slf.handlesConvert(middleware)...)
return slf
}