f.php 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <?php
  2. declare(strict_types=1);
  3. require dirname(__DIR__) . '/constants.php';
  4. require LIB_PATH . '/lib_rss.php'; //Includes class autoloader
  5. require LIB_PATH . '/favicons.php';
  6. require LIB_PATH . '/http-conditional.php';
  7. FreshRSS_Context::initSystem();
  8. if (!FreshRSS_Context::hasSystemConf()) {
  9. header('HTTP/1.1 500 Internal Server Error');
  10. die('Invalid system init!');
  11. }
  12. $frameAncestors = FreshRSS_Context::systemConf()->attributeString('csp.frame-ancestors') ?? "'none'";
  13. header("Content-Security-Policy: default-src 'none'; frame-ancestors $frameAncestors; sandbox");
  14. header('X-Content-Type-Options: nosniff');
  15. $no_cache = file_exists(DATA_PATH . '/no-cache.txt');
  16. function show_default_favicon(int $cacheSeconds = 3600): void {
  17. global $no_cache;
  18. $default_mtime = @filemtime(DEFAULT_FAVICON) ?: 0;
  19. if ($no_cache || !httpConditional($default_mtime, $cacheSeconds, 2)) {
  20. header('Content-Type: image/x-icon');
  21. header('Content-Disposition: attachment; filename="default_favicon.ico"');
  22. readfile(DEFAULT_FAVICON);
  23. }
  24. }
  25. $id = $_GET['h'] ?? '0';
  26. if (!is_string($id) || !ctype_xdigit($id)) {
  27. $id = '0';
  28. }
  29. $txt = FAVICONS_DIR . $id . '.txt';
  30. $ico = FAVICONS_DIR . $id . '.ico';
  31. $ico_mtime = @filemtime($ico) ?: 0;
  32. $txt_mtime = @filemtime($txt) ?: 0;
  33. $is_custom_favicon = $ico_mtime != false && $txt_mtime == false;
  34. if (($ico_mtime == false || $ico_mtime < $txt_mtime || ($ico_mtime < time() - (rand(15, 20) * 86400))) && !$is_custom_favicon) {
  35. if ($txt_mtime == false) {
  36. show_default_favicon(1800);
  37. exit();
  38. }
  39. // no ico file or we should download a new one.
  40. $url = file_get_contents($txt);
  41. if ($url === false) {
  42. show_default_favicon(1800);
  43. exit();
  44. }
  45. // Try downloading the URL as a direct image first (e.g. from a feed's <image><url>),
  46. // then fall back to HTML favicon search if it is not a valid image.
  47. if (!download_favicon_from_image_url($url, $ico) && !download_favicon($url, $ico)) {
  48. // Download failed
  49. if ($ico_mtime == false) {
  50. show_default_favicon(86400);
  51. exit();
  52. }
  53. touch($ico);
  54. }
  55. }
  56. if ($no_cache || !httpConditional($ico_mtime, rand(14, 21) * 86400, 2)) {
  57. $ico_content_type = contentType($ico);
  58. header('Content-Type: ' . $ico_content_type);
  59. header('Content-Disposition: attachment; filename="' . $id . '.ico"');
  60. if (!$no_cache && isset($_GET['t'])) {
  61. header('Cache-Control: immutable');
  62. }
  63. readfile($ico);
  64. }