implement rate limiting
This commit is contained in:
1
go.mod
1
go.mod
@@ -7,6 +7,7 @@ require (
|
|||||||
github.com/gorilla/sessions v1.4.0
|
github.com/gorilla/sessions v1.4.0
|
||||||
golang.org/x/crypto v0.36.0
|
golang.org/x/crypto v0.36.0
|
||||||
modernc.org/sqlite v1.36.1
|
modernc.org/sqlite v1.36.1
|
||||||
|
golang.org/x/time v0.11.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -29,6 +29,8 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||||
|
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||||
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
||||||
|
|||||||
35
helpers/ratelimit.go
Normal file
35
helpers/ratelimit.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
)
|
||||||
|
|
||||||
|
var visitors = make(map[string]*rate.Limiter)
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
func GetVisitorLimiter(ip string) *rate.Limiter {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
|
limiter, exists := visitors[ip]
|
||||||
|
if !exists {
|
||||||
|
limiter = rate.NewLimiter(1, 5)
|
||||||
|
visitors[ip] = limiter
|
||||||
|
}
|
||||||
|
return limiter
|
||||||
|
}
|
||||||
|
|
||||||
|
func RateLimit(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ip, _, _ := net.SplitHostPort(r.RemoteAddr)
|
||||||
|
if !GetVisitorLimiter(ip).Allow() {
|
||||||
|
http.Error(w, "Too many requests", http.StatusTooManyRequests)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
3
main.go
3
main.go
@@ -4,6 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"synlotto-website/handlers"
|
"synlotto-website/handlers"
|
||||||
|
"synlotto-website/helpers"
|
||||||
"synlotto-website/models"
|
"synlotto-website/models"
|
||||||
"synlotto-website/storage"
|
"synlotto-website/storage"
|
||||||
|
|
||||||
@@ -35,5 +36,5 @@ func main() {
|
|||||||
mux.HandleFunc("/results/thunderball", handlers.ResultsThunderball(db))
|
mux.HandleFunc("/results/thunderball", handlers.ResultsThunderball(db))
|
||||||
|
|
||||||
log.Println("🌐 Running on http://localhost:8080")
|
log.Println("🌐 Running on http://localhost:8080")
|
||||||
http.ListenAndServe(":8080", csrfMiddleware(mux))
|
http.ListenAndServe(":8080", helpers.RateLimit(csrfMiddleware(mux)))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user