HTTP Resolve prefetch files can survive process exit and exhaust disk space
Description(required)
For range-capable HTTP resources, Fetcher.Resolve starts asyncPrefetch, which writes the reusable Resolve response to a named gopeed-prefetch-* temporary file.
Current main has two independent lifetime gaps:
- The named temporary file survives a crash or forced process termination.
- A completed Resolve result abandoned by a REST/UI client remains in
fetcherCache; downloader shutdown does not drain that cache.
A deterministic baseline reproduction on current main is:
TMPDIR="$(mktemp -d)" go test ./internal/protocol/http -run '^TestFetcher_Patch_Labels$' -count=1 -vThe test passes but leaves a 209,715,200-byte gopeed-prefetch-* file in TMPDIR. Repeated test runs or abandoned Resolve operations therefore accumulate large orphaned files.
Expected behavior
- No named prefetch data should survive normal close, normal process exit, or forced termination.
- Completed Resolve results that a client abandons should have an explicit, idempotent release operation.
- Downloader shutdown should drain and close all cached Resolve fetchers.
- Stopping prefetch should interrupt a blocked response-body read and wait for its worker before consuming or closing the backing storage.
Scope
This report concerns leaked/orphaned backing storage. The current one-time-URL fallback may still stage a full response while the process remains alive. A TTL, byte budget, or backpressure policy is a separate design issue: a simple hard cap would break the one-time-URL fallback that prefetch currently preserves.
Draft #1451 partially drains the Resolve cache, but it does not make prefetch storage crash-safe and includes broader unrelated changes.
App Version
Current main at 3be8db664c1f8e64e088afe69abcb12c795f63af.
OS Version
macOS
Snapshots
N/A
Log
The deterministic reproduction and leftover-file size are included above.
Source: GopeedLab/gopeed