Spaces:
Build error
Build error
| // ── Parse the username from the URL ────────────────────────────────────────── | |
| // Expected URL format: https://emalawi19-php-hosting.hf.space/site/username/ | |
| // e.g. /site/alice/index.php → serves /data/sites/alice/htdocs/index.php | |
| $requestUri = $_SERVER['REQUEST_URI']; | |
| // Strip query string | |
| $path = parse_url($requestUri, PHP_URL_PATH); | |
| // Match /site/{username}/{filepath} | |
| if (!preg_match('#^/site/([a-z0-9]{3,32})(/.*)?$#', $path, $matches)) { | |
| http_response_code(400); | |
| echo '<h1>400 Bad Request</h1><p>Invalid site URL format.</p>'; | |
| echo '<p>Use: /site/username/filename.php</p>'; | |
| exit; | |
| } | |
| $username = $matches[1]; | |
| $filePath = $matches[2] ?? '/index.php'; | |
| // Default to index.php if only directory requested | |
| if (substr($filePath, -1) === '/') { | |
| $filePath .= 'index.php'; | |
| } | |
| // Sanitise — prevent directory traversal | |
| $filePath = '/' . implode('/', array_filter(array_map(function($part) { | |
| return ($part === '..' || $part === '.') ? '' : $part; | |
| }, explode('/', $filePath)))); | |
| // Check user exists | |
| $db = new PDO('sqlite:/data/db/platform.sqlite'); | |
| $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
| $stmt = $db->prepare('SELECT id FROM users WHERE username = ?'); | |
| $stmt->execute([$username]); | |
| if (!$stmt->fetch()) { | |
| http_response_code(404); | |
| echo '<h1>404 Not Found</h1><p>No site found for user: ' . htmlspecialchars($username) . '</p>'; | |
| exit; | |
| } | |
| $htdocs = "/data/sites/{$username}/htdocs"; | |
| $fullPath = $htdocs . $filePath; | |
| if (!file_exists($fullPath)) { | |
| http_response_code(404); | |
| echo '<h1>404 Not Found</h1><p>File not found: ' . htmlspecialchars($filePath) . '</p>'; | |
| exit; | |
| } | |
| // ── Serve static files directly ─────────────────────────────────────────────── | |
| $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION)); | |
| $mimeTypes = [ | |
| 'html' => 'text/html', | |
| 'htm' => 'text/html', | |
| 'css' => 'text/css', | |
| 'js' => 'application/javascript', | |
| 'json' => 'application/json', | |
| 'png' => 'image/png', | |
| 'jpg' => 'image/jpeg', | |
| 'jpeg' => 'image/jpeg', | |
| 'gif' => 'image/gif', | |
| 'webp' => 'image/webp', | |
| 'svg' => 'image/svg+xml', | |
| 'ico' => 'image/x-icon', | |
| 'txt' => 'text/plain', | |
| 'pdf' => 'application/pdf', | |
| 'woff' => 'font/woff', | |
| 'woff2'=> 'font/woff2', | |
| ]; | |
| if ($ext !== 'php') { | |
| $mime = $mimeTypes[$ext] ?? 'application/octet-stream'; | |
| header("Content-Type: {$mime}"); | |
| readfile($fullPath); | |
| exit; | |
| } | |
| // ── Execute PHP files ───────────────────────────────────────────────────────── | |
| // Set environment so the included PHP file feels like it was requested directly | |
| $_SERVER['DOCUMENT_ROOT'] = $htdocs; | |
| $_SERVER['SCRIPT_FILENAME'] = $fullPath; | |
| $_SERVER['SCRIPT_NAME'] = $filePath; | |
| $_SERVER['PHP_SELF'] = $filePath; | |
| // Change working directory so relative includes work | |
| chdir($htdocs); | |
| // Buffer and include the PHP file | |
| ob_start(); | |
| include $fullPath; | |
| $output = ob_get_clean(); | |
| echo $output; |