[geocode-glib] lib: Use libsoup directly for HTTP GET requests



commit d00059f114e19de706f5226ec9bd2c3319ded739
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Thu Jun 20 16:57:09 2013 +0200

    lib: Use libsoup directly for HTTP GET requests
    
    We should be doing this anyways, libsoup being our direct dependency but
    this patch also avoids the issue of reverse geocoding testcase hanging
    becuase of some gvfs bug.
    
    At the same time, this change reveals that our reverse geocoding API is
    not working anymore since the Yahoo web API we rely on does not seem to
    be available anymore.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=702775

 geocode-glib/geocode-forward.c      |   68 +++++++++++++++----------------
 geocode-glib/geocode-glib-private.h |   15 ++++---
 geocode-glib/geocode-glib.c         |   12 +++--
 geocode-glib/geocode-reverse.c      |   77 +++++++++++++++--------------------
 4 files changed, 81 insertions(+), 91 deletions(-)
---
diff --git a/geocode-glib/geocode-forward.c b/geocode-glib/geocode-forward.c
index e6b5db5..293d53d 100644
--- a/geocode-glib/geocode-forward.c
+++ b/geocode-glib/geocode-forward.c
@@ -41,6 +41,7 @@
 
 struct _GeocodeForwardPrivate {
        GHashTable *ht;
+        SoupSession *soup_session;
        guint       answer_count;
 };
 
@@ -56,6 +57,7 @@ geocode_forward_finalize (GObject *gforward)
        GeocodeForward *forward = (GeocodeForward *) gforward;
 
        g_clear_pointer (&forward->priv->ht, g_hash_table_destroy);
+        g_clear_object (&forward->priv->soup_session);
 
        G_OBJECT_CLASS (geocode_forward_parent_class)->finalize (gforward);
 }
@@ -76,6 +78,7 @@ geocode_forward_init (GeocodeForward *forward)
        forward->priv = G_TYPE_INSTANCE_GET_PRIVATE ((forward), GEOCODE_TYPE_FORWARD, GeocodeForwardPrivate);
        forward->priv->ht = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   g_free, g_free);
+        forward->priv->soup_session = soup_session_new ();
        forward->priv->answer_count = DEFAULT_ANSWER_COUNT;
 }
 
@@ -261,29 +264,25 @@ geocode_forward_add (GeocodeForward *forward,
 }
 
 static void
-on_query_data_loaded (GObject      *source_forward,
-                     GAsyncResult *res,
-                     gpointer      user_data)
+on_query_data_loaded (SoupSession *session,
+                      SoupMessage *query,
+                      gpointer     user_data)
 {
        GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-       GFile *query;
        GError *error = NULL;
        char *contents;
        gpointer ret;
 
-       query = G_FILE (source_forward);
-       if (g_file_load_contents_finish (query,
-                                        res,
-                                        &contents,
-                                        NULL,
-                                        NULL,
-                                        &error) == FALSE) {
-               g_simple_async_result_take_error (simple, error);
+        if (query->status_code != SOUP_STATUS_OK) {
+               g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                     query->reason_phrase ? query->reason_phrase : "Query failed");
+                g_simple_async_result_take_error (simple, error);
                g_simple_async_result_complete_in_idle (simple);
                g_object_unref (simple);
                return;
        }
 
+        contents = g_strndup (query->response_body->data, query->response_body->length);
        if (is_search (G_OBJECT (query)))
                ret = _geocode_parse_search_json (contents, &error);
        else
@@ -312,27 +311,28 @@ on_cache_data_loaded (GObject      *source_forward,
                      gpointer      user_data)
 {
        GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-       GCancellable *cancellable;
        GFile *cache;
        GError *error = NULL;
        char *contents;
        gpointer ret;
 
        cache = G_FILE (source_forward);
-       cancellable = g_object_get_data (G_OBJECT (cache), "cancellable");
        if (g_file_load_contents_finish (cache,
                                         res,
                                         &contents,
                                         NULL,
                                         NULL,
                                         NULL) == FALSE) {
-               GFile *query;
+                GObject *object;
+                SoupMessage *query;
 
+                object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
                query = g_object_get_data (G_OBJECT (cache), "query");
                g_object_set_data (G_OBJECT (query), "is-search",
                                   g_object_get_data (G_OBJECT (cache), "is-search"));
-               g_file_load_contents_async (query,
-                                           cancellable,
+                g_object_ref (query); /* soup_session_queue_message steals ref */
+               soup_session_queue_message (GEOCODE_FORWARD (object)->priv->soup_session,
+                                            query,
                                            on_query_data_loaded,
                                            simple);
                return;
@@ -353,11 +353,11 @@ on_cache_data_loaded (GObject      *source_forward,
        g_object_unref (simple);
 }
 
-static GFile *
+static SoupMessage *
 get_search_query_for_params (GeocodeForward *forward,
                             GError        **error)
 {
-       GFile *ret;
+       SoupMessage *ret;
        GHashTable *ht;
        char *lang;
        char *params;
@@ -392,7 +392,7 @@ get_search_query_for_params (GeocodeForward *forward,
        g_free (params);
        g_free (search_term);
 
-       ret = g_file_new_for_uri (uri);
+       ret = soup_message_new ("GET", uri);
        g_free (uri);
 
        return ret;
@@ -419,7 +419,7 @@ geocode_forward_search_async (GeocodeForward      *forward,
                              gpointer             user_data)
 {
        GSimpleAsyncResult *simple;
-       GFile *query;
+       SoupMessage *query;
        char *cache_path;
        GError *error = NULL;
 
@@ -444,18 +444,16 @@ geocode_forward_search_async (GeocodeForward      *forward,
        cache_path = _geocode_glib_cache_path_for_query (query);
        if (cache_path == NULL) {
                set_is_search (forward, G_OBJECT (query));
-               g_file_load_contents_async (query,
-                                           cancellable,
+               soup_session_queue_message (forward->priv->soup_session,
+                                            query,
                                            on_query_data_loaded,
                                            simple);
-               g_object_unref (query);
        } else {
                GFile *cache;
 
                cache = g_file_new_for_path (cache_path);
                set_is_search (forward, G_OBJECT (cache));
                g_object_set_data_full (G_OBJECT (cache), "query", query, (GDestroyNotify) g_object_unref);
-               g_object_set_data (G_OBJECT (cache), "cancellable", cancellable);
                g_file_load_contents_async (cache,
                                            cancellable,
                                            on_cache_data_loaded,
@@ -842,7 +840,7 @@ GList *
 geocode_forward_search (GeocodeForward      *forward,
                        GError             **error)
 {
-       GFile *query;
+       SoupMessage *query;
        char *contents;
        GList *ret;
        gboolean to_cache = FALSE;
@@ -858,18 +856,18 @@ geocode_forward_search (GeocodeForward      *forward,
                return NULL;
 
        if (_geocode_glib_cache_load (query, &contents) == FALSE) {
-               if (g_file_load_contents (query,
-                                         NULL,
-                                         &contents,
-                                         NULL,
-                                         NULL,
-                                         error) == FALSE) {
+                if (soup_session_send_message (forward->priv->soup_session,
+                                               query) != SOUP_STATUS_OK) {
                        /* FIXME check error value and match against
                         * web service errors:
                         * http://developer.yahoo.com/geo/geoplanet/guide/api_docs.html#response-errors */
-                       g_object_unref (query);
-                       return NULL;
-               }
+                        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                             query->reason_phrase ? query->reason_phrase : "Query failed");
+                        g_object_unref (query);
+                        return NULL;
+                }
+                contents = g_strndup (query->response_body->data, query->response_body->length);
+
                to_cache = TRUE;
        }
 
diff --git a/geocode-glib/geocode-glib-private.h b/geocode-glib/geocode-glib-private.h
index 97fb518..a486ab9 100644
--- a/geocode-glib/geocode-glib-private.h
+++ b/geocode-glib/geocode-glib-private.h
@@ -24,6 +24,7 @@
 #define GEOCODE_GLIB_PRIVATE_H
 
 #include <glib.h>
+#include <libsoup/soup.h>
 #include <geocode-glib/geocode-location.h>
 
 G_BEGIN_DECLS
@@ -40,18 +41,18 @@ GHashTable *_geocode_parse_resolve_json (const char *contents,
                                         GError    **error);
 GList      *_geocode_parse_search_json  (const char *contents,
                                         GError    **error);
-GFile      *_get_resolve_query_for_params (GHashTable  *orig_ht,
-                                          gboolean     reverse);
+SoupMessage *_get_resolve_query_for_params (GHashTable  *orig_ht,
+                                           gboolean     reverse);
 GeocodeLocation *_geocode_ip_json_to_location (const char  *json,
                                               GError     **error);
 
 char       *_geocode_object_get_lang (void);
 
-char *_geocode_glib_cache_path_for_query (GFile *query);
-gboolean _geocode_glib_cache_save (GFile      *query,
-                                 const char *contents);
-gboolean _geocode_glib_cache_load (GFile  *query,
-                                 char  **contents);
+char *_geocode_glib_cache_path_for_query (SoupMessage *query);
+gboolean _geocode_glib_cache_save (SoupMessage *query,
+                                   const char  *contents);
+gboolean _geocode_glib_cache_load (SoupMessage *query,
+                                   char       **contents);
 
 
 G_END_DECLS
diff --git a/geocode-glib/geocode-glib.c b/geocode-glib/geocode-glib.c
index ac45545..2461780 100644
--- a/geocode-glib/geocode-glib.c
+++ b/geocode-glib/geocode-glib.c
@@ -43,10 +43,11 @@
  **/
 
 char *
-_geocode_glib_cache_path_for_query (GFile *query)
+_geocode_glib_cache_path_for_query (SoupMessage *query)
 {
        const char *filename;
        char *path;
+        SoupURI *soup_uri;
        char *uri;
        GChecksum *sum;
 
@@ -62,7 +63,8 @@ _geocode_glib_cache_path_for_query (GFile *query)
        g_free (path);
 
        /* Create path for query */
-       uri = g_file_get_uri (query);
+       soup_uri = soup_message_get_uri (query);
+       uri = soup_uri_to_string (soup_uri, FALSE);
 
        sum = g_checksum_new (G_CHECKSUM_SHA256);
        g_checksum_update (sum, (const guchar *) uri, strlen (uri));
@@ -81,8 +83,8 @@ _geocode_glib_cache_path_for_query (GFile *query)
 }
 
 gboolean
-_geocode_glib_cache_save (GFile      *query,
-                         const char *contents)
+_geocode_glib_cache_save (SoupMessage *query,
+                         const char  *contents)
 {
        char *path;
        gboolean ret;
@@ -96,7 +98,7 @@ _geocode_glib_cache_save (GFile      *query,
 }
 
 gboolean
-_geocode_glib_cache_load (GFile  *query,
+_geocode_glib_cache_load (SoupMessage *query,
                          char  **contents)
 {
        char *path;
diff --git a/geocode-glib/geocode-reverse.c b/geocode-glib/geocode-reverse.c
index b8115bf..5739984 100644
--- a/geocode-glib/geocode-reverse.c
+++ b/geocode-glib/geocode-reverse.c
@@ -42,6 +42,7 @@
 
 struct _GeocodeReversePrivate {
        GHashTable *ht;
+        SoupSession *soup_session;
 };
 
 G_DEFINE_TYPE (GeocodeReverse, geocode_reverse, G_TYPE_OBJECT)
@@ -52,6 +53,7 @@ geocode_reverse_finalize (GObject *gobject)
        GeocodeReverse *object = (GeocodeReverse *) gobject;
 
        g_clear_pointer (&object->priv->ht, g_hash_table_destroy);
+        g_clear_object (&object->priv->soup_session);
 
        G_OBJECT_CLASS (geocode_reverse_parent_class)->finalize (gobject);
 }
@@ -72,6 +74,7 @@ geocode_reverse_init (GeocodeReverse *object)
        object->priv = G_TYPE_INSTANCE_GET_PRIVATE ((object), GEOCODE_TYPE_REVERSE, GeocodeReversePrivate);
        object->priv->ht = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                  g_free, g_free);
+        object->priv->soup_session = soup_session_new ();
 }
 
 /**
@@ -293,29 +296,25 @@ parse:
 }
 
 static void
-on_query_data_loaded (GObject      *source_object,
-                     GAsyncResult *res,
-                     gpointer      user_data)
+on_query_data_loaded (SoupSession *session,
+                      SoupMessage *query,
+                      gpointer     user_data)
 {
        GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-       GFile *query;
        GError *error = NULL;
        char *contents;
        gpointer ret;
 
-       query = G_FILE (source_object);
-       if (g_file_load_contents_finish (query,
-                                        res,
-                                        &contents,
-                                        NULL,
-                                        NULL,
-                                        &error) == FALSE) {
-               g_simple_async_result_take_error (simple, error);
+        if (query->status_code != SOUP_STATUS_OK) {
+               g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                     query->reason_phrase ? query->reason_phrase : "Query failed");
+                g_simple_async_result_take_error (simple, error);
                g_simple_async_result_complete_in_idle (simple);
                g_object_unref (simple);
                return;
        }
 
+        contents = g_strndup (query->response_body->data, query->response_body->length);
        ret = _geocode_parse_resolve_json (contents, &error);
 
        if (ret == NULL) {
@@ -341,25 +340,26 @@ on_cache_data_loaded (GObject      *source_object,
                      gpointer      user_data)
 {
        GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-       GCancellable *cancellable;
        GFile *cache;
        GError *error = NULL;
        char *contents;
        gpointer ret;
 
        cache = G_FILE (source_object);
-       cancellable = g_object_get_data (G_OBJECT (cache), "cancellable");
        if (g_file_load_contents_finish (cache,
                                         res,
                                         &contents,
                                         NULL,
                                         NULL,
                                         NULL) == FALSE) {
-               GFile *query;
+               GObject *object;
+               SoupMessage *query;
 
+                object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
                query = g_object_get_data (G_OBJECT (cache), "query");
-               g_file_load_contents_async (query,
-                                           cancellable,
+                g_object_ref (query); /* soup_session_queue_message steals ref */
+               soup_session_queue_message (GEOCODE_REVERSE (object)->priv->soup_session,
+                                            query,
                                            on_query_data_loaded,
                                            simple);
                return;
@@ -396,11 +396,11 @@ dup_ht (GHashTable *ht)
        return ret;
 }
 
-GFile *
+SoupMessage *
 _get_resolve_query_for_params (GHashTable  *orig_ht,
                              gboolean     reverse)
 {
-       GFile *ret;
+       SoupMessage *ret;
        GHashTable *ht;
        char *locale;
        char *params, *uri;
@@ -426,7 +426,7 @@ _get_resolve_query_for_params (GHashTable  *orig_ht,
        uri = g_strdup_printf ("http://where.yahooapis.com/geocode?%s";, params);
        g_free (params);
 
-       ret = g_file_new_for_uri (uri);
+       ret = soup_message_new ("GET", uri);
        g_free (uri);
 
        return ret;
@@ -453,9 +453,8 @@ geocode_reverse_resolve_async (GeocodeReverse       *object,
                               gpointer             user_data)
 {
        GSimpleAsyncResult *simple;
-       GFile *query;
+       SoupMessage *query;
        char *cache_path;
-       GError *error = NULL;
 
        g_return_if_fail (GEOCODE_IS_REVERSE (object));
 
@@ -465,26 +464,18 @@ geocode_reverse_resolve_async (GeocodeReverse       *object,
                                            geocode_reverse_resolve_async);
 
        query = _get_resolve_query_for_params (object->priv->ht, TRUE);
-       if (query == NULL) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete_in_idle (simple);
-               g_object_unref (simple);
-               return;
-       }
 
        cache_path = _geocode_glib_cache_path_for_query (query);
        if (cache_path == NULL) {
-               g_file_load_contents_async (query,
-                                           cancellable,
+               soup_session_queue_message (object->priv->soup_session,
+                                            query,
                                            on_query_data_loaded,
                                            simple);
-               g_object_unref (query);
        } else {
                GFile *cache;
 
                cache = g_file_new_for_path (cache_path);
                g_object_set_data_full (G_OBJECT (cache), "query", query, (GDestroyNotify) g_object_unref);
-               g_object_set_data (G_OBJECT (cache), "cancellable", cancellable);
                g_file_load_contents_async (cache,
                                            cancellable,
                                            on_cache_data_loaded,
@@ -540,7 +531,7 @@ GHashTable *
 geocode_reverse_resolve (GeocodeReverse      *object,
                         GError             **error)
 {
-       GFile *query;
+       SoupMessage *query;
        char *contents;
        GHashTable *ret;
        gboolean to_cache = FALSE;
@@ -548,19 +539,17 @@ geocode_reverse_resolve (GeocodeReverse      *object,
        g_return_val_if_fail (GEOCODE_IS_REVERSE (object), NULL);
 
        query = _get_resolve_query_for_params (object->priv->ht, TRUE);
-       if (query == NULL)
-               return NULL;
 
        if (_geocode_glib_cache_load (query, &contents) == FALSE) {
-               if (g_file_load_contents (query,
-                                         NULL,
-                                         &contents,
-                                         NULL,
-                                         NULL,
-                                         error) == FALSE) {
-                       g_object_unref (query);
-                       return NULL;
-               }
+                if (soup_session_send_message (object->priv->soup_session,
+                                               query) != SOUP_STATUS_OK) {
+                        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                             query->reason_phrase ? query->reason_phrase : "Query failed");
+                        g_object_unref (query);
+                        return NULL;
+                }
+                contents = g_strndup (query->response_body->data, query->response_body->length);
+
                to_cache = TRUE;
        }
 


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