[libosinfo PATCH 5/7] media: Use libsoup for http://, https://, and ftp:// requests

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

 



As osinfo_media_create_from_location_with_flags_async() can handle
non-local cases, they'd end up relying on GVFS under the hood, which
would cause those APIs to not work when called from an app running as
root.

In order to avoid this situation, let's rely on libsoup for these cases.

https://gitlab.com/libosinfo/libosinfo/issues/30

Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx>
---
 configure.ac          |  1 +
 libosinfo.spec.in     |  1 +
 osinfo/Makefile.am    |  5 +++-
 osinfo/osinfo_media.c | 68 ++++++++++++++++++++++++++++++++++---------
 4 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/configure.ac b/configure.ac
index 59c701d..02ea1df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -42,6 +42,7 @@ GLIB_ENCODED_VERSION="GLIB_VERSION_2_38"
 
 PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.6.0])
 PKG_CHECK_MODULES([LIBXSLT], [libxslt >= 1.0.0])
+PKG_CHECK_MODULES([LIBSOUP], [libsoup-2.4])
 
 PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_MINIMUM_VERSION gobject-2.0 gio-2.0])
 GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=$GLIB_ENCODED_VERSION"
diff --git a/libosinfo.spec.in b/libosinfo.spec.in
index 8118755..e5a16aa 100644
--- a/libosinfo.spec.in
+++ b/libosinfo.spec.in
@@ -13,6 +13,7 @@ BuildRequires: gettext-devel
 BuildRequires: glib2-devel
 BuildRequires: libxml2-devel >= 2.6.0
 BuildRequires: libxslt-devel >= 1.0.0
+BuildRequires: libsoup-devel
 BuildRequires: vala
 BuildRequires: /usr/bin/pod2man
 BuildRequires: hwdata
diff --git a/osinfo/Makefile.am b/osinfo/Makefile.am
index cb1df8f..33e9c66 100644
--- a/osinfo/Makefile.am
+++ b/osinfo/Makefile.am
@@ -50,6 +50,7 @@ libosinfo_impl_la_CFLAGS = \
 	$(GOBJECT_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(GIO_CFLAGS) \
+	$(LIBSOUP_CFLAGS) \
 	-DDATA_DIR='"$(datadir)"' \
 	-DPKG_DATA_DIR='"$(pkgdatadir)"' \
 	-DSYS_CONF_DIR='"$(sysconfdir)"' \
@@ -61,7 +62,9 @@ libosinfo_impl_la_LIBADD = \
 	$(LIBXSLT_LIBS) \
 	$(GOBJECT_LIBS) \
 	$(GLIB_LIBS) \
-	$(GIO_LIBS)
+	$(GIO_LIBS) \
+	$(LIBSOUP_LIBS) \
+	$(NULL)
 
 libosinfo_impl_includedir = $(includedir)/libosinfo-1.0/osinfo
 
diff --git a/osinfo/osinfo_media.c b/osinfo/osinfo_media.c
index aba3e20..ef586a0 100644
--- a/osinfo/osinfo_media.c
+++ b/osinfo/osinfo_media.c
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <glib/gi18n-lib.h>
+#include <libsoup/soup.h>
 
 #define MAX_VOLUME 32
 #define MAX_SYSTEM 32
@@ -129,6 +130,9 @@ static void search_ppc_bootinfo_async_data_free(SearchPPCBootinfoAsyncData *data
 typedef struct _CreateFromLocationAsyncData CreateFromLocationAsyncData;
 struct _CreateFromLocationAsyncData {
     GFile *file;
+    SoupSession *session;
+    SoupMessage *message;
+    gchar *uri;
 
     GTask *res;
 
@@ -150,7 +154,12 @@ struct _CreateFromLocationAsyncData {
 static void create_from_location_async_data_free
                                 (CreateFromLocationAsyncData *data)
 {
-    g_object_unref(data->file);
+    if (data->file != NULL)
+        g_object_unref(data->file);
+    if (data->session != NULL)
+        g_object_unref(data->session);
+    if (data->message != NULL)
+        g_object_unref(data->message);
     g_object_unref(data->res);
     g_free(data->volume);
     g_free(data->system);
@@ -730,6 +739,19 @@ OsinfoMedia *osinfo_media_new(const gchar *id,
     return media;
 }
 
+static gboolean requires_soup(const gchar *location)
+{
+    const gchar *prefixes[] = { "http://";, "https://";, "ftp://";, NULL };
+    gsize i;
+
+    for (i = 0; prefixes[i] != NULL; i++) {
+        if (g_str_has_prefix(location, prefixes[i]))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
 static void on_media_create_from_location_ready(GObject *source_object,
                                                  GAsyncResult *res,
                                                  gpointer user_data)
@@ -835,18 +857,15 @@ static OsinfoMedia *
 create_from_location_async_data(CreateFromLocationAsyncData *data)
 {
     OsinfoMedia *media;
-    gchar *uri;
     guint64 vol_size;
     guint8 index;
 
-    uri = g_file_get_uri(data->file);
     media = g_object_new(OSINFO_TYPE_MEDIA,
-                         "id", uri,
+                         "id", data->uri,
                          NULL);
     osinfo_entity_set_param(OSINFO_ENTITY(media),
                             OSINFO_MEDIA_PROP_URL,
-                            uri);
-    g_free(uri);
+                            data->uri);
     if (!is_str_empty(data->volume))
         osinfo_entity_set_param(OSINFO_ENTITY(media),
                                 OSINFO_MEDIA_PROP_VOLUME_ID,
@@ -1299,7 +1318,17 @@ static void on_location_read(GObject *source,
 
     data = (CreateFromLocationAsyncData *)user_data;
 
-    stream = G_INPUT_STREAM(g_file_read_finish(G_FILE(source), res, &error));
+    if (data->file != NULL) {
+        stream = G_INPUT_STREAM(g_file_read_finish(G_FILE(source), res, &error));
+    } else {
+        stream = soup_session_send_finish(SOUP_SESSION(source), res, &error);
+        if (!SOUP_STATUS_IS_SUCCESSFUL(data->message->status_code) && error == NULL) {
+            g_set_error_literal(&error,
+                                OSINFO_MEDIA_ERROR,
+                                OSINFO_MEDIA_ERROR_NO_DESCRIPTORS,
+                                soup_status_get_phrase(data->message->status_code));
+        }
+    }
     if (error != NULL) {
         g_prefix_error(&error, _("Failed to open file: "));
         g_task_return_error(data->res, error);
@@ -1386,12 +1415,25 @@ void osinfo_media_create_from_location_with_flags_async(const gchar *location,
     g_task_set_priority(data->res, priority);
     data->flags = flags;
 
-    data->file = g_file_new_for_commandline_arg(location);
-    g_file_read_async(data->file,
-                      priority,
-                      cancellable,
-                      on_location_read,
-                      data);
+    data->uri = g_strdup(location);
+
+    if (requires_soup(location)) {
+        data->session = soup_session_new();
+        data->message = soup_message_new("GET", location);
+
+        soup_session_send_async(data->session,
+                                data->message,
+                                cancellable,
+                                on_location_read,
+                                data);
+    } else {
+        data->file = g_file_new_for_commandline_arg(location);
+        g_file_read_async(data->file,
+                          priority,
+                          cancellable,
+                          on_location_read,
+                          data);
+    }
 }
 
 /**
-- 
2.21.0

_______________________________________________
Libosinfo mailing list
Libosinfo@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libosinfo




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Fedora Users]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]

  Powered by Linux