diff options
Diffstat (limited to 'plugins/Irc/extlib/phergie/Phergie/Plugin/Http.php')
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/Plugin/Http.php | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Http.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Http.php new file mode 100644 index 000000000..ae43b34c3 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Plugin/Http.php @@ -0,0 +1,275 @@ +<?php +/** + * Phergie + * + * PHP version 5 + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE. + * It is also available through the world-wide-web at this URL: + * http://phergie.org/license + * + * @category Phergie + * @package Phergie_Plugin_Http + * @author Phergie Development Team <team@phergie.org> + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie_Plugin_Http + */ + +/** + * Provides an HTTP client for plugins to use in contacting web services or + * retrieving feeds or web pages. + * + * @category Phergie + * @package Phergie_Plugin_Http + * @author Phergie Development Team <team@phergie.org> + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie_Plugin_Http + * @uses extension simplexml optional + * @uses extension json optional + */ +class Phergie_Plugin_Http extends Phergie_Plugin_Abstract +{ + /** + * Response to the last executed HTTP request + * + * @var Phergie_Plugin_Http_Response + */ + protected $response; + + /** + * Mapping of content types to handlers for them + * + * @var array + */ + protected $handlers; + + /** + * Initializes the handler lookup table. + * + * @return void + */ + public function onLoad() + { + $this->handlers = array( + '(?:application|text)/xml(?:;.*)?' => 'simplexml_load_string', + '(?:(?:application|text)/(?:x-)?json)|text/javascript.*' => 'json_decode', + ); + + if (is_array($this->config['http.handlers'])) { + $this->handlers = array_merge( + $this->handlers, + $this->config['http.handlers'] + ); + } + } + + /** + * Sets a handler callback for a content type, which is called when a + * response of that content type is received to perform any needed + * transformations on the response body content before storing it in the + * response object. Note that the calling plugin is responsible for + * indicating any dependencies related to specified handler callbacks. + * + * @param string $type PCRE regular expression (without delimiters) that + * matches one or more MIME types + * @param callback $callback Callback to execute when a response of a content + * type matched by $type is encountered + * + * @return Phergie_Plugin_Http Provides a fluent interface + */ + public function setHandler($type, $callback) + { + if (!is_callable($callback)) { + throw new Phergie_Plugin_Exception( + 'Invalid callback specified', + Phergie_Plugin_Exception::ERR_FATAL_ERROR + ); + } + + $this->handlers[$type] = $callback; + + return $this; + } + + /** + * Supporting method that parses the status line of an HTTP response + * message. + * + * @param string $status Status line + * + * @return array Associative array containing the HTTP version, response + * code, and response description + */ + protected function parseStatusLine($status) + { + $parts = explode(' ', $status, 3); + $parsed = array( + 'version' => str_replace('HTTP/', '', $parts[0]), + 'code' => $parts[1], + 'message' => rtrim($parts[2]) + ); + return $parsed; + } + + /** + * Supporting method that acts as an error handler to intercept HTTP + * responses resulting in PHP-level errors. + * + * @param int $errno Level of the error raised + * @param string $errstr Error message + * @param string $errfile Name of the file in which the error was raised + * @param string $errline Line number on which the error was raised + * + * @return bool Always returns TRUE to allow normal execution to + * continue once this method terminates + */ + protected function handleError($errno, $errstr, $errfile, $errline) + { + if ($httperr = strstr($errstr, 'HTTP/')) { + $parts = $this->parseStatusLine($httperr); + $this->response + ->setCode($parts['code']) + ->setMessage($parts['message']); + } + + return true; + } + + /** + * Supporting method that executes a request and handles the response. + * + * @param string $url URL to request + * @param array $context Associative array of stream context parameters + * + * @return Phergie_Plugin_Http_Response Object representing the response + * resulting from the request + */ + public function request($url, array $context) + { + $this->response = new Phergie_Plugin_Http_Response; + + $url = (string) $url; + $context = stream_context_create(array('http' => $context)); + + set_error_handler(array($this, 'handleError'), E_WARNING); + $stream = fopen($url, 'r', false, $context); + if ($stream) { + $meta = stream_get_meta_data($stream); + $status = $this->parseStatusLine($meta['wrapper_data'][0]); + $code = $status['code']; + $message = $status['message']; + $headers = array(); + foreach (array_slice($meta['wrapper_data'], 1) as $header) { + list($name, $value) = explode(': ', $header, 2); + $headers[$name] = $value; + } + unset($meta['wrapper_data']); + + $this->response + ->setCode($code) + ->setMessage($message) + ->setHeaders($headers) + ->setMeta($meta); + + $body = stream_get_contents($stream); + $type = $this->response->getHeaders('content-type'); + foreach ($this->handlers as $expr => $handler) { + if (preg_match('#^' . $expr . '$#i', $type)) { + $body = call_user_func($handler, $body); + } + } + + $this->response->setContent($body); + } + restore_error_handler(); + + return $this->response; + } + + /** + * Performs a GET request. + * + * @param string $url URL for the request + * @param array $query Optional associative array of parameters + * constituting the URL query string if $url has none + * @param array $context Optional associative array of additional stream + * context parameters + * + * @return Phergie_Plugin_Http_Response Received response data + */ + public function get($url, array $query = array(), array $context = array()) + { + if (!empty($query)) { + $url .= '?' . http_build_query($query); + } + + $context['method'] = 'GET'; + + return $this->request($url, $context); + } + + /** + * Performs a HEAD request. + * + * @param string $url URL for the request + * @param array $query Optional associative array of parameters + * constituting the URL query string if $url has none + * @param array $context Optional associative array of additional stream + * context parameters + * + * @return Phergie_Plugin_Http_Response Received response data + */ + public function head($url, array $query = array(), array $context = array()) + { + if (!empty($query)) { + $url .= '?' . http_build_query($query); + } + + $context['method'] = 'HEAD'; + + return $this->request($url, $context); + } + + /** + * Performs a POST request. + * + * @param string $url URL for the request + * @param array $query Optional associative array of parameters + * constituting the URL query string if $url has none + * @param array $post Optional associative array of parameters + * constituting the POST request body if it is using the + * traditional URL-encoded format + * @param array $context Optional associative array of additional stream + * context parameters + * + * @return Phergie_Plugin_Http_Response Received response data + */ + public function post($url, array $query = array(), array $post = array(), array $context = array()) + { + if (!empty($params)) { + $url .= '?' . http_build_query($query); + } + + $context['method'] = 'POST'; + + if (!empty($post) + && (!empty($context['header']) + xor stripos($context['header'], 'Content-Type')) + ) { + if (!empty($context['header'])) { + $context['header'] .= "\r\n"; + } else { + $context['header'] = ''; + } + $context['header'] .= + 'Content-Type: application/x-www-form-urlencoded'; + $context['content'] = http_build_query($post); + } + + return $this->request($url, $context); + } +} |