1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-08 20:41:57 +00:00

add Context.SendFileWithRate, ServeFileWithRate and ServeContentWithRate

as requested at: https://github.com/kataras/iris/issues/1493


Former-commit-id: 7783fde04b4247056e6309e7ec1df27f027dc655
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-05-02 17:46:17 +03:00
parent 1e1d8a4855
commit dbd6fcd2d7
8 changed files with 223 additions and 105 deletions

View File

@@ -50,10 +50,11 @@ type (
Limiter struct {
clientDataFunc func(ctx context.Context) interface{} // fill the Client's Data field.
exceedHandler context.Handler // when too many requests.
limit rate.Limit
burstSize int
clients map[string]*Client
mu sync.RWMutex // mutex for clients.
pool *sync.Pool // object pool for clients.
}
Client struct {
@@ -68,14 +69,10 @@ type (
const Inf = math.MaxFloat64
func Limit(limit float64, burst int, options ...Option) context.Handler {
rateLimit := rate.Limit(limit)
l := &Limiter{
clients: make(map[string]*Client),
pool: &sync.Pool{New: func() interface{} {
return &Client{limiter: rate.NewLimiter(rateLimit, burst)}
}},
clients: make(map[string]*Client),
limit: rate.Limit(limit),
burstSize: burst,
exceedHandler: func(ctx context.Context) {
ctx.StopWithStatus(429) // Too Many Requests.
},
@@ -88,21 +85,10 @@ func Limit(limit float64, burst int, options ...Option) context.Handler {
return l.serveHTTP
}
func (l *Limiter) acquire() *Client {
return l.pool.Get().(*Client)
}
func (l *Limiter) release(client *Client) {
client.IP = ""
client.Data = nil
l.pool.Put(client)
}
func (l *Limiter) Purge(condition func(*Client) bool) {
l.mu.Lock()
for ip, client := range l.clients {
if condition(client) {
l.release(client)
delete(l.clients, ip)
}
}
@@ -116,12 +102,15 @@ func (l *Limiter) serveHTTP(ctx context.Context) {
l.mu.RUnlock()
if !ok {
client = l.acquire()
client.IP = ip
client = &Client{
limiter: rate.NewLimiter(l.limit, l.burstSize),
IP: ip,
}
if l.clientDataFunc != nil {
client.Data = l.clientDataFunc(ctx)
}
// if l.store(ctx, client) {
// ^ no, let's keep it simple.
l.mu.Lock()