add minimal mkcol implementation and prepare delete webdav

Sat, 01 Feb 2020 18:44:31 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 01 Feb 2020 18:44:31 +0100
branch
webdav
changeset 244
e59abb210584
parent 243
1a29b1d8d9d8
child 245
a193c42fc809

add minimal mkcol implementation and prepare delete

src/server/public/webdav.h file | annotate | diff | comparison | revisions
src/server/test/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.h file | annotate | diff | comparison | revisions
--- a/src/server/public/webdav.h	Sun Jan 26 11:50:35 2020 +0100
+++ b/src/server/public/webdav.h	Sat Feb 01 18:44:31 2020 +0100
@@ -320,6 +320,40 @@
             WSBool);
     
     /*
+     * int opt_mkcol(
+     *     Session *sn,
+     *     Request *rq,
+     *     const char *path,
+     *     WSBool *out_created
+     * 
+     * Optional mkcol callback that is called before vfs_mkdir. If the function
+     * sets out_created to TRUE, vfs_mkdir will not be executed.
+     */
+    int (*opt_mkcol)(
+            Session *,
+            Request *,
+            const char *,
+            WSBool *);
+    
+    /*
+     * int opt_delete(
+     *     Session *sn,
+     *     Request *rq,
+     *     const char *path,
+     *     WSBool *out_deleted
+     * 
+     * Optional delete callback that is called once before any VFS deletions.
+     * When the callback sets out_deleted to TRUE, no VFS unlink operations
+     * will be done.
+     * 
+     */
+    int (*opt_delete)(
+            Session *,
+            Request *,
+            const char *,
+            WSBool *);
+    
+    /*
      * See the WS_WEBDAV_* macros for informations about the settings
      */
     uint32_t settings;
--- a/src/server/test/webdav.c	Sun Jan 26 11:50:35 2020 +0100
+++ b/src/server/test/webdav.c	Sat Feb 01 18:44:31 2020 +0100
@@ -123,6 +123,8 @@
     backend2_propfind_finish,
     backend2_proppatch_do,
     backend2_proppatch_finish,
+    NULL, // opt_mkcol
+    NULL, // opt_delete
     0,
     NULL
 };
@@ -221,6 +223,8 @@
     backend1_propfind_finish,
     backend1_proppatch_do,
     backend1_proppatch_finish,
+    NULL, // opt_mkcol
+    NULL, // opt_delete
     0,
     &backend2
 };
--- a/src/server/webdav/webdav.c	Sun Jan 26 11:50:35 2020 +0100
+++ b/src/server/webdav/webdav.c	Sat Feb 01 18:44:31 2020 +0100
@@ -66,6 +66,8 @@
     default_backend.propfind_finish = default_propfind_finish;
     default_backend.proppatch_do = default_proppatch_do;
     default_backend.proppatch_finish = default_proppatch_finish;
+    default_backend.opt_mkcol = NULL;
+    default_backend.opt_delete = NULL;
     default_backend.settings = WS_WEBDAV_PROPFIND_USE_VFS;
 }
 
@@ -444,15 +446,64 @@
 }
 
 int webdav_mkcol(pblock *pb, Session *sn, Request *rq) {
-    return REQ_ABORTED;
+    UcxBuffer *reqbuf;
+    VFSContext *vfs;
+    char *path;
+    
+    if(webdav_init_vfs_op(sn, rq, &reqbuf, &vfs, &path)) {
+        return REQ_ABORTED;
+    }
+    
+    int ret = REQ_PROCEED;
+    if(vfs_mkdir(vfs, path)) {
+        protocol_status(sn, rq, util_errno2status(vfs->vfs_errno), NULL);
+        return REQ_ABORTED;
+    }
+    
+    protocol_status(sn, rq, 201, NULL);
+    
+    // cleanup and return
+    if(reqbuf) {
+        ucx_buffer_free(reqbuf);
+    }
+    return ret;
 }
 
 int webdav_post(pblock *pb, Session *sn, Request *rq) {
     return REQ_ABORTED;
 }
 
+static int webdav_delete_collection(
+        Session *sn,
+        Request *rq,
+        VFSContext *vfs,
+        const char *path)
+{
+    
+}
+
 int webdav_delete(pblock *pb, Session *sn, Request *rq) {
-    return REQ_ABORTED;
+    UcxBuffer *reqbuf;
+    VFSContext *vfs;
+    char *path;
+    
+    if(webdav_init_vfs_op(sn, rq, &reqbuf, &vfs, &path)) {
+        return REQ_ABORTED;
+    }
+    
+    int ret = REQ_PROCEED;
+    
+    // TODO
+    
+    if(ret == REQ_PROCEED) {
+        protocol_status(sn, rq, 200, NULL);
+    }
+    
+    // cleanup and return
+    if(reqbuf) {
+        ucx_buffer_free(reqbuf);
+    }
+    return ret;
 }
 
 int webdav_put(pblock *pb, Session *sn, Request *rq) {
@@ -484,6 +535,51 @@
 }
 
 
+int webdav_init_vfs_op(
+        Session *sn,
+        Request *rq,
+        UcxBuffer **out_reqbuf,
+        VFSContext **out_vfs,
+        char **out_path)
+{
+    *out_reqbuf = NULL;
+    *out_vfs = NULL;
+    *out_path = NULL;
+    
+    // create VFS context
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    if(!vfs) {
+        return REQ_ABORTED;
+    } 
+    
+    // read request body, if it exists
+    char *expect = pblock_findkeyval(pb_key_expect, rq->headers);
+    if(expect) {
+        if(!strcasecmp(expect, "100-continue")) {
+            if(http_send_continue(sn)) {
+                return REQ_ABORTED;
+            }
+        }
+    }
+    
+    UcxBuffer *reqbody = NULL;
+    if(sn->inbuf) {
+        reqbody = rqbody2buffer(sn, rq);
+        if(!reqbody) {
+            return REQ_ABORTED;
+        }
+    }
+    
+    // requested uri and path
+    char *path = pblock_findkeyval(pb_key_path, rq->vars);
+    
+    *out_reqbuf = reqbody;
+    *out_vfs = vfs;
+    *out_path = path;
+    
+    return REQ_PROCEED;
+}
+
 /* ------------------------ default webdav backend  ------------------------ */
 
 int default_propfind_init(
--- a/src/server/webdav/webdav.h	Sun Jan 26 11:50:35 2020 +0100
+++ b/src/server/webdav/webdav.h	Sat Feb 01 18:44:31 2020 +0100
@@ -82,6 +82,25 @@
 int webdav_acl(pblock *pb, Session *sn, Request *rq);
 int webdav_search (pblock *pb, Session *sn, Request *rq);
 
+/*
+ * Initialize a WebDAV VFS operation
+ * 
+ * sn: WS Session
+ * rq: WS Request
+ * out_reqbuf: func returns a pointer to the request body or NULL
+ * out_vfs: func returns a pointer to the newly created VFSContext
+ * out_path: func returns a pointer to the path string
+ * 
+ * return: on success REQ_PROCEED
+ *         on error   REQ_ABORTED
+ */
+int webdav_init_vfs_op(
+        Session *sn,
+        Request *rq,
+        UcxBuffer **out_reqbuf,
+        VFSContext **out_vfs,
+        char **out_path);
+
 int default_propfind_init(
         WebdavPropfindRequest *rq,
         const char* path,

mercurial