File size: 3,256 Bytes
0129337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
// ── 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;