TT-14891 - adds client ip from XFF by depth #7063
Merged
probelabs / Visor: performance
succeeded
Nov 3, 2025 in 3m 54s
✅ Check Passed (Warnings Found)
performance check passed. Found 1 warning, but fail_if condition was not met.
Details
📊 Summary
- Total Issues: 1
- Warning Issues: 1
🐛 Issues by Category
⚡ Performance (1)
⚠️ request/real_ip.go:28 - TheRealIPfunction's new implementation for parsing theX-Forwarded-Forheader usesstrings.Splitfor all cases. This function allocates a new slice and strings for each IP address in the header on every request. This introduces a performance regression compared to the previous, more efficient implementation which usedstrings.IndexBytefor the default case of selecting the first IP. For requests with a long chain of proxies in theX-Forwarded-Forheader, this can lead to a noticeable increase in memory allocations and garbage collector pressure on a critical request path.
Powered by Visor from Probelabs
💡 TIP: You can chat with Visor using /visor ask <your question>
Annotations
Check warning on line 28 in request/real_ip.go
probelabs / Visor: performance
performance Issue
The `RealIP` function's new implementation for parsing the `X-Forwarded-For` header uses `strings.Split` for all cases. This function allocates a new slice and strings for each IP address in the header on every request. This introduces a performance regression compared to the previous, more efficient implementation which used `strings.IndexByte` for the default case of selecting the first IP. For requests with a long chain of proxies in the `X-Forwarded-For` header, this can lead to a noticeable increase in memory allocations and garbage collector pressure on a critical request path.
Raw output
To mitigate the performance impact, optimize for the default case (`XFFDepth` is 0) by reverting to the more performant logic of using `strings.IndexByte` to find the first comma and then slicing the string. This avoids the overhead of `strings.Split` for the most common configuration and prevents a performance regression. The `strings.Split` logic should only be used when `XFFDepth > 0`.
**Example:**
```go
// ...
depth := 0
if Global != nil {
depth = Global().HttpServerOptions.XFFDepth
}
if fw := r.Header.Get(header.XForwardFor); fw != "" {
var ip string
if depth == 0 {
// Optimized path for default case
if i := strings.IndexByte(fw, ','); i >= 0 {
ip = fw[:i]
} else {
ip = fw
}
} else {
// Path for new functionality
xffs := strings.Split(fw, ",")
if depth > len(xffs) {
return ""
}
ip = xffs[len(xffs)-depth]
}
ip = strings.TrimSpace(ip)
if parsedIP := net.ParseIP(ip); parsedIP != nil {
return parsedIP.String()
}
// If IP is invalid, fall through to use RemoteAddr
}
// ...
```
Loading