-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Labels
Description
Steps to reproduce
- Create a project targeting .net 3.1 or higher
- create a zip using
new ZipOutputStream(context.Response.Body)andPutNextEntryAsync()
Expected behavior
the zip file can be sent streamingly to the client by writing directily to context.Response.Body, without creating an intermediary MemoryStream.
The reason for not using a MemoryStream and writing directly to context.Response.Bodyis to prevent high memory consumption on the server when creating big zip files. I haven't found any library that can handle this correctly, except SharpZipLib which seems to be really closed to achieve this 😥
Actual behavior
when calling stream.PutNextEntryAsync(), a "System.NotSupportedException: Specified method is not supported" is thrown., complete stacktrace :
System.NotSupportedException: Specified method is not supported.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.get_Position()
at ICSharpCode.SharpZipLib.Zip.ZipOutputStream.<>c__DisplayClass28_0.<PutNextEntryAsync>b__0(Stream s) in C:\Users\roddone\Source\Repos\SharpZipLib\src\ICSharpCode.SharpZipLib\Zip\ZipOutputStream.cs:line 526
at ICSharpCode.SharpZipLib.Core.StreamUtils.WriteProcToStreamAsync(Stream targetStream, MemoryStream bufferStream, Action`1 writeProc, CancellationToken ct) in C:\Users\roddone\Source\Repos\SharpZipLib\src\ICSharpCode.SharpZipLib\Core\StreamUtils.cs:line 281
at ICSharpCode.SharpZipLib.Core.StreamUtils.WriteProcToStreamAsync(Stream targetStream, Action`1 writeProc, CancellationToken ct) in C:\Users\roddone\Source\Repos\SharpZipLib\src\ICSharpCode.SharpZipLib\Core\StreamUtils.cs:line 291
at ICSharpCode.SharpZipLib.Zip.ZipOutputStream.PutNextEntryAsync(ZipEntry entry, CancellationToken ct) in C:\Users\roddone\Source\Repos\SharpZipLib\src\ICSharpCode.SharpZipLib\Zip\ZipOutputStream.cs:line 524
at Program.<>c.<<<Main>$>b__0_0>d.MoveNext() in C:\Users\roddone\Source\Repos\SharpZipLib\TestStreaming\Program.cs:line 12
--- End of stack trace from previous location ---
at Program.<>c.<<<Main>$>b__0_0>d.MoveNext() in C:\Users\roddone\Source\Repos\SharpZipLib\TestStreaming\Program.cs:line 19
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Version of SharpZipLib
Obtained from (only keep the relevant lines)
- Compiled from source, latest commit from master
full sample to reproduce (must create a .net 6 project) :
using ICSharpCode.SharpZipLib.Zip;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", async (HttpContext context) =>
{
await using (var stream = new ZipOutputStream(context.Response.Body))
{
//add file without compression
await stream.PutNextEntryAsync(new ZipEntry("test.txt") { CompressionMethod = CompressionMethod.Stored });
var bytes = Encoding.UTF8.GetBytes("ah ah !");
await stream.WriteAsync(bytes);
await stream.FinishAsync(CancellationToken.None);
}
});
app.Run();