Skip to content

Commit 572aacb

Browse files
committed
Update
1 parent fd6214a commit 572aacb

File tree

7 files changed

+408
-434
lines changed

7 files changed

+408
-434
lines changed

src/Protocols/Frame.php

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
namespace localzet\Server\Protocols;
2828

29+
use localzet\Server\Connection\ConnectionInterface;
2930
use function pack;
3031
use function strlen;
3132
use function substr;
@@ -34,12 +35,10 @@
3435
/**
3536
* Протокол Frame.
3637
*/
37-
class Frame
38+
class Frame implements ProtocolInterface
3839
{
39-
/**
40-
* Проверка целостности пакета.
41-
*/
42-
public static function input(string $buffer): int
40+
/** @inheritdoc */
41+
public static function input(string $buffer, ConnectionInterface $connection): int
4342
{
4443
// Если длина буфера меньше 4, возвращаем 0.
4544
if (strlen($buffer) < 4) {
@@ -52,23 +51,19 @@ public static function input(string $buffer): int
5251
return $unpackData['total_length'];
5352
}
5453

55-
/**
56-
* Декодирование.
57-
*/
58-
public static function decode(string $buffer): string
59-
{
60-
// Возвращаем подстроку буфера, начиная с 4-го символа.
61-
return substr($buffer, 4);
62-
}
63-
64-
/**
65-
* Кодирование.
66-
*/
67-
public static function encode(string $data): string
54+
/** @inheritdoc */
55+
public static function encode(mixed $data, ConnectionInterface $connection): string
6856
{
6957
// Общая длина равна 4 плюс длина данных.
7058
$totalLength = 4 + strlen($data);
7159
// Возвращаем упакованные данные.
7260
return pack('N', $totalLength) . $data;
7361
}
62+
63+
/** @inheritdoc */
64+
public static function decode(string $buffer, ConnectionInterface $connection): string
65+
{
66+
// Возвращаем подстроку буфера, начиная с 4-го символа.
67+
return substr($buffer, 4);
68+
}
7469
}

src/Protocols/Http.php

Lines changed: 69 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
namespace localzet\Server\Protocols;
2828

29+
use localzet\Server\Connection\ConnectionInterface;
2930
use localzet\Server\Connection\TcpConnection;
3031
use localzet\Server\Protocols\Http\Request;
3132
use localzet\Server\Protocols\Http\Response;
@@ -51,7 +52,7 @@
5152
* Класс Http.
5253
* @package localzet\Server\Protocols
5354
*/
54-
class Http
55+
class Http implements ProtocolInterface
5556
{
5657
/**
5758
* Имя класса Request.
@@ -77,18 +78,14 @@ public static function requestClass(string $className = null): string
7778
return static::$requestClass;
7879
}
7980

80-
/**
81-
* Проверить целостность пакета.
82-
*
83-
* @throws Throwable
84-
*/
85-
public static function input(string $buffer, TcpConnection $tcpConnection): int
81+
/** @inheritdoc */
82+
public static function input(string $buffer, TcpConnection|ConnectionInterface $connection): int
8683
{
8784
$crlfPos = strpos($buffer, "\r\n\r\n");
8885
if (false === $crlfPos) {
8986
// Проверьте, не превышает ли длина пакета лимит.
9087
if (strlen($buffer) >= 16384) {
91-
$tcpConnection->close(format_http_response(413), true);
88+
$connection->close(format_http_response(413), true);
9289
}
9390

9491
return 0;
@@ -106,125 +103,118 @@ public static function input(string $buffer, TcpConnection $tcpConnection): int
106103
!str_starts_with($header, 'PUT ') &&
107104
!str_starts_with($header, 'PATCH ')
108105
) {
109-
$tcpConnection->close(format_http_response(400), true);
106+
$connection->close(format_http_response(400), true);
110107
return 0;
111108
}
112109

113110
if (preg_match('/\b(?:Transfer-Encoding\b.*)|(?:Content-Length:\s*(\d+)(?!.*\bTransfer-Encoding\b))/is', $header, $matches)) {
114111
if (!isset($matches[1])) {
115-
$tcpConnection->close(format_http_response(400), true);
112+
$connection->close(format_http_response(400), true);
116113
return 0;
117114
}
118115
$length += (int)$matches[1];
119116
}
120117

121-
if ($length > $tcpConnection->maxPackageSize) {
122-
$tcpConnection->close(format_http_response(413), true);
118+
if ($length > $connection->maxPackageSize) {
119+
$connection->close(format_http_response(413), true);
123120
return 0;
124121
}
125122

126123
return $length;
127124
}
128125

129-
/**
130-
* Декодирование Http.
131-
*/
132-
public static function decode(string $buffer, TcpConnection $tcpConnection): Request
133-
{
134-
static $requests = [];
135-
if (isset($requests[$buffer])) {
136-
$request = $requests[$buffer];
137-
$request->connection = $tcpConnection;
138-
$tcpConnection->request = $request;
139-
$request->destroy();
140-
return $request;
141-
}
142-
143-
/** @var Request $request */
144-
$request = new static::$requestClass($buffer);
145-
if (!isset($buffer[TcpConnection::MAX_CACHE_STRING_LENGTH])) {
146-
$requests[$buffer] = $request;
147-
if (count($requests) > TcpConnection::MAX_CACHE_SIZE) {
148-
unset($requests[key($requests)]);
149-
}
150-
151-
$request = clone $request;
152-
}
153-
154-
$request->connection = $tcpConnection;
155-
$tcpConnection->request = $request;
156-
157-
foreach ($request->header() as $name => $value) {
158-
$_SERVER[strtoupper((string)$name)] = $value;
159-
}
160-
161-
$_GET = $request->get();
162-
$_POST = $request->post();
163-
$_COOKIE = $request->cookie();
164-
165-
$_REQUEST = $_GET + $_POST + $_COOKIE;
166-
$_SESSION = $request->session();
167-
168-
return $request;
169-
}
170-
171-
/**
172-
* Кодирование Http.
173-
*
174-
* @param string|Response|ServerSentEvents $response
175-
* @throws Throwable
176-
*/
177-
public static function encode(mixed $response, TcpConnection $tcpConnection): string
126+
/** @inheritdoc */
127+
public static function encode(mixed $data, TcpConnection|ConnectionInterface $connection): string
178128
{
179-
if ($tcpConnection->request instanceof Request) {
129+
if ($connection->request instanceof Request) {
180130
// Удаляем ссылки на запрос и соединение для предотвращения утечки памяти.
181-
$request = $tcpConnection->request;
131+
$request = $connection->request;
182132
// Очищаем свойства запроса и соединения.
183-
$request->connection = $tcpConnection->request = null;
133+
$request->connection = $connection->request = null;
184134
}
185135

186-
$response = is_object($response) ? $response : new Response(200, [], (string)$response);
136+
$data = is_object($data) ? $data : new Response(200, [], (string)$data);
187137

188-
if ($tcpConnection->headers && method_exists($response, 'withHeaders')) {
138+
if ($connection->headers && method_exists($data, 'withHeaders')) {
189139
// Добавляем заголовки соединения в ответ.
190-
$response->withHeaders($tcpConnection->headers);
140+
$data->withHeaders($connection->headers);
191141
// Очищаем заголовки после использования.
192-
$tcpConnection->headers = [];
142+
$connection->headers = [];
193143
}
194144

195-
if (!empty($response->file)) {
196-
$file = $response->file['file'];
197-
$offset = $response->file['offset'];
198-
$length = $response->file['length'];
145+
if (!empty($data->file)) {
146+
$file = $data->file['file'];
147+
$offset = $data->file['offset'];
148+
$length = $data->file['length'];
199149
clearstatcache();
200150
$fileSize = (int)filesize($file);
201151
$bodyLen = $length > 0 ? $length : $fileSize - $offset;
202-
$response->withHeaders([
152+
$data->withHeaders([
203153
'Content-Length' => $bodyLen,
204154
'Accept-Ranges' => 'bytes',
205155
]);
206156
if ($offset || $length) {
207157
$offsetEnd = $offset + $bodyLen - 1;
208-
$response->header('Content-Range', "bytes $offset-$offsetEnd/$fileSize");
158+
$data->header('Content-Range', "bytes $offset-$offsetEnd/$fileSize");
209159
}
210160

211161
if ($bodyLen < 2 * 1024 * 1024) {
212-
$tcpConnection->send($response . file_get_contents($file, false, null, $offset, $bodyLen), true);
162+
$connection->send($data . file_get_contents($file, false, null, $offset, $bodyLen), true);
213163
return '';
214164
}
215165

216166
$handler = fopen($file, 'r');
217167
if (false === $handler) {
218-
$tcpConnection->close(new Response(403, [], '403 Forbidden'));
168+
$connection->close(new Response(403, [], '403 Forbidden'));
219169
return '';
220170
}
221171

222-
$tcpConnection->send((string)$response, true);
223-
static::sendStream($tcpConnection, $handler, $offset, $length);
172+
$connection->send((string)$data, true);
173+
static::sendStream($connection, $handler, $offset, $length);
224174
return '';
225175
}
226176

227-
return (string)$response;
177+
return (string)$data;
178+
}
179+
180+
/** @inheritdoc */
181+
public static function decode(string $buffer, TcpConnection|ConnectionInterface $connection): Request
182+
{
183+
static $requests = [];
184+
if (isset($requests[$buffer])) {
185+
$request = $requests[$buffer];
186+
$request->connection = $connection;
187+
$connection->request = $request;
188+
$request->destroy();
189+
return $request;
190+
}
191+
192+
/** @var Request $request */
193+
$request = new static::$requestClass($buffer);
194+
if (!isset($buffer[TcpConnection::MAX_CACHE_STRING_LENGTH])) {
195+
$requests[$buffer] = $request;
196+
if (count($requests) > TcpConnection::MAX_CACHE_SIZE) {
197+
unset($requests[key($requests)]);
198+
}
199+
200+
$request = clone $request;
201+
}
202+
203+
$request->connection = $connection;
204+
$connection->request = $request;
205+
206+
foreach ($request->header() as $name => $value) {
207+
$_SERVER[strtoupper((string)$name)] = $value;
208+
}
209+
210+
$_GET = $request->get();
211+
$_POST = $request->post();
212+
$_COOKIE = $request->cookie();
213+
214+
$_REQUEST = $_GET + $_POST + $_COOKIE;
215+
$_SESSION = $request->session();
216+
217+
return $request;
228218
}
229219

230220
/**

src/Protocols/Https.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
/**
5555
* @uses Http
5656
*/
57-
class Https extends Http
57+
class Https extends Http implements ProtocolInterface
5858
{
5959

6060
}

src/Protocols/ProtocolInterface.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
namespace localzet\Server\Protocols;
2828

2929
use localzet\Server\Connection\ConnectionInterface;
30+
use Throwable;
3031

3132
/**
3233
* Интерфейс протокола
@@ -39,18 +40,32 @@ interface ProtocolInterface
3940
* Если длина неизвестна, верните 0, что означает ожидание дополнительных данных.
4041
* Если в пакете есть какие-то проблемы, верните false, и соединение будет закрыто.
4142
*
42-
* @return int|false
43+
* @param string $buffer
44+
* @param ConnectionInterface $connection
45+
* @return int
46+
* @throws Throwable
4347
*/
4448
public static function input(string $buffer, ConnectionInterface $connection): int;
4549

4650
/**
47-
* Расшифруйте пакет и вызовите обратный вызов onMessage($message), где $message - это результат, возвращенный функцией decode.
51+
* Кодируйте пакет перед отправкой клиенту.
52+
*
53+
* @param mixed $data
54+
* @param ConnectionInterface $connection
55+
* @return string
56+
* @throws Throwable
4857
*/
49-
public static function decode(string $buffer, ConnectionInterface $connection): mixed;
58+
public static function encode(mixed $data, ConnectionInterface $connection): string;
5059

5160
/**
52-
* Кодируйте пакет перед отправкой клиенту.
61+
* Расшифруйте пакет и вызовите обратный вызов onMessage($message),
62+
* где $message - это результат, возвращенный функцией decode.
63+
*
64+
* @param string $buffer
65+
* @param ConnectionInterface $connection
66+
* @return mixed
67+
* @throws Throwable
5368
*/
54-
public static function encode(mixed $data, ConnectionInterface $connection): string;
69+
public static function decode(string $buffer, ConnectionInterface $connection): mixed;
5570
}
5671

src/Protocols/Text.php

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@
3434
/**
3535
* Текстовый протокол.
3636
*/
37-
class Text
37+
class Text implements ProtocolInterface
3838
{
39-
/**
40-
* Проверим целостность пакета.
41-
*/
39+
/** @inheritdoc */
4240
public static function input(string $buffer, ConnectionInterface $connection): int
4341
{
4442
// Проверяем, превышает ли длина пакета установленный предел.
@@ -59,19 +57,15 @@ public static function input(string $buffer, ConnectionInterface $connection): i
5957
return $pos + 1;
6058
}
6159

62-
/**
63-
* Кодируем данные перед отправкой.
64-
*/
65-
public static function encode(string $buffer): string
60+
/** @inheritdoc */
61+
public static function encode(mixed $data, ConnectionInterface $connection): string
6662
{
6763
// Добавляем символ "\n" к данным перед отправкой.
68-
return $buffer . "\n";
64+
return $data . "\n";
6965
}
7066

71-
/**
72-
* Декодируем полученные данные.
73-
*/
74-
public static function decode(string $buffer): string
67+
/** @inheritdoc */
68+
public static function decode(string $buffer, ConnectionInterface $connection): string
7569
{
7670
// Удаляем символы "\r" и "\n" из полученных данных.
7771
return rtrim($buffer, "\r\n");

0 commit comments

Comments
 (0)