diff --git a/apps/files_external/lib/Lib/Backend/AmazonS3.php b/apps/files_external/lib/Lib/Backend/AmazonS3.php index ea518df12e727..606aee0b09d8b 100644 --- a/apps/files_external/lib/Lib/Backend/AmazonS3.php +++ b/apps/files_external/lib/Lib/Backend/AmazonS3.php @@ -27,6 +27,8 @@ public function __construct(IL10N $l, AccessKey $legacyAuth) { ->setFlag(DefinitionParameter::FLAG_OPTIONAL), (new DefinitionParameter('port', $l->t('Port'))) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('proxy', $l->t('Proxy'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), (new DefinitionParameter('region', $l->t('Region'))) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), (new DefinitionParameter('storageClass', $l->t('Storage Class'))) @@ -41,6 +43,9 @@ public function __construct(IL10N $l, AccessKey $legacyAuth) { (new DefinitionParameter('useMultipartCopy', $l->t('Enable multipart copy'))) ->setType(DefinitionParameter::VALUE_BOOLEAN) ->setDefaultValue(true), + (new DefinitionParameter('use_presigned_url', $l->t('Use presigned S3 url'))) + ->setType(DefinitionParameter::VALUE_BOOLEAN) + ->setDefaultValue(false), (new DefinitionParameter('sse_c_key', $l->t('SSE-C encryption key'))) ->setType(DefinitionParameter::VALUE_PASSWORD) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), diff --git a/apps/files_external/lib/Lib/Storage/AmazonS3.php b/apps/files_external/lib/Lib/Storage/AmazonS3.php index 1a866e8c22bf2..ef43939191fd2 100644 --- a/apps/files_external/lib/Lib/Storage/AmazonS3.php +++ b/apps/files_external/lib/Lib/Storage/AmazonS3.php @@ -21,6 +21,7 @@ use OCP\ICache; use OCP\ICacheFactory; use OCP\Server; +use Override; use Psr\Log\LoggerInterface; class AmazonS3 extends Common { @@ -755,4 +756,44 @@ public function writeStream(string $path, $stream, ?int $size = null): int { return $size; } + + #[Override] + public function getDirectDownload(string $path): array|false { + if (!$this->isUsePresignedUrl()) { + return false; + } + + $command = $this->getConnection()->getCommand('GetObject', [ + 'Bucket' => $this->bucket, + 'Key' => $path, + ]); + $expiration = new \DateTimeImmutable('+60 minutes'); + + try { + // generate a presigned URL that expires after $expiration time + $presignedUrl = (string)$this->getConnection()->createPresignedRequest($command, $expiration, [ + 'signPayload' => true, + ])->getUri(); + } catch (S3Exception $exception) { + $this->logger->error($exception->getMessage(), [ + 'app' => 'files_external', + 'exception' => $exception, + ]); + return false; + } + return [ + 'url' => $presignedUrl, + 'expiration' => $expiration->getTimestamp(), + ]; + } + + #[Override] + public function getDirectDownloadById(string $fileId): array|false { + if (!$this->isUsePresignedUrl()) { + return false; + } + + $entry = $this->getCache()->get((int)$fileId); + return $this->getDirectDownload($entry->getPath()); + } } diff --git a/lib/private/Preview/Movie.php b/lib/private/Preview/Movie.php index 00192674a6403..9e312c6176b34 100644 --- a/lib/private/Preview/Movie.php +++ b/lib/private/Preview/Movie.php @@ -53,6 +53,23 @@ public function isAvailable(FileInfo $file): bool { return is_string($this->binary); } + private function connectDirect(File $file): string|false { + if ($file->isEncrypted()) { + return false; + } + + // Checks for availability to access the video file directly via HTTP/HTTPS. + // Returns a string containing URL if available. Only implemented and tested + // with Amazon S3 currently. In all other cases, return false. ffmpeg + // supports other protocols so this function may expand in the future. + $gddValues = $file->getStorage()->getDirectDownloadById((string)$file->getId()); + + if (is_array($gddValues) && array_key_exists('url', $gddValues)) { + return str_starts_with($gddValues['url'], 'http') ? $gddValues['url'] : false; + } + return false; + } + /** * {@inheritDoc} */