Skip to content

Commit

Permalink
Replace Request class with PSR-7 Request
Browse files Browse the repository at this point in the history
  • Loading branch information
legionth committed Mar 17, 2017
1 parent aaca3fb commit e21acf2
Show file tree
Hide file tree
Showing 9 changed files with 481 additions and 433 deletions.
4 changes: 2 additions & 2 deletions examples/01-hello-world.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

use React\EventLoop\Factory;
use React\Socket\Server;
use React\Http\Request;
use React\Http\Response;
use Psr\Http\Message\RequestInterface;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();
$socket = new Server(isset($argv[1]) ? $argv[1] : '0.0.0.0:0', $loop);

$server = new \React\Http\Server($socket, function (Request $request, Response $response) {
$server = new \React\Http\Server($socket, function (RequestInterface $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello world!\n");
});
Expand Down
4 changes: 2 additions & 2 deletions examples/02-hello-world-https.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use React\EventLoop\Factory;
use React\Socket\Server;
use React\Http\Request;
use React\Http\Response;
use React\Socket\SecureServer;
use Psr\Http\Message\RequestInterface;

require __DIR__ . '/../vendor/autoload.php';

Expand All @@ -14,7 +14,7 @@
'local_cert' => isset($argv[2]) ? $argv[2] : __DIR__ . '/localhost.pem'
));

$server = new \React\Http\Server($socket, function (Request $request, Response $response) {
$server = new \React\Http\Server($socket, function (RequestInterface $request, Response $response) {
$response->writeHead(200, array('Content-Type' => 'text/plain'));
$response->end("Hello world!\n");
});
Expand Down
10 changes: 5 additions & 5 deletions examples/03-handling-body-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@

use React\EventLoop\Factory;
use React\Socket\Server;
use React\Http\Request;
use React\Http\Response;
use Psr\Http\Message\RequestInterface;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();
$socket = new Server(isset($argv[1]) ? $argv[1] : '0.0.0.0:0', $loop);

$server = new \React\Http\Server($socket, function (Request $request, Response $response) {
$server = new \React\Http\Server($socket, function (RequestInterface $request, Response $response) {
$contentLength = 0;
$request->on('data', function ($data) use (&$contentLength) {
$request->getBody()->on('data', function ($data) use (&$contentLength) {
$contentLength += strlen($data);
});

$request->on('end', function () use ($response, &$contentLength){
$request->getBody()->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) {
$request->getBody()->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);
});
Expand Down
173 changes: 173 additions & 0 deletions src/HttpBodyStream.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php
namespace React\Http;

use Psr\Http\Message\StreamInterface;
use React\Stream\ReadableStreamInterface;
use React\Stream\WritableStreamInterface;
use Evenement\EventEmitter;
use React\Stream\Util;

/**
* @internal
* Uses a StreamInterface from PSR-7 and a ReadableStreamInterface from ReactPHP
* to use PSR-7 objects and use ReactPHP streams
* This is class is used in `HttpServer` to stream the body of a response
* to the client. Because of this you can stream big amount of data without
* necessity of buffering this data. The data will be send directly to the client.
*/
class HttpBodyStream extends EventEmitter implements StreamInterface, ReadableStreamInterface
{
private $input;
private $closed = false;
private $size;

/**
* @param ReadableStreamInterface $input - Stream data from $stream as a body of a PSR-7 object4
* @þaram int|null $size - size of the data body
*/
public function __construct(ReadableStreamInterface $input, $size)
{
$this->input = $input;
$this->size = $size;

$this->input->on('data', array($this, 'handleData'));
$this->input->on('end', array($this, 'handleEnd'));
$this->input->on('error', array($this, 'handleError'));
$this->input->on('close', array($this, 'close'));
}

public function isReadable()
{
return !$this->closed && $this->input->isReadable();
}

public function pause()
{
$this->input->pause();
}

public function resume()
{
$this->input->resume();
}

public function pipe(WritableStreamInterface $dest, array $options = array())
{
Util::pipe($this, $dest, $options);

return $dest;
}

public function close()
{
if ($this->closed) {
return;
}

$this->closed = true;

$this->input->close();

$this->emit('close');
$this->removeAllListeners();
}

public function getSize()
{
return $this->size;
}

/** @ignore */
public function __toString()
{
return '';
}

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

/** @ignore */
public function tell()
{
throw new \BadMethodCallException();
}

/** @ignore */
public function eof()
{
throw new \BadMethodCallException();
}

/** @ignore */
public function isSeekable()
{
return false;
}

/** @ignore */
public function seek($offset, $whence = SEEK_SET)
{
throw new \BadMethodCallException();
}

/** @ignore */
public function rewind()
{
throw new \BadMethodCallException();
}

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

/** @ignore */
public function write($string)
{
throw new \BadMethodCallException();
}

/** @ignore */
public function read($length)
{
throw new \BadMethodCallException();
}

/** @ignore */
public function getContents()
{
return '';
}

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

/** @internal */
public function handleData($data)
{
$this->emit('data', array($data));
}

/** @internal */
public function handleError(\Exception $e)
{
$this->emit('error', array($e));
$this->close();
}

/** @internal */
public function handleEnd()
{
if (!$this->closed) {
$this->emit('end');
$this->close();
}
}
}
Loading

0 comments on commit e21acf2

Please sign in to comment.