You've already forked pocketbase
mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-09-16 09:36:20 +02:00
added the triggered rate limit rule in the error log details
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
## v0.29.0 (WIP)
|
||||
|
||||
- Added the triggered rate rimit rule in the error log `details`.
|
||||
|
||||
|
||||
## v0.28.4
|
||||
|
||||
- Added global JSVM `toBytes()` helper to return the bytes slice representation of a value such as io.Reader or string (_other types are first serialized to Go string_).
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package apis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -167,7 +168,7 @@ func checkRateLimit(e *core.RequestEvent, rtId string, rule core.RateLimitRule)
|
||||
}
|
||||
|
||||
if !rt.isAllowed(key) {
|
||||
return e.TooManyRequestsError("", nil)
|
||||
return e.TooManyRequestsError("", errors.New("triggered rate limit rule: "+rule.String()))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@@ -704,3 +704,13 @@ func (c RateLimitRule) Validate() error {
|
||||
func (c RateLimitRule) DurationTime() time.Duration {
|
||||
return time.Duration(c.Duration) * time.Second
|
||||
}
|
||||
|
||||
// String returns a string representation of the rule.
|
||||
func (c RateLimitRule) String() string {
|
||||
raw, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
return c.Label // extremely rare case
|
||||
}
|
||||
|
||||
return string(raw)
|
||||
}
|
||||
|
@@ -687,7 +687,7 @@ func TestRateLimitsFindRateLimitRule(t *testing.T) {
|
||||
func TestRateLimitRuleValidate(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
config core.RateLimitRule
|
||||
rule core.RateLimitRule
|
||||
expectedErrors []string
|
||||
}{
|
||||
{
|
||||
@@ -784,7 +784,7 @@ func TestRateLimitRuleValidate(t *testing.T) {
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.name, func(t *testing.T) {
|
||||
result := s.config.Validate()
|
||||
result := s.rule.Validate()
|
||||
|
||||
tests.TestValidationErrors(t, result, s.expectedErrors)
|
||||
})
|
||||
@@ -793,7 +793,7 @@ func TestRateLimitRuleValidate(t *testing.T) {
|
||||
|
||||
func TestRateLimitRuleDurationTime(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
config core.RateLimitRule
|
||||
rule core.RateLimitRule
|
||||
expected time.Duration
|
||||
}{
|
||||
{core.RateLimitRule{}, 0 * time.Second},
|
||||
@@ -801,8 +801,8 @@ func TestRateLimitRuleDurationTime(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
t.Run(fmt.Sprintf("%d_%d", i, s.config.Duration), func(t *testing.T) {
|
||||
result := s.config.DurationTime()
|
||||
t.Run(fmt.Sprintf("%d_%d", i, s.rule.Duration), func(t *testing.T) {
|
||||
result := s.rule.DurationTime()
|
||||
|
||||
if result != s.expected {
|
||||
t.Fatalf("Expected duration %d, got %d", s.expected, result)
|
||||
@@ -810,3 +810,37 @@ func TestRateLimitRuleDurationTime(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateLimitRuleString(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
rule core.RateLimitRule
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"empty",
|
||||
core.RateLimitRule{},
|
||||
`{"label":"","audience":"","duration":0,"maxRequests":0}`,
|
||||
},
|
||||
{
|
||||
"all fields",
|
||||
core.RateLimitRule{
|
||||
Label: "POST /a/b/",
|
||||
Duration: 1,
|
||||
MaxRequests: 2,
|
||||
Audience: core.RateLimitRuleAudienceAuth,
|
||||
},
|
||||
`{"label":"POST /a/b/","audience":"@auth","duration":1,"maxRequests":2}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.name, func(t *testing.T) {
|
||||
result := s.rule.String()
|
||||
|
||||
if result != s.expected {
|
||||
t.Fatalf("Expected string\n%s\ngot\n%s", s.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user