Skip to content
This repository was archived by the owner on Oct 30, 2024. It is now read-only.

Commit ca1b211

Browse files
authored
Merge pull request repejota#122 from tomponline/develop
Adds TLS support
2 parents 68e6d24 + 90e81f2 commit ca1b211

3 files changed

Lines changed: 68 additions & 17 deletions

File tree

src/Nats/Connection.php

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,10 @@ public function isConnected()
229229
* @param string $address Server url string.
230230
* @param float $timeout Number of seconds until the connect() system call should timeout.
231231
*
232-
* @return resource
233232
* @throws \Exception Exception raised if connection fails.
233+
* @return resource
234234
*/
235-
private function getStream($address, $timeout)
235+
private function getStream($address, $timeout, $context)
236236
{
237237
$errno = null;
238238
$errstr = null;
@@ -242,7 +242,8 @@ function () {
242242
return true;
243243
}
244244
);
245-
$fp = stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT);
245+
246+
$fp = stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);
246247
restore_error_handler();
247248

248249
if ($fp === false) {
@@ -315,8 +316,8 @@ public function __construct(ConnectionOptions $options = null)
315316
*
316317
* @param string $payload Message data.
317318
*
318-
* @return void
319319
* @throws \Exception Raises if fails sending data.
320+
* @return void
320321
*/
321322
private function send($payload)
322323
{
@@ -394,8 +395,8 @@ private function handlePING()
394395
*
395396
* @param string $line Message command from Nats.
396397
*
397-
* @return void
398398
* @throws Exception If subscription not found.
399+
* @return void
399400
* @codeCoverageIgnore
400401
*/
401402
private function handleMSG($line)
@@ -408,7 +409,7 @@ private function handleMSG($line)
408409
if (count($parts) === 5) {
409410
$length = trim($parts[4]);
410411
$subject = $parts[3];
411-
} else if (count($parts) === 4) {
412+
} elseif (count($parts) === 4) {
412413
$length = trim($parts[3]);
413414
$subject = $parts[1];
414415
}
@@ -443,19 +444,34 @@ public function connect($timeout = null)
443444
}
444445

445446
$this->timeout = $timeout;
446-
$this->streamSocket = $this->getStream($this->options->getAddress(), $timeout);
447+
$this->streamSocket = $this->getStream(
448+
$this->options->getAddress(), $timeout, $this->options->getStreamContext());
447449
$this->setStreamTimeout($timeout);
448450

449-
$msg = 'CONNECT '.$this->options;
450-
$this->send($msg);
451-
$connectResponse = $this->receive();
451+
$infoResponse = $this->receive();
452452

453-
if ($this->isErrorResponse($connectResponse) === true) {
454-
throw Exception::forFailedConnection($connectResponse);
453+
if ($this->isErrorResponse($infoResponse) === true) {
454+
throw Exception::forFailedConnection($infoResponse);
455455
} else {
456-
$this->processServerInfo($connectResponse);
456+
$this->processServerInfo($infoResponse);
457+
if ($this->serverInfo->isTLSRequired()) {
458+
set_error_handler(
459+
function ($errno, $errstr, $errfile, $errline) {
460+
restore_error_handler();
461+
throw Exception::forFailedConnection($errstr);
462+
});
463+
464+
if (!stream_socket_enable_crypto(
465+
$this->streamSocket, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT)) {
466+
throw Exception::forFailedConnection('Error negotiating crypto');
467+
}
468+
469+
restore_error_handler();
470+
}
457471
}
458472

473+
$msg = 'CONNECT '.$this->options;
474+
$this->send($msg);
459475
$this->ping();
460476
$pingResponse = $this->receive();
461477

@@ -560,9 +576,9 @@ public function unsubscribe($sid, $quantity = null)
560576
* @param string $payload Message data.
561577
* @param string $inbox Message inbox.
562578
*
579+
* @throws Exception If subscription not found.
563580
* @return void
564581
*
565-
* @throws Exception If subscription not found.
566582
*/
567583
public function publish($subject, $payload = null, $inbox = null)
568584
{

src/Nats/ConnectionOptions.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ class ConnectionOptions
8181
*/
8282
private $reconnect = true;
8383

84+
/**
85+
* Stream context to use.
86+
*
87+
* @var resource
88+
*/
89+
private $streamContext = null;
90+
8491
/**
8592
* Allows to define parameters which can be set by passing them to the class constructor.
8693
*
@@ -97,6 +104,7 @@ class ConnectionOptions
97104
'verbose',
98105
'pedantic',
99106
'reconnect',
107+
'streamContext',
100108
];
101109

102110

@@ -120,6 +128,9 @@ class ConnectionOptions
120128
*/
121129
public function __construct($options = null)
122130
{
131+
//Default stream context
132+
$this->streamContext = stream_context_get_default();
133+
123134
if (empty($options) === false) {
124135
$this->initialize($options);
125136
}
@@ -420,6 +431,30 @@ public function setReconnect($reconnect)
420431
return $this;
421432
}
422433

434+
/**
435+
* Get stream context.
436+
*
437+
* @return resource
438+
*/
439+
public function getStreamContext()
440+
{
441+
return $this->streamContext;
442+
}
443+
444+
/**
445+
* Set stream context.
446+
*
447+
* @param resource $streamContext Stream context.
448+
*
449+
* @return $this
450+
*/
451+
public function setStreamContext($streamContext)
452+
{
453+
$this->streamContext = $streamContext;
454+
455+
return $this;
456+
}
457+
423458
/**
424459
* Set the connection options.
425460
*

src/Nats/ServerInfo.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ public function __construct($connectionResponse)
102102
$this->setPort($data['port']);
103103
$this->setVersion($data['version']);
104104
$this->setGoVersion($data['go']);
105-
$this->setAuthRequired($data['auth_required']);
106-
$this->setTLSRequired($data['tls_required']);
107-
$this->setTLSVerify($data['tls_verify']);
105+
$this->setAuthRequired(isset($data['auth_required']) ? $data['auth_required'] : false);
106+
$this->setTLSRequired(isset($data['tls_required']) ? $data['tls_required'] : false);
107+
$this->setTLSVerify(isset($data['tls_verify']) ? $data['tls_verify'] : false);
108108
$this->setMaxPayload($data['max_payload']);
109109

110110
if (version_compare($data['version'], '1.1.0') === -1) {

0 commit comments

Comments
 (0)