diff --git a/apps/files_external/lib/Lib/Storage/AmazonS3.php b/apps/files_external/lib/Lib/Storage/AmazonS3.php index 4da56c9527d9b..22a9b28717f4d 100644 --- a/apps/files_external/lib/Lib/Storage/AmazonS3.php +++ b/apps/files_external/lib/Lib/Storage/AmazonS3.php @@ -1,7 +1,7 @@ */ private CappedMemoryCache $objectCache; @@ -77,6 +73,10 @@ private function isRoot(string $path): bool { return $path === '.'; } + public function needsPartFile(): bool { + return false; + } + private function cleanKey(string $path): string { if ($this->isRoot($path)) { return '/'; @@ -90,24 +90,28 @@ private function clearCache(): void { $this->filesCache = new CappedMemoryCache(); } - private function invalidateCache(string $key): void { - unset($this->objectCache[$key]); - $keys = array_keys($this->objectCache->getData()); - $keyLength = strlen($key); - foreach ($keys as $existingKey) { - if (substr($existingKey, 0, $keyLength) === $key) { - unset($this->objectCache[$existingKey]); - } + private function invalidateCache(string $prefix): void { + if ($prefix === '') { + return; // or throw InvalidArgumentException? } - unset($this->filesCache[$key]); - $keys = array_keys($this->directoryCache->getData()); - $keyLength = strlen($key); + + $this->invalidateByPrefix($this->objectCache, $prefix); + $this->invalidateByPrefix($this->directoryCache, $prefix); + + // FILES: exact match keys only (not hierarchical) + unset($this->filesCache[$prefix]); + } + + private function invalidateByPrefix(CappedMemoryCache $cache, string $prefix): void { + $keys = array_keys($cache->getData()); + $descendantPrefix = rtrim($prefix, '/') . '/'; + foreach ($keys as $existingKey) { - if (substr($existingKey, 0, $keyLength) === $key) { - unset($this->directoryCache[$existingKey]); + // exact + normalized prefix matched keys + if ($existingKey === $prefix || str_starts_with($existingKey, $descendantPrefix)) { + unset($cache[$existingKey]); } } - unset($this->directoryCache[$key]); } private function headObject(string $key): array|false {