Skip to content

Commit

Permalink
add rate limiting middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastvin committed Jan 9, 2025
1 parent 7601607 commit bd7ffe6
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func (s *APIServer) Run() error {
middlewareChain := MiddlewareChain(
RequestLoggerMiddleware,
RequireAuthMiddleware,
ThrottlingMiddleware(5*time.Second),
ThrottlingMiddleware(5*time.Second), // One request per second
RateLimitingMiddleware(3, 1*time.Minute), // Five request per minute
)

server := http.Server{
Expand Down Expand Up @@ -108,7 +109,7 @@ func ThrottlingMiddleware(limit time.Duration) Middleware {

lastTime, exists := lastRequestTime[userID]
if exists && time.Since(lastTime) < limit {
http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
http.Error(w, "Too Many Requests [Throttling Middleware Block Request]", http.StatusTooManyRequests)
return
}

Expand All @@ -118,3 +119,54 @@ func ThrottlingMiddleware(limit time.Duration) Middleware {
}
}
}

func RateLimitingMiddleware(maxRequests int, duration time.Duration) Middleware {
var requestCounts sync.Map

return func(next http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

path := r.URL.Path
if !strings.Contains(path, "/users/") {
http.Error(w, "Invalid URL format", http.StatusBadRequest)
return
}

userID := path[len("/users/"):]
if userID == "" {
http.Error(w, "User ID is required", http.StatusBadRequest)
return
}

value, _ := requestCounts.LoadOrStore(userID, &rateLimiter{
requestCount: 0,
resetTime: time.Now().Add(duration),
mu: sync.Mutex{},
})

limiter := value.(*rateLimiter)

limiter.mu.Lock()
defer limiter.mu.Unlock()

if time.Now().After(limiter.resetTime) {
limiter.requestCount = 0
limiter.resetTime = time.Now().Add(duration)
}

if limiter.requestCount >= maxRequests {
http.Error(w, "Too Many Requests [Rate Limiting Middleware Block Request]", http.StatusTooManyRequests)
return
}

limiter.requestCount++
next.ServeHTTP(w, r)
}
}
}

type rateLimiter struct {
requestCount int
resetTime time.Time
mu sync.Mutex
}

0 comments on commit bd7ffe6

Please sign in to comment.