[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * Copyright 2012 Google Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 require_once 'Google/Http/Request.php'; 19 20 /** 21 * Implement the caching directives specified in rfc2616. This 22 * implementation is guided by the guidance offered in rfc2616-sec13. 23 * @author Chirag Shah <[email protected]> 24 */ 25 class Google_Http_CacheParser 26 { 27 public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD'); 28 public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301'); 29 30 /** 31 * Check if an HTTP request can be cached by a private local cache. 32 * 33 * @static 34 * @param Google_Http_Request $resp 35 * @return bool True if the request is cacheable. 36 * False if the request is uncacheable. 37 */ 38 public static function isRequestCacheable(Google_Http_Request $resp) 39 { 40 $method = $resp->getRequestMethod(); 41 if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) { 42 return false; 43 } 44 45 // Don't cache authorized requests/responses. 46 // [rfc2616-14.8] When a shared cache receives a request containing an 47 // Authorization field, it MUST NOT return the corresponding response 48 // as a reply to any other request... 49 if ($resp->getRequestHeader("authorization")) { 50 return false; 51 } 52 53 return true; 54 } 55 56 /** 57 * Check if an HTTP response can be cached by a private local cache. 58 * 59 * @static 60 * @param Google_Http_Request $resp 61 * @return bool True if the response is cacheable. 62 * False if the response is un-cacheable. 63 */ 64 public static function isResponseCacheable(Google_Http_Request $resp) 65 { 66 // First, check if the HTTP request was cacheable before inspecting the 67 // HTTP response. 68 if (false == self::isRequestCacheable($resp)) { 69 return false; 70 } 71 72 $code = $resp->getResponseHttpCode(); 73 if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) { 74 return false; 75 } 76 77 // The resource is uncacheable if the resource is already expired and 78 // the resource doesn't have an ETag for revalidation. 79 $etag = $resp->getResponseHeader("etag"); 80 if (self::isExpired($resp) && $etag == false) { 81 return false; 82 } 83 84 // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT 85 // store any part of either this response or the request that elicited it. 86 $cacheControl = $resp->getParsedCacheControl(); 87 if (isset($cacheControl['no-store'])) { 88 return false; 89 } 90 91 // Pragma: no-cache is an http request directive, but is occasionally 92 // used as a response header incorrectly. 93 $pragma = $resp->getResponseHeader('pragma'); 94 if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) { 95 return false; 96 } 97 98 // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that 99 // a cache cannot determine from the request headers of a subsequent request 100 // whether this response is the appropriate representation." 101 // Given this, we deem responses with the Vary header as uncacheable. 102 $vary = $resp->getResponseHeader('vary'); 103 if ($vary) { 104 return false; 105 } 106 107 return true; 108 } 109 110 /** 111 * @static 112 * @param Google_Http_Request $resp 113 * @return bool True if the HTTP response is considered to be expired. 114 * False if it is considered to be fresh. 115 */ 116 public static function isExpired(Google_Http_Request $resp) 117 { 118 // HTTP/1.1 clients and caches MUST treat other invalid date formats, 119 // especially including the value “0”, as in the past. 120 $parsedExpires = false; 121 $responseHeaders = $resp->getResponseHeaders(); 122 123 if (isset($responseHeaders['expires'])) { 124 $rawExpires = $responseHeaders['expires']; 125 // Check for a malformed expires header first. 126 if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) { 127 return true; 128 } 129 130 // See if we can parse the expires header. 131 $parsedExpires = strtotime($rawExpires); 132 if (false == $parsedExpires || $parsedExpires <= 0) { 133 return true; 134 } 135 } 136 137 // Calculate the freshness of an http response. 138 $freshnessLifetime = false; 139 $cacheControl = $resp->getParsedCacheControl(); 140 if (isset($cacheControl['max-age'])) { 141 $freshnessLifetime = $cacheControl['max-age']; 142 } 143 144 $rawDate = $resp->getResponseHeader('date'); 145 $parsedDate = strtotime($rawDate); 146 147 if (empty($rawDate) || false == $parsedDate) { 148 // We can't default this to now, as that means future cache reads 149 // will always pass with the logic below, so we will require a 150 // date be injected if not supplied. 151 throw new Google_Exception("All cacheable requests must have creation dates."); 152 } 153 154 if (false == $freshnessLifetime && isset($responseHeaders['expires'])) { 155 $freshnessLifetime = $parsedExpires - $parsedDate; 156 } 157 158 if (false == $freshnessLifetime) { 159 return true; 160 } 161 162 // Calculate the age of an http response. 163 $age = max(0, time() - $parsedDate); 164 if (isset($responseHeaders['age'])) { 165 $age = max($age, strtotime($responseHeaders['age'])); 166 } 167 168 return $freshnessLifetime <= $age; 169 } 170 171 /** 172 * Determine if a cache entry should be revalidated with by the origin. 173 * 174 * @param Google_Http_Request $response 175 * @return bool True if the entry is expired, else return false. 176 */ 177 public static function mustRevalidate(Google_Http_Request $response) 178 { 179 // [13.3] When a cache has a stale entry that it would like to use as a 180 // response to a client's request, it first has to check with the origin 181 // server to see if its cached entry is still usable. 182 return self::isExpired($response); 183 } 184 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |