Began some of the PROPFIND mods needed for CalDAV. Mike Shaver is a self-righteous...
authorArt Cancro <ajc@uncensored.citadel.org>
Wed, 21 Dec 2011 21:17:42 +0000 (16:17 -0500)
committerArt Cancro <ajc@uncensored.citadel.org>
Wed, 21 Dec 2011 21:17:42 +0000 (16:17 -0500)
webcit/configure.ac
webcit/dav_propfind.c
webcit/webcit.h

index 38b8f218663bbc50e70c14e85cf6977a002cb741..6819bb28a03ad48f3558cec5b3cfec23492aa434 100644 (file)
@@ -252,7 +252,7 @@ dnl Checks for the Expat XML parser.
 AC_CHECK_HEADER(expat.h,
        [AC_CHECK_LIB(expat, XML_ParserCreateNS,
                [
-                       SERVER_LIBS="-lexpat $SERVER_LIBS"
+                       LIBS="-lexpat $LIBS"
                ],
                [
                        AC_MSG_ERROR(The Expat XML parser was not found and is required.  More info: http://www.citadel.org/doku.php/installation:start)
index e6d0abb5e5b3f1cafb5260e15a848d64c415481e..ebf145291cce8104f6c6b9b4018d3e44a2632dbc 100644 (file)
@@ -75,7 +75,8 @@ const folder *GetRESTFolder(int IgnoreFloor, HashList *Subfolders)
 
 /*
  * Guess room: if the full URL matches a room, list thats it. We also need to remember direct sub rooms.
- * if the URL is longer, we need to find the "best guess" so we can find the room we're in, and the rest of the URL will be uids and so on.
+ * if the URL is longer, we need to find the "best guess" so we can find the room we're in, and the rest
+ * of the URL will be uids and so on.
  */
        itfl = GetNewHashPos(WCC->Floors, 0);
        urlp = GetCount(WCC->Directory);
@@ -88,7 +89,6 @@ const folder *GetRESTFolder(int IgnoreFloor, HashList *Subfolders)
                    (ThisFolder->Floor != WCC->CurrentFloor))
                        continue;
 
-
                if (ThisFolder->nRoomNameParts > 1) 
                {
                        /*TODO: is that number all right? */
@@ -427,6 +427,15 @@ void dav_collection_list(void)
 }
 
 
+void propfind_xml_start(void *data, const char *supplied_el, const char **attr) {
+       syslog(LOG_DEBUG, "<%s>", supplied_el);
+}
+
+void propfind_xml_end(void *data, const char *supplied_el) {
+       syslog(LOG_DEBUG, "</%s>", supplied_el);
+}
+
+
 
 /*
  * The pathname is always going to be /groupdav/room_name/msg_num
@@ -447,11 +456,45 @@ void dav_propfind(void)
        char datestring[256];
        time_t now;
 
-       syslog(LOG_DEBUG, "PROPFIND\n\033[31m%s\033[0m", ChrPtr(WCC->upload));
-
        now = time(NULL);
        http_datestring(datestring, sizeof datestring, now);
 
+       int parse_success = 0;
+       XML_Parser xp = XML_ParserCreateNS(NULL, '|');
+       if (xp) {
+               // XML_SetUserData(xp, XXX);
+               XML_SetElementHandler(xp, propfind_xml_start, propfind_xml_end);
+               // XML_SetCharacterDataHandler(xp, xrds_xml_chardata);
+
+               const char *req = ChrPtr(WCC->upload);
+               if (req) {
+                       req = strchr(req, '<');                 /* hunt for the first tag */
+               }
+               if (!req) {
+                       req = "ERROR";                          /* force it to barf */
+               }
+
+               i = XML_Parse(xp, req, strlen(req), 1);
+               if (!i) {
+                       syslog(LOG_DEBUG, "XML_Parse() failed: %s", XML_ErrorString(XML_GetErrorCode(xp)));
+                       XML_ParserFree(xp);
+                       parse_success = 0;
+               }
+               else {
+                       parse_success = 1;
+               }
+       }
+
+       if (!parse_success) {
+               hprintf("HTTP/1.1 500 Internal Server Error\r\n");
+               dav_common_headers();
+               hprintf("Date: %s\r\n", datestring);
+               hprintf("Content-Type: text/plain\r\n");
+               wc_printf("An internal error has occurred at %s:%d.\r\n", __FILE__ , __LINE__ );
+               end_burst();
+               return;
+       }
+
        dav_roomname = NewStrBuf();
        dav_uid = NewStrBuf();
        StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
@@ -569,10 +612,13 @@ void dav_propfind(void)
        begin_burst();
 
        wc_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
-               "<multistatus xmlns=\"DAV:\" xmlns:G=\"http://groupdav.org/\">"
+               "<multistatus "
+                       "xmlns=\"DAV:\" "
+                       "xmlns:G=\"http://groupdav.org/\" "
+                       "xmlns:CALDAV=\"urn:ietf:params:xml:ns:caldav\""
+               ">"
        );
 
-
        /* Transmit the collection resource (FIXME check depth and starting point) */
        wc_printf("<response>");
 
@@ -588,11 +634,14 @@ void dav_propfind(void)
        wc_printf("<displayname>");
        escputs(ChrPtr(WCC->CurRoom.name));
        wc_printf("</displayname>");
-       wc_printf("<resourcetype><collection/>");
 
+       wc_printf("<owner/>");          /* empty owner ought to be legal; see rfc3744 section 5.1 */
+
+       wc_printf("<resourcetype><collection/>");
        switch(WCC->CurRoom.defview) {
                case VIEW_CALENDAR:
                        wc_printf("<G:vevent-collection />");
+                       wc_printf("<CALDAV:calendar />");
                        break;
                case VIEW_TASKS:
                        wc_printf("<G:vtodo-collection />");
@@ -601,8 +650,8 @@ void dav_propfind(void)
                        wc_printf("<G:vcard-collection />");
                        break;
        }
-
        wc_printf("</resourcetype>");
+
        /* FIXME get the mtime
        wc_printf("<getlastmodified>");
                escputs(datestring);
@@ -629,6 +678,7 @@ void dav_propfind(void)
 
        if (num_msgs > 0) for (i=0; i<num_msgs; ++i) {
 
+               syslog(LOG_DEBUG, "PROPFIND enumerating message # %ld", msgs[i]);
                strcpy(uid, "");
                now = (-1);
                serv_printf("MSG0 %ld|3", msgs[i]);
index bfad761078615c157be9d30a51d39be0566b6296..de01cf42b156ab51d80c66909094660767bc5362 100644 (file)
@@ -52,6 +52,7 @@
 #include <signal.h>
 #include <syslog.h>
 #include <sys/utsname.h>
+#include <expat.h>
 #include <libcitadel.h>
 
 #ifdef HAVE_ICONV