package main
import (
"fmt"
"net"
"net/http"
"strings"
)
// https://github.com/gin-gonic/gin/blob/4867ff9634d1889156587d5add70d2b29c447542/context.go#L636
// ClientIP implements a best effort algorithm to return the real client IP, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
// Use X-Forwarded-For before X-Real-Ip as nginx uses X-Real-Ip with the proxy's IP.
func ClientIP(r *http.Request) string {
clientIP := r.Header.Get("X-Forwarded-For")
clientIP = strings.TrimSpace(strings.Split(clientIP, ",")[0])
if clientIP == "" {
clientIP = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
}
if clientIP != "" {
return clientIP
}
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
return ip
}
return ""
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "ip is %s", ClientIP(r))
})
http.ListenAndServe(":8080", mux)
}