| Server IP : 34.87.99.72 / Your IP : 216.73.217.31 Web Server : Apache/2.4.46 (Unix) OpenSSL/1.1.1n System : Linux zlock-bitnami-lamp-prod-v2-vm 4.19.0-16-cloud-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 User : bitnami ( 1000) PHP Version : 7.4.18 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /opt/bitnami/apache/htdocs/app/vendor/react/http/src/Middleware/ |
Upload File : |
<?php
namespace React\Http\Middleware;
use OverflowException;
use Psr\Http\Message\ServerRequestInterface;
use React\Http\Io\BufferedBody;
use React\Http\Io\IniUtil;
use React\Promise\Promise;
use React\Stream\ReadableStreamInterface;
final class RequestBodyBufferMiddleware
{
private $sizeLimit;
/**
* @param int|string|null $sizeLimit Either an int with the max request body size
* in bytes or an ini like size string
* or null to use post_max_size from PHP's
* configuration. (Note that the value from
* the CLI configuration will be used.)
*/
public function __construct($sizeLimit = null)
{
if ($sizeLimit === null) {
$sizeLimit = \ini_get('post_max_size');
}
$this->sizeLimit = IniUtil::iniSizeToBytes($sizeLimit);
}
public function __invoke(ServerRequestInterface $request, $next)
{
$body = $request->getBody();
$size = $body->getSize();
// happy path: skip if body is known to be empty (or is already buffered)
if ($size === 0 || !$body instanceof ReadableStreamInterface || !$body->isReadable()) {
// replace with empty body if body is streaming (or buffered size exceeds limit)
if ($body instanceof ReadableStreamInterface || $size > $this->sizeLimit) {
$request = $request->withBody(new BufferedBody(''));
}
return $next($request);
}
// request body of known size exceeding limit
$sizeLimit = $this->sizeLimit;
if ($size > $this->sizeLimit) {
$sizeLimit = 0;
}
/** @var ?\Closure $closer */
$closer = null;
return new Promise(function ($resolve, $reject) use ($body, &$closer, $sizeLimit, $request, $next) {
// buffer request body data in memory, discard but keep buffering if limit is reached
$buffer = '';
$bufferer = null;
$body->on('data', $bufferer = function ($data) use (&$buffer, $sizeLimit, $body, &$bufferer) {
$buffer .= $data;
// On buffer overflow keep the request body stream in,
// but ignore the contents and wait for the close event
// before passing the request on to the next middleware.
if (isset($buffer[$sizeLimit])) {
assert($bufferer instanceof \Closure);
$body->removeListener('data', $bufferer);
$bufferer = null;
$buffer = '';
}
});
// call $next with current buffer and resolve or reject with its results
$body->on('close', $closer = function () use (&$buffer, $request, $resolve, $reject, $next) {
try {
// resolve with result of next handler
$resolve($next($request->withBody(new BufferedBody($buffer))));
} catch (\Exception $e) {
$reject($e);
} catch (\Throwable $e) { // @codeCoverageIgnoreStart
// reject Errors just like Exceptions (PHP 7+)
$reject($e); // @codeCoverageIgnoreEnd
}
});
// reject buffering if body emits error
$body->on('error', function (\Exception $e) use ($reject, $body, $closer) {
// remove close handler to avoid resolving, then close and reject
assert($closer instanceof \Closure);
$body->removeListener('close', $closer);
$body->close();
$reject(new \RuntimeException(
'Error while buffering request body: ' . $e->getMessage(),
$e->getCode(),
$e
));
});
}, function () use ($body, &$closer) {
// cancelled buffering: remove close handler to avoid resolving, then close and reject
assert($closer instanceof \Closure);
$body->removeListener('close', $closer);
$body->close();
throw new \RuntimeException('Cancelled buffering request body');
});
}
}