Return to Snippet

Revision: 18433
at September 30, 2009 08:52 by iroybot


Updated Code
<?php
/**
 * sicheres einlesen externer Dateien
 */
private function URLreadFsock($host, $file, &$errstr, $successonly=true, $port=80, $timeout=10) {
	if (!function_exists('fsockopen')) {
		$errstr = 'fsockopen() unavailable';
		return false;
	}
	if ($fp = @fsockopen($host, 80, $errno, $errstr, $timeout)) {
		$out  = 'GET '.$file.' HTTP/1.0'."
";
		$out .= 'Host: '.$host."
";
		$out .= 'Connection: Close'."

";
		fwrite($fp, $out);

		$isHeader = true;
		$Data_header = '';
		$Data_body   = '';
		$header_newlocation = '';
		while (!feof($fp)) {
			$line = fgets($fp, 1024);
			if ($isHeader) {
				$Data_header .= $line;
			} else {
				$Data_body .= $line;
			}
			if (eregi('^HTTP/[\\.0-9]+ ([0-9]+) (.+)$', rtrim($line), $matches)) {
				list($dummy, $errno, $errstr) = $matches;
				$errno = intval($errno);
			} elseif (eregi('^Location: (.*)$', rtrim($line), $matches)) {
				$header_newlocation = $matches[1];
			}
			if ($isHeader && ($line == "
")) {
				$isHeader = false;
				if ($successonly) {
					switch ($errno) {
						case 200:
							// great, continue
							break;

						default:
							$errstr = $errno.' '.$errstr.($header_newlocation ? '; Location: '.$header_newlocation : '');
							fclose($fp);
							return false;
							break;
					}
				}
			}
		}
		fclose($fp);
		return $Data_body;
	}
	return null;
}


private function ParseURLbetter($url) {
	$parsedURL = @parse_url($url);
	if (!@$parsedURL['port']) {
		switch (strtolower(@$parsedURL['scheme'])) {
			case 'ftp':
				$parsedURL['port'] = 21;
				break;
			case 'https':
				$parsedURL['port'] = 443;
				break;
			case 'http':
				$parsedURL['port'] = 80;
				break;
		}
	}
	return $parsedURL;
}

private function _getVersionFile($url, &$error, $timeout=10, $followredirects=true) {
	$error = '';

	$parsed_url = $this->ParseURLbetter($url);
	$alreadyLookedAtURLs[trim($url)] = true;

	while (true) {
		$tryagain = false;
		$rawData = $this->URLreadFsock(@$parsed_url['host'], @$parsed_url['path'].'?'.@$parsed_url['query'], $errstr, true, (@$parsed_url['port'] ? @$parsed_url['port'] : 80), $timeout);
		if (eregi('302 [a-z ]+; Location\\: (http.*)', $errstr, $matches)) {
			$matches[1] = trim(@$matches[1]);
			if (!@$alreadyLookedAtURLs[$matches[1]]) {
				// loop through and examine new URL
				$error .= 'URL "'.$url.'" redirected to "'.$matches[1].'"';

				$tryagain = true;
				$alreadyLookedAtURLs[$matches[1]] = true;
				$parsed_url = $this->ParseURLbetter($matches[1]);
			}
		}
		if (!$tryagain) {
			break;
		}
	}

	if ($rawData === false) {
		$error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
		return false;
	} elseif ($rawData === null) {
		// fall through
		$error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
	} else {
		return trim($rawData);
	}

	// curl
	if (function_exists('curl_version')) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
		$rawData = curl_exec($ch);
		curl_close($ch);
		if (strlen($rawData) > 0) {
			$error .= 'CURL succeeded ('.strlen($rawData).' bytes); ';
			return trim($rawData);
		}
		$error .= 'CURL available but returned no data; ';
	} else {
		$error .= 'CURL unavailable; ';
	}

	// fopen
	$BrokenURLfopenPHPversions = array('4.4.2');
	if (in_array(phpversion(), $BrokenURLfopenPHPversions)) {
		$error .= 'fopen(URL) broken in PHP v'.phpversion().'; ';
	} elseif (@ini_get('allow_url_fopen')) {
		$rawData = '';
		$error_fopen = '';
		ob_start();
		if ($fp = fopen($url, 'rb')) {
			do {
				$buffer = fread($fp, 8192);
				$rawData .= $buffer;
			} while (strlen($buffer) > 0);
			fclose($fp);
		} else {
			$error_fopen .= trim(strip_tags(ob_get_contents()));
		}
		ob_end_clean();
		$error .= $error_fopen;
		if (!$error_fopen) {
			$error .= '; "allow_url_fopen" succeeded ('.strlen($rawData).' bytes); ';
			return trim($rawData);
		}
		$error .= '; "allow_url_fopen" enabled but returned no data ('.$error_fopen.'); ';
	} else {
		$error .= '"allow_url_fopen" disabled; ';
	}
	return false;
}

Revision: 18432
at September 30, 2009 08:51 by iroybot


Initial Code
<?php
/**
 * sicheres einlesen externer Dateien
 */
private function URLreadFsock($host, $file, &$errstr, $successonly=true, $port=80, $timeout=10) {
	if (!function_exists('fsockopen')) {
		$errstr = 'fsockopen() unavailable';
		return false;
	}
	if ($fp = @fsockopen($host, 80, $errno, $errstr, $timeout)) {
		$out  = 'GET '.$file.' HTTP/1.0'."
";
		$out .= 'Host: '.$host."
";
		$out .= 'Connection: Close'."

";
		fwrite($fp, $out);

		$isHeader = true;
		$Data_header = '';
		$Data_body   = '';
		$header_newlocation = '';
		while (!feof($fp)) {
			$line = fgets($fp, 1024);
			if ($isHeader) {
				$Data_header .= $line;
			} else {
				$Data_body .= $line;
			}
			if (eregi('^HTTP/[\\.0-9]+ ([0-9]+) (.+)$', rtrim($line), $matches)) {
				list($dummy, $errno, $errstr) = $matches;
				$errno = intval($errno);
			} elseif (eregi('^Location: (.*)$', rtrim($line), $matches)) {
				$header_newlocation = $matches[1];
			}
			if ($isHeader && ($line == "
")) {
				$isHeader = false;
				if ($successonly) {
					switch ($errno) {
						case 200:
							// great, continue
							break;

						default:
							$errstr = $errno.' '.$errstr.($header_newlocation ? '; Location: '.$header_newlocation : '');
							fclose($fp);
							return false;
							break;
					}
				}
			}
		}
		fclose($fp);
		return $Data_body;
	}
	return null;
}


private function ParseURLbetter($url) {
	$parsedURL = @parse_url($url);
	if (!@$parsedURL['port']) {
		switch (strtolower(@$parsedURL['scheme'])) {
			case 'ftp':
				$parsedURL['port'] = 21;
				break;
			case 'https':
				$parsedURL['port'] = 443;
				break;
			case 'http':
				$parsedURL['port'] = 80;
				break;
		}
	}
	return $parsedURL;
}


// fetch the latest version of XStandard
private function _getVersionFile($url, &$error, $timeout=10, $followredirects=true) {
	$error = '';

	$parsed_url = $this->ParseURLbetter($url);
	$alreadyLookedAtURLs[trim($url)] = true;

	while (true) {
		$tryagain = false;
		$rawData = $this->URLreadFsock(@$parsed_url['host'], @$parsed_url['path'].'?'.@$parsed_url['query'], $errstr, true, (@$parsed_url['port'] ? @$parsed_url['port'] : 80), $timeout);
		if (eregi('302 [a-z ]+; Location\\: (http.*)', $errstr, $matches)) {
			$matches[1] = trim(@$matches[1]);
			if (!@$alreadyLookedAtURLs[$matches[1]]) {
				// loop through and examine new URL
				$error .= 'URL "'.$url.'" redirected to "'.$matches[1].'"';

				$tryagain = true;
				$alreadyLookedAtURLs[$matches[1]] = true;
				$parsed_url = $this->ParseURLbetter($matches[1]);
			}
		}
		if (!$tryagain) {
			break;
		}
	}

	if ($rawData === false) {
		$error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
		return false;
	} elseif ($rawData === null) {
		// fall through
		$error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
	} else {
		return trim($rawData);
	}

	// curl
	if (function_exists('curl_version')) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
		$rawData = curl_exec($ch);
		curl_close($ch);
		if (strlen($rawData) > 0) {
			$error .= 'CURL succeeded ('.strlen($rawData).' bytes); ';
			return trim($rawData);
		}
		$error .= 'CURL available but returned no data; ';
	} else {
		$error .= 'CURL unavailable; ';
	}

	// fopen
	$BrokenURLfopenPHPversions = array('4.4.2');
	if (in_array(phpversion(), $BrokenURLfopenPHPversions)) {
		$error .= 'fopen(URL) broken in PHP v'.phpversion().'; ';
	} elseif (@ini_get('allow_url_fopen')) {
		$rawData = '';
		$error_fopen = '';
		ob_start();
		if ($fp = fopen($url, 'rb')) {
			do {
				$buffer = fread($fp, 8192);
				$rawData .= $buffer;
			} while (strlen($buffer) > 0);
			fclose($fp);
		} else {
			$error_fopen .= trim(strip_tags(ob_get_contents()));
		}
		ob_end_clean();
		$error .= $error_fopen;
		if (!$error_fopen) {
			$error .= '; "allow_url_fopen" succeeded ('.strlen($rawData).' bytes); ';
			return trim($rawData);
		}
		$error .= '; "allow_url_fopen" enabled but returned no data ('.$error_fopen.'); ';
	} else {
		$error .= '"allow_url_fopen" disabled; ';
	}
	return false;
}

Initial URL


Initial Description
this comes from YAPB plugin for WordPress. kudos to the author.
(there are some functions that are deprecated in PHP 5.2+ - you'll need to replace eregi with the mb_ version). This should be quite failsafe, regardless if curl is installed or the settings in your php.ini (allow_url_fopen), etc.

Initial Title
Reading external files - the safe way

Initial Tags
curl, php

Initial Language
PHP