summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabiano FidĂȘncio <fidencio@redhat.com>2019-06-27 13:45:13 +0200
committerFabiano FidĂȘncio <fidencio@redhat.com>2019-07-17 08:57:58 +0200
commitac692eaa46801032bd7fcbde2ff4eed0ecb29eba (patch)
tree7ace17b1d6906c40c3e1fc1c9dbcad9afc8d8957
parentc9fc9c39c8466a593f18757dcdeaa196c2f93154 (diff)
downloadlibosinfo-ac692eaa46801032bd7fcbde2ff4eed0ecb29eba.tar.gz
media: Use libsoup for http:// & https:// requests
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@redhat.com> Reviewed-by: Cole Robinson <crobinso@redhat.com>
-rw-r--r--configure.ac1
-rw-r--r--libosinfo.spec.in1
-rw-r--r--osinfo/Makefile.am7
-rw-r--r--osinfo/osinfo_media.c60
-rw-r--r--osinfo/osinfo_util_private.c36
-rw-r--r--osinfo/osinfo_util_private.h28
6 files changed, 117 insertions, 16 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..7206c6d 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
@@ -153,6 +156,7 @@ libosinfo_c_files = \
osinfo_imagelist.c \
osinfo_db.c \
osinfo_loader.c \
+ osinfo_util_private.c \
$(NULL)
libosinfo_private_header_files = \
@@ -161,6 +165,7 @@ libosinfo_private_header_files = \
osinfo_product_private.h \
osinfo_media_private.h \
osinfo_resources_private.h \
+ osinfo_util_private.h \
ignore-value.h \
$(NULL)
diff --git a/osinfo/osinfo_media.c b/osinfo/osinfo_media.c
index 60df191..71acb12 100644
--- a/osinfo/osinfo_media.c
+++ b/osinfo/osinfo_media.c
@@ -27,10 +27,12 @@
#include <osinfo/osinfo.h>
#include "osinfo_media_private.h"
+#include "osinfo_util_private.h"
#include <gio/gio.h>
#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 +131,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 +155,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);
@@ -748,7 +758,7 @@ static void on_media_create_from_location_ready(GObject *source_object,
* @error: The location where to store any error, or %NULL
*
* Creates a new #OsinfoMedia for installation media at @location. The @location
- * could be any URI that GIO can handle or a local path.
+ * could be a http:// or a https:// URI or a local path.
*
* NOTE: Currently this only works for ISO images/devices.
*
@@ -772,7 +782,7 @@ OsinfoMedia *osinfo_media_create_from_location(const gchar *location,
* @flags: An #OsinfoMediaDetectFlag, or 0.
*
* Creates a new #OsinfoMedia for installation media at @location. The @location
- * could be any URI that GIO can handle or a local path.
+ * could be a http:// or a https:// URI or a local path.
*
* NOTE: Currently this only works for ISO images/devices.
*
@@ -837,18 +847,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,
@@ -1301,7 +1308,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);
@@ -1392,12 +1409,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 (osinfo_util_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);
+ }
}
/**
diff --git a/osinfo/osinfo_util_private.c b/osinfo/osinfo_util_private.c
new file mode 100644
index 0000000..ba1d611
--- /dev/null
+++ b/osinfo/osinfo_util_private.c
@@ -0,0 +1,36 @@
+/*
+ * libosinfo: A collection of utilities used for medias & trees
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "osinfo_util_private.h"
+
+gboolean
+osinfo_util_requires_soup(const gchar *location)
+{
+ const gchar *prefixes[] = { "http://", "https://", NULL };
+ gsize i;
+
+ for (i = 0; prefixes[i] != NULL; i++) {
+ if (g_str_has_prefix(location, prefixes[i]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/osinfo/osinfo_util_private.h b/osinfo/osinfo_util_private.h
new file mode 100644
index 0000000..d87cfaf
--- /dev/null
+++ b/osinfo/osinfo_util_private.h
@@ -0,0 +1,28 @@
+/*
+ * libosinfo: A collection of utilities used for medias & trees
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OSINFO_UTIL_PRIVATE_H__
+#define __OSINFO_UTIL_PRIVATE_H__
+
+#include <glib.h>
+
+gboolean osinfo_util_requires_soup(const gchar *location);
+
+#endif /* __OSINFO_UTIL_PRIVATE_H__ */