handle($request); if (! $request->hasHeader('Origin')) { return $response; } // Add Allow-Origin header $response = $this->options->responseWithCorsHeaders($request, $response); if ($request->getMethod() !== self::METHOD_OPTIONS) { return $response; } return $this->addOptionsHeaders($request, $response); } private function addOptionsHeaders(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { // Options requests should always be empty and have a 204 status code return EmptyResponse::withHeaders([ ...$response->getHeaders(), 'Access-Control-Allow-Methods' => $this->resolveCorsAllowedMethods($response), 'Access-Control-Allow-Headers' => $request->getHeaderLine('Access-Control-Request-Headers'), 'Access-Control-Max-Age' => $this->options->maxAge, ]); } private function resolveCorsAllowedMethods(ResponseInterface $response): string { // ImplicitOptionsMiddleware resolves allowed methods using the RouteResult request's attribute and sets them // in the "Allow" header. // If the header is there, we can re-use the value as it is. if ($response->hasHeader('Allow')) { return $response->getHeaderLine('Allow'); } return implode(',', [ self::METHOD_GET, self::METHOD_POST, self::METHOD_PUT, self::METHOD_PATCH, self::METHOD_DELETE, ]); } }