web/wp-includes/SimplePie/File.php
changeset 204 09a1c134465b
equal deleted inserted replaced
203:f507feede89a 204:09a1c134465b
       
     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 }