[evolution-data-server] CalDAV: Claim not found objects during refresh as removed
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CalDAV: Claim not found objects during refresh as removed
- Date: Tue, 25 Feb 2020 16:19:27 +0000 (UTC)
commit c05a3374e614c3e9ec5baca0d545e3d76752bedc
Author: Milan Crha <mcrha redhat com>
Date: Tue Feb 25 17:16:57 2020 +0100
CalDAV: Claim not found objects during refresh as removed
Noticed on Google server, which claims existing detached instances
in the REPORT response, but then returns 404 Not Found responses
when trying to get them.
This change claims such objects as removed, which makes them gone also
from the local cache.
.../backends/caldav/e-cal-backend-caldav.c | 89 ++++++++++++++++++----
1 file changed, 75 insertions(+), 14 deletions(-)
---
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index c96f518b1..3f69c4e14 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -394,6 +394,11 @@ ecb_caldav_update_nfo_with_vcalendar (ECalMetaBackendInfo *nfo,
}
}
+typedef struct _MultigetData {
+ GSList *from_link;
+ GSList **out_removed_objects;
+} MultigetData;
+
static gboolean
ecb_caldav_multiget_response_cb (EWebDAVSession *webdav,
xmlXPathContextPtr xpath_ctx,
@@ -403,9 +408,10 @@ ecb_caldav_multiget_response_cb (EWebDAVSession *webdav,
guint status_code,
gpointer user_data)
{
- GSList **from_link = user_data;
+ MultigetData *md = user_data;
- g_return_val_if_fail (from_link != NULL, FALSE);
+ g_return_val_if_fail (md != NULL, FALSE);
+ g_return_val_if_fail (md->from_link != NULL, FALSE);
if (!xpath_prop_prefix) {
e_xml_xpath_context_register_namespaces (xpath_ctx, "C", E_WEBDAV_NS_CALDAV, NULL);
@@ -428,7 +434,7 @@ ecb_caldav_multiget_response_cb (EWebDAVSession *webdav,
if (uid) {
GSList *link;
- for (link = *from_link; link; link = g_slist_next (link)) {
+ for (link = md->from_link; link; link = g_slist_next (link)) {
ECalMetaBackendInfo *nfo = link->data;
if (!nfo)
@@ -437,8 +443,8 @@ ecb_caldav_multiget_response_cb (EWebDAVSession *webdav,
if (g_strcmp0 (nfo->extra, href) == 0) {
/* If the server returns data in the same order as it
had been requested,
then this speeds up lookup for the matching
object. */
- if (link == *from_link)
- *from_link = g_slist_next (*from_link);
+ if (link == md->from_link)
+ md->from_link = g_slist_next (md->from_link);
ecb_caldav_update_nfo_with_vcalendar (nfo, vcalendar,
etag);
@@ -458,7 +464,7 @@ ecb_caldav_multiget_response_cb (EWebDAVSession *webdav,
g_return_val_if_fail (href != NULL, FALSE);
- for (link = *from_link; link; link = g_slist_next (link)) {
+ for (link = md->from_link; link; link = g_slist_next (link)) {
ECalMetaBackendInfo *nfo = link->data;
if (!nfo)
@@ -467,10 +473,14 @@ ecb_caldav_multiget_response_cb (EWebDAVSession *webdav,
if (g_strcmp0 (nfo->extra, href) == 0) {
/* If the server returns data in the same order as it had been requested,
then this speeds up lookup for the matching object. */
- if (link == *from_link)
- *from_link = g_slist_next (*from_link);
+ if (link == md->from_link)
+ md->from_link = g_slist_next (md->from_link);
+
+ if (md->out_removed_objects)
+ *md->out_removed_objects = g_slist_prepend (*md->out_removed_objects,
nfo);
+ else
+ e_cal_meta_backend_info_free (nfo);
- e_cal_meta_backend_info_free (nfo);
link->data = NULL;
break;
@@ -486,6 +496,7 @@ ecb_caldav_multiget_from_sets_sync (ECalBackendCalDAV *cbdav,
EWebDAVSession *webdav,
GSList **in_link,
GSList **set2,
+ GSList **out_removed_objects,
GCancellable *cancellable,
GError **error)
{
@@ -590,8 +601,24 @@ ecb_caldav_multiget_from_sets_sync (ECalBackendCalDAV *cbdav,
g_free (new_uri);
}
- if (!success)
- success = e_webdav_session_get_data_sync (webdav, nfo->extra, NULL, &etag,
&calendar_data, NULL, cancellable, error);
+ if (!success) {
+ GError *local_error = NULL;
+
+ success = e_webdav_session_get_data_sync (webdav, nfo->extra, NULL, &etag,
&calendar_data, NULL, cancellable, &local_error);
+
+ if (!success && g_error_matches (local_error, SOUP_HTTP_ERROR,
SOUP_STATUS_NOT_FOUND)) {
+ if (out_removed_objects)
+ *out_removed_objects = g_slist_prepend (*out_removed_objects,
nfo);
+ else
+ e_cal_meta_backend_info_free (nfo);
+
+ link->data = NULL;
+ g_clear_error (&local_error);
+ continue;
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
+ }
if (success && calendar_data) {
ICalComponent *vcalendar;
@@ -628,10 +655,13 @@ ecb_caldav_multiget_from_sets_sync (ECalBackendCalDAV *cbdav,
if (left_to_go != E_CALDAV_MAX_MULTIGET_AMOUNT &&
!cbdav->priv->is_icloud && success) {
- GSList *from_link = *in_link;
+ MultigetData md;
+
+ md.from_link = *in_link;
+ md.out_removed_objects = out_removed_objects;
success = e_webdav_session_report_sync (webdav, NULL, NULL, xml,
- ecb_caldav_multiget_response_cb, &from_link, NULL, NULL, cancellable, error);
+ ecb_caldav_multiget_response_cb, &md, NULL, NULL, cancellable, error);
}
g_object_unref (xml);
@@ -926,6 +956,7 @@ ecb_caldav_get_changes_sync (ECalMetaBackend *meta_backend,
g_hash_table_destroy (known_items);
if (success && (*out_created_objects || *out_modified_objects)) {
+ ECalCache *cal_cache = e_cal_meta_backend_ref_cache (meta_backend);
GSList *link, *set2 = *out_modified_objects;
if (*out_created_objects) {
@@ -936,8 +967,38 @@ ecb_caldav_get_changes_sync (ECalMetaBackend *meta_backend,
}
do {
- success = ecb_caldav_multiget_from_sets_sync (cbdav, webdav, &link, &set2,
cancellable, &local_error);
+ success = ecb_caldav_multiget_from_sets_sync (cbdav, webdav, &link, &set2,
out_removed_objects, cancellable, &local_error);
} while (success && link);
+
+ for (link = *out_created_objects; link; link = g_slist_next (link)) {
+ ECalMetaBackendInfo *nfo = link->data;
+
+ if (!nfo)
+ continue;
+
+ if (!nfo->uid || !*nfo->uid) {
+ GSList *ids = NULL, *ilink = NULL;
+
+ link->data = NULL;
+
+ if (e_cal_cache_get_ids_with_extra (cal_cache, nfo->extra, &ids, cancellable,
NULL)) {
+ for (ilink = ids; ilink; ilink = g_slist_next (ilink)) {
+ ECalComponentId *id = ilink->data;
+
+ if (id) {
+ *out_removed_objects = g_slist_prepend
(*out_removed_objects,
+ e_cal_meta_backend_info_new
(e_cal_component_id_get_uid (id), nfo->revision, NULL, nfo->extra));
+ }
+ }
+
+ g_slist_free_full (ids, e_cal_component_id_free);
+ }
+
+ e_cal_meta_backend_info_free (nfo);
+ }
+ }
+
+ g_clear_object (&cal_cache);
}
if (local_error) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]