/** * @dataProvider chunkedProvider */ public function testChunkedNormal($data, $expected) { $data = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n" . $data; $parser = new SimplePie_HTTP_Parser($data); $this->assertTrue($parser->parse()); $this->assertEquals(1.1, $parser->http_version); $this->assertEquals(200, $parser->status_code); $this->assertEquals('OK', $parser->reason); $this->assertEquals(array('content-type' => 'text/plain'), $parser->headers); $this->assertEquals($expected, $parser->body); }
public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) { if (class_exists('idna_convert')) { $idn = new idna_convert(); $parsed = SimplePie_Misc::parse_url($url); $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); } $this->url = $url; $this->useragent = $useragent; if (preg_match('/^http(s)?:\\/\\//i', $url)) { if (!is_array($headers)) { $headers = array(); } $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; $headers2 = array(); foreach ($headers as $key => $value) { $headers2[] = "{$key}: {$value}"; } //TODO: allow for HTTP headers // curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); $response = self::$agent->get($url); if ($response === false || !isset($response['status_code'])) { $this->error = 'failed to fetch URL'; $this->success = false; } else { // The extra lines at the end are there to satisfy SimplePie's HTTP parser. // The class expects a full HTTP message, whereas we're giving it only // headers - the new lines indicate the start of the body. $parser = new SimplePie_HTTP_Parser($response['headers'] . "\r\n\r\n"); if ($parser->parse()) { $this->headers = $parser->headers; //$this->body = $parser->body; $this->body = $response['body']; $this->status_code = $parser->status_code; } } } else { $this->error = 'invalid URL'; $this->success = false; } }
/** * The contructor is a copy of the stock simplepie File class which has * been modifed to add in use the Moodle curl class rather than php curl * functions. */ function moodle_simplepie_file($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) { $this->url = $url; $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; $curl = new curl(); $curl->setopt(array('CURLOPT_HEADER' => true, 'CURLOPT_TIMEOUT' => $timeout, 'CURLOPT_CONNECTTIMEOUT' => $timeout)); if ($headers !== null) { // translate simplepie headers to those class curl expects foreach ($headers as $headername => $headervalue) { $headerstr = "{$headername}: {$headervalue}"; $curl->setHeader($headerstr); } } $this->headers = $curl->get($url); if ($curl->error) { $this->error = 'cURL Error: ' . $curl->error; $this->success = false; return false; } $parser = new SimplePie_HTTP_Parser($this->headers); if ($parser->parse()) { $this->headers = $parser->headers; $this->body = $parser->body; $this->status_code = $parser->status_code; if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) { $this->redirects++; $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); return $this->moodle_simplepie_file($location, $timeout, $redirects, $headers); } } }
public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) { if (class_exists('idna_convert')) { $idn = new idna_convert(); $parsed = SimplePie_Misc::parse_url($url); $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); } $this->url = $url; $this->useragent = $useragent; if (preg_match('/^http(s)?:\\/\\//i', $url)) { if ($useragent === null) { $useragent = ini_get('user_agent'); $this->useragent = $useragent; } if (!is_array($headers)) { $headers = array(); } if (!$force_fsockopen && function_exists('curl_exec')) { $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; $fp = curl_init(); $headers2 = array(); foreach ($headers as $key => $value) { $headers2[] = "{$key}: {$value}"; } if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>=')) { curl_setopt($fp, CURLOPT_ENCODING, ''); } curl_setopt($fp, CURLOPT_URL, $url); curl_setopt($fp, CURLOPT_HEADER, 1); curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($fp, CURLOPT_REFERER, $url); curl_setopt($fp, CURLOPT_USERAGENT, $useragent); curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) { curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); } $this->headers = curl_exec($fp); if (curl_errno($fp) === 23 || curl_errno($fp) === 61) { curl_setopt($fp, CURLOPT_ENCODING, 'none'); $this->headers = curl_exec($fp); } if (curl_errno($fp)) { $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); $this->success = false; } else { $info = curl_getinfo($fp); curl_close($fp); $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); $this->headers = array_pop($this->headers); $parser = new SimplePie_HTTP_Parser($this->headers); if ($parser->parse()) { $this->headers = $parser->headers; $this->body = $parser->body; $this->status_code = $parser->status_code; 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) { $this->redirects++; $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); } } } } else { $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN; $url_parts = parse_url($url); $socket_host = $url_parts['host']; if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') { $socket_host = "ssl://{$url_parts['host']}"; $url_parts['port'] = 443; } if (!isset($url_parts['port'])) { $url_parts['port'] = 80; } $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout); if (!$fp) { $this->error = 'fsockopen error: ' . $errstr; $this->success = false; } else { stream_set_timeout($fp, $timeout); if (isset($url_parts['path'])) { if (isset($url_parts['query'])) { $get = "{$url_parts['path']}?{$url_parts['query']}"; } else { $get = $url_parts['path']; } } else { $get = '/'; } $out = "GET {$get} HTTP/1.1\r\n"; $out .= "Host: {$url_parts['host']}\r\n"; $out .= "User-Agent: {$useragent}\r\n"; if (extension_loaded('zlib')) { $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n"; } if (isset($url_parts['user']) && isset($url_parts['pass'])) { $out .= "Authorization: Basic " . base64_encode("{$url_parts['user']}:{$url_parts['pass']}") . "\r\n"; } foreach ($headers as $key => $value) { $out .= "{$key}: {$value}\r\n"; } $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); $info = stream_get_meta_data($fp); $this->headers = ''; while (!$info['eof'] && !$info['timed_out']) { $this->headers .= fread($fp, 1160); $info = stream_get_meta_data($fp); } if (!$info['timed_out']) { $parser = new SimplePie_HTTP_Parser($this->headers); if ($parser->parse()) { $this->headers = $parser->headers; $this->body = $parser->body; $this->status_code = $parser->status_code; 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) { $this->redirects++; $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); } if (isset($this->headers['content-encoding'])) { // Hey, we act dumb elsewhere, so let's do that here too switch (strtolower(trim($this->headers['content-encoding'], "\t\n\r "))) { case 'gzip': case 'x-gzip': $decoder = new SimplePie_gzdecode($this->body); if (!$decoder->parse()) { $this->error = 'Unable to decode HTTP "gzip" stream'; $this->success = false; } else { $this->body = $decoder->data; } break; case 'deflate': if (($decompressed = gzinflate($this->body)) !== false) { $this->body = $decompressed; } else { if (($decompressed = gzuncompress($this->body)) !== false) { $this->body = $decompressed; } else { if (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false) { $this->body = $decompressed; } else { $this->error = 'Unable to decode HTTP "deflate" stream'; $this->success = false; } } } break; default: $this->error = 'Unknown content coding'; $this->success = false; } } } } else { $this->error = 'fsocket timed out'; $this->success = false; } fclose($fp); } } } else { $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS; if (!($this->body = file_get_contents($url))) { $this->error = 'file_get_contents could not read the file'; $this->success = false; } } }
function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) { if (class_exists('idna_convert')) { $idn = new idna_convert(); $parsed = SimplePie_Misc::parse_url($url); $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); } $this->url = $url; $this->useragent = $useragent; if (preg_match('/^http(s)?:\\/\\//i', $url)) { if ($useragent === null) { $useragent = ini_get('user_agent'); $this->useragent = $useragent; } if (!is_array($headers)) { $headers = array(); } if (!$force_fsockopen && extension_loaded('curl')) { $this->method = 'curl'; $fp = curl_init(); $headers2 = array(); foreach ($headers as $key => $value) { $headers2[] = "{$key}: {$value}"; } if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>=')) { curl_setopt($fp, CURLOPT_ENCODING, ''); } curl_setopt($fp, CURLOPT_URL, $url); curl_setopt($fp, CURLOPT_HEADER, 1); curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($fp, CURLOPT_REFERER, $url); curl_setopt($fp, CURLOPT_USERAGENT, $useragent); curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) { curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); } $this->headers = curl_exec($fp); if (curl_errno($fp) == 23 || curl_errno($fp) == 61) { curl_setopt($fp, CURLOPT_ENCODING, 'none'); $this->headers = curl_exec($fp); } if (curl_errno($fp)) { $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); $this->success = false; } else { $info = curl_getinfo($fp); curl_close($fp); $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); $this->headers = array_pop($this->headers); $parser = new SimplePie_HTTP_Parser($this->headers); if ($parser->parse()) { $this->headers = $parser->headers; $this->body = $parser->body; $this->status_code = $parser->status_code; if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) { $this->redirects++; if (isset($this->headers['content-location'])) { $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url)); } else { $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); } return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); } } } } else { $this->method = 'fsockopen'; $url_parts = parse_url($url); if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https') { $url_parts['host'] = "ssl://{$url_parts['host']}"; $url_parts['port'] = 443; } if (!isset($url_parts['port'])) { $url_parts['port'] = 80; } $fp = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout); if (!$fp) { $this->error = 'fsockopen error: ' . $errstr; $this->success = false; } else { if (function_exists('stream_set_timeout')) { stream_set_timeout($fp, $timeout); } else { socket_set_timeout($fp, $timeout); } if (isset($url_parts['path'])) { if (isset($url_parts['query'])) { $get = "{$url_parts['path']}?{$url_parts['query']}"; } else { $get = $url_parts['path']; } } else { $get = '/'; } $out = "GET {$get} HTTP/1.0\r\n"; $out .= "Host: {$url_parts['host']}\r\n"; $out .= "User-Agent: {$useragent}\r\n"; if (function_exists('gzinflate')) { $out .= "Accept-Encoding: gzip,deflate\r\n"; } if (isset($url_parts['user']) && isset($url_parts['pass'])) { $out .= "Authorization: Basic " . base64_encode("{$url_parts['user']}:{$url_parts['pass']}") . "\r\n"; } foreach ($headers as $key => $value) { $out .= "{$key}: {$value}\r\n"; } $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); if (function_exists('stream_get_meta_data')) { $info = stream_get_meta_data($fp); } else { $info = socket_get_status($fp); } $this->headers = ''; while (!$info['eof'] && !$info['timed_out']) { $this->headers .= fread($fp, 1160); if (function_exists('stream_get_meta_data')) { $info = stream_get_meta_data($fp); } else { $info = socket_get_status($fp); } } if (!$info['timed_out']) { $parser = new SimplePie_HTTP_Parser($this->headers); if ($parser->parse()) { $this->headers = $parser->headers; $this->body = $parser->body; $this->status_code = $parser->status_code; if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) { $this->redirects++; if (isset($this->headers['content-location'])) { $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url)); } else { $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); } return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); } if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate')) { if (substr($this->body, 0, 8) == "�") { $this->body = substr($this->body, 10); } $this->body = gzinflate($this->body); } } } else { $this->error = 'fsocket timed out'; $this->success = false; } fclose($fp); } } } elseif (function_exists('file_get_contents')) { $this->method = 'file_get_contents'; if (!($this->body = file_get_contents($url))) { $this->error = 'file_get_contents could not read the file'; $this->success = false; } } else { $this->method = 'fopen'; if (($fp = fopen($url, 'rb')) === false) { $this->error = 'failed to open stream: No such file or directory'; $this->success = false; } else { $this->body = ''; while (!feof($fp)) { $this->body .= fread($fp, 8192); } fclose($fp); } } }
/** * extractHttp * * @param string $string Param * * @return string */ public static function extractHttp($string) { $parts = array(); $headers = explode("\r\n\r\n", $string, 1); $headers = array_pop($headers); // Why reinvent the wheel? $parser = new SimplePie_HTTP_Parser($headers); if ($parser->parse()) { $parts['header'] = $parser->headers; $parts['body'] = $parser->body; } return $parts; }