Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions core/Controller/TaskProcessingApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\Attribute\UserRateLimit;
use OCP\AppFramework\Http\DataDownloadResponse;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\StreamResponse;
use OCP\Files\File;
use OCP\Files\GenericFileException;
use OCP\Files\IAppData;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IRootFolder;
use OCP\Files\NotPermittedException;
use OCP\IL10N;
Expand Down Expand Up @@ -54,6 +54,7 @@ public function __construct(
private ?string $userId,
private IRootFolder $rootFolder,
private IAppData $appData,
private IMimeTypeDetector $mimeTypeDetector,
) {
parent::__construct($appName, $request);
}
Expand Down Expand Up @@ -300,20 +301,22 @@ public function listTasks(?string $taskType, ?string $customId = null): DataResp
*
* @param int $taskId The id of the task
* @param int $fileId The file id of the file to retrieve
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
* @return StreamResponse<Http::STATUS_OK, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
*
* 200: File content returned
* 404: Task or file not found
*/
#[NoAdminRequired]
#[Http\Attribute\NoCSRFRequired]
#[ApiRoute(verb: 'GET', url: '/tasks/{taskId}/file/{fileId}', root: '/taskprocessing')]
public function getFileContents(int $taskId, int $fileId): Http\DataDownloadResponse|DataResponse {
public function getFileContents(int $taskId, int $fileId): StreamResponse|DataResponse {
try {
$task = $this->taskProcessingManager->getUserTask($taskId, $this->userId);
return $this->getFileContentsInternal($task, $fileId);
} catch (NotFoundException) {
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
} catch (LockedException) {
return new DataResponse(['message' => $this->l->t('Node is locked')], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (Exception) {
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
}
Expand All @@ -324,19 +327,21 @@ public function getFileContents(int $taskId, int $fileId): Http\DataDownloadResp
*
* @param int $taskId The id of the task
* @param int $fileId The file id of the file to retrieve
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
* @return StreamResponse<Http::STATUS_OK, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
*
* 200: File content returned
* 404: Task or file not found
*/
#[ExAppRequired]
#[ApiRoute(verb: 'GET', url: '/tasks_provider/{taskId}/file/{fileId}', root: '/taskprocessing')]
public function getFileContentsExApp(int $taskId, int $fileId): Http\DataDownloadResponse|DataResponse {
public function getFileContentsExApp(int $taskId, int $fileId): StreamResponse|DataResponse {
try {
$task = $this->taskProcessingManager->getTask($taskId);
return $this->getFileContentsInternal($task, $fileId);
} catch (NotFoundException) {
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
} catch (LockedException) {
return new DataResponse(['message' => $this->l->t('Node is locked')], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (Exception) {
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
}
Expand Down Expand Up @@ -379,12 +384,11 @@ public function setFileContentsExApp(int $taskId): DataResponse {
/**
* @throws NotPermittedException
* @throws NotFoundException
* @throws GenericFileException
* @throws LockedException
*
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
* @return StreamResponse<Http::STATUS_OK, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
*/
private function getFileContentsInternal(Task $task, int $fileId): Http\DataDownloadResponse|DataResponse {
private function getFileContentsInternal(Task $task, int $fileId): StreamResponse|DataResponse {
$ids = $this->extractFileIdsFromTask($task);
if (!in_array($fileId, $ids)) {
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
Expand All @@ -401,7 +405,25 @@ private function getFileContentsInternal(Task $task, int $fileId): Http\DataDown
} elseif (!$node instanceof File) {
throw new NotFoundException('Node is not a file');
}
return new Http\DataDownloadResponse($node->getContent(), $node->getName(), $node->getMimeType());

$contentType = $node->getMimeType();
if (function_exists('mime_content_type')) {
$mimeType = mime_content_type($node->fopen('rb'));
if ($mimeType !== false) {
$mimeType = $this->mimeTypeDetector->getSecureMimeType($mimeType);
if ($mimeType !== 'application/octet-stream') {
$contentType = $mimeType;
}
}
}

$response = new StreamResponse($node->fopen('rb'));
$response->addHeader(
'Content-Disposition',
'attachment; filename="' . rawurldecode($node->getName()) . '"'
);
$response->addHeader('Content-Type', $contentType);
return $response;
}

/**
Expand Down
Loading