I have a function that writes entries to a logfile, Code: protected void Logging(string item1, string item2, string item3) { StreamWriter sw = new StreamWriter(Server.MapPath("~\\logs\\RequestLog.txt"),true); sw.WriteLine(DateTime.UtcNow.ToLocalTime() + "\t" + item1 + "\t" + item2 + "\t" + item3); sw.Flush(); sw.Close(); } I do the IP address lookup like: Code: string ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (ipAddress == null) { ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } the logging function is called like this: Code: Logging(Request.QueryString["action"],Request.QueryString["userid"],ipAddress) No the weird part... some IP addresses are logged as 'unknown', others in a format like this 'xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx' comma separated. First, how come some entries are listed as 'unknown', every request should be made by a IP, isn't? Second, Why some entries contain 2 IP addresses, comma separated?
OK, i have found a explanation for the comma separated IP addresses listed, eg: http://en.wikipedia.org/wiki/X-Forwarded-For. Seems the last IP is the IP of the client connecting. I think modifying the code like this should work and always pick the last IP listed, am i right? Code: string ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (ipAddress == null) { ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } else { string[] elements = ipAddress.Split(','); foreach (string element in elements) { ipAddress = element.Trim(); } }
Or maybe better... Code: string ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (ipAddress != null) { if (ipAddress.IndexOf(',',0) != -1) { string[] elements = ipAddress.Split(','); foreach (string element in elements) { ipAddress = element.Trim(); } } } else { ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; }
I have little experience with ASP.NET, so I cant comment too much on the code, even though your last example looks good in my eyes. I have only one suggestion, add an additional check for the validity of the IP: Code: using System.Net; IPAddress ip = null; if (IPAddress.TryParse(ipAddress, out ip)) // Valid when == true IPAddress.TryParse() on MSDN