Skip to content

Commit 9f0e7e1

Browse files
committed
more changes
1 parent e90a6c1 commit 9f0e7e1

File tree

1 file changed

+37
-20
lines changed

1 file changed

+37
-20
lines changed

limit.go

+37-20
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
package antiDdos
22

33
import (
4+
"net"
45
"net/http"
5-
"strings"
66
"sync"
77
"time"
88

99
"golang.org/x/time/rate"
1010
)
1111

12-
// r - time.second
13-
// b - request/per time
14-
12+
// IPRateLimiter представляет собой ограничитель скорости по IP-адресу.
1513
type IPRateLimiter struct {
16-
ips map[string]*rate.Limiter
17-
mu *sync.RWMutex
18-
r rate.Limit
19-
b int
14+
ips map[string]*rate.Limiter // Карта IP-адресов и соответствующих ограничителей скорости
15+
mu *sync.RWMutex // Мьютекс для безопасного доступа к картам IP-адресов
16+
r rate.Limit // Предел скорости
17+
b int // Максимальное количество запросов, разрешенных в интервал времени
2018
}
2119

20+
// NewIPRateLimiter создает новый экземпляр IPRateLimiter с заданным интервалом времени и максимальным количеством запросов.
2221
func NewIPRateLimiter(t time.Duration, b int) *IPRateLimiter {
2322
i := &IPRateLimiter{
2423
ips: make(map[string]*rate.Limiter),
@@ -30,6 +29,7 @@ func NewIPRateLimiter(t time.Duration, b int) *IPRateLimiter {
3029
return i
3130
}
3231

32+
// AddIP добавляет IP-адрес в карту IP-адресов и создает для него новый ограничитель скорости.
3333
func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter {
3434
i.mu.Lock()
3535
defer i.mu.Unlock()
@@ -41,24 +41,35 @@ func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter {
4141
return limiter
4242
}
4343

44+
// GetLimiter возвращает ограничитель скорости для заданного IP-адреса.
45+
// Если ограничитель для данного IP-адреса уже существует, он возвращается.
46+
// В противном случае создается новый ограничитель и добавляется в карту IP-адресов.
4447
func (i *IPRateLimiter) GetLimiter(ip string) *rate.Limiter {
4548
i.mu.Lock()
49+
defer i.mu.Unlock()
50+
4651
limiter, exists := i.ips[ip]
4752

4853
if !exists {
49-
i.mu.Unlock()
50-
return i.AddIP(ip)
54+
limiter = i.AddIP(ip)
5155
}
5256

53-
i.mu.Unlock()
54-
5557
return limiter
5658
}
5759

58-
59-
func (i *IPRateLimiter) LimitMiddleware(next http.Handler) http.Handler {
60+
// LimitMiddleware является промежуточным обработчиком HTTP и ограничивает скорость запросов для каждого IP-адреса.
61+
// Если количество запросов превышает максимальное количество разрешенных запросов в заданный интервал времени,
62+
// возвращается ошибка "Too Many Requests" (код 429).
63+
func (i *IPRateLimiter) LimitMiddleware(next http.Handler) http.Handler {
6064
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
61-
limiter := i.GetLimiter(getIPFromRemoteAddr(r.RemoteAddr))
65+
ip := getClientIP(r)
66+
67+
if ip == "" {
68+
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
69+
return
70+
}
71+
72+
limiter := i.GetLimiter(ip)
6273

6374
if !limiter.Allow() {
6475
http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
@@ -69,8 +80,14 @@ func (i *IPRateLimiter) LimitMiddleware(next http.Handler) http.Handler {
6980
})
7081
}
7182

72-
func getIPFromRemoteAddr(remoteAddr string) (ip string) {
73-
trim := strings.Split(remoteAddr, ":")
74-
ip = trim[0]
75-
return
76-
}
83+
// getClientIP возвращает IP-адрес клиента из заголовка X-Forwarded-For
84+
// Если заголовок отсутствует, то IP-адрес извлекается из RemoteAddr.
85+
func getClientIP(r *http.Request) string {
86+
ip := r.Header.Get("X-Forwarded-For")
87+
88+
if ip == "" {
89+
ip, _, _ = net.SplitHostPort(r.RemoteAddr)
90+
}
91+
92+
return ip
93+
}

0 commit comments

Comments
 (0)