From 3a673adcc2ffde7ae38f14677efa288c4173d159 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 14 Feb 2024 12:03:02 -0500 Subject: [PATCH] Filters defined in RFC4791 9.7.1-9.7.5: DRY ingest The code to parse these XML stanzas and ingest them into our filter list was getting quite redundant. This commit abstracts them into a single handler. --- webcit-ng/server/caldav_reports.c | 88 ++++++++++++++----------------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/webcit-ng/server/caldav_reports.c b/webcit-ng/server/caldav_reports.c index b28554e0c..f4eb6c06a 100644 --- a/webcit-ng/server/caldav_reports.c +++ b/webcit-ng/server/caldav_reports.c @@ -69,53 +69,25 @@ void caldav_xml_start(void *data, const char *el, const char **attr) { crp->filters = array_new(SIZ); } - // RFC4791 9.7.1 CALDAV:comp-filter XML Element - else if ( (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:comp-filter")) - && (crp->filters) - && (attr[0]) - && (attr[1]) + // Handle the filters defined in RFC4791 9.7.1 through 9.7.5 + else if ( ( (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:comp-filter")) + || (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:prop-filter")) + || (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:param-filter")) + || (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:is-not-defined")) + || (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:text-match")) + ) + && (crp->filters) // Make sure we actually allocated an array ) { char newfilter[SIZ]; - snprintf(newfilter, SIZ, "comp-filter|%s|%s", attr[0], attr[1]); + int a = 0; + int len = snprintf(newfilter, SIZ, &el[23]); // strip off "urn:ietf:params:xml:ns:caldav:" for our purposes + while (attr[a]) { + len += snprintf(&newfilter[len], SIZ-len, "|%s", attr[a++]); // now save the attributes + } array_append(crp->filters, newfilter); syslog(LOG_DEBUG, "%s", newfilter); } - // RFC4791 9.7.2 CALDAV:prop-filter XML Element - else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:prop-filter")) { - if (crp->filters) { - char newfilter[SIZ]; - snprintf(newfilter, SIZ, "hi there"); - array_append(crp->filters, newfilter); - } - } - - // RFC4791 9.7.3 CALDAV:param-filter XML Element - else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:param-filter")) { - if (crp->filters) { - char newfilter[SIZ]; - snprintf(newfilter, SIZ, "hi there"); - array_append(crp->filters, newfilter); - } - } - - // RFC4791 9.7.4 CALDAV:is-not-defined XML Element - else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:is-not-defined")) { - if (crp->filters) { - char newfilter[SIZ]; - snprintf(newfilter, SIZ, "hi there"); - array_append(crp->filters, newfilter); - } - } - - // RFC4791 9.7.5 CALDAV:text-match XML Element - else if (!strcasecmp(el, "urn:ietf:params:xml:ns:caldav:text-match")) { - if (crp->filters) { - char newfilter[SIZ]; - snprintf(newfilter, SIZ, "hi there"); - array_append(crp->filters, newfilter); - } - } } @@ -293,8 +265,31 @@ void caldav_report_one_item(struct http_transaction *h, struct ctdlsession *c, S } -void caldav_apply_filter(struct cr_params *crp, char *xml_body, long xml_length) { - TRACE; +// Called by caldav_apply_filters() to apply ONE filter. +// Returns 0 if the calendar item does not match the filter. +// Returns 1 if the calendar item DOES match the filter. +int caldav_apply_one_filter(void *cal, char *filter) { + syslog(LOG_DEBUG, "applying filter: %s", filter); + return(1); +} + + +// Recursive function to apply CalDAV FILTERS to a calendar item. +// Returns zero if the calendar item was disqualified by a filter, nonzero if the calendar item still qualifies. +int caldav_apply_filters(void *cal, Array *filters, int index) { + + // Apply *this* filter. + if (caldav_apply_one_filter(cal, array_get_element_at(filters, index)) == 0) { + return(0); + } + + // If we get to this point, the current filter has passed, and we move on to the next one. + if (index < array_len(filters)-1) { + return(caldav_apply_filters(cal, filters, index+1)); + } + + // If we got this far, every filter passed, and the calendar item qualifies for output. + return(1); } @@ -358,10 +353,9 @@ void caldav_report(struct http_transaction *h, struct ctdlsession *c) { // Does this calendar item qualify for output? int qualify = 1; - // FIXME put filters here - if (crp.filters) { - // apply the filters - } + // If there was a filter stanza, run this calendar item through the filters. + qualify = caldav_apply_filters(cal, crp.filters, 0); + syslog(LOG_DEBUG, "Message %ld does%s qualify", m, (qualify ? "" : " NOT")); // Did this calendar item match the query? If so, output it. if (qualify) { -- 2.30.2