[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/horde/framework/Horde/Socket/ -> Client.php (source)

   1  <?php
   2  
   3  namespace Horde\Socket;
   4  
   5  /**
   6   * Copyright 2013-2014 Horde LLC (http://www.horde.org/)
   7   *
   8   * See the enclosed file COPYING for license information (LGPL). If you
   9   * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  10   *
  11   * @category  Horde
  12   * @copyright 2013-2014 Horde LLC
  13   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  14   * @package   Socket_Client
  15   */
  16  
  17  /**
  18   * Utility interface for establishing a stream socket client.
  19   *
  20   * @author    Michael Slusarz <slusarz@horde.org>
  21   * @category  Horde
  22   * @copyright 2013-2014 Horde LLC
  23   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  24   * @package   Socket_Client
  25   *
  26   * @property-read boolean $connected  Is there an active connection?
  27   * @property-read boolean $secure  Is the active connection secure?
  28   */
  29  class Client
  30  {
  31      /**
  32       * Is there an active connection?
  33       *
  34       * @var boolean
  35       */
  36      protected $_connected = false;
  37  
  38      /**
  39       * Configuration parameters.
  40       *
  41       * @var array
  42       */
  43      protected $_params;
  44  
  45      /**
  46       * Is the connection secure?
  47       *
  48       * @var boolean
  49       */
  50      protected $_secure = false;
  51  
  52      /**
  53       * Constructor.
  54       *
  55       * @param string $host      Hostname of remote server.
  56       * @param integer $port     Port number of remote server.
  57       * @param integer $timeout  Connection timeout (in seconds).
  58       * @param mixed $secure     Security layer requested. One of:
  59       * <pre>
  60       *   - false (No encryption) [DEFAULT]
  61       *   - 'ssl' (Auto-detect SSL version)
  62       *   - 'sslv2' (Force SSL version 3)
  63       *   - 'sslv3' (Force SSL version 2)
  64       *   - 'tls' (TLS; started via protocol-level negotation over unencrypted
  65       *     channel)
  66       *   - 'tlsv1' (TLS version 1.x connection) (@since 1.1.0)
  67       *   - true (TLS if available/necessary)
  68       * </pre>
  69       * @param array $params     Additional options.
  70       *
  71       * @throws Horde\Socket\Client\Exception
  72       */
  73      public function __construct(
  74          $host, $port, $timeout = 30, $secure = false, array $params = array()
  75      )
  76      {
  77          if ($secure && !extension_loaded('openssl')) {
  78              if ($secure !== true) {
  79                  throw new \InvalidArgumentException('Secure connections require the PHP openssl extension.');
  80              }
  81              $secure = false;
  82          }
  83  
  84          $this->_params = $params;
  85  
  86          $this->_connect($host, $port, $timeout, $secure);
  87      }
  88  
  89      /**
  90       */
  91      public function __get($name)
  92      {
  93          switch ($name) {
  94          case 'connected':
  95              return $this->_connected;
  96  
  97          case 'secure':
  98              return $this->_secure;
  99          }
 100      }
 101  
 102      /**
 103       * This object can not be cloned.
 104       */
 105      public function __clone()
 106      {
 107          throw new \LogicException('Object cannot be cloned.');
 108      }
 109  
 110      /**
 111       * This object can not be serialized.
 112       */
 113      public function __sleep()
 114      {
 115          throw new \LogicException('Object can not be serialized.');
 116      }
 117  
 118      /**
 119       * Start a TLS connection.
 120       *
 121       * @return boolean  Whether TLS was successfully started.
 122       */
 123      public function startTls()
 124      {
 125          if ($this->connected &&
 126              !$this->secure &&
 127              (@stream_socket_enable_crypto($this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT) === true)) {
 128              $this->_secure = true;
 129              return true;
 130          }
 131  
 132          return false;
 133      }
 134  
 135      /**
 136       * Close the connection.
 137       */
 138      public function close()
 139      {
 140          if ($this->connected) {
 141              @fclose($this->_stream);
 142              $this->_connected = $this->_secure = false;
 143              $this->_stream = null;
 144          }
 145      }
 146  
 147      /* Internal methods. */
 148  
 149      /**
 150       * Connect to the remote server.
 151       *
 152       * @see __construct()
 153       *
 154       * @throws Horde\Socket\Client\Exception
 155       */
 156      protected function _connect($host, $port, $timeout, $secure, $retries = 0)
 157      {
 158          switch (strval($secure)) {
 159          case 'ssl':
 160          case 'sslv2':
 161          case 'sslv3':
 162              $conn = $secure . '://';
 163              $this->_secure = true;
 164              break;
 165  
 166          case 'tlsv1':
 167              $conn = 'tls://';
 168              $this->_secure = true;
 169              break;
 170  
 171          case 'tls':
 172          default:
 173              $conn = 'tcp://';
 174              break;
 175          }
 176  
 177          $this->_stream = @stream_socket_client(
 178              $conn . $host . ':' . $port,
 179              $error_number,
 180              $error_string,
 181              $timeout
 182          );
 183  
 184          if ($this->_stream === false) {
 185              /* From stream_socket_client() page: a function return of false,
 186               * with an error code of 0, indicates a "problem initializing the
 187               * socket". These kind of issues are seen on the same server
 188               * (and even the same user account) as sucessful connections, so
 189               * these are likely transient issues. Retry up to 3 times in these
 190               * instances. */
 191              if (!$error_number && ($retries < 3)) {
 192                  return $this->_connect($host, $port, $timeout, $secure, ++$retries);
 193              }
 194  
 195              $e = new Client\Exception(
 196                  'Error connecting to server.'
 197              );
 198              $e->details = sprintf("[%u] %s", $error_number, $error_string);
 199              throw $e;
 200          }
 201  
 202          stream_set_timeout($this->_stream, $timeout);
 203  
 204          if (function_exists('stream_set_read_buffer')) {
 205              stream_set_read_buffer($this->_stream, 0);
 206          }
 207          stream_set_write_buffer($this->_stream, 0);
 208  
 209          $this->_connected = true;
 210      }
 211  
 212  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1