X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit-ng%2Fserver%2Fcaldav_reports.c;h=d253b777b602ce03d12c8514c61b3ee829c70265;hb=bcdcc6d9a5f4d5f1a86d1fc725a2ce787f1d92f8;hp=ff60dfedcb8fca8c50b48deeb5a426f5651b1493;hpb=ba0fa5e054b43fe2dc13a6050f261e506be096b5;p=citadel.git diff --git a/webcit-ng/server/caldav_reports.c b/webcit-ng/server/caldav_reports.c index ff60dfedc..d253b777b 100644 --- a/webcit-ng/server/caldav_reports.c +++ b/webcit-ng/server/caldav_reports.c @@ -1,10 +1,10 @@ // This file contains functions which handle all of the CalDAV "REPORT" queries // specified in RFC4791 section 7. // -// Copyright (c) 2022 by the citadel.org team +// Copyright (c) 2023-2024 by the citadel.org team // // This program is open source software. Use, duplication, or -// disclosure are subject to the GNU General Public License v3. +// disclosure is subject to the GNU General Public License v3. #include "webcit.h" @@ -24,7 +24,7 @@ struct cr_parms { int tag_nesting_level; // not needed, just kept for pretty-printing enum cr_type report_type; // which RFC4791 section 7 REPORT are we generating StrBuf *Chardata; // XML chardata in between tags is built up here - StrBuf *Hrefs; // list of items requested by a calendar-multiget report + StrBuf *Hrefs; // list of items requested by a `calendar-multiget` REPORT }; @@ -39,14 +39,17 @@ void caldav_xml_start(void *data, const char *el, const char **attr) { syslog(LOG_DEBUG, " Attribute '%s' = '%s'", attr[i], attr[i + 1]); } - if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:calendar-multiget")) { - crp->report_type = cr_calendar_multiget; + // RFC4791 7.8 "calendar-query" REPORT - Client will send a lot of search criteria. + if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:calendar-query")) { + crp->report_type = cr_calendar_query; } - else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:calendar-query")) { - crp->report_type = cr_calendar_query; + // RFC4791 7.9 "calendar-multiget" REPORT - Client will supply a list of specific hrefs. + else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:calendar-multiget")) { + crp->report_type = cr_calendar_multiget; } + // RFC4791 7.10 "free-busy-query" REPORT else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:free-busy-query")) { crp->report_type = cr_freebusy_query; } @@ -96,12 +99,12 @@ void caldav_xml_chardata(void *data, const XML_Char * s, int len) { } -// Called by caldav_response() to fetch a message (by number) in the current room, +// Called by caldav_report_one_item() to fetch a message (by number) in the current room, // and return only the icalendar data as a StrBuf. Returns NULL if not found. // // NOTE: this function expects that "MSGP text/calendar" was issued at the beginning // of a REPORT operation to set our preferred MIME type to calendar data. -StrBuf *fetch_ical(struct ctdlsession * c, long msgnum) { +StrBuf *fetch_ical(struct ctdlsession *c, long msgnum) { char buf[1024]; StrBuf *Buf = NULL; @@ -112,7 +115,7 @@ StrBuf *fetch_ical(struct ctdlsession * c, long msgnum) { } while (ctdl_readline(c, buf, sizeof(buf)), strcmp(buf, "000")) { - if (Buf != NULL) { // already in body + if (Buf != NULL) { // already in body StrBufAppendPrintf(Buf, "%s\n", buf); } else if (IsEmptyStr(buf)) { // beginning of body @@ -121,31 +124,12 @@ StrBuf *fetch_ical(struct ctdlsession * c, long msgnum) { } return Buf; - -// webcit[13039]: msgn=53CE87AF-00392161@uncensored.citadel.org -// webcit[13039]: path=IGnatius T Foobar -// webcit[13039]: time=1208008800 -// webcit[13039]: from=IGnatius T Foobar -// webcit[13039]: room=0000000001.Calendar -// webcit[13039]: node=uncnsrd -// webcit[13039]: hnod=Uncensored -// webcit[13039]: exti=040000E00074C5B7101A82E0080000000080C728F83E84C801000000000000000010000000E857E0DC57F53947ADF0BB91EE3A502F -// webcit[13039]: subj==?UTF-8?B?V2VzbGV5J3MgYmlydGhkYXkgcGFydHk= -// webcit[13039]: ?= -// webcit[13039]: part=||1||text/calendar|1127|| -// webcit[13039]: text -// webcit[13039]: Content-type: text/calendar -// webcit[13039]: Content-length: 1127 -// webcit[13039]: Content-transfer-encoding: 7bit -// webcit[13039]: X-Citadel-MSG4-Partnum: 1 -// webcit[13039]: -// webcit[13039]: BEGIN:VCALENDAR } // Called by caldav_report() to output a single item. // Our policy is to throw away the list of properties the client asked for, and just send everything. -void caldav_response(struct http_transaction *h, struct ctdlsession *c, StrBuf * ReportOut, StrBuf * ThisHref) { +void caldav_report_one_item(struct http_transaction *h, struct ctdlsession *c, StrBuf *ReportOut, StrBuf *ThisHref) { long msgnum; StrBuf *Caldata = NULL; char *euid; @@ -177,7 +161,7 @@ void caldav_response(struct http_transaction *h, struct ctdlsession *c, StrBuf * } if (Caldata != NULL) { - // syslog(LOG_DEBUG, "caldav_response(%s) 200 OK", ChrPtr(ThisHref)); + // syslog(LOG_DEBUG, "caldav_report_one_item(%s) 200 OK", ChrPtr(ThisHref)); StrBufAppendPrintf(ReportOut, ""); StrBufAppendPrintf(ReportOut, "HTTP/1.1 200 OK"); StrBufAppendPrintf(ReportOut, ""); @@ -193,7 +177,7 @@ void caldav_response(struct http_transaction *h, struct ctdlsession *c, StrBuf * Caldata = NULL; } else { - // syslog(LOG_DEBUG, "caldav_response(%s) 404 not found", ChrPtr(ThisHref)); + // syslog(LOG_DEBUG, "caldav_report_one_item(%s) 404 not found", ChrPtr(ThisHref)); StrBufAppendPrintf(ReportOut, ""); StrBufAppendPrintf(ReportOut, "HTTP/1.1 404 not found"); StrBufAppendPrintf(ReportOut, ""); @@ -248,18 +232,34 @@ void caldav_report(struct http_transaction *h, struct ctdlsession *c) { ">" ); - if (crp.Hrefs != NULL) { // Output all qualifying calendar items! + // RFC4791 7.8 "calendar-query" REPORT - Client will send a lot of search criteria. + if (crp.report_type == cr_calendar_query) { + // FIXME build this REPORT. At the moment we send an empty multistatus. + } + + // RFC4791 7.9 "calendar-multiget" REPORT - go get the specific Hrefs the client asked for. + else if ( (crp.report_type == cr_calendar_multiget) && (crp.Hrefs != NULL) ) { StrBuf *ThisHref = NewStrBuf(); const char *pvset = NULL; while (StrBufExtract_NextToken(ThisHref, crp.Hrefs, &pvset, '|') >= 0) { - caldav_response(h, c, ReportOut, ThisHref); + StrBufTrim(ThisHref); // remove leading/trailing whitespace from the href + caldav_report_one_item(h, c, ReportOut, ThisHref); } FreeStrBuf(&ThisHref); + } + + // RFC4791 7.10 "free-busy-query" REPORT + else if (crp.report_type == cr_freebusy_query) { + // FIXME build this REPORT. At the moment we send an empty multistatus. + } + + // Free any query parameters that might have been allocated during the xml parse + if (crp.Hrefs != NULL) { FreeStrBuf(&crp.Hrefs); crp.Hrefs = NULL; } - StrBufAppendPrintf(ReportOut, "\n"); // End the REPORT. + StrBufAppendPrintf(ReportOut, "\n"); // End the REPORT. add_response_header(h, strdup("Content-type"), strdup("text/xml")); h->response_code = 207; @@ -267,3 +267,63 @@ void caldav_report(struct http_transaction *h, struct ctdlsession *c) { h->response_body_length = StrLength(ReportOut); h->response_body = SmashStrBuf(&ReportOut); } + + + + + +// Client is requesting a message list (make this code work for calendar-query REPORT) +void XXXXXXXXXXXXXX(struct http_transaction *h, struct ctdlsession *c, char *range) { + char buf[SIZ]; + + // Determine the date/time range requested by the client + time_t lo = atol(range); + char *colon = strchr(range, ':'); + time_t hi = colon ? atol(++colon) : LONG_MAX; + + // Rule out impossible ranges + if (hi < lo) { + do_404(h); + return; + } + + // Begin by requesting all messages in the room + int i = 0; + Array *msglist = get_msglist(c, "ALL"); + if (msglist == NULL) { + do_404(h); + return; + } + + // We're going to make a lot of MSG4 calls, and the preferred MIME type we want is "text/calendar". + // The iCalendar standard is mature now, and we are no longer interested in text/x-vcal or application/ics. + ctdl_printf(c, "MSGP text/calendar"); + ctdl_readline(c, buf, sizeof buf); + + // Iterate through our message list. + for (i = 0; i < array_len(msglist); ++i) { + long m; + memcpy(&m, array_get_element_at(msglist, i), sizeof(long)); + syslog(LOG_DEBUG, "FIXME %ld", m); + + // now we have to: + // 1. fetch the message from citadel server + // 2. parse the ical + // 3. figure out range + // we should steal code from webcit-classic for this + + StrBuf *one_item; + one_item = fetch_ical(c, m); + syslog(LOG_DEBUG, "calendar item:\n---\n\033[33m%s\n---\033[0m", ChrPtr(one_item)); + FreeStrBuf(&one_item); + + } + array_free(msglist); + + // FIXME we still fail because we aren't finished yet + add_response_header(h, strdup("Content-type"), strdup("application/json")); + h->response_code = 200; + h->response_string = strdup("OK"); + h->response_body = "{ \"one\":111 , \"two\":222 , \"three\":333 }"; + h->response_body_length = strlen(h->response_body); +}