diff --git a/Pilz.Net/Api/ApiClient.cs b/Pilz.Net/Api/ApiClient.cs
index 2844e45..eea248b 100644
--- a/Pilz.Net/Api/ApiClient.cs
+++ b/Pilz.Net/Api/ApiClient.cs
@@ -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");
diff --git a/Pilz.Net/Api/ApiRawStreamMessage.cs b/Pilz.Net/Api/ApiRawStreamMessage.cs
index a28acb0..b232f2c 100644
--- a/Pilz.Net/Api/ApiRawStreamMessage.cs
+++ b/Pilz.Net/Api/ApiRawStreamMessage.cs
@@ -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;
}
diff --git a/Pilz.Net/Api/ApiServer.cs b/Pilz.Net/Api/ApiServer.cs
index 8c2aed9..ef3332e 100644
--- a/Pilz.Net/Api/ApiServer.cs
+++ b/Pilz.Net/Api/ApiServer.cs
@@ -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");
diff --git a/Pilz.Net/Pilz.Net.csproj b/Pilz.Net/Pilz.Net.csproj
index b4e3f77..277e119 100644
--- a/Pilz.Net/Pilz.Net.csproj
+++ b/Pilz.Net/Pilz.Net.csproj
@@ -8,7 +8,7 @@
- 2.10.4
+ 2.11.0