Add support for Ratelimiting
continuous-integration/drone/tag Build is passing Details

master v0.3.5
René Jochum 2 years ago
parent 2d74bf6375
commit febbd416a1
Signed by: jochum
GPG Key ID: F7D906F5E51E8E5E

@ -85,7 +85,7 @@ import (
"jochum.dev/jo-micro/router" "jochum.dev/jo-micro/router"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"go-micro.dev/v4" "go-micro.dev/v4"
"wz2100.net/microlobby/shared/proto/authservicepb/v1" "jochum.dev/jo-micro/auth2/internal/proto/authpb"
) )
func main() { func main() {
@ -95,52 +95,59 @@ func main() {
micro.Action(func(c *cli.Context) error { micro.Action(func(c *cli.Context) error {
s := service.Server() s := service.Server()
r := router.NewHandler( r := router.NewHandler(
config.RouterURI, "api/auth/v1",
router.NewRoute( router.NewRoute(
router.Method(router.MethodGet), router.Method(router.MethodGet),
router.Path("/"), router.Path("/"),
router.Endpoint(authservicepb.AuthV1Service.UserList), router.Endpoint(authpb.AuthService.List),
router.Params("limit", "offset"), router.Params("limit", "offset"),
router.AuthRequired(), router.AuthRequired(),
), router.RatelimitClientIP("1-M"),
router.NewRoute( ),
router.Method(router.MethodPost), router.NewRoute(
router.Path("/login"), router.Method(router.MethodPost),
router.Endpoint(authservicepb.AuthV1Service.Login), router.Path("/login"),
), router.Endpoint(authpb.AuthService.Login),
router.NewRoute( router.RatelimitClientIP("10-M", "30-H", "100-D"),
router.Method(router.MethodPost), ),
router.Path("/register"), router.NewRoute(
router.Endpoint(authservicepb.AuthV1Service.Register), router.Method(router.MethodPost),
), router.Path("/register"),
router.NewRoute( router.Endpoint(authpb.AuthService.Register),
router.Method(router.MethodPost), router.RatelimitClientIP("1-M", "10-H", "50-D"),
router.Path("/refresh"), ),
router.Endpoint(authservicepb.AuthV1Service.Refresh), router.NewRoute(
), router.Method(router.MethodPost),
router.NewRoute( router.Path("/refresh"),
router.Method(router.MethodDelete), router.Endpoint(authpb.AuthService.Refresh),
router.Path("/:userId"), router.RatelimitClientIP("1-M", "10-H", "50-D"),
router.Endpoint(authservicepb.AuthV1Service.UserDelete), ),
router.Params("userId"), router.NewRoute(
router.AuthRequired(), router.Method(router.MethodDelete),
), router.Path("/:userId"),
router.NewRoute( router.Endpoint(authpb.AuthService.Delete),
router.Method(router.MethodGet), router.Params("userId"),
router.Path("/:userId"), router.AuthRequired(),
router.Endpoint(authservicepb.AuthV1Service.UserDetail), router.RatelimitClientIP("10-M"),
router.Params("userId"), ),
router.AuthRequired(), router.NewRoute(
), router.Method(router.MethodGet),
router.NewRoute( router.Path("/:userId"),
router.Method(router.MethodPut), router.Endpoint(authpb.AuthService.Detail),
router.Path("/:userId/roles"), router.Params("userId"),
router.Endpoint(authservicepb.AuthV1Service.UserUpdateRoles), router.AuthRequired(),
router.Params("userId"), router.RatelimitClientIP("100-M"),
router.AuthRequired(), ),
), router.NewRoute(
router.Method(router.MethodPut),
router.Path("/:userId/roles"),
router.Endpoint(authpb.AuthService.UpdateRoles),
router.Params("userId"),
router.AuthRequired(),
router.RatelimitClientIP("1-M"),
),
) )
r.RegisterWithServer(s) r.RegisterWithServer(srv.Server())
} }
) )
} }

@ -7,8 +7,14 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"strconv"
"time" "time"
libredis "github.com/go-redis/redis/v8"
limiter "github.com/ulule/limiter/v3"
sredis "github.com/ulule/limiter/v3/drivers/store/redis"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"go-micro.dev/v4" "go-micro.dev/v4"
"go-micro.dev/v4/client" "go-micro.dev/v4/client"
@ -32,6 +38,7 @@ type Handler struct {
engine *gin.Engine engine *gin.Engine
routerAuth auth2.RouterPlugin routerAuth auth2.RouterPlugin
routes map[string]*routerclientpb.RoutesReply_Route routes map[string]*routerclientpb.RoutesReply_Route
rlStore limiter.Store
} }
func NewHandler() (*Handler, error) { func NewHandler() (*Handler, error) {
@ -40,12 +47,31 @@ func NewHandler() (*Handler, error) {
}, nil }, nil
} }
func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth auth2.RouterPlugin, refreshSeconds int) error { func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth auth2.RouterPlugin, refreshSeconds int, rlStoreURL string) error {
h.service = service h.service = service
h.engine = engine h.engine = engine
h.routerAuth = routerAuth h.routerAuth = routerAuth
globalGroup := h.engine.Group("") globalGroup := h.engine.Group("")
if rlStoreURL != "" {
// Create a redis client.
option, err := libredis.ParseURL(rlStoreURL)
if err != nil {
return err
}
client := libredis.NewClient(option)
// Create a store with the redis client.
store, err := sredis.NewStoreWithOptions(client, limiter.StoreOptions{
Prefix: "rl",
MaxRetry: 10,
})
if err != nil {
return err
}
h.rlStore = store
}
// Refresh routes for the proxy every 10 seconds // Refresh routes for the proxy every 10 seconds
go func() { go func() {
for { for {
@ -84,17 +110,54 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
} }
// Calculate the pathMethod of the route and register it if it's not registered yet // Calculate the pathMethod of the route and register it if it's not registered yet
pathMethod := fmt.Sprintf("%s:%s%s", route.GetMethod(), g.BasePath(), route.GetPath()) pathMethod := fmt.Sprintf("%s:%s%s", route.Method, g.BasePath(), route.Path)
path := fmt.Sprintf("%s%s", g.BasePath(), route.GetPath()) path := fmt.Sprintf("%s%s", g.BasePath(), route.Path)
if _, ok := h.routes[pathMethod]; !ok { if _, ok := h.routes[pathMethod]; !ok {
ilogger.Logrus(). ilogger.Logrus().
WithField("service", s.Name). WithField("service", s.Name).
WithField("endpoint", route.GetEndpoint()). WithField("endpoint", route.Endpoint).
WithField("method", route.GetMethod()). WithField("method", route.Method).
WithField("path", path). WithField("path", path).
Debugf("Found route") WithField("ratelimitClientIP", route.RatelimitClientIP).
Debug("found route")
clientIPRatelimiter := make([]*limiter.Limiter, len(route.RatelimitClientIP))
if len(route.RatelimitClientIP) > 0 {
if h.rlStore == nil {
ilogger.Logrus().
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
WithField("path", path).
WithField("ratelimitClientIP", route.RatelimitClientIP).
Error("found a route with a limiter but there is no limiter store")
continue
}
haveError := false
for idx, rate := range route.RatelimitClientIP {
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("ratelimitClientIP", route.RatelimitClientIP).
Error(err)
haveError = true
break
}
clientIPRatelimiter[idx] = limiter.New(h.rlStore, rate)
}
if haveError {
continue
}
}
g.Handle(route.GetMethod(), route.GetPath(), h.proxy(s.Name, route, route.AuthRequired)) g.Handle(route.Method, route.Path, h.proxy(s.Name, route, route.AuthRequired, path, clientIPRatelimiter))
h.routes[pathMethod] = route h.routes[pathMethod] = route
h.routes[pathMethod].Path = path h.routes[pathMethod].Path = path
} }
@ -112,8 +175,38 @@ func (h *Handler) Stop() error {
return nil return nil
} }
func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Route, authRequired bool) func(*gin.Context) { func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Route, authRequired bool, path string, clientIPRatelimiter []*limiter.Limiter) func(*gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
if len(clientIPRatelimiter) > 0 {
for idx, l := range clientIPRatelimiter {
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",
})
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))
}
if context.Reached {
c.JSON(http.StatusTooManyRequests, gin.H{
"status": http.StatusTooManyRequests,
"message": "To many requests",
})
c.Abort()
return
}
}
}
// Map query/path params // Map query/path params
params := make(map[string]string) params := make(map[string]string)
for _, p := range route.Params { for _, p := range route.Params {
@ -180,7 +273,7 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
request[pn] = p request[pn] = p
} }
req := h.service.Client().NewRequest(serviceName, route.GetEndpoint(), request, client.WithContentType("application/json")) req := h.service.Client().NewRequest(serviceName, route.Endpoint, request, client.WithContentType("application/json"))
// Auth // Auth
ctx, err := h.routerAuth.ForwardContext(c.Request, c) ctx, err := h.routerAuth.ForwardContext(c.Request, c)
@ -217,11 +310,12 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
func (h *Handler) Routes(ctx context.Context, in *emptypb.Empty, out *routerserverpb.RoutesReply) error { func (h *Handler) Routes(ctx context.Context, in *emptypb.Empty, out *routerserverpb.RoutesReply) error {
for _, route := range h.routes { for _, route := range h.routes {
out.Routes = append(out.Routes, &routerserverpb.RoutesReply_Route{ out.Routes = append(out.Routes, &routerserverpb.RoutesReply_Route{
Method: route.Method, Method: route.Method,
Path: route.Path, Path: route.Path,
Params: route.Params, Params: route.Params,
Endpoint: route.Endpoint, Endpoint: route.Endpoint,
AuthRequired: route.AuthRequired, AuthRequired: route.AuthRequired,
RatelimitClientIP: route.RatelimitClientIP,
}) })
} }

@ -54,6 +54,7 @@ func internalService(routerHandler *handler.Handler) {
router.Method(router.MethodGet), router.Method(router.MethodGet),
router.Path("/routes"), router.Path("/routes"),
router.Endpoint(routerserverpb.RouterServerService.Routes), router.Endpoint(routerserverpb.RouterServerService.Routes),
router.RatelimitClientIP("1-S", "50-M", "1000-H"),
), ),
) )
r.RegisterWithServer(srv.Server()) r.RegisterWithServer(srv.Server())
@ -113,6 +114,11 @@ func main() {
EnvVars: []string{"MICRO_ROUTER_LISTEN"}, EnvVars: []string{"MICRO_ROUTER_LISTEN"},
Value: ":8080", Value: ":8080",
}, },
&cli.StringFlag{
Name: "router_ratelimiter_store_url",
Usage: "Ratelimiter store URL, for example redis://localhost:6379/0. No store = no Endpoints that require a ratelimiter",
EnvVars: []string{"MICRO_ROUTER_RATELIMITER_STORE_URL"},
},
}))) })))
routerHandler, err := handler.NewHandler() routerHandler, err := handler.NewHandler()
@ -144,9 +150,10 @@ func main() {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
} }
r := gin.New() r := gin.New()
r.ForwardedByClientIP = true
// Initalize the Handler // Initalize the Handler
if err := routerHandler.Init(srv, r, routerAuthReg.Plugin(), c.Int("router_refresh")); err != nil { if err := routerHandler.Init(srv, r, routerAuthReg.Plugin(), c.Int("router_refresh"), c.String("router_ratelimiter_store_url")); err != nil {
ilogger.Logrus().Fatal(err) ilogger.Logrus().Fatal(err)
} }

@ -10,8 +10,10 @@ require (
github.com/go-micro/plugins/v4/server/http v1.1.0 github.com/go-micro/plugins/v4/server/http v1.1.0
github.com/go-micro/plugins/v4/transport/grpc v1.1.0 github.com/go-micro/plugins/v4/transport/grpc v1.1.0
github.com/go-micro/plugins/v4/transport/nats v1.1.1-0.20220908125827-e0369dde429b github.com/go-micro/plugins/v4/transport/nats v1.1.1-0.20220908125827-e0369dde429b
github.com/go-redis/redis/v8 v8.11.5
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f
github.com/ulule/limiter/v3 v3.10.0
github.com/urfave/cli/v2 v2.16.3 github.com/urfave/cli/v2 v2.16.3
go-micro.dev/v4 v4.8.1 go-micro.dev/v4 v4.8.1
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.28.1
@ -24,8 +26,10 @@ require (
github.com/acomagu/bufpipe v1.0.3 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect
github.com/bitly/go-simplejson v0.5.0 // indirect github.com/bitly/go-simplejson v0.5.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cloudflare/circl v1.2.0 // indirect github.com/cloudflare/circl v1.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
@ -76,7 +80,6 @@ require (
golang.org/x/sync v0.0.0-20220907140024-f12130a52804 // indirect golang.org/x/sync v0.0.0-20220907140024-f12130a52804 // indirect
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.1.12 // indirect
google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737 // indirect google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737 // indirect
google.golang.org/grpc v1.49.0 // indirect google.golang.org/grpc v1.49.0 // indirect

@ -18,6 +18,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.2.0 h1:NheeISPSUcYftKlfrLuOo4T62FkmD4t4jviLfFFYaec= github.com/cloudflare/circl v1.2.0 h1:NheeISPSUcYftKlfrLuOo4T62FkmD4t4jviLfFFYaec=
github.com/cloudflare/circl v1.2.0/go.mod h1:Ch2UgYr6ti2KTtlejELlROl0YIYj7SLjAC8M+INXlMk= github.com/cloudflare/circl v1.2.0/go.mod h1:Ch2UgYr6ti2KTtlejELlROl0YIYj7SLjAC8M+INXlMk=
@ -27,6 +29,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
@ -77,6 +81,8 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
@ -149,6 +155,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
@ -189,6 +197,8 @@ github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f/go.mod h1:X3Dd1S
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/ulule/limiter/v3 v3.10.0 h1:C9mx3tgxYnt4pUYKWktZf7aEOVPbRYxR+onNFjQTEp0=
github.com/ulule/limiter/v3 v3.10.0/go.mod h1:NqPA/r8QfP7O11iC+95X6gcWJPtRWjKrtOUw07BTvoo=
github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk= github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk=
github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
@ -262,7 +272,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@ -301,7 +310,5 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
jochum.dev/jo-micro/auth2 v0.2.0 h1:48fLUtVx2u5NDlO0Nzm8K8cHUPbOXNNuKG9gg4vVmFM=
jochum.dev/jo-micro/auth2 v0.2.0/go.mod h1:z2qub/2K5+C9bpoDImWWPpKFPxds6LQN1Qx6X8c1xEc=
jochum.dev/jo-micro/auth2 v0.3.0 h1:7r9Vo7/Wlc/tB8sBN4BGQFniOy2x1ekoWI5I4+xBUv0= jochum.dev/jo-micro/auth2 v0.3.0 h1:7r9Vo7/Wlc/tB8sBN4BGQFniOy2x1ekoWI5I4+xBUv0=
jochum.dev/jo-micro/auth2 v0.3.0/go.mod h1:fSWMvxDct/jhmP1CC5HQTSfklqZRmygO8Zv5qZVuUHg= jochum.dev/jo-micro/auth2 v0.3.0/go.mod h1:fSWMvxDct/jhmP1CC5HQTSfklqZRmygO8Zv5qZVuUHg=

@ -25,12 +25,13 @@ func NewHandler(routerURI string, routes ...*Route) *Handler {
} }
pbRoutes = append(pbRoutes, &routerclientpb.RoutesReply_Route{ pbRoutes = append(pbRoutes, &routerclientpb.RoutesReply_Route{
IsGlobal: r.IsGlobal, IsGlobal: r.IsGlobal,
Method: r.Method, Method: r.Method,
Path: r.Path, Path: r.Path,
Endpoint: util.ReflectFunctionName(r.Endpoint), Endpoint: util.ReflectFunctionName(r.Endpoint),
Params: r.Params, Params: r.Params,
AuthRequired: r.AuthRequired, AuthRequired: r.AuthRequired,
RatelimitClientIP: r.RatelimitClientIP,
}) })
} }

@ -82,12 +82,13 @@ type RoutesReply_Route struct {
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
// isGlobal=True == no prefix route // isGlobal=True == no prefix route
IsGlobal bool `protobuf:"varint,1,opt,name=isGlobal,proto3" json:"isGlobal,omitempty"` IsGlobal bool `protobuf:"varint,1,opt,name=isGlobal,proto3" json:"isGlobal,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`
Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"` Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
Params []string `protobuf:"bytes,5,rep,name=params,proto3" json:"params,omitempty"` Params []string `protobuf:"bytes,5,rep,name=params,proto3" json:"params,omitempty"`
AuthRequired bool `protobuf:"varint,6,opt,name=authRequired,proto3" json:"authRequired,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"`
} }
func (x *RoutesReply_Route) Reset() { func (x *RoutesReply_Route) Reset() {
@ -164,6 +165,13 @@ func (x *RoutesReply_Route) GetAuthRequired() bool {
return false return false
} }
func (x *RoutesReply_Route) GetRatelimitClientIP() []string {
if x != nil {
return x.RatelimitClientIP
}
return nil
}
var File_routerclientpb_proto protoreflect.FileDescriptor var File_routerclientpb_proto protoreflect.FileDescriptor
var file_routerclientpb_proto_rawDesc = []byte{ var file_routerclientpb_proto_rawDesc = []byte{
@ -171,13 +179,13 @@ var file_routerclientpb_proto_rawDesc = []byte{
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 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, 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, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x90, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x6f, 0x74, 0x6f, 0x22, 0xbe, 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, 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, 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, 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, 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, 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, 0xa7, 0x01, 0x0a, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0xd5, 0x01, 0x0a,
0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x47, 0x6c, 0x6f, 0x62, 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, 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, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01,
@ -188,17 +196,20 @@ var file_routerclientpb_proto_rawDesc = []byte{
0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61,
0x6d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x6d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72,
0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x52, 0x65, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x52, 0x65,
0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x6d, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x07, 0x20, 0x03, 0x28,
0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x09, 0x52, 0x11, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x6e, 0x74, 0x49, 0x50, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6c,
0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52,
0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x5a, 0x3e, 0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x6a, 0x6f, 0x2d, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e,
0x6d, 0x69, 0x63, 0x72, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52,
0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e,
0x62, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x6a, 0x6f, 0x2d, 0x6d, 0x69,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 ( var (

@ -19,6 +19,7 @@ message RoutesReply {
string endpoint = 4; string endpoint = 4;
repeated string params = 5; repeated string params = 5;
bool authRequired = 6; bool authRequired = 6;
repeated string ratelimitClientIP = 7;
} }
string routerURI = 1; string routerURI = 1;

@ -73,11 +73,12 @@ type RoutesReply_Route struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
Params []string `protobuf:"bytes,3,rep,name=params,proto3" json:"params,omitempty"` Params []string `protobuf:"bytes,3,rep,name=params,proto3" json:"params,omitempty"`
Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"` Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
AuthRequired bool `protobuf:"varint,5,opt,name=authRequired,proto3" json:"authRequired,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"`
} }
func (x *RoutesReply_Route) Reset() { func (x *RoutesReply_Route) Reset() {
@ -147,6 +148,13 @@ func (x *RoutesReply_Route) GetAuthRequired() bool {
return false return false
} }
func (x *RoutesReply_Route) GetRatelimitClientIP() []string {
if x != nil {
return x.RatelimitClientIP
}
return nil
}
var File_routerserverpb_proto protoreflect.FileDescriptor var File_routerserverpb_proto protoreflect.FileDescriptor
var file_routerserverpb_proto_rawDesc = []byte{ var file_routerserverpb_proto_rawDesc = []byte{
@ -154,11 +162,11 @@ var file_routerserverpb_proto_rawDesc = []byte{
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 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, 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, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0xd6, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x6f, 0x74, 0x6f, 0x22, 0x84, 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, 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, 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, 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, 0x8b, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0xb9,
0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
@ -167,17 +175,20 @@ var file_routerserverpb_proto_rawDesc = []byte{
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68,
0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
0x61, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x32, 0x56, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x11,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49,
0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x50, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x32, 0x56, 0x0a, 0x13, 0x52, 0x6f,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x75, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f,
0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x65, 0x76, 0x2f, 0x6a, 0x6f, 0x2d, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x65, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x6a, 0x6f, 0x63, 0x68, 0x75, 0x6d, 0x2e, 0x64, 0x65, 0x76,
0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 ( var (

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

@ -5,25 +5,27 @@ import (
) )
type Route struct { type Route struct {
// isGlobal=True == no prefix route IsGlobal bool // isGlobal=True == no prefix route
IsGlobal bool
Method string Method string
Path string Path string
Endpoint interface{} Endpoint interface{}
Params []string Params []string
AuthRequired bool AuthRequired bool // Default false
// https://github.com/ulule/limiter - default is no rate Limiter at all, put the strictes limit first
RatelimitClientIP []string
} }
type Option func(*Route) type Option func(*Route)
func NewRoute(opts ...Option) *Route { func NewRoute(opts ...Option) *Route {
route := &Route{ route := &Route{
IsGlobal: false, IsGlobal: false,
Method: MethodGet, Method: MethodGet,
Path: "/", Path: "/",
Endpoint: nil, Endpoint: nil,
Params: []string{}, Params: []string{},
AuthRequired: false, AuthRequired: false,
RatelimitClientIP: []string{},
} }
for _, o := range opts { for _, o := range opts {
@ -73,3 +75,9 @@ func AuthRequired() Option {
o.AuthRequired = true o.AuthRequired = true
} }
} }
func RatelimitClientIP(n ...string) Option {
return func(o *Route) {
o.RatelimitClientIP = n
}
}

Loading…
Cancel
Save