Posted on 28/01/2025 21:20:08
Hi Nicolai,
At least we figured why IP v6 are getting logged badly (it's coming up more and more)
public static string GetClientIpAddress()
{
try
{
string userHostAddress = Context.Current.Request.UserHostAddress;
// Could use TryParse instead, but I wanted to catch all exceptions
IPAddress.Parse(userHostAddress);
string forwardIp = Context.Current.Request?.Headers?["X-FORWARDED-FOR"];
if (string.IsNullOrEmpty(forwardIp))
{
forwardIp = Context.Current.Request?.Headers?["X-CLIENT-IP"];
}
if (string.IsNullOrEmpty(forwardIp))
{
return userHostAddress;
}
// Get a list of public ip addresses in the X-FORWARDED-FOR and X-CLIENT-IP headers
var publicForwardingIps = new List<string>();
var array = forwardIp.Split(',');
for (int i = 0, loopTo = array.Length - 1; i <= loopTo; i++)
{
string ipString = array[i];
if (ipString.Contains(":"))
{
ipString = ipString.Split(':')[0];
}
if (!IsPrivateIpAddress(ipString) && !publicForwardingIps.Contains(ipString))
{
publicForwardingIps.Add(ipString);
}
}
// If we found any, return the last one, otherwise return the user host address
return publicForwardingIps.Any() ? publicForwardingIps.First() : userHostAddress;
}
catch
{
return null;
}
}
If this could be changed, would at least help support them in future versions.
I found a few way to go about it. Here's a suggestion without a lot of refactoring
public static string GetClientIpAddress()
{
try
{
string userHostAddress = Context.Current.Request.UserHostAddress;
// Could use TryParse instead, but I wanted to catch all exceptions
IPAddress.Parse(userHostAddress);
string forwardIp = Context.Current.Request?.Headers?["X-FORWARDED-FOR"];
if (string.IsNullOrEmpty(forwardIp))
{
forwardIp = Context.Current.Request?.Headers?["X-CLIENT-IP"];
}
if (string.IsNullOrEmpty(forwardIp))
{
return userHostAddress;
}
// Get a list of public ip addresses in the X-FORWARDED-FOR and X-CLIENT-IP headers
var publicForwardingIps = new List<string>();
var array = forwardIp.Split(',');
for (int i = 0, loopTo = array.Length - 1; i <= loopTo; i++)
{
IPAddress address;
if (IPAddress.TryParse(array[i], out address))
{
string ipString = array[i];
if (ipString.Contains(":") && address == System.Net.Sockets.AddressFamily.InterNetwork)
{
ipString = ipString.Split(':')[0];
}
if (!IsPrivateIpAddress(ipString) && !publicForwardingIps.Contains(ipString))
{
publicForwardingIps.Add(ipString);
}
}
}
// If we found any, return the last one, otherwise return the user host address
return publicForwardingIps.Any() ? publicForwardingIps.First() : userHostAddress;
}
catch
{
return null;
}
}
Best Regards,
Nuno Aguiar