Adding upstream version 2.52.6.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a960158181
commit
6d002e9543
441 changed files with 95392 additions and 0 deletions
727
middleware/limiter/limiter_test.go
Normal file
727
middleware/limiter/limiter_test.go
Normal file
|
@ -0,0 +1,727 @@
|
|||
package limiter
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http/httptest"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/internal/storage/memory"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// go test -run Test_Limiter_Concurrency_Store -race -v
|
||||
func Test_Limiter_Concurrency_Store(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test concurrency using a custom store
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 50,
|
||||
Expiration: 2 * time.Second,
|
||||
Storage: memory.New(),
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello tester!")
|
||||
})
|
||||
|
||||
var wg sync.WaitGroup
|
||||
singleRequest := func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, "Hello tester!", string(body))
|
||||
}
|
||||
|
||||
for i := 0; i <= 49; i++ {
|
||||
wg.Add(1)
|
||||
go singleRequest(&wg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Concurrency -race -v
|
||||
func Test_Limiter_Concurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test concurrency using a default store
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 50,
|
||||
Expiration: 2 * time.Second,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello tester!")
|
||||
})
|
||||
|
||||
var wg sync.WaitGroup
|
||||
singleRequest := func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, "Hello tester!", string(body))
|
||||
}
|
||||
|
||||
for i := 0; i <= 49; i++ {
|
||||
wg.Add(1)
|
||||
go singleRequest(&wg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Fixed_Window_No_Skip_Choices -v
|
||||
func Test_Limiter_Fixed_Window_No_Skip_Choices(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 2,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipFailedRequests: false,
|
||||
SkipSuccessfulRequests: false,
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" { //nolint:goconst // False positive
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Fixed_Window_Custom_Storage_No_Skip_Choices -v
|
||||
func Test_Limiter_Fixed_Window_Custom_Storage_No_Skip_Choices(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 2,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipFailedRequests: false,
|
||||
SkipSuccessfulRequests: false,
|
||||
Storage: memory.New(),
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Sliding_Window_No_Skip_Choices -v
|
||||
func Test_Limiter_Sliding_Window_No_Skip_Choices(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 2,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipFailedRequests: false,
|
||||
SkipSuccessfulRequests: false,
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(4*time.Second + 500*time.Millisecond)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Sliding_Window_Custom_Storage_No_Skip_Choices -v
|
||||
func Test_Limiter_Sliding_Window_Custom_Storage_No_Skip_Choices(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 2,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipFailedRequests: false,
|
||||
SkipSuccessfulRequests: false,
|
||||
Storage: memory.New(),
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(4*time.Second + 500*time.Millisecond)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Fixed_Window_Skip_Failed_Requests -v
|
||||
func Test_Limiter_Fixed_Window_Skip_Failed_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipFailedRequests: true,
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Fixed_Window_Custom_Storage_Skip_Failed_Requests -v
|
||||
func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Failed_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
Storage: memory.New(),
|
||||
SkipFailedRequests: true,
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Sliding_Window_Skip_Failed_Requests -v
|
||||
func Test_Limiter_Sliding_Window_Skip_Failed_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipFailedRequests: true,
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(4*time.Second + 500*time.Millisecond)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Sliding_Window_Custom_Storage_Skip_Failed_Requests -v
|
||||
func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Failed_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
Storage: memory.New(),
|
||||
SkipFailedRequests: true,
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(4*time.Second + 500*time.Millisecond)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Fixed_Window_Skip_Successful_Requests -v
|
||||
func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test concurrency using a default store
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipSuccessfulRequests: true,
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests -v
|
||||
func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test concurrency using a default store
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
Storage: memory.New(),
|
||||
SkipSuccessfulRequests: true,
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Sliding_Window_Skip_Successful_Requests -v
|
||||
func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test concurrency using a default store
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
SkipSuccessfulRequests: true,
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(4*time.Second + 500*time.Millisecond)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests -v
|
||||
func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test concurrency using a default store
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 1,
|
||||
Expiration: 2 * time.Second,
|
||||
Storage: memory.New(),
|
||||
SkipSuccessfulRequests: true,
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/:status", func(c *fiber.Ctx) error {
|
||||
if c.Params("status") == "fail" {
|
||||
return c.SendStatus(400)
|
||||
}
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/success", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 200, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
|
||||
time.Sleep(4*time.Second + 500*time.Millisecond)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/fail", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 400, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Limiter_Custom_Store -benchmem -count=4
|
||||
func Benchmark_Limiter_Custom_Store(b *testing.B) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 100,
|
||||
Expiration: 60 * time.Second,
|
||||
Storage: memory.New(),
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
|
||||
h := app.Handler()
|
||||
|
||||
fctx := &fasthttp.RequestCtx{}
|
||||
fctx.Request.Header.SetMethod(fiber.MethodGet)
|
||||
fctx.Request.SetRequestURI("/")
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
h(fctx)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -run Test_Limiter_Next
|
||||
func Test_Limiter_Next(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
app.Use(New(Config{
|
||||
Next: func(_ *fiber.Ctx) bool {
|
||||
return true
|
||||
},
|
||||
}))
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
}
|
||||
|
||||
func Test_Limiter_Headers(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 50,
|
||||
Expiration: 2 * time.Second,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello tester!")
|
||||
})
|
||||
|
||||
fctx := &fasthttp.RequestCtx{}
|
||||
fctx.Request.Header.SetMethod(fiber.MethodGet)
|
||||
fctx.Request.SetRequestURI("/")
|
||||
|
||||
app.Handler()(fctx)
|
||||
|
||||
utils.AssertEqual(t, "50", string(fctx.Response.Header.Peek("X-RateLimit-Limit")))
|
||||
if v := string(fctx.Response.Header.Peek("X-RateLimit-Remaining")); v == "" {
|
||||
t.Errorf("The X-RateLimit-Remaining header is not set correctly - value is an empty string.")
|
||||
}
|
||||
if v := string(fctx.Response.Header.Peek("X-RateLimit-Reset")); !(v == "1" || v == "2") {
|
||||
t.Errorf("The X-RateLimit-Reset header is not set correctly - value is out of bounds.")
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Limiter -benchmem -count=4
|
||||
func Benchmark_Limiter(b *testing.B) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 100,
|
||||
Expiration: 60 * time.Second,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
|
||||
h := app.Handler()
|
||||
|
||||
fctx := &fasthttp.RequestCtx{}
|
||||
fctx.Request.Header.SetMethod(fiber.MethodGet)
|
||||
fctx.Request.SetRequestURI("/")
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
h(fctx)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -run Test_Sliding_Window -race -v
|
||||
func Test_Sliding_Window(t *testing.T) {
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
app.Use(New(Config{
|
||||
Max: 10,
|
||||
Expiration: 2 * time.Second,
|
||||
Storage: memory.New(),
|
||||
LimiterMiddleware: SlidingWindow{},
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello tester!")
|
||||
})
|
||||
|
||||
singleRequest := func(shouldFail bool) {
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
if shouldFail {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 429, resp.StatusCode)
|
||||
} else {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
singleRequest(false)
|
||||
}
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
singleRequest(false)
|
||||
}
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
singleRequest(false)
|
||||
}
|
||||
|
||||
time.Sleep(4 * time.Second)
|
||||
|
||||
for i := 0; i < 9; i++ {
|
||||
singleRequest(false)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue