6
6
use PHPPM \Bootstraps \BootstrapInterface ;
7
7
use PHPPM \Bootstraps \HooksInterface ;
8
8
use PHPPM \Bootstraps \RequestClassProviderInterface ;
9
- use PHPPM \React \HttpResponse ;
10
9
use PHPPM \Utils ;
11
10
use 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 ;
13
14
use Symfony \Component \HttpFoundation \Cookie ;
14
15
use Symfony \Component \HttpFoundation \Request as SymfonyRequest ;
15
16
use Symfony \Component \HttpFoundation \Response as SymfonyResponse ;
@@ -43,7 +44,7 @@ class HttpKernel implements BridgeInterface
43
44
* @param string $appBootstrap The name of the class used to bootstrap the application
44
45
* @param string|null $appenv The environment your application will use to bootstrap (if any)
45
46
* @param boolean $debug If debug is enabled
46
- * @see http://stackphp.com
47
+ * @param LoopInterface $loop Event loop
47
48
*/
48
49
public function bootstrap ($ appBootstrap , $ appenv , $ debug , LoopInterface $ loop )
49
50
{
@@ -61,23 +62,11 @@ public function bootstrap($appBootstrap, $appenv, $debug, LoopInterface $loop)
61
62
/**
62
63
* {@inheritdoc}
63
64
*/
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 )
78
66
{
79
67
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 ' );
81
70
}
82
71
83
72
$ syRequest = $ this ->mapRequest ($ request );
@@ -94,18 +83,18 @@ public function onRequest(ReactRequest $request, HttpResponse $response)
94
83
95
84
$ syResponse = $ this ->application ->handle ($ syRequest );
96
85
} 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 () );
99
88
100
89
// end buffering if we need to throw
101
90
@ob_end_clean ();
102
- throw $ exception ;
91
+ return $ response ;
103
92
}
104
93
105
94
// should not receive output from application->handle()
106
95
@ob_end_clean ();
107
96
108
- $ this ->mapResponse ($ response , $ syResponse );
97
+ $ response = $ this ->mapResponse ($ syResponse );
109
98
110
99
if ($ this ->application instanceof TerminableInterface) {
111
100
$ this ->application ->terminate ($ syRequest , $ syResponse );
@@ -114,6 +103,8 @@ public function onRequest(ReactRequest $request, HttpResponse $response)
114
103
if ($ this ->bootstrap instanceof HooksInterface) {
115
104
$ this ->bootstrap ->postHandle ($ this ->application );
116
105
}
106
+
107
+ return $ response ;
117
108
}
118
109
119
110
/**
@@ -122,48 +113,51 @@ public function onRequest(ReactRequest $request, HttpResponse $response)
122
113
* @param ReactRequest $reactRequest
123
114
* @return SymfonyRequest $syRequest
124
115
*/
125
- protected function mapRequest (ReactRequest $ reactRequest )
116
+ protected function mapRequest (ServerRequestInterface $ psrRequest )
126
117
{
127
- $ method = $ reactRequest ->getMethod ();
128
- $ headers = $ reactRequest ->getHeaders ();
129
- $ query = $ reactRequest ->getQuery ();
118
+ $ method = $ psrRequest ->getMethod ();
119
+ $ query = $ psrRequest ->getQueryParams ();
130
120
121
+ // cookies
131
122
$ _COOKIE = [];
132
-
133
123
$ sessionCookieSet = false ;
124
+ $ headersCookie = explode ('; ' , $ psrRequest ->getHeaderLine ('Cookie ' ));
134
125
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 ;
140
129
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 ;
145
133
}
146
134
}
147
135
148
136
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.
152
141
session_id (Utils::generateSessionId ());
153
142
}
154
143
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 ();
157
151
158
152
if ($ this ->bootstrap instanceof RequestClassProviderInterface) {
159
153
$ class = $ this ->bootstrap ->requestClass ();
160
154
}
161
155
else {
162
- $ class = ' \Symfony\Component\HttpFoundation\Request ' ;
156
+ $ class = SymfonyRequest::class ;
163
157
}
164
158
165
159
/** @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 ());
167
161
168
162
$ syRequest ->setMethod ($ method );
169
163
@@ -173,10 +167,10 @@ protected function mapRequest(ReactRequest $reactRequest)
173
167
/**
174
168
* Convert Symfony\Component\HttpFoundation\Response to React\Http\Response
175
169
*
176
- * @param HttpResponse $reactResponse
177
170
* @param SymfonyResponse $syResponse
171
+ « @return ResponseInterface
178
172
*/
179
- protected function mapResponse (HttpResponse $ reactResponse , SymfonyResponse $ syResponse )
173
+ protected function mapResponse (SymfonyResponse $ syResponse )
180
174
{
181
175
// end active session
182
176
if (PHP_SESSION_ACTIVE === session_status ()) {
@@ -241,33 +235,27 @@ protected function mapResponse(HttpResponse $reactResponse, SymfonyResponse $syR
241
235
$ headers ['Set-Cookie ' ] = $ cookies ;
242
236
}
243
237
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 );
252
239
240
+ // get contents
241
+ ob_start ();
242
+ if ($ syResponse instanceof SymfonyStreamedResponse) {
253
243
$ syResponse ->sendContent ();
254
-
255
- // flush remaining content
256
- @ob_end_flush ();
257
- $ reactResponse ->end ();
244
+ $ content = @ob_get_clean ();
258
245
}
259
246
else {
260
247
ob_start ();
261
248
$ content = $ syResponse ->getContent ();
262
249
@ob_end_flush ();
250
+ }
263
251
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 ));
270
254
}
255
+
256
+ $ psrResponse = $ psrResponse ->withBody (Psr7 \stream_for ($ content ));
257
+
258
+ return $ psrResponse ;
271
259
}
272
260
273
261
/**
0 commit comments