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:
109: if ($this->config['persistent'] == true) {
110: $this->connection = @pfsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
111: } else {
112: $this->connection = @fsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
113: }
114:
115:
116: if (!empty($errNum) || !empty($errStr)) {
117: $this->setLastError($errNum, $errStr);
118: throw new SocketException($errStr, $errNum);
119: }
120:
121: $this->connected = is_resource($this->connection);
122: if ($this->connected) {
123: stream_set_timeout($this->connection, $this->config['timeout']);
124: }
125: return $this->connected;
126: }
127:
128: 129: 130: 131: 132:
133: public function host() {
134: if (Validation::ip($this->config['host'])) {
135: return gethostbyaddr($this->config['host']);
136: }
137: return gethostbyaddr($this->address());
138: }
139:
140: 141: 142: 143: 144:
145: public function address() {
146: if (Validation::ip($this->config['host'])) {
147: return $this->config['host'];
148: }
149: return gethostbyname($this->config['host']);
150: }
151:
152: 153: 154: 155: 156:
157: public function addresses() {
158: if (Validation::ip($this->config['host'])) {
159: return array($this->config['host']);
160: }
161: return gethostbynamel($this->config['host']);
162: }
163:
164: 165: 166: 167: 168:
169: public function lastError() {
170: if (!empty($this->lastError)) {
171: return $this->lastError['num'] . ': ' . $this->lastError['str'];
172: }
173: return null;
174: }
175:
176: 177: 178: 179: 180: 181: 182:
183: public function setLastError($errNum, $errStr) {
184: $this->lastError = array('num' => $errNum, 'str' => $errStr);
185: }
186:
187: 188: 189: 190: 191: 192:
193: public function write($data) {
194: if (!$this->connected) {
195: if (!$this->connect()) {
196: return false;
197: }
198: }
199: $totalBytes = strlen($data);
200: for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
201: $rv = fwrite($this->connection, substr($data, $written));
202: if ($rv === false || $rv === 0) {
203: return $written;
204: }
205: }
206: return $written;
207: }
208:
209: 210: 211: 212: 213: 214: 215:
216: public function read($length = 1024) {
217: if (!$this->connected) {
218: if (!$this->connect()) {
219: return false;
220: }
221: }
222:
223: if (!feof($this->connection)) {
224: $buffer = fread($this->connection, $length);
225: $info = stream_get_meta_data($this->connection);
226: if ($info['timed_out']) {
227: $this->setLastError(E_WARNING, __d('cake_dev', 'Connection timed out'));
228: return false;
229: }
230: return $buffer;
231: }
232: return false;
233: }
234:
235: 236: 237: 238: 239:
240: public function disconnect() {
241: if (!is_resource($this->connection)) {
242: $this->connected = false;
243: return true;
244: }
245: $this->connected = !fclose($this->connection);
246:
247: if (!$this->connected) {
248: $this->connection = null;
249: }
250: return !$this->connected;
251: }
252:
253: 254: 255: 256:
257: public function __destruct() {
258: $this->disconnect();
259: }
260:
261: 262: 263: 264: 265: 266:
267: public function reset($state = null) {
268: if (empty($state)) {
269: static $initalState = array();
270: if (empty($initalState)) {
271: $initalState = get_class_vars(__CLASS__);
272: }
273: $state = $initalState;
274: }
275:
276: foreach ($state as $property => $value) {
277: $this->{$property} = $value;
278: }
279: return true;
280: }
281:
282: }
283: