support raw messages on apiclient->apiserver

This commit is contained in:
Pilzinsel64
2025-12-03 07:58:26 +01:00
parent 2bc2352cb1
commit 06f2fcaddd
4 changed files with 60 additions and 39 deletions

View File

@@ -100,7 +100,17 @@ public class ApiClient(string apiUrl) : IApiClient
Log.Debug("Create content");
if (context.Message is not null)
if (context.Message is ApiRawByteMessage messageRawBytes)
{
content = new ByteArrayContent(messageRawBytes.Data);
content.Headers.ContentType = new("application/octet-stream");
}
else if (context.Message is ApiRawStreamMessage messageRawStream)
{
content = new StreamContent(messageRawStream.Data);
content.Headers.ContentType = new("application/octet-stream");
}
else if (context.Message is not null)
content = new StringContent(context.Serializer.Serialize(context.Message)!, null, "application/json");
else
content = new StringContent(string.Empty, null, "application/json");

View File

@@ -3,4 +3,10 @@
public class ApiRawStreamMessage(Stream data) : ApiRawMessage
{
public Stream Data { get; } = data;
public virtual long Length => Data.Length;
}
public class ApiRawInputStreamMessage(Stream data, long length) : ApiRawStreamMessage(data)
{
public override long Length => length;
}

View File

@@ -436,37 +436,9 @@ public class ApiServer : IApiServer
if (context.Request.Headers.Get("API-AUTH-KEY") is not string authKey)
authKey = null!;
// Read input content
Log.Debug("Read input content");
string? contentJson;
if (context.Request.ContentType is string contentType
&& contentType.Contains("application/json")
&& context.Request.ContentLength64 > 0)
{
try
{
using StreamReader input = new(context.Request.InputStream);
contentJson = input.ReadToEnd();
}
catch (OutOfMemoryException)
{
Log.Error("Error reading remote data due to missing memory");
close(true);
return;
}
catch (Exception ex)
{
Log.Error("Error reading remote data", ex);
close(true);
return;
}
}
else
contentJson = null;
// Handle message
Log.Debug("Handle mssage");
if (HandleMessage(context, path, query, handler, contentJson, authKey) is not PrivateApiResult result)
if (HandleMessage(context, path, query, handler, authKey) is not PrivateApiResult result)
{
Log.Warn("Request couldn't be handled");
close(true);
@@ -514,7 +486,7 @@ public class ApiServer : IApiServer
return;
}
protected virtual PrivateApiResult? HandleMessage(HttpListenerContext context, string url, string? query, PrivateMessageHandler handler, string? json, string? authKey)
protected virtual PrivateApiResult? HandleMessage(HttpListenerContext context, string url, string? query, PrivateMessageHandler handler, string? authKey)
{
// Check authentication
Log.Debug("Check authentication");
@@ -530,13 +502,46 @@ public class ApiServer : IApiServer
var targetType = handler.Handler.Method.GetParameters().FirstOrDefault(p => p.ParameterType.IsAssignableTo(typeof(ApiMessage)))?.ParameterType;
var serializer = GetSerializer(handler.Attribute.Serializer);
// Deserialize
Log.Debug("Deserialize message");
ApiMessage? message;
if (json != null && targetType != null)
message = serializer.Deserialize(json, targetType);
else
message = null;
// Read input content
Log.Debug("Read input content");
ApiMessage? message = null;
switch (context.Request.ContentType)
{
case "application/json":
try
{
Log.Debug("Deserialize message");
using StreamReader input = new(context.Request.InputStream);
var contentJson = input.ReadToEnd();
if (targetType == null)
return null;
message = serializer.Deserialize(contentJson, targetType);
}
catch (OutOfMemoryException)
{
Log.Error("Error reading remote data due to missing memory");
return null;
}
catch (Exception ex)
{
Log.Error("Error reading remote data", ex);
return null;
}
break;
case "application/octet-stream":
Log.Debug("Process raw message");
if (targetType == null)
return null;
else if (targetType.IsAssignableTo(typeof(ApiRawByteMessage)))
{
var bytes = new byte[context.Request.ContentLength64];
context.Request.InputStream.Read(bytes, 0, bytes.Length);
message = new ApiRawByteMessage(bytes);
}
else if (targetType.IsAssignableTo(typeof(ApiRawStreamMessage)))
message = new ApiRawInputStreamMessage(context.Request.InputStream, context.Request.ContentLength64);
break;
}
// Invoke handler
Log.Debug("Invoke handler");

View File

@@ -8,7 +8,7 @@
</PropertyGroup>
<PropertyGroup>
<Version>2.10.4</Version>
<Version>2.11.0</Version>
</PropertyGroup>
<ItemGroup>