Ship production optimization M1-M12.5A: queues, metrics, HTTP observability, and vector search reliability.
Keep similar-ai from tripping the global circuit on a lone URL 502, clamp Qdrant search to 100, and add Server-Timing plus slow-request logging. Studio shared props, Academy S3 exists caching, heat chunking, and Redis/scheduler hygiene stay in this rollout.
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Support\Http;
|
||||
|
||||
final class HttpUriNormalizer
|
||||
{
|
||||
public function normalize(string $uri): string
|
||||
{
|
||||
$path = parse_url($uri, PHP_URL_PATH);
|
||||
if (! is_string($path) || $path === '') {
|
||||
$path = $uri;
|
||||
}
|
||||
|
||||
$path = '/'.ltrim($path, '/');
|
||||
if ($path !== '/') {
|
||||
$path = rtrim($path, '/');
|
||||
}
|
||||
|
||||
if (preg_match('#^/@([^/]+)(/.*)?$#', $path, $matches) === 1) {
|
||||
$rest = $matches[2] ?? '';
|
||||
|
||||
return '/@{user}'.$this->normalizeSegments($rest);
|
||||
}
|
||||
|
||||
return $this->normalizeSegments($path);
|
||||
}
|
||||
|
||||
private function normalizeSegments(string $path): string
|
||||
{
|
||||
if ($path === '' || $path === '/') {
|
||||
return $path === '' ? '' : '/';
|
||||
}
|
||||
|
||||
$segments = explode('/', $path);
|
||||
$normalized = [];
|
||||
|
||||
foreach ($segments as $index => $segment) {
|
||||
if ($segment === '') {
|
||||
$normalized[] = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
$normalized[] = $this->normalizeSegment($segment, $index, $segments);
|
||||
}
|
||||
|
||||
$result = implode('/', $normalized);
|
||||
|
||||
return $result === '' ? '/' : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $segments
|
||||
*/
|
||||
private function normalizeSegment(string $segment, int $index, array $segments): string
|
||||
{
|
||||
if (ctype_digit($segment)) {
|
||||
return '{id}';
|
||||
}
|
||||
|
||||
if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $segment) === 1) {
|
||||
return '{uuid}';
|
||||
}
|
||||
|
||||
if (preg_match('/^[0-9a-f]{32,64}$/i', $segment) === 1) {
|
||||
return '{hash}';
|
||||
}
|
||||
|
||||
if ($this->isArtworkPublicSlug($segment, $index, $segments)) {
|
||||
return '{slug}';
|
||||
}
|
||||
|
||||
return $segment;
|
||||
}
|
||||
|
||||
/**
|
||||
* /art/{id}/{slug} stays distinct from /art/{id}/similar and other actions.
|
||||
*
|
||||
* @param array<int, string> $segments
|
||||
*/
|
||||
private function isArtworkPublicSlug(string $segment, int $index, array $segments): bool
|
||||
{
|
||||
if ($index !== 3 || ($segments[1] ?? '') !== 'art') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! ctype_digit((string) ($segments[2] ?? ''))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$actions = ['similar', 'view', 'download', 'edit', 'comments', 'favourite', 'favorite'];
|
||||
|
||||
return ! in_array(strtolower($segment), $actions, true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user