mirror of
https://github.com/vxcontrol/pentagi.git
synced 2026-07-19 12:11:02 -04:00
[GH-ISSUE #338] [Bug]: ZIP downloads buffer the entire archive in memory [Introduced in 2.1.0] #111
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @john-ramsey on GitHub (Jun 5, 2026).
Original GitHub issue: https://github.com/vxcontrol/pentagi/issues/338
Originally assigned to: @asdek on GitHub.
Affected Component
Core Services (Frontend UI/Backend API)
Describe the bug
What happened:
Directory and multi-path ZIP downloads build the entire archive in a
bytes.Bufferand only then send it, so the whole compressed archive is held on the heap before any response byte is written. Combined with the 2 GB upload/pull limits, an authenticated user with defaultUser-role resource/flow-file permissions can store (or pull) a large, incompressible directory and request it as a ZIP, forcing the API process to allocate memory proportional to the archive size. A handful of concurrent requests can exhaust process/host memory and crash or severely degrade the API.Single-file downloads are fine since they stream from disk. Only the directory / multi-path ZIP paths are affected.
WHat should happen:
We should probably create the zip writer over the response writer (
zw := zip.NewWriter(c.Writer)) after settingContent-Type: application/zipandContent-Disposition, write entries, thenzw.Close().Steps to Reproduce
User-role account, upload (or pull from a flow container) a directory of incompressible data.ZipResources/ZipDirectory/ZipRelativePathswith abytes.Buffer; resident heap grows to roughly the archive size before the response starts.A standalone harness that calls the real
ZipResourceswith abytes.Buffersink shows heap growth proportional to archive size (≈32 MiB incompressible input → ≈33.5 MiB ZIP → ≈105 MiB max heap) and crashes with a runtime OOM under a constrainedulimit -v, with the stack going throughbytes.growSlice→bytes.(*Buffer).Write→archive/zip→io.Copy→resources.ZipResources.System Configuration
Logs and Artifacts
No response
Screenshots or Recordings
No response
Verification