Fix grpcserver rate limiter: move to Server field

The package-level defaultRateLimiter drained its token bucket
across all test cases, causing later tests to hit ResourceExhausted.
Move rateLimiter from a package-level var to a *grpcRateLimiter field
on Server; New() allocates a fresh instance (10 req/s, burst 10) per
server. Each test's newTestEnv() constructs its own Server, so tests
no longer share limiter state.

Production behaviour is unchanged: a single Server is constructed at
startup and lives for the process lifetime.
This commit is contained in:
2026-03-11 19:20:32 -07:00
parent a80242ae3e
commit 4596ea08ab
12 changed files with 276 additions and 123 deletions

View File

@@ -34,6 +34,7 @@ func (u *UIServer) handleAccountsList(w http.ResponseWriter, r *http.Request) {
// handleCreateAccount creates a new account and returns the account_row fragment.
func (u *UIServer) handleCreateAccount(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxFormBytes)
if err := r.ParseForm(); err != nil {
u.renderError(w, r, http.StatusBadRequest, "invalid form")
return
@@ -131,6 +132,7 @@ func (u *UIServer) handleAccountDetail(w http.ResponseWriter, r *http.Request) {
// handleUpdateAccountStatus toggles an account between active and inactive.
func (u *UIServer) handleUpdateAccountStatus(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxFormBytes)
if err := r.ParseForm(); err != nil {
u.renderError(w, r, http.StatusBadRequest, "invalid form")
return
@@ -251,6 +253,7 @@ func (u *UIServer) handleRolesEditForm(w http.ResponseWriter, r *http.Request) {
// handleSetRoles replaces the full role set for an account.
func (u *UIServer) handleSetRoles(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxFormBytes)
if err := r.ParseForm(); err != nil {
u.renderError(w, r, http.StatusBadRequest, "invalid form")
return