Skip to content

Commit bf1c01c

Browse files
committed
Upgrade react/http
1 parent cdede39 commit bf1c01c

File tree

7 files changed

+1056
-237
lines changed

7 files changed

+1056
-237
lines changed

Bootstraps/BootstrapInterface.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace PHPPM\Bootstraps;
4+
5+
/**
6+
* All application bootstraps must implement this interface
7+
*/
8+
interface BootstrapInterface
9+
{
10+
public function getApplication();
11+
}

Bootstraps/Drupal.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,6 @@ public function initialize($appenv, $debug)
3838
$this->debug = $debug;
3939
}
4040

41-
/**
42-
* @return string
43-
*/
44-
public function getStaticDirectory() {
45-
return './';
46-
}
47-
4841
/**
4942
* Create a Drupal application.
5043
*/

Bootstraps/Laravel.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,6 @@ public function initialize($appenv, $debug)
3939
putenv("APP_ENV=" . $this->appenv);
4040
}
4141

42-
/**
43-
* {@inheritdoc}
44-
*/
45-
public function getStaticDirectory() {
46-
return 'public/';
47-
}
48-
4942
/**
5043
* {@inheritdoc}
5144
*/

Bootstraps/Symfony.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,6 @@ public function initialize($appenv, $debug)
3333
$this->debug = $debug;
3434
}
3535

36-
/**
37-
* @return string
38-
*/
39-
public function getStaticDirectory()
40-
{
41-
return 'web/';
42-
}
43-
4436
/**
4537
* Create a Symfony application
4638
*
@@ -58,9 +50,10 @@ public function getApplication()
5850

5951
//since we need to change some services, we need to manually change some services
6052
$app = new \AppKernel($this->appenv, $this->debug);
53+
// We need to change some services, before the boot, because they would
54+
// otherwise be instantiated and passed to other classes which makes it
55+
// impossible to replace them.
6156

62-
//we need to change some services, before the boot, because they would otherwise
63-
//be instantiated and passed to other classes which makes it impossible to replace them.
6457
Utils::bindAndCall(function() use ($app) {
6558
// init bundles
6659
$app->initializeBundles();

Bridges/HttpKernel.php

Lines changed: 51 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
use PHPPM\Bootstraps\BootstrapInterface;
77
use PHPPM\Bootstraps\HooksInterface;
88
use PHPPM\Bootstraps\RequestClassProviderInterface;
9-
use PHPPM\React\HttpResponse;
109
use PHPPM\Utils;
1110
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;
1314
use Symfony\Component\HttpFoundation\Cookie;
1415
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
1516
use 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
/**

composer.json

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
{
22
"name": "php-pm/httpkernel-adapter",
3+
"minimum-stability": "dev",
4+
"prefer-stable": true,
35
"require": {
6+
"php-pm/php-pm": "dev-master",
47
"symfony/http-foundation": "^2.6|^3.0",
58
"symfony/http-kernel": "^2.6|^3.0",
6-
"php-pm/php-pm": "dev-react-0.8"
9+
"ringcentral/psr7": "^1.2"
710
},
811
"autoload": {
912
"psr-4": {
1013
"PHPPM\\": ""
1114
}
12-
},
13-
"repositories": [
14-
{
15-
"type": "vcs",
16-
"url": "https://github.com/andig/php-pm"
17-
}
18-
]
15+
}
1916
}

0 commit comments

Comments
 (0)