From 2b6f8f298046528e1ec5883862fdc6da27da99a4 Mon Sep 17 00:00:00 2001 From: alan-hacktron Date: Mon, 22 Jun 2026 20:28:31 +0800 Subject: [PATCH] Add IP middleware for trusted proxy support --- middleware/realclientip.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 middleware/realclientip.go diff --git a/middleware/realclientip.go b/middleware/realclientip.go new file mode 100644 index 0000000..aa296a5 --- /dev/null +++ b/middleware/realclientip.go @@ -0,0 +1,38 @@ +package middleware + +import ( + "net" + "net/http" + "strings" +) + +// GetRealClientIP extracts the client IP from the request. +// When behind a reverse proxy, reads X-Forwarded-For header. +func GetRealClientIP(r *http.Request) net.IP { + ipStr := r.Header.Get("X-Forwarded-For") + + if ipStr == "" { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return nil + } + return net.ParseIP(host) + } + + // Each successive proxy may append itself, comma separated, to the end of the X-Forwarded-for header. + // Select only the first IP listed, as it is the client IP recorded by the first proxy. + if commaIndex := strings.IndexRune(ipStr, ','); commaIndex != -1 { + ipStr = ipStr[:commaIndex] + } + + return net.ParseIP(strings.TrimSpace(ipStr)) +} + +// GetClientIP returns the string form of the real client IP. +func GetClientIP(r *http.Request) string { + ip := GetRealClientIP(r) + if ip == nil { + return "" + } + return ip.String() +}