3 * SimplePie |
3 * SimplePie |
4 * |
4 * |
5 * A PHP-Based RSS and Atom Feed Framework. |
5 * A PHP-Based RSS and Atom Feed Framework. |
6 * Takes the hard work out of managing a complete RSS/Atom solution. |
6 * Takes the hard work out of managing a complete RSS/Atom solution. |
7 * |
7 * |
8 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors |
8 * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors |
9 * All rights reserved. |
9 * All rights reserved. |
10 * |
10 * |
11 * Redistribution and use in source and binary forms, with or without modification, are |
11 * Redistribution and use in source and binary forms, with or without modification, are |
12 * permitted provided that the following conditions are met: |
12 * permitted provided that the following conditions are met: |
13 * |
13 * |
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
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 |
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33 * POSSIBILITY OF SUCH DAMAGE. |
33 * POSSIBILITY OF SUCH DAMAGE. |
34 * |
34 * |
35 * @package SimplePie |
35 * @package SimplePie |
36 * @version 1.3.1 |
36 * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue |
37 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue |
|
38 * @author Ryan Parman |
37 * @author Ryan Parman |
39 * @author Geoffrey Sneddon |
38 * @author Sam Sneddon |
40 * @author Ryan McCue |
39 * @author Ryan McCue |
41 * @link http://simplepie.org/ SimplePie |
40 * @link http://simplepie.org/ SimplePie |
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License |
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License |
43 */ |
42 */ |
44 |
43 |
62 var $body; |
61 var $body; |
63 var $status_code; |
62 var $status_code; |
64 var $redirects = 0; |
63 var $redirects = 0; |
65 var $error; |
64 var $error; |
66 var $method = SIMPLEPIE_FILE_SOURCE_NONE; |
65 var $method = SIMPLEPIE_FILE_SOURCE_NONE; |
67 |
66 var $permanent_url; |
68 public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) |
67 |
|
68 public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $curl_options = array()) |
69 { |
69 { |
70 if (class_exists('idna_convert')) |
70 if (class_exists('idna_convert')) |
71 { |
71 { |
72 $idn = new idna_convert(); |
72 $idn = new idna_convert(); |
73 $parsed = SimplePie_Misc::parse_url($url); |
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']); |
74 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], NULL); |
75 } |
75 } |
76 $this->url = $url; |
76 $this->url = $url; |
|
77 $this->permanent_url = $url; |
77 $this->useragent = $useragent; |
78 $this->useragent = $useragent; |
78 if (preg_match('/^http(s)?:\/\//i', $url)) |
79 if (preg_match('/^http(s)?:\/\//i', $url)) |
79 { |
80 { |
80 if ($useragent === null) |
81 if ($useragent === null) |
81 { |
82 { |
100 curl_setopt($fp, CURLOPT_ENCODING, ''); |
101 curl_setopt($fp, CURLOPT_ENCODING, ''); |
101 } |
102 } |
102 curl_setopt($fp, CURLOPT_URL, $url); |
103 curl_setopt($fp, CURLOPT_URL, $url); |
103 curl_setopt($fp, CURLOPT_HEADER, 1); |
104 curl_setopt($fp, CURLOPT_HEADER, 1); |
104 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); |
105 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); |
|
106 curl_setopt($fp, CURLOPT_FAILONERROR, 1); |
105 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); |
107 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); |
106 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); |
108 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); |
107 curl_setopt($fp, CURLOPT_REFERER, $url); |
109 curl_setopt($fp, CURLOPT_REFERER, $url); |
108 curl_setopt($fp, CURLOPT_USERAGENT, $useragent); |
110 curl_setopt($fp, CURLOPT_USERAGENT, $useragent); |
109 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); |
111 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', '>=')) |
112 if (!ini_get('open_basedir') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) |
111 { |
113 { |
112 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); |
114 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); |
113 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); |
115 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); |
114 } |
116 } |
|
117 foreach ($curl_options as $curl_param => $curl_value) { |
|
118 curl_setopt($fp, $curl_param, $curl_value); |
|
119 } |
115 |
120 |
116 $this->headers = curl_exec($fp); |
121 $this->headers = curl_exec($fp); |
117 if (curl_errno($fp) === 23 || curl_errno($fp) === 61) |
122 if (curl_errno($fp) === 23 || curl_errno($fp) === 61) |
118 { |
123 { |
119 curl_setopt($fp, CURLOPT_ENCODING, 'none'); |
124 curl_setopt($fp, CURLOPT_ENCODING, 'none'); |
124 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); |
129 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); |
125 $this->success = false; |
130 $this->success = false; |
126 } |
131 } |
127 else |
132 else |
128 { |
133 { |
129 $info = curl_getinfo($fp); |
134 // Use the updated url provided by curl_getinfo after any redirects. |
|
135 if ($info = curl_getinfo($fp)) { |
|
136 $this->url = $info['url']; |
|
137 } |
130 curl_close($fp); |
138 curl_close($fp); |
131 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); |
139 $this->headers = SimplePie_HTTP_Parser::prepareHeaders($this->headers, $info['redirect_count'] + 1); |
132 $this->headers = array_pop($this->headers); |
|
133 $parser = new SimplePie_HTTP_Parser($this->headers); |
140 $parser = new SimplePie_HTTP_Parser($this->headers); |
134 if ($parser->parse()) |
141 if ($parser->parse()) |
135 { |
142 { |
136 $this->headers = $parser->headers; |
143 $this->headers = $parser->headers; |
137 $this->body = $parser->body; |
144 $this->body = trim($parser->body); |
138 $this->status_code = $parser->status_code; |
145 $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) |
146 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 { |
147 { |
141 $this->redirects++; |
148 $this->redirects++; |
142 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); |
149 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); |
143 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); |
150 $previousStatusCode = $this->status_code; |
|
151 $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); |
|
152 $this->permanent_url = ($previousStatusCode == 301) ? $location : $url; |
|
153 return; |
144 } |
154 } |
145 } |
155 } |
146 } |
156 } |
147 } |
157 } |
148 else |
158 else |
220 $this->status_code = $parser->status_code; |
230 $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) |
231 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 { |
232 { |
223 $this->redirects++; |
233 $this->redirects++; |
224 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); |
234 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); |
225 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); |
235 $previousStatusCode = $this->status_code; |
|
236 $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); |
|
237 $this->permanent_url = ($previousStatusCode == 301) ? $location : $url; |
|
238 return; |
226 } |
239 } |
227 if (isset($this->headers['content-encoding'])) |
240 if (isset($this->headers['content-encoding'])) |
228 { |
241 { |
229 // Hey, we act dumb elsewhere, so let's do that here too |
242 // Hey, we act dumb elsewhere, so let's do that here too |
230 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20"))) |
243 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20"))) |