Implement PROPPATCH method for WebDAV
authorLanius Trolling <lanius@laniustrolling.dev>
Sun, 5 May 2024 16:14:01 +0000 (12:14 -0400)
committerLanius Trolling <lanius@laniustrolling.dev>
Sun, 5 May 2024 16:14:01 +0000 (12:14 -0400)
src/jvmMain/kotlin/info/mechyrdia/route/ResourceWebDav.kt

index fcba745e088c89d0f9b4beebad847d787dbdc2b7..36de95ba13f9a57c1c2f2b7b0a1522e1a158e8c7 100644 (file)
@@ -120,6 +120,16 @@ suspend fun getWebDavProperties(path: StoragePath, webRoot: String, depth: Int =
        }
 }
 
+fun <T, C : XmlTagConsumer<T>> C.webDavPropPatchResult(path: StoragePath, webRoot: String) = declaration()
+       .root("multistatus", namespace = "DAV:") {
+               "response" {
+                       "href" { +"${webRoot.removeSuffix("/")}/$path".removeSuffix("/") }
+                       "propstat" {
+                               "status" { +"HTTP/1.1 200 OK" }
+                       }
+               }
+       }
+
 suspend fun FileStorage.copyWebDav(source: StoragePath, target: StoragePath): Boolean {
        return when (getType(source)) {
                StoredFileType.DIRECTORY -> createDir(target) && (listDir(source)
@@ -199,6 +209,18 @@ suspend fun ApplicationCall.webDavPropFind(path: StoragePath) {
                }
 }
 
+suspend fun ApplicationCall.webDavPropPatch(path: StoragePath) {
+       beforeWebDav()
+       
+       val exists = FileStorage.instance.getType(path) != null
+       if (exists)
+               respondXml(status = HttpStatusCode.MultiStatus) {
+                       webDavPropPatchResult(path, WebDavDomainName)
+               }
+       else
+               respond(HttpStatusCode.NotFound)
+}
+
 suspend fun ApplicationCall.webDavGet(path: StoragePath) {
        beforeWebDav()
        
@@ -343,6 +365,7 @@ fun Route.installWebDav() {
        route("{path...}") {
                method(HttpMethod.parse("OPTIONS")) { handle { call.webDavOptions() } }
                method(HttpMethod.parse("PROPFIND")) { handle { call.webDavPropFind(call.webDavPath) } }
+               method(HttpMethod.parse("PROPPATCH")) { handle { call.webDavPropPatch(call.webDavPath) } }
                method(HttpMethod.parse("GET")) { handle { call.webDavGet(call.webDavPath) } }
                method(HttpMethod.parse("MKCOL")) { handle { call.webDavMkCol(call.webDavPath) } }
                method(HttpMethod.parse("PUT")) { handle { call.webDavPut(call.webDavPath) } }