* @author Stig Bakken * @author Tomas V.V.Cox * @author Greg Beaver * @copyright 1997-2005 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: PEAR.php,v 1.96 2005/09/21 00:12:35 cellog Exp $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ define('PEAR_ERROR_RETURN', 1); define('PEAR_ERROR_PRINT', 2); define('PEAR_ERROR_TRIGGER', 4); define('PEAR_ERROR_DIE', 8); define('PEAR_ERROR_CALLBACK', 16); define('PEAR_ERROR_EXCEPTION', 32); define('PEAR_ZE2', (function_exists('version_compare') && version_compare(zend_version(), "2-dev", "ge"))); if (substr(PHP_OS, 0, 3) == 'WIN') { define('OS_WINDOWS', true); define('OS_UNIX', false); define('PEAR_OS', 'Windows'); } else { define('OS_WINDOWS', false); define('OS_UNIX', true); define('PEAR_OS', 'Unix'); // blatant assumption } if (!defined('PATH_SEPARATOR')) { if (OS_WINDOWS) { define('PATH_SEPARATOR', ';'); } else { define('PATH_SEPARATOR', ':'); } } $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; $GLOBALS['_PEAR_destructor_object_list'] = array(); $GLOBALS['_PEAR_shutdown_funcs'] = array(); $GLOBALS['_PEAR_error_handler_stack'] = array(); @ini_set('track_errors', true); class PEAR { var $_debug = false; var $_default_error_mode = null; var $_default_error_options = null; var $_default_error_handler = ''; var $_error_class = 'PEAR_Error'; var $_expected_errors = array(); function PEAR($error_class = null) { $classname = strtolower(get_class($this)); if ($this->_debug) { print "PEAR constructor called, class=$classname\n"; } if ($error_class !== null) { $this->_error_class = $error_class; } while ($classname && strcasecmp($classname, "pear")) { $destructor = "_$classname"; if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; $_PEAR_destructor_object_list[] = &$this; if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { register_shutdown_function("_PEAR_call_destructors"); $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; } break; } else { $classname = get_parent_class($classname); } } } function _PEAR() { if ($this->_debug) { printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); } } function &getStaticProperty($class, $var) { static $properties; return $properties[$class][$var]; } function registerShutdownFunc($func, $args = array()) { $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); } function isError($data, $code = null) { if (is_a($data, 'PEAR_Error')) { if (is_null($code)) { return true; } elseif (is_string($code)) { return $data->getMessage() == $code; } else { return $data->getCode() == $code; } } return false; } function setErrorHandling($mode = null, $options = null) { if (isset($this) && is_a($this, 'PEAR')) { $setmode = &$this->_default_error_mode; $setoptions = &$this->_default_error_options; } else { $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; } switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $setmode = $mode; $setoptions = $options; break; case PEAR_ERROR_CALLBACK: $setmode = $mode; // class/object method callback if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } } function expectError($code = '*') { if (is_array($code)) { array_push($this->_expected_errors, $code); } else { array_push($this->_expected_errors, array($code)); } return sizeof($this->_expected_errors); } function popExpect() { return array_pop($this->_expected_errors); } function _checkDelExpect($error_code) { $deleted = false; foreach ($this->_expected_errors AS $key => $error_array) { if (in_array($error_code, $error_array)) { unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); $deleted = true; } if (0 == count($this->_expected_errors[$key])) { unset($this->_expected_errors[$key]); } } return $deleted; } function delExpect($error_code) { $deleted = false; if ((is_array($error_code) && (0 != count($error_code)))) { foreach($error_code as $key => $error) { if ($this->_checkDelExpect($error)) { $deleted = true; } else { $deleted = false; } } return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME } elseif (!empty($error_code)) { if ($this->_checkDelExpect($error_code)) { return true; } else { return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME } } else { return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME } } function &raiseError($message = null, $code = null, $mode = null, $options = null, $userinfo = null, $error_class = null, $skipmsg = false) { // The error is yet a PEAR error object if (is_object($message)) { $code = $message->getCode(); $userinfo = $message->getUserInfo(); $error_class = $message->getType(); $message->error_message_prefix = ''; $message = $message->getMessage(); } if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { if ($exp[0] == "*" || (is_int(reset($exp)) && in_array($code, $exp)) || (is_string(reset($exp)) && in_array($message, $exp))) { $mode = PEAR_ERROR_RETURN; } } if ($mode === null) { if (isset($this) && isset($this->_default_error_mode)) { $mode = $this->_default_error_mode; $options = $this->_default_error_options; } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { $mode = $GLOBALS['_PEAR_default_error_mode']; $options = $GLOBALS['_PEAR_default_error_options']; } } if ($error_class !== null) { $ec = $error_class; } elseif (isset($this) && isset($this->_error_class)) { $ec = $this->_error_class; } else { $ec = 'PEAR_Error'; } if ($skipmsg) { $a = new $ec($code, $mode, $options, $userinfo); return $a; } else { $a = new $ec($message, $code, $mode, $options, $userinfo); return $a; } } function &throwError($message = null, $code = null, $userinfo = null) { if (isset($this) && is_a($this, 'PEAR')) { $a = &$this->raiseError($message, $code, null, null, $userinfo); return $a; } else { $a = &PEAR::raiseError($message, $code, null, null, $userinfo); return $a; } } function staticPushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; $stack[] = array($def_mode, $def_options); switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $def_mode = $mode; $def_options = $options; break; case PEAR_ERROR_CALLBACK: $def_mode = $mode; if (is_callable($options)) { $def_options = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } $stack[] = array($mode, $options); return true; } function staticPopErrorHandling() { $stack = &$GLOBALS['_PEAR_error_handler_stack']; $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $setmode = $mode; $setoptions = $options; break; case PEAR_ERROR_CALLBACK: $setmode = $mode; // class/object method callback if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } return true; } function pushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; if (isset($this) && is_a($this, 'PEAR')) { $def_mode = &$this->_default_error_mode; $def_options = &$this->_default_error_options; } else { $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; } $stack[] = array($def_mode, $def_options); if (isset($this) && is_a($this, 'PEAR')) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } $stack[] = array($mode, $options); return true; } function popErrorHandling() { $stack = &$GLOBALS['_PEAR_error_handler_stack']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); if (isset($this) && is_a($this, 'PEAR')) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } return true; } function loadExtension($ext) { if (!extension_loaded($ext)) { if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { return false; } if (OS_WINDOWS) { $suffix = '.dll'; } elseif (PHP_OS == 'HP-UX') { $suffix = '.sl'; } elseif (PHP_OS == 'AIX') { $suffix = '.a'; } elseif (PHP_OS == 'OSX') { $suffix = '.bundle'; } else { $suffix = '.so'; } return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); } return true; } } function _PEAR_call_destructors() { global $_PEAR_destructor_object_list; if (is_array($_PEAR_destructor_object_list) && sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) { $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); } while (list($k, $objref) = each($_PEAR_destructor_object_list)) { $classname = get_class($objref); while ($classname) { $destructor = "_$classname"; if (method_exists($objref, $destructor)) { $objref->$destructor(); break; } else { $classname = get_parent_class($classname); } } } $_PEAR_destructor_object_list = array(); } if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { call_user_func_array($value[0], $value[1]); } } } class PEAR_Error { function PEAR_Error($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null) { if ($mode === null) { $mode = PEAR_ERROR_RETURN; } $this->message = $message; $this->code = $code; $this->mode = $mode; $this->userinfo = $userinfo; if (function_exists("debug_backtrace")) { if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { $this->backtrace = debug_backtrace(); } } if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; $this->callback = $options; } else { if ($options === null) { $options = E_USER_NOTICE; } $this->level = $options; $this->callback = null; } if ($this->mode & PEAR_ERROR_PRINT) { if (is_null($options) || is_int($options)) { $format = "%s"; } else { $format = $options; } printf($format, $this->getMessage()); } if ($this->mode & PEAR_ERROR_TRIGGER) { trigger_error($this->getMessage(), $this->level); } if ($this->mode & PEAR_ERROR_DIE) { $msg = $this->getMessage(); if (is_null($options) || is_int($options)) { $format = "%s"; if (substr($msg, -1) != "\n") { $msg .= "\n"; } } else { $format = $options; } die(sprintf($format, $msg)); } if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_callable($this->callback)) { call_user_func($this->callback, $this); } } if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); eval('$e = new Exception($this->message, $this->code);throw($e);'); } } function getMode() { return $this->mode; } function getCallback() { return $this->callback; } function getMessage() { return ($this->error_message_prefix . $this->message); } function getCode() { return $this->code; } function getType() { return get_class($this); } function getUserInfo() { return $this->userinfo; } function getDebugInfo() { return $this->getUserInfo(); } function getBacktrace($frame = null) { if (defined('PEAR_IGNORE_BACKTRACE')) { return null; } if ($frame === null) { return $this->backtrace; } return $this->backtrace[$frame]; } function addUserInfo($info) { if (empty($this->userinfo)) { $this->userinfo = $info; } else { $this->userinfo .= " ** $info"; } } function toString() { $modes = array(); $levels = array(E_USER_NOTICE => 'notice', E_USER_WARNING => 'warning', E_USER_ERROR => 'error'); if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_array($this->callback)) { $callback = (is_object($this->callback[0]) ? strtolower(get_class($this->callback[0])) : $this->callback[0]) . '::' . $this->callback[1]; } else { $callback = $this->callback; } return sprintf('[%s: message="%s" code=%d mode=callback '. 'callback=%s prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo); } if ($this->mode & PEAR_ERROR_PRINT) { $modes[] = 'print'; } if ($this->mode & PEAR_ERROR_TRIGGER) { $modes[] = 'trigger'; } if ($this->mode & PEAR_ERROR_DIE) { $modes[] = 'die'; } if ($this->mode & PEAR_ERROR_RETURN) { $modes[] = 'return'; } return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 'prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, implode("|", $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo); } } /** * HTTP_Request.php code: */ // +-----------------------------------------------------------------------+ // | Copyright (c) 2002-2003, Richard Heyes | // | All rights reserved. | // +-----------------------------------------------------------------------+ define('HTTP_REQUEST_METHOD_GET', 'GET', true); define('HTTP_REQUEST_METHOD_HEAD', 'HEAD', true); define('HTTP_REQUEST_METHOD_POST', 'POST', true); define('HTTP_REQUEST_METHOD_PUT', 'PUT', true); define('HTTP_REQUEST_METHOD_DELETE', 'DELETE', true); define('HTTP_REQUEST_METHOD_OPTIONS', 'OPTIONS', true); define('HTTP_REQUEST_METHOD_TRACE', 'TRACE', true); define('HTTP_REQUEST_HTTP_VER_1_0', '1.0', true); define('HTTP_REQUEST_HTTP_VER_1_1', '1.1', true); class HTTP_Request { var $_url; var $_method; var $_http; var $_requestHeaders; var $_user; var $_pass; var $_sock; var $_proxy_host; var $_proxy_port; var $_proxy_user; var $_proxy_pass; var $_postData; var $_body; var $_bodyDisallowed = array('TRACE'); var $_postFiles = array(); var $_timeout; var $_response; var $_allowRedirects; var $_maxRedirects; var $_redirects; var $_useBrackets = true; var $_listeners = array(); var $_saveBody = true; var $_readTimeout = null; var $_socketOptions = null; function HTTP_Request($url = '', $params = array()) { $this->_sock = new Net_Socket(); $this->_method = HTTP_REQUEST_METHOD_GET; $this->_http = HTTP_REQUEST_HTTP_VER_1_1; $this->_requestHeaders = array(); $this->_postData = array(); $this->_body = null; $this->_user = null; $this->_pass = null; $this->_proxy_host = null; $this->_proxy_port = null; $this->_proxy_user = null; $this->_proxy_pass = null; $this->_allowRedirects = false; $this->_maxRedirects = 3; $this->_redirects = 0; $this->_timeout = null; $this->_response = null; foreach ($params as $key => $value) { $this->{'_' . $key} = $value; } if (!empty($url)) { $this->setURL($url); } $this->addHeader('User-Agent', 'PEAR HTTP_Request class ( http://pear.php.net/ )'); $this->addHeader('Connection', 'close'); if (!empty($this->_user)) { $this->addHeader('Authorization', 'Basic ' . base64_encode($this->_user . ':' . $this->_pass)); } if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && extension_loaded('zlib') && 0 == (2 & ini_get('mbstring.func_overload'))) { $this->addHeader('Accept-Encoding', 'gzip'); } } function _generateHostHeader() { if ($this->_url->port != 80 AND strcasecmp($this->_url->protocol, 'http') == 0) { $host = $this->_url->host . ':' . $this->_url->port; } elseif ($this->_url->port != 443 AND strcasecmp($this->_url->protocol, 'https') == 0) { $host = $this->_url->host . ':' . $this->_url->port; } elseif ($this->_url->port == 443 AND strcasecmp($this->_url->protocol, 'https') == 0 AND strpos($this->_url->url, ':443') !== false) { $host = $this->_url->host . ':' . $this->_url->port; } else { $host = $this->_url->host; } return $host; } function reset($url, $params = array()) { $this->HTTP_Request($url, $params); } function setURL($url) { $this->_url = new Net_URL($url, $this->_useBrackets); if (!empty($this->_url->user) || !empty($this->_url->pass)) { $this->setBasicAuth($this->_url->user, $this->_url->pass); } if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http) { $this->addHeader('Host', $this->_generateHostHeader()); } } function setProxy($host, $port = 8080, $user = null, $pass = null) { $this->_proxy_host = $host; $this->_proxy_port = $port; $this->_proxy_user = $user; $this->_proxy_pass = $pass; if (!empty($user)) { $this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($user . ':' . $pass)); } } function setBasicAuth($user, $pass) { $this->_user = $user; $this->_pass = $pass; $this->addHeader('Authorization', 'Basic ' . base64_encode($user . ':' . $pass)); } function setMethod($method) { $this->_method = $method; } function setHttpVer($http) { $this->_http = $http; } function addHeader($name, $value) { $this->_requestHeaders[strtolower($name)] = $value; } function removeHeader($name) { if (isset($this->_requestHeaders[strtolower($name)])) { unset($this->_requestHeaders[strtolower($name)]); } } function addQueryString($name, $value, $preencoded = false) { $this->_url->addQueryString($name, $value, $preencoded); } function addRawQueryString($querystring, $preencoded = true) { $this->_url->addRawQueryString($querystring, $preencoded); } function addPostData($name, $value, $preencoded = false) { if ($preencoded) { $this->_postData[$name] = $value; } else { $this->_postData[$name] = $this->_arrayMapRecursive('urlencode', $value); } } function _arrayMapRecursive($callback, $value) { if (!is_array($value)) { return call_user_func($callback, $value); } else { $map = array(); foreach ($value as $k => $v) { $map[$k] = $this->_arrayMapRecursive($callback, $v); } return $map; } } function addFile($inputName, $fileName, $contentType = 'application/octet-stream') { if (!is_array($fileName) && !is_readable($fileName)) { return PEAR::raiseError("File '{$fileName}' is not readable"); } elseif (is_array($fileName)) { foreach ($fileName as $name) { if (!is_readable($name)) { return PEAR::raiseError("File '{$name}' is not readable"); } } } $this->addHeader('Content-Type', 'multipart/form-data'); $this->_postFiles[$inputName] = array( 'name' => $fileName, 'type' => $contentType ); return true; } function addRawPostData($postdata, $preencoded = true) { $this->_body = $preencoded ? $postdata : urlencode($postdata); } function setBody($body) { $this->_body = $body; } function clearPostData() { $this->_postData = null; } function addCookie($name, $value) { $cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : ''; $this->addHeader('Cookie', $cookies . $name . '=' . $value); } function clearCookies() { $this->removeHeader('Cookie'); } function sendRequest($saveBody = true) { if (!is_a($this->_url, 'Net_URL')) { return PEAR::raiseError('No URL given.'); } $host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host; $port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port; if (strcasecmp($this->_url->protocol, 'https') == 0 AND function_exists('file_get_contents') AND extension_loaded('openssl')) { if (isset($this->_proxy_host)) { return PEAR::raiseError('HTTPS proxies are not supported.'); } $host = 'ssl://' . $host; } $magicQuotes = ini_get('magic_quotes_runtime'); ini_set('magic_quotes_runtime', false); $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions); PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest()); if (!PEAR::isError($err)) { if (!empty($this->_readTimeout)) { $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]); } $this->_notify('sentRequest'); $this->_response = new HTTP_Response($this->_sock, $this->_listeners); $err = $this->_response->process($this->_saveBody && $saveBody); } ini_set('magic_quotes_runtime', $magicQuotes); if (PEAR::isError($err)) { return $err; } if ( $this->_allowRedirects AND $this->_redirects <= $this->_maxRedirects AND $this->getResponseCode() > 300 AND $this->getResponseCode() < 399 AND !empty($this->_response->_headers['location'])) { $redirect = $this->_response->_headers['location']; // Absolute URL if (preg_match('/^https?:\/\//i', $redirect)) { $this->_url = new Net_URL($redirect); $this->addHeader('Host', $this->_generateHostHeader()); // Absolute path } elseif ($redirect{0} == '/') { $this->_url->path = $redirect; // Relative path } elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') { if (substr($this->_url->path, -1) == '/') { $redirect = $this->_url->path . $redirect; } else { $redirect = dirname($this->_url->path) . '/' . $redirect; } $redirect = Net_URL::resolvePath($redirect); $this->_url->path = $redirect; } else { if (substr($this->_url->path, -1) == '/') { $redirect = $this->_url->path . $redirect; } else { $redirect = dirname($this->_url->path) . '/' . $redirect; } $this->_url->path = $redirect; } $this->_redirects++; return $this->sendRequest($saveBody); } elseif ($this->_allowRedirects AND $this->_redirects > $this->_maxRedirects) { return PEAR::raiseError('Too many redirects'); } $this->_sock->disconnect(); return true; } function getResponseCode() { return isset($this->_response->_code) ? $this->_response->_code : false; } function getResponseHeader($headername = null) { if (!isset($headername)) { return isset($this->_response->_headers)? $this->_response->_headers: array(); } else { $headername = strtolower($headername); return isset($this->_response->_headers[$headername]) ? $this->_response->_headers[$headername] : false; } } function getResponseBody() { return isset($this->_response->_body) ? $this->_response->_body : false; } function getResponseCookies() { return isset($this->_response->_cookies) ? $this->_response->_cookies : false; } function _buildRequest() { $separator = ini_get('arg_separator.output'); ini_set('arg_separator.output', '&'); $querystring = ($querystring = $this->_url->getQueryString()) ? '?' . $querystring : ''; ini_set('arg_separator.output', $separator); $host = isset($this->_proxy_host) ? $this->_url->protocol . '://' . $this->_url->host : ''; $port = (isset($this->_proxy_host) AND $this->_url->port != 80) ? ':' . $this->_url->port : ''; $path = (empty($this->_url->path)? '/': $this->_url->path) . $querystring; $url = $host . $port . $path; $request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n"; if (in_array($this->_method, $this->_bodyDisallowed) || (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body)) || (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_postData) && empty($this->_postFiles))) { $this->removeHeader('Content-Type'); } else { if (empty($this->_requestHeaders['content-type'])) { $this->addHeader('Content-Type', 'application/x-www-form-urlencoded'); } elseif ('multipart/form-data' == $this->_requestHeaders['content-type']) { $boundary = 'HTTP_Request_' . md5(uniqid('request') . microtime()); $this->addHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary); } } if (!empty($this->_requestHeaders)) { foreach ($this->_requestHeaders as $name => $value) { $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); $request .= $canonicalName . ': ' . $value . "\r\n"; } } if (in_array($this->_method, $this->_bodyDisallowed) || (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body))) { $request .= "\r\n"; } elseif (HTTP_REQUEST_METHOD_POST == $this->_method && (!empty($this->_postData) || !empty($this->_postFiles))) { if (!isset($boundary)) { $postdata = implode('&', array_map( create_function('$a', 'return $a[0] . \'=\' . $a[1];'), $this->_flattenArray('', $this->_postData) )); } else { $postdata = ''; if (!empty($this->_postData)) { $flatData = $this->_flattenArray('', $this->_postData); foreach ($flatData as $item) { $postdata .= '--' . $boundary . "\r\n"; $postdata .= 'Content-Disposition: form-data; name="' . $item[0] . '"'; $postdata .= "\r\n\r\n" . urldecode($item[1]) . "\r\n"; } } foreach ($this->_postFiles as $name => $value) { if (is_array($value['name'])) { $varname = $name . ($this->_useBrackets? '[]': ''); } else { $varname = $name; $value['name'] = array($value['name']); } foreach ($value['name'] as $key => $filename) { $fp = fopen($filename, 'r'); $data = fread($fp, filesize($filename)); fclose($fp); $basename = basename($filename); $type = is_array($value['type'])? @$value['type'][$key]: $value['type']; $postdata .= '--' . $boundary . "\r\n"; $postdata .= 'Content-Disposition: form-data; name="' . $varname . '"; filename="' . $basename . '"'; $postdata .= "\r\nContent-Type: " . $type; $postdata .= "\r\n\r\n" . $data . "\r\n"; } } $postdata .= '--' . $boundary . "--\r\n"; } $request .= 'Content-Length: ' . strlen($postdata) . "\r\n\r\n"; $request .= $postdata; // Explicitly set request body } elseif (!empty($this->_body)) { $request .= 'Content-Length: ' . strlen($this->_body) . "\r\n\r\n"; $request .= $this->_body; } return $request; } function _flattenArray($name, $values) { if (!is_array($values)) { return array(array($name, $values)); } else { $ret = array(); foreach ($values as $k => $v) { if (empty($name)) { $newName = $k; } elseif ($this->_useBrackets) { $newName = $name . '[' . $k . ']'; } else { $newName = $name; } $ret = array_merge($ret, $this->_flattenArray($newName, $v)); } return $ret; } } function attach(&$listener) { if (!is_a($listener, 'HTTP_Request_Listener')) { return false; } $this->_listeners[$listener->getId()] =& $listener; return true; } function detach(&$listener) { if (!is_a($listener, 'HTTP_Request_Listener') || !isset($this->_listeners[$listener->getId()])) { return false; } unset($this->_listeners[$listener->getId()]); return true; } function _notify($event, $data = null) { foreach (array_keys($this->_listeners) as $id) { $this->_listeners[$id]->update($this, $event, $data); } } } class HTTP_Response { var $_sock; var $_protocol; var $_code; var $_headers; var $_cookies; var $_body = ''; var $_chunkLength = 0; var $_listeners = array(); function HTTP_Response(&$sock, &$listeners) { $this->_sock =& $sock; $this->_listeners =& $listeners; } function process($saveBody = true) { do { $line = $this->_sock->readLine(); if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) { return PEAR::raiseError('Malformed response.'); } else { $this->_protocol = 'HTTP/' . $http_version; $this->_code = intval($returncode); } while ('' !== ($header = $this->_sock->readLine())) { $this->_processHeader($header); } } while (100 == $this->_code); $this->_notify('gotHeaders', $this->_headers); $chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']); $gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']); $hasBody = false; if (!isset($this->_headers['content-length']) || 0 != $this->_headers['content-length']) { while (!$this->_sock->eof()) { if ($chunked) { $data = $this->_readChunked(); } else { $data = $this->_sock->read(4096); } if ('' == $data) { break; } else { $hasBody = true; if ($saveBody || $gzipped) { $this->_body .= $data; } $this->_notify($gzipped? 'gzTick': 'tick', $data); } } } if ($hasBody) { if ($gzipped) { $this->_body = gzinflate(substr($this->_body, 10)); $this->_notify('gotBody', $this->_body); } else { $this->_notify('gotBody'); } } return true; } function _processHeader($header) { list($headername, $headervalue) = explode(':', $header, 2); $headername = strtolower($headername); $headervalue = ltrim($headervalue); if ('set-cookie' != $headername) { if (isset($this->_headers[$headername])) { $this->_headers[$headername] .= ',' . $headervalue; } else { $this->_headers[$headername] = $headervalue; } } else { $this->_parseCookie($headervalue); } } function _parseCookie($headervalue) { $cookie = array( 'expires' => null, 'domain' => null, 'path' => null, 'secure' => false ); if (!strpos($headervalue, ';')) { $pos = strpos($headervalue, '='); $cookie['name'] = trim(substr($headervalue, 0, $pos)); $cookie['value'] = trim(substr($headervalue, $pos + 1)); } else { $elements = explode(';', $headervalue); $pos = strpos($elements[0], '='); $cookie['name'] = trim(substr($elements[0], 0, $pos)); $cookie['value'] = trim(substr($elements[0], $pos + 1)); for ($i = 1; $i < count($elements); $i++) { if (false === strpos($elements[$i], '=')) { $elName = trim($elements[$i]); $elValue = null; } else { list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); } $elName = strtolower($elName); if ('secure' == $elName) { $cookie['secure'] = true; } elseif ('expires' == $elName) { $cookie['expires'] = str_replace('"', '', $elValue); } elseif ('path' == $elName || 'domain' == $elName) { $cookie[$elName] = urldecode($elValue); } else { $cookie[$elName] = $elValue; } } } $this->_cookies[] = $cookie; } function _readChunked() { if (0 == $this->_chunkLength) { $line = $this->_sock->readLine(); if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) { $this->_chunkLength = hexdec($matches[1]); if (0 == $this->_chunkLength) { $this->_sock->readLine(); return ''; } } else { return ''; } } $data = $this->_sock->read($this->_chunkLength); $this->_chunkLength -= strlen($data); if (0 == $this->_chunkLength) { $this->_sock->readLine(); } return $data; } function _notify($event, $data = null) { foreach (array_keys($this->_listeners) as $id) { $this->_listeners[$id]->update($this, $event, $data); } } } /** * Socket.php */ // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Stig Bakken | // | Chuck Hagenbuch | // +----------------------------------------------------------------------+ // // $Id: Socket.php,v 1.24 2005/02/03 20:40:16 chagenbu Exp $ define('NET_SOCKET_READ', 1); define('NET_SOCKET_WRITE', 2); define('NET_SOCKET_ERROR', 3); class Net_Socket extends PEAR { var $fp = null; var $blocking = true; var $persistent = false; var $addr = ''; var $port = 0; var $timeout = false; var $lineLength = 2048; function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null) { if (is_resource($this->fp)) { @fclose($this->fp); $this->fp = null; } if (!$addr) { return $this->raiseError('$addr cannot be empty'); } elseif (strspn($addr, '.0123456789') == strlen($addr) || strstr($addr, '/') !== false) { $this->addr = $addr; } else { $this->addr = @gethostbyname($addr); } $this->port = $port % 65536; if ($persistent !== null) { $this->persistent = $persistent; } if ($timeout !== null) { $this->timeout = $timeout; } $openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen'; $errno = 0; $errstr = ''; if ($options && function_exists('stream_context_create')) { if ($this->timeout) { $timeout = $this->timeout; } else { $timeout = 0; } $context = stream_context_create($options); $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); } else { if ($this->timeout) { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout); } else { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr); } } if (!$fp) { return $this->raiseError($errstr, $errno); } $this->fp = $fp; return $this->setBlocking($this->blocking); } function disconnect() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } @fclose($this->fp); $this->fp = null; return true; } function isBlocking() { return $this->blocking; } function setBlocking($mode) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $this->blocking = $mode; socket_set_blocking($this->fp, $this->blocking); return true; } function setTimeout($seconds, $microseconds) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return socket_set_timeout($this->fp, $seconds, $microseconds); } function getStatus() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return socket_get_status($this->fp); } function gets($size) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return @fgets($this->fp, $size); } function read($size) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return @fread($this->fp, $size); } function write($data, $blocksize = null) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } if (is_null($blocksize) && !OS_WINDOWS) { return fwrite($this->fp, $data); } else { if (is_null($blocksize)) { $blocksize = 1024; } $pos = 0; $size = strlen($data); while ($pos < $size) { $written = @fwrite($this->fp, substr($data, $pos, $blocksize)); if ($written === false) { return false; } $pos += $written; } return $pos; } } function writeLine($data) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return fwrite($this->fp, $data . "\r\n"); } function eof() { return (is_resource($this->fp) && feof($this->fp)); } function readByte() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return ord(@fread($this->fp, 1)); } function readWord() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 2); return (ord($buf[0]) + (ord($buf[1]) << 8)); } function readInt() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 4); return (ord($buf[0]) + (ord($buf[1]) << 8) + (ord($buf[2]) << 16) + (ord($buf[3]) << 24)); } function readString() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $string = ''; while (($char = @fread($this->fp, 1)) != "\x00") { $string .= $char; } return $string; } function readIPAddress() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 4); return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]), ord($buf[2]), ord($buf[3])); } function readLine() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $line = ''; $timeout = time() + $this->timeout; while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { $line .= @fgets($this->fp, $this->lineLength); if (substr($line, -1) == "\n") { return rtrim($line, "\r\n"); } } return $line; } function readAll() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $data = ''; while (!feof($this->fp)) { $data .= @fread($this->fp, $this->lineLength); } return $data; } function select($state, $tv_sec, $tv_usec = 0) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $read = null; $write = null; $except = null; if ($state & NET_SOCKET_READ) { $read[] = $this->fp; } if ($state & NET_SOCKET_WRITE) { $write[] = $this->fp; } if ($state & NET_SOCKET_ERROR) { $except[] = $this->fp; } if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { return false; } $result = 0; if (count($read)) { $result |= NET_SOCKET_READ; } if (count($write)) { $result |= NET_SOCKET_WRITE; } if (count($except)) { $result |= NET_SOCKET_ERROR; } return $result; } } /** * URL.php */ // +-----------------------------------------------------------------------+ // | Copyright (c) 2002-2004, Richard Heyes | // | All rights reserved. | // +-----------------------------------------------------------------------+ // $Id: URL.php,v 1.36 2004/06/19 18:58:50 richard Exp $ class Net_URL { var $url; var $protocol; var $username; var $password; var $host; var $port; var $path; var $querystring; var $anchor; var $useBrackets; function Net_URL($url = null, $useBrackets = true) { $this->__construct($url, $useBrackets); } function __construct($url = null, $useBrackets = true) { $HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; $this->useBrackets = $useBrackets; $this->url = $url; $this->user = ''; $this->pass = ''; $this->host = ''; $this->port = 80; $this->path = ''; $this->querystring = array(); $this->anchor = ''; if (!preg_match('/^[a-z0-9]+:\/\//i', $url)) { $this->protocol = (@$HTTP_SERVER_VARS['HTTPS'] == 'on' ? 'https' : 'http'); if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) AND preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) { $host = $matches[1]; if (!empty($matches[3])) { $port = $matches[3]; } else { $port = $this->getStandardPort($this->protocol); } } $this->user = ''; $this->pass = ''; $this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); $this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); $this->path = !empty($HTTP_SERVER_VARS['SCRIPT_NAME']) ? $HTTP_SERVER_VARS['SCRIPT_NAME'] : '/'; $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; $this->anchor = ''; } if (!empty($url)) { $urlinfo = parse_url($url); $this->querystring = array(); foreach ($urlinfo as $key => $value) { switch ($key) { case 'scheme': $this->protocol = $value; $this->port = $this->getStandardPort($value); break; case 'user': case 'pass': case 'host': case 'port': $this->$key = $value; break; case 'path': if ($value{0} == '/') { $this->path = $value; } else { $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); $this->path = sprintf('%s/%s', $path, $value); } break; case 'query': $this->querystring = $this->_parseRawQueryString($value); break; case 'fragment': $this->anchor = $value; break; } } } } function getURL() { $querystring = $this->getQueryString(); $this->url = $this->protocol . '://' . $this->user . (!empty($this->pass) ? ':' : '') . $this->pass . (!empty($this->user) ? '@' : '') . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) . $this->path . (!empty($querystring) ? '?' . $querystring : '') . (!empty($this->anchor) ? '#' . $this->anchor : ''); return $this->url; } function addQueryString($name, $value, $preencoded = false) { if ($preencoded) { $this->querystring[$name] = $value; } else { $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); } } function removeQueryString($name) { if (isset($this->querystring[$name])) { unset($this->querystring[$name]); } } function addRawQueryString($querystring) { $this->querystring = $this->_parseRawQueryString($querystring); } function getQueryString() { if (!empty($this->querystring)) { foreach ($this->querystring as $name => $value) { if (is_array($value)) { foreach ($value as $k => $v) { $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); } } elseif (!is_null($value)) { $querystring[] = $name . '=' . $value; } else { $querystring[] = $name; } } $querystring = implode(ini_get('arg_separator.output'), $querystring); } else { $querystring = ''; } return $querystring; } function _parseRawQuerystring($querystring) { $parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); $return = array(); foreach ($parts as $part) { if (strpos($part, '=') !== false) { $value = substr($part, strpos($part, '=') + 1); $key = substr($part, 0, strpos($part, '=')); } else { $value = null; $key = $part; } if (substr($key, -2) == '[]') { $key = substr($key, 0, -2); if (@!is_array($return[$key])) { $return[$key] = array(); $return[$key][] = $value; } else { $return[$key][] = $value; } } elseif (!$this->useBrackets AND !empty($return[$key])) { $return[$key] = (array)$return[$key]; $return[$key][] = $value; } else { $return[$key] = $value; } } return $return; } function resolvePath($path) { $path = explode('/', str_replace('//', '/', $path)); for ($i=0; $i 1 OR ($i == 1 AND $path[0] != '') ) ) { unset($path[$i]); unset($path[$i-1]); $path = array_values($path); $i -= 2; } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { unset($path[$i]); $path = array_values($path); $i--; } else { continue; } } return implode('/', $path); } function getStandardPort($scheme) { switch (strtolower($scheme)) { case 'http': return 80; case 'https': return 443; case 'ftp': return 21; case 'imap': return 143; case 'imaps': return 993; case 'pop3': return 110; case 'pop3s': return 995; default: return null; } } function setProtocol($protocol, $port = null) { $this->protocol = $protocol; $this->port = is_null($port) ? $this->getStandardPort() : $port; } } ?>