![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/public_html/ |
<?php
// Audio Files Handler - Serves local audio files securely
session_start();
// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 0);
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
header('Content-Type: text/plain');
echo "Unauthorized - Please log in";
exit;
}
// Get the task ID and variation from the URL
$taskId = $_GET['id'] ?? '';
$variationIndex = $_GET['variation'] ?? null;
if (empty($taskId)) {
http_response_code(400);
header('Content-Type: text/plain');
echo "Missing id parameter";
exit;
}
// Validate task ID format (alphanumeric)
if (!preg_match('/^[a-zA-Z0-9]+$/', $taskId)) {
http_response_code(400);
header('Content-Type: text/plain');
echo "Invalid id format";
exit;
}
// Include database configuration
require_once 'config/database.php';
// Verify the user owns this track
$pdo = getDBConnection();
if (!$pdo) {
http_response_code(500);
header('Content-Type: text/plain');
echo "Database error";
exit;
}
$stmt = $pdo->prepare("SELECT * FROM music_tracks WHERE task_id = ? AND user_id = ? AND status = 'complete'");
$stmt->execute([$taskId, $_SESSION['user_id']]);
$track = $stmt->fetch();
if (!$track) {
http_response_code(404);
header('Content-Type: text/plain');
echo "Track not found or access denied";
exit;
}
// If variation is requested, get it from audio_variations table
if ($variationIndex !== null) {
$stmt = $pdo->prepare("SELECT * FROM audio_variations WHERE track_id = ? AND variation_index = ?");
$stmt->execute([$track['id'], $variationIndex]);
$variation = $stmt->fetch();
if (!$variation) {
http_response_code(404);
header('Content-Type: text/plain');
echo "Variation not found";
exit;
}
// Use the variation's audio URL
$audioUrl = $variation['audio_url'];
} else {
// Use the main track's audio URL
$audioUrl = $track['audio_url'];
}
if (empty($audioUrl)) {
http_response_code(404);
header('Content-Type: text/plain');
echo "No audio URL found for this track";
exit;
}
// SECURITY: Check if it's a local file path and validate it
if (strpos($audioUrl, '/audio_files/') === 0 || strpos($audioUrl, '/uploads/') === 0) {
// Use file security utility to validate path
require_once __DIR__ . '/includes/file_security.php';
$audio_validation = validateAudioUrl($audioUrl);
if ($audio_validation['type'] !== 'local' || !$audio_validation['path']) {
// Path validation failed - security violation
error_log("SECURITY: Invalid audio path in audiofiles.php: " . htmlspecialchars($audioUrl, ENT_QUOTES, 'UTF-8'));
http_response_code(403);
header('Content-Type: text/plain');
echo "Access denied";
exit;
}
$localPath = $audio_validation['path'];
if (file_exists($localPath)) {
$fileSize = filesize($localPath);
$fileType = mime_content_type($localPath);
// Set proper headers for local file
header('Content-Type: ' . $fileType);
header('Content-Length: ' . $fileSize);
header('Accept-Ranges: bytes');
header('Cache-Control: public, max-age=31536000'); // Cache for 1 year
header('ETag: "' . md5_file($localPath) . '"');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($localPath)) . ' GMT');
header('Content-Disposition: inline; filename="' . basename($localPath) . '"');
// Handle range requests for streaming
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
$range = str_replace('bytes=', '', $range);
$range = explode('-', $range);
$start = intval($range[0]);
$end = isset($range[1]) && $range[1] !== '' ? intval($range[1]) : $fileSize - 1;
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $fileSize);
header('Content-Length: ' . ($end - $start + 1));
$handle = fopen($localPath, 'rb');
fseek($handle, $start);
$buffer = 1024 * 8;
while (!feof($handle) && ftell($handle) <= $end) {
echo fread($handle, min($buffer, $end - ftell($handle) + 1));
flush();
}
fclose($handle);
} else {
// Serve the entire file
readfile($localPath);
}
exit;
} else {
http_response_code(404);
header('Content-Type: text/plain');
echo "Local file not found: " . $localPath;
exit;
}
}
// If it's still an external URL, stream it (fallback)
if (strpos($audioUrl, 'http') === 0) {
// Set headers for audio streaming
header('Content-Type: audio/mpeg');
header('Accept-Ranges: bytes');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Content-Disposition: inline; filename="' . $taskId . '.mp3"');
// Clear any output buffers
while (ob_get_level()) {
ob_end_clean();
}
// Stream the audio from external URL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $audioUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // Stream directly to output
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) {
echo $data;
return strlen($data);
});
$httpCode = curl_exec($ch);
$curlError = curl_error($ch);
curl_close($ch);
if ($httpCode === false || !empty($curlError)) {
http_response_code(500);
header('Content-Type: text/plain');
echo "Failed to stream audio: " . $curlError;
}
exit;
}
// Fallback - file not found
http_response_code(404);
header('Content-Type: text/plain');
echo "Audio not available - unsupported URL format: " . $audioUrl;
?>