about summary refs log tree commit diff
path: root/LibMatrix/Extensions
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix/Extensions')
-rw-r--r--LibMatrix/Extensions/CanonicalJsonSerializer.cs16
-rw-r--r--LibMatrix/Extensions/JsonElementExtensions.cs1
-rw-r--r--LibMatrix/Extensions/MatrixHttpClient.Multi.cs11
-rw-r--r--LibMatrix/Extensions/MatrixHttpClient.Single.cs32
4 files changed, 31 insertions, 29 deletions
diff --git a/LibMatrix/Extensions/CanonicalJsonSerializer.cs b/LibMatrix/Extensions/CanonicalJsonSerializer.cs

index a6fbcf4..55a4b1a 100644 --- a/LibMatrix/Extensions/CanonicalJsonSerializer.cs +++ b/LibMatrix/Extensions/CanonicalJsonSerializer.cs
@@ -1,19 +1,14 @@ using System.Collections.Frozen; using System.Reflection; -using System.Security.Cryptography; -using System.Text.Encodings.Web; using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; -using System.Text.Unicode; using ArcaneLibs.Extensions; namespace LibMatrix.Extensions; public static class CanonicalJsonSerializer { // TODO: Alphabetise dictionaries - private static JsonSerializerOptions _options => new() { + private static JsonSerializerOptions JsonOptions => new() { WriteIndented = false, Encoder = UnicodeJsonEncoder.Singleton, }; @@ -24,7 +19,7 @@ public static class CanonicalJsonSerializer { .ToFrozenSet(); private static JsonSerializerOptions MergeOptions(JsonSerializerOptions? inputOptions) { - var newOptions = _options; + var newOptions = JsonOptions; if (inputOptions == null) return newOptions; @@ -48,7 +43,7 @@ public static class CanonicalJsonSerializer { public static String Serialize<TValue>(TValue value, JsonSerializerOptions? options = null) { var newOptions = MergeOptions(options); - return System.Text.Json.JsonSerializer.SerializeToNode(value, options) // We want to allow passing custom converters for eg. double/float -> string here... + return JsonSerializer.SerializeToNode(value, options) // We want to allow passing custom converters for eg. double/float -> string here... .SortProperties()! .CanonicalizeNumbers()! .ToJsonString(newOptions); @@ -58,13 +53,14 @@ public static class CanonicalJsonSerializer { } - public static String Serialize(object value, Type inputType, JsonSerializerOptions? options = null) => JsonSerializer.Serialize(value, inputType, _options); + public static String Serialize(object value, Type inputType, JsonSerializerOptions? options = null) => JsonSerializer.Serialize(value, inputType, JsonOptions); // public static String Serialize<TValue>(TValue value, JsonTypeInfo<TValue> jsonTypeInfo) => JsonSerializer.Serialize(value, jsonTypeInfo, _options); // public static String Serialize(Object value, JsonTypeInfo jsonTypeInfo) #endregion - private static partial class JsonExtensions { + // ReSharper disable once UnusedType.Local + private static class JsonExtensions { public static Action<JsonTypeInfo> AlphabetizeProperties(Type type) { return typeInfo => { if (typeInfo.Kind != JsonTypeInfoKind.Object || !type.IsAssignableFrom(typeInfo.Type)) diff --git a/LibMatrix/Extensions/JsonElementExtensions.cs b/LibMatrix/Extensions/JsonElementExtensions.cs
index c4ed743..dfec95b 100644 --- a/LibMatrix/Extensions/JsonElementExtensions.cs +++ b/LibMatrix/Extensions/JsonElementExtensions.cs
@@ -126,6 +126,7 @@ public static class JsonElementExtensions { $"Encountered dictionary {field.Name} with key type {keyType.Name} and value type {valueType.Name}!"); return field.Value.EnumerateObject() + // TODO: use key.Value? .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) .Aggregate(false, (current, key) => current | key.FindExtraJsonPropertyFieldsByValueKind(containerType, valueType) diff --git a/LibMatrix/Extensions/MatrixHttpClient.Multi.cs b/LibMatrix/Extensions/MatrixHttpClient.Multi.cs
index e7a2044..bf6fe63 100644 --- a/LibMatrix/Extensions/MatrixHttpClient.Multi.cs +++ b/LibMatrix/Extensions/MatrixHttpClient.Multi.cs
@@ -1,16 +1,5 @@ #define SINGLE_HTTPCLIENT // Use a single HttpClient instance for all MatrixHttpClient instances // #define SYNC_HTTPCLIENT // Only allow one request as a time, for debugging -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Net.Http.Headers; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using ArcaneLibs; -using ArcaneLibs.Extensions; - namespace LibMatrix.Extensions; public static class HttpClientExtensions { diff --git a/LibMatrix/Extensions/MatrixHttpClient.Single.cs b/LibMatrix/Extensions/MatrixHttpClient.Single.cs
index 0e6d467..a3ea409 100644 --- a/LibMatrix/Extensions/MatrixHttpClient.Single.cs +++ b/LibMatrix/Extensions/MatrixHttpClient.Single.cs
@@ -5,12 +5,12 @@ using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Http.Headers; using System.Reflection; -using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using ArcaneLibs; using ArcaneLibs.Extensions; +using LibMatrix.Homeservers.ImplementationDetails.Synapse.Models.Requests; namespace LibMatrix.Extensions; @@ -82,10 +82,11 @@ public class MatrixHttpClient { Console.WriteLine($"Sending {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.GetContentLength())})"); if (request.RequestUri is null) throw new NullReferenceException("RequestUri is null"); - if (!request.RequestUri.IsAbsoluteUri) request.RequestUri = new Uri(BaseAddress, request.RequestUri); + if (!request.RequestUri.IsAbsoluteUri) + request.RequestUri = new Uri(BaseAddress ?? throw new InvalidOperationException("Relative URI passed, but no BaseAddress is specified!"), request.RequestUri); swWait.Stop(); var swExec = Stopwatch.StartNew(); - + foreach (var (key, value) in AdditionalQueryParameters) request.RequestUri = request.RequestUri.AddQuery(key, value); foreach (var (key, value) in DefaultRequestHeaders) { if (request.Headers.Contains(key)) continue; @@ -102,8 +103,16 @@ public class MatrixHttpClient { responseMessage = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); } catch (Exception e) { - Console.WriteLine( - $"Failed to send request {request.Method} {request.RequestUri} ({Util.BytesToString(request.GetContentLength())}):\n{e}"); + if (e is TaskCanceledException or TimeoutException) { + if (request.Method == HttpMethod.Get && !cancellationToken.IsCancellationRequested) { + await Task.Delay(Random.Shared.Next(500, 2500), cancellationToken); + request.ResetSendStatus(); + return await SendAsync(request, cancellationToken); + } + } + else if (!e.ToString().StartsWith("TypeError: NetworkError")) + Console.WriteLine( + $"Failed to send request {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.Content?.Headers.ContentLength ?? 0)}):\n{e}"); throw; } #if SYNC_HTTPCLIENT @@ -156,7 +165,7 @@ public class MatrixHttpClient { if (!content.StartsWith('{')) throw new InvalidDataException("Encountered invalid data:\n" + content); //we have a matrix error - MatrixException? ex = null; + MatrixException? ex; try { ex = JsonSerializer.Deserialize<MatrixException>(content); } @@ -170,7 +179,7 @@ public class MatrixHttpClient { Debug.Assert(ex != null, nameof(ex) + " != null"); ex.RawContent = content; // Console.WriteLine($"Failed to send request: {ex}"); - if (ex?.RetryAfterMs is null) throw ex!; + if (ex.RetryAfterMs is null) throw ex!; //we have a ratelimit error await Task.Delay(ex.RetryAfterMs.Value, cancellationToken); request.ResetSendStatus(); @@ -209,7 +218,7 @@ public class MatrixHttpClient { } // GetStreamAsync - public new async Task<Stream> GetStreamAsync(string requestUri, CancellationToken cancellationToken = default) { + public async Task<Stream> GetStreamAsync(string requestUri, CancellationToken cancellationToken = default) { var request = new HttpRequestMessage(HttpMethod.Get, requestUri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await SendAsync(request, cancellationToken); @@ -271,5 +280,12 @@ public class MatrixHttpClient { var request = new HttpRequestMessage(HttpMethod.Delete, url); await SendAsync(request); } + + public async Task<HttpResponseMessage> DeleteAsJsonAsync<T>(string url, T payload) { + var request = new HttpRequestMessage(HttpMethod.Delete, url) { + Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json") + }; + return await SendAsync(request); + } } #endif