fix: server 429 response json formatting

This commit is contained in:
ae 2025-05-09 15:11:39 +03:00
parent 100f534b4c
commit ae3c0e6c0c
Signed by: ae
GPG Key ID: 995EFD5C1B532B3E

View File

@ -14,7 +14,10 @@ import (
"github.com/rs/zerolog/log"
)
const authRateLimit = 5 // req/min
const (
authRateLimit = 5 // req/min
postAuthRateLimit = 100 // req/min
)
type SvcConfig struct {
JWTSecret string
@ -40,7 +43,7 @@ func Run(conn *pgx.Conn, q *data.Queries, config SvcConfig) error {
authRouter := authResource{
Config: config,
RateLimiter: httprate.NewRateLimiter(authRateLimit, time.Minute),
RateLimiter: getRateLimiter(authRateLimit),
Users: q,
Tokens: q,
}
@ -55,7 +58,7 @@ func Run(conn *pgx.Conn, q *data.Queries, config SvcConfig) error {
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(loggerMiddleware(&log.Logger))
r.Use(httprate.LimitByIP(100, time.Minute)) // Base limit for all routes
r.Use(getRateLimiter(postAuthRateLimit).Handler) // Base limit applied globally
r.Use(cors.Handler(cors.Options{
AllowedOrigins: config.allowedOrigins(),
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
@ -86,6 +89,14 @@ func Run(conn *pgx.Conn, q *data.Queries, config SvcConfig) error {
return http.ListenAndServe(":8080", r)
}
// Generate a new rate limiter that responds to surpassing clients with HTTP 429 + JSON error message.
func getRateLimiter(requestLimit int) *httprate.RateLimiter {
return httprate.NewRateLimiter(requestLimit, time.Minute, httprate.WithLimitHandler(func(w http.ResponseWriter, r *http.Request) {
// NOTE: Error message mustn't contain a dot due to one being added client-side anyway
respondError(w, http.StatusTooManyRequests, "You're rate-limited, please slow down")
}))
}
// Start worker that automatically cleans up the `notes` (cascading to `note_versions`) and
// `refresh_tokens` tables from expired (or revoked) entries. The tasks run once during
// initialization and then once an hour until the backend is shutdown.