[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/PEAR/ -> REST.php (source)

   1  <?php
   2  /**
   3   * PEAR_REST
   4   *
   5   * PHP versions 4 and 5
   6   *
   7   * LICENSE: This source file is subject to version 3.0 of the PHP license
   8   * that is available through the world-wide-web at the following URI:
   9   * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10   * the PHP License and are unable to obtain it through the web, please
  11   * send a note to license@php.net so we can mail you a copy immediately.
  12   *
  13   * @category   pear
  14   * @package    PEAR
  15   * @author     Greg Beaver <cellog@php.net>
  16   * @copyright  1997-2006 The PHP Group
  17   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18   * @version    CVS: $Id: REST.php,v 1.21 2006/03/27 04:33:11 cellog Exp $
  19   * @link       http://pear.php.net/package/PEAR
  20   * @since      File available since Release 1.4.0a1
  21   */
  22  
  23  /**
  24   * For downloading xml files
  25   */
  26  require_once  'PEAR.php';
  27  require_once  'PEAR/XMLParser.php';
  28  
  29  /**
  30   * Intelligently retrieve data, following hyperlinks if necessary, and re-directing
  31   * as well
  32   * @category   pear
  33   * @package    PEAR
  34   * @author     Greg Beaver <cellog@php.net>
  35   * @copyright  1997-2006 The PHP Group
  36   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  37   * @version    Release: 1.5.0
  38   * @link       http://pear.php.net/package/PEAR
  39   * @since      Class available since Release 1.4.0a1
  40   */
  41  class PEAR_REST
  42  {
  43      var $config;
  44      var $_options;
  45      function PEAR_REST(&$config, $options = array())
  46      {
  47          $this->config = &$config;
  48          $this->_options = $options;
  49      }
  50  
  51      /**
  52       * Retrieve REST data, but always retrieve the local cache if it is available.
  53       *
  54       * This is useful for elements that should never change, such as information on a particular
  55       * release
  56       * @param string full URL to this resource
  57       * @param array|false contents of the accept-encoding header
  58       * @param boolean     if true, xml will be returned as a string, otherwise, xml will be
  59       *                    parsed using PEAR_XMLParser
  60       * @return string|array
  61       */
  62      function retrieveCacheFirst($url, $accept = false, $forcestring = false)
  63      {
  64          $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
  65              md5($url) . 'rest.cachefile';
  66          if (file_exists($cachefile)) {
  67              return unserialize(implode('', file($cachefile)));
  68          }
  69          return $this->retrieveData($url, $accept, $forcestring);
  70      }
  71  
  72      /**
  73       * Retrieve a remote REST resource
  74       * @param string full URL to this resource
  75       * @param array|false contents of the accept-encoding header
  76       * @param boolean     if true, xml will be returned as a string, otherwise, xml will be
  77       *                    parsed using PEAR_XMLParser
  78       * @return string|array
  79       */
  80      function retrieveData($url, $accept = false, $forcestring = false)
  81      {
  82          $cacheId = $this->getCacheId($url);
  83          if ($ret = $this->useLocalCache($url, $cacheId)) {
  84              return $ret;
  85          }
  86          if (!isset($this->_options['offline'])) {
  87              $trieddownload = true;
  88              $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept);
  89          } else {
  90              $trieddownload = false;
  91              $file = false;
  92          }
  93          if (PEAR::isError($file)) {
  94              if ($file->getCode() == -9276) {
  95                  $trieddownload = false;
  96                  $file = false; // use local copy if available on socket connect error
  97              } else {
  98                  return $file;
  99              }
 100          }
 101          if (!$file) {
 102              $ret = $this->getCache($url);
 103              if (!PEAR::isError($ret) && $trieddownload) {
 104                  // reset the age of the cache if the server says it was unmodified
 105                  $this->saveCache($url, $ret, null, true, $cacheId);
 106              }
 107              return $ret;
 108          }
 109          if (is_array($file)) {
 110              $headers = $file[2];
 111              $lastmodified = $file[1];
 112              $content = $file[0];
 113          } else {
 114              $content = $file;
 115              $lastmodified = false;
 116              $headers = array();
 117          }
 118          if ($forcestring) {
 119              $this->saveCache($url, $content, $lastmodified, false, $cacheId);
 120              return $content;
 121          }
 122          if (isset($headers['content-type'])) {
 123              switch ($headers['content-type']) {
 124                  case 'text/xml' :
 125                  case 'application/xml' :
 126                      $parser = new PEAR_XMLParser;
 127                      PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
 128                      $err = $parser->parse($content);
 129                      PEAR::popErrorHandling();
 130                      if (PEAR::isError($err)) {
 131                          return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' .
 132                              $err->getMessage());
 133                      }
 134                      $content = $parser->getData();
 135                  case 'text/html' :
 136                  default :
 137                      // use it as a string
 138              }
 139          } else {
 140              // assume XML
 141              $parser = new PEAR_XMLParser;
 142              $parser->parse($content);
 143              $content = $parser->getData();
 144          }
 145          $this->saveCache($url, $content, $lastmodified, false, $cacheId);
 146          return $content;
 147      }
 148  
 149      function useLocalCache($url, $cacheid = null)
 150      {
 151          if ($cacheid === null) {
 152              $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
 153                  md5($url) . 'rest.cacheid';
 154              if (file_exists($cacheidfile)) {
 155                  $cacheid = unserialize(implode('', file($cacheidfile)));
 156              } else {
 157                  return false;
 158              }
 159          }
 160          $cachettl = $this->config->get('cache_ttl');
 161          // If cache is newer than $cachettl seconds, we use the cache!
 162          if (time() - $cacheid['age'] < $cachettl) {
 163              return $this->getCache($url);
 164          }
 165          return false;
 166      }
 167  
 168      function getCacheId($url)
 169      {
 170          $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
 171              md5($url) . 'rest.cacheid';
 172          if (file_exists($cacheidfile)) {
 173              $ret = unserialize(implode('', file($cacheidfile)));
 174              return $ret;
 175          } else {
 176              return false;
 177          }
 178      }
 179  
 180      function getCache($url)
 181      {
 182          $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
 183              md5($url) . 'rest.cachefile';
 184          if (file_exists($cachefile)) {
 185              return unserialize(implode('', file($cachefile)));
 186          } else {
 187              return PEAR::raiseError('No cached content available for "' . $url . '"');
 188          }
 189      }
 190  
 191      /**
 192       * @param string full URL to REST resource
 193       * @param string original contents of the REST resource
 194       * @param array  HTTP Last-Modified and ETag headers
 195       * @param bool   if true, then the cache id file should be regenerated to
 196       *               trigger a new time-to-live value
 197       */
 198      function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null)
 199      {
 200          $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
 201              md5($url) . 'rest.cacheid';
 202          $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
 203              md5($url) . 'rest.cachefile';
 204          if ($cacheid === null && $nochange) {
 205              $cacheid = unserialize(implode('', file($cacheidfile)));
 206          }
 207  
 208          $fp = @fopen($cacheidfile, 'wb');
 209          if (!$fp) {
 210              $cache_dir = $this->config->get('cache_dir');
 211              if (!is_dir($cache_dir)) {
 212                  System::mkdir(array('-p', $cache_dir));
 213                  $fp = @fopen($cacheidfile, 'wb');
 214                  if (!$fp) {
 215                      return false;
 216                  }
 217              } else {
 218                  return false;
 219              }
 220          }
 221  
 222          if ($nochange) {
 223              fwrite($fp, serialize(array(
 224                  'age'        => time(),
 225                  'lastChange' => $cacheid['lastChange'],
 226                  )));
 227              fclose($fp);
 228              return true;
 229          } else {
 230              fwrite($fp, serialize(array(
 231                  'age'        => time(),
 232                  'lastChange' => $lastmodified,
 233                  )));
 234          }
 235          fclose($fp);
 236          $fp = @fopen($cachefile, 'wb');
 237          if (!$fp) {
 238              if (file_exists($cacheidfile)) {
 239                  @unlink($cacheidfile);
 240              }
 241              return false;
 242          }
 243          fwrite($fp, serialize($contents));
 244          fclose($fp);
 245          return true;
 246      }
 247  
 248      /**
 249       * Efficiently Download a file through HTTP.  Returns downloaded file as a string in-memory
 250       * This is best used for small files
 251       *
 252       * If an HTTP proxy has been configured (http_proxy PEAR_Config
 253       * setting), the proxy will be used.
 254       *
 255       * @param string  $url       the URL to download
 256       * @param string  $save_dir  directory to save file in
 257       * @param false|string|array $lastmodified header values to check against for caching
 258       *                           use false to return the header values from this download
 259       * @param false|array $accept Accept headers to send
 260       * @return string|array  Returns the contents of the downloaded file or a PEAR
 261       *                       error on failure.  If the error is caused by
 262       *                       socket-related errors, the error object will
 263       *                       have the fsockopen error code available through
 264       *                       getCode().  If caching is requested, then return the header
 265       *                       values.
 266       *
 267       * @access public
 268       */
 269      function downloadHttp($url, $lastmodified = null, $accept = false)
 270      {
 271          $info = parse_url($url);
 272          if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
 273              return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
 274          }
 275          if (!isset($info['host'])) {
 276              return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
 277          } else {
 278              $host = $info['host'];
 279              if (!array_key_exists('port', $info)) {
 280                  $info['port'] = null;
 281              }
 282              if (!array_key_exists('path', $info)) {
 283                  $info['path'] = null;
 284              }
 285              $port = $info['port'];
 286              $path = $info['path'];
 287          }
 288          $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
 289          if ($this->config->get('http_proxy')&& 
 290                $proxy = parse_url($this->config->get('http_proxy'))) {
 291              $proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
 292              if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
 293                  $proxy_host = 'ssl://' . $proxy_host;
 294              }
 295              $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
 296              $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
 297              $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
 298          }
 299          if (empty($port)) {
 300              if (isset($info['scheme']) && $info['scheme'] == 'https') {
 301                  $port = 443;
 302              } else {
 303                  $port = 80;
 304              }
 305          }
 306          If (isset($proxy['host'])) {
 307              $request = "GET $url HTTP/1.1\r\n";
 308          } else {
 309              $request = "GET $path HTTP/1.1\r\n";
 310          }
 311  
 312          $ifmodifiedsince = '';
 313          if (is_array($lastmodified)) {
 314              if (isset($lastmodified['Last-Modified'])) {
 315                  $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
 316              }
 317              if (isset($lastmodified['ETag'])) {
 318                  $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
 319              }
 320          } else {
 321              $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
 322          }
 323          $request .= "Host: $host:$port\r\n" . $ifmodifiedsince .
 324              "User-Agent: PEAR/1.5.0/PHP/" . PHP_VERSION . "\r\n";
 325          $username = $this->config->get('username');
 326          $password = $this->config->get('password');
 327          if ($username && $password) {
 328              $tmp = base64_encode("$username:$password");
 329              $request .= "Authorization: Basic $tmp\r\n";
 330          }
 331          if ($proxy_host != '' && $proxy_user != '') {
 332              $request .= 'Proxy-Authorization: Basic ' .
 333                  base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
 334          }
 335          if ($accept) {
 336              $request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
 337          }
 338          $request .= "Connection: close\r\n";
 339          $request .= "\r\n";
 340          if ($proxy_host != '') {
 341              $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15);
 342              if (!$fp) {
 343                  return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr",
 344                      -9276);
 345              }
 346          } else {
 347              if (isset($info['scheme']) && $info['scheme'] == 'https') {
 348                  $host = 'ssl://' . $host;
 349              }
 350              $fp = @fsockopen($host, $port, $errno, $errstr);
 351              if (!$fp) {
 352                  return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
 353              }
 354          }
 355          fwrite($fp, $request);
 356          $headers = array();
 357          while (trim($line = fgets($fp, 1024))) {
 358              if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) {
 359                  $headers[strtolower($matches[1])] = trim($matches[2]);
 360              } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
 361                  if ($matches[1] == 304 && ($lastmodified || ($lastmodified === false))) {
 362                      return false;
 363                  }
 364                  if ($matches[1] != 200) {
 365                      return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)", (int) $matches[1]);
 366                  }
 367              }
 368          }
 369          if (isset($headers['content-length'])) {
 370              $length = $headers['content-length'];
 371          } else {
 372              $length = -1;
 373          }
 374          $data = '';
 375          while ($chunk = @fread($fp, 8192)) {
 376              $data .= $chunk;
 377          }
 378          fclose($fp);
 379          if ($lastmodified === false || $lastmodified) {
 380              if (isset($headers['etag'])) {
 381                  $lastmodified = array('ETag' => $headers['etag']);
 382              }
 383              if (isset($headers['last-modified'])) {
 384                  if (is_array($lastmodified)) {
 385                      $lastmodified['Last-Modified'] = $headers['last-modified'];
 386                  } else {
 387                      $lastmodified = $headers['last-modified'];
 388                  }
 389              }
 390              return array($data, $lastmodified, $headers);
 391          }
 392          return $data;
 393      }
 394  }
 395  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7