From 296c9b57d5d2a0c9d10054fb605999c2163c389f Mon Sep 17 00:00:00 2001 From: Belle Aerni Date: Fri, 15 Mar 2024 23:18:23 -0700 Subject: [PATCH 1/3] Also register HEAD for GET routes --- flight/net/Router.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flight/net/Router.php b/flight/net/Router.php index f739a24..43c3f18 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -107,6 +107,10 @@ class Router $methods = explode('|', $method); } + if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { + $methods[] = 'HEAD'; + } + // And this finishes it off. if ($this->group_prefix !== '') { $url = rtrim($this->group_prefix . $url); From 5406bbedc13dc1559896925c9c7028e0b4d5e46f Mon Sep 17 00:00:00 2001 From: Austin Collier Date: Sat, 16 Mar 2024 10:41:33 -0600 Subject: [PATCH 2/3] added test coverage and clearing body for head requests --- composer.json | 2 +- flight/Engine.php | 5 +++++ flight/net/Router.php | 7 ++++--- tests/EngineTest.php | 14 ++++++++++++++ tests/RouterTest.php | 13 +++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index b45d101..028f2da 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,7 @@ }, "scripts": { "test": "phpunit", - "test-coverage": "rm clover.xml && XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage --coverage-clover=clover.xml && vendor/bin/coverage-check clover.xml 100", + "test-coverage": "rm -f clover.xml && XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage --coverage-clover=clover.xml && vendor/bin/coverage-check clover.xml 100", "test-server": "echo \"Running Test Server\" && php -S localhost:8000 -t tests/server/", "test-server-v2": "echo \"Running Test Server\" && php -S localhost:8000 -t tests/server-v2/", "test-coverage:win": "del clover.xml && phpunit --coverage-html=coverage --coverage-clover=clover.xml && coverage-check clover.xml 100", diff --git a/flight/Engine.php b/flight/Engine.php index b0ae09d..7ff98d1 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -533,6 +533,11 @@ class Engine $dispatched = false; } + // HEAD requests should be identical to GET requests but have no body + if($request->method === 'HEAD') { + $response->clearBody(); + } + if ($failed_middleware_check === true) { $this->halt(403, 'Forbidden', empty(getenv('PHPUNIT_TEST'))); } elseif ($dispatched === false) { diff --git a/flight/net/Router.php b/flight/net/Router.php index 43c3f18..81556cd 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -105,10 +105,11 @@ class Router [$method, $url] = explode(' ', $url, 2); $url = trim($url); $methods = explode('|', $method); - } - if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { - $methods[] = 'HEAD'; + // Add head requests to get methods, should they come in as a get request + if (in_array('GET', $methods, true) === true && in_array('HEAD', $methods, true) === false) { + $methods[] = 'HEAD'; + } } // And this finishes it off. diff --git a/tests/EngineTest.php b/tests/EngineTest.php index 400e193..26df60f 100644 --- a/tests/EngineTest.php +++ b/tests/EngineTest.php @@ -263,6 +263,20 @@ class EngineTest extends TestCase $this->assertEquals('/someRoute', $routes[0]->pattern); } + public function testHeadRoute() + { + $engine = new Engine(); + $engine->route('GET /someRoute', function () { + echo 'i ran'; + }, true); + $engine->request()->method = 'HEAD'; + $engine->request()->url = '/someRoute'; + $engine->start(); + + // No body should be sent + $this->expectOutputString(''); + } + public function testHalt() { $engine = new class extends Engine { diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 5f5abcd..5c186bb 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -81,6 +81,10 @@ class RouterTest extends TestCase $dispatched = false; } + if($this->request->method === 'HEAD') { + ob_clean(); + } + if (!$dispatched) { echo '404'; } @@ -122,6 +126,15 @@ class RouterTest extends TestCase $this->check('OK'); } + public function testHeadRouteShortcut() + { + $route = $this->router->get('/path', [$this, 'ok']); + $this->assertEquals(['GET', 'HEAD'], $route->methods); + $this->request->url = '/path'; + $this->request->method = 'HEAD'; + $this->check(''); + } + // POST route public function testPostRoute() { From 38e20242bf9aa3e2b6401e463afc6b8137432368 Mon Sep 17 00:00:00 2001 From: Austin Collier Date: Sat, 16 Mar 2024 10:42:42 -0600 Subject: [PATCH 3/3] beautify --- flight/Engine.php | 2 +- tests/RouterTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index 7ff98d1..bb694cb 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -534,7 +534,7 @@ class Engine } // HEAD requests should be identical to GET requests but have no body - if($request->method === 'HEAD') { + if ($request->method === 'HEAD') { $response->clearBody(); } diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 5c186bb..2314426 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -81,7 +81,7 @@ class RouterTest extends TestCase $dispatched = false; } - if($this->request->method === 'HEAD') { + if ($this->request->method === 'HEAD') { ob_clean(); }