trustedRealClientIP finds the client IP from the request assuming it is from a trusted client. If there is no client IP headers, then the direct remote address is returned. If there are client IP headers, then the first value from those headers is used.
(r *http.Request, headers []string, clientIP string)
| 1089 | // direct remote address is returned. If there are client IP headers, |
| 1090 | // then the first value from those headers is used. |
| 1091 | func trustedRealClientIP(r *http.Request, headers []string, clientIP string) string { |
| 1092 | // Read all the values of the configured client IP headers, in order |
| 1093 | // nolint:prealloc |
| 1094 | var values []string |
| 1095 | for _, field := range headers { |
| 1096 | values = append(values, r.Header.Values(field)...) |
| 1097 | } |
| 1098 | |
| 1099 | // If we don't have any values, then give up |
| 1100 | if len(values) == 0 { |
| 1101 | return clientIP |
| 1102 | } |
| 1103 | |
| 1104 | // Since there can be many header values, we need to |
| 1105 | // join them together before splitting to get the full list |
| 1106 | allValues := strings.SplitSeq(strings.Join(values, ","), ",") |
| 1107 | |
| 1108 | // Get first valid left-most IP address |
| 1109 | for part := range allValues { |
| 1110 | // Some proxies may retain the port number, so split if possible |
| 1111 | host, _, err := net.SplitHostPort(part) |
| 1112 | if err != nil { |
| 1113 | host = part |
| 1114 | } |
| 1115 | |
| 1116 | // Remove any zone identifier from the IP address |
| 1117 | host, _, _ = strings.Cut(strings.TrimSpace(host), "%") |
| 1118 | |
| 1119 | // Parse the IP address |
| 1120 | ipAddr, err := netip.ParseAddr(host) |
| 1121 | if err != nil { |
| 1122 | continue |
| 1123 | } |
| 1124 | return ipAddr.String() |
| 1125 | } |
| 1126 | |
| 1127 | // We didn't find a valid IP |
| 1128 | return clientIP |
| 1129 | } |
| 1130 | |
| 1131 | // strictUntrustedClientIp iterates through the list of client IP headers, |
| 1132 | // parses them from right-to-left, and returns the first valid IP address |