I have a rate limiter for requests and using it as a middleware for every mux handler in my project.
The problem occurs when middleware is called 4 times when going to a page with path of /post. Every other page seems to work as expected - calls the middleware once.
Server handlers / configurations
mux := http.NewServeMux()
mux.Handle("/", ratelimit.Middleware(handler.Home(env)))
mux.Handle("/createpost", ratelimit.Middleware(post.Create(env)))
mux.Handle("/post", ratelimit.Middleware(post.View(env)))
mux.Handle("/addcomment", handler.AddComment(env))
...
// TLS Configurations (dont know if these should matter)
cfg := &tls.Config{
// Causes servers to use Go's default ciphersuite preferences,
// which are tuned to avoid attacks. Does nothing on clients.
PreferServerCipherSuites: true,
// Avoid server using unoptimized curves
CurvePreferences: []tls.CurveID{
tls.CurveP256,
tls.X25519, // Go 1.8 only
},
}
// Create a server with our configurations
s := &http.Server{
Addr: ":8000",
Handler: mux,
TLSConfig: cfg,
IdleTimeout: time.Minute, // Close all keep-alive connections after IdleTimeout
ReadTimeout: 5 * time.Second, // Time for server to read HTTP request body/headers
WriteTimeout: 10 * time.Second, // Time for server to write to response aka http.Handler lifecycle
}
if err := s.ListenAndServeTLS("./cert/CA/localhost/localhost.crt", "./cert/CA/localhost/localhost.decrypted.key"); err != nil {
log.Fatalln(err)
}
Middleware(Rate limiting requests by Token Bucket algorithm)
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
log.Println(err)
return
}
if _, exists := IPTokenBuckets[ip]; !exists {
IPTokenBuckets[ip] = &TokenBucket{
maxTokens: 5,
currentTokens: 5,
lastRefill: time.Now(),
refillRate: 1, // how many per second
}
}
tb := IPTokenBuckets[ip]
// fmt.Println("Token bucket", tb)
if tb.allowRequest() {
} else {
log.Println("Rate limit exceeded", ip)
return
}
fmt.Println("Middleware")
next.ServeHTTP(rw, r)
})
}