refactor!: rename the project from Monitor to MoShiro [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful
ci/woodpecker/push/main-amd64-build Pipeline was successful
Namespaces, assemblies, solution, binaries, images, systemd units, config paths, environment variables, protocol methods and the Linux user are all renamed. Breaking: existing databases, node identities and installed units must be recreated.
This commit is contained in:
1 parent
27ac7fb787
commit
2e146d4da7
309 files changed
+1565
-1572
No files matched your search
@@ -0,0 +1,73 @@
|
||||
using System.Text.Json;
|
||||
using MoShiro.Backend.Application;
|
||||
|
||||
namespace MoShiro.Backend;
|
||||
|
||||
/// <summary>
|
||||
/// 用 IP 归属查询服务(<c>GET {地址}/lookup?ip=…</c>)查国家和运营商。
|
||||
/// 失败(超时、网络不通、服务返回错误)一律返回 null,不往外抛:展示信息没有也不影响别的功能。
|
||||
/// </summary>
|
||||
public sealed class HttpGeoLookup : IGeoLookup, IDisposable
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
|
||||
public HttpGeoLookup(string baseUrl)
|
||||
{
|
||||
_http = new HttpClient { BaseAddress = new Uri(baseUrl.TrimEnd('/') + "/"), Timeout = TimeSpan.FromSeconds(6) };
|
||||
_http.DefaultRequestHeaders.UserAgent.ParseAdd("MoShiro");
|
||||
}
|
||||
|
||||
public async ValueTask<GeoInfo?> LookupAsync(string host, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
using HttpResponseMessage response = await _http.GetAsync("lookup?ip=" + Uri.EscapeDataString(host), ct);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using JsonDocument doc = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync(ct), cancellationToken: ct);
|
||||
return Parse(doc.RootElement);
|
||||
}
|
||||
catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException or JsonException or InvalidOperationException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>只取国家代码、ASN、组织名;其余字段(城市、经纬度、网段……)一概不读。</summary>
|
||||
public static GeoInfo? Parse(JsonElement root)
|
||||
{
|
||||
if (root.TryGetProperty("found", out JsonElement found) && found.ValueKind == JsonValueKind.False)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
bool isPrivate = root.TryGetProperty("is_private", out JsonElement priv) && priv.ValueKind == JsonValueKind.True;
|
||||
string? country = root.TryGetProperty("country_region", out JsonElement region) && region.TryGetProperty("iso_code", out JsonElement code) && code.ValueKind == JsonValueKind.String ? code.GetString() : null;
|
||||
int? asn = null;
|
||||
string? organization = null;
|
||||
if (root.TryGetProperty("network", out JsonElement network))
|
||||
{
|
||||
if (network.TryGetProperty("asn", out JsonElement asnValue) && asnValue.TryGetInt32(out int number))
|
||||
{
|
||||
asn = number;
|
||||
}
|
||||
|
||||
string? isp = network.TryGetProperty("isp", out JsonElement ispValue) && ispValue.ValueKind == JsonValueKind.String ? ispValue.GetString() : null;
|
||||
string? org = network.TryGetProperty("organization", out JsonElement orgValue) && orgValue.ValueKind == JsonValueKind.String ? orgValue.GetString() : null;
|
||||
organization = string.IsNullOrWhiteSpace(isp) ? org : isp;
|
||||
}
|
||||
|
||||
return new GeoInfo(country, asn, organization, isPrivate);
|
||||
}
|
||||
|
||||
public void Dispose() => _http.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>不查(<c>MoShiro__GeoLookupUrl</c> 留空)。</summary>
|
||||
public sealed class NoGeoLookup : IGeoLookup
|
||||
{
|
||||
public ValueTask<GeoInfo?> LookupAsync(string host, CancellationToken ct) => ValueTask.FromResult<GeoInfo?>(null);
|
||||
}
|
||||
Reference in new issue
Block a user