Skip to content
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
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server(8080, $loop);

$http = new React\Http\Server($socket);
$http->on('request', function ($request, $response) {
$http->on('request', function (Request $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello World!\n");
});
Expand All @@ -39,7 +39,30 @@ See also the [examples](examples).

### Server

See the above usage example and the class outline for details.
The `Server` class is responsible for handling incoming connections and then
emit a `request` event for each incoming HTTP request.

It attaches itself to an instance of `React\Socket\ServerInterface` which
emits underlying streaming connections in order to then parse incoming data
as HTTP:

```php
$socket = new React\Socket\Server(8080, $loop);

$http = new React\Http\Server($socket);
```

For each incoming connection, it emits a `request` event with the respective
[`Request`](#request) and [`Response`](#response) objects:

```php
$http->on('request', function (Request $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello World!\n");
});
```

See also [`Request`](#request) and [`Response`](#response) for more details.

### Request

Expand All @@ -48,6 +71,9 @@ and contains meta data which was parsed from the request headers.

It implements the `ReadableStreamInterface`.

The constructor is internal, you SHOULD NOT call this yourself.
The `Server` is responsible for emitting `Request` and `Response` objects.

See the above usage example and the class outline for details.

#### getHeaders()
Expand Down Expand Up @@ -101,6 +127,9 @@ The `Response` class is responsible for streaming the outgoing response body.

It implements the `WritableStreamInterface`.

The constructor is internal, you SHOULD NOT call this yourself.
The `Server` is responsible for emitting `Request` and `Response` objects.

See the above usage example and the class outline for details.

#### writeContinue()
Expand Down
23 changes: 23 additions & 0 deletions src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
use React\Stream\WritableStreamInterface;
use React\Stream\Util;

/**
* The `Request` class is responsible for streaming the incoming request body
* and contains meta data which was parsed from the request headers.
*
* It implements the `ReadableStreamInterface`.
*
* The constructor is internal, you SHOULD NOT call this yourself.
* The `Server` is responsible for emitting `Request` and `Response` objects.
*
* See the usage examples and the class outline for details.
*
* @see ReadableStreamInterface
* @see Server
*/
class Request extends EventEmitter implements ReadableStreamInterface
{
private $readable = true;
Expand All @@ -19,6 +33,15 @@ class Request extends EventEmitter implements ReadableStreamInterface
// metadata, implicitly added externally
public $remoteAddress;

/**
* The constructor is internal, you SHOULD NOT call this yourself.
*
* The `Server` is responsible for emitting `Request` and `Response` objects.
*
* Constructor parameters may change at any time.
*
* @internal
*/
public function __construct($method, $path, $query = array(), $httpVersion = '1.1', $headers = array())
{
$this->method = $method;
Expand Down
6 changes: 4 additions & 2 deletions src/RequestHeaderParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
/**
* @event headers
* @event error
*
* @internal
*/
class RequestHeaderParser extends EventEmitter
{
Expand Down Expand Up @@ -43,13 +45,13 @@ public function feed($data)
}
}

protected function parseAndEmitRequest()
private function parseAndEmitRequest()
{
list($request, $bodyBuffer) = $this->parseRequest($this->buffer);
$this->emit('headers', array($request, $bodyBuffer));
}

public function parseRequest($data)
private function parseRequest($data)
{
list($headers, $bodyBuffer) = explode("\r\n\r\n", $data, 2);

Expand Down
22 changes: 22 additions & 0 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
use React\Socket\ConnectionInterface;
use React\Stream\WritableStreamInterface;

/**
* The `Response` class is responsible for streaming the outgoing response body.
*
* It implements the `WritableStreamInterface`.
*
* The constructor is internal, you SHOULD NOT call this yourself.
* The `Server` is responsible for emitting `Request` and `Response` objects.
*
* See the usage examples and the class outline for details.
*
* @see WritableStreamInterface
* @see Server
*/
class Response extends EventEmitter implements WritableStreamInterface
{
private $closed = false;
Expand All @@ -14,6 +27,15 @@ class Response extends EventEmitter implements WritableStreamInterface
private $headWritten = false;
private $chunkedEncoding = true;

/**
* The constructor is internal, you SHOULD NOT call this yourself.
*
* The `Server` is responsible for emitting `Request` and `Response` objects.
*
* Constructor parameters may change at any time.
*
* @internal
*/
public function __construct(ConnectionInterface $conn)
{
$this->conn = $conn;
Expand Down
2 changes: 2 additions & 0 deletions src/ResponseCodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

/**
* This is copy-pasted from Symfony2's Response class
*
* @internal
*/
class ResponseCodes
{
Expand Down
42 changes: 41 additions & 1 deletion src/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,50 @@
use React\Socket\ServerInterface as SocketServerInterface;
use React\Socket\ConnectionInterface;

/** @event request */
/**
* The `Server` class is responsible for handling incoming connections and then
* emit a `request` event for each incoming HTTP request.
*
* ```php
* $socket = new React\Socket\Server(8080, $loop);
*
* $http = new React\Http\Server($socket);
* ```
*
* For each incoming connection, it emits a `request` event with the respective
* [`Request`](#request) and [`Response`](#response) objects:
*
* ```php
* $http->on('request', function (Request $request, Response $response) {
* $response->writeHead(200, array('Content-Type' => 'text/plain'));
* $response->end("Hello World!\n");
* });
* ```
*
* See also [`Request`](#request) and [`Response`](#response) for more details.
*
* @see Request
* @see Response
*/
class Server extends EventEmitter
{
private $io;

/**
* Creates a HTTP server that accepts connections from the given socket.
*
* It attaches itself to an instance of `React\Socket\ServerInterface` which
* emits underlying streaming connections in order to then parse incoming data
* as HTTP:
*
* ```php
* $socket = new React\Socket\Server(8080, $loop);
*
* $http = new React\Http\Server($socket);
* ```
*
* @param \React\Socket\ServerInterface $io
*/
public function __construct(SocketServerInterface $io)
{
$this->io = $io;
Expand Down Expand Up @@ -54,6 +93,7 @@ public function __construct(SocketServerInterface $io)
});
}

/** @internal */
public function handleRequest(ConnectionInterface $conn, Request $request, $bodyBuffer)
{
$response = new Response($conn);
Expand Down