Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Nebulizer1213 committed Jun 19, 2022
1 parent 7748692 commit 85bd2fb
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 133 deletions.
15 changes: 8 additions & 7 deletions GinRateLimit.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type InMemoryStoreType struct {
mutex *sync.Mutex
}

func (s *InMemoryStoreType) Limit(key string) bool {
func (s *InMemoryStoreType) Limit(key string) (bool, time.Duration) {
s.mutex.Lock()
defer s.mutex.Unlock()
_, ok := s.data[key]
Expand All @@ -42,17 +42,18 @@ func (s *InMemoryStoreType) Limit(key string) bool {
if u.ts+s.rate <= time.Now().Unix() {
u.tokens = s.limit
}
remaining := time.Duration((s.rate - (time.Now().Unix() - u.ts)) * time.Second.Nanoseconds())
if u.tokens <= 0 {
return true
return true, remaining
}
u.tokens--
u.ts = time.Now().Unix()
s.data[key] = u
return false
return false, time.Duration(0)
}

type store interface {
Limit(key string) bool
Limit(key string) (bool, time.Duration)
}

func InMemoryStore(rate time.Duration, limit int) *InMemoryStoreType {
Expand All @@ -63,12 +64,12 @@ func InMemoryStore(rate time.Duration, limit int) *InMemoryStoreType {
return &store
}

func RateLimiter(keyFunc func(c *gin.Context) string, errorHandler func(c *gin.Context), s store) func(ctx *gin.Context) {
func RateLimiter(keyFunc func(c *gin.Context) string, errorHandler func(c *gin.Context, remaining time.Duration), s store) func(ctx *gin.Context) {
return func(c *gin.Context) {
key := keyFunc(c)
limited := s.Limit(key)
limited, remaining := s.Limit(key)
if limited {
errorHandler(c)
errorHandler(c, remaining)
c.Abort()
} else {
c.Next()
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func keyFunc(c *gin.Context) string {
return c.ClientIP()
}

func errorHandler(c *gin.Context) {
c.String(429, "Too many requests")
func errorHandler(c *gin.Context, remaining time.Duration) {
c.String(429, "Too many requests. Try again in "+remaining.String())
}

func main() {
Expand Down Expand Up @@ -71,8 +71,8 @@ func keyFunc(c *gin.Context) string {
return c.ClientIP()
}

func errorHandler(c *gin.Context) {
c.String(429, "Too many requests")
func errorHandler(c *gin.Context, remaining time.Duration) {
c.String(429, "Too many requests. Try again in "+remaining.String())
}

func main() {
Expand All @@ -94,12 +94,15 @@ Custom Store Example
```go
package main

import "time"

type CustomStore struct {
}

// Your store must have a method called Limit that takes a key and returns a bool
func (s *CustomStore) Limit(key string) bool {
func (s *CustomStore) Limit(key string) (bool, time.Duration) {
// Do your rate limit logic, and return true if the user went over the rate limit, otherwise return false
// Return the amount of time the client needs to wait to make a new request
if UserWentOverLimit {
return true
}
Expand Down
38 changes: 22 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
module github.com/JGLTechnologies/GinRateLimit

go 1.17
go 1.18

require (
github.com/gin-gonic/gin v1.7.7
github.com/go-redis/redis/v8 v8.11.4
github.com/gin-gonic/gin v1.8.1
github.com/go-redis/redis/v8 v8.11.5
)

require (
github.com/goccy/go-json v0.9.7 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
golang.org/x/text v0.3.6 // indirect
)

require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect; indirec
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
Loading

0 comments on commit 85bd2fb

Please sign in to comment.