Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 2728c5cc authored by Ricki Hirner's avatar Ricki Hirner Committed by GitHub
Browse files

Add WebDAV-Push draft properties (#33)

* Add PushSubscribe and WebPushSubscriptions; parse HTTP-date as Instant

* Add PushTransports for service discovery

* Add Topic property

* Add experimental note to Push KDoc

* Add all Push properties to default property registry
parent f428759c
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -58,15 +58,15 @@ object HttpUtils {
    /**
     * Parses a HTTP-date according to RFC 7231 section 7.1.1.1.
     *
     * @param dateStr date formatted in one of the three accepted formats:
     * @param dateStr date-time formatted in one of the three accepted formats:
     *
     *   - preferred format (`IMF-fixdate`)
     *   - obsolete RFC 850 format
     *   - ANSI C's `asctime()` format
     *
     * @return date, or null if date could not be parsed
     * @return date-time, or null if date could not be parsed
     */
    fun parseDate(dateStr: String): ZonedDateTime? {
    fun parseDate(dateStr: String): Instant? {
        val zonedFormats = arrayOf(
            // preferred format
            httpDateFormat,
@@ -78,7 +78,7 @@ object HttpUtils {
        // try the two formats with zone info
        for (format in zonedFormats)
            try {
                return ZonedDateTime.parse(dateStr, format)
                return ZonedDateTime.parse(dateStr, format).toInstant()
            } catch (ignored: DateTimeParseException) {
            }

@@ -86,7 +86,7 @@ object HttpUtils {
        try {
            val formatC = DateTimeFormatter.ofPattern("EEE MMM ppd HH:mm:ss yyyy", Locale.US)
            val local = LocalDateTime.parse(dateStr, formatC)
            return local.atZone(ZoneOffset.UTC)
            return local.atZone(ZoneOffset.UTC).toInstant()
        } catch (ignored: DateTimeParseException) {
        }

+11 −1
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@ import at.bitfire.dav4jvm.property.carddav.AddressData
import at.bitfire.dav4jvm.property.carddav.AddressbookDescription
import at.bitfire.dav4jvm.property.carddav.AddressbookHomeSet
import at.bitfire.dav4jvm.property.carddav.SupportedAddressData
import at.bitfire.dav4jvm.property.push.PushSubscribe
import at.bitfire.dav4jvm.property.push.PushTransports
import at.bitfire.dav4jvm.property.push.Subscription
import at.bitfire.dav4jvm.property.push.Topic
import at.bitfire.dav4jvm.property.push.WebPushSubscription
import at.bitfire.dav4jvm.property.webdav.AddMember
import at.bitfire.dav4jvm.property.webdav.CreationDate
import at.bitfire.dav4jvm.property.webdav.CurrentUserPrincipal
@@ -79,16 +84,21 @@ object PropertyRegistry {
            at.bitfire.dav4jvm.property.caldav.MaxResourceSize.Factory,
            at.bitfire.dav4jvm.property.carddav.MaxResourceSize.Factory,
            Owner.Factory,
            PushSubscribe.Factory,
            PushTransports.Factory,
            QuotaAvailableBytes.Factory,
            QuotaUsedBytes.Factory,
            ResourceType.Factory,
            ScheduleTag.Factory,
            Source.Factory,
            Subscription.Factory,
            SupportedAddressData.Factory,
            SupportedCalendarComponentSet.Factory,
            SupportedCalendarData.Factory,
            SupportedReportSet.Factory,
            SyncToken.Factory
            SyncToken.Factory,
            Topic.Factory,
            WebPushSubscription.Factory
        ))
    }

+9 −9
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ class ServiceUnavailableException: HttpException {
        // HTTP-date    = rfc1123-date | rfc850-date | asctime-date

        response.header("Retry-After")?.let { after ->
            retryAfter = HttpUtils.parseDate(after)?.toInstant() ?:
            retryAfter = HttpUtils.parseDate(after) ?:
                // not a HTTP-date, must be delta-seconds
                try {
                    val seconds = after.toLong()
+64 −0
Original line number Diff line number Diff line
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package at.bitfire.dav4jvm.property.push

import at.bitfire.dav4jvm.HttpUtils
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import at.bitfire.dav4jvm.XmlUtils.propertyName
import org.xmlpull.v1.XmlPullParser
import java.time.Instant

/**
 * Represents a `{DAV:Push}push-subscribe` property.
 *
 * Experimental! See https://github.com/bitfireAT/webdav-push/
 */
class PushSubscribe: Property {

    companion object {

        @JvmField
        val NAME = Property.Name(NS_WEBDAV_PUSH, "push-subscribe")

        val EXPIRES = Property.Name(NS_WEBDAV_PUSH, "expires")

    }

    var expires: Instant? = null
    var subscription: Subscription? = null


    object Factory: PropertyFactory {

        override fun getName() = NAME

        override fun create(parser: XmlPullParser): PushSubscribe? {
            val subscribe = PushSubscribe()

            val depth = parser.depth
            var eventType = parser.eventType
            while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
                if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1)
                    when (parser.propertyName()) {
                        EXPIRES -> {
                            val expiresDate = XmlUtils.requireReadText(parser)
                            subscribe.expires = HttpUtils.parseDate(expiresDate)
                        }
                        Subscription.NAME ->
                            subscribe.subscription = Subscription.Factory.create(parser)
                    }
                eventType = parser.next()
            }

            return subscribe
        }

    }

}
 No newline at end of file
+55 −0
Original line number Diff line number Diff line
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package at.bitfire.dav4jvm.property.push

import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import at.bitfire.dav4jvm.XmlUtils.propertyName
import org.xmlpull.v1.XmlPullParser

/**
 * Represents a `{DAV:Push}push-transports` property.
 *
 * Experimental! See https://github.com/bitfireAT/webdav-push/
 */
class PushTransports private constructor(
    val transports: Set<Property.Name>
): Property {

    companion object {
        @JvmField
        val NAME = Property.Name(NS_WEBDAV_PUSH, "push-transports")

        val TRANSPORT = Property.Name(NS_WEBDAV_PUSH, "transport")
        val WEB_PUSH = Property.Name(NS_WEBDAV_PUSH, "web-push")
    }

    fun hasWebPush() = transports.contains(WEB_PUSH)


    object Factory: PropertyFactory {

        override fun getName() = NAME

        override fun create(parser: XmlPullParser): PushTransports {
            val transports = mutableListOf<Property.Name>()
            XmlUtils.processTag(parser, TRANSPORT) {
                val depth = parser.depth
                var eventType = parser.eventType
                while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
                    if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1)
                        transports += parser.propertyName()
                    eventType = parser.next()
                }
            }
            return PushTransports(transports.toSet())
        }

    }

}
 No newline at end of file
Loading