-
Notifications
You must be signed in to change notification settings - Fork 76
Open
Description
Summary
- Extension:
beechit/fal-securedownload - TYPO3 version: 12 LTS
- PHP version: 8.2
- Storage driver: Local file system
- Issue: Enabling the “resumable download” option corrupts binary file delivery (e.g.,
.xls)
Steps to Reproduce
- Install/enable
fal_securedownloadon a TYPO3 v12 site. - Set
EXTENSIONS > fal_securedownload > resumable_download = 1. - Protect a binary file (e.g.,
.xls) and request it viaindex.php?eID=dumpFile&f=...&token=.... - Open the downloaded file in the corresponding application (Excel).
Expected Result
- TYPO3 returns the file through a PSR-7
ResponseInterface, with correctContent-Type,Content-Disposition, andContent-Length. - The file opens without errors or “repaired file” warnings.
Actual Result
- The response is generated via manual
header()/printoutput inModifyFileDumpEventListener::dumpFileContents(). - Downloads contain corrupt bytes; Excel reports “file was repaired” and strips formatting.
- Curl traces show inconsistencies in
Content-Lengthand leading bytes compared to the original file.
Environment Details
- TYPO3: 12.4.37
fal_securedownload: 5.0.7- PHP: 8.2.x FPM
- Web server: Apache/2.4.59
- Compression:
zlib.output_compressionoff
Workaround
- Set
resumable_download = 0, which forces TYPO3 to use the corestreamFile()response and resolves the corruption.
Suspected Root Cause
- The resumable branch bypasses TYPO3’s PSR-7 streaming:
- Manually emits headers (
header(),Content-Length,Accept-Ranges). - Uses
ob_clean(),while (ob_get_level()) { ob_end_clean(); },fread()loop, andprint. - Calls
exit, preventing further middleware cleanup.
- Manually emits headers (
- Any earlier output (BOM/whitespace/cookies) or header injection results in file corruption.
Proposed Fix / Ideas
- Replace the manual streaming logic with a PSR-7 compliant implementation:
- Use
$event->setResponse($streamingResponse)with aStreamInterfacethat supports ranges. - Avoid direct
header()calls; rely onResponseInterface::withHeader. - Remove global
exitusage and depend on the event response.
- Use
- Alternatively, disable resumables by default until a PSR-7 approach is implemented.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels