PassThrough.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. namespace Luracast\Restler;
  3. /**
  4. * Static Class to pass through content outside of web root
  5. *
  6. * @category Framework
  7. * @package Restler
  8. * @author R.Arul Kumaran <arul@luracast.com>
  9. * @copyright 2010 Luracast
  10. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  11. * @link http://luracast.com/products/restler/
  12. *
  13. */
  14. class PassThrough
  15. {
  16. public static $mimeTypes = array(
  17. 'js' => 'text/javascript',
  18. 'css' => 'text/css',
  19. 'png' => 'image/png',
  20. 'jpg' => 'image/jpeg',
  21. 'gif' => 'image/gif',
  22. 'html' => 'text/html',
  23. );
  24. /**
  25. * Serve a file outside web root
  26. *
  27. * Respond with a file stored outside web accessible path
  28. *
  29. * @param string $filename full path for the file to be served
  30. * @param bool $forceDownload should the we download instead of viewing
  31. * @param int $expires cache expiry in number of seconds
  32. * @param bool $isPublic cache control, is it public or private
  33. *
  34. * @throws RestException
  35. *
  36. */
  37. public static function file($filename, $forceDownload = false, $expires = 0, $isPublic = true)
  38. {
  39. if (!is_file($filename))
  40. throw new RestException(404);
  41. if (!is_readable($filename))
  42. throw new RestException(403);
  43. $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
  44. if (!$mime = Util::nestedValue(static::$mimeTypes, $extension)) {
  45. if (!function_exists('finfo_open')) {
  46. throw new RestException(
  47. 500,
  48. 'Unable to find media type of ' .
  49. basename($filename) .
  50. ' either enable fileinfo php extension or update ' .
  51. 'PassThrough::$mimeTypes to include mime type for ' . $extension .
  52. ' extension'
  53. );
  54. }
  55. $finfo = finfo_open(FILEINFO_MIME_TYPE);
  56. $mime = finfo_file($finfo, $filename);
  57. }
  58. if (!is_array(Defaults::$headerCacheControl))
  59. Defaults::$headerCacheControl = array(Defaults::$headerCacheControl);
  60. $cacheControl = Defaults::$headerCacheControl[0];
  61. if ($expires > 0) {
  62. $cacheControl = $isPublic ? 'public' : 'private';
  63. $cacheControl .= end(Defaults::$headerCacheControl);
  64. $cacheControl = str_replace('{expires}', $expires, $cacheControl);
  65. $expires = gmdate('D, d M Y H:i:s \G\M\T', time() + $expires);
  66. }
  67. header('Cache-Control: ' . $cacheControl);
  68. header('Expires: ' . $expires);
  69. $lastModified = filemtime($filename);
  70. if (
  71. isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
  72. strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified
  73. ) {
  74. header("{$_SERVER['SERVER_PROTOCOL']} 304 Not Modified");
  75. exit;
  76. }
  77. header('Last-Modified: ' . date('r', $lastModified));
  78. header('X-Powered-By: Luracast Restler v' . Restler::VERSION);
  79. header('Content-type: ' . $mime);
  80. header("Content-Length: " . filesize($filename));
  81. if ($forceDownload) {
  82. header("Content-Transfer-Encoding: binary");
  83. header('Content-Disposition: attachment; filename="' . $filename . '"');
  84. }
  85. readfile($filename);
  86. exit;
  87. }
  88. }