From 6f6b2adfd7e995e12ca4437f5ec0cf2bb1d3e37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Tue, 21 Feb 2023 19:21:04 +0300 Subject: [PATCH 1/9] Update go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 597accb..dfaa14f 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/JGLTechnologies/gin-rate-limit +module github.com/sercanarga/gin-rate-limit go 1.17 From d3584c51fde7f95a96b8eb81b459d5833325d389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 03:59:32 +0300 Subject: [PATCH 2/9] Rate-Limit-Reset replaced with unixtime --- gin_rate_limit.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gin_rate_limit.go b/gin_rate_limit.go index 0610370..205039c 100644 --- a/gin_rate_limit.go +++ b/gin_rate_limit.go @@ -31,14 +31,14 @@ func RateLimiter(s Store, options *Options) gin.HandlerFunc { } if options.ErrorHandler == nil { options.ErrorHandler = func(c *gin.Context, info Info) { - c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%.2f", time.Until(info.ResetTime).Seconds())) + c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%d", info.ResetTime.Unix())) c.String(429, "Too many requests") } } if options.BeforeResponse == nil { options.BeforeResponse = func(c *gin.Context, info Info) { c.Header("X-Rate-Limit-Remaining", fmt.Sprintf("%v", info.RemainingHits)) - c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%.2f", time.Until(info.ResetTime).Seconds())) + c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%d", info.ResetTime.Unix())) } } if options.KeyFunc == nil { From 4fb24347bdd150488643a02fdac9ddeb2c4b54c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 04:04:37 +0300 Subject: [PATCH 3/9] Update gin_rate_limit.go --- gin_rate_limit.go | 1 + 1 file changed, 1 insertion(+) diff --git a/gin_rate_limit.go b/gin_rate_limit.go index 205039c..2e9d709 100644 --- a/gin_rate_limit.go +++ b/gin_rate_limit.go @@ -37,6 +37,7 @@ func RateLimiter(s Store, options *Options) gin.HandlerFunc { } if options.BeforeResponse == nil { options.BeforeResponse = func(c *gin.Context, info Info) { + fmt.Println(info); c.Header("X-Rate-Limit-Remaining", fmt.Sprintf("%v", info.RemainingHits)) c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%d", info.ResetTime.Unix())) } From 67a9fc1c525f0b9c3033b8d61602c478cb21666a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 04:10:40 +0300 Subject: [PATCH 4/9] Added limit info in info structure --- in_memory.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/in_memory.go b/in_memory.go index a8f3db9..a2e0f09 100644 --- a/in_memory.go +++ b/in_memory.go @@ -43,6 +43,7 @@ func (s *inMemoryStoreType) Limit(key string, c *gin.Context) Info { } if s.skip != nil && s.skip(c) { return Info{ + Limit: s.limit, RateLimited: false, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - u.ts)) * time.Second.Nanoseconds())), RemainingHits: u.tokens, @@ -50,6 +51,7 @@ func (s *inMemoryStoreType) Limit(key string, c *gin.Context) Info { } if u.tokens <= 0 { return Info{ + Limit: s.limit, RateLimited: true, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - u.ts)) * time.Second.Nanoseconds())), RemainingHits: 0, @@ -59,6 +61,7 @@ func (s *inMemoryStoreType) Limit(key string, c *gin.Context) Info { u.ts = time.Now().Unix() s.data.Store(key, u) return Info{ + Limit: s.limit, RateLimited: false, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - u.ts)) * time.Second.Nanoseconds())), RemainingHits: u.tokens, From 85072917beaf333e812180482026d362047a7a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 04:11:44 +0300 Subject: [PATCH 5/9] added header X-Rate-Limit-Limit --- gin_rate_limit.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gin_rate_limit.go b/gin_rate_limit.go index 2e9d709..437d5f8 100644 --- a/gin_rate_limit.go +++ b/gin_rate_limit.go @@ -7,6 +7,7 @@ import ( ) type Info struct { + Limit uint RateLimited bool ResetTime time.Time RemainingHits uint @@ -31,13 +32,14 @@ func RateLimiter(s Store, options *Options) gin.HandlerFunc { } if options.ErrorHandler == nil { options.ErrorHandler = func(c *gin.Context, info Info) { + c.Header("X-Rate-Limit-Limit", fmt.Sprintf("%d", info.Limit)) c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%d", info.ResetTime.Unix())) c.String(429, "Too many requests") } } if options.BeforeResponse == nil { options.BeforeResponse = func(c *gin.Context, info Info) { - fmt.Println(info); + c.Header("X-Rate-Limit-Limit", fmt.Sprintf("%d", info.Limit)) c.Header("X-Rate-Limit-Remaining", fmt.Sprintf("%v", info.RemainingHits)) c.Header("X-Rate-Limit-Reset", fmt.Sprintf("%d", info.ResetTime.Unix())) } From e32cd97e2f3e8f1e6d3569d75e1dbd7bbc0a86a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 04:14:02 +0300 Subject: [PATCH 6/9] changed module name --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index dfaa14f..597accb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/sercanarga/gin-rate-limit +module github.com/JGLTechnologies/gin-rate-limit go 1.17 From a91497ec6e7bfedf2a3738fda85be2a593338f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 04:16:24 +0300 Subject: [PATCH 7/9] Update go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 597accb..dfaa14f 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/JGLTechnologies/gin-rate-limit +module github.com/sercanarga/gin-rate-limit go 1.17 From 2c1ce273931c8248418943208e0a95591f622f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 04:20:02 +0300 Subject: [PATCH 8/9] package name fixed --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index dfaa14f..597accb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/sercanarga/gin-rate-limit +module github.com/JGLTechnologies/gin-rate-limit go 1.17 From b0898951d1b0c1f5e2c5bdfcde2dec14a01d3188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20Ar=C4=9Fa?= Date: Wed, 22 Feb 2023 08:11:53 +0300 Subject: [PATCH 9/9] Edited Info structure in redis.go file. Edited the example in README.md file. --- README.md | 2 ++ redis.go | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 79504a9..be64c52 100644 --- a/README.md +++ b/README.md @@ -117,12 +117,14 @@ type CustomStore struct { func (s *CustomStore) Limit(key string, c *gin.Context) Info { if UserWentOverLimit { return Info{ + Limit: 100, RateLimited: true, ResetTime: reset, RemainingHits: 0, } } return Info{ + Limit: 100, RateLimited: false, ResetTime: reset, RemainingHits: remaining, diff --git a/redis.go b/redis.go index 9ad1206..24b3a9d 100644 --- a/redis.go +++ b/redis.go @@ -38,6 +38,7 @@ func (s *redisStoreType) Limit(key string, c *gin.Context) Info { } if s.skip != nil && s.skip(c) { return Info{ + Limit: s.limit, RateLimited: false, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - ts)) * time.Second.Nanoseconds())), RemainingHits: s.limit - uint(hits), @@ -50,6 +51,7 @@ func (s *redisStoreType) Limit(key string, c *gin.Context) Info { panic(err) } else { return Info{ + Limit: s.limit, RateLimited: false, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - ts)) * time.Second.Nanoseconds())), RemainingHits: 0, @@ -57,6 +59,7 @@ func (s *redisStoreType) Limit(key string, c *gin.Context) Info { } } return Info{ + Limit: s.limit, RateLimited: true, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - ts)) * time.Second.Nanoseconds())), RemainingHits: 0, @@ -74,6 +77,7 @@ func (s *redisStoreType) Limit(key string, c *gin.Context) Info { panic(err) } else { return Info{ + Limit: s.limit, RateLimited: false, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - ts)) * time.Second.Nanoseconds())), RemainingHits: s.limit - uint(hits), @@ -81,6 +85,7 @@ func (s *redisStoreType) Limit(key string, c *gin.Context) Info { } } return Info{ + Limit: s.limit, RateLimited: false, ResetTime: time.Now().Add(time.Duration((s.rate - (time.Now().Unix() - ts)) * time.Second.Nanoseconds())), RemainingHits: s.limit - uint(hits),