diff --git a/src/ServerRequestFactory.php b/src/ServerRequestFactory.php index 57cdc167..ecabc070 100644 --- a/src/ServerRequestFactory.php +++ b/src/ServerRequestFactory.php @@ -9,7 +9,9 @@ use InvalidArgumentException; use Psr\Http\Message\UploadedFileInterface; +use RuntimeException; use stdClass; +use swoole_http_request; use UnexpectedValueException; use function array_change_key_case; @@ -99,6 +101,48 @@ 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 = []; + foreach ($request->server as $key => $value) { + $server[strtoupper($key)] = $value; + } + + $headers = []; + foreach ($request->header as $name => $value) { + $headers[str_replace('-', '_', $name)] = $value; + } + + return new ServerRequest( + $server, + static::normalizeFiles($files), + static::marshalUriFromServer($server, $headers), + $server['REQUEST_METHOD'], + $request->rawContent(), + $headers, + $cookie, + $get, + $post, + static::marshalProtocolVersion($server) + ); + } + /** * Access a value in an array, returning a default value if not found * diff --git a/test/ServerRequestFactoryTest.php b/test/ServerRequestFactoryTest.php index 63f202e1..36b9f06b 100644 --- a/test/ServerRequestFactoryTest.php +++ b/test/ServerRequestFactoryTest.php @@ -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; @@ -580,4 +581,34 @@ public function marshalProtocolVersionProvider() 'HTTP/2' => ['HTTP/2', '2'], ]; } + + public function testFromSwoole() + { + if (! extension_loaded('swoole')) { + $this->markTestSkipped('The Swoole extesion 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('php://input'); + + $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('', $request->getBody()); + $this->assertEquals([], $request->getCookieParams()); + $this->assertEquals([], $request->getQueryParams()); + $this->assertEquals([], $request->getUploadedFiles()); + $this->assertEquals(['host' => ['localhost:9501']], $request->getHeaders()); + } }