69 lines
2.1 KiB
PHP
69 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\common\library\admin;
|
|
|
|
use Webman\Http\Request;
|
|
|
|
final class WebSocketConfigHelper
|
|
{
|
|
public static function wsUrl(?Request $request = null): string
|
|
{
|
|
$url = trim((string) env('H5_WEBSOCKET_URL', ''));
|
|
if ($url !== '' && $request !== null && self::isLoopbackWsUrl($url) && !self::isLoopbackRequestHost($request)) {
|
|
$url = '';
|
|
}
|
|
if ($url !== '') {
|
|
return $url;
|
|
}
|
|
|
|
if ($request !== null) {
|
|
$proto = strtolower((string) $request->header('x-forwarded-proto', ''));
|
|
if ($proto === '') {
|
|
$proto = strtolower((string) $request->header('x-forwarded-protocol', ''));
|
|
}
|
|
$isHttps = $proto === 'https'
|
|
|| strtolower((string) $request->header('x-forwarded-ssl', '')) === 'on'
|
|
|| strtolower((string) $request->header('x-scheme', '')) === 'https';
|
|
$scheme = $isHttps ? 'wss' : 'ws';
|
|
|
|
$host = trim((string) $request->header('host', ''));
|
|
if ($host === '') {
|
|
$host = trim((string) $request->header('x-forwarded-host', ''));
|
|
}
|
|
if ($host !== '') {
|
|
return $scheme . '://' . $host . '/ws/';
|
|
}
|
|
}
|
|
|
|
return 'ws://127.0.0.1:3131/ws/';
|
|
}
|
|
|
|
private static function isLoopbackWsUrl(string $url): bool
|
|
{
|
|
$host = parse_url($url, PHP_URL_HOST);
|
|
if (!is_string($host) || $host === '') {
|
|
return false;
|
|
}
|
|
$host = strtolower($host);
|
|
|
|
return in_array($host, ['127.0.0.1', 'localhost', '::1'], true);
|
|
}
|
|
|
|
private static function isLoopbackRequestHost(Request $request): bool
|
|
{
|
|
$host = strtolower(trim((string) $request->host(true)));
|
|
if ($host === '') {
|
|
$host = strtolower(trim((string) $request->header('host', '')));
|
|
}
|
|
if ($host === '') {
|
|
return false;
|
|
}
|
|
$hostOnly = preg_split('/:/', $host)[0] ?? $host;
|
|
|
|
return in_array($hostOnly, ['127.0.0.1', 'localhost', '::1'], true);
|
|
}
|
|
}
|
|
|