* fix groupdav handling
authorWilfried Göesgens <willi@citadel.org>
Tue, 23 Jun 2009 12:15:10 +0000 (12:15 +0000)
committerWilfried Göesgens <willi@citadel.org>
Tue, 23 Jun 2009 12:15:10 +0000 (12:15 +0000)
* add common logic for outputting 401; centralize it, register it as handler.
* remove params to groupdav functions, since WC gives them all information they need.
* use the general post handler for groupdav too.
* since /groupdav/ isn't left in the path by the current logic anymore, we need to count less when parsing.

webcit/context_loop.c
webcit/groupdav.h
webcit/groupdav_delete.c
webcit/groupdav_get.c
webcit/groupdav_main.c
webcit/groupdav_options.c
webcit/groupdav_propfind.c
webcit/groupdav_put.c
webcit/webcit.c
webcit/webcit.h

index 3a20c7e82092a54a283457151b3d3862b188fe4f..e0c8072b0947471fffa405ed017f4ab19cf5eb8d 100644 (file)
@@ -544,8 +544,16 @@ void context_loop(ParsedHttpHdrs *Hdr)
 
                if ((StrLength(Hdr->c_username) == 0) &&
                    (!Hdr->HR.DontNeedAuth)) {
-                       OverrideRequest(Hdr, HKEY("GET /static/nocookies.html?force_close_session=yes HTTP/1.0"));
-                       Hdr->HR.prohibit_caching = 1;
+
+                       if ((Hdr->HR.Handler != NULL) && 
+                           (XHTTP_COMMANDS & Hdr->HR.Handler->Flags) == XHTTP_COMMANDS) {
+                               OverrideRequest(Hdr, HKEY("GET /401 HTTP/1.0"));
+                               Hdr->HR.prohibit_caching = 1;                           
+                       }
+                       else {
+                               OverrideRequest(Hdr, HKEY("GET /static/nocookies.html?force_close_session=yes HTTP/1.0"));
+                               Hdr->HR.prohibit_caching = 1;
+                       }
                }
                
                if (StrLength(Hdr->c_language) > 0) {
index 82b532192f15f2fd6a7220cf8e30b3ed6490f65e..49b3f49234add84d4fe3b6c13a90767b04d7d8e7 100644 (file)
@@ -14,19 +14,12 @@ struct epdata {
 
 
 void groupdav_common_headers(void);
-void groupdav_main(HashList *HTTPHeaders,
-                  StrBuf *DavPathname,
-                  StrBuf *dav_content_type,
-                  int dav_content_length,
-                  StrBuf *dav_content,
-                  int Offset);
-void groupdav_get(StrBuf *dav_pathname);
-void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
-                 const char *dav_content_type, StrBuf *dav_content,
-                 int offset);
-void groupdav_delete(StrBuf *dav_pathname, char *dav_ifmatch);
-void groupdav_propfind(StrBuf *dav_pathname, int dav_depth, StrBuf *dav_content_type, StrBuf *dav_content, int offset);
-void groupdav_options(StrBuf *dav_pathname);
+void groupdav_get(void);
+void groupdav_put(void);
+void groupdav_delete(void);
+void groupdav_propfind(void);
+void groupdav_options(void);
+
 long locate_message_by_uid(const char *);
 void groupdav_folder_list(void);
 void euid_escapize(char *, const char *);
index cdc65becb459458d7741335b3255423f09b1641e..e18f1a86f348aa69da390fe7d39008c6b8cd7cce 100644 (file)
 /*
  * The pathname is always going to be /groupdav/room_name/euid
  */
-void groupdav_delete(StrBuf *dav_pathname, char *dav_ifmatch) {
+void groupdav_delete(void) 
+{
+       wcsession *WCC = WC;
        char dav_uid[SIZ];
        long dav_msgnum = (-1);
        char buf[SIZ];
        int n = 0;
 
-       /* First, break off the "/groupdav/" prefix */
-       StrBufCutLeft(dav_pathname, 9);
-
        /* Now extract the message euid */
-       n = StrBufNum_tokens(dav_pathname, '/');
-       extract_token(dav_uid, ChrPtr(dav_pathname), n-1, '/', sizeof dav_uid);
-       StrBufRemove_token(dav_pathname, n-1, '/');
+       n = StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/');
+       extract_token(dav_uid, ChrPtr(WCC->Hdr->HR.ReqLine), n-1, '/', sizeof dav_uid);
+       StrBufRemove_token(WCC->Hdr->HR.ReqLine, n-1, '/');
 
        /* What's left is the room name.  Remove trailing slashes. */
-       //len = StrLength(dav_pathname);
-       //if ((len > 0) && (ChrPtr(dav_pathname)[len-1] == '/')) {
-       //      StrBufCutRight(dav_pathname, 1);
+       //len = StrLength(WCC->Hdr->HR.ReqLine);
+       //if ((len > 0) && (ChrPtr(WCC->Hdr->HR.ReqLinee)[len-1] == '/')) {
+       //      StrBufCutRight(WCC->Hdr->HR.ReqLine, 1);
        //}
-       StrBufCutLeft(dav_pathname, 1);
+       StrBufCutLeft(WCC->Hdr->HR.ReqLine, 1);
 
        /* Go to the correct room. */
-       if (strcasecmp(ChrPtr(WC->wc_roomname), ChrPtr(dav_pathname))) {
-               gotoroom(dav_pathname);
+       if (strcasecmp(ChrPtr(WC->wc_roomname), ChrPtr(WCC->Hdr->HR.ReqLine))) {
+               gotoroom(WCC->Hdr->HR.ReqLine);
        }
-       if (strcasecmp(ChrPtr(WC->wc_roomname), ChrPtr(dav_pathname))) {
+       if (strcasecmp(ChrPtr(WC->wc_roomname), ChrPtr(WCC->Hdr->HR.ReqLine))) {
                hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
                hprintf("Content-Length: 0\r\n\r\n");
@@ -61,8 +60,8 @@ void groupdav_delete(StrBuf *dav_pathname, char *dav_ifmatch) {
         * It's there ... check the ETag and make sure it matches
         * the message number.
         */
-       if (!IsEmptyStr(dav_ifmatch)) {
-               if (atol(dav_ifmatch) != dav_msgnum) {
+       if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
+               if (StrTol(WCC->Hdr->HR.dav_ifmatch) != dav_msgnum) {
                        hprintf("HTTP/1.1 412 Precondition Failed\r\n");
                        groupdav_common_headers();
                        hprintf("Content-Length: 0\r\n\r\n");
index 2a4d4cb543e78de07f1d68968bcea056ee839f20..1c6e4830722f052c2eb3819486daf5750f1c5722 100644 (file)
@@ -86,7 +86,9 @@ void extract_preferred(char *name, char *filename, char *partnum, char *disp,
  * /groupdav/room_name/euid    (GroupDAV)
  * /groupdav/room_name         (webcal)
  */
-void groupdav_get(StrBuf *dav_pathname) {
+void groupdav_get(void)
+{
+       wcsession *WCC = WC;
        StrBuf *dav_roomname;
        StrBuf *dav_uid;
        long dav_msgnum = (-1);
@@ -104,7 +106,7 @@ void groupdav_get(StrBuf *dav_pathname) {
        char date[128];
        struct epdata epdata;
 
-       if (StrBufNum_tokens(dav_pathname, '/') < 3) {
+       if (StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/') < 2) {
                hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
                hprintf("Content-Type: text/plain\r\n");
@@ -115,18 +117,18 @@ void groupdav_get(StrBuf *dav_pathname) {
 
        dav_roomname = NewStrBuf();;
        dav_uid = NewStrBuf();;
-       StrBufExtract_token(dav_roomname, dav_pathname, 2, '/');
-       StrBufExtract_token(dav_uid, dav_pathname, 3, '/');
+       StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
+       StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
        if ((!strcasecmp(ChrPtr(dav_uid), "ics")) || 
            (!strcasecmp(ChrPtr(dav_uid), "calendar.ics"))) {
                FlushStrBuf(dav_uid);
        }
 
        /* Go to the correct room. */
-       if (strcasecmp(ChrPtr(WC->wc_roomname), ChrPtr(dav_roomname))) {
+       if (strcasecmp(ChrPtr(WCC->wc_roomname), ChrPtr(dav_roomname))) {
                gotoroom(dav_roomname);
        }
-       if (strcasecmp(ChrPtr(WC->wc_roomname), ChrPtr(dav_roomname))) {
+       if (strcasecmp(ChrPtr(WCC->wc_roomname), ChrPtr(dav_roomname))) {
                hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
                hprintf("Content-Type: text/plain\r\n");
@@ -226,11 +228,11 @@ void groupdav_get(StrBuf *dav_pathname) {
         */
        if (!strncasecmp(content_type, "multipart/", 10)) {
 
-               if ( (WC->wc_default_view == VIEW_CALENDAR) || (WC->wc_default_view == VIEW_TASKS) ) {
+               if ( (WCC->wc_default_view == VIEW_CALENDAR) || (WCC->wc_default_view == VIEW_TASKS) ) {
                        strcpy(epdata.desired_content_type_1, "text/calendar");
                }
 
-               else if (WC->wc_default_view == VIEW_ADDRESSBOOK) {
+               else if (WCC->wc_default_view == VIEW_ADDRESSBOOK) {
                        strcpy(epdata.desired_content_type_1, "text/vcard");
                        strcpy(epdata.desired_content_type_2, "text/x-vcard");
                }
index c31b40b9ec374d52aea785942ecec324bea45ed7..5df6188f2a68295fb63642537a49226246172815 100644 (file)
@@ -84,82 +84,34 @@ void euid_unescapize(char *target, const char *source) {
 /*
  * Main entry point for GroupDAV requests
  */
-void groupdav_main(HashList *HTTPHeaders,
-                  StrBuf *DavPathname,
-                  StrBuf *dav_content_type,
-                  int dav_content_length,
-                  StrBuf *dav_content,
-                  int Offset
-) {
+void groupdav_main(void)
+{
        wcsession *WCC = WC;
-       void *vLine;
-       char dav_ifmatch[256];
-       int dav_depth;
-       char *ds;
        int i, len;
 
-       strcpy(dav_ifmatch, "");
-       dav_depth = 0;
-
-       if ((StrLength(WCC->Hdr->HR.http_host) == 0) &&
-           GetHash(HTTPHeaders, HKEY("HOST"), &vLine) && 
-           (vLine != NULL)) {
-               WCC->Hdr->HR.http_host = (StrBuf*)vLine;
-       }
-       if (GetHash(HTTPHeaders, HKEY("IF-MATCH"), &vLine) && 
-           (vLine != NULL)) {
-               safestrncpy(dav_ifmatch, ChrPtr((StrBuf*)vLine),
-                           sizeof dav_ifmatch);
-       }
-       if (GetHash(HTTPHeaders, HKEY("DEPTH"), &vLine) && 
-           (vLine != NULL)) {
-               if (!strcasecmp(ChrPtr((StrBuf*)vLine), "infinity")) {
-                       dav_depth = 32767;
-               }
-               else if (strcmp(ChrPtr((StrBuf*)vLine), "0") == 0) {
-                       dav_depth = 0;
-               }
-               else if (strcmp(ChrPtr((StrBuf*)vLine), "1") == 0) {
-                       dav_depth = 1;
-               }
-       }
-
-       if (!WC->logged_in) {
-               hprintf("HTTP/1.1 401 Unauthorized\r\n");
-               groupdav_common_headers();
-               hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n",
-                       ChrPtr(WCC->serv_info->serv_humannode));
-               hprintf("Content-Length: 0\r\n");
-               end_burst();
-               return;
-       }
-
-       StrBufUnescape(DavPathname, 0);
+       StrBufUnescape(WCC->Hdr->HR.ReqLine, 0);
 
-       /* Remove any stray double-slashes in pathname */
-       while (ds=strstr(ChrPtr(DavPathname), "//"), ds != NULL) {
-               strcpy(ds, ds+1);
-       }
+       StrBufStripSlashes(WCC->Hdr->HR.ReqLine, 0);
 
        /*
         * If there's an If-Match: header, strip out the quotes if present, and
         * then if all that's left is an asterisk, make it go away entirely.
         */
-       len = strlen(dav_ifmatch);
+       len = StrLength(WCC->Hdr->HR.dav_ifmatch);
        if (len > 0) {
-               stripltlen(dav_ifmatch, &len);
-               if (dav_ifmatch[0] == '\"') {
-                       memmove (dav_ifmatch, &dav_ifmatch[1], len);
+               StrBufTrim(WCC->Hdr->HR.dav_ifmatch);
+               if (ChrPtr(WCC->Hdr->HR.dav_ifmatch)[0] == '\"') {
+                       StrBufCutLeft(WCC->Hdr->HR.dav_ifmatch, 1);
                        len --;
                        for (i=0; i<len; ++i) {
-                               if (dav_ifmatch[i] == '\"') {
-                                       dav_ifmatch[i] = 0;
-                                       len = i - 1;
+                               if (ChrPtr(WCC->Hdr->HR.dav_ifmatch)[i] == '\"') {
+                                       StrBufCutAt(WCC->Hdr->HR.dav_ifmatch, i, NULL);
+                                       len = StrLength(WCC->Hdr->HR.dav_ifmatch);
                                }
                        }
                }
-               if (!strcmp(dav_ifmatch, "*")) {
-                       strcpy(dav_ifmatch, "");
+               if (!strcmp(ChrPtr(WCC->Hdr->HR.dav_ifmatch), "*")) {
+                       FlushStrBuf(WCC->Hdr->HR.dav_ifmatch);
                }
        }
 
@@ -171,7 +123,7 @@ void groupdav_main(HashList *HTTPHeaders,
         * other variants of DAV in the future.
         */
        case eOPTIONS:
-               groupdav_options(DavPathname);
+               groupdav_options();
                break;
 
 
@@ -180,32 +132,28 @@ void groupdav_main(HashList *HTTPHeaders,
         * room, or to list all relevant rooms on the server.
         */
        case ePROPFIND:
-               groupdav_propfind(DavPathname, dav_depth,
-                                 dav_content_type, dav_content, 
-                                 Offset);
+               groupdav_propfind();
                break;
 
        /*
         * The GET method is used for fetching individual items.
         */
        case eGET:
-               groupdav_get(DavPathname);
+               groupdav_get();
                break;
        
        /*
         * The PUT method is used to add or modify items.
         */
        case ePUT:
-               groupdav_put(DavPathname, dav_ifmatch,
-                            ChrPtr(dav_content_type), dav_content, 
-                            Offset);
+               groupdav_put();
                break;
        
        /*
         * The DELETE method kills, maims, and destroys.
         */
        case eDELETE:
-               groupdav_delete(DavPathname, dav_ifmatch);
+               groupdav_delete();
                break;
        default:
 
@@ -236,11 +184,30 @@ void groupdav_identify_host(void) {
 }
 
 
+void Header_HandleIfMatch(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+       hdr->HR.dav_ifmatch = Line;
+}
+       
+void Header_HandleDepth(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+       if (!strcasecmp(ChrPtr(Line), "infinity")) {
+               hdr->HR.dav_depth = 32767;
+       }
+       else if (strcmp(ChrPtr(Line), "0") == 0) {
+               hdr->HR.dav_depth = 0;
+       }
+       else if (strcmp(ChrPtr(Line), "1") == 0) {
+               hdr->HR.dav_depth = 1;
+       }
+}
+
 void 
 InitModule_GROUPDAV
 (void)
 {
-
-       WebcitAddUrlHandler(HKEY("groupdav"), do_logout, XHTTP_COMMANDS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
+       WebcitAddUrlHandler(HKEY("groupdav"), groupdav_main, XHTTP_COMMANDS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
+       RegisterHeaderHandler(HKEY("IF-MATCH"), Header_HandleIfMatch);
+       RegisterHeaderHandler(HKEY("DEPTH"), Header_HandleDepth);
 
 }
index 5f678c1e647b6e2485f44d8ad51ef276c2f0bab7..9f1fefcef7f48bddb153af6963c039f52d695aba 100644 (file)
@@ -12,7 +12,9 @@
 /*
  * The pathname is always going to be /groupdav/room_name/msg_num
  */
-void groupdav_options(StrBuf *dav_pathname) {
+void groupdav_options(void)
+{
+       wcsession *WCC = WC;
        StrBuf *dav_roomname;
        StrBuf *dav_uid;
        long dav_msgnum = (-1);
@@ -24,8 +26,8 @@ void groupdav_options(StrBuf *dav_pathname) {
 
        dav_roomname = NewStrBuf();
        dav_uid = NewStrBuf();
-       StrBufExtract_token(dav_roomname, dav_pathname, 2, '/');
-       StrBufExtract_token(dav_uid, dav_pathname, 3, '/');
+       StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
+       StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
 
        /*
         * If the room name is blank, the client is doing a top-level OPTIONS.
index 00c8d5e3a18745aef716bdf941ee6d532f292143..b28cb636a6fc6ac9331da7a3fb2be86abd1e809d 100644 (file)
@@ -49,8 +49,9 @@ long locate_message_by_uid(const char *uid) {
  * List rooms (or "collections" in DAV terminology) which contain
  * interesting groupware objects.
  */
-void groupdav_collection_list(const char *dav_pathname, int dav_depth)
+void groupdav_collection_list(void)
 {
+       wcsession *WCC = WC;
        char buf[256];
        char roomname[256];
        int view;
@@ -60,16 +61,13 @@ void groupdav_collection_list(const char *dav_pathname, int dav_depth)
        int is_groupware_collection = 0;
        int starting_point = 1;         /**< 0 for /, 1 for /groupdav/ */
 
-       if (!strcmp(dav_pathname, "/")) {
+       if (WCC->Hdr->HR.Handler == NULL) {
                starting_point = 0;
        }
-       else if (!strcasecmp(dav_pathname, "/groupdav")) {
+       else if (StrLength(WCC->Hdr->HR.ReqLine) == 0) {
                starting_point = 1;
        }
-       else if (!strcasecmp(dav_pathname, "/groupdav/")) {
-               starting_point = 1;
-       }
-       else if ( (!strncasecmp(dav_pathname, "/groupdav/", 10)) && (strlen(dav_pathname) > 10) ) {
+       else {
                starting_point = 2;
        }
 
@@ -117,7 +115,7 @@ void groupdav_collection_list(const char *dav_pathname, int dav_depth)
        /**
         *      If the client is requesting "/groupdav", show a /groupdav subdirectory.
         */
-       if ((starting_point + dav_depth) >= 1) {
+       if ((starting_point + WCC->Hdr->HR.dav_depth) >= 1) {
                wprintf("<response>");
                        wprintf("<href>");
                                groupdav_identify_host();
@@ -159,14 +157,18 @@ void groupdav_collection_list(const char *dav_pathname, int dav_depth)
                 * GroupDAV calendar even if the user has switched it to a
                 * Calendar List view.
                 */
-               if ((view == VIEW_CALENDAR) || (view == VIEW_TASKS) || (view == VIEW_ADDRESSBOOK) ) {
+               if ((view == VIEW_CALENDAR) || 
+                   (view == VIEW_TASKS) || 
+                   (view == VIEW_ADDRESSBOOK) ||
+                   (view == VIEW_NOTES) ||
+                   (view == VIEW_JOURNAL) ) {
                        is_groupware_collection = 1;
                }
                else {
                        is_groupware_collection = 0;
                }
 
-               if ( (is_groupware_collection) && ((starting_point + dav_depth) >= 2) ) {
+               if ( (is_groupware_collection) && ((starting_point + WCC->Hdr->HR.dav_depth) >= 2) ) {
                        wprintf("<response>");
 
                        wprintf("<href>");
@@ -184,15 +186,21 @@ void groupdav_collection_list(const char *dav_pathname, int dav_depth)
                        wprintf("<resourcetype><collection/>");
 
                        switch(view) {
-                               case VIEW_CALENDAR:
-                                       wprintf("<G:vevent-collection />");
-                                       break;
-                               case VIEW_TASKS:
-                                       wprintf("<G:vtodo-collection />");
-                                       break;
-                               case VIEW_ADDRESSBOOK:
-                                       wprintf("<G:vcard-collection />");
-                                       break;
+                       case VIEW_CALENDAR:
+                               wprintf("<G:vevent-collection />");
+                               break;
+                       case VIEW_TASKS:
+                               wprintf("<G:vtodo-collection />");
+                               break;
+                       case VIEW_ADDRESSBOOK:
+                               wprintf("<G:vcard-collection />");
+                               break;
+                       case VIEW_NOTES:
+                               wprintf("<G:vnotes-collection />");
+                               break;
+                       case VIEW_JOURNAL:
+                               wprintf("<G:vjournal-collection />");
+                               break;
                        }
 
                        wprintf("</resourcetype>");
@@ -214,7 +222,9 @@ void groupdav_collection_list(const char *dav_pathname, int dav_depth)
 /*
  * The pathname is always going to be /groupdav/room_name/msg_num
  */
-void groupdav_propfind(StrBuf *dav_pathname, int dav_depth, StrBuf *dav_content_type, StrBuf *dav_content, int offset) {
+void groupdav_propfind(void) 
+{
+       wcsession *WCC = WC;
        StrBuf *dav_roomname;
        StrBuf *dav_uid;
        StrBuf *MsgNum;
@@ -233,15 +243,15 @@ void groupdav_propfind(StrBuf *dav_pathname, int dav_depth, StrBuf *dav_content_
 
        dav_roomname = NewStrBuf();
        dav_uid = NewStrBuf();
-       StrBufExtract_token(dav_roomname, dav_pathname, 2, '/');
-       StrBufExtract_token(dav_uid, dav_pathname, 3, '/');
+       StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
+       StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
 
        /*
         * If the room name is blank, the client is requesting a
         * folder list.
         */
        if (StrLength(dav_roomname) == 0) {
-               groupdav_collection_list(ChrPtr(dav_pathname), dav_depth);
+               groupdav_collection_list();
                FreeStrBuf(&dav_roomname);
                FreeStrBuf(&dav_uid);
                return;
index 7f4cc810cc17ba68d5b89b81d8a868d0ba42536f..bacd77e0d3b12c1c0e7e0bfca9bbf375e3a214da 100644 (file)
@@ -15,8 +15,9 @@
  * component.  This would be for webcal:// 'publish' operations, not
  * for GroupDAV.
  */
-void groupdav_put_bigics(StrBuf *dav_content, int offset)
+void groupdav_put_bigics(void)
 {
+       wcsession *WCC = WC;
        char buf[1024];
 
        /*
@@ -37,7 +38,7 @@ void groupdav_put_bigics(StrBuf *dav_content, int offset)
                return;
        }
 
-       serv_write(ChrPtr(dav_content) + offset, StrLength(dav_content) - offset);
+       serv_write(WCC->upload, WCC->upload_length);
        serv_printf("\n000");
 
        /* Report success and not much else. */
@@ -52,13 +53,12 @@ void groupdav_put_bigics(StrBuf *dav_content, int offset)
 
 /*
  * The pathname is always going to take one of two formats:
- * /groupdav/room_name/euid    (GroupDAV)
- * /groupdav/room_name         (webcal)
+ * [/groupdav/]room_name/euid  (GroupDAV)
+ * [/groupdav/]room_name               (webcal)
  */
-void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
-                 const char *dav_content_type, StrBuf *dav_content,
-                 int offset) 
+void groupdav_put(void) 
 {
+       wcsession *WCC = WC;
        StrBuf *dav_roomname;
        StrBuf *dav_uid;
        long new_msgnum = (-2L);
@@ -66,7 +66,7 @@ void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
        char buf[SIZ];
        int n = 0;
 
-       if (StrBufNum_tokens(dav_pathname, '/') < 3) {
+       if (StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/') < 2) {
                hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
                hprintf("Content-Type: text/plain\r\n");
@@ -77,8 +77,8 @@ void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
 
        dav_roomname = NewStrBuf();;
        dav_uid = NewStrBuf();;
-       StrBufExtract_token(dav_roomname, dav_pathname, 2, '/');
-       StrBufExtract_token(dav_uid, dav_pathname, 3, '/');
+       StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
+       StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
        if ((!strcasecmp(ChrPtr(dav_uid), "ics")) || 
            (!strcasecmp(ChrPtr(dav_uid), "calendar.ics"))) {
                FlushStrBuf(dav_uid);
@@ -107,14 +107,14 @@ void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
         * client is expecting.  If not, the server probably contains a newer
         * version, so we fail...
         */
-       if (!IsEmptyStr(dav_ifmatch)) {
-               lprintf(9, "dav_ifmatch: %s\n", dav_ifmatch);
+       if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
+               lprintf(9, "dav_ifmatch: %s\n", WCC->Hdr->HR.dav_ifmatch);
                old_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
                lprintf(9, "old_msgnum:  %ld\n", old_msgnum);
-               if (atol(dav_ifmatch) != old_msgnum) {
+               if (StrTol(WCC->Hdr->HR.dav_ifmatch) != old_msgnum) {
                        hprintf("HTTP/1.1 412 Precondition Failed\r\n");
                        lprintf(9, "HTTP/1.1 412 Precondition Failed (ifmatch=%ld, old_msgnum=%ld)\r\n",
-                               atol(dav_ifmatch), old_msgnum);
+                               StrTol(WCC->Hdr->HR.dav_ifmatch), old_msgnum);
                        groupdav_common_headers();
                        hprintf("Content-Length: 0\r\n");
                        end_burst();
@@ -127,7 +127,7 @@ void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
        /** PUT on the collection itself uploads an ICS of the entire collection.
         */
        if (StrLength(dav_uid) == 0) {
-               groupdav_put_bigics(dav_content, offset);
+               groupdav_put_bigics();
                FreeStrBuf(&dav_roomname);
                FreeStrBuf(&dav_uid);
                return;
@@ -151,8 +151,8 @@ void groupdav_put(StrBuf *dav_pathname, char *dav_ifmatch,
        }
 
        /* Send the content to the Citadel server */
-       serv_printf("Content-type: %s\n\n", dav_content_type);
-       serv_puts(ChrPtr(dav_content) + offset);
+       serv_printf("Content-type: %s\n\n", WCC->upload_content_type);
+       serv_puts(WCC->upload);
        serv_puts("\n000");
 
        /* Fetch the reply from the Citadel server */
index 08dff525967c5b4557e39d6e2269d9bc9580655f..1f9fd521d1db58d8e4b8a4bd0bc4475dfa42eda5 100644 (file)
@@ -366,14 +366,29 @@ void display_success(char *successmessage)
  * Authorization required page 
  * This is probably temporary and should be revisited 
  */
-void authorization_required(const char *message)
+void authorization_required(void)
 {
+       wcsession *WCC = WC;
+       const char *message = "";
+
        hprintf("HTTP/1.1 401 Authorization Required\r\n");
+       hprintf(
+               "Server: %s / %s\r\n"
+               "Connection: close\r\n",
+               PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software)
+       );
        hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", ChrPtr(WC->serv_info->serv_humannode));
        hprintf("Content-Type: text/html\r\n");
        wprintf("<h1>");
        wprintf(_("Authorization Required"));
        wprintf("</h1>\r\n");
+       
+
+       if (WCC->ImportantMsg != NULL)
+               message = ChrPtr(WCC->ImportantMsg);
+       else if (WCC->ImportantMessage != NULL)
+               message = WCC->ImportantMessage;
+
        wprintf(_("The resource you requested requires a valid username and password. "
                "You could not be logged in: %s\n"), message);
        wDumpContent(0);
@@ -548,8 +563,6 @@ void session_loop(void)
        int xhttp;
        StrBuf *Buf;
        
-       char buf[SIZ];
-
        /*
         * We stuff these with the values coming from the client cookies,
         * so we can use them to reconnect a timed out session if we have to.
@@ -620,7 +633,8 @@ void session_loop(void)
                                                 WCC->Hdr->c_password, Buf);
                        } else {
                                /* Should only display when password is wrong */
-                               authorization_required(&buf[4]);
+                               WCC->ImportantMsg = NewStrBufPlain(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
+                               authorization_required();
                                FreeStrBuf(&Buf);
                                goto SKIP_ALL_THIS_CRAP;
                        }
@@ -676,10 +690,25 @@ void session_loop(void)
        }
        /* When all else fais, display the main menu. */
        else {
-               if (!WCC->logged_in) 
-                       display_login(NULL);
-               else
-                       display_main_menu();
+               /* 
+                * ordinary browser users get a nice login screen, DAV etc. requsets
+                * are given a 401 so they can handle it appropriate.
+                */
+               if (!WCC->logged_in)  {
+                       if (xhttp)
+                               authorization_required();
+                       else 
+                               display_login(NULL);
+               }
+               /*
+                * Toplevel dav requests? or just a flat browser request? 
+                */
+               else {
+                       if (xhttp)
+                               groupdav_main();
+                       else
+                               display_main_menu();
+               }
        }
 
 SKIP_ALL_THIS_CRAP:
@@ -755,6 +784,7 @@ InitModule_WEBCIT
        WebcitAddUrlHandler(HKEY("ajax_servcmd"), ajax_servcmd, 0);
        WebcitAddUrlHandler(HKEY("webcit"), blank_page, URLNAMESPACE);
 
+       WebcitAddUrlHandler(HKEY("401"), authorization_required, ANONYMOUS|COOKIEUNNEEDED);
        RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage, CTX_NONE);
        RegisterNamespace("CSSLOCAL", 0, 0, tmplput_csslocal, CTX_NONE);
        RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, CTX_NONE);
index bc7341dc755b3179abd9634a64a6ec0c9f9dcdbf..b1f619ea0a9dcd49db3d846f4cf0c4de149e82e6 100644 (file)
@@ -415,6 +415,7 @@ typedef struct _HdrRefs {
        time_t if_modified_since;
        int gzip_ok;                            /**< Nonzero if Accept-encoding: gzip */
        int prohibit_caching;
+       int dav_depth;
 
        /* these are references into Hdr->HTTPHeaders, so we don't need to free them. */
        StrBuf *ContentType;
@@ -424,7 +425,7 @@ typedef struct _HdrRefs {
        StrBuf *browser_host;
        StrBuf *user_agent;
        StrBuf *plainauth;
-
+       StrBuf *dav_ifmatch;
 
        const WebcitHandler *Handler;
 } HdrRefs;
@@ -725,7 +726,6 @@ void text_to_server(char *ptr);
 void text_to_server_qp(char *ptr);
 void confirm_delete_msg(void);
 void display_success(char *);
-void authorization_required(const char *message);
 void CheckAuthBasic(ParsedHttpHdrs *hdr);
 void GetAuthBasic(ParsedHttpHdrs *hdr);
 void server_to_text(void);