[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/SimplePie/src/ -> File.php (source)

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


Generated : Sat Dec 21 08:20:01 2024 Cross-referenced by PHPXref