fix: SAF delete crash, getFileMetadata drop-first, MKCOL before upload
- LocalAccessor.Saf.delete() now uses docIdCache (same as openInputStream) and catches IllegalStateException from DocumentsContract.deleteDocument instead of propagating it through awaitAll() and crashing the whole sync - WebDavProvider.getFileMetadata() passes dropFirst=false to parsePropfind since Depth:0 returns exactly 1 result (the file); drop(1) was discarding it - SyncEngine.performSync() calls ensureRemoteDirs() before each upload so MKCOL is issued for any missing parent directories (405=exists is success) - Bump version to 1.0.11 (code 12) Verified against live Nextcloud: baseline ↑0 ↓0 ✗0, upload detection ↑1 ↓0 ✗0, download detection ↑0 ↓1 ✗0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -132,7 +132,10 @@ open class WebDavProvider(protected val account: CloudAccount) : CloudProvider {
|
||||
val req = Request.Builder().url(url(remotePath)).method("PROPFIND", PROPFIND_BODY).header("Depth", "0").build()
|
||||
client.newCall(req).execute().use { resp ->
|
||||
if (resp.code != 207) throw Exception("HTTP ${resp.code}")
|
||||
parsePropfind(resp.body?.string() ?: "", remotePath.substringBeforeLast('/'))
|
||||
// Depth:0 returns exactly the requested resource as the single response entry.
|
||||
// parsePropfind normally drops the first entry (the parent dir) for Depth:1
|
||||
// directory listings, so pass dropFirst=false here.
|
||||
parsePropfind(resp.body?.string() ?: "", remotePath.substringBeforeLast('/'), dropFirst = false)
|
||||
.firstOrNull() ?: throw Exception("File not found")
|
||||
}
|
||||
}
|
||||
@@ -153,7 +156,7 @@ open class WebDavProvider(protected val account: CloudAccount) : CloudProvider {
|
||||
|
||||
protected fun url(path: String) = "$baseUrl/${path.trimStart('/')}"
|
||||
|
||||
private fun parsePropfind(xml: String, parentPath: String): List<RemoteFile> {
|
||||
private fun parsePropfind(xml: String, parentPath: String, dropFirst: Boolean = true): List<RemoteFile> {
|
||||
val results = mutableListOf<RemoteFile>()
|
||||
try {
|
||||
val factory = XmlPullParserFactory.newInstance()
|
||||
@@ -192,7 +195,7 @@ open class WebDavProvider(protected val account: CloudAccount) : CloudProvider {
|
||||
eventType = parser.next()
|
||||
}
|
||||
} catch (_: Exception) {}
|
||||
return results.drop(1) // drop the parent folder itself
|
||||
return if (dropFirst) results.drop(1) else results
|
||||
}
|
||||
|
||||
private fun parseHttpDate(value: String): Instant = try {
|
||||
|
||||
Reference in New Issue
Block a user