-
-
Save adeelnasir/3ee5ef9c259ae19562fc5b160df7e6d0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ResolverController : ApiController | |
{ | |
private const string ConnectionString = "DbConnectionString"; | |
private SqlConnection m_Connection; | |
[CORSApiFilter] | |
public JsonResult<Redirect> Get() | |
{ | |
//Get the client IP | |
var foundIP = ""; | |
var context = HttpContext.Current; | |
var ipAddress = context.Request.Headers["X-Forwarded-For"]; | |
if (!string.IsNullOrEmpty(ipAddress)) | |
{ | |
var addresses = ipAddress.Split(','); | |
if (addresses.Length != 0) | |
foundIP = addresses[0]; | |
} | |
else | |
foundIP = context.Request.ServerVariables["REMOTE_ADDR"]; | |
//Get the IP ranges from the DB | |
var foundRedirects = this.GetRedirects(); | |
Redirect matched = null; | |
var db = new DBHelper(); | |
foreach (var redirect in foundRedirects) | |
{ | |
if (IsInRange(foundIP, redirect.StartIp, redirect.EndIp)) | |
{ | |
matched = redirect; | |
break; | |
} | |
} | |
return Json(matched); | |
} | |
/// <summary> | |
/// Get redirects from the DB. | |
/// </summary> | |
private List<Redirect> GetRedirects() | |
{ | |
var connectionString = ConfigurationManager.ConnectionStrings[ConnectionString].ConnectionString; | |
m_Connection = new SqlConnection(connectionString); | |
var loadedRedirects = new List<Redirect>(); | |
using (var cmd = new SqlCommand("SELECT RegistrationId, StartIp, EndIp, RedirectName FROM dbo.Registration", this.m_Connection)) | |
{ | |
cmd.CommandType = CommandType.Text; | |
cmd.Connection.Open(); | |
var rdr = cmd.ExecuteReader(); | |
while (rdr.Read()) | |
{ | |
var newRedirect = new Redirect | |
{ | |
RegistrationId = Guid.Parse(rdr[0].ToString()), | |
StartIp = rdr[1].ToString(), | |
EndIp = rdr[2].ToString(), | |
RedirectName = rdr[3].ToString() | |
}; | |
loadedRedirects.Add(newRedirect); | |
} | |
rdr.Close(); | |
cmd.Connection.Close(); | |
} | |
loadedRedirects.Sort((x, y) => x.StartIp.CompareTo(y.StartIp)); | |
return loadedRedirects; | |
} | |
/// <summary> | |
/// Function returning true if in IP is within the specified ip range. | |
/// </summary> | |
/// <param name="ipAddress">The ip to check.</param> | |
/// <param name="fromAddress">Start IP of the range.</param> | |
/// <param name="toAddress">End IP of the range.</param> | |
/// <returns>true if ip is in range otherwise false.</returns> | |
private static bool IsInRange(string ipAddress, string fromAddress, string toAddress) | |
{ | |
var ip = IpAddressToLongBackwards(ipAddress); | |
return ip >= IpAddressToLongBackwards(fromAddress) && ip <= IpAddressToLongBackwards(toAddress); | |
} | |
// Convert IPAddress to long backwards for comparison. | |
private static long IpAddressToLongBackwards(string ipAddress) | |
{ | |
IPAddress ip; | |
if (!IPAddress.TryParse(ipAddress, out ip)) | |
throw new ArgumentException(string.Format("The value '{0}' could not be parsed as an IP address.", | |
ipAddress)); | |
var byteIp = ip.GetAddressBytes(); | |
var longIp = (long)byteIp[0] << 24; | |
longIp += (long)byteIp[1] << 16; | |
longIp += (long)byteIp[2] << 8; | |
longIp += byteIp[3]; | |
return longIp; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment