85 lines
2.6 KiB
PHP
85 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\Mercureact\Http\Middleware;
|
|
|
|
use NoccyLabs\Mercureact\Broker\TopicManager;
|
|
use NoccyLabs\Mercureact\Configuration;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
use React\Http\Message\Response;
|
|
use React\Promise\Promise;
|
|
use React\Promise\PromiseInterface;
|
|
|
|
class ApiHandler
|
|
{
|
|
|
|
public function __construct(
|
|
private Configuration $config,
|
|
private TopicManager $topicManager
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param ServerRequestInterface $request
|
|
* @param callable $next
|
|
* @return PromiseInterface
|
|
*/
|
|
public function __invoke(ServerRequestInterface $request, callable $next): PromiseInterface
|
|
{
|
|
return new Promise(
|
|
function (callable $resolve, callable $reject) use ($next, $request) {
|
|
|
|
$path = $request->getUri()->getPath();
|
|
|
|
switch (true) {
|
|
case preg_match('<^/.well-known/mercure/subscriptions(/.+?){0,1}$>', $path, $m):
|
|
$query = explode("/", trim($m[1]??null, "/"));
|
|
$topic = array_shift($query);
|
|
$subscription = array_shift($query);
|
|
$resolve($this->apiGetSubscriptions($topic, $subscription));
|
|
return;
|
|
|
|
case preg_match('<^/.well-known/mercure/status$>', $path):
|
|
$resolve([
|
|
'server' => 'Mercureact/1.0',
|
|
'topics' => $this->topicManager->getTopicCount(),
|
|
'subscriptions' => $this->topicManager->getSubscriberCount(),
|
|
'memoryPeak' => memory_get_peak_usage(true),
|
|
'memoryUsage' => memory_get_usage(true)
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$resolve($next($request));
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @return ResponseInterface
|
|
*/
|
|
private function apiGetSubscriptions(string|null $topic, string|null $subscription): ResponseInterface
|
|
{
|
|
$subscriptions = $this->topicManager->getSubscriptions();
|
|
$lastEventId = $this->topicManager->getLastEventId();
|
|
$data = [
|
|
"@context" => "https://mercure.rocks/",
|
|
"id" => "/.well-known/mercure/subscriptions",
|
|
"type" => "Subscriptions",
|
|
"lastEventID" => $lastEventId,
|
|
"subscriptions" => $subscriptions
|
|
];
|
|
|
|
return Response::json($data)
|
|
->withHeader('Content-Type', 'application/ld+json')
|
|
->withHeader('ETag', $lastEventId);
|
|
}
|
|
|
|
}
|
|
|