api response preparing

This commit is contained in:
Yuri Kuznetsov
2023-02-18 11:42:04 +02:00
parent e7b914ff4b
commit 1032b73b85
6 changed files with 102 additions and 42 deletions
@@ -122,31 +122,6 @@ class Attachment extends RecordBase
->getValueMap();
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws NotFound
*/
public function getActionFile(Request $request, Response $response): void
{
$id = $request->getRouteParam('id');
if (!$id) {
throw new BadRequest();
}
$fileData = $this->getAttachmentService()->getFileData($id);
if ($fileData->getType()) {
$response->setHeader('Content-Type', $fileData->getType());
}
$response
->setHeader('Content-Disposition', 'attachment; filename="' . $fileData->getName() . '"')
->setHeader('Content-Length', (string) $fileData->getSize())
->setBody($fileData->getStream());
}
/**
* @throws BadRequest
* @throws Forbidden
+22 -8
View File
@@ -34,6 +34,7 @@ use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Utils\Config;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ResponseInterface as Psr7Response;
use Psr\Http\Message\ServerRequestInterface;
@@ -49,7 +50,8 @@ class ActionHandler implements RequestHandlerInterface
public function __construct(
private Action $action,
private ProcessData $processData
private ProcessData $processData,
private Config $config
) {}
/**
@@ -73,15 +75,27 @@ class ActionHandler implements RequestHandlerInterface
private function prepareResponse(Response $response): Psr7Response
{
$psr7Response = $response instanceof ResponseWrapper ?
$response->toPsr7() :
self::responseToPsr7($response);
if (!$psr7Response->getHeader('Content-Type')) {
$psr7Response = $psr7Response->withHeader('Content-Type', self::DEFAULT_CONTENT_TYPE);
if (!$response->hasHeader('Content-Type')) {
$response->setHeader('Content-Type', self::DEFAULT_CONTENT_TYPE);
}
return $psr7Response;
if (!$response->hasHeader('Cache-Control')) {
$response->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
}
if (!$response->hasHeader('Expires')) {
$response->setHeader('Expires', '0');
}
if (!$response->hasHeader('Last-Modified')) {
$response->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
}
$response->setHeader('X-App-Timestamp', (string) ($this->config->get('appTimestamp') ?? '0'));
return $response instanceof ResponseWrapper ?
$response->toPsr7() :
self::responseToPsr7($response);
}
private static function responseToPsr7(Response $response): Psr7Response
+11 -5
View File
@@ -41,13 +41,19 @@ class ResponseComposer
* @param array<string|int, mixed>|stdClass|scalar|null $data A data to encode.
*/
public static function json(mixed $data): Response
{
return self::empty()
->writeBody(Json::encode($data))
->setHeader('Content-Type', 'application/json');
}
/**
* Compose an empty response.
*/
public static function empty(): Response
{
$psr7Response = (new ResponseFactory())->createResponse();
$response = new ResponseWrapper($psr7Response);
$response->writeBody(Json::encode($data));
$response->setHeader('Content-Type', 'application/json');
return $response;
return new ResponseWrapper($psr7Response);
}
}
@@ -167,6 +167,7 @@ class RouteProcessor
$handler = new ActionHandler(
action: $action,
processData: $processData,
config: $this->config,
);
$dispatcher = new MiddlewareDispatcher($handler);
+1 -4
View File
@@ -271,10 +271,7 @@
{
"route": "/Attachment/file/:id",
"method": "get",
"params": {
"controller": "Attachment",
"action": "file"
}
"actionClassName": "Espo\\Tools\\Attachment\\Api\\GetFile"
},
{
"route": "/Attachment/chunk/:id",
@@ -0,0 +1,67 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Tools\Attachment\Api;
use Espo\Core\Api\Action as ActionAlias;
use Espo\Core\Api\Request;
use Espo\Core\Api\Response;
use Espo\Core\Api\ResponseComposer;
use Espo\Core\Exceptions\BadRequest;
use Espo\Tools\Attachment\Service;
/**
* Download a file.
*/
class GetFile implements ActionAlias
{
public function __construct(private Service $service) {}
public function process(Request $request): Response
{
$id = $request->getRouteParam('id');
if (!$id) {
throw new BadRequest();
}
$fileData = $this->service->getFileData($id);
$response = ResponseComposer::empty()
->setHeader('Content-Disposition', 'attachment; filename="' . $fileData->getName() . '"')
->setHeader('Content-Length', (string) $fileData->getSize())
->setBody($fileData->getStream());
if ($fileData->getType()) {
$response->setHeader('Content-Type', $fileData->getType());
}
return $response;
}
}