Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
legionth committed Mar 17, 2017
1 parent e21acf2 commit ca091f8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 73 deletions.
107 changes: 36 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ Event-driven, streaming plaintext HTTP and secure HTTPS server for [ReactPHP](ht
* [Usage](#usage)
* [Server](#server)
* [Request](#request)
* [getMethod()](#getmethod)
* [getQueryParams()](#getqueryparams)
* [getProtocolVersion()](#getprotocolversion)
* [getHeaders()](#getheaders)
* [getHeader()](#getheader)
* [getHeaderLine()](#getheaderline)
* [hasHeader()](#hasheader)
* [Response](#response)
* [writeHead()](#writehead)
* [Install](#install)
Expand All @@ -31,7 +24,7 @@ This is an HTTP server which responds with `Hello World` to every request.
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server(8080, $loop);

$http = new Server($socket, function (Request $request, Response $response) {
$http = new Server($socket, function (RequestInterface $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello World!\n");
});
Expand Down Expand Up @@ -59,7 +52,7 @@ constructor with the respective [`Request`](#request) and
```php
$socket = new React\Socket\Server(8080, $loop);

$http = new Server($socket, function (Request $request, Response $response) {
$http = new Server($socket, function (RequestInterface $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello World!\n");
});
Expand All @@ -75,7 +68,7 @@ $socket = new React\Socket\SecureServer($socket, $loop, array(
'local_cert' => __DIR__ . '/localhost.pem'
));

$http = new Server($socket, function (Request $request, Response $response) {
$http = new Server($socket, function (RequestInterface $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello World!\n");
});
Expand Down Expand Up @@ -110,94 +103,66 @@ for more details.

### Request

The `Request` class is responsible for streaming the incoming request body
and contains meta data which was parsed from the request headers.
If the request body is chunked-encoded, the data will be decoded and emitted on the data event.
The `Transfer-Encoding` header will be removed.
A HTTP request will be sent by a client to the [Server](#server).
The `Server` will receive this request on the `data` event and
is responsible to create a request object from this data.
This object will be passed to the callback function.

The request is an instance of [PSR-7 RequestInterface](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md#32-psrhttpmessagerequestinterface).

```php
$http = new Server($socket, function (RequestInterface $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->write("Request method: " . $request->getMethod() . "\n");
if ($request->getBody()->getSize() !== null) {
$response->write("Request body size: " . $request->getBody()->getSize() . "\n");
}
$response->end("The requested path is: " . $request->getUri()->getPath());
});
```

It implements the `ReadableStreamInterface`.
The `getBody()` method returns an instance of a [ReactPHP ReadableStreamInterface](https://github.com/reactphp/stream#readablestreaminterface)
which implements the [PSR-7 StreamInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagestreaminterface).

Listen on the `data` event and the `end` event of the [Request](#request)
Some functions of the `PSR-7 StreamInterface` are not used:
`tell`, `eof`, `seek`, `rewind`, `write` and `read`.
These methods SHOULD NOT be called, because these are not compatible
with the `ReactPHP ReadableStreamInterface`.

Listen on the `data` event and the `end` event of the body of the [Request](#request)
to evaluate the data of the request body:

```php
$http = new Server($socket, function (Request $request, Response $response) {
$http = new Server($socket, function (RequestInterface $request, Response $response) {
$contentLength = 0;
$request->on('data', function ($data) use (&$contentLength) {
$body = $request->getBody();
$body->on('data', function ($data) use (&$contentLength) {
$contentLength += strlen($data);
});

$request->on('end', function () use ($response, &$contentLength){
$body->on('end', function () use ($response, &$contentLength){
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("The length of the submitted request body is: " . $contentLength);
});

// an error occures e.g. on invalid chunked encoded data or an unexpected 'end' event
$request->on('error', function (\Exception $exception) use ($response, &$contentLength) {
$body->on('error', function (\Exception $exception) use ($response, &$contentLength) {
$response->writeHead(400, array('Content-Type' => 'text/plain'));
$response->end("An error occured while reading at length: " . $contentLength);
});
});
```

If the request body is chunked-encoded, the data will be decoded and emitted on the data event.
The `Transfer-Encoding` header will be removed.

An error will just `pause` the connection instead of closing it. A response message
can still be sent.

A `close` event will be emitted after an `error` or `end` event.

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.

#### getMethod()

The `getMethod(): string` method can be used to
return the request method.

#### getPath()

The `getPath(): string` method can be used to
return the request path.

#### getQueryParams()

The `getQueryParams(): array` method can be used to
return an array with all query parameters ($_GET).

#### getProtocolVersion()

The `getProtocolVersion(): string` method can be used to
return the HTTP protocol version (such as "1.0" or "1.1").

#### getHeaders()

The `getHeaders(): array` method can be used to
return an array with ALL headers.

The keys represent the header name in the exact case in which they were
originally specified. The values will be an array of strings for each
value for the respective header name.

#### getHeader()

The `getHeader(string $name): string[]` method can be used to
retrieve a message header value by the given case-insensitive name.

Returns a list of all values for this header name or an empty array if header was not found

#### getHeaderLine()

The `getHeaderLine(string $name): string` method can be used to
retrieve a comma-separated string of the values for a single header.

Returns a comma-separated list of all values for this header name or an empty string if header was not found

#### hasHeader()

The `hasHeader(string $name): bool` method can be used to
check if a header exists by the given case-insensitive name.

### Response

The `Response` class is responsible for streaming the outgoing response body.
Expand Down
4 changes: 2 additions & 2 deletions src/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* ```php
* $socket = new React\Socket\Server(8080, $loop);
*
* $http = new Server($socket, function (Request $request, Response $response) {
* $http = new Server($socket, function (RequestInterface $request, Response $response) {
* $response->writeHead(200, array('Content-Type' => 'text/plain'));
* $response->end("Hello World!\n");
* });
Expand All @@ -38,7 +38,7 @@
* 'local_cert' => __DIR__ . '/localhost.pem'
* ));
*
* $http = new Server($socket, function (Request $request, Response $response) {
* $http = new Server($socket, function (RequestInterface $request, Response $response) {
* $response->writeHead(200, array('Content-Type' => 'text/plain'));
* $response->end("Hello World!\n");
* });
Expand Down

0 comments on commit ca091f8

Please sign in to comment.