HOME 1 month ago
parent
commit
6bf71cd078
1 changed files with 39 additions and 20 deletions
  1. 39 20
      ImageConvertService/Controllers/ConvertToWebpController.cs

+ 39 - 20
ImageConvertService/Controllers/ConvertToWebpController.cs

@@ -21,48 +21,67 @@ public class ConvertToWebpController(ImageConverter converter, ArchiveFileAccess
     }
 
     [HttpPost]
-    public IActionResult AnyArchiveQuery(
+    public async Task<FileContentResult> AnyArchiveQuery(
         IFormFile file,
         [FromQuery] string? skips,
         [FromQuery] OutputArchiveFormat? format = OutputArchiveFormat.Fast7Z)
     {
-        return AnyArchiveInternal(file, format, skips);
+        return await AnyArchiveInternal(file.OpenReadStream(), Request.ContentLength, file.FileName, format, skips);
     }
 
     [HttpPost]
-    public IActionResult AnyArchiveForm(
+    public async Task<FileContentResult> AnyArchiveForm(
         IFormFile file,
         [FromForm] string? skips,
         [FromForm] OutputArchiveFormat? format = OutputArchiveFormat.Fast7Z)
     {
-        return AnyArchiveInternal(file, format, skips);
-    }
-
-    private IActionResult AnyArchiveInternal(IFormFile file, OutputArchiveFormat? format, string? skips)
-    {
-        format ??= OutputArchiveFormat.Fast7Z;
-
-        var ms = new MemoryStream();
-        file.CopyTo(ms);
-        ms.Position = 0;
-
-        return ProcessArchiveInternal(ms, file.FileName, skips, format.Value);
+        return await AnyArchiveInternal(file.OpenReadStream(), Request.ContentLength, file.FileName, format, skips);
     }
 
     [HttpPost]
-    public async Task<IActionResult> AnyArchiveStreaming(
+    public async Task<FileContentResult> AnyArchiveStreaming(
         [FromQuery] string filename,
         [FromQuery] string? skips,
         [FromQuery] OutputArchiveFormat format = OutputArchiveFormat.Fast7Z)
     {
+        return await AnyArchiveInternal(Request.Body, Request.ContentLength, filename, format, skips);
+    }
+
+    private async Task<FileContentResult> AnyArchiveInternal(Stream inputStream, long? contentLength, string fileName, OutputArchiveFormat? format, string? skips)
+    {
+        format ??= OutputArchiveFormat.Fast7Z;
+
+        if (inputStream.CanSeek)
+        {
+            inputStream.Position = 0;
+            return ProcessArchiveInternal(inputStream, fileName, skips, format.Value);
+        }
+
+        try
+        {
+            contentLength = inputStream.Length;
+        }
+        catch (NotSupportedException)
+        {
+        }
+
+        if (contentLength.HasValue && contentLength.Value < 2_000_000_000)
+        {
+            var ms = new MemoryStream();
+            await inputStream.CopyToAsync(ms);
+            ms.Position = 0;
+
+            return ProcessArchiveInternal(ms, fileName, skips, format.Value);
+        }
+
         await using var tmpFileStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
-        await Request.Body.CopyToAsync(tmpFileStream);
+        await inputStream.CopyToAsync(tmpFileStream);
         tmpFileStream.Position = 0;
 
-        return ProcessArchiveInternal(tmpFileStream, filename, skips, format);
+        return ProcessArchiveInternal(tmpFileStream, fileName, skips, format.Value);
     }
 
-    private IActionResult ProcessArchiveInternal(Stream ms, string fileName, string? skips, OutputArchiveFormat format)
+    private FileContentResult ProcessArchiveInternal(Stream ms, string fileName, string? skips, OutputArchiveFormat format)
     {
         var (direct, convert) = filter.Filter(archiver.ReadArchive(ms), skips);
 
@@ -106,7 +125,7 @@ public class ConvertToWebpController(ImageConverter converter, ArchiveFileAccess
         return OutputAsArchive(fileName, format, direct, hasError);
     }
 
-    private IActionResult OutputAsArchive(string filename, OutputArchiveFormat format, List<ArchiveEntry> direct, bool withErrors)
+    private FileContentResult OutputAsArchive(string filename, OutputArchiveFormat format, List<ArchiveEntry> direct, bool withErrors)
     {
         return format switch
         {