2018-11-20 13:50:37 +00:00
|
|
|
<?php
|
|
|
|
|
|
2018-11-21 11:13:40 +00:00
|
|
|
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Http\Controllers;
|
2018-11-20 13:50:37 +00:00
|
|
|
|
2018-11-24 00:53:20 +00:00
|
|
|
use BeyondCode\LaravelWebSockets\ClientProviders\Client;
|
2018-11-22 20:36:25 +00:00
|
|
|
use Exception;
|
2018-11-21 11:13:40 +00:00
|
|
|
use Illuminate\Http\Request;
|
2018-11-22 20:36:25 +00:00
|
|
|
use GuzzleHttp\Psr7 as gPsr;
|
|
|
|
|
use GuzzleHttp\Psr7\Response;
|
2018-11-20 13:50:37 +00:00
|
|
|
use Ratchet\ConnectionInterface;
|
|
|
|
|
use Illuminate\Http\JsonResponse;
|
2018-11-21 11:13:40 +00:00
|
|
|
use GuzzleHttp\Psr7\ServerRequest;
|
2018-11-20 13:50:37 +00:00
|
|
|
use Ratchet\Http\HttpServerInterface;
|
|
|
|
|
use Psr\Http\Message\RequestInterface;
|
2018-11-22 20:36:25 +00:00
|
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
2018-11-21 11:13:40 +00:00
|
|
|
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
2018-11-22 23:24:40 +00:00
|
|
|
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager;
|
2018-11-20 13:50:37 +00:00
|
|
|
|
|
|
|
|
abstract class EchoController implements HttpServerInterface
|
|
|
|
|
{
|
2018-11-22 23:24:40 +00:00
|
|
|
/** @var \BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager */
|
|
|
|
|
protected $channelManager;
|
|
|
|
|
|
|
|
|
|
public function __construct(ChannelManager $channelManager)
|
|
|
|
|
{
|
|
|
|
|
$this->channelManager = $channelManager;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-22 20:36:25 +00:00
|
|
|
public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)
|
2018-11-20 13:50:37 +00:00
|
|
|
{
|
2018-11-21 11:13:40 +00:00
|
|
|
$queryParameters = [];
|
|
|
|
|
parse_str($request->getUri()->getQuery(), $queryParameters);
|
|
|
|
|
|
|
|
|
|
$serverRequest = (new ServerRequest(
|
|
|
|
|
$request->getMethod(),
|
|
|
|
|
$request->getUri(),
|
|
|
|
|
$request->getHeaders(),
|
|
|
|
|
$request->getBody(),
|
|
|
|
|
$request->getProtocolVersion()
|
|
|
|
|
))->withQueryParams($queryParameters);
|
|
|
|
|
|
2018-11-22 20:36:25 +00:00
|
|
|
$laravelRequest = Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest));
|
|
|
|
|
|
|
|
|
|
$this->verifyAppId($laravelRequest->appId);
|
2018-11-24 14:36:13 +00:00
|
|
|
$this->verifySignature($laravelRequest);
|
2018-11-22 20:36:25 +00:00
|
|
|
|
|
|
|
|
$response = $this($laravelRequest);
|
|
|
|
|
|
|
|
|
|
$connection->send(JsonResponse::create($response)->send());
|
|
|
|
|
$connection->close();
|
2018-11-20 13:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onMessage(ConnectionInterface $from, $msg)
|
|
|
|
|
{
|
2018-11-21 23:10:47 +00:00
|
|
|
}
|
|
|
|
|
|
2018-11-22 20:36:25 +00:00
|
|
|
function onClose(ConnectionInterface $connection)
|
2018-11-21 23:10:47 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-22 20:36:25 +00:00
|
|
|
function onError(ConnectionInterface $connection, Exception $exception)
|
|
|
|
|
{
|
2018-11-24 00:53:20 +00:00
|
|
|
if ($exception instanceof HttpException) {
|
2018-11-22 21:02:36 +00:00
|
|
|
$response = new Response($exception->getStatusCode(), [
|
|
|
|
|
'Content-Type' => 'application/json'
|
|
|
|
|
], json_encode([
|
|
|
|
|
'error' => $exception->getMessage()
|
|
|
|
|
]));
|
2018-11-22 20:36:25 +00:00
|
|
|
|
2018-11-24 14:23:59 +00:00
|
|
|
$connection->send(gPsr\str($response));
|
2018-11-22 20:36:25 +00:00
|
|
|
$connection->close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function verifyAppId(string $appId)
|
2018-11-21 23:10:47 +00:00
|
|
|
{
|
2018-11-24 00:53:20 +00:00
|
|
|
if ($client = Client::findByAppId($appId)) {
|
|
|
|
|
return;
|
2018-11-22 20:36:25 +00:00
|
|
|
}
|
2018-11-24 00:53:20 +00:00
|
|
|
|
|
|
|
|
throw new HttpException(401, "Unknown app id `{$appId}` provided.");
|
2018-11-20 13:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
2018-11-24 14:36:13 +00:00
|
|
|
protected function verifySignature(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$bodyMd5 = md5($request->getContent());
|
|
|
|
|
|
|
|
|
|
$signature =
|
|
|
|
|
"{$request->getMethod()}\n/{$request->path()}\n".
|
|
|
|
|
"auth_key={$request->get('auth_key')}".
|
|
|
|
|
"&auth_timestamp={$request->get('auth_timestamp')}".
|
|
|
|
|
"&auth_version={$request->get('auth_version')}".
|
|
|
|
|
"&body_md5={$bodyMd5}";
|
|
|
|
|
|
|
|
|
|
$authSignature = hash_hmac('sha256', $signature, Client::findByAppId($request->get('appId'))->appSecret);
|
|
|
|
|
|
|
|
|
|
if ($authSignature !== $request->get('auth_signature')) {
|
|
|
|
|
throw new HttpException(401, 'Invalid auth signature provided.');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-21 11:13:40 +00:00
|
|
|
abstract public function __invoke(Request $request);
|
2018-11-20 13:50:37 +00:00
|
|
|
}
|