1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Server\Transport\Http;
15:
16: use Psr\Http\Message\ResponseInterface;
17: use Psr\Http\Message\ServerRequestInterface;
18: use Psr\Http\Server\MiddlewareInterface;
19: use Psr\Http\Server\RequestHandlerInterface;
20:
21: /**
22: * Composes PSR-15 middleware in front of an inner request handler, typically the Streamable HTTP transport.
23: *
24: * The middleware run outermost-first. The pipeline is re-entrant: one instance serves concurrent requests,
25: * since each `handle()` recurses over a fresh immutable tail rather than mutating shared state.
26: */
27: final readonly class MiddlewarePipeline implements RequestHandlerInterface
28: {
29: /**
30: * @var list<MiddlewareInterface>
31: */
32: private array $middleware;
33:
34: public function __construct(private RequestHandlerInterface $handler, MiddlewareInterface ...$middleware)
35: {
36: $this->middleware = array_values($middleware);
37: }
38:
39: #[\Override]
40: public function handle(ServerRequestInterface $request): ResponseInterface
41: {
42: if ([] === $this->middleware) {
43: return $this->handler->handle($request);
44: }
45:
46: return $this->middleware[0]->process(
47: $request,
48: new self($this->handler, ...\array_slice($this->middleware, 1)),
49: );
50: }
51: }
52: