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() {