ToolsController.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using DnsClient;
  2. using Masuit.MyBlogs.Core.Common;
  3. using Masuit.MyBlogs.Core.Configs;
  4. using Masuit.Tools.AspNetCore.Mime;
  5. using Masuit.Tools.Core.Validator;
  6. using Masuit.Tools.Models;
  7. using MaxMind.GeoIP2.Exceptions;
  8. using MaxMind.GeoIP2.Responses;
  9. using Microsoft.AspNetCore.Mvc;
  10. using Microsoft.Net.Http.Headers;
  11. using Newtonsoft.Json;
  12. using Polly;
  13. using System.Net;
  14. using TimeZoneConverter;
  15. namespace Masuit.MyBlogs.Core.Controllers;
  16. /// <summary>
  17. /// 黑科技
  18. /// </summary>
  19. [Route("tools")]
  20. public sealed class ToolsController : BaseController
  21. {
  22. private readonly HttpClient _httpClient;
  23. public ToolsController(IHttpClientFactory httpClientFactory)
  24. {
  25. _httpClient = httpClientFactory.CreateClient();
  26. }
  27. /// <summary>
  28. /// 获取ip地址详细信息
  29. /// </summary>
  30. /// <param name="ip"></param>
  31. /// <returns></returns>
  32. [Route("ip"), Route("ip/{ip?}", Order = 1), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "ip" })]
  33. public async Task<ActionResult> GetIpInfo([IsIPAddress] string ip)
  34. {
  35. if (!IPAddress.TryParse(ip, out var ipAddress))
  36. {
  37. ipAddress = ClientIP;
  38. }
  39. if (ipAddress.IsPrivateIP())
  40. {
  41. return Ok("内网IP");
  42. }
  43. ViewBag.IP = ip;
  44. var loc = ipAddress.GetIPLocation();
  45. var asn = ipAddress.GetIPAsn();
  46. var nslookup = new LookupClient();
  47. using var cts = new CancellationTokenSource(2000);
  48. var domain = await nslookup.QueryReverseAsync(ipAddress, cts.Token).ContinueWith(t => t.IsCompletedSuccessfully ? t.Result.Answers.Select(r => r.ToString()).Join("; ") : "无");
  49. var address = new IpInfo
  50. {
  51. Location = loc.Coodinate,
  52. Address = loc.Address,
  53. Address2 = loc.Address2,
  54. Network = new NetworkInfo
  55. {
  56. Asn = asn.AutonomousSystemNumber,
  57. Router = asn.Network + "",
  58. Organization = loc.ISP
  59. },
  60. TimeZone = loc.Coodinate.TimeZone + $" UTC{TZConvert.GetTimeZoneInfo(loc.Coodinate.TimeZone ?? "Asia/Shanghai").BaseUtcOffset.Hours:+#;-#;0}",
  61. IsProxy = loc.Network.Contains(new[] { "cloud", "Compute", "Serv", "Tech", "Solution", "Host", "云", "Datacenter", "Data Center", "Business", "ASN" }) || domain.Length > 1 || await ipAddress.IsProxy(cts.Token),
  62. Domain = domain
  63. };
  64. if (Request.Method.Equals(HttpMethods.Get) || (Request.Headers[HeaderNames.Accept] + "").StartsWith(ContentType.Json))
  65. {
  66. return View(address);
  67. }
  68. return Json(address);
  69. }
  70. /// <summary>
  71. /// 根据经纬度获取详细地理信息
  72. /// </summary>
  73. /// <param name="lat"></param>
  74. /// <param name="lng"></param>
  75. /// <returns></returns>
  76. [HttpGet("pos"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "lat", "lng" })]
  77. public async Task<ActionResult> Position(string lat, string lng)
  78. {
  79. if (string.IsNullOrEmpty(lat) || string.IsNullOrEmpty(lng))
  80. {
  81. var ip = ClientIP;
  82. #if DEBUG
  83. var r = new Random();
  84. ip = IPAddress.Parse($"{r.Next(210)}.{r.Next(255)}.{r.Next(255)}.{r.Next(255)}");
  85. #endif
  86. var location = Policy<CityResponse>.Handle<AddressNotFoundException>().Fallback(() => new CityResponse()).Execute(() => CommonHelper.MaxmindReader.City(ip));
  87. var address = new PhysicsAddress()
  88. {
  89. Status = 0,
  90. AddressResult = new AddressResult()
  91. {
  92. FormattedAddress = ip.GetIPLocation().Address,
  93. Location = new Location()
  94. {
  95. Lng = (decimal)location.Location.Longitude.GetValueOrDefault(),
  96. Lat = (decimal)location.Location.Latitude.GetValueOrDefault()
  97. }
  98. }
  99. };
  100. return View(address);
  101. }
  102. using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
  103. var s = await _httpClient.GetStringAsync($"http://api.map.baidu.com/geocoder/v2/?location={lat},{lng}&output=json&pois=1&ak={AppConfig.BaiduAK}", cts.Token).ContinueWith(t =>
  104. {
  105. if (t.IsCompletedSuccessfully)
  106. {
  107. return JsonConvert.DeserializeObject<PhysicsAddress>(t.Result);
  108. }
  109. return new PhysicsAddress();
  110. });
  111. return View(s);
  112. }
  113. /// <summary>
  114. /// 详细地理信息转经纬度
  115. /// </summary>
  116. /// <param name="addr"></param>
  117. /// <returns></returns>
  118. [Route("addr"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "addr" })]
  119. public async Task<ActionResult> Address(string addr)
  120. {
  121. if (string.IsNullOrEmpty(addr))
  122. {
  123. var ip = ClientIP;
  124. #if DEBUG
  125. Random r = new Random();
  126. ip = IPAddress.Parse($"{r.Next(210)}.{r.Next(255)}.{r.Next(255)}.{r.Next(255)}");
  127. #endif
  128. var location = Policy<CityResponse>.Handle<AddressNotFoundException>().Fallback(() => new CityResponse()).Execute(() => CommonHelper.MaxmindReader.City(ip));
  129. var address = new PhysicsAddress()
  130. {
  131. Status = 0,
  132. AddressResult = new AddressResult
  133. {
  134. FormattedAddress = ip.GetIPLocation().Address,
  135. Location = new Location
  136. {
  137. Lng = (decimal)location.Location.Longitude.GetValueOrDefault(),
  138. Lat = (decimal)location.Location.Latitude.GetValueOrDefault()
  139. }
  140. }
  141. };
  142. ViewBag.Address = address.AddressResult.FormattedAddress;
  143. if (Request.Method.Equals(HttpMethods.Get) || (Request.Headers[HeaderNames.Accept] + "").StartsWith(ContentType.Json))
  144. {
  145. return View(address.AddressResult.Location);
  146. }
  147. return Json(address.AddressResult.Location);
  148. }
  149. ViewBag.Address = addr;
  150. using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
  151. var physicsAddress = await _httpClient.GetStringAsync($"http://api.map.baidu.com/geocoder/v2/?output=json&address={addr}&ak={AppConfig.BaiduAK}", cts.Token).ContinueWith(t =>
  152. {
  153. if (t.IsCompletedSuccessfully)
  154. {
  155. return JsonConvert.DeserializeObject<PhysicsAddress>(t.Result);
  156. }
  157. return new PhysicsAddress();
  158. });
  159. if (Request.Method.Equals(HttpMethods.Get) || (Request.Headers[HeaderNames.Accept] + "").StartsWith(ContentType.Json))
  160. {
  161. return View(physicsAddress?.AddressResult?.Location);
  162. }
  163. return Json(physicsAddress?.AddressResult?.Location);
  164. }
  165. }