hostname = $hostname; $this->port = $port; /* Set timeout */ if (is_int($timeout)) { $this->timeout = $timeout; } /* Open socket to server */ $this->open(); return ($this->socketHandler) ? TRUE : FALSE; } /** * Class desctructor. * * @param void * @return void */ public function __destruct() { $this->close(); } /** * Open socket to server. * * @param void * @return void */ protected function open() { $errstr = ""; $errno = ""; $context = stream_context_create(); stream_context_set_option($context, "ssl", "allow_self_signed", true); stream_context_set_option($context, "ssl", "verify_peer", false); stream_context_set_option($context, "ssl", "verify_peer_name", false); $this->socketHandler = @stream_socket_client($this->cipher . $this->hostname . ':' . $this->port, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $context); $this->errorCode = $errno; $this->errorMessage = $errstr; } /** * Close socket to server. * * @param void * @return void */ protected function close() { @fclose($this->socketHandler); unset($this->socketHandler); } /** * Send data to socket. * * @see class/KerioApiSocketInterface::send() * @param string Data to socket * @return string Data from socket * @throws KerioApiException */ public function send($data) { if ($this->checkConnection()) { @fwrite($this->socketHandler, $data); return $this->read(); } else { throw new KerioApiException(sprintf("Cannot connect to %s using port %d.", $this->hostname, $this->port)); } } /** * Read data from socket. * * @param void * @return string HTTP data from socket * @throws KerioApiExceptions */ protected function read() { if ($this->socketHandler) { $response = ''; while (FALSE === feof($this->socketHandler)) { $response .= fgets($this->socketHandler, self::BUFFER_SIZE); } list($this->headers, $this->body) = explode("\r\n\r\n", $response); if (FALSE !== strpos(strtolower($this->headers), 'transfer-encoding: chunked')) { $this->unchunkHttp(); } return $response; } else { throw new KerioApiException('Cannot read data from server, connection timeout.'); } } /** * Unchunk HTTP/1.1 body. * * @param void * @return void */ private function unchunkHttp() { $body = $this->body; for ($new = ''; !empty($body); $str = trim($body)) { $pos = strpos($body, "\r\n"); $len = hexdec(substr($body, 0, $pos)); $new .= substr($body, $pos + 2, $len); $body = substr($body, $pos + 2 + $len); } $this->body = $new; } /** * Set connection encryption to ssl:// * * @param boolen True if ssl:// is used * @return void */ public function setEncryption($boolean) { $this->cipher = ($boolean) ? 'ssl://' : ''; } /** * Check connection to server. * * @param void * @return boolean True on success */ public final function checkConnection() { if ($this->checkHost()) { $socket = @fsockopen($this->hostname, $this->port, $errno, $errstr, $this->timeout); $this->errorCode = $errno; $this->errorMessage = $errstr; return ($socket) ? TRUE : FALSE; } else { return FALSE; } } /** * Check if DNS host is valid. * * @param void * @return boolean True on success */ public final function checkHost() { return gethostbyname($this->hostname) ? TRUE : FALSE; } /** * Get headers. * * @param void * @return string */ public final function getHeaders() { return $this->headers; } /** * Get body. * * @param void * @return string */ public final function getBody() { return $this->body; } /** * Get socker error message. * * @param void * @return string */ public final function getErrorMessage() { return $this->errorMessage; } /** * Get socket error code. * * @param void * @return integer */ public final function getErrorCode() { return $this->errorCode; } }