ecphp/reverse-proxy-helper-bundle
Installation
composer require ecphp/reverse-proxy-helper-bundle
Add to config/bundles.php:
return [
// ...
Ecphp\ReverseProxyHelperBundle\EcphpReverseProxyHelperBundle::class => ['all' => true],
];
Configuration Publish the default config:
php artisan vendor:publish --tag=reverse-proxy-helper-config
Edit config/reverse_proxy_helper.php to define your proxy base URL (e.g., https://your-proxy.example.com).
First Use Case Inject the helper into a controller/service:
use Ecphp\ReverseProxyHelperBundle\ReverseProxyHelper;
public function __construct(private ReverseProxyHelper $proxyHelper) {}
public function someAction(Request $request) {
$originalUrl = $this->proxyHelper->getOriginalUrl($request);
// Use $originalUrl (e.g., for logging, redirects, or API forwarding)
}
Request Header Normalization
Automatically rewrite headers (e.g., X-Forwarded-*) to reflect the original request path/host:
$originalHost = $this->proxyHelper->getOriginalHost($request);
$originalPath = $this->proxyHelper->getOriginalPath($request);
Proxy-Aware Redirects Preserve the original URL when redirecting behind a proxy:
return redirect()->to($this->proxyHelper->getOriginalUrl($request . '/new-path'));
API Forwarding Forward requests to an internal service while exposing the original client IP/URL:
$internalUrl = $this->proxyHelper->getInternalUrl($request, 'api.internal');
$response = Http::get($internalUrl);
Middleware Integration Use the helper in middleware to normalize requests early:
public function handle(Request $request, Closure $next) {
$request = $this->proxyHelper->normalizeRequest($request);
return $next($request);
}
Service Container Binding Bind the helper to a custom interface for testability:
$this->app->bind(
OriginalUrlResolver::class,
fn() => new ReverseProxyHelper($this->app['config'])
);
Dynamic Proxy Detection
Combine with Request::server() to handle multi-proxy setups:
$proxyUrl = $request->server('HTTP_X_PROXY_BASE') ?? config('reverse_proxy_helper.base_url');
$this->proxyHelper->setBaseUrl($proxyUrl);
Header Conflicts
X-Forwarded-* headers are manually set, they may override the bundle’s logic. Use normalizeRequest() to ensure consistency:
$normalizedRequest = $this->proxyHelper->normalizeRequest($request);
HTTPS Mismatches
'schemes' => ['http', 'https'], // in config
Path Normalization
base_url may cause double-slashes in reconstructed URLs. Trim paths in config:
'base_url' => rtrim(config('reverse_proxy_helper.base_url'), '/'),
Log Raw Headers Inspect incoming headers to debug proxy misconfigurations:
\Log::debug('Raw headers:', $request->header());
Test with curl
Simulate proxy requests locally:
curl -H "X-Forwarded-Host: test.example.com" http://localhost:8000
Custom Header Mappings
Extend the ReverseProxyHelper to support non-standard headers:
$helper->addHeaderMapping('X-Custom-Forwarded', 'custom_forwarded');
Event Listeners
Listen for reverse_proxy.normalize events to intercept/modify normalization:
public function handleNormalize(Request $request, NormalizeEvent $event) {
$event->setOriginalHost('custom-host.example.com');
}
Proxy Chaining
For nested proxies, chain helpers or override getInternalUrl():
$internalUrl = $this->proxyHelper->getInternalUrl(
$request,
'internal-service',
['X-Forwarded-For' => $request->ip()]
);
How can I help you explore Laravel packages today?