@@ -28,6 +28,7 @@ import io.ktor.client.request.put
2828import io.ktor.client.request.request
2929import io.ktor.client.statement.HttpResponse
3030import io.ktor.client.statement.readBytes
31+ import io.ktor.client.statement.request
3132import io.ktor.http.HttpStatusCode
3233import io.ktor.http.URLBuilder
3334import io.ktor.http.content.OutgoingContent
@@ -53,20 +54,20 @@ class DavEntry(
5354 override val modifyTime get() = prop.getlastmodified?.time ? : 0
5455 override val directory get() = prop.resourcetype?.collection != null
5556
56- override suspend fun list () = if (directory) {
57+ override suspend fun list (): List <DavEntry > = if (directory) {
58+ val path = if (path.startsWith(' /' )) path.substring(1 ) else path // Unix path correction, "." ("") and "/" are the same
5759 val httpResponse = davSource.httpClient.request<HttpResponse >(" ${davSource._url } /$path " ) { method = httpMethodPropfind }
58- if (httpResponse.status == HttpStatusCode .MultiStatus ) {
59- var first = true
60- xmlMapper.readValue<Multistatus >(httpResponse.readBytes()).response.mapNotNull {
61- if (first) {
62- first = false
63- null
64- } else {
60+ when (httpResponse.status) {
61+ HttpStatusCode .MultiStatus -> {
62+ val href = httpResponse.request.url.encodedPath
63+ xmlMapper.readValue<Multistatus >(httpResponse.readBytes()).response.filter { ! it.href.equals(href, true ) }.mapNotNull {
6564 val name = URLDecoder .decode(it.href.removeSuffix(" /" ).split(' /' ).last(), " UTF-8" )
66- /* if (name != this.name) */ DavEntry (davSource, " ${ if (path == " / " ) " " else path} / ${ name} " , it.propstat.first().prop) /* else null */
67- } // TODO: it is not defined in the standard that the first entry has to be the entry itself
65+ it.propstat.find { it.status == " HTTP/1.1 200 OK " }?.prop?. let { DavEntry (davSource, " $ path/ $ name" , it) }
66+ }
6867 }
69- } else emptyList()
68+ HttpStatusCode .NotFound -> throw NotFoundException (path)
69+ else -> TODO ()
70+ }
7071 } else emptyList()
7172
7273 override suspend fun transferTo (stream : OutputStream ) {
@@ -78,15 +79,15 @@ class DavEntry(
7879 }
7980
8081 override suspend fun transferFrom (name : String , stream : InputStream , length : Long ) {
81- if (davSource.nextcloud && length > chunkSize ) {
82+ if (davSource.nextcloud && length > davSource.nextcloudUploadChunkSize ) {
8283 val id = " blit-${UUID .randomUUID()} "
8384 davSource.httpClient.request<Unit >(" ${davSource.url} /uploads/${davSource.username} /$id " ) { method = httpMethodMkcol }
8485
8586 /* val jobs = mutableListOf<Job>()*/
86- val chunkCount = ceil(length / chunkSize .toDouble())
87+ val chunkCount = ceil(length / davSource.nextcloudUploadChunkSize .toDouble())
8788 for (i in 0 .. chunkCount) {
8889 /* jobs += ioScope.launch { */
89- davSource.httpClient.put<Unit >(" ${davSource.url} /uploads/${davSource.username} /$id /${i * chunkSize } " ) { body = stream.readNBytes(chunkSize .toInt()) }
90+ davSource.httpClient.put<Unit >(" ${davSource.url} /uploads/${davSource.username} /$id /${i * davSource.nextcloudUploadChunkSize } " ) { body = stream.readNBytes(davSource.nextcloudUploadChunkSize .toInt()) }
9091 coroutineContext.progress = i / chunkCount.toDouble() // TODO: more precise progress
9192 /* }*/
9293 }
@@ -124,8 +125,6 @@ class DavEntry(
124125 }
125126
126127 companion object {
127- private const val chunkSize = 10L * 1024 * 1024
128-
129128 private fun ceil (value : Double ): Int {
130129 val valueInt = (value + 1 ).toInt()
131130 return if (value >= valueInt) valueInt else valueInt - 1
0 commit comments