X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=webcit-ng%2Fserver%2Fcaldav_reports.c;fp=webcit-ng%2Fserver%2Fcaldav_reports.c;h=6b068275c02379534c9ffd206d42f9ee926a7a56;hp=95ccb538f090135661b586d69a7652e0461b7f64;hb=fba52410c164f3bf45b35c1f34ad2d640ff5350e;hpb=c5b99d2f192b2e157e1591c18042f9fdd37996f2 diff --git a/webcit-ng/server/caldav_reports.c b/webcit-ng/server/caldav_reports.c index 95ccb538f..6b068275c 100644 --- a/webcit-ng/server/caldav_reports.c +++ b/webcit-ng/server/caldav_reports.c @@ -27,6 +27,9 @@ struct cr_params { StrBuf *Hrefs; // list of items requested by a `calendar-multiget` REPORT Array *filters; // If the query contains a FILTER stanza, the filter criteria are populated here int filter_nest; // tag nesting level where a FILTER stanza begins + int in_prop; // nonzero if we are within the parsing a stanza? + int yes_getetag; // nonzero if client has requested the "getetag" property + int yes_calendar_data; // nonzero if client has requested the "calendar-data" property }; @@ -43,6 +46,32 @@ void caldav_xml_start(void *data, const char *el, const char **attr) { // end logging #endif + // if we are already within a webdav prop stanza, child nodes name properties the client wants to receive. + if (crp->in_prop) { + syslog(LOG_DEBUG, "\033[41m\033[37m\033[1mprop:%s\033[0m", el); + + if (!strcasecmp(el, "DAV::getetag")) { + crp->yes_getetag = 1; + } + else if (!strcasecmp(el, CALDAV"calendar-data")) { + crp->yes_calendar_data = 1; + } + + return; + } + + // webdav prop (not caldav "prop") element + if (!strcasecmp(el, "DAV::prop")) { + ++crp->in_prop; + syslog(LOG_DEBUG, "\033[41m\033[37m\033[1mprop:%d\033[0m", crp->in_prop); + } + + // webdav allprop (not caldav "allprop") element + if (!strcasecmp(el, "DAV::allprop")) { + crp->yes_getetag = 1; + crp->yes_calendar_data = 1; + } + // RFC4791 7.8 "calendar-query" REPORT - Client will send a lot of search criteria. if (!strcasecmp(el, CALDAV"calendar-query")) { crp->report_type = cr_calendar_query; @@ -102,11 +131,16 @@ void caldav_xml_end(void *data, const char *el) { // end logging #endif + // webdav prop (not caldav "prop") filter + if (!strcasecmp(el, "DAV::prop")) { + --crp->in_prop; + syslog(LOG_DEBUG, "\033[41m\033[37m\033[1mprop:%d\033[0m", crp->in_prop); + } + if (!strcasecmp(el, CALDAV"comp-filter")) { --crp->comp_filter_nesting_level; } - if ((!strcasecmp(el, "DAV::href")) || (!strcasecmp(el, "DAV:href"))) { if (crp->Hrefs == NULL) { // append crp->Chardata to crp->Hrefs crp->Hrefs = NewStrBuf(); @@ -186,7 +220,7 @@ StrBuf *fetch_ical(struct ctdlsession *c, long msgnum) { // Called by multiple REPORT types to actually perform the output in "multiget" format. // We need to already know the source message number and the href, but also already have the output data. -void cal_multiget_out(long msgnum, StrBuf *ThisHref, StrBuf *Caldata, StrBuf *ReportOut) { +void cal_multiget_out(long msgnum, StrBuf *ThisHref, StrBuf *Caldata, StrBuf *ReportOut, struct cr_params *crp) { StrBufAppendPrintf(ReportOut, ""); StrBufAppendPrintf(ReportOut, ""); @@ -200,12 +234,19 @@ void cal_multiget_out(long msgnum, StrBuf *ThisHref, StrBuf *Caldata, StrBuf *Re StrBufAppendPrintf(ReportOut, "HTTP/1.1 200 OK"); StrBufAppendPrintf(ReportOut, ""); StrBufAppendPrintf(ReportOut, ""); - StrBufAppendPrintf(ReportOut, ""); - StrBufAppendPrintf(ReportOut, "%ld", msgnum); - StrBufAppendPrintf(ReportOut, ""); - StrBufAppendPrintf(ReportOut, ""); - StrBufXMLEscAppend(ReportOut, Caldata, NULL, 0, 0); - StrBufAppendPrintf(ReportOut, ""); + + if (crp->yes_getetag) { + StrBufAppendPrintf(ReportOut, ""); + StrBufAppendPrintf(ReportOut, "%ld", msgnum); + StrBufAppendPrintf(ReportOut, ""); + } + + if (crp->yes_calendar_data) { + StrBufAppendPrintf(ReportOut, ""); + StrBufXMLEscAppend(ReportOut, Caldata, NULL, 0, 0); + StrBufAppendPrintf(ReportOut, ""); + } + StrBufAppendPrintf(ReportOut, ""); } else { @@ -222,7 +263,7 @@ void cal_multiget_out(long msgnum, StrBuf *ThisHref, StrBuf *Caldata, StrBuf *Re // 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_report_one_item(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, struct cr_params *crp) { long msgnum; StrBuf *Caldata = NULL; char *euid; @@ -250,7 +291,7 @@ void caldav_report_one_item(struct http_transaction *h, struct ctdlsession *c, S Caldata = NULL; } - cal_multiget_out(msgnum, ThisHref, Caldata, ReportOut); + cal_multiget_out(msgnum, ThisHref, Caldata, ReportOut, crp); if (Caldata != NULL) { FreeStrBuf(&Caldata); @@ -325,23 +366,23 @@ int caldav_apply_filters(void *cal, Array *filters, int apply_at_level) { ++num_tokens; } int this_rule_level = atoi(t[0]); - syslog(LOG_DEBUG, "caldav_apply_filters() filter=%d, level=%d, <%s>", f, this_rule_level, array_get_element_at(filters, f) ); + // syslog(LOG_DEBUG, "caldav_apply_filters() filter=%d, level=%d, <%s>", f, this_rule_level, array_get_element_at(filters, f) ); // Handle the individual filters defined in RFC4791 9.7.1 through 9.7.5 if (apply_at_level < previous_level) { - syslog(LOG_DEBUG, "caldav: walking back down"); + // syslog(LOG_DEBUG, "caldav: walking back down"); return(qual); } else if (this_rule_level != apply_at_level) { - syslog(LOG_DEBUG, "caldav: apply_at_level=%d, this_rule_level=%d, skipping this rule", apply_at_level, this_rule_level); + // syslog(LOG_DEBUG, "caldav: apply_at_level=%d, this_rule_level=%d, skipping this rule", apply_at_level, this_rule_level); } else if ( (!strcasecmp(t[1], "comp-filter")) // RFC4791 9.7.1 - filter by component && (!disregard_further_comp_filters) // one is enough to succeed ) { - syslog(LOG_DEBUG, "component filter at level %d", this_rule_level); + // syslog(LOG_DEBUG, "component filter at level %d", this_rule_level); // comp-filter requires exactly one parameter (name="VXXXX") if (num_tokens < 4) { @@ -360,10 +401,10 @@ int caldav_apply_filters(void *cal, Array *filters, int apply_at_level) { && (!strcasecmp(t[2], "name")) ) { if (icalcomponent_isa(cal) == icalcomponent_string_to_kind(t[3]) ) { - syslog(LOG_DEBUG, "caldav: component at level %d is <%s>, looking for <%s>, recursing...", - apply_at_level, - icalcomponent_kind_to_string(icalcomponent_isa(cal)), t[3] - ); + // syslog(LOG_DEBUG, "caldav: component at level %d is <%s>, looking for <%s>, recursing...", + //apply_at_level, + //icalcomponent_kind_to_string(icalcomponent_isa(cal)), t[3] + //); // We have a match. Drill down into the subcomponents. @@ -391,11 +432,11 @@ int caldav_apply_filters(void *cal, Array *filters, int apply_at_level) { } else { - syslog(LOG_DEBUG, "caldav: component at level %d is <%s>, looking for <%s>, rejecting", - apply_at_level, - icalcomponent_kind_to_string(icalcomponent_isa(cal)), - t[3] - ); + //syslog(LOG_DEBUG, "caldav: component at level %d is <%s>, looking for <%s>, rejecting", + //apply_at_level, + //icalcomponent_kind_to_string(icalcomponent_isa(cal)), + //t[3] + //); return(0); } } @@ -442,7 +483,7 @@ int caldav_apply_filters(void *cal, Array *filters, int apply_at_level) { ++f; } - syslog(LOG_DEBUG, "caldav: we reached the end of level %d , returning %d", apply_at_level, qual); + // syslog(LOG_DEBUG, "caldav: we reached the end of level %d , returning %d", apply_at_level, qual); return(qual); } @@ -463,8 +504,6 @@ void caldav_report(struct http_transaction *h, struct ctdlsession *c) { return; } - syslog(LOG_DEBUG, "\033[31mREPORT QUERY: %s\033[0m", h->request_body); - XML_SetElementHandler(xp, caldav_xml_start, caldav_xml_end); XML_SetCharacterDataHandler(xp, caldav_xml_chardata); XML_SetUserData(xp, &crp); @@ -504,19 +543,19 @@ void caldav_report(struct http_transaction *h, struct ctdlsession *c) { icalcomponent *cal = icalcomponent_new_from_string(ChrPtr(one_item)); // Does this calendar item qualify for output? Run this calendar item through the filters. - syslog(LOG_DEBUG, "Evaluating message \033[33m%ld\033[0m...", m); + // syslog(LOG_DEBUG, "Evaluating message \033[33m%ld\033[0m...", m); if (caldav_apply_filters(cal, crp.filters, 0)) { syslog(LOG_DEBUG, "Message %ld \033[32mQUALIFIES\033[0m", m); // FIXME need to populate the Href instead of NULL StrBuf *FIXME = NewStrBufPlain(HKEY("https://FIX.ME.COM/WOW/EEK")); - cal_multiget_out(m, FIXME, one_item, ReportOut); + cal_multiget_out(m, FIXME, one_item, ReportOut, &crp); } else { syslog(LOG_DEBUG, "Message %ld \033[31mDOES NOT QUALIFY\033[0m", m); } - syslog(LOG_DEBUG, ""); + // syslog(LOG_DEBUG, ""); icalcomponent_free(cal); FreeStrBuf(&one_item); @@ -534,7 +573,7 @@ void caldav_report(struct http_transaction *h, struct ctdlsession *c) { const char *pvset = NULL; while (StrBufExtract_NextToken(ThisHref, crp.Hrefs, &pvset, '|') >= 0) { StrBufTrim(ThisHref); // remove leading/trailing whitespace from the href - caldav_report_one_item(h, c, ReportOut, ThisHref); + caldav_report_one_item(h, c, ReportOut, ThisHref, &crp); } FreeStrBuf(&ThisHref); }