first
This commit is contained in:
140
server-api/app/support/PublicAssetUrlService.php
Normal file
140
server-api/app/support/PublicAssetUrlService.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace app\support;
|
||||
|
||||
use support\Request;
|
||||
|
||||
class PublicAssetUrlService
|
||||
{
|
||||
public function buildUrl(Request $request, string $relativePath): string
|
||||
{
|
||||
$relativePath = ltrim($relativePath, '/');
|
||||
$publicPath = $this->configService()->isOss()
|
||||
? $this->configService()->objectKey($relativePath)
|
||||
: $relativePath;
|
||||
|
||||
return $this->resolveBaseUrl($request) . '/' . ltrim($publicPath, '/');
|
||||
}
|
||||
|
||||
public function normalizeUrl(string $value, Request $request): string
|
||||
{
|
||||
$value = trim($value);
|
||||
if ($value === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$parts = parse_url($value);
|
||||
$path = (string)($parts['path'] ?? '');
|
||||
$query = (string)($parts['query'] ?? '');
|
||||
$fragment = (string)($parts['fragment'] ?? '');
|
||||
$host = strtolower((string)($parts['host'] ?? ''));
|
||||
$scheme = (string)($parts['scheme'] ?? '');
|
||||
|
||||
if ($scheme === '' && $host === '') {
|
||||
return $this->appendQueryAndFragment(
|
||||
$this->buildUrl($request, $path !== '' ? $path : $value),
|
||||
$query,
|
||||
$fragment
|
||||
);
|
||||
}
|
||||
|
||||
if ($path !== '' && $this->shouldRewriteHost($host)) {
|
||||
return $this->appendQueryAndFragment(
|
||||
$this->buildUrl($request, $path),
|
||||
$query,
|
||||
$fragment
|
||||
);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function storagePath(string $value): string
|
||||
{
|
||||
$value = trim($value);
|
||||
if ($value === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$path = parse_url($value, PHP_URL_PATH);
|
||||
if (!is_string($path) || $path === '') {
|
||||
$path = ltrim($value, '/');
|
||||
return $this->configService()->isOss() ? $this->configService()->removePathPrefix($path) : $path;
|
||||
}
|
||||
|
||||
$path = ltrim($path, '/');
|
||||
return $this->configService()->isOss() ? $this->configService()->removePathPrefix($path) : $path;
|
||||
}
|
||||
|
||||
private function resolveBaseUrl(Request $request): string
|
||||
{
|
||||
$configured = $this->configService()->publicBaseUrl();
|
||||
if ($configured !== '') {
|
||||
return $configured;
|
||||
}
|
||||
|
||||
$configured = trim((string)($_ENV['PUBLIC_FILE_BASE_URL'] ?? ($_ENV['APP_PUBLIC_BASE_URL'] ?? '')));
|
||||
if ($configured !== '') {
|
||||
return $this->normalizeBaseUrl($configured);
|
||||
}
|
||||
|
||||
$scheme = trim((string)($request->header('x-forwarded-proto') ?: 'http'));
|
||||
$host = trim((string)($request->header('x-forwarded-host') ?: $request->header('host') ?: $request->host()));
|
||||
if (($commaPos = strpos($host, ',')) !== false) {
|
||||
$host = trim(substr($host, 0, $commaPos));
|
||||
}
|
||||
|
||||
$port = trim((string)($request->header('x-forwarded-port') ?: ''));
|
||||
if ($port !== '' && strpos($host, ':') === false) {
|
||||
if (!(($scheme === 'http' && $port === '80') || ($scheme === 'https' && $port === '443'))) {
|
||||
$host .= ':' . $port;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->normalizeBaseUrl($scheme . '://' . $host);
|
||||
}
|
||||
|
||||
private function normalizeBaseUrl(string $baseUrl): string
|
||||
{
|
||||
$baseUrl = trim($baseUrl);
|
||||
if ($baseUrl === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!preg_match('/^https?:\/\//i', $baseUrl)) {
|
||||
$baseUrl = 'https://' . ltrim($baseUrl, '/');
|
||||
}
|
||||
|
||||
return rtrim($baseUrl, '/');
|
||||
}
|
||||
|
||||
private function configService(): FileStorageConfigService
|
||||
{
|
||||
return new FileStorageConfigService();
|
||||
}
|
||||
|
||||
private function shouldRewriteHost(string $host): bool
|
||||
{
|
||||
if ($host === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array($host, ['localhost', '127.0.0.1', '0.0.0.0', 'host.docker.internal'], true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return preg_match('/^(10\.|192\.168\.|172\.(1[6-9]|2\d|3[0-1])\.)/', $host) === 1;
|
||||
}
|
||||
|
||||
private function appendQueryAndFragment(string $url, string $query, string $fragment): string
|
||||
{
|
||||
if ($query !== '') {
|
||||
$url .= '?' . $query;
|
||||
}
|
||||
if ($fragment !== '') {
|
||||
$url .= '#' . $fragment;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user