Skip to content

Commit

Permalink
Merge branch 'issue139/heartbeat-ssl-endpoint'
Browse files Browse the repository at this point in the history
  • Loading branch information
DragonBe committed Apr 3, 2021
2 parents d8800ae + 98fef0a commit a6bfc40
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 19 deletions.
83 changes: 68 additions & 15 deletions src/Vies/HeartBeat.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
*/
class HeartBeat
{
private const DEFAULT_TIMEOUT = 10;

/**
* @var string The host you want to verify
*/
Expand Down Expand Up @@ -57,7 +59,7 @@ class HeartBeat
* @param int $port
* @param int $timeout
*/
public function __construct(?string $host = null, int $port = 80, int $timeout = 10)
public function __construct(?string $host = null, int $port = Vies::VIES_PORT, int $timeout = self::DEFAULT_TIMEOUT)
{
if (null !== $host) {
$this->setHost($host);
Expand Down Expand Up @@ -150,23 +152,35 @@ public function isAlive(): bool
*/
private function reachOut(): bool
{
$errno = 0;
$error = '';
$hostname = $this->getHost();
$portNumber = $this->getPort();
$timeToLive = $this->getTimeout();
try {
if (false === ($handle = \fsockopen('tcp://' . $hostname, $portNumber, $errno, $error, $timeToLive))) {
return false;
}
} catch (\Exception $exception) {
$data = $this->getSecuredResponse();
} catch (\RuntimeException $runtimeException) {
return false;
}
return (
(0 === strcmp('HTTP/1.1 200 OK', $data[0])) ||
(0 === strcmp('HTTP/1.1 307 Temporary Redirect', $data[0]))
);
}

/**
* This method will make a simple request inside a stream
* resource to retrieve its contents. Useful inside secured
* streams.
*
* @param resource $handle
* @return array
*/
private function readContents($handle): array
{
if (! is_resource($handle)) {
throw new \InvalidArgumentException('Expecting a resource to be provided');
}
$response = '';
$uri = sprintf('%s://%s/', Vies::VIES_PROTO, Vies::VIES_DOMAIN);
$uri = sprintf('%s://%s/', Vies::VIES_PROTO, $this->host);
$stream = [
'GET ' . $uri . ' HTTP/1.0',
'Host: ' . Vies::VIES_DOMAIN,
'Host: ' . $this->host,
'Connection: close',
];
fwrite($handle, implode("\r\n", $stream) . "\r\n\r\n");
Expand All @@ -176,9 +190,48 @@ private function reachOut(): bool
fclose($handle);
$response = str_replace("\r\n", PHP_EOL, $response);
$data = explode(PHP_EOL, $response);
return (
(0 === strcmp('HTTP/1.1 200 OK', $data[0])) ||
(0 === strcmp('HTTP/1.1 307 Temporary Redirect', $data[0]))
return $data;
}

/**
* Will make a secured request over SSL/TLS where this
* method will first create a secured stream before
* making the request.
*
* @return array
* @throws \RuntimeException
* @see https://bytephunk.wordpress.com/2017/11/27/ssl-tls-stream-sockets-in-php-7/
*/
private function getSecuredResponse(): array
{
$streamOptions = [
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'allow_self_signed' => false,
],
];
$streamContext = stream_context_create($streamOptions);
$socketAddress = sprintf(
'tls://%s:%d',
$this->host,
$this->port
);
$error = null;
$errno = null;
$stream = stream_socket_client(
$socketAddress,
$errno,
$error,
self::DEFAULT_TIMEOUT,
STREAM_CLIENT_CONNECT,
$streamContext
);

if (! $stream) {
throw new \RuntimeException('Can not create socket stream: ' . $error);
}

return $this->readContents($stream);
}
}
4 changes: 2 additions & 2 deletions src/Vies/Vies.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
*/
class Vies
{
const VIES_PROTO = 'http';
const VIES_PROTO = 'https';
const VIES_DOMAIN = 'ec.europa.eu';
const VIES_PORT = 80;
const VIES_PORT = 443;
const VIES_WSDL = '/taxation_customs/vies/checkVatService.wsdl';
const VIES_TEST_WSDL = '/taxation_customs/vies/checkVatTestService.wsdl';
const VIES_EU_COUNTRY_TOTAL = 29;
Expand Down
6 changes: 4 additions & 2 deletions tests/Vies/HeartBeatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function testDefaultPortIsHttp()
{
$hb = new HeartBeat();
$port = $hb->getPort();
$this->assertSame(80, $port);
$this->assertSame(443, $port);
}

/**
Expand Down Expand Up @@ -113,14 +113,16 @@ public function socketProvider(): array
{
return [
'Non-existing socket on localhost' => ['127.0.0.1', -1, 10, false],
'Socket 80 on ec.europe.eu' => [Vies::VIES_DOMAIN, Vies::VIES_PORT, 10, true],
'Socket 443 on ec.europe.eu' => [Vies::VIES_DOMAIN, Vies::VIES_PORT, 10, true],
];
}

/**
* @dataProvider socketProvider
* @covers ::isAlive
* @covers ::reachOut
* @covers ::getSecuredResponse
* @covers ::readContents
*/
public function testIsAliveUsingSockets($host, $port, $timeout, $expectedResult)
{
Expand Down

0 comments on commit a6bfc40

Please sign in to comment.