+ /* Remove any stray double-slashes in pathname */
+ while (ds=strstr(ChrPtr(DavPathname), "//"), ds != NULL) {
+ strcpy(ds, ds+1);
+ }
+
+ /*
+ * 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);
+ if (len > 0) {
+ stripltlen(dav_ifmatch, &len);
+ if (dav_ifmatch[0] == '\"') {
+ memmove (dav_ifmatch, &dav_ifmatch[1], len);
+ len --;
+ for (i=0; i<len; ++i) {
+ if (dav_ifmatch[i] == '\"') {
+ dav_ifmatch[i] = 0;
+ len = i - 1;
+ }
+ }
+ }
+ if (!strcmp(dav_ifmatch, "*")) {
+ strcpy(dav_ifmatch, "");
+ }
+ }
+
+ /*
+ * The OPTIONS method is not required by GroupDAV. This is an
+ * experiment to determine what might be involved in supporting
+ * other variants of DAV in the future.
+ */
+ if (!strcasecmp(ChrPtr(DavMethod), "OPTIONS")) {
+ groupdav_options(DavPathname);
+ return;
+ }
+
+ /*
+ * The PROPFIND method is basically used to list all objects in a
+ * room, or to list all relevant rooms on the server.
+ */
+ if (!strcasecmp(ChrPtr(DavMethod), "PROPFIND")) {
+ groupdav_propfind(DavPathname, dav_depth,
+ dav_content_type, dav_content,
+ Offset);
+ return;
+ }
+
+ /*
+ * The GET method is used for fetching individual items.
+ */
+ if (!strcasecmp(ChrPtr(DavMethod), "GET")) {
+ groupdav_get(DavPathname);
+ return;
+ }
+
+ /*
+ * The PUT method is used to add or modify items.
+ */
+ if (!strcasecmp(ChrPtr(DavMethod), "PUT")) {
+ groupdav_put(DavPathname, dav_ifmatch,
+ ChrPtr(dav_content_type), dav_content,
+ Offset);
+ return;
+ }
+
+ /*
+ * The DELETE method kills, maims, and destroys.
+ */
+ if (!strcasecmp(ChrPtr(DavMethod), "DELETE")) {
+ groupdav_delete(DavPathname, dav_ifmatch);
+ return;
+ }
+
+ /*
+ * Couldn't find what we were looking for. Die in a car fire.
+ */
+ hprintf("HTTP/1.1 501 Method not implemented\r\n");
+ groupdav_common_headers();
+ hprintf("Content-Type: text/plain\r\n");
+ wprintf("GroupDAV method \"%s\" is not implemented.\r\n",
+ ChrPtr(DavMethod));
+ end_burst();
+}
+
+
+/*
+ * Output our host prefix for globally absolute URL's.
+ */
+void groupdav_identify_host(void) {
+ wcsession *WCC = WC;
+
+ if (StrLength(WCC->http_host)!=0) {
+ wprintf("%s://%s",
+ (is_https ? "https" : "http"),
+ ChrPtr(WCC->http_host));