?
Path : /home/admin/public_html/old/board/libraries/domit/ |
Current File : /home/admin/public_html/old/board/libraries/domit/php_http_client_generic.php |
<?php /** * PHP HTTP Tools is a library for working with the http protocol * php_http_client_generic represents a basic http client * @package php-http-tools * @version 0.3 * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <johnkarl@nbnet.nb.ca> * @link http://www.engageinteractive.com/php_http_tools/ PHP HTTP Tools Home Page * PHP HTTP Tools are Free Software **/ if (!defined('PHP_HTTP_TOOLS_INCLUDE_PATH')) { define('PHP_HTTP_TOOLS_INCLUDE_PATH', (dirname(__FILE__) . "/")); } /** end-of-line character sequence as defined in HTTP spec */ define ('CRLF', "\r\n"); /** carriage return character */ define ('CR', "\r"); /** line feed character */ define ('LF', "\n"); //http read states for client /** beginning read state */ define('HTTP_READ_STATE_BEGIN', 1); /** state when reading headers */ define('HTTP_READ_STATE_HEADERS', 2); /** state when reading body of message */ define('HTTP_READ_STATE_BODY', 3); require_once(PHP_HTTP_TOOLS_INCLUDE_PATH . 'php_http_exceptions.php'); /** * An HTTP Request class * * @package php-http-tools * @author John Heinstein <johnkarl@nbnet.nb.ca> */ class php_http_request { /** @var object A reference to the headers object */ var $headers = null; /** @var string The requested method, e.g. GET, POST, HEAD */ var $requestMethod = 'POST'; /** @var string The requested path */ var $requestPath = ''; /** @var string The requested protocol */ var $protocol = 'HTTP'; /** @var string The version of the requested protocol */ var $protocolVersion= '1.1'; /** * Returns the headers object * @return object The headers object */ function &getHeaders() { return $this->headers; } //getHeaders /** * Sets the header to the specified value * @param string The header name * @param string The header value * @param boolean True if multiple headers with the same name are allowed */ function setHeader($name, $value, $allowMultipleHeaders = false) { $this->headers->setHeader($name, $value, $allowMultipleHeaders); } //setHeader /** * Default method for setting headers; meant to be overridden in subclasses */ function setHeaders() { //you will want to override this method $this->setHeader('User-Agent', 'PHP-HTTP-Client(Generic)/0.1'); $this->setHeader('Connection', 'Close'); } //setHeaders /** * Sets the request method, e.g., GET * @param string The name of the request method * @return boolean True if the version number is valid */ function setRequestMethod($method) { $method = strtoupper($method); switch ($method) { case 'POST': case 'GET': case 'HEAD': case 'PUT': $this->requestMethod = $method; return true; break; } return false; } //setRequestMethod /** * Sets the request path, e.g., http://www.engageinteractive.com/domit/test.xml * @param string The request path */ function setRequestPath($path) { $this->requestPath = $path; } //setRequestPath /** * Sets the version number of the protocol * @param string The version number * @return boolean True if the version number is valid */ function setProtocolVersion($version) { if (($version == '1.0') || ($version == '1.1')) { $this->protocolVersion = $version; return true; } return false; } //setProtocolVersion /** * Specifies a user name and password for basic authentication * @param string The user name * @param string The password */ function setAuthorization($user, $password) { $encodedChallengeResponse = 'Basic ' . base64_encode($this->user . ':' . $this->password); $this->setHeader('Authorization', $encodedChallengeResponse); } //setAuthorization } //php_http_request class php_http_client_generic extends php_http_request { /** @var object A reference to the connection object */ var $connection; /** @var string True if response headers are to be generated as an object */ var $responseHeadersAsObject = false; /** @var object The http response */ var $response = null; /** @var string A list of event names that can be fired by the client */ var $events = array('onRequest' => null, 'onRead' => null, 'onResponse' => null, 'onResponseHeaders' => null, 'onResponseBody' => null); /** * HTTP Client constructor * @param string The client connection host name, with or without its protocol prefix * @param string The client connection path, not including the host name * @param int The port to establish the client connection on * @param int The timeout value for the client connection */ function php_http_client_generic($host = '', $path = '/', $port = 80, $timeout = 0) { $this->connection = new php_http_connection($host, $path, $port, $timeout); $this->headers = new php_http_headers(); $this->requestPath = $path; $this->response = new php_http_response(); $this->setHeaders(); } //php_http_client_generic /** * Specifies that the response headers array should be generated * @param boolean True if the response headers array should be built */ function generateResponseHeadersAsObject($responseHeadersAsObject) { $this->responseHeadersAsObject = $responseHeadersAsObject; if ($responseHeadersAsObject) { $this->response->headers = new php_http_headers(); } } //generateResponseHeadersAsObject /** * Fires an http event that has been registered * @param string The name of the event, e.g., onRead * @param string The data to be passed to the event */ function fireEvent($target, $data) { if ($this->events[$target] != null) { call_user_func($this->events[$target], $data); } } //fireEvent /** * Sets which http events are to be fired * @param string The http event option to be set * @param string True if the event is to be fired * @param object A reference to a custom handler for the http event data */ function setHTTPEvent($option, $truthVal, $customHandler = null) { if ($customHandler != null) { $handler =& $customHandler; } else { $handler = array(&$this, 'defaultHTTPEventHandler'); } switch($option) { case 'onRequest': case 'onRead': case 'onResponse': case 'onResponseHeaders': case 'onResponseBody': $truthVal ? ($this->events[$option] =& $handler) : ($this->events[$option] = null); break; } } //setHTTPEvent /** * Evaluates whether the specified http event option is active * @param string The http event option to evaluate * @return boolean True if the specified option is active */ function getHTTPEvent($option) { switch($option) { case 'onRequest': case 'onRead': case 'onResponse': case 'onResponseHeaders': case 'onResponseBody': return ($this->events[$option] != null); break; } } //getHTTPEvent /** * The default http event handler; fired if no custom handler has been registered * @param string The event data */ function defaultHTTPEventHandler($data) { $this->printHTML($data); } //defaultHTTPEventHandler /** * Prints the data to the browser as preformatted, htmlentified output * @param string The data to be printed */ function printHTML($html) { print('<pre>' . htmlentities($html) . '</pre>'); } //printHTML /** * Establishes a client connection */ function connect() { if (!$this->headers->headerExists('Host')) { $this->setHeader('Host', $this->connection->host); } return $this->connection->connect(); } //connect /** * Disconnects the current client connection if one exists */ function disconnect() { return $this->connection->disconnect(); } //disconnect /** * Evaluated whether the current client is connected * @return boolean True if a connection exists */ function isConnected() { return $this->connection->isOpen(); } //isConnected /** * Performs an HTTP GET * @param string The target url * @return object An HTTP response object */ function &get($url) { $this->setRequestMethod('GET'); $this->setRequestPath($url); $this->get_custom($url); $this->connect(); $result = $this->send(''); return $result; } //get /** * Handler for customizing the HTTP GET call * @param string The target url */ function get_custom($url) { //do nothing; meant to be overridden } //get_custom /** * Performs an HTTP POST * @param string The posted data * @return object An HTTP response object */ function &post($data) { $this->setRequestMethod('POST'); $this->setHeader('Content-Type', 'text/html'); $this->post_custom($data); $this->connect(); return $this->send($data); } //post /** * Handler for customizing the HTTP POST call * @param string The post data */ function post_custom($data) { //do nothing; meant to be overridden } //post_custom /** * Performs an HTTP HEAD * @param string The target url * @return object An HTTP response object */ function &head($url) { $this->setRequestMethod('HEAD'); $this->head_custom($url); $this->connect(); return $this->send(''); } //head /** * Handler for customizing the HTTP HEAD call * @param string The target url */ function head_custom($url) { //do nothing; meant to be overridden } //head_custom /** * Sends data through the client connection * @param string The message to be sent * @return string The http response */ function send($message) { $conn =& $this->connection; if ($conn->isOpen()) { //build header info $request = $this->requestMethod . ' ' . $this->requestPath . ' ' . $this->protocol . '/' . $this->protocolVersion . CRLF; $request .= $this->headers->toString() . CRLF; $request .= $message; //init variables $response = $headers = $body = ''; $readState = HTTP_READ_STATE_BEGIN; $this->fireEvent('onRequest', $request); //send request $connResource =& $conn->connection; fputs ($connResource, $request); //read response while (!feof($connResource)) { $data = fgets($connResource, 4096); $this->fireEvent('onRead', $data); switch ($readState) { case HTTP_READ_STATE_BEGIN: $this->response->statusLine = $data; $readState = HTTP_READ_STATE_HEADERS; break; case HTTP_READ_STATE_HEADERS: if (trim($data) == '') { //end of headers is signalled by a blank line $readState = HTTP_READ_STATE_BODY; } else { if ($this->responseHeadersAsObject) { $this->response->setUnformattedHeader($data); } else { $this->response->headers .= $data; } } break; case HTTP_READ_STATE_BODY: $this->response->message .= $data; break; } } $this->normalizeResponseIfChunked(); $headerString = is_object($this->response->headers) ? $this->response->headers->toString() : $this->response->headers; $this->fireEvent('onResponseHeaders', $headerString); $this->fireEvent('onResponseBody', $this->response->message); $this->fireEvent('onResponse', $this->response->headers . $this->response->message); return $this->response; } else { HTTPExceptions::raiseException(HTTP_SOCKET_CONNECTION_ERR, ('HTTP Transport Error - Unable to establish connection to host ' . $conn->host)); } } //send /** * Determines if response data is transfer encoding chunked, then decodes */ function normalizeResponseIfChunked() { if (($this->protocolVersion = '1.1') && (!$this->response->isResponseChunkDecoded)) { if ($this->responseHeadersAsObject) { if ($this->response->headers->headerExists('Transfer-Encoding') && ($this->response->headers->getHeader('Transfer-Encoding') == 'chunked')) { $this->response->message = $this->decodeChunkedData($this->response->getResponse()); $this->response->isResponseChunkDecoded = true; } } else { if ((strpos($this->response->headers, 'Transfer-Encoding') !== false) && (strpos($this->response->headers, 'chunked') !== false)){ $this->response->message = $this->decodeChunkedData($this->response->getResponse()); $this->response->isResponseChunkDecoded = true; } } } } //normalizeResponseIfChunked /** * Decodes data if transfer encoding chunked * @param string The encoded data * @return string The decoded data */ function decodeChunkedData($data) { $chunkStart = $chunkEnd = strpos($data, CRLF) + 2; $chunkLengthInHex = substr($data, 0, $chunkEnd); $chunkLength = hexdec(trim($chunkLengthInHex)); $decodedData = ''; while ($chunkLength > 0) { $chunkEnd = strpos($data, CRLF, ($chunkStart + $chunkLength)); if (!$chunkEnd) { //if the trailing CRLF is missing, return all the remaining data $decodedData .= substr($data, $chunkStart); break; } $decodedData .= substr($data, $chunkStart, ($chunkEnd - $chunkStart)); $chunkStart = $chunkEnd + 2; $chunkEnd = strpos($data, CRLF, $chunkStart) + 2; if (!$chunkEnd) break; $chunkLengthInHex = substr($data, $chunkStart, ($chunkEnd - $chunkStart)); $chunkLength = hexdec(trim($chunkLengthInHex)); $chunkStart = $chunkEnd; } return $decodedData; } //decodeChunkedData } //php_http_client_generic /** * An HTTP Connection class * * @package php-http-tools * @author John Heinstein <johnkarl@nbnet.nb.ca> */ class php_http_connection { /** @var object A reference to the current connection */ var $connection = null; /** @var string The host of the connection */ var $host; /** @var string The path of the connection */ var $path; /** @var int The port of the connection */ var $port; /** @var int The timeout value for the connection */ var $timeout; /** @var int The error number of the connection */ var $errorNumber = 0; /** @var string The error string of the connection */ var $errorString = ''; /** * HTTP Connection constructor * @param string The connection host name, with or without its protocol prefix * @param string The connection path, not including the host name * @param int The port to establish the client connection on * @param int The timeout value for the client connection */ function php_http_connection($host = '', $path = '/', $port = 80, $timeout = 0) { $this->host = $this->formatHost($host); $this->path = $this->formatPath($path); $this->port = $port; $this->timeout = $timeout; } //php_http_connection /** * Formats a host string by stripping off the http:// prefix * @param string The host name * @return string The formatted host name */ function formatHost($hostString) { $hasProtocol = (substr(strtoupper($hostString), 0, 7) == 'HTTP://'); if ($hasProtocol) { $hostString = substr($hostString, 7); } return $hostString; } //formatHost /** * Formats a path string * @param string The path * @return string The formatted path */ function formatPath($pathString) { if (($pathString == '') || ($pathString == null)) { $pathString = '/'; } return $pathString; } //formatPath /** * Establishes a socket connection * @return boolean True if the connection was successful */ function connect() { if ($this->timeout == 0) { $this->connection = @fsockopen($this->host, $this->port, $errorNumber, $errorString); } else { $this->connection = @fsockopen($this->host, $this->port, $errorNumber, $errorString, $this->timeout); } $this->errorNumber = $errorNumber; $this->errorString = $errorString; return is_resource($this->connection); } //connect /** * Determines whether the connection is still open * @return boolean True if the connection is still open */ function isOpen() { return (is_resource($this->connection) && (!feof($this->connection))); } //isOpen /** * Disconnects the current connection * @return boolean True if the connection has been disconnected */ function disconnect() { fclose($this->connection); $this->connection = null; return true; } //disconnect } //php_http_connection /** * An HTTP Headers class * * @package php-http-tools * @author John Heinstein <johnkarl@nbnet.nb.ca> */ class php_http_headers { /** @var object An array of headers */ var $headers; /** * HTTP Headers constructor */ function php_http_headers() { $this->headers = array(); } //php_http_headers /** * Returns the specified header value * @param string The header name * @return mixed The header value, or an array of header values */ function &getHeader($name) { if ($this->headerExists($name)) { return $this->headers[$name]; } return false; } //getHeader /** * Sets the named header to the specified value * @param string The header name * @param string The header value * @param boolean True if multiple headers with the same name are allowed */ function setHeader($name, $value, $allowMultipleHeaders = false) { if ($allowMultipleHeaders) { if (isset($this->headers[$name])) { if (is_array($this->headers[$name])) { $this->headers[$name][count($this->headers)] = $value; } else { $tempVal = $this->headers[$name]; $this->headers[$name] = array($tempVal, $value); } } else { $this->headers[$name] = array(); $this->headers[$name][0] = $value; } } else { $this->headers[$name] = $value; } } //setHeader /** * Determines whether the specified header exists * @param string The header name * @return boolean True if the specified header exists */ function headerExists($name) { return isset($this->headers[$name]); } //headerExists /** * Removes the specified header * @param string The header name * @return boolean True if the specified header has been removed */ function removeHeader($name) { if ($this->headerExists($name)) { unset($this->headers[$name]); return true; } return false; } //removeHeader /** * Returns a reference to the headers array * @return array The headers array */ function getHeaders() { return $this->headers; } //getHeaders /** * Returns a list of existing headers names * @return array A list of existing header names */ function getHeaderList() { return array_keys($this->headers); } //getHeaderList /** * Returns a string representation of the headers array * @return string A string representation of the headers array */ function toString() { $retString = ''; foreach ($this->headers as $key => $value) { if (is_array($value)) { foreach ($value as $key2 => $value2) { $retString .= $key . ': ' . $value2 . CRLF; } } else { $retString .= $key . ': ' . $value . CRLF; } } return $retString; } //toString } //php_http_headers /** * An HTTP Response class * * @package php-http-tools * @author John Heinstein <johnkarl@nbnet.nb.ca> */ class php_http_response { /** @var string Response number */ var $statusLine = ''; /** @var mixed Response headers, either as object or string */ var $headers = ''; /** @var string Response message */ var $message = ''; /** @var boolean True if the chunked transfer-encoding of the response has been decoded */ var $isResponseChunkDecoded = false; /** * Returns a reference to the headers array * @return array The headers array */ function getResponse() { return $this->message; } //getResponse /** * Returns the response status line * @return string The response status line */ function getStatusLine() { return $this->statusLine; } //getStatusLine /** * Returns the response status code * @return int The response status code */ function getStatusCode() { $statusArray = split(' ', $this->statusLine); if (count($statusArray > 1)) { return intval($statusArray[1], 10); } return -1; } //getStatusCode /** * Returns a reference to the headers array * @return array The headers array */ function &getHeaders() { return $this->headers; } //getHeaders /** * Converts a header string into a key value pair and sets header */ function setUnformattedHeader($headerString) { $colonIndex = strpos($headerString, ':'); if ($colonIndex !== false) { $key = trim(substr($headerString, 0, $colonIndex)); $value = trim(substr($headerString, ($colonIndex + 1))); $this->headers->setHeader($key, $value, true); } } //setUnformattedHeader } //php_http_response ?>