/lib/Mage/HTTP/Client/Socket.php
PHP | 537 lines | 260 code | 63 blank | 214 comment | 32 complexity | 7a889fed729d92eba849d6fdfa32d7d6 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
- <?php
- /**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category Mage
- * @package Mage_Connect
- * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
- */
- /**
- * Class to work with HTTP protocol using sockets
- *
- * @category Mage
- * @package Mage_Connect
- * @author Magento Core Team <core@magentocommerce.com>
- */
- class Mage_HTTP_Client_Socket
- implements Mage_HTTP_IClient
- {
- /**
- * Hostname
- * @var string
- */
- private $_host = 'localhost';
- /**
- * Port
- * @var int
- */
- private $_port = 80;
- /**
- * Stream resource
- * @var object
- */
- private $_sock = null;
-
- /**
- * Request headers
- * @var array
- */
- private $_headers = array();
-
-
- /**
- * Fields for POST method - hash
- * @var array
- */
- private $_postFields = array();
-
- /**
- * Request cookies
- * @var array
- */
- private $_cookies = array();
-
- /**
- * Response headers
- * @var array
- */
- private $_responseHeaders = array();
-
- /**
- * Response body
- * @var string
- */
- private $_responseBody = '';
-
- /**
- * Response status
- * @var int
- */
- private $_responseStatus = 0;
-
-
- /**
- * Request timeout
- * @var int
- */
- private $_timeout = 300;
-
- /**
- * TODO
- * @var int
- */
- private $_redirectCount = 0;
- /**
- * Set request timeout, msec
- *
- * @param int $value
- */
- public function setTimeout($value)
- {
- $this->_timeout = (int) $value;
- }
- /**
- * Constructor
- * @param string $host
- * @param int $port
- */
- public function __construct($host = null, $port = 80)
- {
- if($host) {
- $this->connect($host, (int) $port);
- }
- }
- /**
- * Set connection params
- *
- * @param string $host
- * @param int $port
- */
- public function connect($host, $port = 80)
- {
- $this->_host = $host;
- $this->_port = (int) $port;
- }
-
- /**
- * Disconnect
- */
- public function disconnect()
- {
- @fclose($this->_sock);
- }
- /**
- * Set headers from hash
-
- * @param array $headers
- */
- public function setHeaders($headers)
- {
- $this->_headers = $headers;
- }
-
- /**
- * Add header
- *
- * @param $name name, ex. "Location"
- * @param $value value ex. "http://google.com"
- */
- public function addHeader($name, $value)
- {
- $this->_headers[$name] = $value;
- }
-
- /**
- * Remove specified header
- *
- * @param string $name
- */
- public function removeHeader($name)
- {
- unset($this->_headers[$name]);
- }
- /**
- * Authorization: Basic header
- * Login credentials support
- *
- * @param string $login username
- * @param string $pass password
- */
- public function setCredentials($login, $pass)
- {
- $val= base64_encode( "$login:$pass" );
- $this->addHeader( "Authorization", "Basic $val" );
- }
- /**
- * Add cookie
- *
- * @param string $name
- * @param string $value
- */
- public function addCookie($name, $value)
- {
- $this->_cookies[$name] = $value;
- }
- /**
- * Remove cookie
- *
- * @param string $name
- */
- public function removeCookie($name)
- {
- unset($this->_cookies[$name]);
- }
- /**
- * Set cookies array
- *
- * @param array $cookies
- */
- public function setCookies($cookies)
- {
- $this->_cookies = $cookies;
- }
- /**
- * Clear cookies
- */
- public function removeCookies()
- {
- $this->setCookies(array());
- }
-
- /**
- * Make GET request
- *
- * @param string $uri full uri path
- */
- public function get($uri)
- {
- $this->makeRequest("GET",$this->parseUrl($uri));
- }
- /**
- * Set host, port from full url
- * and return relative url
- *
- * @param string $uri ex. http://google.com/index.php?a=b
- * @return string ex. /index.php?a=b
- */
- protected function parseUrl($uri)
- {
- $parts = parse_url($uri);
- if(!empty($parts['user']) && !empty($parts['pass'])) {
- $this->setCredentials($parts['user'], $parts['pass']);
- }
- if(!empty($parts['port'])) {
- $this->_port = (int) $parts['port'];
- }
-
- if(!empty($parts['host'])) {
- $this->_host = $parts['host'];
- } else {
- throw new InvalidArgumentException("Uri doesn't contain host part");
- }
-
-
- if(!empty($parts['path'])) {
- $requestUri = $parts['path'];
- } else {
- throw new InvalidArgumentException("Uri doesn't contain path part");
- }
- if(!empty($parts['query'])) {
- $requestUri .= "?".$parts['query'];
- }
- return $requestUri;
- }
-
- /**
- * Make POST request
- */
- public function post($uri, $params)
- {
- $this->makeRequest("POST", $this->parseUrl($uri), $params);
- }
- /**
- * Get response headers
- *
- * @return array
- */
- public function getHeaders()
- {
- return $this->_responseHeaders;
- }
-
- /**
- * Get response body
- *
- * @return string
- */
- public function getBody()
- {
- return $this->_responseBody;
- }
- /**
- * Get cookies response hash
- *
- * @return array
- */
- public function getCookies()
- {
- if(empty($this->_responseHeaders['Set-Cookie'])) {
- return array();
- }
- $out = array();
- foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
- $values = explode("; ", $row);
- $c = count($values);
- if(!$c) {
- continue;
- }
- list($key, $val) = explode("=", $values[0]);
- if(is_null($val)) {
- continue;
- }
- $out[trim($key)] = trim($val);
- }
- return $out;
- }
- /**
- * Get cookies array with details
- * (domain, expire time etc)
- * @return array
- */
- public function getCookiesFull()
- {
- if(empty($this->_responseHeaders['Set-Cookie'])) {
- return array();
- }
- $out = array();
- foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
- $values = explode("; ", $row);
- $c = count($values);
- if(!$c) {
- continue;
- }
- list($key, $val) = explode("=", $values[0]);
- if(is_null($val)) {
- continue;
- }
- $out[trim($key)] = array('value'=>trim($val));
- array_shift($values);
- $c--;
- if(!$c) {
- continue;
- }
- for($i = 0; $i<$c; $i++) {
- list($subkey, $val) = explode("=", $values[$i]);
- $out[trim($key)][trim($subkey)] = trim($val);
- }
- }
- return $out;
- }
- /**
- * Process response headers
- */
- protected function processResponseHeaders()
- {
- $crlf = "\r\n";
- $this->_responseHeaders = array();
- while (!feof($this->_sock)) {
- $line = fgets($this->_sock, 1024);
- if($line === $crlf) {
- return;
- }
- $name = $value = '';
- $out = explode(": ", trim($line), 2);
- if(count($out) == 2) {
- $name = $out[0];
- $value = $out[1];
- }
- if(!empty($value)) {
- if($name == "Set-Cookie") {
- if(!isset($this->_responseHeaders[$name])) {
- $this->_responseHeaders[$name] = array();
- }
- $this->_responseHeaders[$name][] = $value;
- } else {
- $this->_responseHeaders[$name] = $value;
- }
- }
- }
- }
- /**
- * Process response body
- */
- protected function processResponseBody()
- {
- $this->_responseBody = '';
- while (!feof($this->_sock)) {
- $this->_responseBody .= @fread($this->_sock, 1024);
- }
- }
- /**
- * Process response
- */
- protected function processResponse()
- {
- $response = '';
- $responseLine = trim(fgets($this->_sock, 1024));
- $line = explode(" ", $responseLine, 3);
- if(count($line) != 3) {
- return $this->doError("Invalid response line returned from server: ".$responseLine);
- }
- $this->_responseStatus = intval($line[1]);
- $this->processResponseHeaders();
- $this->processRedirect();
- $this->processResponseBody();
- }
- /**
- * Process redirect
- */
- protected function processRedirect()
- {
- // TODO: implement redircets support
- }
-
- /**
- * Get response status code
- * @see lib/Mage/HTTP/Mage_HTTP_Client#getStatus()
- */
- public function getStatus()
- {
- return $this->_responseStatus;
- }
- /**
- * Make request
- * @param string $method
- * @param string $uri
- * @param array $params
- * @return null
- */
- protected function makeRequest($method, $uri, $params = array())
- {
- $errno = $errstr = '';
- $this->_sock = @fsockopen($this->_host, $this->_port, $errno, $errstr, $this->_timeout);
- if(!$this->_sock) {
- return $this->doError(sprintf("[errno: %d] %s", $errno, $errstr));
- }
- $crlf = "\r\n";
- $isPost = $method == "POST";
- $appendHeaders = array();
- $paramsStr = false;
- if($isPost && count($params)) {
- $paramsStr = http_build_query($params);
- $appendHeaders['Content-type'] = 'application/x-www-form-urlencoded';
- $appendHeaders['Content-length'] = strlen($paramsStr);
- }
- $out = "{$method} {$uri} HTTP/1.1{$crlf}";
- $out .= $this->headersToString($appendHeaders);
- $out .= $crlf;
- if($paramsStr) {
- $out .= $paramsStr.$crlf;
- }
-
- fwrite($this->_sock, $out);
- $this->processResponse();
- }
-
- /**
- * Throw error excpetion
- * @param $string
- * @throws Exception
- */
- public function doError($string)
- {
- throw new Exception($string);
- }
- /**
- * Convert headers hash to string
- * @param $delimiter
- * @param $append
- * @return string
- */
- protected function headersToString($append = array())
- {
- $headers = array();
- $headers["Host"] = $this->_host;
- $headers['Connection'] = "close";
- $headers = array_merge($headers, $this->_headers, $append);
- $str = array();
- foreach ($headers as $k=>$v) {
- $str []= "$k: $v\r\n";
- }
- return implode($str);
- }
- /**
- * TODO
- */
- public function setOptions($arr)
- {
- // Stub
- }
-
- /**
- * TODO
- */
- public function setOption($name, $value)
- {
- // Stub
- }
- }