.+?)__(?P.+?)__(?P\\d+)-(?P[A-Za-z]+)\\.(?P[A-Za-z0-9]+)$/', $requestedFilename, $parts)) { http_response_code(404); header('Content-Type: text/plain; charset=utf-8'); echo 'Not found'; exit; } $prefix = (string)$parts['prefix']; $type = (string)$parts['type']; $baseDir = __DIR__ . '/fileadmin/downloads/Collateral'; if (!is_dir($baseDir) || !is_readable($baseDir)) { http_response_code(404); header('Content-Type: text/plain; charset=utf-8'); echo 'Not found'; exit; } $escapedPrefix = preg_quote($prefix, '/'); $escapedType = preg_quote($type, '/'); $pattern = '/^' . $escapedPrefix . '__' . $escapedType . '__(\\d+)-([A-Za-z]+)\\.([A-Za-z0-9]+)$/'; $bestFilename = null; $bestNumber = -1; $bestLetterRank = -1; $entries = scandir($baseDir); if ($entries === false) { http_response_code(404); header('Content-Type: text/plain; charset=utf-8'); echo 'Not found'; exit; } foreach ($entries as $entry) { if (!is_string($entry) || $entry === '.' || $entry === '..') { continue; } if (!preg_match($pattern, $entry, $matches)) { continue; } $number = (int)$matches[1]; $letterRank = letterSequenceToRank((string)$matches[2]); if ($number > $bestNumber || ($number === $bestNumber && $letterRank > $bestLetterRank)) { $bestNumber = $number; $bestLetterRank = $letterRank; $bestFilename = $entry; } } if ($bestFilename === null) { http_response_code(404); header('Content-Type: text/plain; charset=utf-8'); echo 'Not found'; exit; } $bestPath = $baseDir . '/' . $bestFilename; if (!is_file($bestPath) || !is_readable($bestPath)) { http_response_code(404); header('Content-Type: text/plain; charset=utf-8'); echo 'Not found'; exit; } $clientIp = isset($_SERVER['REMOTE_ADDR']) ? (string)$_SERVER['REMOTE_ADDR'] : '-'; $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? (string)$_SERVER['HTTP_USER_AGENT'] : '-'; logFallbackRecovery($requestedFilename, $bestFilename, $clientIp, $userAgent); $target = '/fileadmin/downloads/Collateral/' . rawurlencode($bestFilename); header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Pragma: no-cache'); header('Location: ' . $target, true, 302); exit; function letterSequenceToRank(string $letters): int { $rank = 0; $letters = strtoupper($letters); $length = strlen($letters); for ($i = 0; $i < $length; $i++) { $char = ord($letters[$i]); if ($char < 65 || $char > 90) { continue; } $rank = ($rank * 26) + ($char - 64); } return $rank; } function logFallbackRecovery(string $requested, string $resolved, string $clientIp, string $userAgent): void { $logDir = dirname(__DIR__) . '/var/log'; if (!is_dir($logDir)) { return; } $timestamp = gmdate('c'); $line = sprintf( "%s collateral-fallback requested=\"%s\" resolved=\"%s\" ip=%s ua=\"%s\"\n", $timestamp, str_replace('"', '\\"', $requested), str_replace('"', '\\"', $resolved), $clientIp, str_replace('"', '\\"', $userAgent) ); @file_put_contents($logDir . '/collateral-fallback.log', $line, FILE_APPEND | LOCK_EX); }