[ Index ]
 

Code source de LifeType 1.2.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/class/net/http/ -> httpcache.class.php (source)

   1  <?php
   2  
   3  //In RSS/ATOM feedMode, contains the date of the clients last update.
   4  $clientCacheDate=0; //Global public variable because PHP4 does not allow conditional arguments by reference
   5  $_sessionMode=false; //Global private variable
   6  
   7  /**
   8   * \ingroup Net_HTTP
   9   * Enable support for HTTP/1.x conditional requests in PHP.
  10   * Goal: Optimisation
  11   * - If the client sends a HEAD request, avoid transferring data and return the correct headers.
  12   * - If the client already has the same version in its cache, avoid transferring data again (304 Not Modified).
  13   * - Possibility to control cache for client and proxies (public or private policy, life time).
  14   * - When $feedMode is set to true, in the case of a RSS/ATOM feed,
  15   *   it puts a timestamp in the global variable $clientCacheDate to allow the sending of only the articles newer than the client's cache.
  16   * - When $compression is set to true, compress the data before sending it to the client and persitent connections are allowed.
  17   * - When $session is set to true, automatically checks if $_SESSION has been modified during the last generation the document.
  18   *
  19   * Interface:
  20   * - function httpConditional($UnixTimeStamp,$cacheSeconds=0,$cachePrivacy=0,$feedMode=false,$compression=false)
  21   *  [Required] $UnixTimeStamp: Date of the last modification of the data to send to the client (Unix Timestamp format).
  22   *  [Implied] $cacheSeconds=0: Lifetime in seconds of the document. If $cacheSeconds>0, the document will be cashed and not revalidated against the server for this delay.
  23   *  [Implied] $cachePrivacy=0: 0=private, 1=normal (public), 2=forced public. When public, it allows a cashed document ($cacheSeconds>0) to be shared by several users.
  24   *  [Implied] $feedMode=false: Special RSS/ATOM feeds. When true, it sets $cachePrivacy to 0 (private), does not use the modification time of the script itself, and puts the date of the client's cache (or a old date from 1980) in the global variable $clientCacheDate.
  25   *  [implied] $compression=false: Enable the compression and allows persistant connections (automatic detection of the capacities of the client).
  26   *  [implied] $session=false: To be turned on when sessions are used. Checks if the data contained in $_SESSION has been modified during the last generation the document.
  27   *  Returns: True if the connection can be closed (e.g.: the client has already the lastest version), false if the new content has to be send to the client.
  28   *
  29   * Typical use:
  30   * <?php
  31   *  require_once('http-conditional.php');
  32   *  //Date of the last modification of the content (Unix Timestamp format).
  33   *  //Examples: query the database, or last modification of a static file.
  34   *  $dateLastModification=...;
  35   *  if (httpConditional($dateLastModification))
  36   *  {
  37   *   ... //Close database connections, and other cleaning.
  38   *   exit(); //No need to send anything
  39   *  }
  40   *  //Do not send any text to the client before this line.
  41   *  ... //Rest of the script, just as you would do normally.
  42   * ?>
  43   *
  44   * Version 1.6.1, 2005-04-03, http://alexandre.alapetite.net/doc-alex/php-http-304/
  45   *
  46   * ------------------------------------------------------------------
  47   * Written by Alexandre Alapetite, http://alexandre.alapetite.net/cv/
  48   *
  49   * Copyright 2004-2005, Licence: Creative Commons "Attribution-ShareAlike 2.0 France" BY-SA (FR),
  50   * http://creativecommons.org/licenses/by-sa/2.0/fr/
  51   * http://alexandre.alapetite.net/divers/apropos/#by-sa
  52   * - Attribution. You must give the original author credit
  53   * - Share Alike. If you alter, transform, or build upon this work,
  54   *   you may distribute the resulting work only under a license identical to this one
  55   * - The French law is authoritative
  56   * - Any of these conditions can be waived if you get permission from Alexandre Alapetite
  57   * - Please send to Alexandre Alapetite the modifications you make,
  58   *   in order to improve this file for the benefit of everybody
  59   *
  60   * If you want to distribute this code, please do it as a link to:
  61   * http://alexandre.alapetite.net/doc-alex/php-http-304/
  62   */
  63  class HttpCache {
  64      function httpConditional($UnixTimeStamp,$cacheSeconds=0,
  65                               $cachePrivacy=0,$feedMode=false,
  66                               $compression=false,$session=false){
  67              //Credits: http://alexandre.alapetite.net/doc-alex/php-http-304/
  68              //RFC2616 HTTP/1.1: http://www.w3.org/Protocols/rfc2616/rfc2616.html
  69              //RFC1945 HTTP/1.0: http://www.w3.org/Protocols/rfc1945/rfc1945.txt
  70  
  71          if (headers_sent()) return false;
  72  
  73          if (isset($_SERVER['SCRIPT_FILENAME'])) $scriptName=$_SERVER['SCRIPT_FILENAME'];
  74          elseif (isset($_SERVER['PATH_TRANSLATED'])) $scriptName=$_SERVER['PATH_TRANSLATED'];
  75          else return false;
  76  
  77          if ((!$feedMode)&&(($modifScript=filemtime($scriptName))>$UnixTimeStamp))
  78              $UnixTimeStamp=$modifScript;
  79          $UnixTimeStamp=min($UnixTimeStamp,time());
  80          $is304=true;
  81          $is412=false;
  82          $nbCond=0;
  83  
  84              //rfc2616-sec3.html#sec3.3.1
  85          $dateLastModif=gmdate('D, d M Y H:i:s \G\M\T',$UnixTimeStamp);
  86          $dateCacheClient='Thu, 10 Jan 1980 20:30:40 GMT';
  87  
  88              //rfc2616-sec14.html#sec14.19 //='"0123456789abcdef0123456789abcdef"'
  89          if (isset($_SERVER['QUERY_STRING'])) $myQuery='?'.$_SERVER['QUERY_STRING'];
  90          else $myQuery='';
  91          if ($session&&isset($_SESSION))
  92          {
  93              global $_sessionMode;
  94              $_sessionMode=$session;
  95              $myQuery.=print_r($_SESSION,true).session_name().'='.session_id();
  96          }
  97          $etagServer='"'.md5($scriptName.$myQuery.'#'.$dateLastModif).'"';
  98  
  99          if ((!$is412)&&isset($_SERVER['HTTP_IF_MATCH']))
 100          {//rfc2616-sec14.html#sec14.24
 101              $etagsClient=stripslashes($_SERVER['HTTP_IF_MATCH']);
 102              $is412=(($etagClient!='*')&&(strpos($etagsClient,$etagServer)===false));
 103          }
 104          if ($is304&&isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
 105          {//rfc2616-sec14.html#sec14.25 //rfc1945.txt
 106              $nbCond++;
 107              $dateCacheClient=$_SERVER['HTTP_IF_MODIFIED_SINCE'];
 108              $p=strpos($dateCacheClient,';');
 109              if ($p!==false)
 110                  $dateCacheClient=substr($dateCacheClient,0,$p);
 111              $is304=($dateCacheClient==$dateLastModif);
 112          }
 113          if ($is304&&isset($_SERVER['HTTP_IF_NONE_MATCH']))
 114          {//rfc2616-sec14.html#sec14.26
 115              $nbCond++;
 116              $etagClient=stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
 117              $is304=(($etagClient==$etagServer)||($etagClient=='*'));
 118          }
 119          if ((!$is412)&&isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE']))
 120          {//rfc2616-sec14.html#sec14.28
 121              $dateCacheClient=$_SERVER['HTTP_IF_UNMODIFIED_SINCE'];
 122              $p=strpos($dateCacheClient,';');
 123              if ($p!==false)
 124                  $dateCacheClient=substr($dateCacheClient,0,$p);
 125              $is412=($dateCacheClient!=$dateLastModif);
 126          }
 127          if ($feedMode)
 128          {//Special RSS/ATOM
 129              global $clientCacheDate;
 130              $clientCacheDate=strtotime($dateCacheClient);
 131              $cachePrivacy=0;
 132          }
 133  
 134          if ($is412)
 135          {//rfc2616-sec10.html#sec10.4.13
 136              header('HTTP/1.1 412 Precondition Failed');
 137              header('Cache-Control: private, max-age=0, must-revalidate');
 138              header('Content-Type: text/plain');
 139              echo "HTTP/1.1 Error 412 Precondition Failed: Precondition request failed positive evaluation\n";
 140              return true;
 141          }
 142          elseif ($is304&&($nbCond>0))
 143          {//rfc2616-sec10.html#sec10.3.5
 144              header('HTTP/1.0 304 Not Modified');
 145              header('Etag: '.$etagServer);
 146              if ($feedMode) header('Connection: close'); //Comment this line under IIS
 147              return true;
 148          }
 149          else
 150          {//rfc2616-sec10.html#sec10.2.1
 151                  //rfc2616-sec14.html#sec14.3
 152              if ($compression) ob_start('_httpConditionalCallBack'); //Will check HTTP_ACCEPT_ENCODING
 153                  //header('HTTP/1.0 200 OK');
 154              if ($cacheSeconds==0)
 155              {
 156                  $cache='private, must-revalidate, ';
 157                      //$cacheSeconds=-1500000; //HTTP/1.0
 158              }
 159              elseif ($cachePrivacy==0) $cache='private, ';
 160              elseif ($cachePrivacy==2) $cache='public, ';
 161              else $cache='';
 162              $cache.='max-age='.floor($cacheSeconds);
 163          // header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T',time()+$cacheSeconds)); //HTTP/1.0 //rfc2616-sec14.html#sec14.21
 164              header('Cache-Control: '.$cache); //rfc2616-sec14.html#sec14.9
 165              header('Last-Modified: '.$dateLastModif);
 166              header('Etag: '.$etagServer);
 167              if ($feedMode) header('Connection: close'); //rfc2616-sec14.html#sec14.10 //Comment this line under IIS
 168              return $_SERVER['REQUEST_METHOD']=='HEAD'; //rfc2616-sec9.html#sec9.4
 169          }
 170      }
 171  
 172      function _httpConditionalCallBack($buffer,$mode=5){
 173              //Private function automatically called at the end of the script when compression is enabled
 174              //rfc2616-sec14.html#sec14.11
 175              //You can adjust the level of compression with zlib.output_compression_level in php.ini
 176          if (extension_loaded('zlib')&&(!ini_get('zlib.output_compression')))
 177          {
 178              $buffer2=ob_gzhandler($buffer,$mode); //Will check HTTP_ACCEPT_ENCODING and put correct headers
 179              if (strlen($buffer2)>1) //When ob_gzhandler succeeded
 180                  $buffer=$buffer2;
 181          }
 182          header('Content-Length: '.strlen($buffer)); //Allows persistant connections //rfc2616-sec14.html#sec14.13
 183          return $buffer;
 184      }
 185      
 186      function httpConditionalRefresh($UnixTimeStamp){
 187              //Update HTTP headers if the content has just been modified by the client's request
 188              //See an example on http://alexandre.alapetite.net/doc-alex/compteur/
 189          if (headers_sent()) return false;
 190          
 191          if (isset($_SERVER['SCRIPT_FILENAME'])) $scriptName=$_SERVER['SCRIPT_FILENAME'];
 192          elseif (isset($_SERVER['PATH_TRANSLATED'])) $scriptName=$_SERVER['PATH_TRANSLATED'];
 193          else return false;
 194          
 195          $dateLastModif=gmdate('D, d M Y H:i:s \G\M\T',$UnixTimeStamp);
 196          
 197          if (isset($_SERVER['QUERY_STRING'])) $myQuery='?'.$_SERVER['QUERY_STRING'];
 198          else $myQuery='';
 199          global $_sessionMode;
 200          if ($_sessionMode&&isset($_SESSION))
 201              $myQuery.=print_r($_SESSION,true).session_name().'='.session_id();
 202          $etagServer='"'.md5($scriptName.$myQuery.'#'.$dateLastModif).'"';
 203          
 204          header('Last-Modified: '.$dateLastModif);
 205          header('Etag: '.$etagServer);
 206      }
 207  }
 208  ?>


Généré le : Mon Nov 26 21:04:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics