upgraded dependencies
This commit is contained in:
61
vendor/asm89/stack-cors/src/Cors.php
vendored
Normal file
61
vendor/asm89/stack-cors/src/Cors.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of asm89/stack-cors.
|
||||
*
|
||||
* (c) Alexander <iam.asm89@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Asm89\Stack;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Cors implements HttpKernelInterface
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* @var \Asm89\Stack\CorsService
|
||||
*/
|
||||
private $cors;
|
||||
|
||||
private $defaultOptions = [
|
||||
'allowedHeaders' => [],
|
||||
'allowedMethods' => [],
|
||||
'allowedOrigins' => [],
|
||||
'allowedOriginsPatterns' => [],
|
||||
'exposedHeaders' => [],
|
||||
'maxAge' => 0,
|
||||
'supportsCredentials' => false,
|
||||
];
|
||||
|
||||
public function __construct(HttpKernelInterface $app, array $options = [])
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->cors = new CorsService(array_merge($this->defaultOptions, $options));
|
||||
}
|
||||
|
||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true): Response
|
||||
{
|
||||
if ($this->cors->isPreflightRequest($request)) {
|
||||
$response = $this->cors->handlePreflightRequest($request);
|
||||
return $this->cors->varyHeader($response, 'Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
$response = $this->app->handle($request, $type, $catch);
|
||||
|
||||
if ($request->getMethod() === 'OPTIONS') {
|
||||
$this->cors->varyHeader($response, 'Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
return $this->cors->addActualRequestHeaders($response, $request);
|
||||
}
|
||||
}
|
||||
225
vendor/asm89/stack-cors/src/CorsService.php
vendored
Normal file
225
vendor/asm89/stack-cors/src/CorsService.php
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of asm89/stack-cors.
|
||||
*
|
||||
* (c) Alexander <iam.asm89@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Asm89\Stack;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CorsService
|
||||
{
|
||||
private $options;
|
||||
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = $this->normalizeOptions($options);
|
||||
}
|
||||
|
||||
private function normalizeOptions(array $options = []): array
|
||||
{
|
||||
$options += [
|
||||
'allowedOrigins' => [],
|
||||
'allowedOriginsPatterns' => [],
|
||||
'supportsCredentials' => false,
|
||||
'allowedHeaders' => [],
|
||||
'exposedHeaders' => [],
|
||||
'allowedMethods' => [],
|
||||
'maxAge' => 0,
|
||||
];
|
||||
|
||||
// normalize array('*') to true
|
||||
if (in_array('*', $options['allowedOrigins'])) {
|
||||
$options['allowedOrigins'] = true;
|
||||
}
|
||||
if (in_array('*', $options['allowedHeaders'])) {
|
||||
$options['allowedHeaders'] = true;
|
||||
} else {
|
||||
$options['allowedHeaders'] = array_map('strtolower', $options['allowedHeaders']);
|
||||
}
|
||||
|
||||
if (in_array('*', $options['allowedMethods'])) {
|
||||
$options['allowedMethods'] = true;
|
||||
} else {
|
||||
$options['allowedMethods'] = array_map('strtoupper', $options['allowedMethods']);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use isOriginAllowed
|
||||
*/
|
||||
public function isActualRequestAllowed(Request $request): bool
|
||||
{
|
||||
return $this->isOriginAllowed($request);
|
||||
}
|
||||
|
||||
public function isCorsRequest(Request $request): bool
|
||||
{
|
||||
return $request->headers->has('Origin');
|
||||
}
|
||||
|
||||
public function isPreflightRequest(Request $request): bool
|
||||
{
|
||||
return $request->getMethod() === 'OPTIONS' && $request->headers->has('Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
public function handlePreflightRequest(Request $request): Response
|
||||
{
|
||||
$response = new Response();
|
||||
|
||||
$response->setStatusCode(204);
|
||||
|
||||
return $this->addPreflightRequestHeaders($response, $request);
|
||||
}
|
||||
|
||||
public function addPreflightRequestHeaders(Response $response, Request $request): Response
|
||||
{
|
||||
$this->configureAllowedOrigin($response, $request);
|
||||
|
||||
if ($response->headers->has('Access-Control-Allow-Origin')) {
|
||||
$this->configureAllowCredentials($response, $request);
|
||||
|
||||
$this->configureAllowedMethods($response, $request);
|
||||
|
||||
$this->configureAllowedHeaders($response, $request);
|
||||
|
||||
$this->configureMaxAge($response, $request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function isOriginAllowed(Request $request): bool
|
||||
{
|
||||
if ($this->options['allowedOrigins'] === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$request->headers->has('Origin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$origin = $request->headers->get('Origin');
|
||||
|
||||
if (in_array($origin, $this->options['allowedOrigins'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->options['allowedOriginsPatterns'] as $pattern) {
|
||||
if (preg_match($pattern, $origin)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addActualRequestHeaders(Response $response, Request $request): Response
|
||||
{
|
||||
$this->configureAllowedOrigin($response, $request);
|
||||
|
||||
if ($response->headers->has('Access-Control-Allow-Origin')) {
|
||||
$this->configureAllowCredentials($response, $request);
|
||||
|
||||
$this->configureExposedHeaders($response, $request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function configureAllowedOrigin(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['allowedOrigins'] === true && !$this->options['supportsCredentials']) {
|
||||
// Safe+cacheable, allow everything
|
||||
$response->headers->set('Access-Control-Allow-Origin', '*');
|
||||
} elseif ($this->isSingleOriginAllowed()) {
|
||||
// Single origins can be safely set
|
||||
$response->headers->set('Access-Control-Allow-Origin', array_values($this->options['allowedOrigins'])[0]);
|
||||
} else {
|
||||
// For dynamic headers, set the requested Origin header when set and allowed
|
||||
if ($this->isCorsRequest($request) && $this->isOriginAllowed($request)) {
|
||||
$response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin'));
|
||||
}
|
||||
|
||||
$this->varyHeader($response, 'Origin');
|
||||
}
|
||||
}
|
||||
|
||||
private function isSingleOriginAllowed(): bool
|
||||
{
|
||||
if ($this->options['allowedOrigins'] === true || !empty($this->options['allowedOriginsPatterns'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return count($this->options['allowedOrigins']) === 1;
|
||||
}
|
||||
|
||||
private function configureAllowedMethods(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['allowedMethods'] === true) {
|
||||
$allowMethods = strtoupper($request->headers->get('Access-Control-Request-Method'));
|
||||
$this->varyHeader($response, 'Access-Control-Request-Method');
|
||||
} else {
|
||||
$allowMethods = implode(', ', $this->options['allowedMethods']);
|
||||
}
|
||||
|
||||
$response->headers->set('Access-Control-Allow-Methods', $allowMethods);
|
||||
}
|
||||
|
||||
private function configureAllowedHeaders(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['allowedHeaders'] === true) {
|
||||
$allowHeaders = $request->headers->get('Access-Control-Request-Headers');
|
||||
$this->varyHeader($response, 'Access-Control-Request-Headers');
|
||||
} else {
|
||||
$allowHeaders = implode(', ', $this->options['allowedHeaders']);
|
||||
}
|
||||
$response->headers->set('Access-Control-Allow-Headers', $allowHeaders);
|
||||
}
|
||||
|
||||
private function configureAllowCredentials(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['supportsCredentials']) {
|
||||
$response->headers->set('Access-Control-Allow-Credentials', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
private function configureExposedHeaders(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['exposedHeaders']) {
|
||||
$response->headers->set('Access-Control-Expose-Headers', implode(', ', $this->options['exposedHeaders']));
|
||||
}
|
||||
}
|
||||
|
||||
private function configureMaxAge(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['maxAge'] !== null) {
|
||||
$response->headers->set('Access-Control-Max-Age', (int) $this->options['maxAge']);
|
||||
}
|
||||
}
|
||||
|
||||
public function varyHeader(Response $response, $header): Response
|
||||
{
|
||||
if (!$response->headers->has('Vary')) {
|
||||
$response->headers->set('Vary', $header);
|
||||
} elseif (!in_array($header, explode(', ', $response->headers->get('Vary')))) {
|
||||
$response->headers->set('Vary', $response->headers->get('Vary') . ', ' . $header);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function isSameHost(Request $request): bool
|
||||
{
|
||||
return $request->headers->get('Origin') === $request->getSchemeAndHttpHost();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user