Skip to content

Commit 3589149

Browse files
committed
Breaking change: Replace headers configured in settings.responseHeaders
- Response headers defined in `settings.responseHeaders` will no longer be merged with the previous header value, but will replace them - Add support for `settings.defaultResponseHeaders` to define headers that will be set if the response does **not** already has that header - Add CORS to the Header constants - Add visibility for the Header constants
1 parent 2a0ea1b commit 3589149

File tree

3 files changed

+71
-38
lines changed

3 files changed

+71
-38
lines changed

Classes/Dispatcher.php

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace Cundd\Rest;
55

66
use Cundd\Rest\Dispatcher\DispatcherInterface;
7+
use Cundd\Rest\Http\Header;
78
use Cundd\Rest\Http\RestRequestInterface;
89
use Cundd\Rest\Log\LoggerInterface;
910
use Cundd\Rest\Router\ResultConverter;
@@ -221,27 +222,12 @@ public static function getSharedDispatcher()
221222
*/
222223
private function addAdditionalHeaders(ResponseInterface $response)
223224
{
224-
$additionalResponseHeaders = $this->objectManager
225-
->getConfigurationProvider()
226-
->getSetting('responseHeaders', null);
225+
$configurationProvider = $this->objectManager->getConfigurationProvider();
226+
$fixedResponseHeaders = $configurationProvider->getSetting('responseHeaders', null);
227+
$defaultResponseHeaders = $configurationProvider->getSetting('defaultResponseHeaders', null);
227228

228-
if (!is_array($additionalResponseHeaders)) {
229-
return $response;
230-
}
231-
232-
foreach ($additionalResponseHeaders as $responseHeaderType => $value) {
233-
if (is_string($value)) {
234-
$response = $response->withAddedHeader(
235-
$responseHeaderType,
236-
$value
237-
);
238-
} elseif (is_array($value) && array_key_exists('userFunc', $value)) {
239-
$response = $response->withAddedHeader(
240-
rtrim($responseHeaderType, '.'),
241-
GeneralUtility::callUserFunction($value['userFunc'], $value, $this)
242-
);
243-
}
244-
}
229+
$response = $this->addHeaders($response, $defaultResponseHeaders, false);
230+
$response = $this->addHeaders($response, $fixedResponseHeaders, true);
245231

246232
return $response;
247233
}
@@ -256,7 +242,7 @@ private function addCorsHeaders(RestRequestInterface $request, ResponseInterface
256242

257243
foreach ($allowedOrigins as $allowedOrigin) {
258244
if ($allowedOrigin === $origin) {
259-
return $response->withHeader('Access-Control-Allow-Origin', $allowedOrigin);
245+
return $response->withHeader(Header::CORS_ORIGIN, $allowedOrigin);
260246
}
261247
}
262248
}
@@ -300,4 +286,37 @@ private function dispatchInternal(RestRequestInterface $request, ResponseInterfa
300286

301287
return $newResponse;
302288
}
289+
290+
/**
291+
* @param ResponseInterface $response
292+
* @param array|null $defaultResponseHeaders
293+
* @param bool $overwrite
294+
* @return ResponseInterface
295+
*/
296+
private function addHeaders(
297+
ResponseInterface $response,
298+
?array $defaultResponseHeaders,
299+
bool $overwrite
300+
): ResponseInterface {
301+
foreach ((array)$defaultResponseHeaders as $responseHeaderType2 => $value2) {
302+
// If the header is already set skip it unless `$overwrite` is TRUE
303+
if (!$overwrite && $response->getHeaderLine($responseHeaderType2)) {
304+
continue;
305+
}
306+
307+
if (is_string($value2)) {
308+
$response = $response->withHeader(
309+
$responseHeaderType2,
310+
$value2
311+
);
312+
} elseif (is_array($value2) && array_key_exists('userFunc', $value2)) {
313+
$response = $response->withHeader(
314+
rtrim($responseHeaderType2, '.'),
315+
GeneralUtility::callUserFunction($value2['userFunc'], $value2, $this)
316+
);
317+
}
318+
}
319+
320+
return $response;
321+
}
303322
}

Classes/Http/Header.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,21 @@
88
*/
99
abstract class Header
1010
{
11-
const CONTENT_ENCODING = 'Content-Encoding';
12-
const CACHE_CONTROL = 'Cache-Control';
13-
const LAST_MODIFIED = 'Last-Modified';
14-
const EXPIRES = 'Expires';
15-
const ETAG = 'ETag';
16-
const CONTENT_TYPE = 'Content-Type';
17-
const CONTENT_LENGTH = 'Content-Length';
11+
public const CONTENT_ENCODING = 'Content-Encoding';
12+
public const CACHE_CONTROL = 'Cache-Control';
13+
public const LAST_MODIFIED = 'Last-Modified';
14+
public const EXPIRES = 'Expires';
15+
public const ETAG = 'ETag';
16+
public const CONTENT_TYPE = 'Content-Type';
17+
public const CONTENT_LENGTH = 'Content-Length';
18+
19+
public const CORS_ORIGIN = 'Access-Control-Allow-Origin';
20+
public const CORS_METHODS = 'Access-Control-Allow-Methods';
21+
public const CORS_CREDENTIALS = 'Access-Control-Allow-Credentials';
1822

1923
// This header will be sent if the response has been cached by the REST extension
20-
const CUNDD_REST_CACHED = 'Cundd-Rest-Cached';
24+
public const CUNDD_REST_CACHED = 'Cundd-Rest-Cached';
2125

2226
// This header can be set to prevent the REST extension from caching a response
23-
const CUNDD_REST_NO_CACHE = 'Cundd-Rest-No-Cache';
27+
public const CUNDD_REST_NO_CACHE = 'Cundd-Rest-No-Cache';
2428
}

ext_typoscript_setup.txt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,24 @@ plugin.tx_rest.settings {
1717
}
1818
}
1919

20-
# You may add custom response headers, see example below
21-
#responseHeaders {
22-
# Access-Control-Allow-Origin = example.com
23-
# Access-Control-Allow-Methods = GET, POST, OPTIONS, DELETE
24-
#}
25-
#cors.allowedOrigins {
26-
# 0 = http://localhost:3000
27-
#}
20+
# Configure a set of default response headers that will be set if the response does **not** already contain them
21+
# defaultResponseHeaders {
22+
# Access-Control-Allow-Credentials = true
23+
# Access-Control-Allow-Methods = GET, POST, OPTIONS, DELETE
24+
# }
25+
26+
# Overwrite the response's headers with the following ones
27+
# responseHeaders {
28+
# Access-Control-Allow-Credentials = true
29+
# Access-Control-Allow-Methods = GET, POST, OPTIONS, DELETE
30+
# }
31+
32+
# Define a list of allowed origins:
33+
# If the request's `Origin`-header matches one of the listed origins, it will be whitelisted in the
34+
# `Access-Control-Allow-Origin`-header of the response
35+
# cors.allowedOrigins {
36+
# 0 = http://localhost:3000
37+
# }
2838

2939
# This is not defined here to allow easy customization in third party extensions TypoScript setup
3040
# cacheLifetime = -1

0 commit comments

Comments
 (0)