RemoteAddr tries to parse and return the real client's request IP. Based on allowed headers names that can be modified from Configuration.RemoteAddrHeaders. If parse based on these headers fail then it will return the Request's `RemoteAddr` field which is filled by the server before the HTTP handl
()
| 1120 | // Configuration.WithoutRemoteAddrHeader(...) and |
| 1121 | // Configuration.RemoteAddrPrivateSubnetsW for more. |
| 1122 | func (ctx *Context) RemoteAddr() string { |
| 1123 | if remoteHeaders := ctx.app.ConfigurationReadOnly().GetRemoteAddrHeaders(); len(remoteHeaders) > 0 { |
| 1124 | privateSubnets := ctx.app.ConfigurationReadOnly().GetRemoteAddrPrivateSubnets() |
| 1125 | |
| 1126 | for _, headerName := range remoteHeaders { |
| 1127 | ipAddresses := strings.Split(ctx.GetHeader(headerName), ",") |
| 1128 | if ip, ok := netutil.GetIPAddress(ipAddresses, privateSubnets); ok { |
| 1129 | return ip |
| 1130 | } |
| 1131 | } |
| 1132 | |
| 1133 | if ctx.app.ConfigurationReadOnly().GetRemoteAddrHeadersForce() { |
| 1134 | for _, headerName := range remoteHeaders { |
| 1135 | // return the first valid IP, |
| 1136 | // even if it's a part of a private network. |
| 1137 | ipAddresses := strings.Split(ctx.GetHeader(headerName), ",") |
| 1138 | for _, addr := range ipAddresses { |
| 1139 | if ip, _, err := net.SplitHostPort(addr); err == nil { |
| 1140 | return ip |
| 1141 | } |
| 1142 | } |
| 1143 | } |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 | addr := strings.TrimSpace(ctx.request.RemoteAddr) |
| 1148 | if addr != "" { |
| 1149 | // if addr has port use the net.SplitHostPort otherwise(error occurs) take as it is |
| 1150 | if ip, _, err := net.SplitHostPort(addr); err == nil { |
| 1151 | return ip |
| 1152 | } |
| 1153 | } |
| 1154 | |
| 1155 | return addr |
| 1156 | } |
| 1157 | |
| 1158 | // TrimHeaderValue returns the "v[0:first space or semicolon]". |
| 1159 | func TrimHeaderValue(v string) string { |
no test coverage detected