forked from JointCloud/pcm-coordinator
49 lines
992 B
Go
49 lines
992 B
Go
package utils
|
||
|
||
import (
|
||
"net"
|
||
"net/http"
|
||
"strings"
|
||
)
|
||
|
||
func GetClientIP(r *http.Request) string {
|
||
// 检查反向代理设置的常用头信息(按优先级排序)
|
||
headers := []string{
|
||
"X-Forwarded-For",
|
||
"X-Real-Ip",
|
||
"Proxy-Client-IP",
|
||
"WL-Proxy-Client-IP",
|
||
"HTTP_CLIENT_IP",
|
||
"HTTP_X_FORWARDED_FOR",
|
||
}
|
||
|
||
for _, header := range headers {
|
||
ip := r.Header.Get(header)
|
||
if ip != "" {
|
||
// 处理多IP情况(取第一个有效IP)
|
||
parts := strings.Split(ip, ",")
|
||
for _, part := range parts {
|
||
ip = strings.TrimSpace(part)
|
||
if ip != "" && !strings.EqualFold(ip, "unknown") {
|
||
return parseIP(ip)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 回退到直接连接IP(带端口时需要处理)
|
||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||
if err != nil {
|
||
return r.RemoteAddr // 无端口的情况直接返回
|
||
}
|
||
return parseIP(ip)
|
||
}
|
||
|
||
// 处理特殊格式IP(如IPv6本地地址)
|
||
func parseIP(ip string) string {
|
||
if ip == "::1" {
|
||
return "127.0.0.1"
|
||
}
|
||
return ip
|
||
}
|