1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Shlinkio\Shlink\Rest\Middleware; |
6
|
|
|
|
7
|
|
|
use Fig\Http\Message\RequestMethodInterface; |
8
|
|
|
use Laminas\Diactoros\Response\EmptyResponse; |
9
|
|
|
use Mezzio\Router\RouteResult; |
10
|
|
|
use Psr\Http\Message\ResponseInterface; |
11
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
12
|
|
|
use Psr\Http\Server\MiddlewareInterface; |
13
|
|
|
use Psr\Http\Server\RequestHandlerInterface; |
14
|
|
|
|
15
|
|
|
use function array_merge; |
16
|
|
|
use function implode; |
17
|
|
|
|
18
|
|
|
class CrossDomainMiddleware implements MiddlewareInterface, RequestMethodInterface |
19
|
|
|
{ |
20
|
|
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface |
21
|
22 |
|
{ |
22
|
|
|
$response = $handler->handle($request); |
23
|
22 |
|
if (! $request->hasHeader('Origin')) { |
24
|
22 |
|
return $response; |
25
|
2 |
|
} |
26
|
|
|
|
27
|
|
|
// Add Allow-Origin header |
28
|
|
|
$response = $response->withHeader('Access-Control-Allow-Origin', $request->getHeader('Origin')) |
29
|
20 |
|
->withHeader('Access-Control-Expose-Headers', AuthenticationMiddleware::API_KEY_HEADER); |
30
|
20 |
|
if ($request->getMethod() !== self::METHOD_OPTIONS) { |
31
|
20 |
|
return $response; |
32
|
|
|
} |
33
|
20 |
|
|
34
|
13 |
|
return $this->addOptionsHeaders($request, $response); |
35
|
|
|
} |
36
|
|
|
|
37
|
7 |
|
private function addOptionsHeaders(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface |
38
|
|
|
{ |
39
|
|
|
/** @var RouteResult|null $matchedRoute */ |
40
|
7 |
|
$matchedRoute = $request->getAttribute(RouteResult::class); |
41
|
|
|
$matchedMethods = $matchedRoute !== null ? $matchedRoute->getAllowedMethods() : [ |
42
|
|
|
self::METHOD_GET, |
43
|
7 |
|
self::METHOD_POST, |
44
|
7 |
|
self::METHOD_PUT, |
45
|
5 |
|
self::METHOD_PATCH, |
46
|
5 |
|
self::METHOD_DELETE, |
47
|
5 |
|
self::METHOD_OPTIONS, |
48
|
5 |
|
]; |
49
|
5 |
|
$corsHeaders = [ |
50
|
7 |
|
'Access-Control-Allow-Methods' => implode(',', $matchedMethods), |
|
|
|
|
51
|
|
|
'Access-Control-Max-Age' => '1000', |
52
|
|
|
'Access-Control-Allow-Headers' => $request->getHeaderLine('Access-Control-Request-Headers'), |
53
|
7 |
|
]; |
54
|
7 |
|
|
55
|
7 |
|
// Options requests should always be empty and have a 204 status code |
56
|
|
|
return EmptyResponse::withHeaders(array_merge($response->getHeaders(), $corsHeaders)); |
57
|
|
|
} |
58
|
|
|
} |
59
|
|
|
|