Skip to content

Commit 603cb79

Browse files
EPP Socket Connection V2 (alpha)
1 parent 644f8de commit 603cb79

File tree

5 files changed

+75
-86
lines changed

5 files changed

+75
-86
lines changed

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1+
.idea
12
vendor
23
composer.phar
34
composer.lock
4-
5-
php-cs-fixer
6-
.php_cs.cache

README.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,19 @@ Socket connection for communicating with EPP(Extensible Provisioning Protocol) s
66
```php
77
<?php
88

9-
use Struzik\EPPClient\Connection\StreamSocketConnection;
109
use Psr\Log\NullLogger;
10+
use Struzik\EPPClient\SocketConnection\StreamSocketConfig;
11+
use Struzik\EPPClient\SocketConnection\StreamSocketConnection;
1112

12-
$connection = new StreamSocketConnection(
13-
[
14-
'uri' => 'tls://epp.example.com:700',
15-
'timeout' => 30,
16-
'context' => [
17-
'ssl' => [
18-
'local_cert' => __DIR__.'/certificate.pem',
19-
],
20-
],
13+
$connectionConfig = new StreamSocketConfig();
14+
$connectionConfig->uri = 'tls://epp.example.com:700';
15+
$connectionConfig->timeout = 30;
16+
$connectionConfig->context = [
17+
'ssl' => [
18+
'local_cert' => __DIR__.'/certificate.pem',
2119
],
22-
new NullLogger()
23-
);
20+
];
21+
$connection = new StreamSocketConnection($connectionConfig, new NullLogger());
2422

2523
$connection->open();
2624
echo $connection->read();

composer.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010
}
1111
],
1212
"require": {
13-
"php": ">=5.6",
14-
"psr/log": "~1.0",
15-
"symfony/options-resolver": "~3.2",
13+
"php": ">=7.4 <8.2",
14+
"psr/log": "~1.0 | ~2.0 | ~3.0",
1615
"struzik-vladislav/php-error-handler": "~1.0",
17-
"struzik-vladislav/epp-client": "~1.0"
16+
"struzik-vladislav/epp-client": "dev-master"
1817
},
1918
"autoload": {
2019
"psr-4": {
21-
"Struzik\\EPPClient\\Connection\\": "src/"
20+
"Struzik\\EPPClient\\SocketConnection\\": "src/"
2221
}
2322
}
2423
}

src/StreamSocketConfig.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Struzik\EPPClient\SocketConnection;
4+
5+
class StreamSocketConfig
6+
{
7+
/**
8+
* EPP server URI.
9+
*/
10+
public string $uri = '';
11+
12+
/**
13+
* Number of seconds until the connect() system call should timeout.
14+
*/
15+
public int $timeout = 30;
16+
17+
/**
18+
* Value of $options parameter in stream_context_create(). See: https://secure.php.net/manual/en/function.stream-context-create.php.
19+
*/
20+
public array $context = [];
21+
}

src/StreamSocketConnection.php

Lines changed: 39 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<?php
22

3-
namespace Struzik\EPPClient\Connection;
3+
namespace Struzik\EPPClient\SocketConnection;
44

5+
use Psr\Log\LoggerInterface;
6+
use Struzik\EPPClient\Connection\ConnectionInterface;
57
use Struzik\EPPClient\Exception\ConnectionException;
8+
use Struzik\EPPClient\Response\Session\GreetingResponse;
69
use Struzik\ErrorHandler\ErrorHandler;
7-
use Struzik\ErrorHandler\Processor\IntoExceptionProcessor;
810
use Struzik\ErrorHandler\Exception\ErrorException;
9-
use Symfony\Component\OptionsResolver\OptionsResolver;
10-
use Symfony\Component\OptionsResolver\Exception\ExceptionInterface;
11-
use Psr\Log\LoggerInterface;
11+
use Struzik\ErrorHandler\Processor\IntoExceptionProcessor;
1212

1313
/**
1414
* Connection to EPP server based on stream_socket_client.
@@ -17,17 +17,13 @@ class StreamSocketConnection implements ConnectionInterface
1717
{
1818
/**
1919
* Server connection settings.
20-
*
21-
* @var array
2220
*/
23-
private $config;
21+
private StreamSocketConfig $config;
2422

2523
/**
2624
* Logger object.
27-
*
28-
* @var LoggerInterface
2925
*/
30-
private $logger;
26+
private LoggerInterface $logger;
3127

3228
/**
3329
* Resource of connection to the server.
@@ -36,50 +32,24 @@ class StreamSocketConnection implements ConnectionInterface
3632
*/
3733
private $connection;
3834

39-
/**
40-
* Buffer for stream reading.
41-
*
42-
* @var string
43-
*/
44-
private $buffer;
45-
4635
/**
4736
* Creating connection object to the EPP server.
4837
*
49-
* @param array $config
50-
* 'uri' - (string) EPP server URI
51-
* 'timeout' - (int) Number of seconds until the connect() system call should timeout.
52-
* 'context' - (array) Value of $options parameter in stream_context_create(). See: https://secure.php.net/manual/en/function.stream-context-create.php
53-
* @param LoggerInterface $logger PSR-3 compatible logger
54-
*
55-
* @throws ConnectionException
38+
* @param StreamSocketConfig $config connection settings
39+
* @param LoggerInterface $logger PSR-3 compatible logger
5640
*/
57-
public function __construct(array $config = [], LoggerInterface $logger)
41+
public function __construct(StreamSocketConfig $config, LoggerInterface $logger)
5842
{
59-
try {
60-
$this->logger = $logger;
61-
62-
$resolver = new OptionsResolver();
63-
$resolver->setRequired('uri');
64-
$resolver->setRequired('timeout');
65-
$resolver->setRequired('context');
66-
$resolver->setDefault('context', []);
67-
$resolver->setAllowedTypes('uri', 'string');
68-
$resolver->setAllowedTypes('timeout', 'int');
69-
$resolver->setAllowedTypes('context', 'array');
70-
71-
$this->config = $resolver->resolve($config);
72-
} catch (ExceptionInterface $e) {
73-
throw new ConnectionException('Invalid configuration parameters. See previous exception.', 0, $e);
74-
}
43+
$this->config = $config;
44+
$this->logger = $logger;
7545
}
7646

7747
/**
7848
* {@inheritdoc}
7949
*
8050
* @throws ConnectionException
8151
*/
82-
public function open()
52+
public function open(): void
8353
{
8454
try {
8555
// Setting up error handler
@@ -88,8 +58,18 @@ public function open()
8858
$errorHandler->set();
8959

9060
// Trying to open connection
91-
$context = stream_context_create($this->config['context']);
92-
$this->connection = stream_socket_client($this->config['uri'], $errno, $errstr, $this->config['timeout'], STREAM_CLIENT_CONNECT, $context);
61+
$context = stream_context_create($this->config->context);
62+
$this->connection = stream_socket_client($this->config->uri, $errno, $errstr, $this->config->timeout, STREAM_CLIENT_CONNECT, $context);
63+
64+
// Read greeting
65+
$greetingXML = $this->read();
66+
$this->logger->info(sprintf('Read greeting on connect: %s', $greetingXML));
67+
68+
// Check greeting
69+
$greeting = new GreetingResponse($greetingXML);
70+
if (!$greeting->isSuccess()) {
71+
throw new ConnectionException('Invalid greeting content. Node <greeting> not found. See log for details.');
72+
}
9373

9474
// Restore previous error handler
9575
$errorHandler->restore();
@@ -102,22 +82,22 @@ public function open()
10282
/**
10383
* {@inheritdoc}
10484
*/
105-
public function isOpened()
85+
public function isOpened(): bool
10686
{
10787
return is_resource($this->connection) && !feof($this->connection);
10888
}
10989

11090
/**
11191
* {@inheritdoc}
11292
*/
113-
public function close()
93+
public function close(): void
11494
{
11595
if (!$this->isOpened()) {
11696
return;
11797
}
11898

11999
if (fclose($this->connection) === false) {
120-
throw new ConnectionException('An error occured while closing the connection.');
100+
throw new ConnectionException('An error occurred while closing the connection.');
121101
}
122102

123103
$this->connection = null;
@@ -126,11 +106,9 @@ public function close()
126106
/**
127107
* {@inheritdoc}
128108
*
129-
* @return string
130-
*
131109
* @throws ConnectionException
132110
*/
133-
public function read()
111+
public function read(): string
134112
{
135113
// Checking open connection
136114
if (!$this->isOpened()) {
@@ -145,29 +123,29 @@ public function read()
145123

146124
// Trying to read a response
147125
$beginTime = microtime(true);
148-
$this->buffer = '';
126+
$readBuffer = '';
149127
$length = $this->readResponseLength();
150128
$this->logger->debug(sprintf('The length of the response body is %s bytes.', $length));
151129
if ($length) {
152-
for ($i = 0; (strlen($this->buffer) < $length) && ($i < 25); ++$i) {
130+
for ($i = 0; (strlen($readBuffer) < $length) && ($i < 25); ++$i) {
153131
usleep($i * 100000); // 100000 = 1/10 seconds
154-
$residualLength = $length - strlen($this->buffer);
132+
$residualLength = $length - strlen($readBuffer);
155133
$this->logger->debug(sprintf('Trying to read %s bytes of the response body.', $residualLength), ['iteration-number' => $i]);
156-
$this->buffer .= fread($this->connection, $residualLength);
134+
$readBuffer .= fread($this->connection, $residualLength);
157135
}
158136
}
159137
$endTime = microtime(true);
160138
$this->logger->debug(sprintf('The response time is %s seconds.', round($endTime - $beginTime, 3)));
161139

162140
// Checking lengths of the response body
163-
if ($length !== strlen($this->buffer)) {
141+
if ($length !== strlen($readBuffer)) {
164142
throw new ConnectionException('The number of bytes of a response body is not equal to the number of bytes from header.');
165143
}
166144

167145
// Restore previous error handler
168146
$errorHandler->restore();
169147

170-
return $this->buffer;
148+
return $readBuffer;
171149
} catch (ErrorException $e) {
172150
throw new ConnectionException('An error occurred while trying to read the response. See previous exception.', 0, $e);
173151
}
@@ -178,7 +156,7 @@ public function read()
178156
*
179157
* @throws ConnectionException
180158
*/
181-
public function write($xml)
159+
public function write(string $xml): void
182160
{
183161
// Checking open connection
184162
if (!$this->isOpened()) {
@@ -214,10 +192,8 @@ public function write($xml)
214192
* Preparing the request for sending to the EPP server. Adds a header to the command text.
215193
*
216194
* @param string $xml RAW-request without header
217-
*
218-
* @return string
219195
*/
220-
protected function prependHeader($xml)
196+
protected function prependHeader(string $xml): string
221197
{
222198
$header = pack('N', strlen($xml) + self::HEADER_LENGTH);
223199

@@ -226,10 +202,8 @@ protected function prependHeader($xml)
226202

227203
/**
228204
* Returns the length of the response (without header) in bytes.
229-
*
230-
* @return int
231205
*/
232-
protected function readResponseLength()
206+
protected function readResponseLength(): int
233207
{
234208
// Executing several attempt for reading
235209
$rawHeader = '';
@@ -243,8 +217,7 @@ protected function readResponseLength()
243217
// Unpack header from binary string
244218
$this->logger->debug(sprintf('Number of bytes of a response header: %s', strlen($rawHeader)));
245219
$unpackedHeader = unpack('N', $rawHeader);
246-
$length = $unpackedHeader[1] - self::HEADER_LENGTH;
247220

248-
return $length;
221+
return $unpackedHeader[1] - self::HEADER_LENGTH;
249222
}
250223
}

0 commit comments

Comments
 (0)