[WIP] Wrapping RFC 8030 #19
Replies: 2 comments 2 replies
-
XML's vocabulary is supposed to be scoped to a namespace. Do we need
An interesting information Apple's
(having both is probably not needed) Such an information can be useful:
|
Beta Was this translation helpful? Give feedback.
-
1. DAV Server setupWhen the DAV Server first starts, there can be two situations:
1.1. Creating a new subscription setWhen a new collection that supports PUSH is created, a subscription must also be initialized. This is, creating a new subscription set which will hold all the subscriptions made to that resource. This task must be performed by the DAV server. For security, the subscription set id must be a random string. I suggest creating a new UUIDv4, and storing it somewhere in the DAV server's database, even though I wouldn't specify it in the standard but leave it to the implementation. So let's say the server says "I want to enable PUSH subscriptions for collection x", the steps to follow are:
Tip Note that maybe this step isn't really mandatory. We can just create the subscription set identifier, and store it somewhere. Then the PUSH server would create the subscription set when the first subscription is requested. 2. User
|
Beta Was this translation helpful? Give feedback.
-
Note
Still a work in progress, will be further expanded.
Note
To be clear, this only talks about subscription method. There's no definition here on how the push distribution should work. That is being discussed in #16, #17, #18 and #20.
As discussed, I think that we can define WebDAV PUSH on top of RFC-8030. This way we don't have to reinvent some things, and also we work over some standards, which is always good.
And commented in our Bitfire internal discussion, it can be a good option to just reference sections of RFC8030, and build the specification by referencing and extending.
Push properties
Following this idea, and developing what we have come up with until now, I think it's safe to say that we will be providing the information about PUSH in the
propstat
section of aPROPFIND
to the resource. So to illustrate some examples. Let's say we make a propfind to our personal collection in Nextcloud. Usingcurl
:Let's say that the response is something like this:
Then what we can do is provide an extra property in the first
response
>propstat
>prop
. Let's call itpush-subscription
, for example, which targets a subscription endpoint as defined in RFC-8030~4.Following this idea, we can even provide another property, for example
supported-push-component-set
, that specifies exactly which PUSH providers are available to subscribe with. So for example, if this subscription endpoint supports FCM and UnifiedPush, the contents of this set can be as simple as:Then we already know which services or PUSH providers are available for this endpoint. Scoping it this way also provides the server the possibility to restrict PUSH support for specific collections for example.
The same can be applied to CalDAV, I've modified the response from Nextcloud to include the features described above.
Note that the endpoints have been invented and are arbitrary, further specification, if any shall be discussed.
Subscription
Now that we know where to subscribe to, we can follow up the instructions at RFC-8030~4, with even the possibility of adopting RFC-8030~4.1, which maybe can be useful in cases where topics are not supported, I'm not sure about this, but in any case, I think it can be useful to group subscriptions.
To summarize a little bit Section 4, let's say we want to subscribe to the adressbook above, we can make the following POST request:
In here we can also pass the PUSH provider in some way, I think a header may be enough. I've done some research, and even though it's not intended for this use, the
Push-Policy
draft header (which has expired), may be used. So if we want to use FCM, the full request would be:Though maybe we can just make up a new header name, something like
Push-Method
, for example, which may be more suitable, and we really don't need to adapt to an existing header name.Then, the server can respond with the
201 Created
specified by RFC-8030:I think it's important to know that in this case, the Nextcloud installation (DAV server) and the PUSH server are on the same machine, but the
push-subscription
can really be anywhere, that's why the whole HTTP address is written down, and not a relative path.As specified by RFC-8030:
To be more clear, as as far as I understand, the URI given in the
Link
response header (/remote.php/dav/push/addressbooks/username/v4QjZ53F8B4G2GM2N7Urjt4XxuNW4DY4
) is where clients can PUSH to this subscription, so for example, if the client that is making the subscription does a modification, making a POST request to this endpoint should notify all the subscribed clients.In our case, to follow the specification, the DAV server must subscribe to all the resources that support PUSH. And that's where I think the subscriptions set may be useful. We can define an interface where the DAV server "creates" new subscription sets, and then they are stored to be distributed to the requesting clients in the
push-subscription
property. In this sense,push-subscription
won't be a proper subscription endpoint but a subscription set. So we might have to define again a new property, for examplepush-server
, which actually holds the subscription URL, which can be a simple one, it doesn't need to have a long path, maybe just something likehttps://nextcloud.local/remote.php/dav/push/subscribe
, and then the subscription set is specified through aLink
header as specified by RFC-8030~4.1.To give a proper example, and summarize everything, the POST request for subscribing would be something like:
Error handling
We must provide some standarized way of notifying the client about subscription errors. RFC8030 says:
Then, errors would be:
400 Bad Request
: Subscription set invalid.405 Method Not Allowed
: The requested PUSH provider (Push-Policy
) is not acceptable.429 Too Many Requests
: Missing subscription set.503 Service Unavailable
: The requested PUSH provider is not available (service down?).PUSH Message Delivery
Following on the specification given in RFC-8030~5, and the structure given before, the client would never know the "push resource" of the collection, instead, this information would be known by the server, which created the subscription set. So the client will never have to request the distribution of the PUSH notification, the server will handle all the work automatically when some data is updated through any request.
Then this section only applies to the DAV server, clients won't have anything to do here.
Once a resource is updated in the server, let's say a calendar event has been created, since the DAV server already knows the PUSH resource URL of the collection updated, it has to make the following POST request:
Until further specification, I think the body can remain empty. Since there's one PUSH resource set for each collection (as listed in the PROPFIND), pushing there already specifies which collection has been updated, and then the client just asks the DAV server for the new data. In this way, the PUSH server can be completely unaware of what's in the collection, it just knows there's a collection called something, somewhere.
To provide more security and get rid of metadata, DAV servers could also just generate random resource set names, and it would be really opaque for the PUSH server to know which data is being handled.
Then, once the PUSH server processes the request, a
201 Created
response is given:I'm not sure which information this message endpoint may have, but for example we can use the TTL header to hold the information about the PUSH message for a given amount of time, as specified in RFC-8030~5.2, and if a request is made to the message endpoint, some information about the delivery can be provided. Then the information of
can also be fetched from here. And maybe also being able to make
DELETE
requests to get rid of messages that are queued. But I think that's not important right now, and can be discussed in the future.Beta Was this translation helpful? Give feedback.
All reactions