Skip to content

Both Server and StreamingServer accept middleware arrays #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,8 @@ passed explicitly.

### Middleware

As documented above, the [`StreamingServer`](#streamingserver) accepts a single
As documented above, the [`Server`](#server) and advanced
[`StreamingServer`](#streamingserver) accept a single
request handler argument that is responsible for processing an incoming
HTTP request and then creating and returning an outgoing HTTP response.

Expand Down Expand Up @@ -704,12 +705,13 @@ required to match PHP's request behavior (see below) and otherwise actively
encourages [Third-Party Middleware](#third-party-middleware) implementations.

In order to use middleware request handlers, simply pass an array with all
callables as defined above to the [`StreamingServer`](#streamingserver).
callables as defined above to the [`Server`](#server) or
[`StreamingServer`](#streamingserver) respectively.
The following example adds a middleware request handler that adds the current time to the request as a
header (`Request-Time`) and a final request handler that always returns a 200 code without a body:

```php
$server = new StreamingServer(array(
$server = new Server(array(
function (ServerRequestInterface $request, callable $next) {
$request = $request->withHeader('Request-Time', time());
return $next($request);
Expand Down Expand Up @@ -740,7 +742,7 @@ The following example shows how this middleware can be used to ensure no more
than 10 handlers will be invoked at once:

```php
$server = new StreamingServer(array(
$server = new Server(array(
new LimitConcurrentRequestsMiddleware(10),
$handler
));
Expand Down
19 changes: 15 additions & 4 deletions src/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ final class Server extends EventEmitter
/**
* @see StreamingServer::__construct()
*/
public function __construct($callback)
public function __construct($requestHandler)
{
if (!is_callable($callback)) {
throw new \InvalidArgumentException();
if (!is_callable($requestHandler) && !is_array($requestHandler)) {
throw new \InvalidArgumentException('Invalid request handler given');
}

$middleware = array();
Expand All @@ -66,7 +66,14 @@ public function __construct($callback)
if ($enablePostDataReading !== '') {
$middleware[] = new RequestBodyParserMiddleware();
}
$middleware[] = $callback;

if (is_callable($requestHandler)) {
$middleware[] = $requestHandler;
} else {
foreach ($requestHandler as $one) {
$middleware[] = $one;
}
}

$this->streamingServer = new StreamingServer($middleware);

Expand All @@ -84,6 +91,10 @@ public function listen(ServerInterface $server)
$this->streamingServer->listen($server);
}

/**
* @return int
* @codeCoverageIgnore
*/
private function getConcurrentRequestsLimit()
{
if (ini_get('memory_limit') == -1) {
Expand Down
6 changes: 3 additions & 3 deletions src/StreamingServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ final class StreamingServer extends EventEmitter
*/
public function __construct($requestHandler)
{
if (is_array($requestHandler)) {
$requestHandler = new MiddlewareRunner($requestHandler);
if (!is_callable($requestHandler) && !is_array($requestHandler)) {
throw new \InvalidArgumentException('Invalid request handler given');
} elseif (!is_callable($requestHandler)) {
throw new \InvalidArgumentException();
$requestHandler = new MiddlewareRunner($requestHandler);
}

$this->callback = $requestHandler;
Expand Down
65 changes: 65 additions & 0 deletions tests/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,71 @@ public function setUp()
$this->socket = new SocketServerStub();
}

/**
* @expectedException InvalidArgumentException
*/
public function testInvalidCallbackFunctionLeadsToException()
{
new Server('invalid');
}

public function testSimpleRequestCallsRequestHandlerOnce()
{
$called = null;
$server = new Server(function (ServerRequestInterface $request) use (&$called) {
++$called;
});

$server->listen($this->socket);
$this->socket->emit('connection', array($this->connection));
$this->connection->emit('data', array("GET / HTTP/1.0\r\n\r\n"));

$this->assertSame(1, $called);
}

/**
* @requires PHP 5.4
*/
public function testSimpleRequestCallsArrayRequestHandlerOnce()
{
$this->called = null;
$server = new Server(array($this, 'helperCallableOnce'));

$server->listen($this->socket);
$this->socket->emit('connection', array($this->connection));
$this->connection->emit('data', array("GET / HTTP/1.0\r\n\r\n"));

$this->assertSame(1, $this->called);
}

public function helperCallableOnce()
{
++$this->called;
}

public function testSimpleRequestWithMiddlewareArrayProcessesMiddlewareStack()
{
$called = null;
$server = new Server(array(
function (ServerRequestInterface $request, $next) use (&$called) {
$called = 'before';
$ret = $next($request->withHeader('Demo', 'ok'));
$called .= 'after';

return $ret;
},
function (ServerRequestInterface $request) use (&$called) {
$called .= $request->getHeaderLine('Demo');
}
));

$server->listen($this->socket);
$this->socket->emit('connection', array($this->connection));
$this->connection->emit('data', array("GET / HTTP/1.0\r\n\r\n"));

$this->assertSame('beforeokafter', $called);
}

public function testPostFileUpload()
{
$loop = Factory::create();
Expand Down
22 changes: 22 additions & 0 deletions tests/StreamingServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,28 @@ public function testRequestEventIsEmitted()
$this->connection->emit('data', array($data));
}

/**
* @requires PHP 5.4
*/
public function testRequestEventIsEmittedForArrayCallable()
{
$this->called = null;
$server = new StreamingServer(array($this, 'helperCallableOnce'));

$server->listen($this->socket);
$this->socket->emit('connection', array($this->connection));

$data = $this->createGetRequest();
$this->connection->emit('data', array($data));

$this->assertEquals(1, $this->called);
}

public function helperCallableOnce()
{
++$this->called;
}

public function testRequestEvent()
{
$i = 0;
Expand Down