11<?php
22
33/**
4- * High-performance PHP process supervisor and load balancer written in Go. Http core.
4+ * This file is part of RoadRunner package.
5+ *
6+ * For the full copyright and license information, please view the LICENSE
7+ * file that was distributed with this source code.
58 */
69
710declare (strict_types=1 );
1821
1922/**
2023 * Manages PSR-7 request and response.
24+ *
25+ * @psalm-import-type UploadedFile from Request
26+ * @psalm-import-type UploadedFilesList from Request
2127 */
22- class PSR7Worker
28+ class PSR7Worker implements PSR7WorkerInterface
2329{
24- private HttpWorker $ httpWorker ;
30+ /**
31+ * @var HttpWorker
32+ */
33+ private HttpWorker $ httpWorker ;
34+
35+ /**
36+ * @var ServerRequestFactoryInterface
37+ */
2538 private ServerRequestFactoryInterface $ requestFactory ;
26- private StreamFactoryInterface $ streamFactory ;
27- private UploadedFileFactoryInterface $ uploadsFactory ;
2839
29- /** @var mixed[] */
30- private array $ originalServer = [];
40+ /**
41+ * @var StreamFactoryInterface
42+ */
43+ private StreamFactoryInterface $ streamFactory ;
44+
45+ /**
46+ * @var UploadedFileFactoryInterface
47+ */
48+ private UploadedFileFactoryInterface $ uploadsFactory ;
3149
32- /** @var string[] Valid values for HTTP protocol version */
33- private static array $ allowedVersions = ['1.0 ' , '1.1 ' , '2 ' ,];
50+ /**
51+ * @var array
52+ */
53+ private array $ originalServer ;
3454
3555 /**
36- * @param WorkerInterface $worker
56+ * @var string[] Valid values for HTTP protocol version
57+ */
58+ private static array $ allowedVersions = ['1.0 ' , '1.1 ' , '2 ' ];
59+
60+ /**
61+ * @param WorkerInterface $worker
3762 * @param ServerRequestFactoryInterface $requestFactory
38- * @param StreamFactoryInterface $streamFactory
39- * @param UploadedFileFactoryInterface $uploadsFactory
63+ * @param StreamFactoryInterface $streamFactory
64+ * @param UploadedFileFactoryInterface $uploadsFactory
4065 */
4166 public function __construct (
4267 WorkerInterface $ worker ,
@@ -61,6 +86,7 @@ public function getWorker(): WorkerInterface
6186
6287 /**
6388 * @return ServerRequestInterface|null
89+ * @throws \JsonException
6490 */
6591 public function waitRequest (): ?ServerRequestInterface
6692 {
@@ -78,12 +104,13 @@ public function waitRequest(): ?ServerRequestInterface
78104 * Send response to the application server.
79105 *
80106 * @param ResponseInterface $response
107+ * @throws \JsonException
81108 */
82109 public function respond (ResponseInterface $ response ): void
83110 {
84111 $ this ->httpWorker ->respond (
85112 $ response ->getStatusCode (),
86- $ response ->getBody ()-> __toString (),
113+ ( string ) $ response ->getBody (),
87114 $ response ->getHeaders ()
88115 );
89116 }
@@ -93,51 +120,69 @@ public function respond(ResponseInterface $response): void
93120 * request-time and other values.
94121 *
95122 * @param Request $request
96- * @return mixed[]
123+ * @return non-empty-array<array-key|string, mixed|string>
97124 */
98125 protected function configureServer (Request $ request ): array
99126 {
100127 $ server = $ this ->originalServer ;
101128
102129 $ server ['REQUEST_URI ' ] = $ request ->uri ;
103- $ server ['REQUEST_TIME ' ] = time ();
104- $ server ['REQUEST_TIME_FLOAT ' ] = microtime ( true );
130+ $ server ['REQUEST_TIME ' ] = $ this -> timeInt ();
131+ $ server ['REQUEST_TIME_FLOAT ' ] = $ this -> timeFloat ( );
105132 $ server ['REMOTE_ADDR ' ] = $ request ->getRemoteAddr ();
106133 $ server ['REQUEST_METHOD ' ] = $ request ->method ;
107134
108135 $ server ['HTTP_USER_AGENT ' ] = '' ;
109136 foreach ($ request ->headers as $ key => $ value ) {
110- $ key = strtoupper (str_replace ('- ' , '_ ' , $ key ));
137+ $ key = \ strtoupper (\ str_replace ('- ' , '_ ' , $ key ));
111138 if (\in_array ($ key , ['CONTENT_TYPE ' , 'CONTENT_LENGTH ' ])) {
112- $ server [$ key ] = implode (', ' , $ value );
139+ $ server [$ key ] = \ implode (', ' , $ value );
113140 } else {
114- $ server ['HTTP_ ' . $ key ] = implode (', ' , $ value );
141+ $ server ['HTTP_ ' . $ key ] = \ implode (', ' , $ value );
115142 }
116143 }
117144
118145 return $ server ;
119146 }
120147
148+ /**
149+ * @return int
150+ */
151+ protected function timeInt (): int
152+ {
153+ return \time ();
154+ }
155+
156+ /**
157+ * @return float
158+ */
159+ protected function timeFloat (): float
160+ {
161+ return \microtime (true );
162+ }
163+
121164 /**
122165 * @param Request $httpRequest
123- * @param array $server
166+ * @param array $server
124167 * @return ServerRequestInterface
168+ * @throws \JsonException
125169 */
126170 protected function mapRequest (Request $ httpRequest , array $ server ): ServerRequestInterface
127171 {
128172 $ request = $ this ->requestFactory ->createServerRequest (
129173 $ httpRequest ->method ,
130174 $ httpRequest ->uri ,
131- $ _SERVER
175+ $ server
132176 );
133177
134-
135178 $ request = $ request
136179 ->withProtocolVersion (static ::fetchProtocolVersion ($ httpRequest ->protocol ))
137180 ->withCookieParams ($ httpRequest ->cookies )
138181 ->withQueryParams ($ httpRequest ->query )
139- ->withUploadedFiles ($ this ->wrapUploads ($ httpRequest ->uploads ));
182+ ->withUploadedFiles ($ this ->wrapUploads ($ httpRequest ->uploads ))
183+ ;
140184
185+ /** @psalm-suppress MixedAssignment */
141186 foreach ($ httpRequest ->attributes as $ name => $ value ) {
142187 $ request = $ request ->withAttribute ($ name , $ value );
143188 }
@@ -150,7 +195,7 @@ protected function mapRequest(Request $httpRequest, array $server): ServerReques
150195 return $ request ->withParsedBody ($ httpRequest ->getParsedBody ());
151196 }
152197
153- if ($ httpRequest ->body !== null ) {
198+ if ($ httpRequest ->body ) {
154199 return $ request ->withBody ($ this ->streamFactory ->createStream ($ httpRequest ->body ));
155200 }
156201
@@ -160,30 +205,32 @@ protected function mapRequest(Request $httpRequest, array $server): ServerReques
160205 /**
161206 * Wraps all uploaded files with UploadedFile.
162207 *
163- * @param array[] $files
208+ * @param UploadedFilesList $files
164209 * @return UploadedFileInterface[]|mixed[]
165210 */
166211 protected function wrapUploads (array $ files ): array
167212 {
168213 $ result = [];
169- foreach ($ files as $ index => $ f ) {
170- if (!isset ($ f ['name ' ])) {
171- $ result [$ index ] = $ this ->wrapUploads ($ f );
214+
215+ foreach ($ files as $ index => $ file ) {
216+ if (! isset ($ file ['name ' ])) {
217+ /** @psalm-var UploadedFilesList $file */
218+ $ result [$ index ] = $ this ->wrapUploads ($ file );
172219 continue ;
173220 }
174221
175- if (UPLOAD_ERR_OK === $ f ['error ' ]) {
176- $ stream = $ this ->streamFactory ->createStreamFromFile ($ f ['tmpName ' ]);
222+ if (\ UPLOAD_ERR_OK === $ file ['error ' ]) {
223+ $ stream = $ this ->streamFactory ->createStreamFromFile ($ file ['tmpName ' ]);
177224 } else {
178225 $ stream = $ this ->streamFactory ->createStream ();
179226 }
180227
181228 $ result [$ index ] = $ this ->uploadsFactory ->createUploadedFile (
182229 $ stream ,
183- $ f ['size ' ],
184- $ f ['error ' ],
185- $ f ['name ' ],
186- $ f ['mime ' ]
230+ $ file ['size ' ],
231+ $ file ['error ' ],
232+ $ file ['name ' ],
233+ $ file ['mime ' ]
187234 );
188235 }
189236
@@ -198,14 +245,14 @@ protected function wrapUploads(array $files): array
198245 */
199246 private static function fetchProtocolVersion (string $ version ): string
200247 {
201- $ v = substr ($ version , 5 );
248+ $ v = \ substr ($ version , 5 );
202249
203250 if ($ v === '2.0 ' ) {
204251 return '2 ' ;
205252 }
206253
207254 // Fallback for values outside of valid protocol versions
208- if (!in_array ($ v , static ::$ allowedVersions , true )) {
255+ if (! \ in_array ($ v , static ::$ allowedVersions , true )) {
209256 return '1.1 ' ;
210257 }
211258
0 commit comments