Gin可以通过c.Request.URL.Path 拿到请求的路径

从url中获取参数:ShouldBindUri(&req)

从body中获取参数:c.ShouldBindJSON(&req)

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
// Context is the most important part of gin. It allows us to pass variables between middleware,
// manage the flow, validate the JSON of a request and render a JSON response for example.
type Context struct {
writermem responseWriter
Request *http.Request
Writer ResponseWriter

Params Params
handlers HandlersChain
index int8
fullPath string

engine *Engine
params *Params
skippedNodes *[]skippedNode

// This mutex protect Keys map
mu sync.RWMutex

// Keys is a key/value pair exclusively for the context of each request.
Keys map[string]interface{}

// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs

// Accepted defines a list of manually accepted formats for content negotiation.
Accepted []string

// queryCache use url.ParseQuery cached the param query result from c.Request.URL.Query()
queryCache url.Values

// formCache use url.ParseQuery cached PostForm contains the parsed form data from POST, PATCH,
// or PUT body parameters.
formCache url.Values

// SameSite allows a server to define a cookie attribute making it impossible for
// the browser to send this cookie along with cross-site requests.
sameSite http.SameSite
}


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

func RateLimitMiddleware(c *gin.Context) {

fmt.Println("路径为:", c.Request.URL.Path)

cid, err := getV2RequestCid(c)

if err != nil {
logrus.Errorf("getV2RequestCid err: %v", err)
return
}

fmt.Println("cid is:", cid)

// 获取接口名称的中间件,此处写死为v2/api/room/history,对应一个全局map里的key,value是对应的sid,此处认为是sid7

params := make(map[string]string)
params["resourceName"] = fmt.Sprintf("%s#%d", "sid1112", cid)

fmt.Println("进入限流中间件....")

ok, err := ratelimit.FlowRule(params)

fmt.Println("ok, err :", ok, err)

if err != nil && errors.Is(err, errors.New("resourceName 为必传key")) {
fmt.Println("resourceName 为必传key")
c.Abort()
}

// 判断限流中间件的返回值,如果为true则通过; 否则 c.Abort() 方法取消请求的继续进行,抛出异常
if !ok {
fmt.Println("限流:", err)
c.JSON(http.StatusTooManyRequests, gin.H{"error": "请求过多"})
c.Abort()
} else {
fmt.Println("限流中间件放行")
// 让程序继续正常运行
c.Next()
}
}