diff --git a/Pilz.Net/Api/ApiClient.cs b/Pilz.Net/Api/ApiClient.cs
index a9be748..2844e45 100644
--- a/Pilz.Net/Api/ApiClient.cs
+++ b/Pilz.Net/Api/ApiClient.cs
@@ -66,8 +66,10 @@ public class ApiClient(string apiUrl) : IApiClient
{
if (mediaType == "application/json" && context.Serializer != null)
result = context.Serializer.Deserialize(await context.HttpResponse.Content.ReadAsStringAsync(), typeof(TResponse)) as TResponse;
- else if (typeof(TResponse).IsAssignableTo(typeof(ApiRawMessage)) && mediaType == "application/octet-stream")
- result = (TResponse)(object)new ApiRawMessage(await context.HttpResponse.Content.ReadAsByteArrayAsync());
+ else if (typeof(TResponse).IsAssignableTo(typeof(ApiRawByteMessage)) && mediaType == "application/octet-stream")
+ result = (TResponse)(object)new ApiRawByteMessage(await context.HttpResponse.Content.ReadAsByteArrayAsync());
+ else if (typeof(TResponse).IsAssignableTo(typeof(ApiRawStreamMessage)) && mediaType == "application/octet-stream")
+ result = (TResponse)(object)new ApiRawStreamMessage(await context.HttpResponse.Content.ReadAsStreamAsync());
}
}
diff --git a/Pilz.Net/Api/ApiRawByteMessage.cs b/Pilz.Net/Api/ApiRawByteMessage.cs
new file mode 100644
index 0000000..87d61cb
--- /dev/null
+++ b/Pilz.Net/Api/ApiRawByteMessage.cs
@@ -0,0 +1,6 @@
+namespace Pilz.Net.Api;
+
+public class ApiRawByteMessage(byte[] data) : ApiRawMessage
+{
+ public byte[] Data { get; } = data;
+}
diff --git a/Pilz.Net/Api/ApiRawMessage.cs b/Pilz.Net/Api/ApiRawMessage.cs
index 90f3325..fe456c0 100644
--- a/Pilz.Net/Api/ApiRawMessage.cs
+++ b/Pilz.Net/Api/ApiRawMessage.cs
@@ -1,6 +1,6 @@
namespace Pilz.Net.Api;
-public class ApiRawMessage(byte[] data) : ApiMessage
+public abstract class ApiRawMessage : ApiMessage
{
- public byte[] Data { get; } = data;
+ public string? FileName { get; set; }
}
diff --git a/Pilz.Net/Api/ApiRawStreamMessage.cs b/Pilz.Net/Api/ApiRawStreamMessage.cs
new file mode 100644
index 0000000..a28acb0
--- /dev/null
+++ b/Pilz.Net/Api/ApiRawStreamMessage.cs
@@ -0,0 +1,6 @@
+namespace Pilz.Net.Api;
+
+public class ApiRawStreamMessage(Stream data) : ApiRawMessage
+{
+ public Stream Data { get; } = data;
+}
diff --git a/Pilz.Net/Api/ApiServer.cs b/Pilz.Net/Api/ApiServer.cs
index ce7078d..5a8f006 100644
--- a/Pilz.Net/Api/ApiServer.cs
+++ b/Pilz.Net/Api/ApiServer.cs
@@ -464,6 +464,8 @@ public class ApiServer : IApiServer
// Set response header
Log.Debug("Set response headers");
context.Response.AppendHeader("API-VERSION", ApiVersion.ToString());
+ if (result.Original.Message is ApiRawMessage apiRawMessage && !string.IsNullOrWhiteSpace(apiRawMessage.FileName))
+ context.Response.AppendHeader("Content-Disposition", $"filename=\"{apiRawMessage.FileName}\"");
// Set response parameters
Log.Debug("Set response parameters");
@@ -486,6 +488,14 @@ public class ApiServer : IApiServer
context.Response.OutputStream.Write(resultBytes, 0, resultBytes.Length);
context.Response.OutputStream.Flush();
}
+ else if (result.ResultContent is Stream resultStream)
+ {
+ Log.Info("Sending stream response for " + context.Request.RawUrl);
+ context.Response.ContentType = "application/octet-stream";
+ resultStream.CopyTo(context.Response.OutputStream);
+ context.Response.OutputStream.Flush();
+ resultStream.Close();
+ }
Log.Debug("Finish response");
close(false);
@@ -528,8 +538,10 @@ public class ApiServer : IApiServer
return new(result, null);
// Return result with raw data
- if (result.Message is ApiRawMessage dataMsg)
+ if (result.Message is ApiRawByteMessage dataMsg)
return new(result, dataMsg.Data);
+ if (result.Message is ApiRawStreamMessage streamMsg)
+ return new(result, streamMsg.Data);
// Serializer
Log.Debug("Serialize message");
diff --git a/Pilz.Net/Pilz.Net.csproj b/Pilz.Net/Pilz.Net.csproj
index 2b9f4c4..9c7ebf3 100644
--- a/Pilz.Net/Pilz.Net.csproj
+++ b/Pilz.Net/Pilz.Net.csproj
@@ -8,7 +8,7 @@
- 2.9.2
+ 2.9.3