HTTP Configuration
Middleware aliases, rate limiting, and trusted proxy handling.
config/http.php controls the HTTP middleware stack, named rate limiters, and trusted proxy behavior.
Middleware aliases #
Built-in middleware aliases:
| Alias | Class |
|---|---|
errors |
VelvetCMS\Http\Middleware\ErrorHandlingMiddleware |
throttle |
VelvetCMS\Http\Middleware\ThrottleRequests |
csrf |
VelvetCMS\Http\Middleware\VerifyCsrfToken |
session |
VelvetCMS\Http\Middleware\StartSessionMiddleware |
Global middleware #
The default global stack applies to every request:
'global' => [
'errors',
'session',
'throttle',
],
Override it in user/config/http.php when you need a different baseline.
Rate limiting #
Rate limiting uses named limiters with configurable attempts, decay windows, and key strategies.
Configuration #
'rate_limit' => [
'enabled' => true,
'default' => 'standard',
'limiters' => [
'standard' => ['attempts' => 60, 'decay' => 60, 'by' => 'ip'],
'api' => ['attempts' => 120, 'decay' => 60, 'by' => 'ip'],
'auth' => ['attempts' => 5, 'decay' => 60, 'by' => 'ip'],
'strict' => ['attempts' => 10, 'decay' => 60, 'by' => 'ip'],
],
'whitelist' => ['127.0.0.1', '::1'],
],
Keys #
| Key | Default | Description |
|---|---|---|
http.rate_limit.enabled |
true |
Enable or disable rate limiting globally |
http.rate_limit.default |
standard |
Default limiter name |
http.rate_limit.limiters |
Built-ins shown above | Named limiter definitions |
http.rate_limit.whitelist |
Localhost IPv4 and IPv6 | IPs that bypass rate limiting |
Using named limiters #
$router->post('/api/data', [ApiController::class, 'store'])
->middleware('throttle:api');
$router->post('/login', [AuthController::class, 'login'])
->middleware('throttle:auth');
Programmatic limiters #
use VelvetCMS\Http\RateLimiting\Limit;
use VelvetCMS\Http\RateLimiting\RateLimiter;
$rateLimiter = app(RateLimiter::class);
$rateLimiter->for('uploads', Limit::perMinute(10));
$rateLimiter->for('internal', fn () => Limit::none());
Limit helper API #
Limit::perMinute(60);
Limit::perHour(1000);
Limit::perDay(10000);
Limit::perSeconds(30, 10);
Limit::none();
You can also customize the keying strategy:
Limit::perMinute(60)->by('ip');
Limit::perMinute(60)->by('ip_route');
Limit::perMinute(60)->withKey('custom-key');
Trusted Proxies #
Reverse proxy support is opt-in. If your app sits behind Nginx, Apache, Caddy, a load balancer, or a CDN, you can tell the request layer which proxy IPs are trusted and which forwarded headers it should honor.
'trusted_proxies' => [
'enabled' => false,
'proxies' => [],
'headers' => [
'for' => 'X-Forwarded-For',
'proto' => 'X-Forwarded-Proto',
'host' => 'X-Forwarded-Host',
],
],
Keys #
| Key | Description |
|---|---|
http.trusted_proxies.enabled |
Turn forwarded-header handling on or off |
http.trusted_proxies.proxies |
Trusted proxy IPs or CIDR ranges |
http.trusted_proxies.headers.for |
Header used to resolve client IP |
http.trusted_proxies.headers.proto |
Header used to resolve scheme |
http.trusted_proxies.headers.host |
Header used to resolve host |
Enable trusted proxies only when requests actually come through infrastructure you control and can identify. If you enable it too broadly, any client could spoof forwarded headers and affect URL, host, scheme, or IP resolution.
See Trusted Proxies for deployment examples.