home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / SimplePie / File.php < prev    next >
Encoding:
PHP Script  |  2012-11-21  |  9.5 KB  |  293 lines

  1. <?php
  2. /**
  3.  * SimplePie
  4.  *
  5.  * A PHP-Based RSS and Atom Feed Framework.
  6.  * Takes the hard work out of managing a complete RSS/Atom solution.
  7.  *
  8.  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without modification, are
  12.  * permitted provided that the following conditions are met:
  13.  *
  14.  *     * Redistributions of source code must retain the above copyright notice, this list of
  15.  *       conditions and the following disclaimer.
  16.  *
  17.  *     * Redistributions in binary form must reproduce the above copyright notice, this list
  18.  *       of conditions and the following disclaimer in the documentation and/or other materials
  19.  *       provided with the distribution.
  20.  *
  21.  *     * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22.  *       to endorse or promote products derived from this software without specific prior
  23.  *       written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26.  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27.  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28.  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33.  * POSSIBILITY OF SUCH DAMAGE.
  34.  *
  35.  * @package SimplePie
  36.  * @version 1.3.1
  37.  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
  38.  * @author Ryan Parman
  39.  * @author Geoffrey Sneddon
  40.  * @author Ryan McCue
  41.  * @link http://simplepie.org/ SimplePie
  42.  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43.  */
  44.  
  45. /**
  46.  * Used for fetching remote files and reading local files
  47.  *
  48.  * Supports HTTP 1.0 via cURL or fsockopen, with spotty HTTP 1.1 support
  49.  *
  50.  * This class can be overloaded with {@see SimplePie::set_file_class()}
  51.  *
  52.  * @package SimplePie
  53.  * @subpackage HTTP
  54.  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
  55.  */
  56. class SimplePie_File
  57. {
  58.     var $url;
  59.     var $useragent;
  60.     var $success = true;
  61.     var $headers = array();
  62.     var $body;
  63.     var $status_code;
  64.     var $redirects = 0;
  65.     var $error;
  66.     var $method = SIMPLEPIE_FILE_SOURCE_NONE;
  67.  
  68.     public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
  69.     {
  70.         if (class_exists('idna_convert'))
  71.         {
  72.             $idn = new idna_convert();
  73.             $parsed = SimplePie_Misc::parse_url($url);
  74.             $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
  75.         }
  76.         $this->url = $url;
  77.         $this->useragent = $useragent;
  78.         if (preg_match('/^http(s)?:\/\//i', $url))
  79.         {
  80.             if ($useragent === null)
  81.             {
  82.                 $useragent = ini_get('user_agent');
  83.                 $this->useragent = $useragent;
  84.             }
  85.             if (!is_array($headers))
  86.             {
  87.                 $headers = array();
  88.             }
  89.             if (!$force_fsockopen && function_exists('curl_exec'))
  90.             {
  91.                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
  92.                 $fp = curl_init();
  93.                 $headers2 = array();
  94.                 foreach ($headers as $key => $value)
  95.                 {
  96.                     $headers2[] = "$key: $value";
  97.                 }
  98.                 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
  99.                 {
  100.                     curl_setopt($fp, CURLOPT_ENCODING, '');
  101.                 }
  102.                 curl_setopt($fp, CURLOPT_URL, $url);
  103.                 curl_setopt($fp, CURLOPT_HEADER, 1);
  104.                 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
  105.                 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
  106.                 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
  107.                 curl_setopt($fp, CURLOPT_REFERER, $url);
  108.                 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
  109.                 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
  110.                 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
  111.                 {
  112.                     curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
  113.                     curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
  114.                 }
  115.  
  116.                 $this->headers = curl_exec($fp);
  117.                 if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
  118.                 {
  119.                     curl_setopt($fp, CURLOPT_ENCODING, 'none');
  120.                     $this->headers = curl_exec($fp);
  121.                 }
  122.                 if (curl_errno($fp))
  123.                 {
  124.                     $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
  125.                     $this->success = false;
  126.                 }
  127.                 else
  128.                 {
  129.                     $info = curl_getinfo($fp);
  130.                     curl_close($fp);
  131.                     $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
  132.                     $this->headers = array_pop($this->headers);
  133.                     $parser = new SimplePie_HTTP_Parser($this->headers);
  134.                     if ($parser->parse())
  135.                     {
  136.                         $this->headers = $parser->headers;
  137.                         $this->body = $parser->body;
  138.                         $this->status_code = $parser->status_code;
  139.                         if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  140.                         {
  141.                             $this->redirects++;
  142.                             $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  143.                             return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  144.                         }
  145.                     }
  146.                 }
  147.             }
  148.             else
  149.             {
  150.                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
  151.                 $url_parts = parse_url($url);
  152.                 $socket_host = $url_parts['host'];
  153.                 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
  154.                 {
  155.                     $socket_host = "ssl://$url_parts[host]";
  156.                     $url_parts['port'] = 443;
  157.                 }
  158.                 if (!isset($url_parts['port']))
  159.                 {
  160.                     $url_parts['port'] = 80;
  161.                 }
  162.                 $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
  163.                 if (!$fp)
  164.                 {
  165.                     $this->error = 'fsockopen error: ' . $errstr;
  166.                     $this->success = false;
  167.                 }
  168.                 else
  169.                 {
  170.                     stream_set_timeout($fp, $timeout);
  171.                     if (isset($url_parts['path']))
  172.                     {
  173.                         if (isset($url_parts['query']))
  174.                         {
  175.                             $get = "$url_parts[path]?$url_parts[query]";
  176.                         }
  177.                         else
  178.                         {
  179.                             $get = $url_parts['path'];
  180.                         }
  181.                     }
  182.                     else
  183.                     {
  184.                         $get = '/';
  185.                     }
  186.                     $out = "GET $get HTTP/1.1\r\n";
  187.                     $out .= "Host: $url_parts[host]\r\n";
  188.                     $out .= "User-Agent: $useragent\r\n";
  189.                     if (extension_loaded('zlib'))
  190.                     {
  191.                         $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
  192.                     }
  193.  
  194.                     if (isset($url_parts['user']) && isset($url_parts['pass']))
  195.                     {
  196.                         $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
  197.                     }
  198.                     foreach ($headers as $key => $value)
  199.                     {
  200.                         $out .= "$key: $value\r\n";
  201.                     }
  202.                     $out .= "Connection: Close\r\n\r\n";
  203.                     fwrite($fp, $out);
  204.  
  205.                     $info = stream_get_meta_data($fp);
  206.  
  207.                     $this->headers = '';
  208.                     while (!$info['eof'] && !$info['timed_out'])
  209.                     {
  210.                         $this->headers .= fread($fp, 1160);
  211.                         $info = stream_get_meta_data($fp);
  212.                     }
  213.                     if (!$info['timed_out'])
  214.                     {
  215.                         $parser = new SimplePie_HTTP_Parser($this->headers);
  216.                         if ($parser->parse())
  217.                         {
  218.                             $this->headers = $parser->headers;
  219.                             $this->body = $parser->body;
  220.                             $this->status_code = $parser->status_code;
  221.                             if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
  222.                             {
  223.                                 $this->redirects++;
  224.                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
  225.                                 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
  226.                             }
  227.                             if (isset($this->headers['content-encoding']))
  228.                             {
  229.                                 // Hey, we act dumb elsewhere, so let's do that here too
  230.                                 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
  231.                                 {
  232.                                     case 'gzip':
  233.                                     case 'x-gzip':
  234.                                         $decoder = new SimplePie_gzdecode($this->body);
  235.                                         if (!$decoder->parse())
  236.                                         {
  237.                                             $this->error = 'Unable to decode HTTP "gzip" stream';
  238.                                             $this->success = false;
  239.                                         }
  240.                                         else
  241.                                         {
  242.                                             $this->body = $decoder->data;
  243.                                         }
  244.                                         break;
  245.  
  246.                                     case 'deflate':
  247.                                         if (($decompressed = gzinflate($this->body)) !== false)
  248.                                         {
  249.                                             $this->body = $decompressed;
  250.                                         }
  251.                                         else if (($decompressed = gzuncompress($this->body)) !== false)
  252.                                         {
  253.                                             $this->body = $decompressed;
  254.                                         }
  255.                                         else if (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false)
  256.                                         {
  257.                                             $this->body = $decompressed;
  258.                                         }
  259.                                         else
  260.                                         {
  261.                                             $this->error = 'Unable to decode HTTP "deflate" stream';
  262.                                             $this->success = false;
  263.                                         }
  264.                                         break;
  265.  
  266.                                     default:
  267.                                         $this->error = 'Unknown content coding';
  268.                                         $this->success = false;
  269.                                 }
  270.                             }
  271.                         }
  272.                     }
  273.                     else
  274.                     {
  275.                         $this->error = 'fsocket timed out';
  276.                         $this->success = false;
  277.                     }
  278.                     fclose($fp);
  279.                 }
  280.             }
  281.         }
  282.         else
  283.         {
  284.             $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
  285.             if (!$this->body = file_get_contents($url))
  286.             {
  287.                 $this->error = 'file_get_contents could not read the file';
  288.                 $this->success = false;
  289.             }
  290.         }
  291.     }
  292. }
  293.