[evolution-ews] Bug 699373 - Refetches full OAB.xml when unchanged



commit 8cd5721040c8b5f302cd45cf5e53afa67e064598
Author: David Woodhouse <David Woodhouse intel com>
Date:   Thu May 2 18:08:28 2013 +0100

    Bug 699373 - Refetches full OAB.xml when unchanged
    
    Use If-None-Match / ETag to avoid the gratuitous refetch

 src/addressbook/e-book-backend-ews.c |   16 ++++++++++++++--
 src/server/e-ews-connection.c        |   26 +++++++++++++++++++++++---
 src/server/e-ews-connection.h        |    4 ++++
 3 files changed, 41 insertions(+), 5 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 930182b..c6796bd 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -2236,8 +2236,10 @@ ebews_start_gal_sync (gpointer data)
        EEwsConnection *oab_cnc;
        GSList *full_l = NULL;
        gboolean ret = TRUE;
+       gboolean is_populated;
        gchar *uncompressed_filename = NULL;
        gchar *password;
+       gchar *old_etag = NULL, *etag = NULL;
        CamelEwsSettings *ews_settings;
 
        cbews = (EBookBackendEws *) data;
@@ -2252,8 +2254,13 @@ ebews_start_gal_sync (gpointer data)
 
        d (printf ("Ewsgal: Fetching oal full details file \n");)
 
+       is_populated = e_book_backend_sqlitedb_get_is_populated (priv->summary, priv->folder_id, NULL);
+       if (is_populated)
+               old_etag = e_book_backend_sqlitedb_get_key_value (
+                       priv->summary, priv->folder_id, "etag", NULL);
+
        if (!e_ews_connection_get_oal_detail_sync (
-               oab_cnc, priv->folder_id, "Full", &full_l,
+               oab_cnc, priv->folder_id, "Full", old_etag, &full_l, &etag,
                priv->cancellable, &error)) {
                ret = FALSE;
                goto exit;
@@ -2268,7 +2275,7 @@ ebews_start_gal_sync (gpointer data)
 
        full = (EwsOALDetails *) full_l->data;
        /* TODO fetch differential updates if available instead of downloading the whole GAL */
-       if (!e_book_backend_sqlitedb_get_is_populated (priv->summary, priv->folder_id, NULL) || 
ews_gal_needs_update (cbews, full, &error)) {
+       if (!is_populated || ews_gal_needs_update (cbews, full, &error)) {
                gchar *seq;
 
                d (printf ("Ewsgal: Downloading full gal \n");)
@@ -2290,6 +2297,8 @@ ebews_start_gal_sync (gpointer data)
                if (!ret)
                        goto exit;
 
+               e_book_backend_sqlitedb_set_key_value (priv->summary, priv->folder_id, "etag", etag, NULL);
+
                seq = g_strdup_printf ("%"G_GUINT32_FORMAT, full->seq);
                ret = e_book_backend_sqlitedb_set_key_value (priv->summary, priv->folder_id, "seq", seq, 
&error);
                g_free (seq);
@@ -2308,6 +2317,9 @@ exit:
                g_clear_error (&error);
        }
 
+       g_free (old_etag);
+       g_free (etag);
+
        /* preserve  the oab file once we are able to decode the differential updates */
        if (uncompressed_filename) {
                g_unlink (uncompressed_filename);
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index d4bd9e9..f1a46e9 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -2431,6 +2431,7 @@ struct _oal_req_data {
 
        GSList *oals;
        GSList *elements;
+       gchar *etag;
 
        GCancellable *cancellable;
        gulong cancel_id;
@@ -2452,6 +2453,7 @@ oal_req_data_free (struct _oal_req_data *data)
 
        g_free (data->oal_id);
        g_free (data->oal_element);
+       g_free (data->etag);
 
        g_slist_free_full (data->oals, (GDestroyNotify) ews_oal_free);
        g_slist_free_full (data->elements, (GDestroyNotify) ews_oal_details_free);
@@ -2542,6 +2544,7 @@ oal_response_cb (SoupSession *soup_session,
 {
        GSimpleAsyncResult *simple;
        struct _oal_req_data *data;
+       const gchar *etag;
        xmlDoc *doc;
        xmlNode *node;
 
@@ -2558,6 +2561,11 @@ oal_response_cb (SoupSession *soup_session,
                goto exit;
        }
 
+       etag = soup_message_headers_get_one(soup_message->response_headers,
+                                           "ETag");
+       if (etag)
+               data->etag = g_strdup(etag);
+
        ews_dump_raw_soup_response (soup_message);
 
        doc = xmlReadMemory (
@@ -2739,7 +2747,9 @@ gboolean
 e_ews_connection_get_oal_detail_sync (EEwsConnection *cnc,
                                       const gchar *oal_id,
                                       const gchar *oal_element,
+                                     const gchar *old_etag,
                                       GSList **elements,
+                                     gchar **etag,
                                       GCancellable *cancellable,
                                       GError **error)
 {
@@ -2752,13 +2762,13 @@ e_ews_connection_get_oal_detail_sync (EEwsConnection *cnc,
        closure = e_async_closure_new ();
 
        e_ews_connection_get_oal_detail (
-               cnc, oal_id, oal_element, cancellable,
-               e_async_closure_callback, closure);
+               cnc, oal_id, oal_element, old_etag,
+               cancellable, e_async_closure_callback, closure);
 
        result = e_async_closure_wait (closure);
 
        success = e_ews_connection_get_oal_detail_finish (
-               cnc, result, elements, error);
+               cnc, result, elements, etag, error);
 
        e_async_closure_free (closure);
 
@@ -2769,6 +2779,7 @@ void
 e_ews_connection_get_oal_detail (EEwsConnection *cnc,
                                  const gchar *oal_id,
                                  const gchar *oal_element,
+                                const gchar *etag,
                                  GCancellable *cancellable,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
@@ -2793,6 +2804,10 @@ e_ews_connection_get_oal_detail (EEwsConnection *cnc,
                return;
        }
 
+       if (etag)
+               soup_message_headers_append (soup_message->request_headers,
+                                            "If-None-Match", etag);
+
        data = g_slice_new0 (struct _oal_req_data);
        data->cnc = g_object_ref (cnc);
        data->soup_message = soup_message;  /* the session owns this */
@@ -2822,6 +2837,7 @@ gboolean
 e_ews_connection_get_oal_detail_finish (EEwsConnection *cnc,
                                         GAsyncResult *result,
                                         GSList **elements,
+                                       gchar **etag,
                                         GError **error)
 {
        GSimpleAsyncResult *simple;
@@ -2843,6 +2859,10 @@ e_ews_connection_get_oal_detail_finish (EEwsConnection *cnc,
                *elements = data->elements;
                data->elements = NULL;
        }
+       if (etag != NULL) {
+               *etag = data->etag;
+               data->etag = NULL;
+       }
 
        return TRUE;
 
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 3ecac5c..6a6fd16 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -802,12 +802,15 @@ gboolean  e_ews_connection_get_oal_detail_sync
                                                (EEwsConnection *cnc,
                                                 const gchar *oal_id,
                                                 const gchar *oal_element,
+                                                const gchar *old_etag,
                                                 GSList **elements,
+                                                gchar **etag,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_ews_connection_get_oal_detail (EEwsConnection *cnc,
                                                 const gchar *oal_id,
                                                 const gchar *oal_element,
+                                                const gchar *etag,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
@@ -815,6 +818,7 @@ gboolean    e_ews_connection_get_oal_detail_finish
                                                (EEwsConnection *cnc,
                                                 GAsyncResult *result,
                                                 GSList **elements,
+                                                gchar **etag,
                                                 GError **error);
 
 void           e_ews_connection_get_free_busy  (EEwsConnection *cnc,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]