mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
fix: set headers for CORS (#9437)
Some checks failed
Deploy API Documentation / Deploy to api (push) Has been cancelled
Deploy User Guide (latest) / Deploy to gh-pages (push) Has been cancelled
AutoReview / Automatic Code Review (push) Has been cancelled
AutoReview / Check normalized composer.json (push) Has been cancelled
Coding Standards / PHP 8.1 Lint with PHP CS Fixer (push) Has been cancelled
Coding Standards / PHP 8.4 Lint with PHP CS Fixer (push) Has been cancelled
Deptrac / Architectural Inspection (push) Has been cancelled
Check File Permissions / Check File Permission (push) Has been cancelled
PHPCPD / phpcpd (push) Has been cancelled
PHPStan / PHP ${{ matrix.php-versions }} Static Analysis (push) Has been cancelled
PHPUnit / Setup PHP Version for Code Coverage (push) Has been cancelled
Psalm / Psalm Analysis (push) Has been cancelled
Rector / PHP 8.1 Analyze code (Rector) (push) Has been cancelled
Rector / PHP 8.4 Analyze code (Rector) (push) Has been cancelled
PHPUnit / Others (8.1) (push) Has been cancelled
PHPUnit / Others (8.2) (push) Has been cancelled
PHPUnit / Others (8.3) (push) Has been cancelled
PHPUnit / Others (8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 5.7, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.4) (push) Has been cancelled
PHPUnit / SeparateProcess (8.1) (push) Has been cancelled
PHPUnit / SeparateProcess (8.2) (push) Has been cancelled
PHPUnit / SeparateProcess (8.3) (push) Has been cancelled
PHPUnit / SeparateProcess (8.4) (push) Has been cancelled
PHPUnit / CacheLive (8.1) (push) Has been cancelled
PHPUnit / CacheLive (8.2) (push) Has been cancelled
PHPUnit / CacheLive (8.3) (push) Has been cancelled
PHPUnit / CacheLive (8.4) (push) Has been cancelled
PHPUnit / Upload coverage results to Coveralls (push) Has been cancelled
Some checks failed
Deploy API Documentation / Deploy to api (push) Has been cancelled
Deploy User Guide (latest) / Deploy to gh-pages (push) Has been cancelled
AutoReview / Automatic Code Review (push) Has been cancelled
AutoReview / Check normalized composer.json (push) Has been cancelled
Coding Standards / PHP 8.1 Lint with PHP CS Fixer (push) Has been cancelled
Coding Standards / PHP 8.4 Lint with PHP CS Fixer (push) Has been cancelled
Deptrac / Architectural Inspection (push) Has been cancelled
Check File Permissions / Check File Permission (push) Has been cancelled
PHPCPD / phpcpd (push) Has been cancelled
PHPStan / PHP ${{ matrix.php-versions }} Static Analysis (push) Has been cancelled
PHPUnit / Setup PHP Version for Code Coverage (push) Has been cancelled
Psalm / Psalm Analysis (push) Has been cancelled
Rector / PHP 8.1 Analyze code (Rector) (push) Has been cancelled
Rector / PHP 8.4 Analyze code (Rector) (push) Has been cancelled
PHPUnit / Others (8.1) (push) Has been cancelled
PHPUnit / Others (8.2) (push) Has been cancelled
PHPUnit / Others (8.3) (push) Has been cancelled
PHPUnit / Others (8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 5.7, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (MySQLi, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (OCI8, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (Postgre, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLSRV, 8.0, 8.4) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.1) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.2) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.3) (push) Has been cancelled
PHPUnit / DatabaseLive (SQLite3, 8.0, 8.4) (push) Has been cancelled
PHPUnit / SeparateProcess (8.1) (push) Has been cancelled
PHPUnit / SeparateProcess (8.2) (push) Has been cancelled
PHPUnit / SeparateProcess (8.3) (push) Has been cancelled
PHPUnit / SeparateProcess (8.4) (push) Has been cancelled
PHPUnit / CacheLive (8.1) (push) Has been cancelled
PHPUnit / CacheLive (8.2) (push) Has been cancelled
PHPUnit / CacheLive (8.3) (push) Has been cancelled
PHPUnit / CacheLive (8.4) (push) Has been cancelled
PHPUnit / Upload coverage results to Coveralls (push) Has been cancelled
* fix: set everything in the before filter for CORS * fix append vary header * cors: apply response headers in the after filter only if they are not already set * cs fix
This commit is contained in:
parent
efcabb3fdf
commit
c430f34720
@ -58,13 +58,10 @@ class Cors implements FilterInterface
|
||||
|
||||
$this->createCorsService($arguments);
|
||||
|
||||
if (! $this->cors->isPreflightRequest($request)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var ResponseInterface $response */
|
||||
$response = service('response');
|
||||
|
||||
if ($this->cors->isPreflightRequest($request)) {
|
||||
$response = $this->cors->handlePreflightRequest($request, $response);
|
||||
|
||||
// Always adds `Vary: Access-Control-Request-Method` header for cacheability.
|
||||
@ -76,6 +73,19 @@ class Cors implements FilterInterface
|
||||
return $response;
|
||||
}
|
||||
|
||||
if ($request->is('OPTIONS')) {
|
||||
// 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');
|
||||
}
|
||||
|
||||
$this->cors->addResponseHeaders($request, $response);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string>|null $arguments
|
||||
*/
|
||||
@ -87,8 +97,6 @@ class Cors implements FilterInterface
|
||||
|
||||
/**
|
||||
* @param list<string>|null $arguments
|
||||
*
|
||||
* @return ResponseInterface|null
|
||||
*/
|
||||
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
|
||||
{
|
||||
@ -98,6 +106,10 @@ class Cors implements FilterInterface
|
||||
|
||||
$this->createCorsService($arguments);
|
||||
|
||||
if ($this->cors->hasResponseHeaders($request, $response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -227,4 +227,24 @@ class Cors
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if response headers were set
|
||||
*/
|
||||
public function hasResponseHeaders(RequestInterface $request, ResponseInterface $response): bool
|
||||
{
|
||||
if (! $response->hasHeader('Access-Control-Allow-Origin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->config['supportsCredentials']
|
||||
&& ! $response->hasHeader('Access-Control-Allow-Credentials')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! ($this->config['exposedHeaders'] !== [] && (! $response->hasHeader('Access-Control-Expose-Headers') || ! str_contains(
|
||||
$response->getHeaderLine('Access-Control-Expose-Headers'),
|
||||
implode(', ', $this->config['exposedHeaders']),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ namespace CodeIgniter\Filters;
|
||||
use CodeIgniter\Exceptions\ConfigException;
|
||||
use CodeIgniter\HTTP\CLIRequest;
|
||||
use CodeIgniter\HTTP\IncomingRequest;
|
||||
use CodeIgniter\HTTP\RedirectResponse;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\HTTP\SiteURI;
|
||||
@ -154,6 +155,25 @@ final class CorsTest extends CIUnitTestCase
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function handleRedirect(RequestInterface $request): ResponseInterface
|
||||
{
|
||||
$response = $this->cors->before($request);
|
||||
if ($response instanceof ResponseInterface) {
|
||||
$this->response = $response;
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response = service('redirectresponse');
|
||||
|
||||
$response = $this->cors->after($request, $response);
|
||||
$response ??= service('redirectresponse');
|
||||
|
||||
$this->response = $response;
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function testItDoesModifyOnARequestWithSameOrigin(): void
|
||||
{
|
||||
$this->cors = $this->createCors(['allowedOrigins' => ['*']]);
|
||||
@ -461,4 +481,29 @@ final class CorsTest extends CIUnitTestCase
|
||||
// Always adds `Vary: Access-Control-Request-Method` header.
|
||||
$this->assertHeader('Vary', 'Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
public function testItReturnsAllowOriginHeaderOnValidActualRequestWithRedirect(): void
|
||||
{
|
||||
$this->cors = $this->createCors();
|
||||
$request = $this->createValidActualRequest();
|
||||
|
||||
$response = $this->handleRedirect($request);
|
||||
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||
$this->assertTrue($response->hasHeader('Access-Control-Allow-Origin'));
|
||||
$this->assertHeader('Access-Control-Allow-Origin', 'http://localhost');
|
||||
}
|
||||
|
||||
public function testItReturnsAllowOriginHeaderOnAllowAllOriginRequestWithRedirect(): void
|
||||
{
|
||||
$this->cors = $this->createCors(['allowedOrigins' => ['*']]);
|
||||
$request = $this->createRequest();
|
||||
$request->setHeader('Origin', 'http://localhost');
|
||||
|
||||
$response = $this->handleRedirect($request);
|
||||
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||
$this->assertTrue($response->hasHeader('Access-Control-Allow-Origin'));
|
||||
$this->assertHeader('Access-Control-Allow-Origin', '*');
|
||||
}
|
||||
}
|
||||
|
@ -521,4 +521,41 @@ final class CorsTest extends CIUnitTestCase
|
||||
$response->hasHeader('Access-Control-Allow-Methods'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasResponseHeadersFalse(): void
|
||||
{
|
||||
$config = $this->getDefaultConfig();
|
||||
$config['allowedOrigins'] = ['http://localhost:8080'];
|
||||
$config['allowedMethods'] = ['GET', 'POST', 'PUT'];
|
||||
$cors = $this->createCors($config);
|
||||
|
||||
$request = $this->createRequest()
|
||||
->withMethod('GET')
|
||||
->setHeader('Origin', 'http://localhost:8080');
|
||||
|
||||
$response = service('redirectresponse', null, false);
|
||||
|
||||
$this->assertFalse(
|
||||
$cors->hasResponseHeaders($request, $response),
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasResponseHeadersTrue(): void
|
||||
{
|
||||
$config = $this->getDefaultConfig();
|
||||
$config['allowedOrigins'] = ['http://localhost:8080'];
|
||||
$config['allowedMethods'] = ['GET', 'POST'];
|
||||
$cors = $this->createCors($config);
|
||||
|
||||
$request = $this->createRequest()
|
||||
->withMethod('GET')
|
||||
->setHeader('Origin', 'http://localhost:8080');
|
||||
|
||||
$response = service('redirectresponse', null, false);
|
||||
$response = $cors->addResponseHeaders($request, $response);
|
||||
|
||||
$this->assertTrue(
|
||||
$cors->hasResponseHeaders($request, $response),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ Bugs Fixed
|
||||
**********
|
||||
|
||||
- **CURLRequest:** Fixed an issue where multiple header sections appeared in the CURL response body during multiple redirects from the target server.
|
||||
- **Cors:** Fixed a bug in the Cors filter that caused the appropriate headers to not be added when another filter returned a response object in the ``before`` filter.
|
||||
|
||||
See the repo's
|
||||
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_
|
||||
|
Loading…
x
Reference in New Issue
Block a user