feat: improve ignoreIPs performance on CIDRs

This commit is contained in:
Oleh Astappiev 2024-12-08 00:13:00 +01:00
parent b2597fb5ed
commit b6d30d47ac
No known key found for this signature in database
GPG key ID: 37D7AC22589E9632

View file

@ -4,8 +4,8 @@ import (
"context" "context"
"fmt" "fmt"
"log" "log"
"net"
"net/http" "net/http"
"net/netip"
"os" "os"
"path" "path"
"strings" "strings"
@ -44,7 +44,7 @@ type Config struct {
// IgnoreUserAgents is a list of user agents that should be ignored. // IgnoreUserAgents is a list of user agents that should be ignored.
IgnoreUserAgents []string `json:"ignoreUserAgents"` IgnoreUserAgents []string `json:"ignoreUserAgents"`
// IgnoreIPs is a list of IPs that should be ignored. // IgnoreIPs is a list of IPs or CIDRs that should be ignored.
IgnoreIPs []string `json:"ignoreIPs"` IgnoreIPs []string `json:"ignoreIPs"`
// headerIp Header associated to real IP // headerIp Header associated to real IP
HeaderIp string `json:"headerIp"` HeaderIp string `json:"headerIp"`
@ -92,7 +92,7 @@ type UmamiFeeder struct {
trackExtensions []string trackExtensions []string
ignoreUserAgents []string ignoreUserAgents []string
ignoreIPs []string ignorePrefixes []netip.Prefix
headerIp string headerIp string
} }
@ -116,7 +116,7 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
trackExtensions: config.TrackExtensions, trackExtensions: config.TrackExtensions,
ignoreUserAgents: config.IgnoreUserAgents, ignoreUserAgents: config.IgnoreUserAgents,
ignoreIPs: config.IgnoreIPs, ignorePrefixes: []netip.Prefix{},
headerIp: config.HeaderIp, headerIp: config.HeaderIp,
} }
@ -129,6 +129,25 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
} }
} }
if len(config.IgnoreIPs) > 0 {
for _, ignoreIp := range config.IgnoreIPs {
network, err := netip.ParsePrefix(ignoreIp)
if err != nil {
network, err = netip.ParsePrefix(ignoreIp + "/32")
}
if err != nil || !network.IsValid() {
if err != nil {
h.error(err.Error())
}
h.error(fmt.Sprintf("invalid ignoreIp given %s, this param accepts only IP addresses or CIRD in a format 10.0.0.1/16", ignoreIp))
h.isDisabled = true
} else {
h.ignorePrefixes = append(h.ignorePrefixes, network)
}
}
}
return h, nil return h, nil
} }
@ -196,26 +215,20 @@ func (h *UmamiFeeder) shouldTrack(req *http.Request) bool {
} }
} }
if len(h.ignoreIPs) > 0 { if len(h.ignorePrefixes) > 0 {
requestIp := req.Header.Get(h.headerIp) requestIp := req.Header.Get(h.headerIp)
if requestIp == "" { if requestIp == "" {
requestIp = req.RemoteAddr requestIp = req.RemoteAddr
} }
ip := net.ParseIP(requestIp)
if ip == nil { ip, err := netip.ParseAddr(requestIp)
if err != nil {
h.debug("invalid IP %s", requestIp) h.debug("invalid IP %s", requestIp)
return false return false
} }
for _, disabledIp := range h.ignoreIPs {
dIp := net.ParseIP(disabledIp) for _, prefix := range h.ignorePrefixes {
if dIp == nil { if prefix.Contains(ip) {
_, ipNet, err := net.ParseCIDR(disabledIp)
if err != nil {
h.debug("invalid ignoreIp %s", disabledIp)
} else if ipNet.Contains(ip) {
return false
}
} else if dIp.Equal(ip) {
return false return false
} }
} }