<?php
// serve_raw.php
// 必要：$pathInfo（index.php からスコープ共有）

if (!$pathInfo['exists'] || !$pathInfo['is_file']) {
    http_response_code(404);
    echo "404 Not Found";
    exit;
}

$full  = $pathInfo['full'];
$size  = filesize($full);
$mtime = filemtime($full);
$etag  = '"' . sha1($full . '|' . $size . '|' . $mtime) . '"';
$mime  = @mime_content_type($full) ?: 'application/octet-stream';

// CORS が必要なら以下の1行を有効化
// header('Access-Control-Allow-Origin: *');

header("Content-Type: {$mime}");
header('Accept-Ranges: bytes');
header("ETag: {$etag}");
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $mtime) . ' GMT');
header('Cache-Control: public, max-age=31536000, immutable'); // 長期キャッシュ

// 304 判定
$ifNoneMatch     = $_SERVER['HTTP_IF_NONE_MATCH'] ?? '';
$ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? '';
if ($ifNoneMatch === $etag || ($ifModifiedSince && strtotime($ifModifiedSince) >= $mtime)) {
    http_response_code(304);
    exit;
}

// Range（部分配信）対応
$range = $_SERVER['HTTP_RANGE'] ?? '';
if ($range && preg_match('/bytes=(\d*)-(\d*)/', $range, $m)) {
    $start = ($m[1] === '') ? 0 : (int)$m[1];
    $end   = ($m[2] === '') ? ($size - 1) : (int)$m[2];
    if ($start > $end || $start >= $size) {
        header("Content-Range: bytes */{$size}");
        http_response_code(416); // Range Not Satisfiable
        exit;
    }
    $length = $end - $start + 1;
    header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
    header('Content-Length: ' . $length);
    http_response_code(206);

    $fp = fopen($full, 'rb');
    fseek($fp, $start);
    $buf = 8192;
    $sent = 0;
    while (!feof($fp) && $sent < $length) {
        $read = min($buf, $length - $sent);
        $chunk = fread($fp, $read);
        if ($chunk === false) break;
        echo $chunk;
        $sent += strlen($chunk);
        if (connection_aborted()) break;
    }
    fclose($fp);
    exit;
}

// 全体配信
header('Content-Length: ' . $size);
readfile($full);
