26
26
27
27
namespace localzet \Server \Protocols ;
28
28
29
+ use localzet \Server \Connection \ConnectionInterface ;
29
30
use localzet \Server \Connection \TcpConnection ;
30
31
use localzet \Server \Protocols \Http \Request ;
31
32
use localzet \Server \Protocols \Http \Response ;
51
52
* Класс Http.
52
53
* @package localzet\Server\Protocols
53
54
*/
54
- class Http
55
+ class Http implements ProtocolInterface
55
56
{
56
57
/**
57
58
* Имя класса Request.
@@ -77,18 +78,14 @@ public static function requestClass(string $className = null): string
77
78
return static ::$ requestClass ;
78
79
}
79
80
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
86
83
{
87
84
$ crlfPos = strpos ($ buffer , "\r\n\r\n" );
88
85
if (false === $ crlfPos ) {
89
86
// Проверьте, не превышает ли длина пакета лимит.
90
87
if (strlen ($ buffer ) >= 16384 ) {
91
- $ tcpConnection ->close (format_http_response (413 ), true );
88
+ $ connection ->close (format_http_response (413 ), true );
92
89
}
93
90
94
91
return 0 ;
@@ -106,125 +103,118 @@ public static function input(string $buffer, TcpConnection $tcpConnection): int
106
103
!str_starts_with ($ header , 'PUT ' ) &&
107
104
!str_starts_with ($ header , 'PATCH ' )
108
105
) {
109
- $ tcpConnection ->close (format_http_response (400 ), true );
106
+ $ connection ->close (format_http_response (400 ), true );
110
107
return 0 ;
111
108
}
112
109
113
110
if (preg_match ('/\b(?:Transfer-Encoding\b.*)|(?:Content-Length:\s*(\d+)(?!.*\bTransfer-Encoding\b))/is ' , $ header , $ matches )) {
114
111
if (!isset ($ matches [1 ])) {
115
- $ tcpConnection ->close (format_http_response (400 ), true );
112
+ $ connection ->close (format_http_response (400 ), true );
116
113
return 0 ;
117
114
}
118
115
$ length += (int )$ matches [1 ];
119
116
}
120
117
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 );
123
120
return 0 ;
124
121
}
125
122
126
123
return $ length ;
127
124
}
128
125
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
178
128
{
179
- if ($ tcpConnection ->request instanceof Request) {
129
+ if ($ connection ->request instanceof Request) {
180
130
// Удаляем ссылки на запрос и соединение для предотвращения утечки памяти.
181
- $ request = $ tcpConnection ->request ;
131
+ $ request = $ connection ->request ;
182
132
// Очищаем свойства запроса и соединения.
183
- $ request ->connection = $ tcpConnection ->request = null ;
133
+ $ request ->connection = $ connection ->request = null ;
184
134
}
185
135
186
- $ response = is_object ($ response ) ? $ response : new Response (200 , [], (string )$ response );
136
+ $ data = is_object ($ data ) ? $ data : new Response (200 , [], (string )$ data );
187
137
188
- if ($ tcpConnection ->headers && method_exists ($ response , 'withHeaders ' )) {
138
+ if ($ connection ->headers && method_exists ($ data , 'withHeaders ' )) {
189
139
// Добавляем заголовки соединения в ответ.
190
- $ response ->withHeaders ($ tcpConnection ->headers );
140
+ $ data ->withHeaders ($ connection ->headers );
191
141
// Очищаем заголовки после использования.
192
- $ tcpConnection ->headers = [];
142
+ $ connection ->headers = [];
193
143
}
194
144
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 ' ];
199
149
clearstatcache ();
200
150
$ fileSize = (int )filesize ($ file );
201
151
$ bodyLen = $ length > 0 ? $ length : $ fileSize - $ offset ;
202
- $ response ->withHeaders ([
152
+ $ data ->withHeaders ([
203
153
'Content-Length ' => $ bodyLen ,
204
154
'Accept-Ranges ' => 'bytes ' ,
205
155
]);
206
156
if ($ offset || $ length ) {
207
157
$ offsetEnd = $ offset + $ bodyLen - 1 ;
208
- $ response ->header ('Content-Range ' , "bytes $ offset- $ offsetEnd/ $ fileSize " );
158
+ $ data ->header ('Content-Range ' , "bytes $ offset- $ offsetEnd/ $ fileSize " );
209
159
}
210
160
211
161
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 );
213
163
return '' ;
214
164
}
215
165
216
166
$ handler = fopen ($ file , 'r ' );
217
167
if (false === $ handler ) {
218
- $ tcpConnection ->close (new Response (403 , [], '403 Forbidden ' ));
168
+ $ connection ->close (new Response (403 , [], '403 Forbidden ' ));
219
169
return '' ;
220
170
}
221
171
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 );
224
174
return '' ;
225
175
}
226
176
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 ;
228
218
}
229
219
230
220
/**
0 commit comments