diff --git a/src/HttpApi/Controllers/Controller.php b/src/HttpApi/Controllers/Controller.php index 43f2ebd..92315c2 100644 --- a/src/HttpApi/Controllers/Controller.php +++ b/src/HttpApi/Controllers/Controller.php @@ -9,6 +9,7 @@ use GuzzleHttp\Psr7\Response; use Ratchet\ConnectionInterface; use Illuminate\Http\JsonResponse; use GuzzleHttp\Psr7\ServerRequest; +use Illuminate\Support\Collection; use Ratchet\Http\HttpServerInterface; use Psr\Http\Message\RequestInterface; use BeyondCode\LaravelWebSockets\Apps\App; @@ -19,6 +20,15 @@ use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager; abstract class Controller implements HttpServerInterface { + /** @var string */ + protected $requestBuffer = ''; + + /** @var RequestInterface */ + protected $request; + + /** @var int */ + protected $contentLength; + /** @var \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager */ protected $channelManager; @@ -29,28 +39,51 @@ abstract class Controller implements HttpServerInterface public function onOpen(ConnectionInterface $connection, RequestInterface $request = null) { - $serverRequest = (new ServerRequest( - $request->getMethod(), - $request->getUri(), - $request->getHeaders(), - $request->getBody(), - $request->getProtocolVersion() - ))->withQueryParams(QueryParameters::create($request)->all()); + $this->request = $request; - $laravelRequest = Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest)); + $this->contentLength = $this->findContentLength($request->getHeaders()); - $this - ->ensureValidAppId($laravelRequest->appId) - ->ensureValidSignature($laravelRequest); + $this->requestBuffer = (string)$request->getBody(); - $response = $this($laravelRequest); + $this->checkContentLength($connection); + } - $connection->send(JsonResponse::create($response)); - $connection->close(); + protected function findContentLength(array $headers): int + { + return Collection::make($headers)->first(function ($values, $header) { + return strtolower($header) === 'content-length'; + }); } public function onMessage(ConnectionInterface $from, $msg) { + $this->requestBuffer .= $msg; + + $this->checkContentLength(); + } + + protected function checkContentLength(ConnectionInterface $connection) + { + if (strlen($this->requestBuffer) === $this->contentLength) { + $serverRequest = (new ServerRequest( + $this->request->getMethod(), + $this->request->getUri(), + $this->request->getHeaders(), + $this->requestBuffer, + $this->request->getProtocolVersion() + ))->withQueryParams(QueryParameters::create($this->request)->all()); + + $laravelRequest = Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest)); + + $this + ->ensureValidAppId($laravelRequest->appId) + ->ensureValidSignature($laravelRequest); + + $response = $this($laravelRequest); + + $connection->send(JsonResponse::create($response)); + $connection->close(); + } } public function onClose(ConnectionInterface $connection)