Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Added Swoole emitter
Browse files Browse the repository at this point in the history
  • Loading branch information
ezimuel committed Jun 5, 2018
1 parent 6ffa7f6 commit 08a46aa
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 0 deletions.
84 changes: 84 additions & 0 deletions src/Response/SwooleEmitter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* @see https://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2015-2018 Zend Technologies USA Inc. (http://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.
*
* @param ResponseInterface $response
*/
public function emit(ResponseInterface $response)
{
$this->emitStatusCode($response);
$this->emitHeaders($response);
$this->emitBody($response);
}

/**
* Emit the message body.
*
* @param ResponseInterface $response
*/
private function emitBody(ResponseInterface $response)
{
$body = $response->getBody();
$body->rewind();
if ($body->getSize() > static::CHUNK_SIZE) {
while (! $body->eof()) {
$this->swooleResponse->write($body->read(static::CHUNK_SIZE));
}
$this->swooleResponse->end();
} else {
$this->swooleResponse->end($body->getContents());
}
}

/**
* Emit the headers
*
* @param ResponseInterface $response
*/
private function emitHeaders(ResponseInterface $response)
{
foreach ($response->getHeaders() as $name => $values) {
$name = $this->filterHeader($name);
$this->swooleResponse->header($name, implode(', ', $values));
}
}

/**
* Emit the status code
*
* @param ResponseInterface $response
*/
private function emitStatusCode(ResponseInterface $response)
{
$this->swooleResponse->status($response->getStatusCode());
}
}
87 changes: 87 additions & 0 deletions test/Response/SwooleEmitterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
/**
* @see https://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2015-2017 Zend Technologies USA Inc. (http://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()
{
$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();
}
}

0 comments on commit 08a46aa

Please sign in to comment.