comparison cake/libs/cake_socket.php @ 0:261e66bd5a0c

hg init
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Sun, 24 Jul 2011 21:08:31 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:261e66bd5a0c
1 <?php
2 /**
3 * Cake Socket connection class.
4 *
5 * PHP versions 4 and 5
6 *
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8 * Copyright 2005-2010, 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-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
14 * @link http://cakephp.org CakePHP(tm) Project
15 * @package cake
16 * @subpackage cake.cake.libs
17 * @since CakePHP(tm) v 1.2.0
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
19 */
20 App::import('Core', 'Validation');
21
22 /**
23 * Cake network socket connection class.
24 *
25 * Core base class for network communication.
26 *
27 * @package cake
28 * @subpackage cake.cake.libs
29 */
30 class CakeSocket extends Object {
31
32 /**
33 * Object description
34 *
35 * @var string
36 * @access public
37 */
38 var $description = 'Remote DataSource Network Socket Interface';
39
40 /**
41 * Base configuration settings for the socket connection
42 *
43 * @var array
44 * @access protected
45 */
46 var $_baseConfig = array(
47 'persistent' => false,
48 'host' => 'localhost',
49 'protocol' => 'tcp',
50 'port' => 80,
51 'timeout' => 30
52 );
53
54 /**
55 * Configuration settings for the socket connection
56 *
57 * @var array
58 * @access public
59 */
60 var $config = array();
61
62 /**
63 * Reference to socket connection resource
64 *
65 * @var resource
66 * @access public
67 */
68 var $connection = null;
69
70 /**
71 * This boolean contains the current state of the CakeSocket class
72 *
73 * @var boolean
74 * @access public
75 */
76 var $connected = false;
77
78 /**
79 * This variable contains an array with the last error number (num) and string (str)
80 *
81 * @var array
82 * @access public
83 */
84 var $lastError = array();
85
86 /**
87 * Constructor.
88 *
89 * @param array $config Socket configuration, which will be merged with the base configuration
90 * @see CakeSocket::$_baseConfig
91 */
92 function __construct($config = array()) {
93 parent::__construct();
94
95 $this->config = array_merge($this->_baseConfig, $config);
96 if (!is_numeric($this->config['protocol'])) {
97 $this->config['protocol'] = getprotobyname($this->config['protocol']);
98 }
99 }
100
101 /**
102 * Connect the socket to the given host and port.
103 *
104 * @return boolean Success
105 * @access public
106 */
107 function connect() {
108 if ($this->connection != null) {
109 $this->disconnect();
110 }
111
112 $scheme = null;
113 if (isset($this->config['request']) && $this->config['request']['uri']['scheme'] == 'https') {
114 $scheme = 'ssl://';
115 }
116
117 if ($this->config['persistent'] == true) {
118 $tmp = null;
119 $this->connection = @pfsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
120 } else {
121 $this->connection = @fsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
122 }
123
124 if (!empty($errNum) || !empty($errStr)) {
125 $this->setLastError($errNum, $errStr);
126 }
127
128 $this->connected = is_resource($this->connection);
129 if ($this->connected) {
130 stream_set_timeout($this->connection, $this->config['timeout']);
131 }
132 return $this->connected;
133 }
134
135 /**
136 * Get the host name of the current connection.
137 *
138 * @return string Host name
139 * @access public
140 */
141 function host() {
142 if (Validation::ip($this->config['host'])) {
143 return gethostbyaddr($this->config['host']);
144 } else {
145 return gethostbyaddr($this->address());
146 }
147 }
148
149 /**
150 * Get the IP address of the current connection.
151 *
152 * @return string IP address
153 * @access public
154 */
155 function address() {
156 if (Validation::ip($this->config['host'])) {
157 return $this->config['host'];
158 } else {
159 return gethostbyname($this->config['host']);
160 }
161 }
162
163 /**
164 * Get all IP addresses associated with the current connection.
165 *
166 * @return array IP addresses
167 * @access public
168 */
169 function addresses() {
170 if (Validation::ip($this->config['host'])) {
171 return array($this->config['host']);
172 } else {
173 return gethostbynamel($this->config['host']);
174 }
175 }
176
177 /**
178 * Get the last error as a string.
179 *
180 * @return string Last error
181 * @access public
182 */
183 function lastError() {
184 if (!empty($this->lastError)) {
185 return $this->lastError['num'] . ': ' . $this->lastError['str'];
186 } else {
187 return null;
188 }
189 }
190
191 /**
192 * Set the last error.
193 *
194 * @param integer $errNum Error code
195 * @param string $errStr Error string
196 * @access public
197 */
198 function setLastError($errNum, $errStr) {
199 $this->lastError = array('num' => $errNum, 'str' => $errStr);
200 }
201
202 /**
203 * Write data to the socket.
204 *
205 * @param string $data The data to write to the socket
206 * @return boolean Success
207 * @access public
208 */
209 function write($data) {
210 if (!$this->connected) {
211 if (!$this->connect()) {
212 return false;
213 }
214 }
215 $totalBytes = strlen($data);
216 for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
217 $rv = fwrite($this->connection, substr($data, $written));
218 if ($rv === false || $rv === 0) {
219 return $written;
220 }
221 }
222 return $written;
223 }
224
225 /**
226 * Read data from the socket. Returns false if no data is available or no connection could be
227 * established.
228 *
229 * @param integer $length Optional buffer length to read; defaults to 1024
230 * @return mixed Socket data
231 * @access public
232 */
233 function read($length = 1024) {
234 if (!$this->connected) {
235 if (!$this->connect()) {
236 return false;
237 }
238 }
239
240 if (!feof($this->connection)) {
241 $buffer = fread($this->connection, $length);
242 $info = stream_get_meta_data($this->connection);
243 if ($info['timed_out']) {
244 $this->setLastError(E_WARNING, __('Connection timed out', true));
245 return false;
246 }
247 return $buffer;
248 } else {
249 return false;
250 }
251 }
252
253 /**
254 * Abort socket operation.
255 *
256 * @return boolean Success
257 * @access public
258 */
259 function abort() {
260 }
261
262 /**
263 * Disconnect the socket from the current connection.
264 *
265 * @return boolean Success
266 * @access public
267 */
268 function disconnect() {
269 if (!is_resource($this->connection)) {
270 $this->connected = false;
271 return true;
272 }
273 $this->connected = !fclose($this->connection);
274
275 if (!$this->connected) {
276 $this->connection = null;
277 }
278 return !$this->connected;
279 }
280
281 /**
282 * Destructor, used to disconnect from current connection.
283 *
284 * @access private
285 */
286 function __destruct() {
287 $this->disconnect();
288 }
289
290 /**
291 * Resets the state of this Socket instance to it's initial state (before Object::__construct got executed)
292 *
293 * @return boolean True on success
294 * @access public
295 */
296 function reset($state = null) {
297 if (empty($state)) {
298 static $initalState = array();
299 if (empty($initalState)) {
300 $initalState = get_class_vars(__CLASS__);
301 }
302 $state = $initalState;
303 }
304
305 foreach ($state as $property => $value) {
306 $this->{$property} = $value;
307 }
308 return true;
309 }
310 }