[evolution-data-server] Bug 766747 - WebDAV discovery for GMX CalDAV server fails
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 766747 - WebDAV discovery for GMX CalDAV server fails
- Date: Tue, 24 May 2016 14:19:00 +0000 (UTC)
commit f32ad370c4faf3b11502b4b0b6161005eb9bcd00
Author: Milan Crha <mcrha redhat com>
Date: Tue May 24 16:18:54 2016 +0200
Bug 766747 - WebDAV discovery for GMX CalDAV server fails
libedataserver/e-webdav-discover.c | 282 ++++++++++++++++++++++++++----------
1 files changed, 202 insertions(+), 80 deletions(-)
---
diff --git a/libedataserver/e-webdav-discover.c b/libedataserver/e-webdav-discover.c
index 6eb3432..fcd51bb 100644
--- a/libedataserver/e-webdav-discover.c
+++ b/libedataserver/e-webdav-discover.c
@@ -614,7 +614,8 @@ e_webdav_discover_process_user_address_set (xmlXPathContextPtr xp_ctx,
static guint32
e_webdav_discover_get_supported_component_set (xmlXPathContextPtr xp_ctx,
- gint index)
+ gint response_index,
+ gint propstat_index)
{
xmlXPathObjectPtr xp_obj;
guint32 set = 0;
@@ -624,10 +625,12 @@ e_webdav_discover_get_supported_component_set (xmlXPathContextPtr xp_ctx,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/C:supported-calendar-component-set"
- "/C:comp", index);
+ "/C:comp",
+ response_index,
+ propstat_index);
/* If the property is not present, assume all component
* types are supported. (RFC 4791, Section 5.2.3) */
@@ -645,11 +648,14 @@ e_webdav_discover_get_supported_component_set (xmlXPathContextPtr xp_ctx,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/C:supported-calendar-component-set"
"/C:comp[%d]"
- "/@name", index, ii + 1);
+ "/@name",
+ response_index,
+ propstat_index,
+ ii + 1);
if (name == NULL)
continue;
@@ -670,10 +676,11 @@ e_webdav_discover_get_supported_component_set (xmlXPathContextPtr xp_ctx,
}
static void
-e_webdav_discover_process_calendar_response (SoupMessage *message,
- xmlXPathContextPtr xp_ctx,
- gint index,
- GSList **out_discovered_sources)
+e_webdav_discover_process_calendar_response_propstat (SoupMessage *message,
+ xmlXPathContextPtr xp_ctx,
+ gint response_index,
+ gint propstat_index,
+ GSList **out_discovered_sources)
{
xmlXPathObjectPtr xp_obj;
guint32 comp_set;
@@ -693,9 +700,10 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:status",
- index);
+ response_index,
+ propstat_index);
if (status_line == NULL)
return;
@@ -708,7 +716,7 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
if (!success || status != SOUP_STATUS_OK)
return;
- comp_set = e_webdav_discover_get_supported_component_set (xp_ctx, index);
+ comp_set = e_webdav_discover_get_supported_component_set (xp_ctx, response_index, propstat_index);
if (comp_set == E_WEBDAV_DISCOVER_SUPPORTS_NONE)
return;
@@ -717,7 +725,7 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
"/D:multistatus"
"/D:response[%d]"
"/D:href",
- index);
+ response_index);
if (href_encoded == NULL)
return;
@@ -728,11 +736,12 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/D:resourcetype"
"/C:calendar",
- index);
+ response_index,
+ propstat_index);
if (xp_obj == NULL) {
g_free (href_encoded);
@@ -747,10 +756,11 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/D:displayname",
- index);
+ response_index,
+ propstat_index);
if (display_name == NULL) {
gchar *href_decoded = soup_uri_decode (href_encoded);
@@ -776,10 +786,11 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/C:calendar-description",
- index);
+ response_index,
+ propstat_index);
/* Get the color specification string. */
@@ -787,10 +798,11 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/IC:calendar-color",
- index);
+ response_index,
+ propstat_index);
discovered_source = g_new0 (EWebDAVDiscoveredSource, 1);
discovered_source->href = e_webdav_discover_make_href_full_uri (soup_message_get_uri (message),
href_encoded);
@@ -807,6 +819,56 @@ e_webdav_discover_process_calendar_response (SoupMessage *message,
g_free (color_spec);
}
+static void
+e_webdav_discover_traverse_responses (SoupMessage *message,
+ xmlXPathContextPtr xp_ctx,
+ GSList **out_discovered_sources,
+ void (* func) (
+ SoupMessage *message,
+ xmlXPathContextPtr xp_ctx,
+ gint response_index,
+ gint propstat_index,
+ GSList **out_discovered_sources))
+{
+ xmlXPathObjectPtr xp_obj_response;
+
+ xp_obj_response = e_webdav_discover_get_xpath (
+ xp_ctx,
+ "/D:multistatus"
+ "/D:response");
+
+ if (xp_obj_response != NULL) {
+ gint response_index, response_length;
+
+ response_length = xmlXPathNodeSetGetLength (xp_obj_response->nodesetval);
+
+ for (response_index = 0; response_index < response_length; response_index++) {
+ xmlXPathObjectPtr xp_obj_propstat;
+
+ xp_obj_propstat = e_webdav_discover_get_xpath (
+ xp_ctx,
+ "/D:multistatus"
+ "/D:response[%d]"
+ "/D:propstat",
+ response_index + 1);
+
+ if (xp_obj_propstat != NULL) {
+ gint propstat_index, propstat_length;
+
+ propstat_length = xmlXPathNodeSetGetLength (xp_obj_propstat->nodesetval);
+
+ for (propstat_index = 0; propstat_index < propstat_length; propstat_index++) {
+ func (message, xp_ctx, response_index + 1, propstat_index + 1,
out_discovered_sources);
+ }
+
+ xmlXPathFreeObject (xp_obj_propstat);
+ }
+ }
+
+ xmlXPathFreeObject (xp_obj_response);
+ }
+}
+
static gboolean
e_webdav_discover_get_calendar_collection_details (SoupSession *session,
SoupMessage *message,
@@ -820,8 +882,8 @@ e_webdav_discover_get_calendar_collection_details (SoupSession *session,
{
xmlDocPtr doc;
xmlXPathContextPtr xp_ctx;
- xmlXPathObjectPtr xp_obj;
SoupURI *soup_uri;
+ GError *local_error = NULL;
if (g_cancellable_is_cancelled (cancellable))
return FALSE;
@@ -856,11 +918,38 @@ e_webdav_discover_get_calendar_collection_details (SoupSession *session,
/* This takes ownership of the message. */
soup_session_send_message (session, message);
+ if (message->status_code == SOUP_STATUS_BAD_REQUEST) {
+ g_clear_object (&message);
+
+ message = e_webdav_discover_new_propfind (
+ session, soup_uri, DEPTH_0,
+ NS_WEBDAV, XC ("displayname"),
+ NS_WEBDAV, XC ("resourcetype"),
+ NS_CALDAV, XC ("calendar-description"),
+ NS_CALDAV, XC ("supported-calendar-component-set"),
+ NS_CALDAV, XC ("calendar-user-address-set"),
+ NS_ICAL, XC ("calendar-color"),
+ NULL);
+
+ e_soup_ssl_trust_connect (message, source);
+ soup_session_send_message (session, message);
+ }
+
soup_uri_free (soup_uri);
- doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, error);
+ doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, &local_error);
if (!doc) {
g_clear_object (&message);
+
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ /* Ignore these errors */
+ g_clear_error (&local_error);
+ return TRUE;
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
+
return FALSE;
}
@@ -870,22 +959,8 @@ e_webdav_discover_get_calendar_collection_details (SoupSession *session,
xmlXPathRegisterNs (xp_ctx, XC ("A"), XC (NS_CARDDAV));
xmlXPathRegisterNs (xp_ctx, XC ("IC"), XC (NS_ICAL));
- xp_obj = e_webdav_discover_get_xpath (
- xp_ctx,
- "/D:multistatus"
- "/D:response");
-
- if (xp_obj != NULL) {
- gint length, ii;
-
- length = xmlXPathNodeSetGetLength (xp_obj->nodesetval);
-
- for (ii = 0; ii < length; ii++)
- e_webdav_discover_process_calendar_response (
- message, xp_ctx, ii + 1, out_discovered_sources);
-
- xmlXPathFreeObject (xp_obj);
- }
+ e_webdav_discover_traverse_responses (message, xp_ctx, out_discovered_sources,
+ e_webdav_discover_process_calendar_response_propstat);
xmlXPathFreeContext (xp_ctx);
xmlFreeDoc (doc);
@@ -911,6 +986,7 @@ e_webdav_discover_process_calendar_home_set (SoupSession *session,
xmlXPathContextPtr xp_ctx;
xmlXPathObjectPtr xp_obj;
gchar *calendar_home_set;
+ GError *local_error = NULL;
gboolean success;
g_return_val_if_fail (SOUP_IS_SESSION (session), FALSE);
@@ -921,10 +997,20 @@ e_webdav_discover_process_calendar_home_set (SoupSession *session,
if (g_cancellable_is_cancelled (cancellable))
return FALSE;
- doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, error);
+ doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, &local_error);
+
+ if (!doc) {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ /* Ignore these errors */
+ g_clear_error (&local_error);
+ return TRUE;
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
- if (!doc)
return FALSE;
+ }
xp_ctx = xmlXPathNewContext (doc);
xmlXPathRegisterNs (xp_ctx, XC ("D"), XC (NS_WEBDAV));
@@ -1078,6 +1164,19 @@ e_webdav_discover_process_calendar_home_set (SoupSession *session,
/* This takes ownership of the message. */
soup_session_send_message (session, message);
+ if (message->status_code == SOUP_STATUS_BAD_REQUEST) {
+ g_clear_object (&message);
+
+ message = e_webdav_discover_new_propfind (
+ session, soup_uri, DEPTH_0,
+ NS_CALDAV, XC ("calendar-home-set"),
+ NS_CALDAV, XC ("calendar-user-address-set"),
+ NULL);
+
+ e_soup_ssl_trust_connect (message, source);
+ soup_session_send_message (session, message);
+ }
+
soup_uri_free (soup_uri);
g_free (calendar_home_set);
@@ -1092,10 +1191,11 @@ e_webdav_discover_process_calendar_home_set (SoupSession *session,
}
static void
-e_webdav_discover_process_addressbook_response (SoupMessage *message,
- xmlXPathContextPtr xp_ctx,
- gint index,
- GSList **out_discovered_sources)
+e_webdav_discover_process_addressbook_response_propstat (SoupMessage *message,
+ xmlXPathContextPtr xp_ctx,
+ gint response_index,
+ gint propstat_index,
+ GSList **out_discovered_sources)
{
xmlXPathObjectPtr xp_obj;
gchar *display_name;
@@ -1113,9 +1213,10 @@ e_webdav_discover_process_addressbook_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:status",
- index);
+ response_index,
+ propstat_index);
if (status_line == NULL)
return;
@@ -1133,7 +1234,7 @@ e_webdav_discover_process_addressbook_response (SoupMessage *message,
"/D:multistatus"
"/D:response[%d]"
"/D:href",
- index);
+ response_index);
if (href_encoded == NULL)
return;
@@ -1144,11 +1245,12 @@ e_webdav_discover_process_addressbook_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/D:resourcetype"
"/A:addressbook",
- index);
+ response_index,
+ propstat_index);
if (xp_obj == NULL) {
g_free (href_encoded);
@@ -1163,10 +1265,11 @@ e_webdav_discover_process_addressbook_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/D:displayname",
- index);
+ response_index,
+ propstat_index);
if (display_name == NULL) {
gchar *href_decoded = soup_uri_decode (href_encoded);
@@ -1192,10 +1295,11 @@ e_webdav_discover_process_addressbook_response (SoupMessage *message,
xp_ctx,
"/D:multistatus"
"/D:response[%d]"
- "/D:propstat"
+ "/D:propstat[%d]"
"/D:prop"
"/A:addressbook-description",
- index);
+ response_index,
+ propstat_index);
discovered_source = g_new0 (EWebDAVDiscoveredSource, 1);
discovered_source->href = e_webdav_discover_make_href_full_uri (soup_message_get_uri (message),
href_encoded);
@@ -1224,8 +1328,8 @@ e_webdav_discover_get_addressbook_collection_details (SoupSession *session,
{
xmlDocPtr doc;
xmlXPathContextPtr xp_ctx;
- xmlXPathObjectPtr xp_obj;
SoupURI *soup_uri;
+ GError *local_error = NULL;
if (g_cancellable_is_cancelled (cancellable))
return FALSE;
@@ -1259,9 +1363,19 @@ e_webdav_discover_get_addressbook_collection_details (SoupSession *session,
soup_uri_free (soup_uri);
- doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, error);
+ doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, &local_error);
if (!doc) {
g_clear_object (&message);
+
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ /* Ignore these errors */
+ g_clear_error (&local_error);
+ return TRUE;
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
+
return FALSE;
}
@@ -1271,22 +1385,8 @@ e_webdav_discover_get_addressbook_collection_details (SoupSession *session,
xmlXPathRegisterNs (xp_ctx, XC ("A"), XC (NS_CARDDAV));
xmlXPathRegisterNs (xp_ctx, XC ("IC"), XC (NS_ICAL));
- xp_obj = e_webdav_discover_get_xpath (
- xp_ctx,
- "/D:multistatus"
- "/D:response");
-
- if (xp_obj != NULL) {
- gint length, ii;
-
- length = xmlXPathNodeSetGetLength (xp_obj->nodesetval);
-
- for (ii = 0; ii < length; ii++)
- e_webdav_discover_process_addressbook_response (
- message, xp_ctx, ii + 1, out_discovered_sources);
-
- xmlXPathFreeObject (xp_obj);
- }
+ e_webdav_discover_traverse_responses (message, xp_ctx, out_discovered_sources,
+ e_webdav_discover_process_addressbook_response_propstat);
xmlXPathFreeContext (xp_ctx);
xmlFreeDoc (doc);
@@ -1311,6 +1411,7 @@ e_webdav_discover_process_addressbook_home_set (SoupSession *session,
xmlXPathContextPtr xp_ctx;
xmlXPathObjectPtr xp_obj;
gchar *addressbook_home_set;
+ GError *local_error = NULL;
gboolean success;
g_return_val_if_fail (SOUP_IS_SESSION (session), FALSE);
@@ -1321,10 +1422,19 @@ e_webdav_discover_process_addressbook_home_set (SoupSession *session,
if (g_cancellable_is_cancelled (cancellable))
return FALSE;
- doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, error);
+ doc = e_webdav_discover_parse_xml (message, "multistatus", out_certificate_pem,
out_certificate_errors, &local_error);
+ if (!doc) {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ /* Ignore these errors */
+ g_clear_error (&local_error);
+ return TRUE;
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
- if (!doc)
return FALSE;
+ }
xp_ctx = xmlXPathNewContext (doc);
xmlXPathRegisterNs (xp_ctx, XC ("D"), XC (NS_WEBDAV));
@@ -1782,6 +1892,7 @@ e_webdav_discover_sources_sync (ESource *source,
session,
SOUP_SESSION_ACCEPT_LANGUAGE_AUTO, TRUE,
NULL);
+
message = e_webdav_discover_new_propfind (
session, soup_uri, DEPTH_0,
NS_WEBDAV, XC ("resourcetype"),
@@ -1872,11 +1983,14 @@ e_webdav_discover_sources_sync (ESource *source,
if (!calendars && !g_cancellable_is_cancelled (cancellable) && (!soup_uri_get_path
(soup_uri) ||
!strstr (soup_uri_get_path (soup_uri), "/.well-known/"))) {
- g_clear_object (&message);
+ SoupMessage *well_known_message;
+ gchar *saved_path;
+
+ saved_path = g_strdup (soup_uri_get_path (soup_uri));
soup_uri_set_path (soup_uri, "/.well-known/caldav");
- message = e_webdav_discover_new_propfind (
+ well_known_message = e_webdav_discover_new_propfind (
session, soup_uri, DEPTH_0,
NS_WEBDAV, XC ("resourcetype"),
NS_WEBDAV, XC ("current-user-principal"),
@@ -1885,12 +1999,18 @@ e_webdav_discover_sources_sync (ESource *source,
NS_CALDAV, XC ("calendar-user-address-set"),
NULL);
- if (message) {
- soup_session_send_message (session, message);
+ soup_uri_set_path (soup_uri, saved_path);
+ g_free (saved_path);
+
+ if (well_known_message) {
+ e_soup_ssl_trust_connect (well_known_message, source);
+ soup_session_send_message (session, well_known_message);
/* Ignore errors here */
- e_webdav_discover_process_calendar_home_set (session, message,
source, out_certificate_pem,
+ e_webdav_discover_process_calendar_home_set (session,
well_known_message, source, out_certificate_pem,
out_certificate_errors, &calendars,
out_calendar_user_addresses, cancellable, NULL);
+
+ g_clear_object (&well_known_message);
}
}
}
@@ -1900,7 +2020,8 @@ e_webdav_discover_sources_sync (ESource *source,
success = e_webdav_discover_process_addressbook_home_set (session, message, source,
out_certificate_pem,
out_certificate_errors, &addressbooks, cancellable, &local_error);
- if (!addressbooks && !g_cancellable_is_cancelled (cancellable)) {
+ if (!addressbooks && !g_cancellable_is_cancelled (cancellable) && (!soup_uri_get_path
(soup_uri) ||
+ !strstr (soup_uri_get_path (soup_uri), "/.well-known/"))) {
g_clear_object (&message);
soup_uri_set_path (soup_uri, "/.well-known/carddav");
@@ -1915,6 +2036,7 @@ e_webdav_discover_sources_sync (ESource *source,
NULL);
if (message) {
+ e_soup_ssl_trust_connect (message, source);
soup_session_send_message (session, message);
/* Ignore errors here */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]