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

Commit

Permalink
Merge 66c56a0 into 26efe24
Browse files Browse the repository at this point in the history
  • Loading branch information
ezimuel committed Jun 12, 2018
2 parents 26efe24 + 66c56a0 commit 154e920
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 3 deletions.
11 changes: 10 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,45 @@ matrix:
- php: 7
env:
- DEPS=lowest
- INSTALL_SWOOLE=true
- php: 7
env:
- DEPS=locked
- CHECK_CS=true
- TEST_COVERAGE=true
- INSTALL_SWOOLE=true
- php: 7
env:
- DEPS=latest
- INSTALL_SWOOLE=true
- php: 7.1
env:
- DEPS=lowest
- INSTALL_SWOOLE=true
- php: 7.1
env:
- DEPS=locked
- INSTALL_SWOOLE=true
- php: 7.1
env:
- DEPS=latest
- INSTALL_SWOOLE=true
- php: 7.2
env:
- DEPS=lowest
- INSTALL_SWOOLE=true
- php: 7.2
env:
- DEPS=locked
- INSTALL_SWOOLE=true
- php: 7.2
env:
- DEPS=latest
- INSTALL_SWOOLE=true

before_install:
- if [[ $TEST_COVERAGE != 'true' && "$(php --version | grep xdebug -ci)" -ge 1 ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
- travis_retry composer self-update
- if [[ $INSTALL_SWOOLE == 'true' ]]; then ./.travis/install_swoole.sh ; fi

install:
- travis_retry composer install $COMPOSER_ARGS --ignore-platform-reqs
Expand Down
10 changes: 10 additions & 0 deletions .travis/install_swoole.sh
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
16 changes: 16 additions & 0 deletions doc/book/swoole.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Swoole

[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 a static
method 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).

This method is as follows:

```
Zend\Diactoros\ServerRequestFactory::fromSwoole(swoole_http_request $request)
```

Where `$request` is an instance of `swoole_http_request` (alias of
`Swoole\Http\Request`).
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pages:
- "Emitting Responses": emitting-responses.md
- Serialization: serialization.md
- API: api.md
- Swoole: swoole.md
site_name: zend-diactoros
site_description: 'zend-diactoros: PSR-7 HTTP message implementation'
repo_url: 'https://github.com/zendframework/zend-diactoros'
Expand Down
50 changes: 49 additions & 1 deletion src/ServerRequestFactory.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<?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)
* @copyright Copyright (c) 2015-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;

use InvalidArgumentException;
use Psr\Http\Message\UploadedFileInterface;
use RuntimeException;
use stdClass;
use swoole_http_request;
use UnexpectedValueException;

use function array_change_key_case;
Expand Down Expand Up @@ -99,6 +101,52 @@ public static function fromGlobals(
);
}

/**
* Create a request from a Swoole request
*
* @param swoole_http_request $request
* @return ServerRequest
* @throws RuntimeException if Swoole is not installed
*/

public static function fromSwoole(swoole_http_request $request)
{
if (! extension_loaded('swoole')) {
throw new Exception\RuntimeException('Swoole extension is not installed!');
}
$get = isset($request->get) ? $request->get : [];
$post = isset($request->post) ? $request->post : [];
$cookie = isset($request->cookie) ? $request->cookie : [];
$files = isset($request->files) ? $request->files : [];

$server = [];
if (isset($request->server)) {
foreach ($request->server as $key => $value) {
$server[strtoupper($key)] = $value;
}
}

$headers = [];
if (isset($request->header)) {
foreach ($request->header as $name => $value) {
$headers[str_replace('-', '_', $name)] = $value;
}
}

return new ServerRequest(
$server,
static::normalizeFiles($files),
static::marshalUriFromServer($server, $headers),
isset($server['REQUEST_METHOD']) ? $server['REQUEST_METHOD'] : 'GET',
new SwooleStream($request),
$headers,
$cookie,
$get,
$post,
static::marshalProtocolVersion($server)
);
}

/**
* Access a value in an array, returning a default value if not found
*
Expand Down
189 changes: 189 additions & 0 deletions src/SwooleStream.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?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 Zend\Diactoros;

use Psr\Http\Message\StreamInterface;
use RuntimeException;
use swoole_http_request;

class SwooleStream implements StreamInterface
{
/**
* @var string
*/
protected $body;

/**
* @var int
*/
protected $bodySize;

/**
* @var int
*/
protected $index = 0;

public function __construct(swoole_http_request $request)
{
$this->request = $request;
}

/**
* {@inheritdoc}
*/
public function getContents()
{
if (! isset($this->body)) {
$this->body = $this->request->rawcontent();
}
return $this->body;
}

/**
* {@inheritdoc}
*/
public function __toString()
{
return $this->getContents();
}

/**
* {@inheritdoc}
*/
public function getSize()
{
if (! isset($this->bodySize)) {
$this->bodySize = strlen($this->getContents());
}
return $this->bodySize;
}

/**
* {@inheritdoc}
*/
public function tell()
{
return $this->index;
}

/**
* {@inheritdoc}
*/
public function eof()
{
return $this->index >= $this->getSize() - 1;
}

/**
* {@inheritdoc}
*/
public function isReadable()
{
return true;
}

/**
* {@inheritdoc}
*/
public function read($length)
{
$result = substr($this->getContents(), $this->index, $length);
$this->index += $length;
return $result;
}

/**
* {@inheritdoc}
*/
public function isSeekable()
{
return true;
}

/**
* {@inheritdoc}
*/
public function seek($offset, $whence = SEEK_SET)
{

switch ($whence) {
case SEEK_SET:
if ($offset >= $this->getSize()) {
throw new RuntimeException(
'Offset cannot be longer than content size'
);
}
$this->index = $offset;
break;
case SEEK_CUR:
if ($offset + $this->index >= $this->getSize()) {
throw new RuntimeException(
'Offset + current position cannot be longer than content size'
);
}
$this->index += $offset;
break;
case SEEK_END:
if ($offset + $this->getSize() >= $this->getSize()) {
throw new RuntimeException(
'Offset must be a negative number to be under the content size'
);
}
$this->index = $this->getSize() - 1 + $offset;
break;
}
}

/**
* {@inheritdoc}
*/
public function rewind()
{
$this->index = 0;
}

/**
* {@inheritdoc}
*/
public function isWritable()
{
return false;
}

/**
* {@inheritdoc}
*/
public function write($string)
{
throw new RuntimeException('Stream is not writable');
}

/**
* {@inheritdoc}
*/
public function getMetadata($key = null)
{
return null;
}

/**
* {@inheritdoc}
*/
public function detach()
{
return null;
}

/**
* {@inheritdoc}
*/
public function close()
{
return null;
}
}
33 changes: 32 additions & 1 deletion test/ServerRequestFactoryTest.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?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)
* @copyright Copyright (c) 2015-2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
*/

Expand All @@ -10,6 +10,7 @@
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
use ReflectionProperty;
use swoole_http_request;
use UnexpectedValueException;
use Zend\Diactoros\ServerRequest;
use Zend\Diactoros\ServerRequestFactory;
Expand Down Expand Up @@ -580,4 +581,34 @@ public function marshalProtocolVersionProvider()
'HTTP/2' => ['HTTP/2', '2'],
];
}

public function testFromSwoole()
{
if (! extension_loaded('swoole')) {
$this->markTestSkipped('The Swoole extension is not available');
}

$swooleRequest = $this->createMock(swoole_http_request::class);
$swooleRequest->header['host'] = 'localhost:9501';
$swooleRequest->server['request_method'] = 'GET';
$swooleRequest->server['request_uri'] = '/';
$swooleRequest->server['path_info'] = '/';
$swooleRequest->server['request_time'] = time();
$swooleRequest->server['server_protocol'] = 'HTTP/1.1';
$swooleRequest->server['server_port'] = 9501;
$swooleRequest->server['remote_port'] = 45314;
$swooleRequest->method('rawContent')->willReturn('some content');

$request = ServerRequestFactory::fromSwoole($swooleRequest);
$this->assertInstanceOf(ServerRequest::class, $request);
$this->assertEquals('GET', $request->getMethod());
$this->assertEquals('/', $request->getRequestTarget());
$this->assertEquals('/', $request->getUri()->getPath());
$this->assertEquals('1.1', $request->getProtocolVersion());
$this->assertEquals('some content', $request->getBody());
$this->assertEquals([], $request->getCookieParams());
$this->assertEquals([], $request->getQueryParams());
$this->assertEquals([], $request->getUploadedFiles());
$this->assertEquals(['host' => ['localhost:9501']], $request->getHeaders());
}
}
Loading

0 comments on commit 154e920

Please sign in to comment.