-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
extractIP
may return empty IP if RemoteAddr
has no port ( SplitHostPort
fallback suggestion)
#2757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
extractIP
may return empty IP if RemoteAddr has no port (SplitHostPort fallback suggestion)extractIP
may return empty IP if RemoteAddr
has no port ( SplitHostPort
fallback suggestion)
I have a issue with the ip extractor that looks verry much like this issue. However it behaves differently on ARM vs on X86_64 func getIpFromContext(c echo.Context) net.IP {
contextIp := c.RealIP()
if strings.Contains(contextIp, "[") {
endIndex := strings.Index(contextIp, "]:")
return net.ParseIP(contextIp[1:endIndex])
}
if strings.Contains(contextIp, ":") {
endIndex := strings.Index(contextIp, ":")
return net.ParseIP(contextIp[:endIndex])
}
return net.ParseIP(contextIp)
} This is used in production like this: var requesterIpAddress string
frameworkExtractedIP := c.RealIP()
customIpExtractor := getIpFromContext(c).String()
// this is required due to differences with X86_64 and ARM implementations of the echo frameworks ip extractor.
if ip := net.ParseIP(frameworkExtractedIP); ip != nil {
requesterIpAddress = ip.String()
}
// this is required due to differences with X86_64 and ARM implementations of the echo frameworks ip extractor.
if ip := net.ParseIP(customIpExtractor); ip != nil {
requesterIpAddress = ip.String()
} To be honest this was a dirty work around but it works and it was only an issue as I tried to support ARM |
Echo does not differentiate any CPU architecture from each other. Echo is built on Go standard library and if there are differences - it has to originate from there. about
// RemoteAddr allows HTTP servers and other software to record
// the network address that sent the request, usually for
// logging. This field is not filled in by ReadRequest and
// has no defined format. The HTTP server in this package
// sets RemoteAddr to an "IP:port" address before invoking a
// handler.
// This field is ignored by the HTTP client.
RemoteAddr string In which situation/environment/OS I am testing with this trivial example: package main
import (
"fmt"
"github.com/labstack/echo/v4"
"log/slog"
"net/http"
)
func main() {
e := echo.New()
//_, trusted, _ := net.ParseCIDR("127.0.0.1/32")
//e.IPExtractor = echo.ExtractIPFromRealIPHeader(
// echo.TrustIPRange(trusted),
//)
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, fmt.Sprintf("RemoteAddr: %s\n", c.Request().RemoteAddr))
})
if err := e.Start(":8080"); err != nil {
slog.Error("start server error: %v", err)
}
} |
I'm sorry for jumping to conclusions to quickly, the issue I'm experiencing may not be related to this issue at all... |
The extractIP function currently uses net.SplitHostPort to parse
http.Request.RemoteAddr
and extract the IP address.This works well when
RemoteAddr
is in the form "host:port", but SplitHostPort returns an error (and an empty host) if the port is missing — which is an intentional design choice in Go. In such cases, the extractIP function ends up returning an empty string.Relevant code:
https://github.com/labstack/echo/blob/master/ip.go#L221-L224
Introduced in:
124825e
This behavior can lead to issues in environments where
RemoteAddr
does not include a port such as "192.0.2.10". In such cases, extractIP returns an empty string, which causes functions likeRealIP()
orExtractIPFromXForwardedFor()
to behave unexpectedly (e.g. returning an empty IP or skipping IP trust checks).Suggested improvement:
Instead of returning an empty string when
SplitHostPort
fails, we propose falling back to the originalRemoteAddr
value — possibly with a simple validation using net.ParseIP.This approach improves robustness when
RemoteAddr
lacks a port. Alternatively, using a regular expression to extract the IP part may also work, but parsing it with net.ParseIP is likely sufficient.Let me know if this makes sense — happy to submit a PR if it would be helpful.
The text was updated successfully, but these errors were encountered: