2 namespace wcf\system\io
;
3 use wcf\system\exception\SystemException
;
6 * The RemoteFile class opens a connection to a remote host as a file.
9 * @copyright 2001-2019 WoltLab GmbH
10 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
11 * @package WoltLabSuite\Core\System\Io
13 class RemoteFile
extends File
{
30 protected $errorNumber = 0;
36 protected $errorDesc = '';
39 * true if PHP supports SSL/TLS
42 private static $hasSSLSupport = null;
44 /** @noinspection PhpMissingParentConstructorInspection */
46 * Opens a new connection to a remote host.
49 * @param integer $port
50 * @param integer $timeout
51 * @param array $options
52 * @throws SystemException
54 public function __construct($host, $port, $timeout = 30, $options = []) {
58 if (!preg_match('/^[a-z0-9]+:/', $this->host
)) $this->host
= 'tcp://'.$this->host
;
60 $context = stream_context_create($options);
61 $this->resource = @stream_socket_client
($this->host
.':'.$this->port
, $this->errorNumber
, $this->errorDesc
, $timeout, STREAM_CLIENT_CONNECT
, $context);
62 if ($this->resource === false) {
63 throw new SystemException('Can not connect to ' . $host, 0, $this->errorDesc
);
66 stream_set_timeout($this->resource, $timeout);
70 * Returns the error number of the last error.
74 public function getErrorNumber() {
75 return $this->errorNumber
;
79 * Returns the error description of the last error.
83 public function getErrorDesc() {
84 return $this->errorDesc
;
88 * Switches TLS support for this connection.
89 * Usually used in combination with 'STARTTLS'
91 * @param boolean $enable Whether TLS support should be enabled
92 * @return boolean True on success, false otherwise
94 public function setTLS($enable) {
95 if (!$this->hasTLSSupport()) return false;
97 $cryptoType = STREAM_CRYPTO_METHOD_TLS_CLIENT
;
99 // PHP 5.6.8+ defines STREAM_CRYPTO_METHOD_TLS_CLIENT as STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT for BC reasons.
100 // STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT was introduced in PHP 5.6.8, but is not exposed to userland. Try to use
101 // it for forward compatibility.
102 if (defined('STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT')) $cryptoType = STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT
;
104 // Add bits for all known TLS versions for the reasons above.
105 if (defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) $cryptoType |
= STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
;
106 if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) $cryptoType |
= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
;
107 if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) $cryptoType |
= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
;
109 return stream_socket_enable_crypto($this->resource, $enable, $cryptoType);
113 * Returns whether TLS support is available.
117 public function hasTLSSupport() {
118 return function_exists('stream_socket_enable_crypto');
122 * Returns true if PHP supports SSL/TLS.
126 public static function supportsSSL() {
127 if (static::$hasSSLSupport === null) {
128 static::$hasSSLSupport = false;
130 $transports = stream_get_transports();
131 foreach ($transports as $transport) {
132 if (preg_match('~^(ssl(v[23])?|tls(v[0-9\.]+)?)$~', $transport)) {
133 static::$hasSSLSupport = true;
139 return static::$hasSSLSupport;
143 * Disables SSL/TLS support on runtime regardless if PHP is theoretically capable of it.
145 public static function disableSSL() {
146 static::$hasSSLSupport = false;