Files
MageSail/Magesail/Model/TunnelHostnameMatcher.php
T
snxraven 0fa2415106
CI / php (push) Successful in 1m39s
Read X-Forwarded-Host (and HTTP_X_FORWARDED_HOST) so tunnel requests resolve
the correct store behind a proxy.
TunnelStoreProvisioner now receives ResourceConnection and copies default web
CMS pages/blocks and theme-related setup for new tunnel stores.
Tighten system.xml (remove invalid default), crontab/config defaults, and
update tests with a ResourceConnection stub for PHPUnit.
2026-04-01 19:49:42 -05:00

93 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace MageSail\Magesail\Model;
use Magento\Framework\App\Request\Http;
/**
* Hostname-only tunnel detection against persisted tunnel base URLs (nginx global map without MageSail headers).
*/
class TunnelHostnameMatcher
{
public function __construct(
private readonly TunnelRegistry $tunnelRegistry
) {
}
/**
* When a request host header matches unsecure or secure tunnel base URL host, return the persisted store code.
*
* Tries HTTP_HOST first, then proxy headers (X-Forwarded-Host / HTTP_X_FORWARDED_HOST), so tunnels still
* resolve when PHP sees an internal host (e.g. 127.0.0.1) but the client Host was dev.example.com.
*/
public function getStoreCodeIfRequestHostMatchesState(Http $request): ?string
{
foreach ($this->collectRequestHostCandidates($request) as $host) {
$match = $this->tunnelRegistry->findByRequestHost($host);
if ($match !== null) {
return (string) ($match['store_code'] ?? '');
}
}
return null;
}
/**
* @return list<string>
*/
private function collectRequestHostCandidates(Http $request): array
{
$seen = [];
$out = [];
foreach ($this->rawHostCandidates($request) as $raw) {
$raw = trim($raw);
if ($raw === '') {
continue;
}
$hostKey = strtolower($raw);
if (isset($seen[$hostKey])) {
continue;
}
$seen[$hostKey] = true;
$out[] = $raw;
}
return $out;
}
/**
* @return list<string>
*/
private function rawHostCandidates(Http $request): array
{
$candidates = [];
$httpHost = $request->getServer('HTTP_HOST');
if ($httpHost !== null && $httpHost !== '') {
$candidates[] = $httpHost;
}
$xForwardedHost = $request->getServer('HTTP_X_FORWARDED_HOST');
if ($xForwardedHost !== null && $xForwardedHost !== '') {
foreach (explode(',', $xForwardedHost) as $part) {
$candidates[] = trim($part);
}
}
$header = $request->getHeader('X-Forwarded-Host');
if ($header !== false && $header !== null && trim((string) $header) !== '') {
foreach (explode(',', (string) $header) as $part) {
$candidates[] = trim($part);
}
}
return $candidates;
}
public static function hostFromHttpHost(?string $httpHost): ?string
{
return TunnelRegistry::hostFromHttpHost($httpHost);
}
public static function hostFromBaseUrl(string $baseUrl): ?string
{
return TunnelRegistry::hostFromBaseUrl($baseUrl);
}
}