savsgio / atreugo

High performance and extensible micro web framework. Zero memory allocations in hot paths.
Apache License 2.0
1.23k stars 71 forks source link

rate limit middleware request #91

Open anxuanzi opened 3 years ago

anxuanzi commented 3 years ago

Hi, I really like your framework and I'm currently using it for my project. I really need a rate limiter to control the traffic, I found some libraries that support Fasthttp. But I don't really know how to use them in Atreugo. Can you make a simple rate limiter middleware example to extend the Atreugo?

Libraries I found may be helpful:

savsgio commented 3 years ago

Hi @anxuanzi,

I will try to develop the middleware as soon as possible.

Thanks for use Atreugo 😉

anxuanzi commented 3 years ago

Hi @anxuanzi,

I will try to develop the middleware as soon as possible.

Thanks for use Atreugo

Thank you! Looking forward to that~

savsgio commented 3 years ago

Hi @anxuanzi,

I don't forget the middleware, but lately, i don't have too much time.

I will try to has it soon.

figuerom16 commented 2 weeks ago

Couldn't a rate limiter be something simple as this that we create ourselves? I know we wouldn't be able to prefork because limiters map wouldn't be shared. Is there a better way?

package main

import (
    "errors"
    "net"
    "sync"

    "github.com/savsgio/atreugo/v11"
    "github.com/valyala/fasthttp"
    "golang.org/x/time/rate"
)

var limiters sync.Map

func RateLimiter(a *atreugo.RequestCtx) error {
    ip, _, err := net.SplitHostPort(a.RemoteAddr().String())
    if err != nil {
        return a.ErrorResponse(err, 555)
    }
    if ip == "127.0.0.1" || ip == "::1" {
        return a.Next()
    }
    limiter, _ := limiters.LoadOrStore(ip, rate.NewLimiter(10, 100))
    if !limiter.(*rate.Limiter).Allow() {
        return a.ErrorResponse(errors.New("too many requests"), fasthttp.StatusTooManyRequests)
    }
    return a.Next()
}