Add user ratelimiter
continuous-integration/drone/tag Build is passing Details

master v0.3.8
René Jochum 1 year ago
parent 5cb80e9ae0
commit 7e8b26f38c
Signed by: jochum
GPG Key ID: F7D906F5E51E8E5E

@ -134,7 +134,7 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
WithField("method", route.Method).
WithField("path", path).
WithField("ratelimitClientIP", route.RatelimitClientIP).
Error("found a route with a limiter but there is no limiter store")
Error("found a route with a clientip limiter but there is no limiter store")
continue
}
@ -161,7 +161,43 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
}
}
g.Handle(route.Method, route.Path, h.proxy(s.Name, route, route.AuthRequired, path, clientIPRatelimiter))
userRatelimiter := make([]*limiter.Limiter, len(route.RatelimitUser))
if route.AuthRequired && len(route.RatelimitUser) > 0 {
if h.rlStore == nil {
ilogger.Logrus().
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
WithField("path", path).
WithField("ratelimitUser", route.RatelimitUser).
Error("found a route with a user limiter but there is no limiter store")
continue
}
haveError := false
for idx, rate := range route.RatelimitUser {
rate, err := limiter.NewRateFromFormatted(rate)
if err != nil {
ilogger.Logrus().
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
WithField("path", path).
WithField("ratelimitUser", route.RatelimitUser).
Error(err)
haveError = true
break
}
userRatelimiter[idx] = limiter.New(h.rlStore, rate)
}
if haveError {
continue
}
}
g.Handle(route.Method, route.Path, h.proxy(s.Name, route, route.AuthRequired, path, clientIPRatelimiter, userRatelimiter))
h.routes[pathMethod] = route
h.routes[pathMethod].Path = path
}
@ -179,7 +215,7 @@ func (h *Handler) Stop() error {
return nil
}
func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Route, authRequired bool, path string, clientIPRatelimiter []*limiter.Limiter) func(*gin.Context) {
func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Route, authRequired bool, path string, clientIPRatelimiter []*limiter.Limiter, userRatelimiter []*limiter.Limiter) func(*gin.Context) {
return func(c *gin.Context) {
if len(clientIPRatelimiter) > 0 {
@ -187,23 +223,31 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
context, err := l.Get(c, fmt.Sprintf("%s-%s-%s", path, l.Rate.Formatted, c.ClientIP()))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": http.StatusInternalServerError,
"message": "Internal server error",
"errors": []gin.H{
gin.H{
"id": "INTERNAL_SERVER_ERROR",
"message": err,
},
},
})
c.Abort()
return
}
if idx == 0 {
c.Header("X-RateLimit-Limit", strconv.FormatInt(context.Limit, 10))
c.Header("X-RateLimit-Remaining", strconv.FormatInt(context.Remaining, 10))
c.Header("X-RateLimit-Reset", strconv.FormatInt(context.Reset, 10))
c.Header("X-ClientIPRateLimit-Limit", strconv.FormatInt(context.Limit, 10))
c.Header("X-ClientIPRateLimit-Remaining", strconv.FormatInt(context.Remaining, 10))
c.Header("X-ClientIPRateLimit-Reset", strconv.FormatInt(context.Reset, 10))
}
if context.Reached {
c.JSON(http.StatusTooManyRequests, gin.H{
"status": http.StatusTooManyRequests,
"message": "To many requests",
"errors": []gin.H{
gin.H{
"id": "TO_MANY_REQUESTS",
"message": "To many requests",
},
},
})
c.Abort()
return
@ -263,9 +307,14 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
} else {
if c.ContentType() == "" {
c.JSON(http.StatusUnsupportedMediaType, gin.H{
"status": http.StatusUnsupportedMediaType,
"message": "provide a content-type header",
"errors": []gin.H{
gin.H{
"id": "UNSUPPORTED_MEDIA_TYPE",
"message": "provide a content-type header",
},
},
})
c.Abort()
return
}
c.ShouldBind(&request)
@ -280,13 +329,68 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
req := h.service.Client().NewRequest(serviceName, route.Endpoint, request, client.WithContentType("application/json"))
// Auth
ctx, err := h.routerAuth.ForwardContext(c.Request, c)
u, err := h.routerAuth.Inspect(c.Request)
var ctx context.Context
if err != nil && authRequired {
c.JSON(http.StatusUnauthorized, gin.H{
"status": http.StatusUnauthorized,
"message": err,
"errors": []gin.H{
gin.H{
"id": "UNAUTHORIZED",
"message": err,
},
},
})
c.Abort()
return
} else {
ctx, err = h.routerAuth.ForwardContext(u, c.Request, c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"errors": []gin.H{
gin.H{
"id": "INTERNAL_SERVER_ERROR",
"message": err,
},
},
})
}
}
if len(userRatelimiter) > 0 {
for idx, l := range userRatelimiter {
context, err := l.Get(c, fmt.Sprintf("%s-%s-%s", path, l.Rate.Formatted, u.Id))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"errors": []gin.H{
gin.H{
"id": "INTERNAL_SERVER_ERROR",
"message": err,
},
},
})
c.Abort()
return
}
if idx == 0 {
c.Header("X-UserRateLimit-Limit", strconv.FormatInt(context.Limit, 10))
c.Header("X-UserRateLimit-Remaining", strconv.FormatInt(context.Remaining, 10))
c.Header("X-UserRateLimit-Reset", strconv.FormatInt(context.Reset, 10))
}
if context.Reached {
c.JSON(http.StatusTooManyRequests, gin.H{
"errors": []gin.H{
gin.H{
"id": "TO_MANY_REQUESTS",
"message": "To many requests",
},
},
})
c.Abort()
return
}
}
}
// remote call
@ -297,13 +401,19 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
pErr := errors.FromError(err)
code := int(http.StatusInternalServerError)
id := pErr.Id
if pErr.Code != 0 {
code = int(pErr.Code)
}
c.JSON(code, gin.H{
"status": code,
"message": pErr.Detail,
"errors": []gin.H{
gin.H{
"id": id,
"message": pErr.Detail,
},
},
})
c.Abort()
return
}

@ -17,11 +17,11 @@ require (
github.com/urfave/cli/v2 v2.16.3
go-micro.dev/v4 v4.8.1
google.golang.org/protobuf v1.28.1
jochum.dev/jo-micro/auth2 v0.3.2
jochum.dev/jo-micro/auth2 v0.3.3
)
require (
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect
@ -74,10 +74,10 @@ require (
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/xanzy/ssh-agent v0.3.2 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 // indirect
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220921203646-d300de134e69 // indirect
golang.org/x/sync v0.0.0-20220907140024-f12130a52804 // indirect
golang.org/x/net v0.0.0-20220923203811-8be639271d50 // indirect
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 // indirect
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.12 // indirect

@ -2,6 +2,8 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
@ -222,6 +224,8 @@ golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY=
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7 h1:WJywXQVIb56P2kAvXeMGTIgQ1ZHQxR60+F9dLsodECc=
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -234,10 +238,14 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220921203646-d300de134e69 h1:hUJpGDpnfwdJW8iNypFjmSY0sCBEL+spFTZ2eO+Sfps=
golang.org/x/net v0.0.0-20220921203646-d300de134e69/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20220923203811-8be639271d50 h1:vKyz8L3zkd+xrMeIaBsQ/MNVPVFSffdaU3ZyYlBGFnI=
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220907140024-f12130a52804 h1:0SH2R3f1b1VmIMG7BXbEZCBUu2dKmHschSmjqGUrW8A=
golang.org/x/sync v0.0.0-20220907140024-f12130a52804/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -313,3 +321,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
jochum.dev/jo-micro/auth2 v0.3.2 h1:dWY7RPLS3/Sn7YWDz4Kl8Str6lzMXUdfbMBLJLXmehk=
jochum.dev/jo-micro/auth2 v0.3.2/go.mod h1:VRGDU1tsDrlEVN9ch3DlvhUslDTQGGp3KLReBRL6V1s=
jochum.dev/jo-micro/auth2 v0.3.3 h1:mL8ipUfgNx2d5/JeuW7i1P/ZUzUpVT8G9WYH02xr/vA=
jochum.dev/jo-micro/auth2 v0.3.3/go.mod h1:14yXAQkyHYC1RyHNoweNZahsRsaHrCEek7YlXDtt7Hg=

@ -32,6 +32,7 @@ func NewHandler(routerURI string, routes ...*Route) *Handler {
Params: r.Params,
AuthRequired: r.AuthRequired,
RatelimitClientIP: r.RatelimitClientIP,
RatelimitUser: r.RatelimitUser,
})
}

@ -89,6 +89,7 @@ type RoutesReply_Route struct {
Params []string `protobuf:"bytes,5,rep,name=params,proto3" json:"params,omitempty"`
AuthRequired bool `protobuf:"varint,6,opt,name=authRequired,proto3" json:"authRequired,omitempty"`
RatelimitClientIP []string `protobuf:"bytes,7,rep,name=ratelimitClientIP,proto3" json:"ratelimitClientIP,omitempty"`
RatelimitUser []string `protobuf:"bytes,8,rep,name=ratelimitUser,proto3" json:"ratelimitUser,omitempty"`
}
func (x *RoutesReply_Route) Reset() {
@ -172,6 +173,13 @@ func (x *RoutesReply_Route) GetRatelimitClientIP() []string {
return nil
}
func (x *RoutesReply_Route) GetRatelimitUser() []string {
if x != nil {
return x.RatelimitUser
}
return nil
}
var File_routerclientpb_proto protoreflect.FileDescriptor
var file_routerclientpb_proto_rawDesc = []byte{
@ -179,13 +187,13 @@ var file_routerclientpb_proto_rawDesc = []byte{
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0xbe, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65,
0x6f, 0x74, 0x6f, 0x22, 0xe4, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65,
0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x55, 0x52, 0x49,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x55, 0x52,
0x49, 0x12, 0x39, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2e, 0x52,
0x6f, 0x75, 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0xd5, 0x01, 0x0a,
0x6f, 0x75, 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0xfb, 0x01, 0x0a,
0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x47, 0x6c, 0x6f, 0x62,
0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x47, 0x6c, 0x6f, 0x62,
0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01,
@ -199,17 +207,19 @@ var file_routerclientpb_proto_rawDesc = []byte{
0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69,
0x6d, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x07, 0x20, 0x03, 0x28,
0x09, 0x52, 0x11, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x49, 0x50, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e,
0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x6a, 0x6f, 0x2d, 0x6d, 0x69,
0x63, 0x72, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x3b,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x74, 0x49, 0x50, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69,
0x74, 0x55, 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x61, 0x74,
0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f,
0x75, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76,
0x2f, 0x6a, 0x6f, 0x2d, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x70, 0x62, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

@ -20,6 +20,7 @@ message RoutesReply {
repeated string params = 5;
bool authRequired = 6;
repeated string ratelimitClientIP = 7;
repeated string ratelimitUser = 8;
}
string routerURI = 1;

@ -79,6 +79,7 @@ type RoutesReply_Route struct {
Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
AuthRequired bool `protobuf:"varint,5,opt,name=authRequired,proto3" json:"authRequired,omitempty"`
RatelimitClientIP []string `protobuf:"bytes,6,rep,name=ratelimitClientIP,proto3" json:"ratelimitClientIP,omitempty"`
ReatelimitUser []string `protobuf:"bytes,7,rep,name=reatelimitUser,proto3" json:"reatelimitUser,omitempty"`
}
func (x *RoutesReply_Route) Reset() {
@ -155,6 +156,13 @@ func (x *RoutesReply_Route) GetRatelimitClientIP() []string {
return nil
}
func (x *RoutesReply_Route) GetReatelimitUser() []string {
if x != nil {
return x.ReatelimitUser
}
return nil
}
var File_routerserverpb_proto protoreflect.FileDescriptor
var file_routerserverpb_proto_rawDesc = []byte{
@ -162,11 +170,11 @@ var file_routerserverpb_proto_rawDesc = []byte{
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x84, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65,
0x6f, 0x74, 0x6f, 0x22, 0xac, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65,
0x70, 0x6c, 0x79, 0x12, 0x39, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0xb9,
0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0xe1,
0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
@ -178,17 +186,20 @@ var file_routerserverpb_proto_rawDesc = []byte{
0x61, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x11,
0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49,
0x50, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f,
0x75, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76,
0x2f, 0x6a, 0x6f, 0x2d, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72,
0x76, 0x65, 0x72, 0x70, 0x62, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65,
0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x18, 0x07, 0x20, 0x03,
0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73,
0x65, 0x72, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x72, 0x6f,
0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x6a, 0x6f,
0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x6a, 0x6f, 0x2d, 0x6d, 0x69, 0x63, 0x72,
0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x3b, 0x72, 0x6f,
0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (

@ -18,6 +18,7 @@ message RoutesReply {
string endpoint = 4;
bool authRequired = 5;
repeated string ratelimitClientIP = 6;
repeated string reatelimitUser = 7;
}
repeated Route routes = 1;

@ -13,6 +13,7 @@ type Route struct {
AuthRequired bool // Default false
// https://github.com/ulule/limiter - default is no rate Limiter at all, put the strictes limit first
RatelimitClientIP []string
RatelimitUser []string
}
type Option func(*Route)
@ -26,6 +27,7 @@ func NewRoute(opts ...Option) *Route {
Params: []string{},
AuthRequired: false,
RatelimitClientIP: []string{},
RatelimitUser: []string{},
}
for _, o := range opts {
@ -81,3 +83,9 @@ func RatelimitClientIP(n ...string) Option {
o.RatelimitClientIP = n
}
}
func RatelimitUser(n ...string) Option {
return func(o *Route) {
o.RatelimitUser = n
}
}

Loading…
Cancel
Save