Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit 15e6b6a

Browse files
committed
Use content length check for requests split into multiple messages
1 parent 53691ce commit 15e6b6a

File tree

1 file changed

+47
-14
lines changed

1 file changed

+47
-14
lines changed

src/HttpApi/Controllers/Controller.php

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Ratchet\ConnectionInterface;
1010
use Illuminate\Http\JsonResponse;
1111
use GuzzleHttp\Psr7\ServerRequest;
12+
use Illuminate\Support\Collection;
1213
use Ratchet\Http\HttpServerInterface;
1314
use Psr\Http\Message\RequestInterface;
1415
use BeyondCode\LaravelWebSockets\Apps\App;
@@ -19,6 +20,15 @@
1920

2021
abstract class Controller implements HttpServerInterface
2122
{
23+
/** @var string */
24+
protected $requestBuffer = '';
25+
26+
/** @var RequestInterface */
27+
protected $request;
28+
29+
/** @var int */
30+
protected $contentLength;
31+
2232
/** @var \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager */
2333
protected $channelManager;
2434

@@ -29,28 +39,51 @@ public function __construct(ChannelManager $channelManager)
2939

3040
public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)
3141
{
32-
$serverRequest = (new ServerRequest(
33-
$request->getMethod(),
34-
$request->getUri(),
35-
$request->getHeaders(),
36-
$request->getBody(),
37-
$request->getProtocolVersion()
38-
))->withQueryParams(QueryParameters::create($request)->all());
42+
$this->request = $request;
3943

40-
$laravelRequest = Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest));
44+
$this->contentLength = $this->findContentLength($request->getHeaders());
4145

42-
$this
43-
->ensureValidAppId($laravelRequest->appId)
44-
->ensureValidSignature($laravelRequest);
46+
$this->requestBuffer = (string)$request->getBody();
4547

46-
$response = $this($laravelRequest);
48+
$this->checkContentLength($connection);
49+
}
4750

48-
$connection->send(JsonResponse::create($response));
49-
$connection->close();
51+
protected function findContentLength(array $headers): int
52+
{
53+
return Collection::make($headers)->first(function ($values, $header) {
54+
return strtolower($header) === 'content-length';
55+
});
5056
}
5157

5258
public function onMessage(ConnectionInterface $from, $msg)
5359
{
60+
$this->requestBuffer .= $msg;
61+
62+
$this->checkContentLength();
63+
}
64+
65+
protected function checkContentLength(ConnectionInterface $connection)
66+
{
67+
if (strlen($this->requestBuffer) === $this->contentLength) {
68+
$serverRequest = (new ServerRequest(
69+
$this->request->getMethod(),
70+
$this->request->getUri(),
71+
$this->request->getHeaders(),
72+
$this->requestBuffer,
73+
$this->request->getProtocolVersion()
74+
))->withQueryParams(QueryParameters::create($this->request)->all());
75+
76+
$laravelRequest = Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest));
77+
78+
$this
79+
->ensureValidAppId($laravelRequest->appId)
80+
->ensureValidSignature($laravelRequest);
81+
82+
$response = $this($laravelRequest);
83+
84+
$connection->send(JsonResponse::create($response));
85+
$connection->close();
86+
}
5487
}
5588

5689
public function onClose(ConnectionInterface $connection)

0 commit comments

Comments
 (0)