mirror of
https://github.com/bitfireAT/davx5-ose
synced 2024-07-22 11:11:02 +00:00
WebDAV: allow other MIME types for (Ranged) GET, use coroutines for streaming (#503)
* StreamingFileDescriptor: use coroutines instead of threading * WebDAV GET: accept any MIME type, but prefer known one
This commit is contained in:
parent
769147b193
commit
c56461ea9e
|
@ -13,9 +13,16 @@ import at.bitfire.davdroid.network.Android10Resolver
|
|||
import okhttp3.HttpUrl
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import org.xbill.DNS.*
|
||||
import org.xbill.DNS.ExtendedResolver
|
||||
import org.xbill.DNS.Lookup
|
||||
import org.xbill.DNS.Record
|
||||
import org.xbill.DNS.SRVRecord
|
||||
import org.xbill.DNS.SimpleResolver
|
||||
import org.xbill.DNS.TXTRecord
|
||||
import java.net.InetAddress
|
||||
import java.util.*
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import java.util.TreeMap
|
||||
|
||||
/**
|
||||
* Some WebDAV and HTTP network utility methods.
|
||||
|
@ -30,6 +37,19 @@ object DavUtils {
|
|||
val MEDIA_TYPE_OCTET_STREAM = "application/octet-stream".toMediaType()
|
||||
val MEDIA_TYPE_VCARD = "text/vcard".toMediaType()
|
||||
|
||||
/**
|
||||
* Builds an HTTP `Accept` header that accepts anything (*/*), but optionally
|
||||
* specifies a preference.
|
||||
*
|
||||
* @param preferred preferred MIME type (optional)
|
||||
*
|
||||
* @return `media-range` for `Accept` header that accepts anything, but prefers [preferred] (if it was specified)
|
||||
*/
|
||||
fun acceptAnything(preferred: MediaType?): String =
|
||||
if (preferred != null)
|
||||
"$preferred, $MIME_TYPE_ACCEPT_ALL;q=0.8"
|
||||
else
|
||||
MIME_TYPE_ACCEPT_ALL
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun ARGBtoCalDAVColor(colorWithAlpha: Int): String {
|
||||
|
|
|
@ -167,7 +167,7 @@ class RandomAccessCallback private constructor(
|
|||
|
||||
var result: ByteArray? = null
|
||||
dav.getRange(
|
||||
mimeType?.toString() ?: DavUtils.MIME_TYPE_ACCEPT_ALL,
|
||||
DavUtils.acceptAnything(preferred = mimeType),
|
||||
key.segment * PAGE_SIZE.toLong(),
|
||||
PAGE_SIZE,
|
||||
ifMatch
|
||||
|
|
|
@ -12,12 +12,16 @@ import androidx.core.app.NotificationCompat
|
|||
import androidx.core.app.NotificationManagerCompat
|
||||
import at.bitfire.dav4jvm.DavResource
|
||||
import at.bitfire.dav4jvm.exception.HttpException
|
||||
import at.bitfire.davdroid.network.HttpClient
|
||||
import at.bitfire.davdroid.R
|
||||
import at.bitfire.davdroid.log.Logger
|
||||
import at.bitfire.davdroid.network.HttpClient
|
||||
import at.bitfire.davdroid.ui.NotificationUtils
|
||||
import at.bitfire.davdroid.ui.NotificationUtils.notifyIfPossible
|
||||
import at.bitfire.davdroid.util.DavUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runInterruptible
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
|
@ -26,7 +30,6 @@ import okio.BufferedSink
|
|||
import org.apache.commons.io.FileUtils
|
||||
import java.io.IOException
|
||||
import java.util.logging.Level
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* @param client HTTP client– [StreamingFileDescriptor] is responsible to close it
|
||||
|
@ -64,7 +67,7 @@ class StreamingFileDescriptor(
|
|||
private fun doStreaming(upload: Boolean): ParcelFileDescriptor {
|
||||
val (readFd, writeFd) = ParcelFileDescriptor.createReliablePipe()
|
||||
|
||||
val worker = thread {
|
||||
val result = CoroutineScope(Dispatchers.IO).async {
|
||||
try {
|
||||
if (upload)
|
||||
uploadNow(readFd)
|
||||
|
@ -92,7 +95,7 @@ class StreamingFileDescriptor(
|
|||
|
||||
cancellationSignal?.setOnCancelListener {
|
||||
Logger.log.fine("Cancelling transfer of $url")
|
||||
worker.interrupt()
|
||||
result.cancel()
|
||||
}
|
||||
|
||||
return if (upload)
|
||||
|
@ -102,8 +105,8 @@ class StreamingFileDescriptor(
|
|||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun downloadNow(writeFd: ParcelFileDescriptor) {
|
||||
dav.get(mimeType?.toString() ?: DavUtils.MIME_TYPE_ACCEPT_ALL, null) { response ->
|
||||
private suspend fun downloadNow(writeFd: ParcelFileDescriptor) = runInterruptible {
|
||||
dav.get(DavUtils.acceptAnything(preferred = mimeType), null) { response ->
|
||||
response.body?.use { body ->
|
||||
if (response.isSuccessful) {
|
||||
val length = response.headersContentLength()
|
||||
|
@ -156,7 +159,7 @@ class StreamingFileDescriptor(
|
|||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun uploadNow(readFd: ParcelFileDescriptor) {
|
||||
private suspend fun uploadNow(readFd: ParcelFileDescriptor) = runInterruptible {
|
||||
val body = object: RequestBody() {
|
||||
override fun contentType(): MediaType? = mimeType
|
||||
override fun isOneShot() = true
|
||||
|
|
|
@ -7,6 +7,7 @@ package at.bitfire.davdroid
|
|||
import at.bitfire.davdroid.util.DavUtils
|
||||
import at.bitfire.davdroid.util.DavUtils.parent
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
|
@ -19,6 +20,13 @@ class DavUtilsTest {
|
|||
|
||||
val exampleURL = "http://example.com/"
|
||||
|
||||
|
||||
@Test
|
||||
fun testAcceptAnything() {
|
||||
assertEquals("*/*", DavUtils.acceptAnything(null))
|
||||
assertEquals("some/thing;v=2.1, */*;q=0.8", DavUtils.acceptAnything("some/thing;v=2.1".toMediaType()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testARGBtoCalDAVColor() {
|
||||
assertEquals("#00000000", DavUtils.ARGBtoCalDAVColor(0))
|
||||
|
|
Loading…
Reference in a new issue