summaryrefslogtreecommitdiff
path: root/res/res_calendar_caldav.c
diff options
context:
space:
mode:
authorSean Bright <sean.bright@gmail.com>2017-09-13 15:08:39 -0400
committerSean Bright <sean.bright@gmail.com>2017-09-13 14:47:21 -0500
commitd8112cd98b5f8c8402e04220018b6a96f789869d (patch)
treee0c9b4d4ec062c436944cd1afab6e63554c48e2c /res/res_calendar_caldav.c
parentec940f4fec4e216b30be562a31ec3586f7d302c3 (diff)
res_calendar: Various fixes
* The way that we were looking at XML elements for CalDAV was extremely fragile, so use SAX2 for increased robustness. * Don't complain about a 'channel' not be specified if autoreminder is not set. Assume that if 'channel' is not set, we don't want to be notified. * Fix some truncated CLI output in 'calendar show calendar' and make the 'Autoreminder' description a bit more clear ASTERISK-24588 #close Reported by: Stefan Gofferje ASTERISK-25523 #close Reported by: Jesper Change-Id: I200d11afca6a47e7d97888f286977e2e69874b2c
Diffstat (limited to 'res/res_calendar_caldav.c')
-rw-r--r--res/res_calendar_caldav.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/res/res_calendar_caldav.c b/res/res_calendar_caldav.c
index 3c1c74a4c..b6822b085 100644
--- a/res/res_calendar_caldav.c
+++ b/res/res_calendar_caldav.c
@@ -156,6 +156,7 @@ static struct ast_str *caldav_request(struct caldav_pvt *pvt, const char *method
ne_add_response_body_reader(req, debug_response_handler, fetch_response_reader, &response);
ne_set_request_body_buffer(req, ast_str_buffer(req_body), ast_str_strlen(req_body));
ne_add_request_header(req, "Content-type", ast_strlen_zero(content_type) ? "text/xml" : content_type);
+ ne_add_request_header(req, "Depth", "1");
ret = ne_request_dispatch(req);
ne_request_destroy(req);
@@ -476,17 +477,26 @@ struct xmlstate {
time_t end;
};
-static void handle_start_element(void *data, const xmlChar *fullname, const xmlChar **atts)
+static const xmlChar *caldav_node_localname = BAD_CAST "calendar-data";
+static const xmlChar *caldav_node_nsuri = BAD_CAST "urn:ietf:params:xml:ns:caldav";
+
+static void handle_start_element(void *data,
+ const xmlChar *localname, const xmlChar *prefix, const xmlChar *uri,
+ int nb_namespaces, const xmlChar **namespaces,
+ int nb_attributes, int nb_defaulted, const xmlChar **attributes)
{
struct xmlstate *state = data;
- if (!xmlStrcasecmp(fullname, BAD_CAST "C:calendar-data") || !xmlStrcasecmp(fullname, BAD_CAST "caldav:calendar-data")) {
- state->in_caldata = 1;
- ast_str_reset(state->cdata);
+ if (xmlStrcmp(localname, caldav_node_localname) || xmlStrcmp(uri, caldav_node_nsuri)) {
+ return;
}
+
+ state->in_caldata = 1;
+ ast_str_reset(state->cdata);
}
-static void handle_end_element(void *data, const xmlChar *name)
+static void handle_end_element(void *data,
+ const xmlChar *localname, const xmlChar *prefix, const xmlChar *uri)
{
struct xmlstate *state = data;
struct icaltimetype start, end;
@@ -494,7 +504,7 @@ static void handle_end_element(void *data, const xmlChar *name)
icalcomponent *iter;
icalcomponent *comp;
- if (xmlStrcasecmp(name, BAD_CAST "C:calendar-data") && xmlStrcasecmp(name, BAD_CAST "caldav:calendar-data")) {
+ if (xmlStrcmp(localname, caldav_node_localname) || xmlStrcmp(uri, caldav_node_nsuri)) {
return;
}
@@ -557,9 +567,23 @@ static int update_caldav(struct caldav_pvt *pvt)
state.start = start;
state.end = end;
+ /*
+ * We want SAX2, so you assume that we want to call xmlSAXVersion() here, and
+ * that certainly seems like the right thing to do, but the default SAX
+ * handling functions assume that the 'data' pointer is going to be a
+ * xmlParserCtxtPtr, not a user data pointer, so we have to make sure that we
+ * are only calling the handlers that we control.
+ *
+ * So instead we hack things up a bit, clearing the struct and then assigning
+ * the magic number manually.
+ *
+ * There may be a cleaner way to do this, but frankly the libxml2 docs are
+ * pretty sparse.
+ */
memset(&saxHandler, 0, sizeof(saxHandler));
- saxHandler.startElement = handle_start_element;
- saxHandler.endElement = handle_end_element;
+ saxHandler.initialized = XML_SAX2_MAGIC;
+ saxHandler.startElementNs = handle_start_element;
+ saxHandler.endElementNs = handle_end_element;
saxHandler.characters = handle_characters;
xmlSAXUserParseMemory(&saxHandler, &state, ast_str_buffer(response), ast_str_strlen(response));