From ba59f7df79b696af4acdac76e013ec97d0a0ef42 Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Fri, 31 Oct 2025 11:36:28 +0100 Subject: [PATCH] ApiStreamMessage --- Pilz.Net/Api/ApiClient.cs | 6 ++++-- Pilz.Net/Api/ApiRawByteMessage.cs | 6 ++++++ Pilz.Net/Api/ApiRawMessage.cs | 4 ++-- Pilz.Net/Api/ApiRawStreamMessage.cs | 6 ++++++ Pilz.Net/Api/ApiServer.cs | 14 +++++++++++++- Pilz.Net/Pilz.Net.csproj | 2 +- 6 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 Pilz.Net/Api/ApiRawByteMessage.cs create mode 100644 Pilz.Net/Api/ApiRawStreamMessage.cs 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