Esempio n. 1
0
 /**
  * Add the appropriate caching headers to the response, including If-Modified-Since / 304 handling.
  *
  * @param HTTPResponse The HTTPResponse object to augment.  Omitted the argument or passing a string is deprecated; in these
  * cases, the headers are output directly.
  */
 static function add_cache_headers($body = null)
 {
     // Validate argument
     if ($body && !$body instanceof HTTPResponse) {
         user_error("HTTP::add_cache_headers() must be passed an HTTPResponse object", E_USER_WARNING);
         $body = null;
     }
     // Development sites have frequently changing templates; this can get stuffed up by the code
     // below.
     if (Director::isDev()) {
         return;
     }
     // The headers have been sent and we don't have an HTTPResponse object to attach things to; no point in us trying.
     if (headers_sent() && !$body) {
         return;
     }
     // Popuplate $responseHeaders with all the headers that we want to build
     $responseHeaders = array();
     if (function_exists('apache_request_headers')) {
         $requestHeaders = apache_request_headers();
         if (isset($requestHeaders['X-Requested-With']) && $requestHeaders['X-Requested-With'] == 'XMLHttpRequest') {
             self::$cache_age = 0;
         }
         // bdc: now we must check for DUMB IE6:
         if (isset($requestHeaders['x-requested-with']) && $requestHeaders['x-requested-with'] == 'XMLHttpRequest') {
             self::$cache_age = 0;
         }
     }
     if (self::$cache_age > 0) {
         $responseHeaders["Cache-Control"] = "max-age=" . self::$cache_age . ", must-revalidate";
         $responseHeaders["Pragma"] = "";
     } else {
         $responseHeaders["Cache-Control"] = "no-cache, max-age=0, must-revalidate";
     }
     if (self::$modification_date && self::$cache_age > 0) {
         $responseHeaders["Last-Modified"] = self::gmt_date(self::$modification_date);
         // 304 response detection
         if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
             $ifModifiedSince = strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']));
             if ($ifModifiedSince >= self::$modification_date) {
                 if ($body) {
                     $body->setStatusCode(304);
                     $body->setBody('');
                 } else {
                     header('HTTP/1.0 304 Not Modified');
                     die;
                 }
             }
         }
         $expires = time() + self::$cache_age;
         $responseHeaders["Expires"] = self::gmt_date($expires);
     }
     if (self::$etag) {
         $responseHeaders['ETag'] = self::$etag;
     }
     // Now that we've generated them, either output them or attach them to the HTTPResponse as appropriate
     foreach ($responseHeaders as $k => $v) {
         if ($body) {
             $body->addHeader($k, $v);
         } else {
             if (!headers_sent()) {
                 header("{$k}: {$v}");
             }
         }
     }
 }
Esempio n. 2
0
 /**
  * Add the appropriate caching headers to the response, including If-Modified-Since / 304 handling.
  *
  * @param SS_HTTPResponse The SS_HTTPResponse object to augment.  Omitted the argument or passing a string is
  *                            deprecated; in these cases, the headers are output directly.
  */
 public static function add_cache_headers($body = null)
 {
     // Validate argument
     if ($body && !$body instanceof SS_HTTPResponse) {
         user_error("HTTP::add_cache_headers() must be passed an SS_HTTPResponse object", E_USER_WARNING);
         $body = null;
     }
     // Development sites have frequently changing templates; this can get stuffed up by the code
     // below.
     if (Director::isDev()) {
         return;
     }
     // The headers have been sent and we don't have an SS_HTTPResponse object to attach things to; no point in
     // us trying.
     if (headers_sent() && !$body) {
         return;
     }
     // Popuplate $responseHeaders with all the headers that we want to build
     $responseHeaders = array();
     if (function_exists('apache_request_headers')) {
         $requestHeaders = apache_request_headers();
         if (isset($requestHeaders['X-Requested-With']) && $requestHeaders['X-Requested-With'] == 'XMLHttpRequest') {
             self::$cache_age = 0;
         }
         // bdc: now we must check for DUMB IE6:
         if (isset($requestHeaders['x-requested-with']) && $requestHeaders['x-requested-with'] == 'XMLHttpRequest') {
             self::$cache_age = 0;
         }
     }
     if (self::$cache_age > 0) {
         $responseHeaders["Cache-Control"] = "max-age=" . self::$cache_age . ", must-revalidate, no-transform";
         $responseHeaders["Pragma"] = "";
         // To do: User-Agent should only be added in situations where you *are* actually
         // varying according to user-agent.
         $responseHeaders['Vary'] = 'Cookie, X-Forwarded-Protocol, User-Agent, Accept';
     } else {
         if ($body) {
             // Grab header for checking. Unfortunately HTTPRequest uses a mistyped variant.
             $contentDisposition = $body->getHeader('Content-disposition');
             if (!$contentDisposition) {
                 $contentDisposition = $body->getHeader('Content-Disposition');
             }
         }
         if ($body && Director::is_https() && strstr($_SERVER["HTTP_USER_AGENT"], 'MSIE') == true && strstr($contentDisposition, 'attachment;') == true) {
             // IE6-IE8 have problems saving files when https and no-cache are used
             // (http://support.microsoft.com/kb/323308)
             // Note: this is also fixable by ticking "Do not save encrypted pages to disk" in advanced options.
             $responseHeaders["Cache-Control"] = "max-age=3, must-revalidate, no-transform";
             $responseHeaders["Pragma"] = "";
         } else {
             $responseHeaders["Cache-Control"] = "no-cache, max-age=0, must-revalidate, no-transform";
         }
     }
     if (self::$modification_date && self::$cache_age > 0) {
         $responseHeaders["Last-Modified"] = self::gmt_date(self::$modification_date);
         // Chrome ignores Varies when redirecting back (http://code.google.com/p/chromium/issues/detail?id=79758)
         // which means that if you log out, you get redirected back to a page which Chrome then checks against
         // last-modified (which passes, getting a 304)
         // when it shouldn't be trying to use that page at all because it's the "logged in" version.
         // By also using and etag that includes both the modification date and all the varies
         // values which we also check against we can catch this and not return a 304
         $etagParts = array(self::$modification_date, serialize($_COOKIE));
         if (isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) {
             $etagParts[] = $_SERVER['HTTP_X_FORWARDED_PROTOCOL'];
         }
         if (isset($_SERVER['HTTP_USER_AGENT'])) {
             $etagParts[] = $_SERVER['HTTP_USER_AGENT'];
         }
         if (isset($_SERVER['HTTP_ACCEPT'])) {
             $etagParts[] = $_SERVER['HTTP_ACCEPT'];
         }
         $etag = sha1(implode(':', $etagParts));
         $responseHeaders["ETag"] = $etag;
         // 304 response detection
         if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
             $ifModifiedSince = strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']));
             // As above, only 304 if the last request had all the same varies values
             // (or the etag isn't passed as part of the request - but with chrome it always is)
             $matchesEtag = !isset($_SERVER['HTTP_IF_NONE_MATCH']) || $_SERVER['HTTP_IF_NONE_MATCH'] == $etag;
             if ($ifModifiedSince >= self::$modification_date && $matchesEtag) {
                 if ($body) {
                     $body->setStatusCode(304);
                     $body->setBody('');
                 } else {
                     header('HTTP/1.0 304 Not Modified');
                     die;
                 }
             }
         }
         $expires = time() + self::$cache_age;
         $responseHeaders["Expires"] = self::gmt_date($expires);
     }
     if (self::$etag) {
         $responseHeaders['ETag'] = self::$etag;
     }
     // Now that we've generated them, either output them or attach them to the SS_HTTPResponse as appropriate
     foreach ($responseHeaders as $k => $v) {
         if ($body) {
             $body->addHeader($k, $v);
         } else {
             if (!headers_sent()) {
                 header("{$k}: {$v}");
             }
         }
     }
 }
Esempio n. 3
0
 /**
  * Set the maximum age of this page in web caches, in seconds
  */
 public static function set_cache_age($age)
 {
     self::$cache_age = $age;
 }
Esempio n. 4
0
 /**
  * Add the appropriate caching headers to the response
  *
  * @param string The reponse body
  */
 static function add_cache_headers($body = null)
 {
     // Development sites have frequently changing templates; this can get stuffed up by the code
     // below.
     if (Director::isDev()) {
         return;
     }
     if (!headers_sent()) {
         if (function_exists('apache_request_headers')) {
             $headers = apache_request_headers();
             if (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest') {
                 self::$cache_age = 0;
             }
             // bdc: now we must check for DUMB IE6:
             if (isset($headers['x-requested-with']) && $headers['x-requested-with'] == 'XMLHttpRequest') {
                 self::$cache_age = 0;
             }
         }
         if (self::$cache_age > 0) {
             header("Cache-Control: max-age=" . self::$cache_age . ", must-revalidate");
             header("Pragma:");
         } else {
             header("Cache-Control: no-cache, max-age=0, must-revalidate");
         }
         if (self::$modification_date && self::$cache_age > 0) {
             header("Last-Modified: " . self::gmt_date(self::$modification_date));
             $expires = 2 * time() - self::$modification_date;
             header("Expires: " . self::gmt_date($expires));
         }
         if (self::$etag) {
             header('ETag: ' . self::$etag);
         }
     }
 }