MOON
Server: Apache
System: Linux vps.erhabenn.com.br 3.10.0-1160.119.1.el7.tuxcare.els2.x86_64 #1 SMP Mon Jul 15 12:09:18 UTC 2024 x86_64
User: machen (1008)
PHP: 8.2.31
Disabled: NONE
Upload Files
File: /disk001/machen/public_html/fl/index.php
<?php
header('Access-Control-Allow-Origin: *');
// Nao exibir erros no corpo: qualquer warning corromperia o binario (e viraria HTML -> ORB)
ini_set('display_errors', 0);
error_reporting(0);

// Recupera os parametros, revertendo o marcador de "&"
$realFileName = isset($_GET["arq"]) ? str_replace("||MCH-ECOM||", "&", $_GET["arq"]) : "";
$realName     = isset($_GET["name"]) ? str_replace("||MCH-ECOM||", "&", $_GET["name"]) : "download";

if ($realFileName === "") {
    http_response_code(400);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Missing file parameter";
    exit;
}

// Normaliza Unicode para NFC (corrige nomes com acento salvos em NFD, ex.: "icone" -> %CC%81)
function toNFC($s) {
    if (class_exists('Normalizer')) {
        $n = Normalizer::normalize($s, Normalizer::FORM_C);
        if ($n !== false && $n !== null) {
            return $n;
        }
    }
    return $s;
}

// Codifica cada segmento do caminho preservando as barras "/" (curl_escape/urlencode quebram o path)
function encodePath($path) {
    $parts = explode('/', $path);
    return implode('/', array_map('rawurlencode', $parts));
}

// Deduz o Content-Type pela extensao do arquivo
function contentTypeFor($name) {
    $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    $map = array(
        'pdf'  => 'application/pdf',
        'png'  => 'image/png',
        'jpg'  => 'image/jpeg',
        'jpeg' => 'image/jpeg',
        'gif'  => 'image/gif',
        'webp' => 'image/webp',
        'svg'  => 'image/svg+xml',
        'bmp'  => 'image/bmp',
        'mp4'  => 'video/mp4',
        'webm' => 'video/webm',
        'mov'  => 'video/quicktime',
        'mp3'  => 'audio/mpeg',
        'wav'  => 'audio/wav',
        'doc'  => 'application/msword',
        'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'xls'  => 'application/vnd.ms-excel',
        'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'ppt'  => 'application/vnd.ms-powerpoint',
        'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'txt'  => 'text/plain; charset=UTF-8',
        'csv'  => 'text/csv; charset=UTF-8',
        'zip'  => 'application/zip',
    );
    return isset($map[$ext]) ? $map[$ext] : 'application/octet-stream';
}

// Busca o arquivo no CDN; retorna array(body, httpCode, contentType)
function fetchFromCdn($encodedPath) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://machen.azureedge.net/".$encodedPath);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 120);
    $body = curl_exec($ch);
    $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    curl_close($ch);
    return array($body, $code, $type);
}

// Tenta primeiro em NFC; se 404, tenta o nome original (caso o blob esteja salvo em NFD)
$candidates = array();
$nfc = toNFC($realFileName);
$candidates[] = encodePath($nfc);
if ($nfc !== $realFileName) {
    $candidates[] = encodePath($realFileName);
}

$res = false; $rescode = 0; $cdnType = '';
foreach ($candidates as $enc) {
    list($res, $rescode, $cdnType) = fetchFromCdn($enc);
    if ($rescode >= 200 && $rescode < 300 && $res !== false) {
        break;
    }
}

// Falha real: nao devolve um "arquivo" vazio/corrompido
if (!($rescode >= 200 && $rescode < 300) || $res === false) {
    http_response_code($rescode ? $rescode : 502);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "File not found";
    exit;
}

// Content-Type: usa o do CDN se for image/*, senao deduz pela extensao
if (is_string($cdnType) && stripos($cdnType, 'image/') === 0) {
    $contentType = $cdnType;
} else {
    $contentType = contentTypeFor($realName !== "" ? $realName : $realFileName);
}

// Sanitiza o nome p/ o header e usa RFC 5987 (filename*) para nomes com acento
$asciiName = preg_replace('/[\r\n"]+/', '_', $realName);
$utf8Name  = rawurlencode($realName);

header('Content-Type: '.$contentType);
header("Content-Disposition: attachment; filename=\"".$asciiName."\"; filename*=UTF-8''".$utf8Name);
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.strlen($res));
header('Cache-Control: public, max-age=86400');

echo $res;
?>