Skip to content

Commit ccecc0c

Browse files
committed
Introduce RespondOnLimit() vs. OnLimit()
1 parent c4c778c commit ccecc0c

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ r.Post("/login", func(w http.ResponseWriter, r *http.Request) {
9595
}
9696

9797
// Rate-limit login at 5 req/min.
98-
if loginRateLimiter.OnLimit(w, r, payload.Username) {
98+
if loginRateLimiter.RespondOnLimit(w, r, payload.Username) {
9999
return
100100
}
101101

_example/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func main() {
5656
}
5757

5858
// Rate-limit login at 5 req/min.
59-
if loginRateLimiter.OnLimit(w, r, payload.Username) {
59+
if loginRateLimiter.RespondOnLimit(w, r, payload.Username) {
6060
return
6161
}
6262

limiter.go

+17-6
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ type RateLimiter struct {
6666
mu sync.Mutex
6767
}
6868

69-
// OnLimit checks the rate limit for the given key. If the limit is reached, it returns true
70-
// and automatically sends HTTP response. The caller should halt further request processing.
71-
// If the limit is not reached, it increments the request count and returns false, allowing
72-
// the request to proceed.
69+
// OnLimit checks the rate limit for the given key and updates the response headers accordingly.
70+
// If the limit is reached, it returns true, indicating that the request should be halted. Otherwise,
71+
// it increments the request count and returns false. This method does not send an HTTP response,
72+
// so the caller must handle the response themselves or use the RespondOnLimit() method instead.
7373
func (l *RateLimiter) OnLimit(w http.ResponseWriter, r *http.Request, key string) bool {
7474
currentWindow := time.Now().UTC().Truncate(l.windowLength)
7575
ctx := r.Context()
@@ -100,7 +100,6 @@ func (l *RateLimiter) OnLimit(w http.ResponseWriter, r *http.Request, key string
100100

101101
l.mu.Unlock()
102102
setHeader(w, l.headers.RetryAfter, fmt.Sprintf("%d", int(l.windowLength.Seconds()))) // RFC 6585
103-
l.onRateLimited(w, r)
104103
return true
105104
}
106105

@@ -116,6 +115,18 @@ func (l *RateLimiter) OnLimit(w http.ResponseWriter, r *http.Request, key string
116115
return false
117116
}
118117

118+
// RespondOnLimit checks the rate limit for the given key and updates the response headers accordingly.
119+
// If the limit is reached, it automatically sends an HTTP response and returns true, signaling the
120+
// caller to halt further request processing. If the limit is not reached, it increments the request
121+
// count and returns false, allowing the request to proceed.
122+
func (l *RateLimiter) RespondOnLimit(w http.ResponseWriter, r *http.Request, key string) bool {
123+
onLimit := l.OnLimit(w, r, key)
124+
if onLimit {
125+
l.onRateLimited(w, r)
126+
}
127+
return onLimit
128+
}
129+
119130
func (l *RateLimiter) Counter() LimitCounter {
120131
return l.limitCounter
121132
}
@@ -132,7 +143,7 @@ func (l *RateLimiter) Handler(next http.Handler) http.Handler {
132143
return
133144
}
134145

135-
if l.OnLimit(w, r, key) {
146+
if l.RespondOnLimit(w, r, key) {
136147
return
137148
}
138149

limiter_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ func TestRateLimitPayload(t *testing.T) {
454454
}
455455

456456
// Rate-limit login at 5 req/min.
457-
if loginRateLimiter.OnLimit(w, r, payload.Username) {
457+
if loginRateLimiter.RespondOnLimit(w, r, payload.Username) {
458458
return
459459
}
460460

0 commit comments

Comments
 (0)