Skip to content

Commit

Permalink
Merge pull request #85 from micanzhang/feature/exclude_key
Browse files Browse the repository at this point in the history
drivers/middleware/gin: add ExcludedKey Option
  • Loading branch information
novln authored Apr 7, 2020
2 parents 1366201 + 53840c1 commit 4572462
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
6 changes: 6 additions & 0 deletions drivers/middleware/gin/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Middleware struct {
OnError ErrorHandler
OnLimitReached LimitReachedHandler
KeyGetter KeyGetter
ExcludedKey func(string) bool
}

// NewMiddleware return a new instance of a gin middleware.
Expand All @@ -37,6 +38,11 @@ func NewMiddleware(limiter *limiter.Limiter, options ...Option) gin.HandlerFunc
// Handle gin request.
func (middleware *Middleware) Handle(c *gin.Context) {
key := middleware.KeyGetter(c)
if middleware.ExcludedKey != nil && middleware.ExcludedKey(key) {
c.Next()
return
}

context, err := middleware.Limiter.Get(c, key)
if err != nil {
middleware.OnError(c, err)
Expand Down
33 changes: 33 additions & 0 deletions drivers/middleware/gin/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,37 @@ func TestHTTPMiddleware(t *testing.T) {
is.Equal(http.StatusOK, resp.Code, strconv.FormatInt(i, 10))
}

//
// Test ExcludedKey
//
store = memory.NewStore()
is.NotZero(store)
counter = int64(0)
excludedKeyFn := func(key string) bool {
return key == "1"
}
middleware = gin.NewMiddleware(limiter.New(store, rate),
gin.WithKeyGetter(func(c *libgin.Context) string {
v := atomic.AddInt64(&counter, 1)
return strconv.FormatInt(v%2, 10)
}),
gin.WithExcludedKey(excludedKeyFn),
)
is.NotZero(middleware)

router = libgin.New()
router.Use(middleware)
router.GET("/", func(c *libgin.Context) {
c.String(http.StatusOK, "hello")
})
success = 20
for i := int64(1); i < clients; i++ {
resp := httptest.NewRecorder()
router.ServeHTTP(resp, request)
if i <= success || i%2 == 1 {
is.Equal(http.StatusOK, resp.Code, strconv.FormatInt(i, 10))
} else {
is.Equal(resp.Code, http.StatusTooManyRequests)
}
}
}
7 changes: 7 additions & 0 deletions drivers/middleware/gin/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,10 @@ func WithKeyGetter(KeyGetter KeyGetter) Option {
func DefaultKeyGetter(c *gin.Context) string {
return c.ClientIP()
}

// WithExcludedKey will configure the Middleware to use the given function.
func WithExcludedKey(fn func(string) bool) Option {
return option(func(middleware *Middleware) {
middleware.ExcludedKey = fn
})
}

0 comments on commit 4572462

Please sign in to comment.