55namespace Spiral \RoadRunner \Http ;
66
77use Generator ;
8+ use RoadRunner \HTTP \DTO \V1BETA1 \FileUpload ;
9+ use RoadRunner \HTTP \DTO \V1BETA1 \HeaderValue ;
10+ use RoadRunner \HTTP \DTO \V1BETA1 \Request as RequestProto ;
11+ use Spiral \RoadRunner \Encoding ;
812use Spiral \RoadRunner \Http \Exception \StreamStoppedException ;
913use Spiral \RoadRunner \Message \Command \StreamStop ;
1014use Spiral \RoadRunner \Payload ;
@@ -56,10 +60,17 @@ public function waitRequest(): ?Request
5660 return null ;
5761 }
5862
63+ if ($ payload ->encoding === Encoding::Protobuf) {
64+ $ message = new RequestProto ();
65+ $ message ->mergeFromString ($ payload ->body );
66+
67+ return $ this ->requestFromProto ($ message );
68+ }
69+
5970 /** @var RequestContext $context */
6071 $ context = \json_decode ($ payload ->header , true , 512 , \JSON_THROW_ON_ERROR );
6172
62- return $ this ->createRequest ($ payload ->body , $ context );
73+ return $ this ->arrayToRequest ($ payload ->body , $ context );
6374 }
6475
6576 /**
@@ -134,7 +145,7 @@ private function respondStream(int $status, Generator $body, array $headers = []
134145 /**
135146 * @param RequestContext $context
136147 */
137- private function createRequest (string $ body , array $ context ): Request
148+ private function arrayToRequest (string $ body , array $ context ): Request
138149 {
139150 \parse_str ($ context ['rawQuery ' ], $ query );
140151 return new Request (
@@ -154,6 +165,47 @@ private function createRequest(string $body, array $context): Request
154165 );
155166 }
156167
168+ private function requestFromProto (RequestProto $ message ): Request
169+ {
170+ $ headers = $ this ->headerValueToArray ($ message ->getHeader ());
171+ $ uploadedFiles = [];
172+
173+ /**
174+ * @var non-empty-string $name
175+ * @var FileUpload $uploads
176+ */
177+ foreach ($ message ->getUploads () as $ name => $ uploads ) {
178+ $ uploadedFiles [$ name ] = [
179+ 'name ' => $ uploads ->getName (),
180+ 'mime ' => $ uploads ->getMime (),
181+ 'size ' => $ uploads ->getSize (),
182+ 'error ' => $ uploads ->getError (),
183+ 'tmpName ' => $ uploads ->getTempFilename (),
184+ ];
185+ }
186+
187+ \parse_str ($ message ->getRawQuery (), $ query );
188+ return new Request (
189+ remoteAddr: $ message ->getRemoteAddr (),
190+ protocol: $ message ->getProtocol (),
191+ method: $ message ->getMethod (),
192+ uri: $ message ->getUri (),
193+ headers: $ this ->filterHeaders ($ headers ),
194+ cookies: \array_map (
195+ static fn (array $ values ) => \implode (', ' , $ values ),
196+ $ this ->headerValueToArray ($ message ->getCookies ()),
197+ ),
198+ uploads: $ uploadedFiles ,
199+ attributes: [
200+ Request::PARSED_BODY_ATTRIBUTE_NAME => $ message ->getParsed (),
201+ ] + \iterator_to_array ($ message ->getAttributes ()),
202+ query: $ query ,
203+ // todo rawBody?
204+ body: $ message ->getBody (),
205+ parsed: $ message ->getParsed (),
206+ );
207+ }
208+
157209 /**
158210 * Remove all non-string and empty-string keys
159211 *
@@ -164,7 +216,7 @@ private function filterHeaders(array $headers): array
164216 {
165217 foreach ($ headers as $ key => $ _ ) {
166218 if (!\is_string ($ key ) || $ key === '' ) {
167- // ignore invalid header names or values (otherwise, the worker will be crashed)
219+ // ignore invalid header names or values (otherwise, the worker might be crashed)
168220 // @see: <https://git.io/JzjgJ>
169221 unset($ headers [$ key ]);
170222 }
@@ -173,4 +225,22 @@ private function filterHeaders(array $headers): array
173225 /** @var HeadersList $headers */
174226 return $ headers ;
175227 }
228+
229+ /**
230+ * @param \Traversable<non-empty-string, HeaderValue> $message
231+ * @return HeadersList
232+ */
233+ private function headerValueToArray (\Traversable $ message ): array
234+ {
235+ $ result = [];
236+ /**
237+ * @var non-empty-string $key
238+ * @var HeaderValue $value
239+ */
240+ foreach ($ message as $ key => $ value ) {
241+ $ result [$ key ] = \iterator_to_array ($ value ->getValue ());
242+ }
243+
244+ return $ result ;
245+ }
176246}
0 commit comments