From b0001c6010840362355c181b831b4517ac19b8fc Mon Sep 17 00:00:00 2001 From: jld3103 Date: Wed, 14 Jun 2023 08:56:42 +0200 Subject: [PATCH] Add template types to responses Signed-off-by: jld3103 --- lib/private/AppFramework/OCS/BaseResponse.php | 10 ++- lib/private/AppFramework/OCS/V1Response.php | 9 +++ lib/private/AppFramework/OCS/V2Response.php | 9 +++ .../AppFramework/Http/DataDisplayResponse.php | 15 ++-- .../Http/DataDownloadResponse.php | 15 +++- lib/public/AppFramework/Http/DataResponse.php | 26 ++++--- .../AppFramework/Http/DownloadResponse.php | 15 +++- .../AppFramework/Http/FileDisplayResponse.php | 21 +++--- lib/public/AppFramework/Http/JSONResponse.php | 23 ++++--- .../AppFramework/Http/NotFoundResponse.php | 13 +++- .../AppFramework/Http/RedirectResponse.php | 11 ++- .../Http/RedirectToDefaultAppResponse.php | 11 ++- lib/public/AppFramework/Http/Response.php | 68 +++++++++++-------- .../Http/StandaloneTemplateResponse.php | 4 ++ .../AppFramework/Http/StreamResponse.php | 10 ++- .../Http/Template/PublicTemplateResponse.php | 11 ++- .../AppFramework/Http/TemplateResponse.php | 14 +++- .../AppFramework/Http/TextPlainResponse.php | 12 ++-- .../Http/TooManyRequestsResponse.php | 12 +++- lib/public/AppFramework/Http/ZipResponse.php | 11 ++- tests/lib/AppFramework/Http/ResponseTest.php | 5 +- 21 files changed, 229 insertions(+), 96 deletions(-) diff --git a/lib/private/AppFramework/OCS/BaseResponse.php b/lib/private/AppFramework/OCS/BaseResponse.php index 533cff74a3007..123b73d302c6f 100644 --- a/lib/private/AppFramework/OCS/BaseResponse.php +++ b/lib/private/AppFramework/OCS/BaseResponse.php @@ -7,6 +7,7 @@ * @author Joas Schilling * @author Lukas Reschke * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -30,6 +31,13 @@ use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\Response; +/** + * @psalm-import-type DataResponseType from DataResponse + * @template S of int + * @template-covariant T of DataResponseType + * @template H of array + * @template-extends Response> + */ abstract class BaseResponse extends Response { /** @var array */ protected $data; @@ -49,7 +57,7 @@ abstract class BaseResponse extends Response { /** * BaseResponse constructor. * - * @param DataResponse $dataResponse + * @param DataResponse $dataResponse * @param string $format * @param string|null $statusMessage * @param int|null $itemsCount diff --git a/lib/private/AppFramework/OCS/V1Response.php b/lib/private/AppFramework/OCS/V1Response.php index cca3c267ec483..e6b0165278999 100644 --- a/lib/private/AppFramework/OCS/V1Response.php +++ b/lib/private/AppFramework/OCS/V1Response.php @@ -5,6 +5,7 @@ * @author Christoph Wurst * @author Joas Schilling * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -25,8 +26,16 @@ namespace OC\AppFramework\OCS; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; +/** + * @psalm-import-type DataResponseType from DataResponse + * @template S of int + * @template-covariant T of DataResponseType + * @template H of array + * @template-extends BaseResponse> + */ class V1Response extends BaseResponse { /** * The V1 endpoint has very limited http status codes basically everything diff --git a/lib/private/AppFramework/OCS/V2Response.php b/lib/private/AppFramework/OCS/V2Response.php index 8bf4c37a5787b..1e81a3c7d938c 100644 --- a/lib/private/AppFramework/OCS/V2Response.php +++ b/lib/private/AppFramework/OCS/V2Response.php @@ -4,6 +4,7 @@ * * @author Christoph Wurst * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -24,8 +25,16 @@ namespace OC\AppFramework\OCS; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; +/** + * @psalm-import-type DataResponseType from DataResponse + * @template S of int + * @template-covariant T of DataResponseType + * @template H of array + * @template-extends BaseResponse> + */ class V2Response extends BaseResponse { /** * The V2 endpoint just passes on status codes. diff --git a/lib/public/AppFramework/Http/DataDisplayResponse.php b/lib/public/AppFramework/Http/DataDisplayResponse.php index 78ab343abd643..be2ade50bb551 100644 --- a/lib/public/AppFramework/Http/DataDisplayResponse.php +++ b/lib/public/AppFramework/Http/DataDisplayResponse.php @@ -6,6 +6,7 @@ * @author Julius Härtl * @author Morris Jobke * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -30,6 +31,9 @@ * Class DataDisplayResponse * * @since 8.1.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class DataDisplayResponse extends Response { /** @@ -41,17 +45,14 @@ class DataDisplayResponse extends Response { /** * @param string $data the data to display - * @param int $statusCode the Http status code, defaults to 200 - * @param array $headers additional key value based headers + * @param S $statusCode the Http status code, defaults to 200 + * @param H $headers additional key value based headers * @since 8.1.0 */ - public function __construct($data = '', $statusCode = Http::STATUS_OK, - $headers = []) { - parent::__construct(); + public function __construct(string $data = '', int $statusCode = Http::STATUS_OK, array $headers = []) { + parent::__construct($statusCode, $headers); $this->data = $data; - $this->setStatus($statusCode); - $this->setHeaders(array_merge($this->getHeaders(), $headers)); $this->addHeader('Content-Disposition', 'inline; filename=""'); } diff --git a/lib/public/AppFramework/Http/DataDownloadResponse.php b/lib/public/AppFramework/Http/DataDownloadResponse.php index 7f2bc73f6e2e8..f70056047956b 100644 --- a/lib/public/AppFramework/Http/DataDownloadResponse.php +++ b/lib/public/AppFramework/Http/DataDownloadResponse.php @@ -5,6 +5,7 @@ * @author Georg Ehrke * @author Morris Jobke * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -23,10 +24,16 @@ */ namespace OCP\AppFramework\Http; +use OCP\AppFramework\Http; + /** * Class DataDownloadResponse * * @since 8.0.0 + * @template S of int + * @template C of string + * @template H of array + * @template-extends DownloadResponse> */ class DataDownloadResponse extends DownloadResponse { /** @@ -38,12 +45,14 @@ class DataDownloadResponse extends DownloadResponse { * Creates a response that prompts the user to download the text * @param string $data text to be downloaded * @param string $filename the name that the downloaded file should have - * @param string $contentType the mimetype that the downloaded file should have + * @param C $contentType the mimetype that the downloaded file should have + * @param S $status + * @param H $headers * @since 8.0.0 */ - public function __construct($data, $filename, $contentType) { + public function __construct(string $data, string $filename, string $contentType, int $status = Http::STATUS_OK, array $headers = []) { $this->data = $data; - parent::__construct($filename, $contentType); + parent::__construct($filename, $contentType, $status, $headers); } /** diff --git a/lib/public/AppFramework/Http/DataResponse.php b/lib/public/AppFramework/Http/DataResponse.php index e329b9c297564..1a56847d63d8e 100644 --- a/lib/public/AppFramework/Http/DataResponse.php +++ b/lib/public/AppFramework/Http/DataResponse.php @@ -6,6 +6,7 @@ * @author Christoph Wurst * @author Morris Jobke * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -30,34 +31,37 @@ * A generic DataResponse class that is used to return generic data responses * for responders to transform * @since 8.0.0 + * @psalm-type DataResponseType = array|int|float|string|bool|object|null|\stdClass|\JsonSerializable + * @template S of int + * @template-covariant T of DataResponseType + * @template H of array + * @template-extends Response> */ class DataResponse extends Response { /** * response data - * @var array|int|float|string|bool|object + * @var T */ protected $data; /** - * @param array|int|float|string|bool|object $data the object or array that should be transformed - * @param int $statusCode the Http status code, defaults to 200 - * @param array $headers additional key value based headers + * @param T $data the object or array that should be transformed + * @param S $statusCode the Http status code, defaults to 200 + * @param H $headers additional key value based headers * @since 8.0.0 */ - public function __construct($data = [], $statusCode = Http::STATUS_OK, - array $headers = []) { - parent::__construct(); + public function __construct(mixed $data = [], int $statusCode = Http::STATUS_OK, array $headers = []) { + parent::__construct($statusCode, $headers); $this->data = $data; - $this->setStatus($statusCode); - $this->setHeaders(array_merge($this->getHeaders(), $headers)); } /** * Sets values in the data json array - * @param array|int|float|string|object $data an array or object which will be transformed + * @psalm-suppress InvalidTemplateParam + * @param T $data an array or object which will be transformed * @return DataResponse Reference to this object * @since 8.0.0 */ @@ -70,7 +74,7 @@ public function setData($data) { /** * Used to get the set parameters - * @return array|int|float|string|bool|object the data + * @return T the data * @since 8.0.0 */ public function getData() { diff --git a/lib/public/AppFramework/Http/DownloadResponse.php b/lib/public/AppFramework/Http/DownloadResponse.php index b80f03958c0e8..5b3a235d4447a 100644 --- a/lib/public/AppFramework/Http/DownloadResponse.php +++ b/lib/public/AppFramework/Http/DownloadResponse.php @@ -7,6 +7,7 @@ * @author Morris Jobke * @author Roeland Jago Douma * @author Thomas Müller + * @author Kate Döen * * @license AGPL-3.0 * @@ -25,19 +26,27 @@ */ namespace OCP\AppFramework\Http; +use OCP\AppFramework\Http; + /** * Prompts the user to download the a file * @since 7.0.0 + * @template S of int + * @template C of string + * @template H of array + * @template-extends Response> */ class DownloadResponse extends Response { /** * Creates a response that prompts the user to download the file * @param string $filename the name that the downloaded file should have - * @param string $contentType the mimetype that the downloaded file should have + * @param C $contentType the mimetype that the downloaded file should have + * @param S $status + * @param H $headers * @since 7.0.0 */ - public function __construct(string $filename, string $contentType) { - parent::__construct(); + public function __construct(string $filename, string $contentType, int $status = Http::STATUS_OK, array $headers = []) { + parent::__construct($status, $headers); $filename = strtr($filename, ['"' => '\\"', '\\' => '\\\\']); diff --git a/lib/public/AppFramework/Http/FileDisplayResponse.php b/lib/public/AppFramework/Http/FileDisplayResponse.php index 41b452b555328..f194a23f1fea7 100644 --- a/lib/public/AppFramework/Http/FileDisplayResponse.php +++ b/lib/public/AppFramework/Http/FileDisplayResponse.php @@ -4,6 +4,7 @@ * * @author Christoph Wurst * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -24,31 +25,33 @@ namespace OCP\AppFramework\Http; use OCP\AppFramework\Http; +use OCP\Files\File; +use OCP\Files\SimpleFS\ISimpleFile; /** * Class FileDisplayResponse * * @since 11.0.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class FileDisplayResponse extends Response implements ICallbackResponse { - /** @var \OCP\Files\File|\OCP\Files\SimpleFS\ISimpleFile */ + /** @var File|ISimpleFile */ private $file; /** * FileDisplayResponse constructor. * - * @param \OCP\Files\File|\OCP\Files\SimpleFS\ISimpleFile $file - * @param int $statusCode - * @param array $headers + * @param File|ISimpleFile $file + * @param S $statusCode + * @param H $headers * @since 11.0.0 */ - public function __construct($file, $statusCode = Http::STATUS_OK, - $headers = []) { - parent::__construct(); + public function __construct(File|ISimpleFile $file, int $statusCode = Http::STATUS_OK, array $headers = []) { + parent::__construct($statusCode, $headers); $this->file = $file; - $this->setStatus($statusCode); - $this->setHeaders(array_merge($this->getHeaders(), $headers)); $this->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"'); $this->setETag($file->getEtag()); diff --git a/lib/public/AppFramework/Http/JSONResponse.php b/lib/public/AppFramework/Http/JSONResponse.php index d31a276167373..f600429632385 100644 --- a/lib/public/AppFramework/Http/JSONResponse.php +++ b/lib/public/AppFramework/Http/JSONResponse.php @@ -9,6 +9,7 @@ * @author Roeland Jago Douma * @author Thomas Müller * @author Thomas Tanghus + * @author Kate Döen * * @license AGPL-3.0 * @@ -32,26 +33,30 @@ /** * A renderer for JSON calls * @since 6.0.0 + * @template S of int + * @template-covariant T of array|object|\stdClass|\JsonSerializable + * @template H of array + * @template-extends Response> */ class JSONResponse extends Response { /** * response data - * @var array|object + * @var T */ protected $data; /** * constructor of JSONResponse - * @param array|object $data the object or array that should be transformed - * @param int $statusCode the Http status code, defaults to 200 + * @param T $data the object or array that should be transformed + * @param S $statusCode the Http status code, defaults to 200 + * @param H $headers * @since 6.0.0 */ - public function __construct($data = [], $statusCode = Http::STATUS_OK) { - parent::__construct(); + public function __construct(mixed $data = [], int $statusCode = Http::STATUS_OK, array $headers = []) { + parent::__construct($statusCode, $headers); $this->data = $data; - $this->setStatus($statusCode); $this->addHeader('Content-Type', 'application/json; charset=utf-8'); } @@ -68,7 +73,8 @@ public function render() { /** * Sets values in the data json array - * @param array|object $data an array or object which will be transformed + * @psalm-suppress InvalidTemplateParam + * @param T $data an array or object which will be transformed * to JSON * @return JSONResponse Reference to this object * @since 6.0.0 - return value was added in 7.0.0 @@ -81,8 +87,7 @@ public function setData($data) { /** - * Used to get the set parameters - * @return array the data + * @return T the data * @since 6.0.0 */ public function getData() { diff --git a/lib/public/AppFramework/Http/NotFoundResponse.php b/lib/public/AppFramework/Http/NotFoundResponse.php index 34b74d353db8d..d6df0f6046749 100644 --- a/lib/public/AppFramework/Http/NotFoundResponse.php +++ b/lib/public/AppFramework/Http/NotFoundResponse.php @@ -6,6 +6,7 @@ * @author Lukas Reschke * @author Morris Jobke * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -24,18 +25,24 @@ */ namespace OCP\AppFramework\Http; +use OCP\AppFramework\Http; + /** * A generic 404 response showing an 404 error page as well to the end-user * @since 8.1.0 + * @template S of int + * @template H of array + * @template-extends TemplateResponse> */ class NotFoundResponse extends TemplateResponse { /** + * @param S $status + * @param H $headers * @since 8.1.0 */ - public function __construct() { - parent::__construct('core', '404', [], 'guest'); + public function __construct(int $status = Http::STATUS_NOT_FOUND, array $headers = []) { + parent::__construct('core', '404', [], 'guest', $status, $headers); $this->setContentSecurityPolicy(new ContentSecurityPolicy()); - $this->setStatus(404); } } diff --git a/lib/public/AppFramework/Http/RedirectResponse.php b/lib/public/AppFramework/Http/RedirectResponse.php index 87853391e863f..b69161959546f 100644 --- a/lib/public/AppFramework/Http/RedirectResponse.php +++ b/lib/public/AppFramework/Http/RedirectResponse.php @@ -7,6 +7,7 @@ * @author Roeland Jago Douma * @author Thomas Müller * @author v1r0x + * @author Kate Döen * * @license AGPL-3.0 * @@ -30,6 +31,9 @@ /** * Redirects to a different URL * @since 7.0.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class RedirectResponse extends Response { private $redirectURL; @@ -37,13 +41,14 @@ class RedirectResponse extends Response { /** * Creates a response that redirects to a url * @param string $redirectURL the url to redirect to + * @param S $status + * @param H $headers * @since 7.0.0 */ - public function __construct($redirectURL) { - parent::__construct(); + public function __construct(string $redirectURL, int $status = Http::STATUS_SEE_OTHER, array $headers = []) { + parent::__construct($status, $headers); $this->redirectURL = $redirectURL; - $this->setStatus(Http::STATUS_SEE_OTHER); $this->addHeader('Location', $redirectURL); } diff --git a/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php b/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php index ad11b53637b51..7a1bfdbaf8fee 100644 --- a/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php +++ b/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php @@ -7,6 +7,7 @@ * * @author Joas Schilling * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -26,6 +27,7 @@ */ namespace OCP\AppFramework\Http; +use OCP\AppFramework\Http; use OCP\IURLGenerator; /** @@ -33,17 +35,22 @@ * * @since 16.0.0 * @deprecated 23.0.0 Use RedirectResponse() with IURLGenerator::linkToDefaultPageUrl() instead + * @template S of int + * @template H of array + * @template-extends RedirectResponse> */ class RedirectToDefaultAppResponse extends RedirectResponse { /** * Creates a response that redirects to the default app * + * @param S $status + * @param H $headers * @since 16.0.0 * @deprecated 23.0.0 Use RedirectResponse() with IURLGenerator::linkToDefaultPageUrl() instead */ - public function __construct() { + public function __construct(int $status = Http::STATUS_SEE_OTHER, array $headers = []) { /** @var IURLGenerator $urlGenerator */ $urlGenerator = \OC::$server->get(IURLGenerator::class); - parent::__construct($urlGenerator->linkToDefaultPageUrl()); + parent::__construct($urlGenerator->linkToDefaultPageUrl(), $status, $headers); } } diff --git a/lib/public/AppFramework/Http/Response.php b/lib/public/AppFramework/Http/Response.php index 152f8c4a3c5ea..d14d68d32b374 100644 --- a/lib/public/AppFramework/Http/Response.php +++ b/lib/public/AppFramework/Http/Response.php @@ -12,6 +12,7 @@ * @author Roeland Jago Douma * @author Thomas Müller * @author Thomas Tanghus + * @author Kate Döen * * @license AGPL-3.0 * @@ -41,15 +42,15 @@ * * It handles headers, HTTP status code, last modified and ETag. * @since 6.0.0 + * @template S of int + * @template H of array */ class Response { /** - * Headers - defaults to ['Cache-Control' => 'no-cache, no-store, must-revalidate'] - * @var array + * Headers + * @var H */ - private $headers = [ - 'Cache-Control' => 'no-cache, no-store, must-revalidate' - ]; + private $headers; /** @@ -61,9 +62,9 @@ class Response { /** * HTTP status code - defaults to STATUS OK - * @var int + * @var S */ - private $status = Http::STATUS_OK; + private $status; /** @@ -91,15 +92,13 @@ class Response { private $throttleMetadata = []; /** + * @param S $status + * @param H $headers * @since 17.0.0 */ - public function __construct() { - /** @var IRequest $request */ - /** - * @psalm-suppress UndefinedClass - */ - $request = \OC::$server->get(IRequest::class); - $this->addHeader("X-Request-Id", $request->getId()); + public function __construct(int $status = Http::STATUS_OK, array $headers = []) { + $this->setStatus($status); + $this->setHeaders($headers); } /** @@ -231,11 +230,14 @@ public function addHeader($name, $value) { /** * Set the headers - * @param array $headers value header pairs - * @return $this + * @template NewH as array + * @param NewH $headers value header pairs + * @psalm-this-out static + * @return static * @since 8.0.0 */ - public function setHeaders(array $headers) { + public function setHeaders(array $headers): static { + /** @psalm-suppress InvalidPropertyAssignmentValue Expected due to @psalm-this-out */ $this->headers = $headers; return $this; @@ -244,21 +246,27 @@ public function setHeaders(array $headers) { /** * Returns the set headers - * @return array the headers + * @return array{X-Request-Id: string, Cache-Control: string, Content-Security-Policy: string, Feature-Policy: string, X-Robots-Tag: string, Last-Modified?: string, ETag?: string, ...H} the headers * @since 6.0.0 */ public function getHeaders() { - $mergeWith = []; + /** @var IRequest $request */ + /** + * @psalm-suppress UndefinedClass + */ + $request = \OC::$server->get(IRequest::class); + $mergeWith = [ + 'X-Request-Id' => $request->getId(), + 'Cache-Control' => 'no-cache, no-store, must-revalidate', + 'Content-Security-Policy' => $this->getContentSecurityPolicy()->buildPolicy(), + 'Feature-Policy' => $this->getFeaturePolicy()->buildPolicy(), + 'X-Robots-Tag' => 'noindex, nofollow', + ]; if ($this->lastModified) { - $mergeWith['Last-Modified'] = - $this->lastModified->format(\DateTimeInterface::RFC2822); + $mergeWith['Last-Modified'] = $this->lastModified->format(\DateTimeInterface::RFC2822); } - $this->headers['Content-Security-Policy'] = $this->getContentSecurityPolicy()->buildPolicy(); - $this->headers['Feature-Policy'] = $this->getFeaturePolicy()->buildPolicy(); - $this->headers['X-Robots-Tag'] = 'noindex, nofollow'; - if ($this->ETag) { $mergeWith['ETag'] = '"' . $this->ETag . '"'; } @@ -279,11 +287,14 @@ public function render() { /** * Set response status - * @param int $status a HTTP status code, see also the STATUS constants - * @return Response Reference to this object + * @template NewS as int + * @param NewS $status a HTTP status code, see also the STATUS constants + * @psalm-this-out static + * @return static * @since 6.0.0 - return value was added in 7.0.0 */ - public function setStatus($status) { + public function setStatus($status): static { + /** @psalm-suppress InvalidPropertyAssignmentValue Expected due to @psalm-this-out */ $this->status = $status; return $this; @@ -338,6 +349,7 @@ public function setFeaturePolicy(EmptyFeaturePolicy $featurePolicy): self { /** * Get response status * @since 6.0.0 + * @return S */ public function getStatus() { return $this->status; diff --git a/lib/public/AppFramework/Http/StandaloneTemplateResponse.php b/lib/public/AppFramework/Http/StandaloneTemplateResponse.php index 35a48481333be..8a39dca71e3f0 100644 --- a/lib/public/AppFramework/Http/StandaloneTemplateResponse.php +++ b/lib/public/AppFramework/Http/StandaloneTemplateResponse.php @@ -6,6 +6,7 @@ * @copyright Copyright (c) 2019, Roeland Jago Douma * * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -32,6 +33,9 @@ * full nextcloud UI. Like the 2FA page, or the grant page in the login flow. * * @since 16.0.0 + * @template S of int + * @template H of array + * @template-extends TemplateResponse> */ class StandaloneTemplateResponse extends TemplateResponse { } diff --git a/lib/public/AppFramework/Http/StreamResponse.php b/lib/public/AppFramework/Http/StreamResponse.php index 25ad37e5d9a22..14394383ba1bd 100644 --- a/lib/public/AppFramework/Http/StreamResponse.php +++ b/lib/public/AppFramework/Http/StreamResponse.php @@ -8,6 +8,7 @@ * @author Morris Jobke * @author Robin Appelman * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -32,6 +33,9 @@ * Class StreamResponse * * @since 8.1.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class StreamResponse extends Response implements ICallbackResponse { /** @var string */ @@ -39,10 +43,12 @@ class StreamResponse extends Response implements ICallbackResponse { /** * @param string|resource $filePath the path to the file or a file handle which should be streamed + * @param S $status + * @param H $headers * @since 8.1.0 */ - public function __construct($filePath) { - parent::__construct(); + public function __construct(mixed $filePath, int $status = Http::STATUS_OK, array $headers = []) { + parent::__construct($status, $headers); $this->filePath = $filePath; } diff --git a/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php b/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php index 1196c90935dd0..def25d01c5193 100644 --- a/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php +++ b/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php @@ -5,6 +5,7 @@ * @author Christoph Wurst * @author Julius Härtl * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -25,12 +26,16 @@ namespace OCP\AppFramework\Http\Template; use InvalidArgumentException; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\TemplateResponse; /** * Class PublicTemplateResponse * * @since 14.0.0 + * @template H of array + * @template S of int + * @template-extends TemplateResponse> */ class PublicTemplateResponse extends TemplateResponse { private $headerTitle = ''; @@ -44,10 +49,12 @@ class PublicTemplateResponse extends TemplateResponse { * @param string $appName * @param string $templateName * @param array $params + * @param S $status + * @param H $headers * @since 14.0.0 */ - public function __construct(string $appName, string $templateName, array $params = []) { - parent::__construct($appName, $templateName, $params, 'public'); + public function __construct(string $appName, string $templateName, array $params = [], $status = Http::STATUS_OK, array $headers = []) { + parent::__construct($appName, $templateName, $params, 'public', $status, $headers); \OC_Util::addScript('core', 'public/publicpage'); } diff --git a/lib/public/AppFramework/Http/TemplateResponse.php b/lib/public/AppFramework/Http/TemplateResponse.php index 48097674fdf20..0364ba10e505b 100644 --- a/lib/public/AppFramework/Http/TemplateResponse.php +++ b/lib/public/AppFramework/Http/TemplateResponse.php @@ -10,6 +10,7 @@ * @author Roeland Jago Douma * @author Thomas Müller * @author Thomas Tanghus + * @author Kate Döen * * @license AGPL-3.0 * @@ -28,9 +29,15 @@ */ namespace OCP\AppFramework\Http; +use OCP\AppFramework\Http; + /** * Response for a normal template * @since 6.0.0 + * + * @template S of int + * @template H of array + * @template-extends Response> */ class TemplateResponse extends Response { /** @@ -98,11 +105,12 @@ class TemplateResponse extends Response { * @param array $params an array of parameters which should be passed to the * template * @param string $renderAs how the page should be rendered, defaults to user + * @param S $status + * @param H $headers * @since 6.0.0 - parameters $params and $renderAs were added in 7.0.0 */ - public function __construct($appName, $templateName, array $params = [], - $renderAs = self::RENDER_AS_USER) { - parent::__construct(); + public function __construct(string $appName, string $templateName, array $params = [], string $renderAs = self::RENDER_AS_USER, int $status = Http::STATUS_OK, array $headers = []) { + parent::__construct($status, $headers); $this->templateName = $templateName; $this->appName = $appName; diff --git a/lib/public/AppFramework/Http/TextPlainResponse.php b/lib/public/AppFramework/Http/TextPlainResponse.php index 93edf70486301..7bcd353e10212 100644 --- a/lib/public/AppFramework/Http/TextPlainResponse.php +++ b/lib/public/AppFramework/Http/TextPlainResponse.php @@ -6,6 +6,7 @@ * @copyright 2021 Lukas Reschke * * @author 2021 Lukas Reschke + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -30,6 +31,9 @@ /** * A renderer for text responses * @since 22.0.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class TextPlainResponse extends Response { /** @var string */ @@ -38,14 +42,14 @@ class TextPlainResponse extends Response { /** * constructor of TextPlainResponse * @param string $text The text body - * @param int $statusCode the Http status code, defaults to 200 + * @param S $statusCode the Http status code, defaults to 200 + * @param H $headers * @since 22.0.0 */ - public function __construct(string $text = '', int $statusCode = Http::STATUS_OK) { - parent::__construct(); + public function __construct(string $text = '', int $statusCode = Http::STATUS_OK, array $headers = []) { + parent::__construct($statusCode, $headers); $this->text = $text; - $this->setStatus($statusCode); $this->addHeader('Content-Type', 'text/plain'); } diff --git a/lib/public/AppFramework/Http/TooManyRequestsResponse.php b/lib/public/AppFramework/Http/TooManyRequestsResponse.php index caf565ee954eb..043ae0161e957 100644 --- a/lib/public/AppFramework/Http/TooManyRequestsResponse.php +++ b/lib/public/AppFramework/Http/TooManyRequestsResponse.php @@ -6,6 +6,7 @@ * @copyright Copyright (c) 2020 Joas Schilling * * @author Joas Schilling + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -26,20 +27,25 @@ namespace OCP\AppFramework\Http; use OCP\Template; +use OCP\AppFramework\Http; /** * A generic 429 response showing an 404 error page as well to the end-user * @since 19.0.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class TooManyRequestsResponse extends Response { /** + * @param S $status + * @param H $headers * @since 19.0.0 */ - public function __construct() { - parent::__construct(); + public function __construct(int $status = Http::STATUS_TOO_MANY_REQUESTS, array $headers = []) { + parent::__construct($status, $headers); $this->setContentSecurityPolicy(new ContentSecurityPolicy()); - $this->setStatus(429); } /** diff --git a/lib/public/AppFramework/Http/ZipResponse.php b/lib/public/AppFramework/Http/ZipResponse.php index 23e9f1f7a9455..cd7f71f858d91 100644 --- a/lib/public/AppFramework/Http/ZipResponse.php +++ b/lib/public/AppFramework/Http/ZipResponse.php @@ -9,6 +9,7 @@ * @author Jakob Sack * @author Morris Jobke * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -29,12 +30,16 @@ namespace OCP\AppFramework\Http; use OC\Streamer; +use OCP\AppFramework\Http; use OCP\IRequest; /** * Public library to send several files in one zip archive. * * @since 15.0.0 + * @template S of int + * @template H of array + * @template-extends Response> */ class ZipResponse extends Response implements ICallbackResponse { /** @var array{internalName: string, resource: resource, size: int, time: int}[] Files to be added to the zip response */ @@ -44,10 +49,12 @@ class ZipResponse extends Response implements ICallbackResponse { private IRequest $request; /** + * @param S $status + * @param H $headers * @since 15.0.0 */ - public function __construct(IRequest $request, string $name = 'output') { - parent::__construct(); + public function __construct(IRequest $request, string $name = 'output', int $status = Http::STATUS_OK, array $headers = []) { + parent::__construct($status, $headers); $this->name = $name; $this->request = $request; diff --git a/tests/lib/AppFramework/Http/ResponseTest.php b/tests/lib/AppFramework/Http/ResponseTest.php index dac4606124a1a..c1c122e789e10 100644 --- a/tests/lib/AppFramework/Http/ResponseTest.php +++ b/tests/lib/AppFramework/Http/ResponseTest.php @@ -52,13 +52,16 @@ public function testSetHeaders() { 'ETag' => 3, 'Something-Else' => 'hi', 'X-Robots-Tag' => 'noindex, nofollow', + 'Cache-Control' => 'no-cache, no-store, must-revalidate', ]; $this->childResponse->setHeaders($expected); - $headers = $this->childResponse->getHeaders(); $expected['Content-Security-Policy'] = "default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'"; $expected['Feature-Policy'] = "autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'"; + $headers = $this->childResponse->getHeaders(); + unset($headers['X-Request-Id']); + $this->assertEquals($expected, $headers); }