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

Commit 2504a810 authored by Ricki Hirner's avatar Ricki Hirner
Browse files

jCard: check MIME type from server; use MediaType for MIME types when possible

parent ede9e1cf
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.resource.LocalAddressBook
import at.bitfire.davdroid.resource.TaskUtils
import okhttp3.HttpUrl
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import org.xbill.DNS.*
import java.util.*

@@ -34,8 +36,11 @@ object DavUtils {
        ACTIVE, PENDING, IDLE
    }

    const val MIME_TYPE_ALL = "*/*"
    const val MIME_TYPE_OCTET_STREAM = "application/octet-stream"
    const val MIME_TYPE_ACCEPT_ALL = "*/*"

    val MEDIA_TYPE_JCARD = "application/vcard+json".toMediaType()
    val MEDIA_TYPE_OCTET_STREAM = "application/octet-stream".toMediaType()
    val MEDIA_TYPE_VCARD = "text/vcard".toMediaType()


    @Suppress("FunctionName")
@@ -204,4 +209,18 @@ object DavUtils {
        return result
    }


    // extension methods

    /**
     * Compares MIME type and subtype of two MediaTypes. Does _not_ compare parameters
     * like `charset` or `version`.
     *
     * @param other   MediaType to compare with
     *
     * @return *true* if type and subtype match; *false* if they don't
     */
    fun MediaType.sameTypeAs(other: MediaType) =
        type == other.type && subtype == other.subtype

}
+11 −1
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@ package at.bitfire.davdroid.model
import androidx.room.TypeConverter
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull

class Converters {

@@ -10,8 +12,16 @@ class Converters {
    fun httpUrlToString(url: HttpUrl?) =
            url?.toString()

    @TypeConverter
    fun mediaTypeToString(mediaType: MediaType?) =
        mediaType?.toString()

    @TypeConverter
    fun stringToHttpUrl(url: String?): HttpUrl? =
        url?.toHttpUrlOrNull()

    @TypeConverter
    fun stringToMediaType(mimeType: String?): MediaType? =
        mimeType?.toMediaTypeOrNull()

}
 No newline at end of file
+8 −6
Original line number Diff line number Diff line
@@ -8,8 +8,10 @@ import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
import at.bitfire.davdroid.DavUtils.MIME_TYPE_OCTET_STREAM
import at.bitfire.davdroid.DavUtils.MEDIA_TYPE_OCTET_STREAM
import okhttp3.HttpUrl
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import java.io.FileNotFoundException

@Entity(
@@ -38,7 +40,7 @@ data class WebDavDocument(
    var isDirectory: Boolean = false,

    var displayName: String? = null,
    var mimeType: String? = null,
    var mimeType: MediaType? = null,
    var eTag: String? = null,
    var lastModified: Long? = null,
    var size: Long? = null,
@@ -75,11 +77,11 @@ data class WebDavDocument(
            val reportedMimeType = mimeType ?:
                MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                    MimeTypeMap.getFileExtensionFromUrl(name)
                ) ?:
                MIME_TYPE_OCTET_STREAM
                )?.toMediaTypeOrNull() ?:
                MEDIA_TYPE_OCTET_STREAM

            bundle.putString(Document.COLUMN_MIME_TYPE, reportedMimeType)
            if (mimeType?.startsWith("image/") == true)
            bundle.putString(Document.COLUMN_MIME_TYPE, reportedMimeType.toString())
            if (mimeType?.type == "image")
                flags += Document.FLAG_SUPPORTS_THUMBNAIL
            if (mayWriteContent != false)
                flags += Document.FLAG_SUPPORTS_WRITE
+3 −1
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@ import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.ical4android.DateUtils
import at.bitfire.ical4android.Event
import at.bitfire.ical4android.InvalidCalendarException
import net.fortuna.ical4j.model.Component
import net.fortuna.ical4j.model.component.VAlarm
import net.fortuna.ical4j.model.component.VEvent
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.RequestBody
@@ -105,7 +107,7 @@ class CalendarSyncManager(

        return remoteExceptionContext { remote ->
            Logger.log.info("Querying events since $limitStart")
            remote.calendarQuery("VEVENT", limitStart, null, callback)
            remote.calendarQuery(Component.VEVENT, limitStart, null, callback)
        }
    }

+14 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import at.bitfire.dav4jvm.Response
import at.bitfire.dav4jvm.exception.DavException
import at.bitfire.dav4jvm.property.*
import at.bitfire.davdroid.DavUtils
import at.bitfire.davdroid.DavUtils.sameTypeAs
import at.bitfire.davdroid.HttpClient
import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger
@@ -140,7 +141,8 @@ class ContactsSyncManager(
                }
            }

            Logger.log.info("Server supports vCard/4: $hasVCard4")
            Logger.log.info("Server supports jCard: $hasJCard")
            Logger.log.info("Server supports vCard4: $hasVCard4")
            Logger.log.info("Server supports Collection Sync: $hasCollectionSync")

            syncState
@@ -231,15 +233,15 @@ class ContactsSyncManager(
            val version: String?
            when {
                hasJCard -> {
                    contentType = "application/vcard+json"
                    version = "4.0"
                    contentType = DavUtils.MEDIA_TYPE_JCARD.toString()
                    version = VCardVersion.V4_0.version
                }
                hasVCard4 -> {
                    contentType = "text/vcard"
                    version = "4.0"
                    contentType = DavUtils.MEDIA_TYPE_VCARD.toString()
                    version = VCardVersion.V4_0.version
                }
                else -> {
                    contentType = "text/vcard"
                    contentType = DavUtils.MEDIA_TYPE_VCARD.toString()
                    version = null     // 3.0 is the default version; don't request 3.0 explicitly because maybe some vCard3-only servers don't understand it
                }
            }
@@ -253,11 +255,16 @@ class ContactsSyncManager(
                    val eTag = response[GetETag::class.java]?.eTag
                            ?: throw DavException("Received multi-get response without ETag")

                    var isJCard = hasJCard      // assume that server has sent what we have requested (we ask for jCard only when the server advertises it)
                    response[GetContentType::class.java]?.type?.let { type ->
                        isJCard = type.sameTypeAs(DavUtils.MEDIA_TYPE_JCARD)
                    }

                    val addressData = response[AddressData::class.java]
                    val card = addressData?.card
                            ?: throw DavException("Received multi-get response without address data")

                    processCard(DavUtils.lastSegmentOfUrl(response.href), eTag, StringReader(card), hasJCard, resourceDownloader)
                    processCard(DavUtils.lastSegmentOfUrl(response.href), eTag, StringReader(card), isJCard, resourceDownloader)
                }
            }
        }
Loading