Compare commits
2 commits
main
...
parallel-n
Author | SHA1 | Date | |
---|---|---|---|
|
f0e9043519 | ||
|
e2805beb16 |
4 changed files with 32 additions and 21 deletions
|
@ -10,14 +10,15 @@ Watch the video (YouTube):
|
|||
|
||||
# Nextcloud extension for WebDAV-Push
|
||||
|
||||
`nc_ext_dav_push` is a [Nextcloud](https://github.com/nextcloud/server) extension to demonstrate [WebDAV-Push](https://github.com/bitfireAT/webdav-push/) support on calendars (address books are not supported yet).
|
||||
`nc_ext_dav_push` is a [Nextcloud](https://github.com/nextcloud/server) extension to demonstrate [WebDAV-Push](https://github.com/bitfireAT/webdav-push/) support on calendars/address books.
|
||||
|
||||
It is the server part of our efforts to draft a WebDAV-Push standard and provide a working implementation (server + client) in order to demonstrate it.
|
||||
|
||||
> [!WARNING]
|
||||
> This extension is in an early stage of development. It is for demonstration and testing purposes only. Don't use it on production systems!
|
||||
**This extension is in a very early stage of development. It is for demonstration and testing purposes only. Don't use it on production systems!**
|
||||
|
||||
For instance, push subscriptions currently don't expire and won't be removed when they have become invalid. So the table will grow bigger and bigger and everything will become slow over time. You can however install/enable the extension to test it and disable or remove it again at any time. When the extension is disabled, it doesn't influence your system.
|
||||
For instance, push subscriptions currently don't expire, can't be deleted by clients and won't be removed when they have become invalid. So the table will grow bigger and bigger and everything will become slow over time.
|
||||
|
||||
You can however install/enable the extension to test it and disable or remove it again at any time. When the extension is disabled, it doesn't influence your system.
|
||||
|
||||
|
||||
## About WebDAV-Push
|
||||
|
|
|
@ -37,6 +37,7 @@ use OCA\DAV\Events\CardDeletedEvent;
|
|||
use OCA\DAV\Events\CardUpdatedEvent;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use GuzzleHttp\Promise;
|
||||
|
||||
use OCA\DavPush\Service\SubscriptionService;
|
||||
use OCA\DavPush\Transport\TransportManager;
|
||||
|
@ -59,13 +60,16 @@ class CalendarListener implements IEventListener {
|
|||
$collectionName = $event->getCalendarData()['uri'];
|
||||
$subscriptions = $this->subscriptionService->findAll($collectionName);
|
||||
|
||||
$notificationPromises = (function () use ($collectionName, $subscriptions): \Generator {
|
||||
foreach($subscriptions as $subscription) {
|
||||
$transport = $this->transportManager->getTransport($subscription->getTransport());
|
||||
try {
|
||||
$transport->notify($subscription->getUserId(), $collectionName, $subscription->getId());
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("transport " . $subscription->getTransport() . " failed to deliver notification to subscription " . $subscription->getId());
|
||||
}
|
||||
}
|
||||
yield $transport->notify($subscription->getUserId(), $collectionName, $subscription->getId());
|
||||
}
|
||||
})();
|
||||
|
||||
$responses = Promise\Utils::settle($notificationPromises)->wait();
|
||||
|
||||
// TODO: iterate over responses and log errors
|
||||
// $this->logger->error("transport " . $subscription->getTransport() . " failed to deliver notification to subscription " . $subscription->getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ use OCA\DavPush\Transport\Transport;
|
|||
use OCA\DavPush\Service\WebPushSubscriptionService;
|
||||
use OCA\DavPush\Errors\WebPushSubscriptionNotFound;
|
||||
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\Http\Client\IPromise;
|
||||
|
||||
use Sabre\Xml\Service;
|
||||
|
||||
class WebPushTransport extends Transport {
|
||||
|
@ -37,6 +40,7 @@ class WebPushTransport extends Transport {
|
|||
|
||||
public function __construct(
|
||||
private WebPushSubscriptionService $webPushSubscriptionService,
|
||||
private IClientService $httpClientService
|
||||
) {}
|
||||
|
||||
private function parseOptions(array $options): array {
|
||||
|
@ -79,7 +83,7 @@ class WebPushTransport extends Transport {
|
|||
];
|
||||
}
|
||||
|
||||
public function notify(string $userId, string $collectionName, int $subscriptionId) {
|
||||
public function notify(string $userId, string $collectionName, int $subscriptionId): IPromise {
|
||||
$xmlService = new Service();
|
||||
|
||||
$pushResource = $this->webPushSubscriptionService->findBySubscriptionId($subscriptionId)->getPushResource();
|
||||
|
@ -88,15 +92,15 @@ class WebPushTransport extends Transport {
|
|||
'{DAV:Push}topic' => $collectionName,
|
||||
]);
|
||||
|
||||
$options = [
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
'content' => $content,
|
||||
],
|
||||
];
|
||||
$httpClient = $this->httpClientService->newClient();
|
||||
|
||||
$context = stream_context_create($options);
|
||||
$result = file_get_contents($pushResource, false, $context);
|
||||
return $httpClient->postAsync($pushResource, [
|
||||
"body" => $content,
|
||||
"timeout" => 10,
|
||||
"headers" => [
|
||||
"Content-Type" => "application/xml",
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSubscriptionIdFromOptions(string $userId, string $collectionName, $options): ?int {
|
||||
|
|
|
@ -26,6 +26,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\DavPush\Transport;
|
||||
|
||||
use OCP\Http\Client\IPromise;
|
||||
|
||||
abstract class Transport {
|
||||
protected $id;
|
||||
|
||||
|
@ -69,5 +71,5 @@ abstract class Transport {
|
|||
// Change mutable options of the subscription (if any exist)
|
||||
abstract public function updateSubscription($subsciptionId, $options);
|
||||
|
||||
abstract public function notify(string $userId, string $collectionName, int $subscriptionId);
|
||||
abstract public function notify(string $userId, string $collectionName, int $subscriptionId): IPromise;
|
||||
}
|
Loading…
Reference in a new issue