/lib/limb/net/src/lmbHttpCache.class.php

https://github.com/limb-php-framework/limb-app-buildman · PHP · 203 lines · 159 code · 32 blank · 12 comment · 21 complexity · 243099021b50255a832d486120b881ee MD5 · raw file

  1. <?php
  2. /**
  3. * Limb Web Application Framework
  4. *
  5. * @link http://limb-project.com
  6. *
  7. * @copyright Copyright &copy; 2004-2007 BIT
  8. * @license LGPL http://www.gnu.org/copyleft/lesser.html
  9. * @version $Id: lmbHttpCache.class.php 5001 2007-02-08 15:36:45Z pachanga $
  10. * @package net
  11. */
  12. //inspired by http://alexandre.alapetite.net/doc-alex/php-http-304/
  13. define('LIMB_HTTP_CACHE_TYPE_PRIVATE', 0);
  14. define('LIMB_HTTP_CACHE_TYPE_PUBLIC', 1);
  15. class lmbHttpCache
  16. {
  17. protected $etag;
  18. protected $last_modified_time;
  19. protected $cache_time;
  20. protected $cache_type;
  21. function __construct()
  22. {
  23. $this->reset();
  24. }
  25. function reset()
  26. {
  27. $this->last_modified_time = time();
  28. $this->etag = null;
  29. $this->cache_time = 0;
  30. $this->cache_type = LIMB_HTTP_CACHE_TYPE_PRIVATE;
  31. }
  32. function checkAndWrite($response)
  33. {
  34. if($this->is412())
  35. {
  36. $this->_write412Response($response);
  37. return true;
  38. }
  39. elseif($this->is304())
  40. {
  41. $this->_write304Response($response);
  42. return true;
  43. }
  44. else
  45. {
  46. $this->_writeCachingResponse($response);
  47. return isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'HEAD'; //rfc2616-sec9.html#sec9.4
  48. }
  49. }
  50. function is412()
  51. {
  52. if (isset($_SERVER['HTTP_IF_MATCH'])) //rfc2616-sec14.html#sec14.24
  53. {
  54. $etag_client = stripslashes($_SERVER['HTTP_IF_MATCH']);
  55. return (($etag_client != '*') && (strpos($etag_client, $this->getEtag()) === false));
  56. }
  57. if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE'])) //http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.28
  58. {
  59. return (strcasecmp($_SERVER['HTTP_IF_UNMODIFIED_SINCE'], $this->formatLastModifiedTime()) != 0);
  60. }
  61. return false;
  62. }
  63. function is304()
  64. {
  65. if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) //rfc2616-sec14.html#sec14.25 //rfc1945.txt
  66. {
  67. return ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $this->formatLastModifiedTime());
  68. }
  69. if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) //rfc2616-sec14.html#sec14.26
  70. {
  71. $etag_client = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
  72. return (($etag_client == $this->getEtag()) || ($etag_client == '*'));
  73. }
  74. return false;
  75. }
  76. protected function _write412Response($response)
  77. {
  78. $response->header('HTTP/1.1 412 Precondition Failed');
  79. $response->header('Cache-Control: protected, max-age=0, must-revalidate');
  80. $response->header('Content-Type: text/plain');
  81. $response->write("HTTP/1.1 Error 412 Precondition Failed: Precondition request failed positive evaluation\n");
  82. }
  83. protected function _write304Response($response)
  84. {
  85. $response->header('HTTP/1.0 304 Not Modified');
  86. $response->header('Etag: ' . $this->getEtag());
  87. $response->header('Pragma: ');
  88. $response->header('Cache-Control: ');
  89. $response->header('Last-Modified: ');
  90. $response->header('Expires: ');
  91. }
  92. protected function _writeCachingResponse($response)
  93. {
  94. $response->header('Cache-Control: ' . $this->_getCacheControl()); //rfc2616-sec14.html#sec14.9
  95. $response->header('Last-Modified: ' . $this->formatLastModifiedTime());
  96. $response->header('Etag: ' . $this->getEtag());
  97. $response->header('Pragma: ');
  98. $response->header('Expires: ');
  99. }
  100. protected function _getCacheControl()
  101. {
  102. if ($this->cache_time == 0)
  103. $cache = 'protected, must-revalidate, ';
  104. elseif ($this->cache_type == LIMB_HTTP_CACHE_TYPE_PRIVATE)
  105. $cache = 'protected, ';
  106. elseif ($this->cache_type == LIMB_HTTP_CACHE_TYPE_PUBLIC)
  107. $cache = 'public, ';
  108. else
  109. $cache = '';
  110. $cache .= 'max-age=' . floor($this->cache_time);
  111. return $cache;
  112. }
  113. function formatLastModifiedTime()
  114. {
  115. return $this->_formatGmtTime($this->last_modified_time);
  116. }
  117. protected function _formatGmtTime($time)
  118. {
  119. return gmdate('D, d M Y H:i:s \G\M\T', $time);
  120. }
  121. function setLastModifiedTime($last_modified_time)
  122. {
  123. $this->last_modified_time = $last_modified_time;
  124. }
  125. function getLastModifiedTime()
  126. {
  127. return $this->last_modified_time;
  128. }
  129. function setEtag($etag)
  130. {
  131. $this->etag = $etag;
  132. }
  133. function getEtag()
  134. {
  135. if($this->etag)
  136. return $this->etag;
  137. //rfc2616-sec14.html#sec14.19 //='"0123456789abcdef0123456789abcdef"'
  138. if (isset($_SERVER['QUERY_STRING']))
  139. $query = '?' . $_SERVER['QUERY_STRING'];
  140. else
  141. $query = '';
  142. $this->etag = '"' . md5($this->_getScriptName() . $query . '#' . $this->last_modified_time ) . '"';
  143. return $this->etag;
  144. }
  145. protected function _getScriptName()
  146. {
  147. if (isset($_SERVER['SCRIPT_FILENAME']))
  148. return $_SERVER['SCRIPT_FILENAME'];
  149. elseif (isset($_SERVER['PATH_TRANSLATED']))
  150. return $_SERVER['PATH_TRANSLATED'];
  151. else
  152. return '';
  153. }
  154. function setCacheTime($cache_time)
  155. {
  156. $this->cache_time = $cache_time;
  157. }
  158. function getCacheTime()
  159. {
  160. return $this->cache_time;
  161. }
  162. function setCacheType($cache_type)
  163. {
  164. $this->cache_type = $cache_type;
  165. }
  166. function getCacheType()
  167. {
  168. return $this->cache_type;
  169. }
  170. }
  171. ?>