diff options
Diffstat (limited to 'src/font.php')
| -rw-r--r-- | src/font.php | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/font.php b/src/font.php new file mode 100644 index 0000000..de39569 --- /dev/null +++ b/src/font.php | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | <?php | ||
| 2 | /* font.php — serve font files from the server's font directories */ | ||
| 3 | |||
| 4 | $encoded = $_GET['f'] ?? ''; | ||
| 5 | if (empty($encoded)) { | ||
| 6 | http_response_code(400); | ||
| 7 | exit('Missing parameter'); | ||
| 8 | } | ||
| 9 | |||
| 10 | $file = base64_decode($encoded, true); | ||
| 11 | if ($file === false || !file_exists($file)) { | ||
| 12 | http_response_code(404); | ||
| 13 | exit('Font not found'); | ||
| 14 | } | ||
| 15 | |||
| 16 | $real = realpath($file); | ||
| 17 | $allowed = ['/usr/share/fonts', '/usr/local/share/fonts']; | ||
| 18 | $ok = false; | ||
| 19 | |||
| 20 | foreach ($allowed as $dir) { | ||
| 21 | if (str_starts_with($real, $dir)) { | ||
| 22 | $ok = true; | ||
| 23 | break; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | if (!$ok) { | ||
| 28 | http_response_code(403); | ||
| 29 | exit('Access denied'); | ||
| 30 | } | ||
| 31 | |||
| 32 | $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); | ||
| 33 | $mime = match ($ext) { | ||
| 34 | 'ttf' => 'font/ttf', | ||
| 35 | 'otf' => 'font/otf', | ||
| 36 | 'woff' => 'font/woff', | ||
| 37 | 'woff2' => 'font/woff2', | ||
| 38 | default => 'application/octet-stream', | ||
| 39 | }; | ||
| 40 | |||
| 41 | header("Content-Type: $mime"); | ||
| 42 | header('Cache-Control: public, max-age=31536000, immutable'); | ||
| 43 | header('Content-Length: ' . filesize($file)); | ||
| 44 | readfile($file); | ||
