From a87d29c2280d10caa8bc6354be0f4b5f0a8a0541 Mon Sep 17 00:00:00 2001 From: mwpn Date: Wed, 17 Dec 2025 14:25:29 +0700 Subject: [PATCH] chore: Normalize Origin header in CORS middleware dan update test_cors --- bin/test_cors.php | 23 ++++++++++++++--------- src/Middleware/CorsMiddleware.php | 14 +++++++++++--- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/bin/test_cors.php b/bin/test_cors.php index dba3496..1af1d81 100644 --- a/bin/test_cors.php +++ b/bin/test_cors.php @@ -34,10 +34,12 @@ $response1->getBody()->write(json_encode(['status' => 'ok'])); $middleware = new CorsMiddleware(); $handler = new class($response1) implements \Psr\Http\Server\RequestHandlerInterface { private $response; - public function __construct($response) { + public function __construct($response) + { $this->response = $response; } - public function handle(\Psr\Http\Message\ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface { + public function handle(\Psr\Http\Message\ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface + { return $this->response; } }; @@ -52,17 +54,19 @@ foreach ($result1->getHeaders() as $name => $values) { } // Test 2: Origin yang tidak ada di .env -echo "\nTest 2: Origin 'http://example.com' (tidak ada di .env):\n"; +echo "\nTest 2: Origin 'http://retribusi.btekno.cloud' (tidak ada di .env):\n"; $request2 = $requestFactory->createServerRequest('GET', '/health') - ->withHeader('Origin', 'http://example.com'); + ->withHeader('Origin', 'http://retribusi.btekno.cloud'); $response2 = $responseFactory->createResponse(200); $handler2 = new class($response2) implements \Psr\Http\Server\RequestHandlerInterface { private $response; - public function __construct($response) { + public function __construct($response) + { $this->response = $response; } - public function handle(\Psr\Http\Message\ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface { + public function handle(\Psr\Http\Message\ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface + { return $this->response; } }; @@ -89,10 +93,12 @@ $request3 = $requestFactory->createServerRequest('OPTIONS', '/health') $response3 = $responseFactory->createResponse(200); $handler3 = new class($response3) implements \Psr\Http\Server\RequestHandlerInterface { private $response; - public function __construct($response) { + public function __construct($response) + { $this->response = $response; } - public function handle(\Psr\Http\Message\ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface { + public function handle(\Psr\Http\Message\ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface + { return $this->response; } }; @@ -112,4 +118,3 @@ echo "\nJika Test 1 tidak ada CORS headers, kemungkinan:\n"; echo "1. PHP-FPM belum di-restart setelah perubahan code\n"; echo "2. Opcache masih cache code lama (clear opcache)\n"; echo "3. Check error log: tail -f /www/wwwlogs/api.btekno.cloud.error.log\n"; - diff --git a/src/Middleware/CorsMiddleware.php b/src/Middleware/CorsMiddleware.php index 2cdf7dc..fc2a3a7 100644 --- a/src/Middleware/CorsMiddleware.php +++ b/src/Middleware/CorsMiddleware.php @@ -22,8 +22,8 @@ class CorsMiddleware implements MiddlewareInterface { // Load allowed origins from ENV or use defaults $originsEnv = AppConfig::get('CORS_ALLOWED_ORIGINS', '*'); - $this->allowedOrigins = $originsEnv === '*' - ? ['*'] + $this->allowedOrigins = $originsEnv === '*' + ? ['*'] : array_map('trim', explode(',', $originsEnv)); // Allowed HTTP methods @@ -47,6 +47,15 @@ class CorsMiddleware implements MiddlewareInterface ): ResponseInterface { $origin = $request->getHeaderLine('Origin'); + // Normalize origin (strip path if someone sends invalid Origin) + if ($origin && str_contains($origin, '/')) { + $parsed = parse_url($origin); + if (isset($parsed['scheme'], $parsed['host'])) { + $origin = $parsed['scheme'] . '://' . $parsed['host'] + . (isset($parsed['port']) ? ':' . $parsed['port'] : ''); + } + } + // Handle preflight OPTIONS request if ($request->getMethod() === 'OPTIONS') { $responseFactory = new ResponseFactory(); @@ -132,4 +141,3 @@ class CorsMiddleware implements MiddlewareInterface return $this->allowedOrigins[0] ?? null; } } -