Directory Index PHP file Rumi, March 17, 2026 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mango CA Repository</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif; background: #f5f5f7; min-height: 100vh; padding: 20px; color: #1d1d1f; line-height: 1.47059; font-weight: 400; letter-spacing: -0.022em; } .container { max-width: 980px; margin: 0 auto; background: #ffffff; border-radius: 18px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.04); overflow: hidden; backdrop-filter: blur(20px); border: 1px solid rgba(0, 0, 0, 0.1); } .header { background: #ffffff; padding: 25px 30px; border-bottom: 1px solid #d2d2d7; text-align: left; } .header h1 { font-size: 1.2em; font-weight: 700; color: #1d1d1f; letter-spacing: -0.003em; margin: 0; } @media (max-width: 768px) { .header { padding: 20px 20px; } .header h1 { font-size: 1.1em; } } @media (max-width: 480px) { .header { padding: 15px 15px; } .header h1 { font-size: 1em; } } .directory-stats { background: #f5f5f7; padding: 12px 30px; border-bottom: 1px solid #d2d2d7; display: flex; justify-content: space-between; align-items: center; color: #86868b; font-size: 0.9em; flex-wrap: wrap; gap: 15px; } .stats-info { display: flex; gap: 20px; } .stat-item { display: flex; align-items: center; gap: 5px; color: #1d1d1f; } .stat-icon { font-size: 1.1em; color: #86868b; } .parent-link { background: #ffffff; padding: 12px 30px; border-bottom: 1px solid #d2d2d7; } .parent-link a { display: inline-flex; align-items: center; gap: 8px; color: #0066cc; text-decoration: none; padding: 6px 12px; border-radius: 6px; transition: all 0.2s ease; font-weight: 500; font-size: 0.95em; } .parent-link a:hover { background: #f5f5f7; text-decoration: underline; } .file-list { padding: 20px 30px; } @media (max-width: 640px) { .file-list { padding: 15px 15px; } } .list-header { display: grid; grid-template-columns: auto 100px 120px; padding: 12px 15px; background: #f5f5f7; border-radius: 10px; margin-bottom: 5px; font-weight: 600; color: #1d1d1f; border: 1px solid #d2d2d7; font-size: 0.9em; text-transform: uppercase; letter-spacing: 0.5px; } .file-item { display: grid; grid-template-columns: auto 100px 120px; padding: 12px 15px; border-bottom: 1px solid #e9e9ed; transition: all 0.2s ease; align-items: center; font-size: 0.95em; } .file-item:hover { background: #f5f5f7; border-radius: 8px; } .file-info { display: flex; align-items: center; gap: 12px; } .file-icon { font-size: 1.3em; width: 30px; text-align: center; color: #86868b; } .file-name { color: #1d1d1f; text-decoration: none; font-weight: 500; word-break: break-word; cursor: pointer; } .file-name:hover { color: #0066cc; text-decoration: underline; } .file-size { color: #86868b; font-size: 0.9em; } .file-modified { color: #86868b; font-size: 0.9em; } .directory-item .file-icon { color: #0066cc; } .file-item.file .file-icon { color: #86868b; } .file-item.image .file-icon { color: #00a400; } .file-item.pdf .file-icon { color: #ff3b30; } .file-item.zip .file-icon { color: #ff9500; } .footer { background: #f5f5f7; padding: 20px 30px; text-align: center; color: #86868b; border-top: 1px solid #d2d2d7; font-size: 0.85em; } .empty-directory { text-align: center; padding: 60px 20px; color: #86868b; } .empty-icon { font-size: 4em; margin-bottom: 20px; opacity: 0.5; } .search-box { margin-left: auto; } .search-input { padding: 8px 15px; border: 1px solid #d2d2d7; border-radius: 8px; font-size: 0.95em; transition: all 0.2s ease; font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif; background: #ffffff; width: 100%; max-width: 250px; } .search-input:focus { outline: none; border-color: #0066cc; box-shadow: 0 0 0 4px rgba(0, 102, 204, 0.1); } @media (max-width: 768px) { .directory-stats { flex-direction: column; align-items: flex-start; } .search-box { margin-left: 0; width: 100%; } .search-input { max-width: 100%; } } @media (max-width: 640px) { .list-header, .file-item { grid-template-columns: 1fr 80px; gap: 8px; } .file-modified { display: none; } .list-header span:last-child, .file-item .file-modified { display: none; } .stats-info { flex-wrap: wrap; gap: 15px; } .file-size { text-align: right; } } @media (max-width: 480px) { .list-header, .file-item { grid-template-columns: 1fr; gap: 5px; } .file-size { grid-row: 2; padding-left: 42px; text-align: left; } .list-header span:nth-child(2) { display: none; } .file-item .file-size { font-size: 0.85em; color: #86868b; } } /* Apple-style animation */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .file-item { animation: fadeIn 0.3s ease forwards; } /* Custom scrollbar */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: #f5f5f7; } ::-webkit-scrollbar-thumb { background: #c6c6c8; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #86868b; } /* CRL specific styling */ .file-item.crl .file-icon { color: #0066cc; } .file-item.crl .file-name { font-weight: 500; } /* Download link styling */ .download-link { text-decoration: none; color: inherit; display: block; width: 100%; } </style> </head> <body> <div class="container"> <?php // Get the requested path, default to current directory $requested_path = isset($_GET['path']) ? $_GET['path'] : '.'; // Security: Prevent directory traversal attacks $requested_path = str_replace(['../', './'], '', $requested_path); if ($requested_path === '') { $requested_path = '.'; } // Get absolute path for display $absolute_path = realpath($requested_path); if (!$absolute_path || !is_dir($absolute_path)) { die('<div class="error">Invalid directory path</div>'); } // Get directory contents $files = scandir($absolute_path); $directories = []; $file_list = []; foreach ($files as $file) { // Skip index.php and current/parent directory references if ($file === '.' || $file === '..' || $file === 'index.php') continue; $file_path = $absolute_path . DIRECTORY_SEPARATOR . $file; if (is_dir($file_path)) { $directories[] = $file; } else { $file_list[] = $file; } } // Sort alphabetically sort($directories, SORT_STRING | SORT_FLAG_CASE); sort($file_list, SORT_STRING | SORT_FLAG_CASE); // Count items $total_items = count($directories) + count($file_list); $total_dirs = count($directories); $total_files = count($file_list); // Get current year for footer $current_year = date('Y'); ?> <div class="header"> <h1>Mango CA Repository</h1> </div> <div class="directory-stats"> <div class="stats-info"> <span class="stat-item"> <span class="stat-icon">📁</span> <?php echo $total_dirs; ?> Folders </span> <span class="stat-item"> <span class="stat-icon">📄</span> <?php echo $total_files; ?> Files </span> <span class="stat-item"> <span class="stat-icon">⚡</span> <?php echo $total_items; ?> Total </span> </div> <div class="search-box"> <input type="text" class="search-input" placeholder="Search CRLs..." id="searchInput"> </div> </div> <?php if ($requested_path !== '.'): ?> <div class="parent-link"> <a href="?path=<?php echo urlencode(dirname($requested_path)); ?>"> <span>←</span> Parent Directory </a> </div> <?php endif; ?> <div class="file-list"> <div class="list-header"> <span>Name</span> <span>Size</span> <span>Modified</span> </div> <div id="fileList"> <?php if ($total_items === 0): ?> <div class="empty-directory"> <div class="empty-icon">📂</div> <h3>Empty Repository</h3> <p>No CRLs or files in this location</p> </div> <?php else: ?> <?php // Display directories first foreach ($directories as $dir): $dir_path = $absolute_path . DIRECTORY_SEPARATOR . $dir; $modified = date('M d, Y H:i', filemtime($dir_path)); ?> <div class="file-item directory-item" data-name="<?php echo htmlspecialchars(strtolower($dir)); ?>"> <div class="file-info"> <span class="file-icon">📁</span> <a href="?path=<?php echo urlencode($requested_path . DIRECTORY_SEPARATOR . $dir); ?>" class="file-name"> <?php echo htmlspecialchars($dir); ?> </a> </div> <div class="file-size">--</div> <div class="file-modified"><?php echo $modified; ?></div> </div> <?php endforeach; ?> <?php // Display files with download links foreach ($file_list as $file): $file_path = $absolute_path . DIRECTORY_SEPARATOR . $file; $size = filesize($file_path); $modified = date('M d, Y H:i', filemtime($file_path)); // Format file size if ($size < 1024) { $size_formatted = $size . ' B'; } elseif ($size < 1048576) { $size_formatted = round($size / 1024, 1) . ' KB'; } elseif ($size < 1073741824) { $size_formatted = round($size / 1048576, 1) . ' MB'; } else { $size_formatted = round($size / 1073741824, 1) . ' GB'; } // Determine file type for icon $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); $icon = '📄'; $file_class = 'file'; $image_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp']; $pdf_extensions = ['pdf']; $zip_extensions = ['zip', 'rar', '7z', 'tar', 'gz']; $crl_extensions = ['crl', 'crt', 'pem', 'der']; if (in_array($extension, $crl_extensions)) { $icon = '🔒'; $file_class = 'crl'; } elseif (in_array($extension, $image_extensions)) { $icon = '🖼️'; $file_class = 'image'; } elseif (in_array($extension, $pdf_extensions)) { $icon = '📕'; $file_class = 'pdf'; } elseif (in_array($extension, $zip_extensions)) { $icon = '🗜️'; $file_class = 'zip'; } ?> <div class="file-item <?php echo $file_class; ?>" data-name="<?php echo htmlspecialchars(strtolower($file)); ?>"> <div class="file-info"> <span class="file-icon"><?php echo $icon; ?></span> <?php // Create download link for files $relative_path = $requested_path . DIRECTORY_SEPARATOR . $file; if ($requested_path === '.') { $relative_path = $file; } ?> <a href="?download=<?php echo urlencode($relative_path); ?>" class="file-name" download> <?php echo htmlspecialchars($file); ?> </a> </div> <div class="file-size"><?php echo $size_formatted; ?></div> <div class="file-modified"><?php echo $modified; ?></div> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> <div class="footer"> <p>© Mango Teleservices Limited - 2012-<?php echo $current_year; ?></p> </div> </div> <?php // Handle file download if (isset($_GET['download'])) { $download_file = $_GET['download']; // Security: Prevent directory traversal $download_file = str_replace(['../', './'], '', $download_file); $file_path = realpath($download_file); // Check if file exists and is within allowed directory if ($file_path && file_exists($file_path) && is_file($file_path)) { // Get file info $file_name = basename($file_path); $file_size = filesize($file_path); // Set headers for download header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $file_name . '"'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . $file_size); // Clear output buffer ob_clean(); flush(); // Read file and output to browser readfile($file_path); exit; } } ?> <script> // Live search functionality document.getElementById('searchInput').addEventListener('keyup', function() { let searchTerm = this.value.toLowerCase(); let items = document.querySelectorAll('.file-item'); items.forEach(function(item) { let fileName = item.getAttribute('data-name'); if (fileName.includes(searchTerm)) { item.style.display = 'grid'; } else { item.style.display = 'none'; } }); }); // Smooth scrolling document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); </script> </body> </html> Scripts Direcoty BrowserDirectory Browsingindex.php