src/server/webdav/multistatus.c

branch
webdav
changeset 233
c5985d2fc19a
parent 231
4714468b9b7e
child 237
ee1680ef1ef2
--- a/src/server/webdav/multistatus.c	Sat Jan 18 13:48:59 2020 +0100
+++ b/src/server/webdav/multistatus.c	Sat Jan 18 16:31:52 2020 +0100
@@ -30,13 +30,15 @@
 #include <stdlib.h>
 
 #include "../daemon/session.h"
+#include "../daemon/protocol.h"
 #include "../util/platform.h"
 
 #include <ucx/string.h>
 
-#include "operation.h"
+#include "multistatus.h"
 
-#include "multistatus.h"
+#include "operation.h"
+#include "xml.h"
 
 #define MULTISTATUS_BUFFER_LENGTH 2048
 
@@ -141,7 +143,10 @@
         switch(property->vtype) {
             case WS_VALUE_NO_TYPE: break;
             case WS_VALUE_XML_NODE: {
-                // TODO
+                wsxml_write_nodes_without_nsdef(
+                        ms->sn->pool,
+                        out,
+                        property->value.node);
                 break;
             }
             case WS_VALUE_XML_DATA: {
@@ -163,13 +168,13 @@
         }
         
         // end tag
-        writer_putc(out, '<');
+        writer_puts(out, S("</"));
         writer_puts(out, sstr((char*)property->namespace->prefix));
         writer_putc(out, ':');
         writer_puts(out, sstr((char*)property->name));
         writer_putc(out, '>');
     } else {
-        writer_putc(out, '/>');
+        writer_puts(out, S("/>"));
     }
     
     return out->error;
@@ -179,42 +184,79 @@
     writer_puts(out, S(" <D:response>\n"
                        "  <D:href>"));
     writer_puts(out, sstr(rp->resource.href));
-    writer_puts(out, S("</href>\n"));
+    writer_puts(out, S("</D:href>\n"));
     
     if(rp->plist_begin) {
-        writer_puts(out, S("  <D:propstat>"
+        writer_puts(out, S("  <D:propstat>\n"
                            "   <D:prop>\n"));
         // send properties
         PropertyOkList *p = rp->plist_begin;
         while(p) {
+            writer_puts(out, S("    "));
             if(send_property(ms, p->property, p->nsdef, TRUE, out)) {
                 return out->error;
             }
+            writer_puts(out, S("\n    "));
             p = p->next;
         }
         
         writer_puts(out, S("   </D:prop>\n"
-                           "   <D:status>HTTP/1.1 200 OK</D:status>"
+                           "   <D:status>HTTP/1.1 200 OK</D:status>\n"
                            "  </D:propstat>\n"));
     }
     
     // send error properties
     PropertyErrorList *error = rp->errors;
     while(error) {
+        writer_puts(out, S("  <D:propstat>\n"
+                           "   <D:prop>\n"));
+        
         WebdavPList *errprop = error->begin;
         while(errprop) {
+            writer_puts(out, S("    "));
             if(send_property(ms, errprop->property, NULL, FALSE, out)) {
                 return out->error;
             }
+            writer_puts(out, S("\n    "));
             errprop = errprop->next;
         }
+        
+        char statuscode[8];
+        int sclen = snprintf(statuscode, 8, "%d ", error->status);
+        if(sclen > 4) {
+            statuscode[0] = '5';
+            statuscode[1] = '0';
+            statuscode[2] = '0';
+            statuscode[3] = ' ';
+            sclen = 4;
+        }
+        writer_puts(out, S("   </D:prop>\n"
+                           "   <D:status>HTTP/1.1 "));
+        writer_put(out, statuscode, sclen);
+        const char *status_msg = protocol_status_message(error->status);
+        if(status_msg) {
+            writer_put(out, status_msg, strlen(status_msg));
+        } else {
+            writer_puts(out, S("Server Error"));
+        }
+        writer_puts(out, S("</D:status>\n"
+                           "  </D:propstat>\n"));
+        
+        
         error = error->next;
     }
     
+    // end response tag
+    writer_puts(out, S(" </D:response>\n"));
+    
     return out->error;
 }
 
 int multistatus_send(Multistatus *ms, SYS_NETFD net) {
+    // start http response
+    protocol_status(ms->sn, ms->rq, 207, NULL);
+    protocol_start_response(ms->sn, ms->rq);
+    
     char buffer[MULTISTATUS_BUFFER_LENGTH];
     // create a writer, that flushes the buffer when it is filled
     Writer writer;
@@ -235,6 +277,11 @@
         response = response->next;
     }
     
+    // end multistatus
+    writer_puts(out, S("</D:multistatus>\n"));
+    
+    writer_flush(out);
+    
     return 0;
 }
 

mercurial