diff --git a/LibMatrix/Services/HomeserverResolverService.cs b/LibMatrix/Services/HomeserverResolverService.cs
index fa75f1e..01b11cc 100644
--- a/LibMatrix/Services/HomeserverResolverService.cs
+++ b/LibMatrix/Services/HomeserverResolverService.cs
@@ -49,6 +49,7 @@ public class HomeserverResolverService {
ArgumentNullException.ThrowIfNull(homeserver);
_logger.LogTrace("Resolving client well-known: {homeserver}", homeserver);
ClientWellKnown? clientWellKnown = null;
+ homeserver = homeserver.TrimEnd('/');
// check if homeserver has a client well-known
if (homeserver.StartsWith("https://")) {
clientWellKnown = await _httpClient.TryGetFromJsonAsync<ClientWellKnown>($"{homeserver}/.well-known/matrix/client");
@@ -80,6 +81,7 @@ public class HomeserverResolverService {
ArgumentNullException.ThrowIfNull(homeserver);
_logger.LogTrace($"Resolving server well-known: {homeserver}");
ServerWellKnown? serverWellKnown = null;
+ homeserver = homeserver.TrimEnd('/');
// check if homeserver has a server well-known
if (homeserver.StartsWith("https://")) {
serverWellKnown = await _httpClient.TryGetFromJsonAsync<ServerWellKnown>($"{homeserver}/.well-known/matrix/server");
@@ -95,7 +97,7 @@ public class HomeserverResolverService {
_logger.LogInformation("Server well-known for {hs}: {json}", homeserver, serverWellKnown?.ToJson() ?? "null");
if (!string.IsNullOrWhiteSpace(serverWellKnown?.Homeserver)) {
- var resolved = serverWellKnown.Homeserver;
+ var resolved = serverWellKnown.Homeserver.TrimEnd('/');
if (resolved.StartsWith("https://") || resolved.StartsWith("http://"))
return resolved;
if (await _httpClient.CheckSuccessStatus($"https://{resolved}/_matrix/federation/v1/version"))
@@ -106,7 +108,7 @@ public class HomeserverResolverService {
}
// fallback: most servers host C2S and S2S on the same domain
- var clientUrl = await _tryResolveClientEndpoint(homeserver);
+ var clientUrl = (await _tryResolveClientEndpoint(homeserver)).TrimEnd('/');
if (clientUrl is not null && await _httpClient.CheckSuccessStatus($"{clientUrl}/_matrix/federation/v1/version"))
return clientUrl;
diff --git a/LibMatrix/Services/ServiceInstaller.cs b/LibMatrix/Services/ServiceInstaller.cs
index ecc3f09..5ffd43a 100644
--- a/LibMatrix/Services/ServiceInstaller.cs
+++ b/LibMatrix/Services/ServiceInstaller.cs
@@ -1,4 +1,5 @@
-using LibMatrix.Services.WellKnownResolvers;
+using LibMatrix.Services.WellKnownResolver;
+using LibMatrix.Services.WellKnownResolver.WellKnownResolvers;
using Microsoft.Extensions.DependencyInjection;
namespace LibMatrix.Services;
@@ -10,6 +11,10 @@ public static class ServiceInstaller {
//Add services
services.AddSingleton<ClientWellKnownResolver>();
+ services.AddSingleton<ServerWellKnownResolver>();
+ services.AddSingleton<SupportWellKnownResolver>();
+ if (!services.Any(x => x.ServiceType == typeof(WellKnownResolverConfiguration)))
+ services.AddSingleton<WellKnownResolverConfiguration>();
services.AddSingleton<WellKnownResolverService>();
// Legacy
services.AddSingleton<HomeserverResolverService>();
diff --git a/LibMatrix/Services/WellKnownResolver/WellKnownResolverConfiguration.cs b/LibMatrix/Services/WellKnownResolver/WellKnownResolverConfiguration.cs
new file mode 100644
index 0000000..26a4c43
--- /dev/null
+++ b/LibMatrix/Services/WellKnownResolver/WellKnownResolverConfiguration.cs
@@ -0,0 +1,49 @@
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.Services.WellKnownResolver;
+
+public class WellKnownResolverConfiguration {
+ /// <summary>
+ /// Allow transparent downgrades to plaintext HTTP if HTTPS fails
+ /// Enabling this is unsafe!
+ /// </summary>
+ [JsonPropertyName("allow_http")]
+ public bool AllowHttp { get; set; } = false;
+
+ /// <summary>
+ /// Use DNS resolution if available, for resolving SRV records
+ /// </summary>
+ [JsonPropertyName("allow_dns")]
+ public bool AllowDns { get; set; } = true;
+
+ /// <summary>
+ /// Use system resolver(s) if empty
+ /// </summary>
+ [JsonPropertyName("dns_servers")]
+ public List<string> DnsServers { get; set; } = new();
+
+ /// <summary>
+ /// Same as AllowDns, but for DNS over HTTPS - useful in browser contexts
+ /// </summary>
+ [JsonPropertyName("allow_doh")]
+ public bool AllowDoh { get; set; } = true;
+
+ /// <summary>
+ /// Use DNS over HTTPS - useful in browser contexts
+ /// Disabled if empty
+ /// </summary>
+ [JsonPropertyName("doh_servers")]
+ public List<string> DohServers { get; set; } = new();
+
+ /// <summary>
+ /// Whether to allow fallback subdomain lookups
+ /// </summary>
+ [JsonPropertyName("allow_fallback_subdomains")]
+ public bool AllowFallbackSubdomains { get; set; } = true;
+
+ /// <summary>
+ /// Fallback subdomains to try if the homeserver is not found
+ /// </summary>
+ [JsonPropertyName("fallback_subdomains")]
+ public List<string> FallbackSubdomains { get; set; } = ["matrix", "chat", "im"];
+}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolver/WellKnownResolverService.cs b/LibMatrix/Services/WellKnownResolver/WellKnownResolverService.cs
new file mode 100644
index 0000000..4c78347
--- /dev/null
+++ b/LibMatrix/Services/WellKnownResolver/WellKnownResolverService.cs
@@ -0,0 +1,91 @@
+using System.Diagnostics;
+using System.Text.Json.Serialization;
+using LibMatrix.Extensions;
+using LibMatrix.Services.WellKnownResolver.WellKnownResolvers;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+
+namespace LibMatrix.Services.WellKnownResolver;
+
+public class WellKnownResolverService {
+ private readonly MatrixHttpClient _httpClient = new();
+
+ private readonly ILogger<WellKnownResolverService> _logger;
+ private readonly ClientWellKnownResolver _clientWellKnownResolver;
+ private readonly SupportWellKnownResolver _supportWellKnownResolver;
+ private readonly ServerWellKnownResolver _serverWellKnownResolver;
+ private readonly WellKnownResolverConfiguration _configuration;
+
+ public WellKnownResolverService(ILogger<WellKnownResolverService> logger, ClientWellKnownResolver clientWellKnownResolver, SupportWellKnownResolver supportWellKnownResolver,
+ WellKnownResolverConfiguration configuration, ServerWellKnownResolver serverWellKnownResolver) {
+ _logger = logger;
+ _clientWellKnownResolver = clientWellKnownResolver;
+ _supportWellKnownResolver = supportWellKnownResolver;
+ _configuration = configuration;
+ _serverWellKnownResolver = serverWellKnownResolver;
+ if (logger is NullLogger<WellKnownResolverService>) {
+ var stackFrame = new StackTrace(true).GetFrame(1);
+ Console.WriteLine(
+ $"WARN | Null logger provided to WellKnownResolverService!\n{stackFrame?.GetMethod()?.DeclaringType?.ToString() ?? "null"} at {stackFrame?.GetFileName() ?? "null"}:{stackFrame?.GetFileLineNumber().ToString() ?? "null"}");
+ }
+ }
+
+ public async Task<WellKnownRecords> TryResolveWellKnownRecords(string homeserver, bool includeClient = true, bool includeServer = true, bool includeSupport = true,
+ WellKnownResolverConfiguration? config = null) {
+ WellKnownRecords records = new();
+ _logger.LogDebug($"Resolving well-knowns for {homeserver}");
+ if (includeClient && await _clientWellKnownResolver.TryResolveWellKnown(homeserver, config ?? _configuration) is { } clientResult) {
+ records.ClientWellKnown = clientResult;
+ }
+
+ if (includeServer && await _serverWellKnownResolver.TryResolveWellKnown(homeserver, config ?? _configuration) is { } serverResult) {
+ records.ServerWellKnown = serverResult;
+ }
+
+ if (includeSupport && await _supportWellKnownResolver.TryResolveWellKnown(homeserver, config ?? _configuration) is { } supportResult) {
+ records.SupportWellKnown = supportResult;
+ }
+
+ return records;
+ }
+
+ public class WellKnownRecords {
+ public WellKnownResolutionResult<ClientWellKnown?>? ClientWellKnown { get; set; }
+ public WellKnownResolutionResult<ServerWellKnown?>? ServerWellKnown { get; set; }
+ public WellKnownResolutionResult<SupportWellKnown?>? SupportWellKnown { get; set; }
+ }
+
+ public class WellKnownResolutionResult<T> {
+ public WellKnownSource Source { get; set; }
+ public string? SourceUri { get; set; }
+ public T? Content { get; set; }
+ public List<WellKnownResolutionWarning> Warnings { get; set; } = [];
+ }
+
+ [JsonConverter(typeof(JsonStringEnumConverter))]
+ public enum WellKnownSource {
+ None,
+ Https,
+ Dns,
+ Http,
+ ManualCheck,
+ Search
+ }
+
+ public struct WellKnownResolutionWarning {
+ public WellKnownResolutionWarningType Type { get; set; }
+ public string Message { get; set; }
+ [JsonIgnore]
+ public Exception? Exception { get; set; }
+ public string? ExceptionMessage => Exception?.Message;
+
+ [JsonConverter(typeof(JsonStringEnumConverter))]
+ public enum WellKnownResolutionWarningType {
+ None,
+ Exception,
+ InvalidResponse,
+ Timeout,
+ SlowResponse
+ }
+ }
+}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/BaseWellKnownResolver.cs b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/BaseWellKnownResolver.cs
new file mode 100644
index 0000000..cbe5b0a
--- /dev/null
+++ b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/BaseWellKnownResolver.cs
@@ -0,0 +1,52 @@
+using System.Diagnostics;
+using System.Net.Http.Json;
+using ArcaneLibs.Collections;
+using LibMatrix.Extensions;
+
+namespace LibMatrix.Services.WellKnownResolver.WellKnownResolvers;
+
+public class BaseWellKnownResolver<T> where T : class, new() {
+ internal static readonly SemaphoreCache<WellKnownResolverService.WellKnownResolutionResult<T>> WellKnownCache = new() {
+ StoreNulls = false
+ };
+
+ internal static readonly MatrixHttpClient HttpClient = new();
+
+ internal async Task<WellKnownResolverService.WellKnownResolutionResult<T>> TryGetWellKnownFromUrl(string url,
+ WellKnownResolverService.WellKnownSource source) {
+ var sw = Stopwatch.StartNew();
+ try {
+ var request = await HttpClient.GetAsync(url);
+ sw.Stop();
+ var result = new WellKnownResolverService.WellKnownResolutionResult<T> {
+ Content = await request.Content.ReadFromJsonAsync<T>(),
+ Source = source,
+ SourceUri = url,
+ Warnings = []
+ };
+
+ if (sw.ElapsedMilliseconds > 1000) {
+ // logger.LogWarning($"Support well-known resolution took {sw.ElapsedMilliseconds}ms: {url}");
+ result.Warnings.Add(new() {
+ Type = WellKnownResolverService.WellKnownResolutionWarning.WellKnownResolutionWarningType.SlowResponse,
+ Message = $"Well-known resolution took {sw.ElapsedMilliseconds}ms"
+ });
+ }
+
+ return result;
+ }
+ catch (Exception e) {
+ return new WellKnownResolverService.WellKnownResolutionResult<T> {
+ Source = source,
+ SourceUri = url,
+ Warnings = [
+ new() {
+ Exception = e,
+ Type = WellKnownResolverService.WellKnownResolutionWarning.WellKnownResolutionWarningType.Exception,
+ Message = e.Message
+ }
+ ]
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/ClientWellKnownResolver.cs b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/ClientWellKnownResolver.cs
new file mode 100644
index 0000000..f8de38d
--- /dev/null
+++ b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/ClientWellKnownResolver.cs
@@ -0,0 +1,42 @@
+using System.Text.Json.Serialization;
+using ArcaneLibs.Collections;
+using LibMatrix.Extensions;
+using Microsoft.Extensions.Logging;
+using WellKnownType = LibMatrix.Services.WellKnownResolver.WellKnownResolvers.ClientWellKnown;
+using ResultType =
+ LibMatrix.Services.WellKnownResolver.WellKnownResolverService.WellKnownResolutionResult<LibMatrix.Services.WellKnownResolver.WellKnownResolvers.ClientWellKnown?>;
+
+namespace LibMatrix.Services.WellKnownResolver.WellKnownResolvers;
+
+public class ClientWellKnownResolver(ILogger<ClientWellKnownResolver> logger, WellKnownResolverConfiguration configuration)
+ : BaseWellKnownResolver<ClientWellKnown> {
+ private static readonly SemaphoreCache<WellKnownResolverService.WellKnownResolutionResult<ClientWellKnown>> ClientWellKnownCache = new() {
+ StoreNulls = false
+ };
+
+ private static readonly MatrixHttpClient HttpClient = new();
+
+ public Task<WellKnownResolverService.WellKnownResolutionResult<ClientWellKnown>> TryResolveWellKnown(string homeserver, WellKnownResolverConfiguration? config = null) {
+ config ??= configuration;
+ return ClientWellKnownCache.TryGetOrAdd(homeserver, async () => {
+ logger.LogTrace($"Resolving client well-known: {homeserver}");
+
+ WellKnownResolverService.WellKnownResolutionResult<ClientWellKnown> result =
+ await TryGetWellKnownFromUrl($"https://{homeserver}/.well-known/matrix/client", WellKnownResolverService.WellKnownSource.Https);
+ if (result.Content != null) return result;
+
+
+ return result;
+ });
+ }
+}
+
+public class ClientWellKnown {
+ [JsonPropertyName("m.homeserver")]
+ public WellKnownHomeserver Homeserver { get; set; }
+
+ public class WellKnownHomeserver {
+ [JsonPropertyName("base_url")]
+ public required string BaseUrl { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/ServerWellKnownResolver.cs b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/ServerWellKnownResolver.cs
new file mode 100644
index 0000000..a99185c
--- /dev/null
+++ b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/ServerWellKnownResolver.cs
@@ -0,0 +1,38 @@
+using System.Text.Json.Serialization;
+using ArcaneLibs.Collections;
+using LibMatrix.Extensions;
+using Microsoft.Extensions.Logging;
+using WellKnownType = LibMatrix.Services.WellKnownResolver.WellKnownResolvers.ServerWellKnown;
+using ResultType =
+ LibMatrix.Services.WellKnownResolver.WellKnownResolverService.WellKnownResolutionResult<LibMatrix.Services.WellKnownResolver.WellKnownResolvers.ServerWellKnown?>;
+
+namespace LibMatrix.Services.WellKnownResolver.WellKnownResolvers;
+
+public class ServerWellKnownResolver(ILogger<ServerWellKnownResolver> logger, WellKnownResolverConfiguration configuration)
+ : BaseWellKnownResolver<ServerWellKnown> {
+ private static readonly SemaphoreCache<WellKnownResolverService.WellKnownResolutionResult<ServerWellKnown>> ClientWellKnownCache = new() {
+ StoreNulls = false
+ };
+
+ private static readonly MatrixHttpClient HttpClient = new();
+
+ public Task<WellKnownResolverService.WellKnownResolutionResult<ServerWellKnown>> TryResolveWellKnown(string homeserver, WellKnownResolverConfiguration? config = null) {
+ config ??= configuration;
+ return ClientWellKnownCache.TryGetOrAdd(homeserver, async () => {
+ logger.LogTrace($"Resolving client well-known: {homeserver}");
+
+ WellKnownResolverService.WellKnownResolutionResult<ServerWellKnown> result =
+ await TryGetWellKnownFromUrl($"https://{homeserver}/.well-known/matrix/server", WellKnownResolverService.WellKnownSource.Https);
+ if (result.Content != null) return result;
+
+
+ return result;
+ });
+ }
+}
+
+
+public class ServerWellKnown {
+ [JsonPropertyName("m.server")]
+ public string Homeserver { get; set; }
+}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/SupportWellKnownResolver.cs b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/SupportWellKnownResolver.cs
new file mode 100644
index 0000000..99313db
--- /dev/null
+++ b/LibMatrix/Services/WellKnownResolver/WellKnownResolvers/SupportWellKnownResolver.cs
@@ -0,0 +1,44 @@
+using System.Diagnostics;
+using System.Net.Http.Json;
+using System.Text.Json.Serialization;
+using Microsoft.Extensions.Logging;
+using WellKnownType = LibMatrix.Services.WellKnownResolver.WellKnownResolvers.SupportWellKnown;
+using ResultType = LibMatrix.Services.WellKnownResolver.WellKnownResolverService.WellKnownResolutionResult<
+ LibMatrix.Services.WellKnownResolver.WellKnownResolvers.SupportWellKnown?
+>;
+
+namespace LibMatrix.Services.WellKnownResolver.WellKnownResolvers;
+
+public class SupportWellKnownResolver(ILogger<SupportWellKnownResolver> logger, WellKnownResolverConfiguration configuration) : BaseWellKnownResolver<WellKnownType> {
+ public Task<ResultType> TryResolveWellKnown(string homeserver, WellKnownResolverConfiguration? config = null) {
+ config ??= configuration;
+ return WellKnownCache.TryGetOrAdd(homeserver, async () => {
+ logger.LogTrace($"Resolving support well-known: {homeserver}");
+
+ ResultType result = await TryGetWellKnownFromUrl($"https://{homeserver}/.well-known/matrix/support", WellKnownResolverService.WellKnownSource.Https);
+ if (result.Content != null)
+ return result;
+
+ return null;
+ });
+ }
+}
+
+public class SupportWellKnown {
+ [JsonPropertyName("contacts")]
+ public List<WellKnownContact>? Contacts { get; set; }
+
+ [JsonPropertyName("support_page")]
+ public Uri? SupportPage { get; set; }
+
+ public class WellKnownContact {
+ [JsonPropertyName("email_address")]
+ public string? EmailAddress { get; set; }
+
+ [JsonPropertyName("matrix_id")]
+ public string? MatrixId { get; set; }
+
+ [JsonPropertyName("role")]
+ public required string Role { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolverService.cs b/LibMatrix/Services/WellKnownResolverService.cs
deleted file mode 100644
index ab2660f..0000000
--- a/LibMatrix/Services/WellKnownResolverService.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System.Diagnostics;
-using System.Text.Json.Serialization;
-using ArcaneLibs.Collections;
-using ArcaneLibs.Extensions;
-using LibMatrix.Extensions;
-using LibMatrix.Services.WellKnownResolvers;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-
-namespace LibMatrix.Services;
-
-public class WellKnownResolverService {
- private readonly MatrixHttpClient _httpClient = new();
-
- private readonly ILogger<WellKnownResolverService> _logger;
-
- public WellKnownResolverService(ILogger<WellKnownResolverService> logger) {
- _logger = logger;
- if (logger is NullLogger<WellKnownResolverService>) {
- var stackFrame = new StackTrace(true).GetFrame(1);
- Console.WriteLine(
- $"WARN | Null logger provided to WellKnownResolverService!\n{stackFrame?.GetMethod()?.DeclaringType?.ToString() ?? "null"} at {stackFrame?.GetFileName() ?? "null"}:{stackFrame?.GetFileLineNumber().ToString() ?? "null"}");
- }
- }
-
- public async Task<WellKnownRecords> TryResolveWellKnownRecords(string homeserver) {
- WellKnownRecords records = new();
- _logger.LogDebug($"Resolving well-knowns for {homeserver}");
-
- return records;
- }
-
-
-
- public class ServerWellKnown {
- [JsonPropertyName("m.server")]
- public required string Homeserver { get; set; }
- }
-
- public class WellKnownRecords {
- public ClientWellKnownResolver.ClientWellKnown? ClientWellKnown { get; set; }
- public ServerWellKnown? ServerWellKnown { get; set; }
- public SupportWellKnownResolver.SupportWellKnown? SupportWellKnown { get; set; }
-
- /// <summary>
- /// Reports the source of the client well-known data.
- /// </summary>
- public WellKnownSource? ClientWellKnownSource { get; set; }
-
- /// <summary>
- /// Reports the source of the server well-known data.
- /// </summary>
- public WellKnownSource? ServerWellKnownSource { get; set; }
-
- /// <summary>
- /// Reports the source of the support well-known data.
- /// </summary>
- public WellKnownSource? SupportWellKnownSource { get; set; }
- }
-
- public struct WellKnownResolutionResult<T> {
- public WellKnownResolverService.WellKnownSource Source { get; set; }
- public T WellKnown { get; set; }
- public List<WellKnownResolverService.WellKnownResolutionWarning> Warnings { get; set; }
- }
-
- public enum WellKnownSource {
- None,
- Https,
- Dns,
- Http,
- ManualCheck,
- Search
- }
-
- public struct WellKnownResolutionWarning {
- public WellKnownResolutionWarningType Type { get; set; }
- public string Message { get; set; }
- public Exception? Exception { get; set; }
-
- public enum WellKnownResolutionWarningType {
- None,
- Exception,
- InvalidResponse,
- Timeout
- }
- }
-}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolvers/ClientWellKnownResolver.cs b/LibMatrix/Services/WellKnownResolvers/ClientWellKnownResolver.cs
deleted file mode 100644
index d4d0166..0000000
--- a/LibMatrix/Services/WellKnownResolvers/ClientWellKnownResolver.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System.Text.Json.Serialization;
-using ArcaneLibs.Collections;
-using LibMatrix.Extensions;
-using Microsoft.Extensions.Logging;
-
-namespace LibMatrix.Services.WellKnownResolvers;
-
-public class ClientWellKnownResolver(ILogger<ClientWellKnownResolver> logger) {
- private static readonly SemaphoreCache<WellKnownResolutionResult> ClientWellKnownCache = new() {
- StoreNulls = false
- };
- private static readonly MatrixHttpClient HttpClient = new();
-
- public Task<WellKnownResolutionResult> TryResolveClientWellKnown(string homeserver) {
- return ClientWellKnownCache.TryGetOrAdd(homeserver, async () => {
- logger.LogTrace($"Resolving client well-known: {homeserver}");
- if ((await TryGetClientWellKnownFromHttps(homeserver)) is { } clientWellKnown)
- return new() {
- Source = WellKnownResolverService.WellKnownSource.Https,
- WellKnown = clientWellKnown
- };
-
- return default!;
- });
- }
-
- private async Task<ClientWellKnown?> TryGetClientWellKnownFromHttps(string homeserver) {
- try {
- return await HttpClient.TryGetFromJsonAsync<ClientWellKnown>($"https://{homeserver}/.well-known/matrix/client");
- }
- catch {
- return null;
- }
- }
-
-
-
- public class ClientWellKnown {
- [JsonPropertyName("m.homeserver")]
- public required WellKnownHomeserver Homeserver { get; set; }
-
- public class WellKnownHomeserver {
- [JsonPropertyName("base_url")]
- public required string BaseUrl { get; set; }
- }
- }
-
- public struct WellKnownResolutionResult {
- public WellKnownResolverService.WellKnownSource Source { get; set; }
- public ClientWellKnown WellKnown { get; set; }
- public List<WellKnownResolverService.WellKnownResolutionWarning> Warnings { get; set; }
- }
-}
\ No newline at end of file
diff --git a/LibMatrix/Services/WellKnownResolvers/SupportWellKnownResolver.cs b/LibMatrix/Services/WellKnownResolvers/SupportWellKnownResolver.cs
deleted file mode 100644
index 1d7567a..0000000
--- a/LibMatrix/Services/WellKnownResolvers/SupportWellKnownResolver.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System.Text.Json.Serialization;
-using ArcaneLibs.Collections;
-using LibMatrix.Extensions;
-using Microsoft.Extensions.Logging;
-
-namespace LibMatrix.Services.WellKnownResolvers;
-
-public class SupportWellKnownResolver(ILogger<SupportWellKnownResolver> logger) {
- private static readonly SemaphoreCache<WellKnownResolverService.WellKnownResolutionResult<SupportWellKnown>> ClientWellKnownCache = new() {
- StoreNulls = false
- };
-
- private static readonly MatrixHttpClient HttpClient = new();
-
- public Task<WellKnownResolverService.WellKnownResolutionResult<SupportWellKnown>> TryResolveClientWellKnown(string homeserver) {
- return ClientWellKnownCache.TryGetOrAdd(homeserver, async () => {
- logger.LogTrace($"Resolving client well-known: {homeserver}");
- if ((await TryGetClientWellKnownFromHttps(homeserver)) is { } clientWellKnown)
- return new() {
- Source = WellKnownResolverService.WellKnownSource.Https,
- WellKnown = clientWellKnown
- };
- return default!;
- });
- }
-
- private async Task<SupportWellKnown?> TryGetClientWellKnownFromHttps(string homeserver) {
- try {
- return await HttpClient.TryGetFromJsonAsync<SupportWellKnown>($"https://{homeserver}/.well-known/matrix/support");
- }
- catch {
- return null;
- }
- }
-
- public struct SupportWellKnown {
- [JsonPropertyName("contacts")]
- public List<WellKnownContact>? Contacts { get; set; }
-
- [JsonPropertyName("support_page")]
- public Uri? SupportPage { get; set; }
-
- public class WellKnownContact {
- [JsonPropertyName("email_address")]
- public string? EmailAddress { get; set; }
-
- [JsonPropertyName("matrix_id")]
- public string? MatrixId { get; set; }
-
- [JsonPropertyName("role")]
- public required string Role { get; set; }
- }
- }
-}
\ No newline at end of file
|