* * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ namespace CodeIgniter\Filters; use CodeIgniter\HTTP\Cors as CorsService; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; /** * @see \CodeIgniter\Filters\CorsTest */ class Cors implements FilterInterface { private ?CorsService $cors = null; /** * @testTag $config is used for testing purposes only. * * @param array{ * allowedOrigins?: list, * allowedOriginsPatterns?: list, * supportsCredentials?: bool, * allowedHeaders?: list, * exposedHeaders?: list, * allowedMethods?: list, * maxAge?: int, * } $config */ public function __construct(array $config = []) { if ($config !== []) { $this->cors = new CorsService($config); } } /** * @param list|null $arguments * * @return ResponseInterface|string|void */ public function before(RequestInterface $request, $arguments = null) { if (! $request instanceof IncomingRequest) { return; } $this->createCorsService($arguments); if (! $this->cors->isPreflightRequest($request)) { return; } /** @var ResponseInterface $response */ $response = service('response'); $response = $this->cors->handlePreflightRequest($request, $response); // Always adds `Vary: Access-Control-Request-Method` header for cacheability. // If there is an intermediate cache server such as a CDN, if a plain // OPTIONS request is sent, it may be cached. But valid preflight requests // have this header, so it will be cached separately. $response->appendHeader('Vary', 'Access-Control-Request-Method'); return $response; } /** * @param list|null $arguments */ private function createCorsService(?array $arguments): void { $this->cors ??= ($arguments === null) ? CorsService::factory() : CorsService::factory($arguments[0]); } /** * @param list|null $arguments * * @return ResponseInterface|void */ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { if (! $request instanceof IncomingRequest) { return; } $this->createCorsService($arguments); // Always adds `Vary: Access-Control-Request-Method` header for cacheability. // If there is an intermediate cache server such as a CDN, if a plain // OPTIONS request is sent, it may be cached. But valid preflight requests // have this header, so it will be cached separately. if ($request->is('OPTIONS')) { $response->appendHeader('Vary', 'Access-Control-Request-Method'); } return $this->cors->addResponseHeaders($request, $response); } }