Google_CacheParser

Implement the caching directives specified in rfc2616.

Defined (1)

The class is defined in the following location(s).

/gdwpm-api/io/Google_CacheParser.php  
  1. class Google_CacheParser { 
  2. public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD'); 
  3. public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301'); 
  4.  
  5. private function __construct() {} 
  6.  
  7. /** 
  8. * Check if an HTTP request can be cached by a private local cache. 
  9. * @static 
  10. * @param Google_HttpRequest $resp 
  11. * @return bool True if the request is cacheable. 
  12. * False if the request is uncacheable. 
  13. */ 
  14. public static function isRequestCacheable (Google_HttpRequest $resp) { 
  15. $method = $resp->getRequestMethod(); 
  16. if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) { 
  17. return false; 
  18.  
  19. // Don't cache authorized requests/responses. 
  20. // [rfc2616-14.8] When a shared cache receives a request containing an 
  21. // Authorization field, it MUST NOT return the corresponding response 
  22. // as a reply to any other request... 
  23. if ($resp->getRequestHeader("authorization")) { 
  24. return false; 
  25.  
  26. return true; 
  27.  
  28. /** 
  29. * Check if an HTTP response can be cached by a private local cache. 
  30. * @static 
  31. * @param Google_HttpRequest $resp 
  32. * @return bool True if the response is cacheable. 
  33. * False if the response is un-cacheable. 
  34. */ 
  35. public static function isResponseCacheable (Google_HttpRequest $resp) { 
  36. // First, check if the HTTP request was cacheable before inspecting the 
  37. // HTTP response. 
  38. if (false == self::isRequestCacheable($resp)) { 
  39. return false; 
  40.  
  41. $code = $resp->getResponseHttpCode(); 
  42. if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) { 
  43. return false; 
  44.  
  45. // The resource is uncacheable if the resource is already expired and 
  46. // the resource doesn't have an ETag for revalidation. 
  47. $etag = $resp->getResponseHeader("etag"); 
  48. if (self::isExpired($resp) && $etag == false) { 
  49. return false; 
  50.  
  51. // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT 
  52. // store any part of either this response or the request that elicited it. 
  53. $cacheControl = $resp->getParsedCacheControl(); 
  54. if (isset($cacheControl['no-store'])) { 
  55. return false; 
  56.  
  57. // Pragma: no-cache is an http request directive, but is occasionally 
  58. // used as a response header incorrectly. 
  59. $pragma = $resp->getResponseHeader('pragma'); 
  60. if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) { 
  61. return false; 
  62.  
  63. // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that 
  64. // a cache cannot determine from the request headers of a subsequent request 
  65. // whether this response is the appropriate representation." 
  66. // Given this, we deem responses with the Vary header as uncacheable. 
  67. $vary = $resp->getResponseHeader('vary'); 
  68. if ($vary) { 
  69. return false; 
  70.  
  71. return true; 
  72.  
  73. /** 
  74. * @static 
  75. * @param Google_HttpRequest $resp 
  76. * @return bool True if the HTTP response is considered to be expired. 
  77. * False if it is considered to be fresh. 
  78. */ 
  79. public static function isExpired(Google_HttpRequest $resp) { 
  80. // HTTP/1.1 clients and caches MUST treat other invalid date formats,  
  81. // especially including the value *0*, as in the past. 
  82. $parsedExpires = false; 
  83. $responseHeaders = $resp->getResponseHeaders(); 
  84. if (isset($responseHeaders['expires'])) { 
  85. $rawExpires = $responseHeaders['expires']; 
  86. // Check for a malformed expires header first. 
  87. if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) { 
  88. return true; 
  89.  
  90. // See if we can parse the expires header. 
  91. $parsedExpires = strtotime($rawExpires); 
  92. if (false == $parsedExpires || $parsedExpires <= 0) { 
  93. return true; 
  94.  
  95. // Calculate the freshness of an http response. 
  96. $freshnessLifetime = false; 
  97. $cacheControl = $resp->getParsedCacheControl(); 
  98. if (isset($cacheControl['max-age'])) { 
  99. $freshnessLifetime = $cacheControl['max-age']; 
  100.  
  101. $rawDate = $resp->getResponseHeader('date'); 
  102. $parsedDate = strtotime($rawDate); 
  103.  
  104. if (empty($rawDate) || false == $parsedDate) { 
  105. $parsedDate = time(); 
  106. if (false == $freshnessLifetime && isset($responseHeaders['expires'])) { 
  107. $freshnessLifetime = $parsedExpires - $parsedDate; 
  108.  
  109. if (false == $freshnessLifetime) { 
  110. return true; 
  111.  
  112. // Calculate the age of an http response. 
  113. $age = max(0, time() - $parsedDate); 
  114. if (isset($responseHeaders['age'])) { 
  115. $age = max($age, strtotime($responseHeaders['age'])); 
  116.  
  117. return $freshnessLifetime <= $age; 
  118.  
  119. /** 
  120. * Determine if a cache entry should be revalidated with by the origin. 
  121. * @param Google_HttpRequest $response 
  122. * @return bool True if the entry is expired, else return false. 
  123. */ 
  124. public static function mustRevalidate(Google_HttpRequest $response) { 
  125. // [13.3] When a cache has a stale entry that it would like to use as a 
  126. // response to a client's request, it first has to check with the origin 
  127. // server to see if its cached entry is still usable. 
  128. return self::isExpired($response);