ToolsController.cs 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using AngleSharp;
  2. using DnsClient;
  3. using Masuit.Tools.Mime;
  4. using Masuit.Tools.Core.Validator;
  5. using Microsoft.Net.Http.Headers;
  6. using System.Net;
  7. using TimeZoneConverter;
  8. using Configuration = AngleSharp.Configuration;
  9. namespace Masuit.MyBlogs.Core.Controllers;
  10. /// <summary>
  11. /// 黑科技
  12. /// </summary>
  13. [Route("tools")]
  14. public sealed class ToolsController(IHttpClientFactory httpClientFactory) : BaseController
  15. {
  16. private readonly HttpClient _httpClient = httpClientFactory.CreateClient();
  17. /// <summary>
  18. /// 获取ip地址详细信息
  19. /// </summary>
  20. /// <param name="ip"></param>
  21. /// <returns></returns>
  22. [Route("ip"), Route("ip/{ip?}", Order = 1), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "ip" })]
  23. public async Task<ActionResult> GetIpInfo([IsIPAddress] string ip)
  24. {
  25. ViewBag.IP = ip;
  26. if (!IPAddress.TryParse(ip, out var ipAddress))
  27. {
  28. ipAddress = ClientIP;
  29. ViewBag.IP = ClientIP;
  30. }
  31. if (ipAddress.IsPrivateIP())
  32. {
  33. return Ok("内网IP");
  34. }
  35. var loc = ipAddress.GetIPLocation();
  36. var asn = ipAddress.GetIPAsn();
  37. var nslookup = new LookupClient();
  38. using var cts = new CancellationTokenSource(2000);
  39. var domain = await nslookup.QueryReverseAsync(ipAddress, cts.Token).ContinueWith(t => t.IsCompletedSuccessfully ? t.Result.Answers.Select(r => r.ToString()).Join("; ") : "无");
  40. var address = new IpInfo
  41. {
  42. Location = loc.Coodinate,
  43. Address = loc.Address,
  44. Address2 = loc.Address2,
  45. Network = new NetworkInfo
  46. {
  47. Asn = asn.AutonomousSystemNumber,
  48. Router = asn.Network + "",
  49. Organization = loc.ISP
  50. },
  51. Network2 = loc.Network2,
  52. TimeZone = loc.Coodinate.TimeZone + $" UTC{TZConvert.GetTimeZoneInfo(loc.Coodinate.TimeZone ?? "Asia/Shanghai").BaseUtcOffset.Hours:+#;-#;0}",
  53. IsProxy = loc.Network.Contains(["cloud", "Compute", "Serv", "Tech", "Solution", "Host", "云", "Datacenter", "Data Center", "Business", "ASN"]) || domain.Length > 1 || await IsProxy(ipAddress, cts.Token),
  54. Domain = domain
  55. };
  56. if (Request.Method.Equals(HttpMethods.Get) || (Request.Headers[HeaderNames.Accept] + "").StartsWith(ContentType.Json))
  57. {
  58. return View(address);
  59. }
  60. return Json(address);
  61. }
  62. /// <summary>
  63. /// 是否是代理ip
  64. /// </summary>
  65. /// <param name="ip"></param>
  66. /// <param name="cancellationToken"></param>
  67. /// <returns></returns>
  68. private async Task<bool> IsProxy(IPAddress ip, CancellationToken cancellationToken = default)
  69. {
  70. _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62");
  71. return await _httpClient.GetStringAsync("https://ipinfo.io/" + ip, cancellationToken).ContinueWith(t =>
  72. {
  73. if (t.IsCompletedSuccessfully)
  74. {
  75. var ctx = BrowsingContext.New(Configuration.Default);
  76. var doc = ctx.OpenAsync(res => res.Content(t.Result)).Result;
  77. var isAnycast = doc.DocumentElement.QuerySelectorAll(".title").Where(e => e.TextContent.Contains("Anycast")).Select(e => e.Parent).Any(n => n.TextContent.Contains("True"));
  78. var isproxy = doc.DocumentElement.QuerySelectorAll("#block-privacy img").Any(e => e.OuterHtml.Contains("right"));
  79. return isAnycast || isproxy;
  80. }
  81. return false;
  82. });
  83. }
  84. [HttpGet("loan")]
  85. public ActionResult Loan()
  86. {
  87. return View();
  88. }
  89. }