Search by

mammatus / http-server

WyriHaximus

🐙 Multi vhost HTTP Server

Package info

github.com/MammatusPHP/http-server

Language:Makefile

Type:composer-plugin

pkg:composer/mammatus/http-server

Statistics

Installs: 24 900

Dependents: 1

Suggesters: 0

Stars: 2

Open Issues: 3

dev-master 2026-10-16 20:32 UTC

This package is auto-updated.

Last update: 2026-10-16 22:41:54 UTC


README

Continuous Integration Latest Stable Version Total Downloads Type Coverage License

Async multi-vhost HTTP on ReactPHP and react/http for MammatusPHP applications. mammatus/http-server is a Composer plugin that discovers virtual hosts and route handlers across your project and installed packages, then generates ReactPHP server classes and Kubernetes-oriented Helm values. Generated servers implement LifeCycleHandler and start or stop with Mammatus groups.

Install

To install via Composer, use the command below. Composer picks the latest compatible version and applies a ^ constraint.

composer require mammatus/http-server

The plugin runs on every composer dump-autoload (pre-autoload-dump) and via the composer generate-config script. Both call Mammatus\Http\Server\Composer\Installer::findServers.

How it works

On autoload dump the plugin scans the codebase and installed packages, collects vhosts, HTTP handlers, and optional Kubernetes metadata, then writes generated PHP under the plugin install path (for example vendor/mammatus/http-server/ in an application).

flowchart LR
  subgraph discover [Discovery on composer dump]
    VhostClasses["Classes implementing Vhost"]
    HandlerClasses["Classes with Vhost plus Route attributes"]
    Packages["Packages with extra.mammatus.http.server.has-vhosts"]
  end
  Plugin["mammatus/http-server Plugin"]
  Generated["src/Server LifeCycleHandlers"]
  Helm["Kubernetes Helm ServerValues"]
  discover --> Plugin
  Plugin --> Generated
  Plugin --> Helm
  Generated --> Groups["Mammatus groups start and stop"]
Loading
  • Discovery filters: Plugin::filters() matches packages with extra.mammatus.http.server.has-vhosts, classes implementing Vhost, and handler classes that carry both #[Vhost] and #[Route].
  • Collection: Collector yields servers, handlers, and optional Service / Ingress items from vhost classes.
  • Generated output:
  • Do not edit generated files manually. They are overwritten on the next install or update (see the banner on Frontend).
  • Routing: FastRoute with a on-disk route cache under var/fast-route/{vhostName} inside generated code.
  • Per-vhost HTTP stack: request logging, body buffer and parser, optional PSR-15 middleware from the vhost, optional webroot preload middleware, then FastRoute dispatch.

Define a virtual host

Implement Mammatus\Http\Server\Configuration\Vhost: static name(), port(), and webroot() (NoWebroot or a path-backed webroot), plus instance middleware(). Optional #[Group], #[Service], and #[Ingress] on the class feed Helm values generation.

Example from this repository's dev app (FrontendVhost.php):

<?php declare(strict_types=1);

namespace Mammatus\DevApp\Http\Server;

use Mammatus\Groups\Attributes\Group;
use Mammatus\Groups\Type;
use Mammatus\Http\Server\Configuration\Vhost;
use Mammatus\Http\Server\Configuration\Webroot;
use Mammatus\Http\Server\Webroot\NoWebroot;
use Mammatus\Kubernetes\Attributes\Ingress;
use Mammatus\Kubernetes\Attributes\Service;
use Psr\Http\Server\MiddlewareInterface;

#[Group(Type::Daemon, 'frontend')]
#[Service]
#[Ingress('www.example.com')]
final class FrontendVhost implements Vhost
{
    private const string SERVER_NAME = 'frontend';
    private const int LISTEN_PORT    = 1337;

    public static function port(): int
    {
        return self::LISTEN_PORT;
    }

    public static function name(): string
    {
        return self::SERVER_NAME;
    }

    public static function webroot(): Webroot
    {
        return new NoWebroot();
    }

    public static function maxConcurrentRequests(): null
    {
        return null;
    }

    /** @return iterable<MiddlewareInterface> */
    public function middleware(): iterable
    {
        yield from [];
    }
}

For a ready-made health and probe vhost, see mammatus/healthz-vhost (port 9666, Kubernetes probes, static files under public/).

HTTP route handlers

Handlers are plain PHP classes annotated with #[Vhost] and #[Route]. The collector (Collector::handler()) registers each matching public method that is not a constructor or destructor and has zero or one parameter. With one parameter, the type is a route payload DTO (FastRoute path segments map into it). Static and instance methods are both supported (Handler).

Home page handler (HomePageHandler.php):

#[Vhost('frontend')]
#[Route(HttpMethod::GET, '/')]
final readonly class HomePageHandler
{
    public function handle(): ResponseInterface
    {
        return new Response(OK, ['Content-Type' => 'text/plain'], 'Hello World!');
    }
}

Route parameter payload (PingHandler.php and Ping.php):

#[Vhost('frontend')]
#[Route(HttpMethod::GET, '/ping/{name}')]
final readonly class PingHandler
{
    public function handle(Ping $ping): ResponseInterface
    {
        return new Response(OK, ['Content-Type' => 'application/json'], '{}');
    }
}

Probe routes and other attributes are documented in mammatus/http-server-attributes.

Publishing vhosts from a Composer package

Set extra.mammatus.http.server.has-vhosts to true in composer.json so the plugin scans that package for Vhost implementations and attributed handlers (this package and healthz-vhost use the same flag):

"extra": {
  "mammatus": {
    "http": {
      "server": {
        "has-vhosts": true
      }
    }
  }
}

Application code and every scanned package contribute handlers to the same generated servers keyed by vhost name.

Hacking this repository

See CONTRIBUTING.md. Run make install, then make contrib while iterating and make before opening a pull request. Example vhost and handlers live under etc/dev-app/.

License

The MIT License (MIT)

Copyright (c) 2026 Cees-Jan Kiewiet

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.