about summary refs log tree commit diff
path: root/LibMatrix
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix')
-rw-r--r--LibMatrix/Extensions/HttpClientExtensions.cs34
-rw-r--r--LibMatrix/RoomTypes/GenericRoom.cs6
2 files changed, 34 insertions, 6 deletions
diff --git a/LibMatrix/Extensions/HttpClientExtensions.cs b/LibMatrix/Extensions/HttpClientExtensions.cs
index 01ce6ea..64b4f6a 100644
--- a/LibMatrix/Extensions/HttpClientExtensions.cs
+++ b/LibMatrix/Extensions/HttpClientExtensions.cs
@@ -29,6 +29,10 @@ public class MatrixHttpClient : HttpClient {
     public Dictionary<string, string> AdditionalQueryParameters { get; set; } = new();
     internal string? AssertedUserId { get; set; }
 
+    internal SemaphoreSlim _rateLimitSemaphore { get; } = new(1, 1);
+    
+    internal const bool debug = false;
+
     private JsonSerializerOptions GetJsonSerializerOptions(JsonSerializerOptions? options = null) {
         options ??= new JsonSerializerOptions();
         options.Converters.Add(new JsonFloatStringConverter());
@@ -39,7 +43,8 @@ public class MatrixHttpClient : HttpClient {
     }
 
     public async Task<HttpResponseMessage> SendUnhandledAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
-        Console.WriteLine($"Sending {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.Content?.Headers.ContentLength ?? 0)})");
+        if(debug) await _rateLimitSemaphore.WaitAsync(cancellationToken);
+        // Console.WriteLine($"Sending {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.Content?.Headers.ContentLength ?? 0)})");
         if (request.RequestUri is null) throw new NullReferenceException("RequestUri is null");
         if (!request.RequestUri.IsAbsoluteUri) request.RequestUri = new Uri(BaseAddress, request.RequestUri);
         // if (AssertedUserId is not null) request.RequestUri = request.RequestUri.AddQuery("user_id", AssertedUserId);
@@ -57,7 +62,17 @@ public class MatrixHttpClient : HttpClient {
             Console.WriteLine(e);
         }
 
-        var responseMessage = await base.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
+        HttpResponseMessage? responseMessage;
+        try {
+            responseMessage = await base.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
+        }
+        catch (Exception e) {
+            Console.WriteLine($"Failed to send request {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.Content?.Headers.ContentLength ?? 0)}):\n{e}");
+            throw;
+        }
+        finally {
+            if(debug) _rateLimitSemaphore.Release();
+        }
 
         return responseMessage;
     }
@@ -75,7 +90,18 @@ public class MatrixHttpClient : HttpClient {
             };
         if (!content.StartsWith('{')) throw new InvalidDataException("Encountered invalid data:\n" + content);
         //we have a matrix error
-        var ex = JsonSerializer.Deserialize<MatrixException>(content);
+
+        MatrixException? ex = null;
+        try {
+            ex = JsonSerializer.Deserialize<MatrixException>(content);
+        }
+        catch (JsonException e) {
+            throw new LibMatrixException() {
+                ErrorCode = "M_INVALID_JSON",
+                Error = e.Message + "\nBody:\n" + await responseMessage.Content.ReadAsStringAsync(cancellationToken)
+            };
+        }
+
         Debug.Assert(ex != null, nameof(ex) + " != null");
         ex.RawContent = content;
         // Console.WriteLine($"Failed to send request: {ex}");
@@ -136,7 +162,7 @@ public class MatrixHttpClient : HttpClient {
         options = GetJsonSerializerOptions(options);
         var request = new HttpRequestMessage(HttpMethod.Put, requestUri);
         request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
-        Console.WriteLine($"Sending PUT {requestUri}");
+        // Console.WriteLine($"Sending PUT {requestUri}");
         // Console.WriteLine($"Content: {JsonSerializer.Serialize(value, value.GetType(), options)}");
         // Console.WriteLine($"Type: {value.GetType().FullName}");
         request.Content = new StringContent(JsonSerializer.Serialize(value, value.GetType(), options),
diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs
index 43f3acc..742f5d9 100644
--- a/LibMatrix/RoomTypes/GenericRoom.cs
+++ b/LibMatrix/RoomTypes/GenericRoom.cs
@@ -517,18 +517,20 @@ public class GenericRoom {
 #endregion
 
     public async IAsyncEnumerable<StateEventResponse> GetRelatedEventsAsync(string eventId, string? relationType = null, string? eventType = null, string? dir = "f",
-        string? from = null, int? chunkLimit = 100, bool? recurse = false, string? to = null) {
-        var path = $"/_matrix/client/v3/rooms/{RoomId}/relations/{eventId}";
+        string? from = null, int? chunkLimit = 100, bool? recurse = null, string? to = null) {
+        var path = $"/_matrix/client/v1/rooms/{RoomId}/relations/{HttpUtility.UrlEncode(eventId)}";
         if (!string.IsNullOrEmpty(relationType)) path += $"/{relationType}";
         if (!string.IsNullOrEmpty(eventType)) path += $"/{eventType}";
 
         var uri = new Uri(path, UriKind.Relative);
         if (dir == "b" || dir == "f") uri = uri.AddQuery("dir", dir);
+        else if(!string.IsNullOrWhiteSpace(dir)) throw new ArgumentException("Invalid direction", nameof(dir));
         if (!string.IsNullOrEmpty(from)) uri = uri.AddQuery("from", from);
         if (chunkLimit is not null) uri = uri.AddQuery("limit", chunkLimit.Value.ToString());
         if (recurse is not null) uri = uri.AddQuery("recurse", recurse.Value.ToString());
         if (!string.IsNullOrEmpty(to)) uri = uri.AddQuery("to", to);
 
+        // Console.WriteLine($"Getting related events from {uri}");
         var result = await Homeserver.ClientHttpClient.GetFromJsonAsync<RecursedBatchedChunkedStateEventResponse>(uri);
         while (result!.Chunk.Count > 0) {
             foreach (var resp in result.Chunk) {