This repository has been archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
353 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/bin/bash | ||
pecl install swoole << EOF | ||
`#enable debug/trace log support? [no] :` | ||
`#enable sockets supports? [no] :`y | ||
`#enable openssl support? [no] :` | ||
`#enable http2 support? [no] :` | ||
`#enable async-redis support? [no] :` | ||
`#enable mysqlnd support? [no] :` | ||
`#enable postgresql coroutine client support? [no] :` | ||
EOF |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Swoole | ||
use Zend\Diactoros\ServerRequestFactory; | ||
|
||
[Swoole](https://www.swoole.co.uk/) is an async programming Framework for PHP | ||
that can be used to create high performance HTTP server applications, e.g. web | ||
APIs. We provided the support of Swoole in `zend-diactoros` using two methods to | ||
convert a [Swoole\Http\Request](http://php.net/manual/en/class.swoole-http-request.php) | ||
in a [PSR-7 Request](https://www.php-fig.org/psr/psr-7/#32-psrhttpmessagerequestinterface) | ||
and a [PSR-7 Response](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface) | ||
in a [Swoole\Http\Response](http://php.net/manual/en/class.swoole-http-response.php). | ||
|
||
To convert a Swoole request in PSR-7 we provided the following static function: | ||
|
||
``` | ||
Zend\Diactoros\ServerRequestFactory::fromSwoole(swoole_http_request $request) | ||
``` | ||
|
||
Where `$request` is an instance of `swoole_http_request` (alias of | ||
`Swoole\Http\Request`). | ||
|
||
To convert a PSR-7 response in a Swoole response we built a specific emitter, | ||
`Zend\Diactoros\Response\SwooleEmitter`. If you can use this emitter instead of | ||
`Zend\Diactoros\Response\SapiEmitter`. | ||
|
||
You need to instantiate the `SwooleEmitter` passing a `swoole_http_response` | ||
object in the constructor. | ||
|
||
You can execute Swoole with [Expressive](https://getexpressive.org/) using the | ||
following server implementation: | ||
|
||
```php | ||
use Zend\Diactoros\ServerRequestFactory; | ||
use Zend\Diactoros\Response\SwooleEmitter; | ||
|
||
$http = new swoole_http_server("127.0.0.1", 9501); | ||
|
||
$http->on("start", function ($server) { | ||
echo "Swoole http server is started at http://127.0.0.1:9501\n"; | ||
}); | ||
|
||
// Bootstrap of zend-expressive | ||
$container = require 'config/container.php'; | ||
$app = $container->get(\Zend\Expressive\Application::class); | ||
|
||
$http->on("request", function ($request, $response) use ($app) { | ||
$psr7Request = ServerRequestFactory::fromSwoole($request); | ||
$psr7Response = $app->handle($psr7Request); | ||
|
||
$emitter = new SwooleEmitter($response); | ||
$emitter->emit($psr7Response); | ||
}); | ||
|
||
$http->start(); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?php | ||
/** | ||
* @see https://github.com/zendframework/zend-diactoros for the canonical source repository | ||
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com) | ||
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License | ||
*/ | ||
|
||
namespace Zend\Diactoros\Response; | ||
|
||
use Psr\Http\Message\ResponseInterface; | ||
use swoole_http_response; | ||
|
||
/** | ||
* @deprecated since 1.8.0. The package zendframework/zend-httphandlerrunner | ||
* now provides this functionality. | ||
*/ | ||
class SwooleEmitter implements EmitterInterface | ||
{ | ||
use SapiEmitterTrait; | ||
|
||
/** | ||
* @see https://www.swoole.co.uk/docs/modules/swoole-http-server/methods-properties#swoole-http-response-write | ||
*/ | ||
const CHUNK_SIZE = 2097152; // 2 MB | ||
|
||
private $swooleResponse; | ||
|
||
public function __construct(swoole_http_response $swooleResponse) | ||
{ | ||
$this->swooleResponse = $swooleResponse; | ||
} | ||
|
||
/** | ||
* Emits a response for the Swoole environment. | ||
* | ||
* @return void | ||
*/ | ||
public function emit(ResponseInterface $response) | ||
{ | ||
$this->emitStatusCode($response); | ||
$this->emitHeaders($response); | ||
$this->emitBody($response); | ||
} | ||
|
||
/** | ||
* Emit the status code | ||
* | ||
* @return void | ||
*/ | ||
private function emitStatusCode(ResponseInterface $response) | ||
{ | ||
$this->swooleResponse->status($response->getStatusCode()); | ||
} | ||
|
||
/** | ||
* Emit the headers | ||
* | ||
* @return void | ||
*/ | ||
private function emitHeaders(ResponseInterface $response) | ||
{ | ||
foreach ($response->getHeaders() as $name => $values) { | ||
$name = $this->filterHeader($name); | ||
$this->swooleResponse->header($name, implode(', ', $values)); | ||
} | ||
} | ||
|
||
/** | ||
* Emit the message body. | ||
* | ||
* @return void | ||
*/ | ||
private function emitBody(ResponseInterface $response) | ||
{ | ||
$body = $response->getBody(); | ||
$body->rewind(); | ||
|
||
if ($body->getSize() <= static::CHUNK_SIZE) { | ||
$this->swooleResponse->end($body->getContents()); | ||
return; | ||
} | ||
|
||
while (! $body->eof()) { | ||
$this->swooleResponse->write($body->read(static::CHUNK_SIZE)); | ||
} | ||
$this->swooleResponse->end(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
/** | ||
* @see https://github.com/zendframework/zend-diactoros for the canonical source repository | ||
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com) | ||
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License | ||
*/ | ||
|
||
namespace ZendTest\Diactoros\Response; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use swoole_http_response; | ||
use Zend\Diactoros\Response; | ||
use Zend\Diactoros\Response\SwooleEmitter; | ||
|
||
class SwooleEmitterTest extends TestCase | ||
{ | ||
public function setUp() | ||
{ | ||
if (! extension_loaded('swoole')) { | ||
$this->markTestSkipped('The Swoole extension is not available'); | ||
} | ||
$this->swooleResponse = $this->prophesize(swoole_http_response::class); | ||
$this->emitter = new SwooleEmitter($this->swooleResponse->reveal()); | ||
} | ||
|
||
public function testEmit() | ||
{ | ||
$response = (new Response()) | ||
->withStatus(200) | ||
->withAddedHeader('Content-Type', 'text/plain'); | ||
$response->getBody()->write('Content!'); | ||
|
||
$this->emitter->emit($response); | ||
|
||
$this->swooleResponse | ||
->status(200) | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->header('Content-Type', 'text/plain') | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->end('Content!') | ||
->shouldHaveBeenCalled(); | ||
} | ||
|
||
public function testMultipleHeaders() | ||
{ | ||
$response = (new Response()) | ||
->withStatus(200) | ||
->withHeader('Content-Type', 'text/plain') | ||
->withHeader('Content-Length', '256'); | ||
|
||
$this->emitter->emit($response); | ||
|
||
$this->swooleResponse | ||
->status(200) | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->header('Content-Type', 'text/plain') | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->header('Content-Length', '256') | ||
->shouldHaveBeenCalled(); | ||
} | ||
|
||
public function testMultipleSetCookieHeaders() | ||
{ | ||
$response = (new Response()) | ||
->withStatus(200) | ||
->withAddedHeader('Set-Cookie', 'foo=bar') | ||
->withAddedHeader('Set-Cookie', 'bar=baz'); | ||
|
||
$this->emitter->emit($response); | ||
|
||
$this->swooleResponse | ||
->status(200) | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->header('Set-Cookie', 'foo=bar, bar=baz') | ||
->shouldHaveBeenCalled(); | ||
} | ||
|
||
public function testEmitWithBigContentBody() | ||
{ | ||
$content = base64_encode(random_bytes(SwooleEmitter::CHUNK_SIZE)); // CHUNK_SIZE * 1.33333 | ||
$response = (new Response()) | ||
->withStatus(200) | ||
->withAddedHeader('Content-Type', 'text/plain'); | ||
$response->getBody()->write($content); | ||
|
||
$this->emitter->emit($response); | ||
|
||
$this->swooleResponse | ||
->status(200) | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->header('Content-Type', 'text/plain') | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->write(substr($content, 0, SwooleEmitter::CHUNK_SIZE)) | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->write(substr($content, SwooleEmitter::CHUNK_SIZE)) | ||
->shouldHaveBeenCalled(); | ||
$this->swooleResponse | ||
->end() | ||
->shouldHaveBeenCalled(); | ||
} | ||
} |
Oops, something went wrong.