Skip to content

Commit ad78b60

Browse files
committed
fix(router): handle HEAD requests
1 parent d0a4e1e commit ad78b60

File tree

5 files changed

+33
-10
lines changed

5 files changed

+33
-10
lines changed

packages/router/src/GenericResponseSender.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use Generator;
88
use Tempest\Http\ContentType;
99
use Tempest\Http\Header;
10+
use Tempest\Http\Method;
11+
use Tempest\Http\Request;
1012
use Tempest\Http\Response;
1113
use Tempest\Http\Responses\Download;
1214
use Tempest\Http\Responses\EventStream;
@@ -19,6 +21,7 @@
1921
final readonly class GenericResponseSender implements ResponseSender
2022
{
2123
public function __construct(
24+
private Request $request,
2225
private ViewRenderer $viewRenderer,
2326
) {}
2427

@@ -27,7 +30,11 @@ public function send(Response $response): Response
2730
ob_start();
2831
$this->sendHeaders($response);
2932
ob_flush();
30-
$this->sendContent($response);
33+
34+
if (! $this->shouldSendContent()) {
35+
$this->sendContent($response);
36+
}
37+
3138
ob_end_flush();
3239

3340
if (function_exists('fastcgi_finish_request')) {
@@ -37,6 +44,15 @@ public function send(Response $response): Response
3744
return $response;
3845
}
3946

47+
private function shouldSendContent(): bool
48+
{
49+
if ($this->request->method === Method::HEAD) {
50+
return false;
51+
}
52+
53+
return true;
54+
}
55+
4056
private function sendHeaders(Response $response): void
4157
{
4258
// TODO: Handle SAPI/FastCGI

packages/router/src/GenericRouter.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public function dispatch(Request|PsrRequest $request): Response
3939
$request = map($request)->with(PsrRequestToGenericRequestMapper::class)->do();
4040
}
4141

42+
$this->container->singleton(Request::class, $request);
43+
4244
$callable = $this->getCallable();
4345

4446
return $this->processResponse($callable($request));

packages/router/src/HttpApplication.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,10 @@ public function run(): void
5252
$router = $this->container->get(Router::class);
5353

5454
$psrRequest = $this->container->get(RequestFactory::class)->make();
55+
$response = $router->dispatch($psrRequest);
5556

5657
$responseSender = $this->container->get(ResponseSender::class);
57-
58-
$responseSender->send(
59-
$router->dispatch($psrRequest),
60-
);
58+
$responseSender->send($response);
6159

6260
$this->container->get(Session::class)->cleanup();
6361

packages/router/src/ResponseSenderInitializer.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44

55
namespace Tempest\Router;
66

7-
use Tempest\Clock\Clock;
87
use Tempest\Container\Container;
98
use Tempest\Container\Initializer;
109
use Tempest\Container\Singleton;
10+
use Tempest\Http\Request;
1111
use Tempest\View\ViewRenderer;
1212

1313
final class ResponseSenderInitializer implements Initializer
1414
{
1515
#[Singleton]
1616
public function initialize(Container $container): ResponseSender
1717
{
18-
return new GenericResponseSender($container->get(ViewRenderer::class));
18+
return new GenericResponseSender(
19+
request: $container->get(Request::class),
20+
viewRenderer: $container->get(ViewRenderer::class),
21+
);
1922
}
2023
}

packages/router/src/Routing/Construction/RouteConfigurator.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Router\Routing\Construction;
66

77
use Tempest\Container\Singleton;
8+
use Tempest\Http\Method;
89
use Tempest\Router\RouteConfig;
910

1011
/**
@@ -46,16 +47,19 @@ private function addDynamicRoute(DiscoveredRoute $route): void
4647
{
4748
$markedRoute = $this->markRoute($route);
4849
$this->dynamicRoutes[$route->method->value][$markedRoute->mark] = $route;
50+
$this->dynamicRoutes[Method::HEAD->value][$markedRoute->mark] = $route;
4951

5052
$this->routingTree->add($markedRoute);
5153
}
5254

5355
private function addStaticRoute(DiscoveredRoute $route): void
5456
{
55-
$uriWithTrailingSlash = rtrim($route->uri, '/');
57+
$uriWithoutTrailingSlash = rtrim($route->uri, '/');
5658

57-
$this->staticRoutes[$route->method->value][$uriWithTrailingSlash] = $route;
58-
$this->staticRoutes[$route->method->value][$uriWithTrailingSlash . '/'] = $route;
59+
$this->staticRoutes[$route->method->value][$uriWithoutTrailingSlash] = $route;
60+
$this->staticRoutes[$route->method->value][$uriWithoutTrailingSlash . '/'] = $route;
61+
$this->staticRoutes[Method::HEAD->value][$uriWithoutTrailingSlash] = $route;
62+
$this->staticRoutes[Method::HEAD->value][$uriWithoutTrailingSlash . '/'] = $route;
5963
}
6064

6165
private function markRoute(DiscoveredRoute $route): MarkedRoute

0 commit comments

Comments
 (0)