Configuring the Rate Limiters.

This commit is contained in:
Maxime Delporte
2025-11-18 20:10:55 +01:00
parent 7de9ef89b7
commit 83bb7294db
2 changed files with 42 additions and 25 deletions

View File

@@ -62,34 +62,40 @@ func (app *application) rateLimit(next http.Handler) http.Handler {
// The function we are returning is a closure, which 'closes over' the limiter variable
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Extract the client's IP address from request.
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
app.serverErrorResponse(w, r, err)
return
}
// Only carry out the check if rate limiting is enabled
if app.config.limiter.enabled {
// Extract the client's IP address from request.
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
app.serverErrorResponse(w, r, err)
return
}
// Lock the mutex to prevent this code from being executed concurrently
mu.Lock()
// Lock the mutex to prevent this code from being executed concurrently
mu.Lock()
// Check to see if the IP address already exists in the map. If it doesn't, then initialize a new rate limiter and add the IP address and limiter to he map.
if _, found := clients[ip]; !found {
clients[ip] = &client{limiter: rate.NewLimiter(2, 4)}
}
// Check to see if the IP address already exists in the map. If it doesn't, then initialize a new rate limiter and add the IP address and limiter to the map.
if _, found := clients[ip]; !found {
// Use the requests-per-second and burst values from the config struct
rps := rate.Limit(app.config.limiter.rps)
burst := app.config.limiter.burst
clients[ip] = &client{limiter: rate.NewLimiter(rps, burst)}
}
// Update the last see time for the client.
clients[ip].lastSeen = time.Now()
// Update the last see time for the client.
clients[ip].lastSeen = time.Now()
// Call the Allow() method on the rate limiter for the current IP address. If the request isn't allowed, unlock the mutex and send a 429 Too Many Requests response
if !clients[ip].limiter.Allow() {
// Call the Allow() method on the rate limiter for the current IP address. If the request isn't allowed, unlock the mutex and send a 429 Too Many Requests response
if !clients[ip].limiter.Allow() {
mu.Unlock()
app.rateLimitExceededResponse(w, r)
return
}
// Very importantly, unlock the mutex before calling the next handler in the chain. Notice that we DON'T use defer to unlock the mutex, as that would mean that the mutex isn't unlocked until all the handlers downstream of this middleware have also returned
mu.Unlock()
app.rateLimitExceededResponse(w, r)
return
}
// Very importantly, unlock the mutex before calling the next handler in the chain. Notice that we DON'T use defer to unlock the mutex, as that would mean that the mutex isn't unlocked until all the handlers downstream of this middleware have also returned
mu.Unlock()
next.ServeHTTP(w, r)
})
}