From 05b3ab7c755d7a6667852576ed11944304acdd4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
 <congdanhqx@gmail.com>
Date: Fri, 1 Mar 2024 21:56:34 +0700
Subject: [PATCH 3/5] libsoup: Port to libsoup-3.0

Upstream-Status: Backport [https://github.com/xfce-mirror/xfce4-weather-plugin/commit/05b3ab7c755d7a6667852576ed11944304acdd4a]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 README                         |   4 +-
 configure.ac                   |   2 +-
 panel-plugin/weather-config.c  |  32 ++++---
 panel-plugin/weather-search.c  |  37 ++++++---
 panel-plugin/weather-summary.c |  23 ++++--
 panel-plugin/weather.c         | 147 +++++++++++++++------------------
 panel-plugin/weather.h         |   2 +-
 7 files changed, 132 insertions(+), 115 deletions(-)

diff --git a/README b/README
index 6587581..3530b1f 100644
--- a/README
+++ b/README
@@ -152,10 +152,10 @@ using gdb or any other debugger should the plugin crash:
 BUILD REQUIREMENTS AND DEPENDENCIES
 ==========================================================================
 To be able to build the plugin, the following requirements have to be
-met in addition to those of XFCE-4.14:
+met in addition to those of XFCE-4.16:
 
 * >=libxml-2.4.0
-* >=libsoup-2.42.0
+* >=libsoup-3.0.0
 * >=upower-0.9.0 (optional)
 
 You might also need developer libraries necessary for building other
diff --git a/configure.ac b/configure.ac
index cf82b7e..15e8b46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,7 +70,7 @@ XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-2], [4.16.0])
 XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-2.0], [4.14.0])
 XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0])
 XDT_CHECK_PACKAGE([LIBXML], [libxml-2.0], [2.4.0])
-XDT_CHECK_PACKAGE([SOUP], [libsoup-2.4], [2.42.0])
+XDT_CHECK_PACKAGE([SOUP], [libsoup-3.0], [3.0.0])
 XDT_CHECK_PACKAGE([JSON], [json-c], [0.13.1])
 XDT_CHECK_OPTIONAL_PACKAGE([UPOWER_GLIB], [upower-glib], [0.9.0], [upower],
                            [upower for adapting update interval to power state])
diff --git a/panel-plugin/weather-config.c b/panel-plugin/weather-config.c
index 19fa1d8..d27c825 100644
--- a/panel-plugin/weather-config.c
+++ b/panel-plugin/weather-config.c
@@ -238,8 +238,8 @@ sanitize_location_name(const gchar *location_name)
 
 
 static void
-cb_lookup_altitude(SoupSession *session,
-                   SoupMessage *msg,
+cb_lookup_altitude(GObject *source,
+                   GAsyncResult *result,
                    gpointer user_data)
 {
     xfceweather_dialog *dialog = (xfceweather_dialog *) user_data;
@@ -247,11 +247,14 @@ cb_lookup_altitude(SoupSession *session,
     gdouble alt = 0;
     const gchar *body = NULL;
     gsize len = 0;
+    GError *error = NULL;
+    GBytes *response =
+        soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error);
 
-    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-        body = msg->response_body->data;
-        len = msg->response_body->length;
-    }
+    if (G_UNLIKELY(error))
+        g_error_free(error);
+    else
+        body = g_bytes_get_data(response, &len);
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -271,23 +274,27 @@ cb_lookup_altitude(SoupSession *session,
     else if (dialog->pd->units->altitude == FEET)
         alt /= 0.3048;
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_alt), alt);
+    g_bytes_unref(response);
 }
 
 
 static void
-cb_lookup_timezone(SoupSession *session,
-                   SoupMessage *msg,
+cb_lookup_timezone(GObject *source,
+                   GAsyncResult *result,
                    gpointer user_data)
 {
     xfceweather_dialog *dialog = (xfceweather_dialog *) user_data;
     xml_timezone *xml_tz;
     const gchar *body = NULL;
     gsize len = 0;
+    GError *error = NULL;
+    GBytes *response =
+        soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error);
 
-    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-        body = msg->response_body->data;
-        len = msg->response_body->length;
-    }
+    if (G_UNLIKELY(error))
+        g_error_free(error);
+    else
+        body = g_bytes_get_data(response, &len);
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -304,6 +311,7 @@ cb_lookup_timezone(SoupSession *session,
         xml_timezone_free(xml_tz);
     } else
         gtk_entry_set_text(GTK_ENTRY(dialog->text_timezone), "");
+    g_bytes_unref(response);
 }
 
 
diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c
index 6a2ba1f..e030ff8 100644
--- a/panel-plugin/weather-search.c
+++ b/panel-plugin/weather-search.c
@@ -78,8 +78,8 @@ sanitize_str(const gchar *str)
 
 
 static void
-cb_searchdone(SoupSession *session,
-              SoupMessage *msg,
+cb_searchdone(GObject *source,
+              GAsyncResult *result,
               gpointer user_data)
 {
     search_dialog *dialog = (search_dialog *) user_data;
@@ -91,11 +91,14 @@ cb_searchdone(SoupSession *session,
     GtkTreeSelection *selection;
     const gchar *body = NULL;
     gsize len = 0;
+    GError *error = NULL;
+    GBytes *response =
+        soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error);
 
-    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-        body = msg->response_body->data;
-        len = msg->response_body->length;
-    }
+    if (G_UNLIKELY(error))
+        g_error_free(error);
+    else
+        body = g_bytes_get_data(response, &len);
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -105,8 +108,10 @@ cb_searchdone(SoupSession *session,
     gtk_widget_set_sensitive(dialog->find_button, TRUE);
 
     doc = get_xml_document(body, len);
-    if (!doc)
+    if (!doc) {
+        g_bytes_unref(response);
         return;
+    }
 
     cur_node = xmlDocGetRootElement(doc);
     if (cur_node) {
@@ -140,6 +145,7 @@ cb_searchdone(SoupSession *session,
         }
 
     gtk_tree_view_column_set_title(dialog->column, _("Results"));
+    g_bytes_unref(response);
 }
 
 
@@ -384,8 +390,8 @@ get_preferred_units(const gchar *country_code)
 
 
 static void
-cb_geolocation(SoupSession *session,
-               SoupMessage *msg,
+cb_geolocation(GObject *source,
+               GAsyncResult *result,
                gpointer user_data)
 {
     geolocation_data *data = (geolocation_data *) user_data;
@@ -394,11 +400,14 @@ cb_geolocation(SoupSession *session,
     units_config *units;
     const gchar *body = NULL;
     gsize len = 0;
+    GError *error = NULL;
+    GBytes *response =
+        soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error);
 
-    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-        body = msg->response_body->data;
-        len = msg->response_body->length;
-    }
+    if (G_UNLIKELY(error))
+        g_error_free(error);
+    else
+        body = g_bytes_get_data(response, &len);
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -411,6 +420,7 @@ cb_geolocation(SoupSession *session,
 
     if (!geo) {
         data->cb(NULL, NULL, NULL, NULL, data->user_data);
+        g_bytes_unref(response);
         g_free(data);
         return;
     }
@@ -441,6 +451,7 @@ cb_geolocation(SoupSession *session,
     g_slice_free(units_config, units);
     xml_geolocation_free(geo);
     g_free(full_loc);
+    g_bytes_unref(response);
     g_free(data);
 }
 
diff --git a/panel-plugin/weather-summary.c b/panel-plugin/weather-summary.c
index a6a2f56..224bb34 100644
--- a/panel-plugin/weather-summary.c
+++ b/panel-plugin/weather-summary.c
@@ -234,22 +234,29 @@ get_logo_path(void)
 
 
 static void
-logo_fetched(SoupSession *session,
-             SoupMessage *msg,
+logo_fetched(GObject *source,
+             GAsyncResult *result,
              gpointer user_data)
 {
-    if (msg && msg->response_body && msg->response_body->length > 0) {
+    GError *error = NULL;
+    GBytes *response =
+        soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error);
+
+    if (G_LIKELY(error == NULL)) {
+        gsize len = 0;
+        const gchar *body = g_bytes_get_data(response, &len);
         gchar *path = get_logo_path();
-        GError *error = NULL;
         GdkPixbuf *pixbuf = NULL;
         gint scale_factor;
-        if (!g_file_set_contents(path, msg->response_body->data,
-                                 msg->response_body->length, &error)) {
+        g_file_set_contents(path, body, len, &error);
+        g_bytes_unref(response);
+        if (error) {
             g_warning("Error downloading met.no logo image to %s, "
                       "reason: %s\n", path,
                       error ? error->message : "unknown");
             g_error_free(error);
             g_free(path);
+            g_bytes_unref(response);
             return;
         }
         scale_factor = gtk_widget_get_scale_factor(user_data);
@@ -261,7 +268,9 @@ logo_fetched(SoupSession *session,
             cairo_surface_destroy(surface);
             g_object_unref(pixbuf);
         }
-    }
+        g_bytes_unref(response);
+    } else
+        g_error_free(error);
 }
 
 
diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c
index b75c633..1a84537 100644
--- a/panel-plugin/weather.c
+++ b/panel-plugin/weather.c
@@ -23,6 +23,8 @@
 #include <string.h>
 #include <sys/stat.h>
 
+#include <glib.h>
+
 #include <libxfce4util/libxfce4util.h>
 #include <libxfce4ui/libxfce4ui.h>
 #include <xfconf/xfconf.h>
@@ -106,13 +108,14 @@ static void schedule_next_wakeup(plugin_data *data);
 void
 weather_http_queue_request(SoupSession *session,
                            const gchar *uri,
-                           SoupSessionCallback callback_func,
+                           GAsyncReadyCallback callback_func,
                            gpointer user_data)
 {
     SoupMessage *msg;
 
     msg = soup_message_new("GET", uri);
-    soup_session_queue_message(session, msg, callback_func, user_data);
+    soup_session_send_and_read_async(session, msg, G_PRIORITY_DEFAULT, NULL,
+                                     callback_func, user_data);
 }
 
 
@@ -481,8 +484,8 @@ calc_next_download_time(const update_info *upi,
  * Process downloaded sun astro data and schedule next astro update.
  */
 static void
-cb_astro_update_sun(SoupSession *session,
-                    SoupMessage *msg,
+cb_astro_update_sun(GObject *source,
+                    GAsyncResult *result,
                     gpointer user_data)
 {
     plugin_data *data = user_data;
@@ -491,14 +494,17 @@ cb_astro_update_sun(SoupSession *session,
     guint astro_forecast_days;
     const gchar *body = NULL;
     gsize len = 0;
+    SoupMessage *msg;
+    GError *error = NULL;
+    GBytes *response;
 
+    msg = soup_session_get_async_result_message(SOUP_SESSION(source), result);
     data->msg_parse->sun_msg_processed++;
-    data->astro_update->http_status_code = msg->status_code;
-    if ((msg->status_code == 200 || msg->status_code == 203)) {
-        if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-            body = msg->response_body->data;
-            len = msg->response_body->length;
-        }
+    data->astro_update->http_status_code = soup_message_get_status(msg);
+    response = soup_session_send_and_read_finish(SOUP_SESSION(source),
+                                                 result, &error);
+    if (G_LIKELY(error == NULL)) {
+        body = g_bytes_get_data(response, &len);
         json_tree = get_json_tree(body, len);
         if (G_LIKELY(json_tree)) {
             if (!parse_astrodata_sun(json_tree, data->astrodata))  {
@@ -514,10 +520,12 @@ cb_astro_update_sun(SoupSession *session,
             g_warning("Error parsing sun astronomical data!");
             weather_debug("No json_tree");
         }
+        g_bytes_unref(response);
     } else {
         data->msg_parse->http_msg_fail = TRUE;
-        g_warning_once("Download of sun astronomical data failed with HTTP Status Code %d, Reason phrase: %s",
-                       msg->status_code, msg->reason_phrase);
+        g_warning_once("Download of sun astronomical data failed: %s",
+                       error->message);
+        g_error_free(error);
     }
 
     astro_forecast_days = data->forecast_days + 1;
@@ -543,8 +551,8 @@ cb_astro_update_sun(SoupSession *session,
  * Process downloaded moon astro data and schedule next astro update.
  */
 static void
-cb_astro_update_moon(SoupSession *session,
-                     SoupMessage *msg,
+cb_astro_update_moon(GObject *source,
+                     GAsyncResult *result,
                      gpointer user_data)
 {
     plugin_data *data = user_data;
@@ -553,14 +561,17 @@ cb_astro_update_moon(SoupSession *session,
     guint astro_forecast_days;
     const gchar *body = NULL;
     gsize len = 0;
+    SoupMessage *msg;
+    GError *error = NULL;
+    GBytes *response;
 
+    response = soup_session_send_and_read_finish(SOUP_SESSION(source),
+                                                 result, &error);
+    msg = soup_session_get_async_result_message(SOUP_SESSION(source), result);
     data->msg_parse->moon_msg_processed++;
-    data->astro_update->http_status_code = msg->status_code;
-    if ((msg->status_code == 200 || msg->status_code == 203)) {
-        if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-            body = msg->response_body->data;
-            len = msg->response_body->length;
-        }
+    data->astro_update->http_status_code = soup_message_get_status(msg);
+    if (G_LIKELY(error == NULL)) {
+        body = g_bytes_get_data(response, &len);
         json_tree = get_json_tree(body, len);
         if (G_LIKELY(json_tree)) {
             if (!parse_astrodata_moon(json_tree, data->astrodata))  {
@@ -576,10 +587,12 @@ cb_astro_update_moon(SoupSession *session,
             g_warning("Error parsing moon astronomical data");
             weather_debug("No json_tree");
         }
+        g_bytes_unref(response);
     } else {
         data->msg_parse->http_msg_fail = TRUE;
-        g_warning_once("Download of moon astronomical data failed with HTTP Status Code %d, Reason phrase: %s",
-                       msg->status_code, msg->reason_phrase);
+        g_warning_once("Download of moon astronomical data failed: %s",
+                       error->message);
+        g_error_free(error);
     }
 
     astro_forecast_days = data->forecast_days + 1;
@@ -613,8 +626,8 @@ cb_astro_update_moon(SoupSession *session,
  * Process downloaded weather data and schedule next weather update.
  */
 static void
-cb_weather_update(SoupSession *session,
-                  SoupMessage *msg,
+cb_weather_update(GObject *source,
+                  GAsyncResult *result,
                   gpointer user_data)
 {
     plugin_data *data = user_data;
@@ -624,16 +637,19 @@ cb_weather_update(SoupSession *session,
     gboolean parsing_error = TRUE;
     const gchar *body = NULL;
     gsize len = 0;
+    SoupMessage *msg;
+    GError *error = NULL;
+    GBytes *response = NULL;
 
     weather_debug("Processing downloaded weather data.");
+    response = soup_session_send_and_read_finish(SOUP_SESSION(source),
+                                                 result, &error);
+    msg = soup_session_get_async_result_message(SOUP_SESSION(source), result);
     time(&now_t);
     data->weather_update->attempt++;
-    data->weather_update->http_status_code = msg->status_code;
-    if (msg->status_code == 200 || msg->status_code == 203) {
-        if (G_LIKELY(msg->response_body && msg->response_body->data)) {
-            body = msg->response_body->data;
-            len = msg->response_body->length;
-        }
+    data->weather_update->http_status_code = soup_message_get_status(msg);
+    if (G_LIKELY(error == NULL)) {
+        body = g_bytes_get_data(response, &len);
         doc = get_xml_document(body, len);
         if (G_LIKELY(doc)) {
             root_node = xmlDocGetRootElement(doc);
@@ -645,12 +661,13 @@ cb_weather_update(SoupSession *session,
                 }
             xmlFreeDoc(doc);
         }
+        g_bytes_unref(response);
         if (parsing_error)
             g_warning("Error parsing weather data!");
-    } else
-        weather_debug
-            ("Download of weather data failed with HTTP Status Code %d, "
-             "Reason phrase: %s", msg->status_code, msg->reason_phrase);
+    } else {
+        weather_debug("Download of weather data failed: %s", error->message);
+        g_error_free(error);
+    }
     data->weather_update->next = calc_next_download_time(data->weather_update,
                                                          now_t);
 
@@ -1708,32 +1725,6 @@ mi_click(GtkWidget *widget,
     update_weatherdata_with_reset(data);
 }
 
-static void
-proxy_auth(SoupSession *session,
-           SoupMessage *msg,
-           SoupAuth *auth,
-           gboolean retrying,
-           gpointer user_data)
-{
-    SoupURI *soup_proxy_uri;
-    const gchar *proxy_uri;
-
-    if (!retrying) {
-        if (msg->status_code == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED) {
-            proxy_uri = g_getenv("HTTP_PROXY");
-            if (!proxy_uri)
-                proxy_uri = g_getenv("http_proxy");
-            if (proxy_uri) {
-                soup_proxy_uri = soup_uri_new(proxy_uri);
-                soup_auth_authenticate(auth,
-                                       soup_uri_get_user(soup_proxy_uri),
-                                       soup_uri_get_password(soup_proxy_uri));
-                soup_uri_free(soup_proxy_uri);
-            }
-        }
-    }
-}
-
 
 #ifdef HAVE_UPOWER_GLIB
 static void
@@ -2037,9 +2028,10 @@ static plugin_data *
 xfceweather_create_control(XfcePanelPlugin *plugin)
 {
     plugin_data *data = g_slice_new0(plugin_data);
-    SoupURI *soup_proxy_uri;
+    GProxyResolver *proxy_resolver;
     const gchar *proxy_uri;
-    const gchar *proxy_user;
+    const gchar *no_proxy;
+    gchar **no_proxy_lst = NULL;
     GtkWidget *refresh;
     cairo_surface_t *icon = NULL;
     data_types lbl;
@@ -2077,29 +2069,26 @@ xfceweather_create_control(XfcePanelPlugin *plugin)
 
     /* Setup session for HTTP connections */
     data->session = soup_session_new();
-    g_object_set(data->session, SOUP_SESSION_USER_AGENT,
-                 PACKAGE_NAME "-" PACKAGE_VERSION, NULL);
-    g_object_set(data->session, SOUP_SESSION_TIMEOUT,
-                 CONN_TIMEOUT, NULL);
+    soup_session_set_user_agent(data->session,
+                                PACKAGE_NAME "-" PACKAGE_VERSION);
+    soup_session_set_timeout(data->session, CONN_TIMEOUT);
 
     /* Set the proxy URI from environment */
     proxy_uri = g_getenv("HTTP_PROXY");
     if (!proxy_uri)
         proxy_uri = g_getenv("http_proxy");
     if (proxy_uri) {
-        soup_proxy_uri = soup_uri_new(proxy_uri);
-        g_object_set(data->session, SOUP_SESSION_PROXY_URI,
-                     soup_proxy_uri, NULL);
-
-        /* check if uri contains authentication info */
-        proxy_user = soup_uri_get_user(soup_proxy_uri);
-        if (proxy_user && strlen(proxy_user) > 0) {
-            g_signal_connect(G_OBJECT(data->session), "authenticate",
-                             G_CALLBACK(proxy_auth), NULL);
-        }
-
-        soup_uri_free(soup_proxy_uri);
-    }
+        no_proxy = g_getenv("no_proxy");
+        if (!no_proxy)
+            no_proxy = g_getenv("NO_PROXY");
+        if (no_proxy)
+            no_proxy_lst = g_strsplit(no_proxy, ",", -1);
+        proxy_resolver = g_simple_proxy_resolver_new(proxy_uri, no_proxy_lst);
+        g_strfreev(no_proxy_lst);
+        soup_session_set_proxy_resolver(data->session, proxy_resolver);
+        g_object_unref(proxy_resolver);
+    }
+    /* Otherwise, g_proxy_resolver_get_default() will be used */
 
     data->scrollbox = gtk_scrollbox_new();
 
diff --git a/panel-plugin/weather.h b/panel-plugin/weather.h
index 208de09..01974ce 100644
--- a/panel-plugin/weather.h
+++ b/panel-plugin/weather.h
@@ -183,7 +183,7 @@ extern gboolean debug_mode;
 
 void weather_http_queue_request(SoupSession *session,
                                 const gchar *uri,
-                                SoupSessionCallback callback_func,
+                                GAsyncReadyCallback callback_func,
                                 gpointer user_data);
 
 void scrollbox_set_visible(plugin_data *data);
