3 namespace wcf\system\io
;
5 use wcf\system\exception\SystemException
;
8 * The RemoteFile class opens a connection to a remote host as a file.
11 * @copyright 2001-2019 WoltLab GmbH
12 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14 class RemoteFile
extends File
32 protected $errorNumber = 0;
38 protected $errorDesc = '';
41 * true if PHP supports SSL/TLS
44 private static $hasSSLSupport;
46 /** @noinspection PhpMissingParentConstructorInspection */
49 * Opens a new connection to a remote host.
54 * @param array $options
55 * @throws SystemException
57 public function __construct($host, $port, $timeout = 30, $options = [])
62 if (!\
preg_match('/^[a-z0-9]+:/', $this->host
)) {
63 $this->host
= 'tcp://' . $this->host
;
66 $context = \
stream_context_create($options);
68 $this->resource = \
stream_socket_client(
69 $this->host
. ':' . $this->port
,
73 \STREAM_CLIENT_CONNECT
,
76 if ($this->resource === false) {
77 throw new \
Exception('stream_socket_client returned false: ' . $this->errorDesc
, $this->errorNumber
);
79 } catch (\Exception
$e) {
80 throw new SystemException('Can not connect to ' . $host, 0, $this->errorDesc
, $e);
83 \
stream_set_timeout($this->resource, $timeout);
87 * Returns the error number of the last error.
91 public function getErrorNumber()
93 return $this->errorNumber
;
97 * Returns the error description of the last error.
101 public function getErrorDesc()
103 return $this->errorDesc
;
107 * Switches TLS support for this connection.
108 * Usually used in combination with 'STARTTLS'
110 * @param bool $enable Whether TLS support should be enabled
111 * @return bool True on success, false otherwise
113 public function setTLS($enable)
115 if (!$this->hasTLSSupport()) {
119 $cryptoType = \STREAM_CRYPTO_METHOD_TLS_CLIENT
;
121 // PHP 5.6.8+ defines STREAM_CRYPTO_METHOD_TLS_CLIENT as STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT for BC reasons.
122 // STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT was introduced in PHP 5.6.8, but is not exposed to userland. Try to use
123 // it for forward compatibility.
125 // As of PHP 7.2+ STREAM_CRYPTO_METHOD_TLS_CLIENT is equivalent to STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT.
126 // see: https://wiki.php.net/rfc/improved-tls-constants
127 // see: https://github.com/php/php-src/blob/197cac65fdf712effb19ad3e40688ceb7ebc7f7d/main/streams/php_stream_transport.h#L173-L175
128 if (\
defined('STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT')) {
129 $cryptoType |
= STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT
;
132 // Add bits for all known TLS versions for the reasons above.
133 if (\
defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) {
134 $cryptoType |
= \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
;
136 if (\
defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
137 $cryptoType |
= \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
;
139 if (\
defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
140 $cryptoType |
= \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
;
142 if (\
defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) {
143 $cryptoType |
= \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT
;
146 return \
stream_socket_enable_crypto($this->resource, $enable, $cryptoType);
150 * Returns whether TLS support is available.
154 public function hasTLSSupport()
156 return \function_exists
('stream_socket_enable_crypto');
160 * @deprecated 6.0 This method is effectively returning bogus data, because the majority of TLS communication uses Guzzle/cURL.
162 public static function supportsSSL()
164 if (static::$hasSSLSupport === null) {
165 static::$hasSSLSupport = false;
167 $transports = \
stream_get_transports();
168 foreach ($transports as $transport) {
169 if (\
preg_match('~^(ssl(v[23])?|tls(v[0-9\.]+)?)$~', $transport)) {
170 static::$hasSSLSupport = true;
176 return static::$hasSSLSupport;
180 * @deprecated 6.0 See RemoteFile::supportsSSL(). The implementation is a noop.
182 public static function disableSSL()