CI / php (push) Successful in 1m39s
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.
93 lines
2.7 KiB
PHP
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);
|
|
}
|
|
}
|