Skip to content

Commit 9099a79

Browse files
authored
Merge pull request #293 from binaryfire/coroutine-safe-cors
improve: make `Cors` service overridable in HandleCors middleware
2 parents 4defe80 + 0bd3a4f commit 9099a79

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed

src/http/src/Middleware/HandleCors.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ public function __construct(
2626
protected RequestContract $request,
2727
protected Cors $cors,
2828
) {
29-
$this->cors->setOptions(
30-
$this->config = $container->get(ConfigInterface::class)->get('cors', [])
31-
);
29+
$this->config = $container->get(ConfigInterface::class)->get('cors', []);
3230
}
3331

3432
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
@@ -37,9 +35,11 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
3735
return $handler->handle($request);
3836
}
3937

40-
if ($this->cors->isPreflightRequest($this->request)) {
41-
$response = $this->cors->handlePreflightRequest($this->request);
42-
return $this->cors->varyHeader($response, 'Access-Control-Request-Method');
38+
$cors = $this->getCors();
39+
40+
if ($cors->isPreflightRequest($this->request)) {
41+
$response = $cors->handlePreflightRequest($this->request);
42+
return $cors->varyHeader($response, 'Access-Control-Request-Method');
4343
}
4444

4545
try {
@@ -60,11 +60,13 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
6060
*/
6161
protected function addRequestHeaders(ResponseInterface $response): ResponseInterface
6262
{
63+
$cors = $this->getCors();
64+
6365
if ($this->request->getMethod() === 'OPTIONS') {
64-
$response = $this->cors->varyHeader($response, 'Access-Control-Request-Method');
66+
$response = $cors->varyHeader($response, 'Access-Control-Request-Method');
6567
}
6668

67-
return $this->cors->addActualRequestHeaders($response, $this->request);
69+
return $cors->addActualRequestHeaders($response, $this->request);
6870
}
6971

7072
/**
@@ -101,4 +103,20 @@ protected function getPathsByHost(string $host): array
101103
return is_string($path);
102104
});
103105
}
106+
107+
/**
108+
* Get the Cors service instance.
109+
*/
110+
protected function getCors(): Cors
111+
{
112+
return new Cors($this->getCorsConfig());
113+
}
114+
115+
/**
116+
* Get the CORS configuration.
117+
*/
118+
protected function getCorsConfig(): array
119+
{
120+
return $this->config;
121+
}
104122
}

tests/Http/Middleware/HandleCorsTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,24 @@ public function testValidationException()
252252
$this->assertEquals(422, $crawler->getStatusCode());
253253
}
254254

255+
public function testSubclassCanOverrideCorsConfig(): void
256+
{
257+
// Replace middleware with custom subclass that allows a different origin
258+
$this->setGlobalMiddleware([
259+
CustomHandleCors::class,
260+
]);
261+
262+
// Request with the custom origin (not in the base config)
263+
$crawler = $this->options('api/ping', [], [
264+
'Origin' => 'http://custom.example.com',
265+
'Access-Control-Request-Method' => 'POST',
266+
]);
267+
268+
// The custom origin should be allowed because CustomHandleCors adds it
269+
$this->assertSame('http://custom.example.com', $crawler->getHeaderLine('Access-Control-Allow-Origin'));
270+
$this->assertEquals(204, $crawler->getStatusCode());
271+
}
272+
255273
protected function registerRoutes()
256274
{
257275
$router = $this->app->get(Router::class);
@@ -281,3 +299,19 @@ protected function registerRoutes()
281299
});
282300
}
283301
}
302+
303+
/**
304+
* Custom HandleCors subclass for testing the extension pattern.
305+
*/
306+
class CustomHandleCors extends HandleCors
307+
{
308+
protected function getCorsConfig(): array
309+
{
310+
$config = parent::getCorsConfig();
311+
312+
// Add a custom allowed origin
313+
$config['allowed_origins'][] = 'http://custom.example.com';
314+
315+
return $config;
316+
}
317+
}

0 commit comments

Comments
 (0)