mirror of
https://github.com/marcusDenslow/terminalShop.git
synced 2026-10-25 10:02:21 +01:00
41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"strconv"
|
|
|
|
"github.com/go-chi/httprate"
|
|
"terminalShop/pkg/utils"
|
|
)
|
|
|
|
// RateLimitByIP returns a per-IP rate limiter for public endpoints.
|
|
func RateLimitByIP(limit int, window time.Duration) func(http.Handler) http.Handler {
|
|
return httprate.Limit(
|
|
limit, window,
|
|
httprate.WithKeyFuncs(httprate.KeyByIP),
|
|
httprate.WithLimitHandler(func(w http.ResponseWriter, r *http.Request) {
|
|
utils.RespondError(w, http.StatusTooManyRequests, "RATE_LIMITED", "too many requests", nil)
|
|
}),
|
|
)
|
|
}
|
|
|
|
// RateLimitByUser returns a per-authenticated-user rate limiter for protected endpoints.
|
|
func RateLimitByUser(limit int, window time.Duration) func(http.Handler) http.Handler {
|
|
return httprate.Limit(
|
|
limit, window,
|
|
httprate.WithKeyFuncs(func(r *http.Request) (string, error) {
|
|
userID := UserIDFromContext(r.Context())
|
|
if userID == 0 {
|
|
// Fall back to IP if no user context (shouldn't happen on protected routes).
|
|
return httprate.KeyByIP(r)
|
|
}
|
|
return "user:" + strconv.FormatUint(uint64(userID), 10), nil
|
|
}),
|
|
httprate.WithLimitHandler(func(w http.ResponseWriter, r *http.Request) {
|
|
utils.RespondError(w, http.StatusTooManyRequests, "RATE_LIMITED", "too many requests", nil)
|
|
}),
|
|
)
|
|
}
|