amphp/http-server-static-content
AMPHP HTTP server component for efficiently serving static files (assets, downloads) with correct MIME types, caching headers, range requests, and directory handling. Designed for non-blocking, event-driven apps built on amphp/http-server.
Start by installing the package via Composer:
composer require amphp/http-server-static-content
The first step is to create a StaticContentMiddleware instance, pointing to your document root (e.g., public/). Then inject it into your Amp HTTP server’s middleware stack before other handlers to ensure static files are served directly.
use Amp\Http\Server\Middleware\StaticContentMiddleware;
use Amp\Http\Server\Server;
$middleware = new StaticContentMiddleware('/var/www/public');
$server = new Server([
$middleware, // Order matters: static middleware first
// other middleware/handlers...
]);
The simplest use case is serving front-end assets (JS, CSS, images) or a single-page app (SPA) from a directory — just drop your index.html and assets into your document root, and the middleware serves them efficiently with correct headers.
Check public/ layout expectations: it serves index.html or index.htm in directories unless you configure otherwise.
Middleware Chaining: Use StaticContentMiddleware early in your middleware stack. It returns false for non-static paths (e.g., /api/users), allowing downstream handlers to take over.
Multiple Document Roots: For microservices or mono-repos, instantiate multiple middleware instances with different roots and use Pipeline or route-based dispatch logic.
$frontend = new StaticContentMiddleware(__DIR__ . '/frontend/dist');
$docs = new StaticContentMiddleware(__DIR__ . '/docs/build');
$server = new Server([
new RouteMiddleware([
'GET' => [
'/docs' => $docs,
'/' => $frontend,
],
]),
]);
Conditional Headers & Caching: Leverage built-in ETag and Last-Modified handling — no extra code needed. Combine with cache-control headers (e.g., via custom middleware) for long-term caching strategies on hashed assets.
Error Handling & Fallbacks: If a file is missing, the middleware throws an Amp\Http\Server\HttpException with status 404. Use custom middleware after static content to render user-friendly error pages or serve a fallback index.html (e.g., for SPAs).
Integration with Laravel or Symfony (via Amp bridge): Though this package targets raw Amp, you can embed it inside PSR-15-compatible bridges (e.g., php-http/psr7) to serve static assets without blocking the PHP-FPM worker.
Directory Traversal Protection: The middleware auto-sanitizes paths (e.g., ../../etc/passwd → 400/404), but never trust user input for path construction outside this middleware. Verify your request routing doesn’t leak full paths.
MIME Type Reliance: MIME detection uses finfo_file() — ensure the fileinfo extension is enabled. Misconfigured MIME types (e.g., missing text/html for .html) often stem from system locale or missing mime.types files.
Index Files Behavior: By default, / serves index.html. To disable this, pass false for $index in the constructor:
$middleware = new StaticContentMiddleware($root, index: false);
Streaming Performance: Files > ~10 MB should be streamed (handled automatically), but memory usage spikes can occur if the event loop is blocked elsewhere. Profile your loop with amphp/byte-stream or amphp/cache.
Overriding Headers: The middleware sets headers (e.g., Content-Type, Cache-Control, ETag). To customize, wrap it in a decorator:
class CustomStaticMiddleware implements Middleware {
private StaticContentMiddleware $inner;
public function __construct(StaticContentMiddleware $inner) { $this->inner = $inner; }
public function handle(Request $request, Response $response): void {
$this->inner->handle($request, $response);
$response->setHeader('X-Content-Type-Options', 'nosniff');
}
}
Testing Locally: Use php -S localhost:8080 -t public only for dev, but in production always run via Amp\Server — static content middleware uses async I/O (Amp\File) and won’t work with Apache/Nginx directly.
How can I help you explore Laravel packages today?