[Libosinfo] [osinfo-db-tools PATCH 1/9] import: Use libsoup for http://, https://, and ftp:// requests

Fabiano Fidêncio fidencio at redhat.com
Fri Jun 28 09:41:12 UTC 2019


As osinfo-db-import handles non-local requests, it'd en ud relying on
GVFS under the hood, which would cause the app to not work when running
as root.

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

It's important to mention that glib minimum version has been bumped to
2.44 as that's the version where g_input_stream_read_all() has been
introduced.

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

Signed-off-by: Fabiano Fidêncio <fidencio at redhat.com>
---
 configure.ac             |   5 +-
 osinfo-db-tools.spec.in  |   1 +
 tools/Makefile.am        |   2 +
 tools/osinfo-db-import.c | 111 +++++++++++++++++++++++++++++----------
 4 files changed, 90 insertions(+), 29 deletions(-)

diff --git a/configure.ac b/configure.ac
index 4df1139..d019941 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,13 +63,14 @@ m4_if(m4_version_compare([2.61a.100],
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 
 # Keep these two definitions in agreement.
-GLIB_MINIMUM_VERSION="2.36"
-GLIB_ENCODED_VERSION="GLIB_VERSION_2_36"
+GLIB_MINIMUM_VERSION="2.44"
+GLIB_ENCODED_VERSION="GLIB_VERSION_2_44"
 
 PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.6.0])
 PKG_CHECK_MODULES([LIBXSLT], [libxslt >= 1.0.0])
 PKG_CHECK_MODULES([LIBARCHIVE], [libarchive >= 3.0.0])
 PKG_CHECK_MODULES([JSON_GLIB], [json-glib-1.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/osinfo-db-tools.spec.in b/osinfo-db-tools.spec.in
index 459dde9..8a82c56 100644
--- a/osinfo-db-tools.spec.in
+++ b/osinfo-db-tools.spec.in
@@ -18,6 +18,7 @@ BuildRequires: gettext-devel
 BuildRequires: glib2-devel
 BuildRequires: libxml2-devel >= 2.6.0
 BuildRequires: libxslt-devel >= 1.0.0
+BuildRequires: libsoup-devel
 BuildRequires: libarchive-devel
 BuildRequires: json-glib-devel
 BuildRequires: /usr/bin/pod2man
diff --git a/tools/Makefile.am b/tools/Makefile.am
index e43e85d..f124d4f 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -2,6 +2,7 @@ AM_CFLAGS = $(GOBJECT_CFLAGS) \
 	    $(GIO_CFLAGS)     \
 	    $(GLIB_CFLAGS)    \
 	    $(LIBXML_CFLAGS)  \
+	    $(LIBSOUP_CFLAGS)  \
 	    -DPKGDATADIR="\"$(pkgdatadir)\"" \
 	    -DDATA_DIR="\"$(datadir)\"" \
 	    -DSYSCONFDIR="\"$(sysconfdir)\"" \
@@ -36,6 +37,7 @@ osinfo_db_import_SOURCES = osinfo-db-import.c $(COMMON_SOURCES)
 osinfo_db_import_LDADD = $(GOBJECT_LIBS)	\
 		      $(GIO_LIBS)		\
 		      $(GLIB_LIBS)		\
+		      $(LIBSOUP_LIBS)		\
 		      $(JSON_GLIB_LIBS)	\
 		      $(LIBARCHIVE_LIBS)
 osinfo_db_import_CFLAGS = $(AM_CFLAGS)		\
diff --git a/tools/osinfo-db-import.c b/tools/osinfo-db-import.c
index 675961d..9a6465c 100644
--- a/tools/osinfo-db-import.c
+++ b/tools/osinfo-db-import.c
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <archive.h>
 #include <archive_entry.h>
+#include <libsoup/soup.h>
 
 #include "osinfo-db-util.h"
 
@@ -36,6 +37,7 @@
 #define VERSION_FILE "VERSION"
 
 const char *argv0;
+static SoupSession *session = NULL;
 
 static int osinfo_db_import_create_reg(GFile *file,
                                        struct archive *arc,
@@ -139,33 +141,64 @@ static GFile *osinfo_db_import_get_file(GFile *target,
     return g_file_resolve_relative_path(target, tmp);
 }
 
-static int
-osinfo_db_import_download_file(GFile *file,
-                               gchar **source_file)
+static gchar *
+osinfo_db_import_download_file(const gchar *source)
 {
+    GInputStream *stream = NULL;
     GFile *out = NULL;
     GError *err = NULL;
+    SoupMessage *message = NULL;
     gchar *filename = NULL;
-    GFileCopyFlags flags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_BACKUP;
+    gchar *source_file = NULL;
+    gchar *content = NULL;
+    goffset content_size = 0;
+    GFileCreateFlags flags = G_FILE_CREATE_REPLACE_DESTINATION;
     int ret = -1;
 
-    filename = g_file_get_basename(file);
+    filename = g_path_get_basename(source);
     if (filename == NULL)
         goto cleanup;
 
-    *source_file = g_build_filename(g_get_user_cache_dir(), filename, NULL);
-    if (*source_file == NULL)
+    source_file = g_build_filename(g_get_user_cache_dir(), filename, NULL);
+    if (source_file == NULL)
         goto cleanup;
 
-    out = g_file_new_for_path(*source_file);
+    out = g_file_new_for_path(source_file);
     if (out == NULL)
         goto cleanup;
 
-    if (!g_file_copy(file, out, flags, NULL, NULL, NULL, &err)) {
-        gchar *path = g_file_get_path(file);
+    if (session == NULL)
+        session = soup_session_new();
+
+    if (session == NULL)
+        goto cleanup;
+
+    message = soup_message_new("GET", source);
+    if (message == NULL)
+        goto cleanup;
+
+    stream = soup_session_send(session, message, NULL, &err);
+    if (stream == NULL ||
+        !SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) {
+        g_printerr("Could not access %s: %s\n",
+                   source,
+                   err != NULL ? err->message :
+                                 soup_status_get_phrase(message->status_code));
+        goto cleanup;
+    }
+
+    content_size = soup_message_headers_get_content_length(message->response_headers);
+    content = g_malloc0(content_size);
+
+    if (!g_input_stream_read_all(stream, content, content_size, NULL, NULL, &err)) {
+        g_printerr("Could not load the content of %s: %s\n",
+                   source, err->message);
+        goto cleanup;
+    }
+
+    if (!g_file_replace_contents(out, content, content_size, NULL, TRUE, flags, NULL, NULL, &err)) {
         g_printerr("Could not download file \"%s\": %s\n",
-                   path, err->message);
-        g_free(path);
+                   source, err->message);
         goto cleanup;
     }
 
@@ -173,14 +206,20 @@ osinfo_db_import_download_file(GFile *file,
 
  cleanup:
     g_free(filename);
+    g_free(content);
+    g_clear_object(&message);
+    g_clear_object(&stream);
     if (out != NULL)
         g_object_unref(out);
     if (err != NULL)
         g_error_free(err);
-    if (ret != 0 && *source_file != NULL)
-        unlink(*source_file);
+    if (ret != 0 && source_file != NULL) {
+        unlink(source_file);
+        g_free(source_file);
+        source_file = NULL;
+    }
 
-    return ret;
+    return source_file;
 }
 
 static gboolean osinfo_db_get_installed_version(GFile *dir,
@@ -214,18 +253,39 @@ static gboolean osinfo_db_get_installed_version(GFile *dir,
 static gboolean osinfo_db_get_latest_info(gchar **version,
                                           gchar **url)
 {
+    SoupMessage *message = NULL;
+    GInputStream *stream = NULL;
     JsonParser *parser = NULL;
     JsonReader *reader = NULL;
-    GFile *uri = NULL;
     GError *err = NULL;
     gchar *content = NULL;
+    goffset content_size = 0;
     gboolean ret = FALSE;
 
-    uri = g_file_new_for_uri(LATEST_URI);
-    if (uri == NULL)
-        return FALSE;
+    if (session == NULL)
+        session = soup_session_new();
+
+    if (session == NULL)
+        goto cleanup;
 
-    if (!g_file_load_contents(uri, NULL, &content, NULL, NULL, &err)) {
+    message = soup_message_new("GET", LATEST_URI);
+    if (message == NULL)
+        goto cleanup;
+
+    stream = soup_session_send(session, message, NULL, &err);
+    if (stream == NULL ||
+        !SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) {
+        g_printerr("Could not access %s: %s\n",
+                   LATEST_URI,
+                   err != NULL ? err->message :
+                                 soup_status_get_phrase(message->status_code));
+        goto cleanup;
+    }
+
+    content_size = soup_message_headers_get_content_length(message->response_headers);
+    content = g_malloc0(content_size);
+
+    if (!g_input_stream_read_all(stream, content, content_size, NULL, NULL, &err)) {
         g_printerr("Could not load the content of %s: %s\n",
                    LATEST_URI, err->message);
         goto cleanup;
@@ -286,7 +346,7 @@ static gboolean osinfo_db_get_latest_info(gchar **version,
     ret = TRUE;
 
  cleanup:
-    g_object_unref(uri);
+    g_clear_object(&message);
     if (parser != NULL)
         g_object_unref(parser);
     if (reader != NULL)
@@ -323,12 +383,8 @@ static int osinfo_db_import_extract(GFile *target,
             goto cleanup;
 
         file_is_native = g_file_is_native(file);
-        if (!file_is_native) {
-            if (osinfo_db_import_download_file(file, &source_file) < 0)
-                goto cleanup;
-        } else {
-            source_file = g_file_get_path(file);
-        }
+        source_file = file_is_native ? g_file_get_path(file) :
+                                       osinfo_db_import_download_file(source);
         if (source_file == NULL)
             goto cleanup;
 
@@ -478,6 +534,7 @@ gint main(gint argc, gchar **argv)
     g_free(installed_version);
     g_free(latest_version);
     g_free(latest_url);
+    g_clear_object(&session);
     g_clear_error(&error);
     g_option_context_free(context);
 
-- 
2.21.0




More information about the Libosinfo mailing list