PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Cake/Network/CakeSocket.php

https://bitbucket.org/udeshika/fake_twitter
PHP | 279 lines | 131 code | 27 blank | 121 comment | 29 complexity | f85c3119ed9c2c65fc806f234234c0b6 MD5 | raw file
  1. <?php
  2. /**
  3. * Cake Socket connection class.
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @package Cake.Network
  16. * @since CakePHP(tm) v 1.2.0
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('Validation', 'Utility');
  20. /**
  21. * Cake network socket connection class.
  22. *
  23. * Core base class for network communication.
  24. *
  25. * @package Cake.Network
  26. */
  27. class CakeSocket {
  28. /**
  29. * Object description
  30. *
  31. * @var string
  32. */
  33. public $description = 'Remote DataSource Network Socket Interface';
  34. /**
  35. * Base configuration settings for the socket connection
  36. *
  37. * @var array
  38. */
  39. protected $_baseConfig = array(
  40. 'persistent' => false,
  41. 'host' => 'localhost',
  42. 'protocol' => 'tcp',
  43. 'port' => 80,
  44. 'timeout' => 30
  45. );
  46. /**
  47. * Configuration settings for the socket connection
  48. *
  49. * @var array
  50. */
  51. public $config = array();
  52. /**
  53. * Reference to socket connection resource
  54. *
  55. * @var resource
  56. */
  57. public $connection = null;
  58. /**
  59. * This boolean contains the current state of the CakeSocket class
  60. *
  61. * @var boolean
  62. */
  63. public $connected = false;
  64. /**
  65. * This variable contains an array with the last error number (num) and string (str)
  66. *
  67. * @var array
  68. */
  69. public $lastError = array();
  70. /**
  71. * Constructor.
  72. *
  73. * @param array $config Socket configuration, which will be merged with the base configuration
  74. * @see CakeSocket::$_baseConfig
  75. */
  76. public function __construct($config = array()) {
  77. $this->config = array_merge($this->_baseConfig, $config);
  78. if (!is_numeric($this->config['protocol'])) {
  79. $this->config['protocol'] = getprotobyname($this->config['protocol']);
  80. }
  81. }
  82. /**
  83. * Connect the socket to the given host and port.
  84. *
  85. * @return boolean Success
  86. * @throws SocketException
  87. */
  88. public function connect() {
  89. if ($this->connection != null) {
  90. $this->disconnect();
  91. }
  92. $scheme = null;
  93. if (isset($this->config['request']) && $this->config['request']['uri']['scheme'] == 'https') {
  94. $scheme = 'ssl://';
  95. }
  96. if ($this->config['persistent'] == true) {
  97. $this->connection = @pfsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
  98. } else {
  99. $this->connection = @fsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
  100. }
  101. if (!empty($errNum) || !empty($errStr)) {
  102. $this->setLastError($errNum, $errStr);
  103. throw new SocketException($errStr, $errNum);
  104. }
  105. $this->connected = is_resource($this->connection);
  106. if ($this->connected) {
  107. stream_set_timeout($this->connection, $this->config['timeout']);
  108. }
  109. return $this->connected;
  110. }
  111. /**
  112. * Get the host name of the current connection.
  113. *
  114. * @return string Host name
  115. */
  116. public function host() {
  117. if (Validation::ip($this->config['host'])) {
  118. return gethostbyaddr($this->config['host']);
  119. }
  120. return gethostbyaddr($this->address());
  121. }
  122. /**
  123. * Get the IP address of the current connection.
  124. *
  125. * @return string IP address
  126. */
  127. public function address() {
  128. if (Validation::ip($this->config['host'])) {
  129. return $this->config['host'];
  130. }
  131. return gethostbyname($this->config['host']);
  132. }
  133. /**
  134. * Get all IP addresses associated with the current connection.
  135. *
  136. * @return array IP addresses
  137. */
  138. public function addresses() {
  139. if (Validation::ip($this->config['host'])) {
  140. return array($this->config['host']);
  141. }
  142. return gethostbynamel($this->config['host']);
  143. }
  144. /**
  145. * Get the last error as a string.
  146. *
  147. * @return string Last error
  148. */
  149. public function lastError() {
  150. if (!empty($this->lastError)) {
  151. return $this->lastError['num'] . ': ' . $this->lastError['str'];
  152. }
  153. return null;
  154. }
  155. /**
  156. * Set the last error.
  157. *
  158. * @param integer $errNum Error code
  159. * @param string $errStr Error string
  160. * @return void
  161. */
  162. public function setLastError($errNum, $errStr) {
  163. $this->lastError = array('num' => $errNum, 'str' => $errStr);
  164. }
  165. /**
  166. * Write data to the socket.
  167. *
  168. * @param string $data The data to write to the socket
  169. * @return boolean Success
  170. */
  171. public function write($data) {
  172. if (!$this->connected) {
  173. if (!$this->connect()) {
  174. return false;
  175. }
  176. }
  177. $totalBytes = strlen($data);
  178. for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
  179. $rv = fwrite($this->connection, substr($data, $written));
  180. if ($rv === false || $rv === 0) {
  181. return $written;
  182. }
  183. }
  184. return $written;
  185. }
  186. /**
  187. * Read data from the socket. Returns false if no data is available or no connection could be
  188. * established.
  189. *
  190. * @param integer $length Optional buffer length to read; defaults to 1024
  191. * @return mixed Socket data
  192. */
  193. public function read($length = 1024) {
  194. if (!$this->connected) {
  195. if (!$this->connect()) {
  196. return false;
  197. }
  198. }
  199. if (!feof($this->connection)) {
  200. $buffer = fread($this->connection, $length);
  201. $info = stream_get_meta_data($this->connection);
  202. if ($info['timed_out']) {
  203. $this->setLastError(E_WARNING, __d('cake_dev', 'Connection timed out'));
  204. return false;
  205. }
  206. return $buffer;
  207. }
  208. return false;
  209. }
  210. /**
  211. * Disconnect the socket from the current connection.
  212. *
  213. * @return boolean Success
  214. */
  215. public function disconnect() {
  216. if (!is_resource($this->connection)) {
  217. $this->connected = false;
  218. return true;
  219. }
  220. $this->connected = !fclose($this->connection);
  221. if (!$this->connected) {
  222. $this->connection = null;
  223. }
  224. return !$this->connected;
  225. }
  226. /**
  227. * Destructor, used to disconnect from current connection.
  228. *
  229. */
  230. public function __destruct() {
  231. $this->disconnect();
  232. }
  233. /**
  234. * Resets the state of this Socket instance to it's initial state (before Object::__construct got executed)
  235. *
  236. * @param array $state Array with key and values to reset
  237. * @return boolean True on success
  238. */
  239. public function reset($state = null) {
  240. if (empty($state)) {
  241. static $initalState = array();
  242. if (empty($initalState)) {
  243. $initalState = get_class_vars(__CLASS__);
  244. }
  245. $state = $initalState;
  246. }
  247. foreach ($state as $property => $value) {
  248. $this->{$property} = $value;
  249. }
  250. return true;
  251. }
  252. }