66use PHPPM \Bootstraps \BootstrapInterface ;
77use PHPPM \Bootstraps \HooksInterface ;
88use PHPPM \Bootstraps \RequestClassProviderInterface ;
9- use PHPPM \React \HttpResponse ;
109use PHPPM \Utils ;
1110use React \EventLoop \LoopInterface ;
12- use React \Http \Request as ReactRequest ;
11+ use Psr \Http \Message \ServerRequestInterface ;
12+ use Psr \Http \Message \ResponseInterface ;
13+ use RingCentral \Psr7 ;
1314use Symfony \Component \HttpFoundation \Cookie ;
1415use Symfony \Component \HttpFoundation \Request as SymfonyRequest ;
1516use Symfony \Component \HttpFoundation \Response as SymfonyResponse ;
@@ -43,7 +44,7 @@ class HttpKernel implements BridgeInterface
4344 * @param string $appBootstrap The name of the class used to bootstrap the application
4445 * @param string|null $appenv The environment your application will use to bootstrap (if any)
4546 * @param boolean $debug If debug is enabled
46- * @see http://stackphp.com
47+ * @param LoopInterface $loop Event loop
4748 */
4849 public function bootstrap ($ appBootstrap , $ appenv , $ debug , LoopInterface $ loop )
4950 {
@@ -61,23 +62,11 @@ public function bootstrap($appBootstrap, $appenv, $debug, LoopInterface $loop)
6162 /**
6263 * {@inheritdoc}
6364 */
64- public function getStaticDirectory ()
65- {
66- return $ this ->bootstrap ->getStaticDirectory ();
67- }
68-
69- /**
70- * Handle a request using a HttpKernelInterface implementing application.
71- *
72- * @param ReactRequest $request
73- * @param HttpResponse $response
74- *
75- * @throws \Exception
76- */
77- public function onRequest (ReactRequest $ request , HttpResponse $ response )
65+ public function handle (ServerRequestInterface $ request )
7866 {
7967 if (null === $ this ->application ) {
80- return ;
68+ // internal server error
69+ return new Psr7 \Response (500 , ['Content-type ' => 'text/plain ' ], 'Application not configured during bootstrap ' );
8170 }
8271
8372 $ syRequest = $ this ->mapRequest ($ request );
@@ -94,18 +83,18 @@ public function onRequest(ReactRequest $request, HttpResponse $response)
9483
9584 $ syResponse = $ this ->application ->handle ($ syRequest );
9685 } catch (\Exception $ exception ) {
97- $ response -> writeHead ( 500 ); // internal server error
98- $ response-> end ( );
86+ // internal server error
87+ $ response = new Psr7 \ Response ( 500 , [ ' Content-type ' => ' text/plain ' ], $ exception -> getMessage () );
9988
10089 // end buffering if we need to throw
10190 @ob_end_clean ();
102- throw $ exception ;
91+ return $ response ;
10392 }
10493
10594 // should not receive output from application->handle()
10695 @ob_end_clean ();
10796
108- $ this ->mapResponse ($ response , $ syResponse );
97+ $ response = $ this ->mapResponse ($ syResponse );
10998
11099 if ($ this ->application instanceof TerminableInterface) {
111100 $ this ->application ->terminate ($ syRequest , $ syResponse );
@@ -114,6 +103,8 @@ public function onRequest(ReactRequest $request, HttpResponse $response)
114103 if ($ this ->bootstrap instanceof HooksInterface) {
115104 $ this ->bootstrap ->postHandle ($ this ->application );
116105 }
106+
107+ return $ response ;
117108 }
118109
119110 /**
@@ -122,48 +113,51 @@ public function onRequest(ReactRequest $request, HttpResponse $response)
122113 * @param ReactRequest $reactRequest
123114 * @return SymfonyRequest $syRequest
124115 */
125- protected function mapRequest (ReactRequest $ reactRequest )
116+ protected function mapRequest (ServerRequestInterface $ psrRequest )
126117 {
127- $ method = $ reactRequest ->getMethod ();
128- $ headers = $ reactRequest ->getHeaders ();
129- $ query = $ reactRequest ->getQuery ();
118+ $ method = $ psrRequest ->getMethod ();
119+ $ query = $ psrRequest ->getQueryParams ();
130120
121+ // cookies
131122 $ _COOKIE = [];
132-
133123 $ sessionCookieSet = false ;
124+ $ headersCookie = explode ('; ' , $ psrRequest ->getHeaderLine ('Cookie ' ));
134125
135- if (isset ($ headers ['Cookie ' ]) || isset ($ headers ['cookie ' ])) {
136- $ headersCookie = explode ('; ' , isset ($ headers ['Cookie ' ]) ? $ headers ['Cookie ' ] : $ headers ['cookie ' ]);
137- foreach ($ headersCookie as $ cookie ) {
138- list ($ name , $ value ) = explode ('= ' , trim ($ cookie ));
139- $ _COOKIE [$ name ] = $ value ;
126+ foreach ($ headersCookie as $ cookie ) {
127+ list ($ name , $ value ) = explode ('= ' , trim ($ cookie ));
128+ $ _COOKIE [$ name ] = $ value ;
140129
141- if ($ name === session_name ()) {
142- session_id ($ value );
143- $ sessionCookieSet = true ;
144- }
130+ if ($ name === session_name ()) {
131+ session_id ($ value );
132+ $ sessionCookieSet = true ;
145133 }
146134 }
147135
148136 if (!$ sessionCookieSet && session_id ()) {
149- //session id already set from the last round but not got from the cookie header,
150- //so generate a new one, since php is not doing it automatically with session_start() if session
151- //has already been started.
137+ // session id already set from the last round but not obtained
138+ // from the cookie header, so generate a new one, since php is
139+ // not doing it automatically with session_start() if session
140+ // has already been started.
152141 session_id (Utils::generateSessionId ());
153142 }
154143
155- $ files = $ reactRequest ->getFiles ();
156- $ post = $ reactRequest ->getPost ();
144+ // files
145+ $ files = $ psrRequest ->getUploadedFiles ();
146+
147+ // @todo check howto handle additional headers
148+
149+ // @todo check howto support other HTTP methods with bodies
150+ $ post = $ psrRequest ->getParsedBody () ?: array ();
157151
158152 if ($ this ->bootstrap instanceof RequestClassProviderInterface) {
159153 $ class = $ this ->bootstrap ->requestClass ();
160154 }
161155 else {
162- $ class = ' \Symfony\Component\HttpFoundation\Request ' ;
156+ $ class = SymfonyRequest::class ;
163157 }
164158
165159 /** @var SymfonyRequest $syRequest */
166- $ syRequest = new $ class ($ query , $ post , $ attributes = [], $ _COOKIE , $ files , $ _SERVER , $ reactRequest ->getBody ());
160+ $ syRequest = new $ class ($ query , $ post , $ attributes = [], $ _COOKIE , $ files , $ _SERVER , $ psrRequest ->getBody ());
167161
168162 $ syRequest ->setMethod ($ method );
169163
@@ -173,10 +167,10 @@ protected function mapRequest(ReactRequest $reactRequest)
173167 /**
174168 * Convert Symfony\Component\HttpFoundation\Response to React\Http\Response
175169 *
176- * @param HttpResponse $reactResponse
177170 * @param SymfonyResponse $syResponse
171+ « @return ResponseInterface
178172 */
179- protected function mapResponse (HttpResponse $ reactResponse , SymfonyResponse $ syResponse )
173+ protected function mapResponse (SymfonyResponse $ syResponse )
180174 {
181175 // end active session
182176 if (PHP_SESSION_ACTIVE === session_status ()) {
@@ -241,33 +235,27 @@ protected function mapResponse(HttpResponse $reactResponse, SymfonyResponse $syR
241235 $ headers ['Set-Cookie ' ] = $ cookies ;
242236 }
243237
244- if ($ syResponse instanceof SymfonyStreamedResponse) {
245- $ reactResponse ->writeHead ($ syResponse ->getStatusCode (), $ headers );
246-
247- // asynchronously get content
248- ob_start (function ($ buffer ) use ($ reactResponse ) {
249- $ reactResponse ->write ($ buffer );
250- return '' ;
251- }, 4096 );
238+ $ psrResponse = new Psr7 \Response ($ syResponse ->getStatusCode (), $ headers );
252239
240+ // get contents
241+ ob_start ();
242+ if ($ syResponse instanceof SymfonyStreamedResponse) {
253243 $ syResponse ->sendContent ();
254-
255- // flush remaining content
256- @ob_end_flush ();
257- $ reactResponse ->end ();
244+ $ content = @ob_get_clean ();
258245 }
259246 else {
260247 ob_start ();
261248 $ content = $ syResponse ->getContent ();
262249 @ob_end_flush ();
250+ }
263251
264- if (!isset ($ headers ['Content-Length ' ])) {
265- $ headers ['Content-Length ' ] = strlen ($ content );
266- }
267-
268- $ reactResponse ->writeHead ($ syResponse ->getStatusCode (), $ headers );
269- $ reactResponse ->end ($ content );
252+ if (!isset ($ headers ['Content-Length ' ])) {
253+ $ psrResponse = $ psrResponse ->withAddedHeader ('Content-Length ' , strlen ($ content ));
270254 }
255+
256+ $ psrResponse = $ psrResponse ->withBody (Psr7 \stream_for ($ content ));
257+
258+ return $ psrResponse ;
271259 }
272260
273261 /**
0 commit comments