From b75135d8cdb702423d693558ffaec3f025264b98 Mon Sep 17 00:00:00 2001 From: TheArcaneBrony Date: Thu, 26 Oct 2023 13:09:05 +0000 Subject: split client and server http client for homeservers --- .../Homeservers/AuthenticatedHomeserverGeneric.cs | 36 ++++++++++------ .../Homeservers/AuthenticatedHomeserverSynapse.cs | 2 +- LibMatrix/Homeservers/RemoteHomeServer.cs | 48 ++++++++++++++++------ 3 files changed, 60 insertions(+), 26 deletions(-) (limited to 'LibMatrix/Homeservers') diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs index e5e4274..c3684a1 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -13,19 +13,29 @@ using LibMatrix.Services; namespace LibMatrix.Homeservers; -public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) : RemoteHomeServer(baseUrl) { +public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) : RemoteHomeserver(baseUrl) { public static async Task Create(string baseUrl, string accessToken) where T : AuthenticatedHomeserverGeneric { var instance = Activator.CreateInstance(typeof(T), baseUrl, accessToken) as T ?? throw new InvalidOperationException($"Failed to create instance of {typeof(T).Name}"); - instance._httpClient = new() { - BaseAddress = new Uri(await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl) + var urls = await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl); + + instance.ClientHttpClient = new() { + BaseAddress = new Uri(urls.client ?? throw new InvalidOperationException("Failed to resolve homeserver")), Timeout = TimeSpan.FromMinutes(15), DefaultRequestHeaders = { Authorization = new AuthenticationHeaderValue("Bearer", accessToken) } }; - instance.WhoAmI = await instance._httpClient.GetFromJsonAsync("/_matrix/client/v3/account/whoami"); + instance.ServerHttpClient = new() { + BaseAddress = new Uri(urls.server + ?? throw new InvalidOperationException("Failed to resolve homeserver")), + Timeout = TimeSpan.FromMinutes(15), + DefaultRequestHeaders = { + Authorization = new AuthenticationHeaderValue("Bearer", accessToken) + } + }; + instance.WhoAmI = await instance.ClientHttpClient.GetFromJsonAsync("/_matrix/client/v3/account/whoami"); return instance; } @@ -59,7 +69,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) } public virtual async Task> GetJoinedRooms() { - var roomQuery = await _httpClient.GetAsync("/_matrix/client/v3/joined_rooms"); + var roomQuery = await ClientHttpClient.GetAsync("/_matrix/client/v3/joined_rooms"); var roomsJson = await roomQuery.Content.ReadFromJsonAsync(); var rooms = roomsJson.GetProperty("joined_rooms").EnumerateArray().Select(room => GetRoom(room.GetString()!)).ToList(); @@ -70,7 +80,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) } public virtual async Task UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") { - var res = await _httpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream)); + var res = await ClientHttpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream)); if (!res.IsSuccessStatusCode) { Console.WriteLine($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); throw new InvalidDataException($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); @@ -99,7 +109,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) } creationEvent.CreationContent["creator"] = WhoAmI.UserId; - var res = await _httpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent, new JsonSerializerOptions { + var res = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); if (!res.IsSuccessStatusCode) { @@ -116,7 +126,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) } public virtual async Task Logout() { - var res = await _httpClient.PostAsync("/_matrix/client/v3/logout", null); + var res = await ClientHttpClient.PostAsync("/_matrix/client/v3/logout", null); if (!res.IsSuccessStatusCode) { Console.WriteLine($"Failed to logout: {await res.Content.ReadAsStringAsync()}"); throw new InvalidDataException($"Failed to logout: {await res.Content.ReadAsStringAsync()}"); @@ -153,11 +163,11 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) // } // // return await res.Content.ReadFromJsonAsync(); - return await _httpClient.GetFromJsonAsync($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}"); + return await ClientHttpClient.GetFromJsonAsync($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}"); } public virtual async Task SetAccountDataAsync(string key, object data) { - var res = await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}", data); + var res = await ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}", data); if (!res.IsSuccessStatusCode) { Console.WriteLine($"Failed to set account data: {await res.Content.ReadAsStringAsync()}"); throw new InvalidDataException($"Failed to set account data: {await res.Content.ReadAsStringAsync()}"); @@ -169,7 +179,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) public string? ResolveMediaUri(string? mxcUri) { if (mxcUri is null) return null; if (mxcUri.StartsWith("https://")) return mxcUri; - return $"{_httpClient.BaseAddress}/_matrix/media/v3/download/{mxcUri.Replace("mxc://", "")}".Replace("//_matrix", "/_matrix"); + return $"{ClientHttpClient.BaseAddress}/_matrix/media/v3/download/{mxcUri.Replace("mxc://", "")}".Replace("//_matrix", "/_matrix"); } public async Task UpdateProfileAsync(UserProfileResponse? newProfile, bool preserveCustomRoomProfile = true) { @@ -217,14 +227,14 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) } if (oldProfile.DisplayName != newProfile.DisplayName) { - await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/displayname", new { displayname = newProfile.DisplayName }); + await ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/displayname", new { displayname = newProfile.DisplayName }); } else { Console.WriteLine($"Not updating display name because {oldProfile.DisplayName} == {newProfile.DisplayName}"); } if (oldProfile.AvatarUrl != newProfile.AvatarUrl) { - await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/avatar_url", new { avatar_url = newProfile.AvatarUrl }); + await ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/avatar_url", new { avatar_url = newProfile.AvatarUrl }); } else { Console.WriteLine($"Not updating avatar URL because {newProfile.AvatarUrl} == {newProfile.AvatarUrl}"); diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs index 6d60dd7..0910cbe 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs @@ -23,7 +23,7 @@ public class AuthenticatedHomeserverSynapse : AuthenticatedHomeserverGeneric { Console.WriteLine($"--- ADMIN Querying Room List with URL: {url} - Already have {i} items... ---"); - res = await _authenticatedHomeserver._httpClient.GetFromJsonAsync(url); + res = await _authenticatedHomeserver.ClientHttpClient.GetFromJsonAsync(url); totalRooms ??= res?.TotalRooms; Console.WriteLine(res.ToJson(false)); foreach (var room in res.Rooms) { diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs index a8d0326..0757f6e 100644 --- a/LibMatrix/Homeservers/RemoteHomeServer.cs +++ b/LibMatrix/Homeservers/RemoteHomeServer.cs @@ -9,19 +9,25 @@ using LibMatrix.Services; namespace LibMatrix.Homeservers; -public class RemoteHomeServer(string baseUrl) { - public static async Task Create(string baseUrl) => - new(baseUrl) { - _httpClient = new() { - BaseAddress = new Uri(await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl) - ?? throw new InvalidOperationException("Failed to resolve homeserver")), +public class RemoteHomeserver(string baseUrl) { + public static async Task Create(string baseUrl) { + var urls = await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl); + return new RemoteHomeserver(baseUrl) { + ClientHttpClient = new() { + BaseAddress = new Uri(urls.client ?? throw new InvalidOperationException("Failed to resolve homeserver")), + Timeout = TimeSpan.FromSeconds(120) + }, + ServerHttpClient = new() { + BaseAddress = new Uri(urls.server ?? throw new InvalidOperationException("Failed to resolve homeserver")), Timeout = TimeSpan.FromSeconds(120) } }; + } private Dictionary _profileCache { get; set; } = new(); public string BaseUrl { get; } = baseUrl; - public MatrixHttpClient _httpClient { get; set; } + public MatrixHttpClient ClientHttpClient { get; set; } + public MatrixHttpClient ServerHttpClient { get; set; } public async Task GetProfileAsync(string mxid) { if (mxid is null) throw new ArgumentNullException(nameof(mxid)); @@ -32,7 +38,7 @@ public class RemoteHomeServer(string baseUrl) { _profileCache[mxid] = new SemaphoreSlim(1); - var resp = await _httpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}"); + var resp = await ClientHttpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}"); var data = await resp.Content.ReadFromJsonAsync(); if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); _profileCache[mxid] = data; @@ -41,14 +47,14 @@ public class RemoteHomeServer(string baseUrl) { } public async Task GetClientVersionsAsync() { - var resp = await _httpClient.GetAsync($"/_matrix/client/versions"); + var resp = await ClientHttpClient.GetAsync($"/_matrix/client/versions"); var data = await resp.Content.ReadFromJsonAsync(); if (!resp.IsSuccessStatusCode) Console.WriteLine("ClientVersions: " + data); return data; } public async Task ResolveRoomAliasAsync(string alias) { - var resp = await _httpClient.GetAsync($"/_matrix/client/v3/directory/room/{alias.Replace("#", "%23")}"); + var resp = await ClientHttpClient.GetAsync($"/_matrix/client/v3/directory/room/{alias.Replace("#", "%23")}"); var data = await resp.Content.ReadFromJsonAsync(); var text = await resp.Content.ReadAsStringAsync(); if (!resp.IsSuccessStatusCode) Console.WriteLine("ResolveAlias: " + data.ToJson()); @@ -58,7 +64,7 @@ public class RemoteHomeServer(string baseUrl) { #region Authentication public async Task LoginAsync(string username, string password, string? deviceName = null) { - var resp = await _httpClient.PostAsJsonAsync("/_matrix/client/r0/login", new { + var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/r0/login", new { type = "m.login.password", identifier = new { type = "m.id.user", @@ -73,7 +79,7 @@ public class RemoteHomeServer(string baseUrl) { } public async Task RegisterAsync(string username, string password, string? deviceName = null) { - var resp = await _httpClient.PostAsJsonAsync("/_matrix/client/r0/register", new { + var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/r0/register", new { kind = "user", auth = new { type = "m.login.dummy" @@ -90,6 +96,24 @@ public class RemoteHomeServer(string baseUrl) { } #endregion + + public async Task GetServerVersionAsync() { + return await ServerHttpClient.GetFromJsonAsync("/_matrix/federation/v1/version"); + } +} + +public class ServerVersionResponse { + + [JsonPropertyName("server")] + public ServerInfo Server { get; set; } + + public class ServerInfo { + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("version")] + public string Version { get; set; } + } } public class AliasResult { -- cgit 1.4.1