diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index ee6e3fbd..5e3dad77 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -743,7 +743,7 @@ public function saveOutputFile(string $userId, int $ocpTaskId, int $fileId): arr * @throws NotPermittedException */ private function getTargetFileName(File $file): string { - $mimeType = mime_content_type($file->fopen('rb')); + $mimeType = $this->detectMimeType($file->fopen('rb')); $fileName = $file->getName(); $mimes = new \Mimey\MimeTypes; @@ -755,6 +755,29 @@ private function getTargetFileName(File $file): string { return $fileName; } + /** + * Wraps mime_content_type() to avoid a PHP warning when given a stream + * that does not implement stream_cast() (e.g. Icewind\Streams\CallbackWrapper, + * returned by File::fopen() for some storage backends). The stream is + * drained into a temp file first so mime_content_type() can operate on a + * real path instead of the unsupported stream resource. + * + * @param resource $stream + * @return string|false + */ + private function detectMimeType($stream) { + $tmpFile = tempnam(sys_get_temp_dir(), 'nc_assistant_mime_'); + $tmpHandle = fopen($tmpFile, 'wb'); + stream_copy_to_stream($stream, $tmpHandle); + fclose($tmpHandle); + if (is_resource($stream)) { + fclose($stream); + } + $mimeType = mime_content_type($tmpFile); + unlink($tmpFile); + return $mimeType; + } + /** * @param Task $task * @return array @@ -807,7 +830,7 @@ private function extractFileIdsFromTask(Task $task): array { */ public function getOutputFilePreviewFile(string $userId, int $taskId, int $fileId, ?int $x = 100, ?int $y = 100): ?array { $taskOutputFile = $this->getTaskOutputFile($userId, $taskId, $fileId); - $realMime = mime_content_type($taskOutputFile->fopen('rb')); + $realMime = $this->detectMimeType($taskOutputFile->fopen('rb')); return $this->previewService->getFilePreviewFile($taskOutputFile, $x, $y, $realMime ?: null); }