1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
19:
20: App::uses('Validation', 'Utility');
21:
22: 23: 24: 25: 26: 27: 28:
29: class CakeSocket {
30:
31: 32: 33: 34: 35:
36: public $description = 'Remote DataSource Network Socket Interface';
37:
38: 39: 40: 41: 42:
43: protected $_baseConfig = array(
44: 'persistent' => false,
45: 'host' => 'localhost',
46: 'protocol' => 'tcp',
47: 'port' => 80,
48: 'timeout' => 30
49: );
50:
51: 52: 53: 54: 55:
56: public $config = array();
57:
58: 59: 60: 61: 62:
63: public $connection = null;
64:
65: 66: 67: 68: 69:
70: public $connected = false;
71:
72: 73: 74: 75: 76:
77: public $lastError = array();
78:
79: 80: 81: 82: 83: 84:
85: public function __construct($config = array()) {
86: $this->config = array_merge($this->_baseConfig, $config);
87: if (!is_numeric($this->config['protocol'])) {
88: $this->config['protocol'] = getprotobyname($this->config['protocol']);
89: }
90: }
91:
92: 93: 94: 95: 96: 97:
98: public function connect() {
99: if ($this->connection != null) {
100: $this->disconnect();
101: }
102:
103: $scheme = null;
104: if (isset($this->config['request']) && $this->config['request']['uri']['scheme'] == 'https') {
105: $scheme = 'ssl://';
106: }
107:
108: if ($this->config['persistent'] == true) {
109: $this->connection = @pfsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
110: } else {
111: $this->connection = @fsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
112: }
113:
114: if (!empty($errNum) || !empty($errStr)) {
115: $this->setLastError($errNum, $errStr);
116: throw new SocketException($errStr, $errNum);
117: }
118:
119: $this->connected = is_resource($this->connection);
120: if ($this->connected) {
121: stream_set_timeout($this->connection, $this->config['timeout']);
122: }
123: return $this->connected;
124: }
125:
126: 127: 128: 129: 130:
131: public function host() {
132: if (Validation::ip($this->config['host'])) {
133: return gethostbyaddr($this->config['host']);
134: }
135: return gethostbyaddr($this->address());
136: }
137:
138: 139: 140: 141: 142:
143: public function address() {
144: if (Validation::ip($this->config['host'])) {
145: return $this->config['host'];
146: }
147: return gethostbyname($this->config['host']);
148: }
149:
150: 151: 152: 153: 154:
155: public function addresses() {
156: if (Validation::ip($this->config['host'])) {
157: return array($this->config['host']);
158: }
159: return gethostbynamel($this->config['host']);
160: }
161:
162: 163: 164: 165: 166:
167: public function lastError() {
168: if (!empty($this->lastError)) {
169: return $this->lastError['num'] . ': ' . $this->lastError['str'];
170: }
171: return null;
172: }
173:
174: 175: 176: 177: 178: 179: 180:
181: public function setLastError($errNum, $errStr) {
182: $this->lastError = array('num' => $errNum, 'str' => $errStr);
183: }
184:
185: 186: 187: 188: 189: 190:
191: public function write($data) {
192: if (!$this->connected) {
193: if (!$this->connect()) {
194: return false;
195: }
196: }
197: $totalBytes = strlen($data);
198: for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
199: $rv = fwrite($this->connection, substr($data, $written));
200: if ($rv === false || $rv === 0) {
201: return $written;
202: }
203: }
204: return $written;
205: }
206:
207: 208: 209: 210: 211: 212: 213:
214: public function read($length = 1024) {
215: if (!$this->connected) {
216: if (!$this->connect()) {
217: return false;
218: }
219: }
220:
221: if (!feof($this->connection)) {
222: $buffer = fread($this->connection, $length);
223: $info = stream_get_meta_data($this->connection);
224: if ($info['timed_out']) {
225: $this->setLastError(E_WARNING, __d('cake_dev', 'Connection timed out'));
226: return false;
227: }
228: return $buffer;
229: }
230: return false;
231: }
232:
233: 234: 235: 236: 237:
238: public function disconnect() {
239: if (!is_resource($this->connection)) {
240: $this->connected = false;
241: return true;
242: }
243: $this->connected = !fclose($this->connection);
244:
245: if (!$this->connected) {
246: $this->connection = null;
247: }
248: return !$this->connected;
249: }
250:
251: 252: 253: 254:
255: public function __destruct() {
256: $this->disconnect();
257: }
258:
259: 260: 261: 262: 263: 264:
265: public function reset($state = null) {
266: if (empty($state)) {
267: static $initalState = array();
268: if (empty($initalState)) {
269: $initalState = get_class_vars(__CLASS__);
270: }
271: $state = $initalState;
272: }
273:
274: foreach ($state as $property => $value) {
275: $this->{$property} = $value;
276: }
277: return true;
278: }
279: }
280: