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