From 2ad19b99f9960609365e800d01daa4e858fc718d Mon Sep 17 00:00:00 2001 From: Louis Chmn Date: Thu, 9 Oct 2025 17:44:07 +0200 Subject: [PATCH] fix(S3): Only append streams if non-seekable Later, when we rewind the stream in `writeMultiPart` during retry, both streams were rewinded, so the resulting stream was bigger than expected. Inspired by https://github.com/aws/aws-sdk-php/blob/master/src/S3/ObjectUploader.php#L136-L146 Signed-off-by: Louis Chmn --- lib/private/Files/ObjectStore/S3ObjectTrait.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php index 89405de2e8e..9362609fa5a 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -222,7 +222,19 @@ trait S3ObjectTrait { // buffer is fully seekable, so use it directly for the small upload $this->writeSingle($urn, $buffer, $metaData); } else { - $loadStream = new Psr7\AppendStream([$buffer, $psrStream]); + if ($psrStream->isSeekable()) { + // If the body is seekable, just rewind the body. + $psrStream->rewind(); + $loadStream = $psrStream; + } else { + // If the body is non-seekable, stitch the rewind the buffer and + // the partially read body together into one stream. This avoids + // unnecessary disk usage and does not require seeking on the + // original stream. + $buffer->rewind(); + $loadStream = new Psr7\AppendStream([$buffer, $psrStream]); + } + $this->writeMultiPart($urn, $loadStream, $metaData); } } else {