Skip to content

Commit ff49774

Browse files
authored
Merge pull request #53290 from nextcloud/backport/53277/stable31
[stable31] fix(TaskProcessingApiController): use StreamResponse to return file content
2 parents b00e21d + 6238590 commit ff49774

1 file changed

Lines changed: 32 additions & 10 deletions

File tree

core/Controller/TaskProcessingApiController.php

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
2020
use OCP\AppFramework\Http\Attribute\PublicPage;
2121
use OCP\AppFramework\Http\Attribute\UserRateLimit;
22-
use OCP\AppFramework\Http\DataDownloadResponse;
2322
use OCP\AppFramework\Http\DataResponse;
23+
use OCP\AppFramework\Http\StreamResponse;
2424
use OCP\Files\File;
25-
use OCP\Files\GenericFileException;
2625
use OCP\Files\IAppData;
26+
use OCP\Files\IMimeTypeDetector;
2727
use OCP\Files\IRootFolder;
2828
use OCP\Files\NotPermittedException;
2929
use OCP\IL10N;
@@ -54,6 +54,7 @@ public function __construct(
5454
private ?string $userId,
5555
private IRootFolder $rootFolder,
5656
private IAppData $appData,
57+
private IMimeTypeDetector $mimeTypeDetector,
5758
) {
5859
parent::__construct($appName, $request);
5960
}
@@ -300,20 +301,22 @@ public function listTasks(?string $taskType, ?string $customId = null): DataResp
300301
*
301302
* @param int $taskId The id of the task
302303
* @param int $fileId The file id of the file to retrieve
303-
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
304+
* @return StreamResponse<Http::STATUS_OK, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
304305
*
305306
* 200: File content returned
306307
* 404: Task or file not found
307308
*/
308309
#[NoAdminRequired]
309310
#[Http\Attribute\NoCSRFRequired]
310311
#[ApiRoute(verb: 'GET', url: '/tasks/{taskId}/file/{fileId}', root: '/taskprocessing')]
311-
public function getFileContents(int $taskId, int $fileId): Http\DataDownloadResponse|DataResponse {
312+
public function getFileContents(int $taskId, int $fileId): StreamResponse|DataResponse {
312313
try {
313314
$task = $this->taskProcessingManager->getUserTask($taskId, $this->userId);
314315
return $this->getFileContentsInternal($task, $fileId);
315316
} catch (NotFoundException) {
316317
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
318+
} catch (LockedException) {
319+
return new DataResponse(['message' => $this->l->t('Node is locked')], Http::STATUS_INTERNAL_SERVER_ERROR);
317320
} catch (Exception) {
318321
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
319322
}
@@ -324,19 +327,21 @@ public function getFileContents(int $taskId, int $fileId): Http\DataDownloadResp
324327
*
325328
* @param int $taskId The id of the task
326329
* @param int $fileId The file id of the file to retrieve
327-
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
330+
* @return StreamResponse<Http::STATUS_OK, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
328331
*
329332
* 200: File content returned
330333
* 404: Task or file not found
331334
*/
332335
#[ExAppRequired]
333336
#[ApiRoute(verb: 'GET', url: '/tasks_provider/{taskId}/file/{fileId}', root: '/taskprocessing')]
334-
public function getFileContentsExApp(int $taskId, int $fileId): Http\DataDownloadResponse|DataResponse {
337+
public function getFileContentsExApp(int $taskId, int $fileId): StreamResponse|DataResponse {
335338
try {
336339
$task = $this->taskProcessingManager->getTask($taskId);
337340
return $this->getFileContentsInternal($task, $fileId);
338341
} catch (NotFoundException) {
339342
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
343+
} catch (LockedException) {
344+
return new DataResponse(['message' => $this->l->t('Node is locked')], Http::STATUS_INTERNAL_SERVER_ERROR);
340345
} catch (Exception) {
341346
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
342347
}
@@ -379,12 +384,11 @@ public function setFileContentsExApp(int $taskId): DataResponse {
379384
/**
380385
* @throws NotPermittedException
381386
* @throws NotFoundException
382-
* @throws GenericFileException
383387
* @throws LockedException
384388
*
385-
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
389+
* @return StreamResponse<Http::STATUS_OK, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
386390
*/
387-
private function getFileContentsInternal(Task $task, int $fileId): Http\DataDownloadResponse|DataResponse {
391+
private function getFileContentsInternal(Task $task, int $fileId): StreamResponse|DataResponse {
388392
$ids = $this->extractFileIdsFromTask($task);
389393
if (!in_array($fileId, $ids)) {
390394
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
@@ -401,7 +405,25 @@ private function getFileContentsInternal(Task $task, int $fileId): Http\DataDown
401405
} elseif (!$node instanceof File) {
402406
throw new NotFoundException('Node is not a file');
403407
}
404-
return new Http\DataDownloadResponse($node->getContent(), $node->getName(), $node->getMimeType());
408+
409+
$contentType = $node->getMimeType();
410+
if (function_exists('mime_content_type')) {
411+
$mimeType = mime_content_type($node->fopen('rb'));
412+
if ($mimeType !== false) {
413+
$mimeType = $this->mimeTypeDetector->getSecureMimeType($mimeType);
414+
if ($mimeType !== 'application/octet-stream') {
415+
$contentType = $mimeType;
416+
}
417+
}
418+
}
419+
420+
$response = new StreamResponse($node->fopen('rb'));
421+
$response->addHeader(
422+
'Content-Disposition',
423+
'attachment; filename="' . rawurldecode($node->getName()) . '"'
424+
);
425+
$response->addHeader('Content-Type', $contentType);
426+
return $response;
405427
}
406428

407429
/**

0 commit comments

Comments
 (0)