Compare commits
1 commit
parallel-n
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
c0f400fa94 |
4 changed files with 21 additions and 32 deletions
|
@ -10,15 +10,14 @@ Watch the video (YouTube):
|
||||||
|
|
||||||
# Nextcloud extension for WebDAV-Push
|
# 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.
|
`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).
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
**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!**
|
> [!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!
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
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
|
## About WebDAV-Push
|
||||||
|
|
|
@ -37,7 +37,6 @@ use OCA\DAV\Events\CardDeletedEvent;
|
||||||
use OCA\DAV\Events\CardUpdatedEvent;
|
use OCA\DAV\Events\CardUpdatedEvent;
|
||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use GuzzleHttp\Promise;
|
|
||||||
|
|
||||||
use OCA\DavPush\Service\SubscriptionService;
|
use OCA\DavPush\Service\SubscriptionService;
|
||||||
use OCA\DavPush\Transport\TransportManager;
|
use OCA\DavPush\Transport\TransportManager;
|
||||||
|
@ -60,16 +59,13 @@ class CalendarListener implements IEventListener {
|
||||||
$collectionName = $event->getCalendarData()['uri'];
|
$collectionName = $event->getCalendarData()['uri'];
|
||||||
$subscriptions = $this->subscriptionService->findAll($collectionName);
|
$subscriptions = $this->subscriptionService->findAll($collectionName);
|
||||||
|
|
||||||
$notificationPromises = (function () use ($collectionName, $subscriptions): \Generator {
|
|
||||||
foreach($subscriptions as $subscription) {
|
foreach($subscriptions as $subscription) {
|
||||||
$transport = $this->transportManager->getTransport($subscription->getTransport());
|
$transport = $this->transportManager->getTransport($subscription->getTransport());
|
||||||
yield $transport->notify($subscription->getUserId(), $collectionName, $subscription->getId());
|
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());
|
||||||
$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,9 +30,6 @@ use OCA\DavPush\Transport\Transport;
|
||||||
use OCA\DavPush\Service\WebPushSubscriptionService;
|
use OCA\DavPush\Service\WebPushSubscriptionService;
|
||||||
use OCA\DavPush\Errors\WebPushSubscriptionNotFound;
|
use OCA\DavPush\Errors\WebPushSubscriptionNotFound;
|
||||||
|
|
||||||
use OCP\Http\Client\IClientService;
|
|
||||||
use OCP\Http\Client\IPromise;
|
|
||||||
|
|
||||||
use Sabre\Xml\Service;
|
use Sabre\Xml\Service;
|
||||||
|
|
||||||
class WebPushTransport extends Transport {
|
class WebPushTransport extends Transport {
|
||||||
|
@ -40,7 +37,6 @@ class WebPushTransport extends Transport {
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private WebPushSubscriptionService $webPushSubscriptionService,
|
private WebPushSubscriptionService $webPushSubscriptionService,
|
||||||
private IClientService $httpClientService
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private function parseOptions(array $options): array {
|
private function parseOptions(array $options): array {
|
||||||
|
@ -83,7 +79,7 @@ class WebPushTransport extends Transport {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function notify(string $userId, string $collectionName, int $subscriptionId): IPromise {
|
public function notify(string $userId, string $collectionName, int $subscriptionId) {
|
||||||
$xmlService = new Service();
|
$xmlService = new Service();
|
||||||
|
|
||||||
$pushResource = $this->webPushSubscriptionService->findBySubscriptionId($subscriptionId)->getPushResource();
|
$pushResource = $this->webPushSubscriptionService->findBySubscriptionId($subscriptionId)->getPushResource();
|
||||||
|
@ -92,15 +88,15 @@ class WebPushTransport extends Transport {
|
||||||
'{DAV:Push}topic' => $collectionName,
|
'{DAV:Push}topic' => $collectionName,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$httpClient = $this->httpClientService->newClient();
|
$options = [
|
||||||
|
'http' => [
|
||||||
return $httpClient->postAsync($pushResource, [
|
'method' => 'POST',
|
||||||
"body" => $content,
|
'content' => $content,
|
||||||
"timeout" => 10,
|
|
||||||
"headers" => [
|
|
||||||
"Content-Type" => "application/xml",
|
|
||||||
],
|
],
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
$context = stream_context_create($options);
|
||||||
|
$result = file_get_contents($pushResource, false, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscriptionIdFromOptions(string $userId, string $collectionName, $options): ?int {
|
public function getSubscriptionIdFromOptions(string $userId, string $collectionName, $options): ?int {
|
||||||
|
|
|
@ -26,8 +26,6 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\DavPush\Transport;
|
namespace OCA\DavPush\Transport;
|
||||||
|
|
||||||
use OCP\Http\Client\IPromise;
|
|
||||||
|
|
||||||
abstract class Transport {
|
abstract class Transport {
|
||||||
protected $id;
|
protected $id;
|
||||||
|
|
||||||
|
@ -71,5 +69,5 @@ abstract class Transport {
|
||||||
// Change mutable options of the subscription (if any exist)
|
// Change mutable options of the subscription (if any exist)
|
||||||
abstract public function updateSubscription($subsciptionId, $options);
|
abstract public function updateSubscription($subsciptionId, $options);
|
||||||
|
|
||||||
abstract public function notify(string $userId, string $collectionName, int $subscriptionId): IPromise;
|
abstract public function notify(string $userId, string $collectionName, int $subscriptionId);
|
||||||
}
|
}
|
Loading…
Reference in a new issue